1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0025477: Boolean Operations with additional tolerance - Fuzzy Boolean operations

Implementation of Fuzzy Boolean operations. Such operations allow to perform Boolean operations on the shapes
with near-coincidence between the entities of these shapes, i.e. between shapes in which some entities from one shape
are intended to be coincide with some entities from the other, but the coincidence is not precise.

API for Boolean operations has been improved to have a possibility to add new options.

Modified entities:
1. New option of setting additional tolerance have been added to the following classes:
class BOPAlgo_ArgumentAnalyzer
class BOPAlgo_BOP
class BOPAlgo_Builder
class BOPAlgo_MakerVolume
class BOPAlgo_PaveFiller
class BOPDS_DS
class BRepAlgoAPI_BooleanOperation
class BRepAlgoAPI_Check
class BRepAlgoAPI_Common
class BRepAlgoAPI_Cut
class BRepAlgoAPI_Fuse
class BRepAlgoAPI_Section

2. Following draw commands have been modified to support new functionality:
BOP commands:
bop b1 b2 [tol]
bcommon r b1 b2 [tol]
bcut r b1 b2 [tol]
bfuse r b1 b2 [tol]
bsection r s1 s2 [-n2d/-n2d1/-n2d2] [-na] [tol]
mkvolume r b1 b2 ... [-c] [-ni] [-s] [tol]
bfillds [-s -t] [tol]

Check commands:
bopcheck Shape [level of check: 0 - 9] [-t -s] [-tol tol]
bopargcheck [-F/O/C/T/S/U] [/R|F|T|V|E|I|P|C|S]] [#BF] [-tol tol]

3. Two new classes have been added to API to provide the root interface for algorithms
class BRepAlgoAPI_Algo
class BRepAlgoAPI_BuilderAlgo

Fix to eliminate the warning.

Test-cases for issue #25477
This commit is contained in:
emv
2014-11-28 12:23:58 +03:00
committed by bugmaster
parent 49e1a5c7e9
commit b1d15f53b3
41 changed files with 2273 additions and 1084 deletions

View File

@@ -14,6 +14,7 @@
-- commercial license or contractual agreement.
class ArgumentAnalyzer from BOPAlgo
inherits Algo from BOPAlgo
---Purpose: check the validity of argument(s) for Boolean Operations
uses
@@ -21,11 +22,13 @@ uses
Operation from BOPAlgo,
CheckStatus from BOPAlgo,
ShapeEnum from TopAbs,
ListOfCheckResult from BOPAlgo
ListOfCheckResult from BOPAlgo,
DataMapOfShapeReal from BOPCol
is
Create
returns ArgumentAnalyzer;
---C++: alias "Standard_EXPORT virtual ~BOPAlgo_ArgumentAnalyzer();"
---Purpose: empty constructor
SetShape1(me: in out; TheShape: Shape from TopoDS);
@@ -167,8 +170,25 @@ is
is protected;
-- TestMergeFace(me: out)
-- is protected;
-- is protected;
SetFuzzyValue(me:out;
theFuzz : Real from Standard);
---C++: inline
---Purpose: Sets the additional tolerance
FuzzyValue(me)
returns Real from Standard;
---C++: inline
---Purpose: Returns the additional tolerance
UpdateTolerances(me:out)
is protected;
---Purpose: Updates the shapes tolerance values.
SetDefaultTolerances(me:out)
is protected;
---Purpose: Reverts the tolerance values for all entities to default values.
fields
@@ -186,6 +206,8 @@ fields
myContinuityMode : Boolean from Standard;
myCurveOnSurfaceMode : Boolean from Standard;
myEmpty1, myEmpty2 : Boolean from Standard;
myResult : ListOfCheckResult from BOPAlgo;
myResult : ListOfCheckResult from BOPAlgo;
myFuzzyValue : Real from Standard;
myToleranceMap : DataMapOfShapeReal from BOPCol;
end ArgumentAnalyzer;

View File

@@ -31,6 +31,9 @@
#include <TopoDS_Shell.hxx>
#include <TopoDS_Solid.hxx>
#include <BRep_TVertex.hxx>
#include <BRep_TEdge.hxx>
#include <BRep_TFace.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
@@ -49,6 +52,7 @@
#include <IntTools_Context.hxx>
#include <BOPTools.hxx>
#include <BOPTools_AlgoTools3D.hxx>
#include <BOPTools_AlgoTools.hxx>
@@ -64,6 +68,7 @@
// purpose:
// ================================================================================
BOPAlgo_ArgumentAnalyzer::BOPAlgo_ArgumentAnalyzer() :
BOPAlgo_Algo(),
myStopOnFirst(Standard_False),
myOperation(BOPAlgo_UNKNOWN),
myArgumentTypeMode(Standard_False),
@@ -76,9 +81,19 @@ myMergeEdgeMode(Standard_False),
myContinuityMode(Standard_False),
myCurveOnSurfaceMode(Standard_False),
myEmpty1(Standard_False),
myEmpty2(Standard_False)
myEmpty2(Standard_False),
myFuzzyValue(0.)
{
}
//=======================================================================
// function: ~
// purpose:
//=======================================================================
BOPAlgo_ArgumentAnalyzer::~BOPAlgo_ArgumentAnalyzer()
{
myResult.Clear();
myToleranceMap.Clear();
}
// ================================================================================
// function: SetShape1
@@ -157,47 +172,82 @@ void BOPAlgo_ArgumentAnalyzer::Perform()
try {
OCC_CATCH_SIGNALS
myResult.Clear();
//
UserBreak();
//
// 1. Prepare
Prepare();
//
UserBreak();
//
// 2. Update Tolerances according to myFuzzyValue
UpdateTolerances();
//
UserBreak();
//
// 3. Test types
if(myArgumentTypeMode) {
TestTypes();
}
//
UserBreak();
//
// 4. Test self-interference
if(mySelfInterMode) {
TestSelfInterferences();
}
//
UserBreak();
//
// 5. Test small edges
if(mySmallEdgeMode) {
if(!(!myResult.IsEmpty() && myStopOnFirst))
TestSmallEdge();
}
//
UserBreak();
//
// 6. Test possibility to rebuild faces
if(myRebuildFaceMode) {
if(!(!myResult.IsEmpty() && myStopOnFirst))
TestRebuildFace();
}
//
UserBreak();
//
// 7. Test tangent
if(myTangentMode) {
if(!(!myResult.IsEmpty() && myStopOnFirst))
TestTangent();
}
//
UserBreak();
//
// 8. Test merge vertices
if(myMergeVertexMode) {
if(!(!myResult.IsEmpty() && myStopOnFirst))
TestMergeVertex();
}
//
UserBreak();
//
// 9. Test merge edges
if(myMergeEdgeMode) {
if(!(!myResult.IsEmpty() && myStopOnFirst))
TestMergeEdge();
}
//
UserBreak();
//
// 10. Test shapes continuity
if(myContinuityMode) {
if(!(!myResult.IsEmpty() && myStopOnFirst))
TestContinuity();
}
//
UserBreak();
//
// 11. Test validity of the curves on the surfaces
if(myCurveOnSurfaceMode) {
if(!(!myResult.IsEmpty() && myStopOnFirst))
TestCurveOnSurface();
@@ -208,6 +258,8 @@ void BOPAlgo_ArgumentAnalyzer::Perform()
aResult.SetCheckStatus(BOPAlgo_CheckUnknown);
myResult.Append(aResult);
}
//
SetDefaultTolerances();
}
// ================================================================================
@@ -329,6 +381,8 @@ void BOPAlgo_ArgumentAnalyzer::TestSelfInterferences()
anArgs.Append(aS);
aChecker.SetArguments(anArgs);
aChecker.SetNonDestructive(Standard_True);
aChecker.SetRunParallel(myRunParallel);
aChecker.SetProgressIndicator(myProgressIndicator);
//
aChecker.Perform();
iErr=aChecker.ErrorStatus();
@@ -874,3 +928,121 @@ void BOPAlgo_ArgumentAnalyzer::TestCurveOnSurface()
}
}
// ================================================================================
// function: UpdateTolerances
// purpose:
// ================================================================================
void BOPAlgo_ArgumentAnalyzer::UpdateTolerances()
{
if (myFuzzyValue == 0.) {
return;
}
//
BOPCol_MapOfShape aMapShapes;
//
if (!myShape1.IsNull()) {
BOPTools::MapShapes(myShape1, aMapShapes);
}
if (!myShape2.IsNull()) {
BOPTools::MapShapes(myShape2, aMapShapes);
}
//
if (aMapShapes.IsEmpty()) {
return;
}
//
Standard_Real aTol, aFuzz;
TopAbs_ShapeEnum aType;
BOPCol_MapIteratorOfMapOfShape aIt;
//
aFuzz = myFuzzyValue / 2.;
aIt.Initialize(aMapShapes);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS = aIt.Value();
aType = aS.ShapeType();
//
switch (aType) {
case TopAbs_VERTEX: {
const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aS;
const Handle(BRep_TVertex)& TV =
*((Handle(BRep_TVertex)*)&aV.TShape());
aTol = TV->Tolerance();
myToleranceMap.Bind(aS, aTol);
TV->Tolerance(aTol + aFuzz);
break;
}
case TopAbs_EDGE: {
const TopoDS_Edge& aE = *(TopoDS_Edge*)&aS;
const Handle(BRep_TEdge)& TE =
*((Handle(BRep_TEdge)*)&aE.TShape());
aTol = TE->Tolerance();
myToleranceMap.Bind(aS, aTol);
TE->Tolerance(aTol + aFuzz);
break;
}
case TopAbs_FACE: {
const TopoDS_Face& aF = *(TopoDS_Face*)&aS;
const Handle(BRep_TFace)& TF =
*((Handle(BRep_TFace)*)&aF.TShape());
aTol = TF->Tolerance();
myToleranceMap.Bind(aS, aTol);
TF->Tolerance(aTol + aFuzz);
break;
}
default:
break;
} // switch (aType) {
} // for (; aIt.More(); aIt.Next()) {
}
// ================================================================================
// function: SetDefaultTolerances
// purpose:
// ================================================================================
void BOPAlgo_ArgumentAnalyzer::SetDefaultTolerances()
{
if (myFuzzyValue == 0.) {
return;
}
//
if (myToleranceMap.IsEmpty()) {
return;
}
//
Standard_Real aTol;
TopAbs_ShapeEnum aType;
BOPCol_DataMapIteratorOfDataMapOfShapeReal aIt;
//
aIt.Initialize(myToleranceMap);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS = aIt.Key();
aTol = aIt.Value();
aType = aS.ShapeType();
//
switch (aType) {
case TopAbs_VERTEX: {
const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aS;
const Handle(BRep_TVertex)& TV =
*((Handle(BRep_TVertex)*)&aV.TShape());
TV->Tolerance(aTol);
break;
}
case TopAbs_EDGE: {
const TopoDS_Edge& aE = *(TopoDS_Edge*)&aS;
const Handle(BRep_TEdge)& TE =
*((Handle(BRep_TEdge)*)&aE.TShape());
TE->Tolerance(aTol);
break;
}
case TopAbs_FACE: {
const TopoDS_Face& aF = *(TopoDS_Face*)&aS;
const Handle(BRep_TFace)& TF =
*((Handle(BRep_TFace)*)&aF.TShape());
TF->Tolerance(aTol);
break;
}
default:
break;
} // switch (aType) {
} // for (; aIt.More(); aIt.Next()) {
}

View File

@@ -61,6 +61,24 @@ inline Standard_Boolean& BOPAlgo_ArgumentAnalyzer::CurveOnSurfaceMode()
{
return myCurveOnSurfaceMode;
}
//=======================================================================
//function : SetFuzzyValue
//purpose :
//=======================================================================
inline void BOPAlgo_ArgumentAnalyzer::SetFuzzyValue(const Standard_Real theFuzz)
{
if (theFuzz > 0.) {
myFuzzyValue = theFuzz;
}
}
//=======================================================================
//function : FuzzyValue
//purpose :
//=======================================================================
inline Standard_Real BOPAlgo_ArgumentAnalyzer::FuzzyValue() const
{
return myFuzzyValue;
}
// inline Standard_Boolean& BOPAlgo_ArgumentAnalyzer::MergeFaceMode()
// {
// return myMergeFaceMode;

View File

@@ -350,6 +350,9 @@ void BOPAlgo_BOP::Perform()
//
pPF=new BOPAlgo_PaveFiller(aAllocator);
pPF->SetArguments(aLS);
pPF->SetRunParallel(myRunParallel);
pPF->SetProgressIndicator(myProgressIndicator);
pPF->SetFuzzyValue(myFuzzyValue);
//
pPF->Perform();
//

View File

@@ -219,7 +219,15 @@ is
Splits (me)
returns DataMapOfShapeListOfShape from BOPCol;
---C++: return const &
---Purpose: Returns mySplits.
---Purpose: Returns mySplits.
SetFuzzyValue(me:out;
theFuzz : Real from Standard);
---Purpose: Sets the additional tolerance
FuzzyValue(me)
returns Real from Standard;
---Purpose: Returns the additional tolerance
fields
myArguments : ListOfShape from BOPCol is protected;
@@ -233,7 +241,8 @@ fields
myShapesSD : DataMapOfShapeShape from BOPCol is protected;
--
mySplits : DataMapOfShapeListOfShape from BOPCol is protected;
myOrigins : DataMapOfShapeShape from BOPCol is protected;
myOrigins : DataMapOfShapeShape from BOPCol is protected;
myFuzzyValue : Real from Standard is protected;
end Builder;

View File

@@ -42,7 +42,8 @@ BOPAlgo_Builder::BOPAlgo_Builder()
myImages(100, myAllocator),
myShapesSD(100, myAllocator),
mySplits(100, myAllocator),
myOrigins(100, myAllocator)
myOrigins(100, myAllocator),
myFuzzyValue(0.)
{
}
//=======================================================================
@@ -61,7 +62,8 @@ BOPAlgo_Builder::BOPAlgo_Builder
myImages(100, myAllocator),
myShapesSD(100, myAllocator),
mySplits(100, myAllocator),
myOrigins(100, myAllocator)
myOrigins(100, myAllocator),
myFuzzyValue(0.)
{
}
//=======================================================================
@@ -172,6 +174,24 @@ BOPDS_PDS BOPAlgo_Builder::PDS()
return myDS;
}
//=======================================================================
//function : SetFuzzyValue
//purpose :
//=======================================================================
void BOPAlgo_Builder::SetFuzzyValue(const Standard_Real theFuzz)
{
if (theFuzz > 0.) {
myFuzzyValue = theFuzz;
}
}
//=======================================================================
//function : FuzzyValue
//purpose :
//=======================================================================
Standard_Real BOPAlgo_Builder::FuzzyValue() const
{
return myFuzzyValue;
}
//=======================================================================
// function: CheckData
// purpose:
//=======================================================================
@@ -236,6 +256,8 @@ void BOPAlgo_Builder::Perform()
//
pPF->SetArguments(myArguments);
pPF->SetRunParallel(myRunParallel);
pPF->SetProgressIndicator(myProgressIndicator);
pPF->SetFuzzyValue(myFuzzyValue);
//
pPF->Perform();
//

View File

@@ -104,6 +104,7 @@ void BOPAlgo_CheckerSI::Init()
// 1. myDS
myDS=new BOPDS_DS(myAllocator);
myDS->SetArguments(myArguments);
myDS->SetFuzzyValue(myFuzzyValue);
myDS->Init();
//
// 2.myIterator

View File

@@ -43,6 +43,29 @@ static
BOPCol_MapOfShape& aMFence,
BOPCol_ListOfShape& theLS);
//=======================================================================
//function : CheckData
//purpose :
//=======================================================================
void BOPAlgo_MakerVolume::CheckData()
{
if (myArguments.IsEmpty()) {
myErrorStatus = 100; // no arguments to process
return;
}
// myPaveFiller
if (!myPaveFiller) {
myErrorStatus = 101;
return;
}
//
myErrorStatus = myPaveFiller->ErrorStatus();
if (myErrorStatus) {
myErrorStatus = 102; // PaveFiller is failed
return;
}
}
//=======================================================================
//function : Perform
//purpose :
@@ -84,6 +107,8 @@ void BOPAlgo_MakerVolume::Perform()
}
//
pPF->SetRunParallel(myRunParallel);
pPF->SetProgressIndicator(myProgressIndicator);
pPF->SetFuzzyValue(myFuzzyValue);
pPF->Perform();
//
myEntryPoint = 1;

View File

@@ -92,26 +92,3 @@ inline const BOPCol_ListOfShape& BOPAlgo_MakerVolume::Faces()const
{
return myFaces;
}
//=======================================================================
//function : CheckData
//purpose :
//=======================================================================
inline void BOPAlgo_MakerVolume::CheckData()
{
if (myArguments.IsEmpty()) {
myErrorStatus = 100; // no arguments to process
return;
}
// myPaveFiller
if (!myPaveFiller) {
myErrorStatus = 101;
return;
}
//
myErrorStatus = myPaveFiller->ErrorStatus();
if (myErrorStatus) {
myErrorStatus = 102; // PaveFiller is failed
return;
}
}

View File

@@ -463,12 +463,20 @@ is
---Purpose:
-- Updates pave blocks which have the paves with indices contained
-- in the map <theDMI>.
SetFuzzyValue(me:out;
theFuzz : Real from Standard);
---Purpose: Sets the additional tolerance
FuzzyValue(me)
returns Real from Standard;
---Purpose: Returns the additional tolerance
fields
myArguments : ListOfShape from BOPCol is protected;
myDS : PDS from BOPDS is protected;
myIterator : PIterator from BOPDS is protected;
myContext : Context from IntTools is protected;
mySectionAttribute : SectionAttribute from BOPAlgo is protected;
myFuzzyValue : Real from Standard is protected;
end PaveFiller;

View File

@@ -33,7 +33,8 @@
//=======================================================================
BOPAlgo_PaveFiller::BOPAlgo_PaveFiller()
:
BOPAlgo_Algo()
BOPAlgo_Algo(),
myFuzzyValue(0.)
{
myDS=NULL;
myIterator=NULL;
@@ -45,7 +46,8 @@ BOPAlgo_PaveFiller::BOPAlgo_PaveFiller()
BOPAlgo_PaveFiller::BOPAlgo_PaveFiller
(const Handle(NCollection_BaseAllocator)& theAllocator)
:
BOPAlgo_Algo(theAllocator)
BOPAlgo_Algo(theAllocator),
myFuzzyValue(0.)
{
myDS=NULL;
myIterator=NULL;
@@ -123,6 +125,24 @@ const BOPCol_ListOfShape& BOPAlgo_PaveFiller::Arguments()const
return myArguments;
}
//=======================================================================
//function : SetFuzzyValue
//purpose :
//=======================================================================
void BOPAlgo_PaveFiller::SetFuzzyValue(const Standard_Real theFuzz)
{
if (theFuzz > 0.) {
myFuzzyValue = theFuzz;
}
}
//=======================================================================
//function : FuzzyValue
//purpose :
//=======================================================================
Standard_Real BOPAlgo_PaveFiller::FuzzyValue() const
{
return myFuzzyValue;
}
//=======================================================================
// function: Init
// purpose:
//=======================================================================
@@ -141,6 +161,7 @@ void BOPAlgo_PaveFiller::Init()
// 1.myDS
myDS=new BOPDS_DS(myAllocator);
myDS->SetArguments(myArguments);
myDS->SetFuzzyValue(myFuzzyValue);
myDS->Init();
//
// 2.myIterator
@@ -170,6 +191,8 @@ void BOPAlgo_PaveFiller::Perform()
catch (Standard_Failure) {
myErrorStatus=11;
}
//
myDS->SetDefaultTolerances();
}
//=======================================================================
// function: PerformInternal
@@ -244,7 +267,6 @@ void BOPAlgo_PaveFiller::PerformInternal()
return;
}
//
//modified by NIZNHY-PKV Fri Sep 12 07:06:50 2014f
// 03
PerformVZ();
if (myErrorStatus) {
@@ -265,5 +287,4 @@ void BOPAlgo_PaveFiller::PerformInternal()
if (myErrorStatus) {
return;
}
//modified by NIZNHY-PKV Fri Sep 12 07:06:52 2014t
}