1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

Compare commits

...

4 Commits

Author SHA1 Message Date
emv
8d2ebfcc11 Implementation of the Oriented Bounding Boxes using PCA-based algorithm to use in Boolean operations for filtering of the intersections.
OBB is implemented in IntTools_OBB class, and is represented as center, axes and half-size dimensions.

The method IntTools_OBB::IsOut(theOther) is based on the Separated Axes theorem for Oriented Bounding Boxes.
According to this theorem it is necessary to consider 15 separating axes.

By default the OBB are not used. To enable the OBB usage in Boolean Operations it is necessary to call the method BOPAlgo_PaveFiller::SetUseOBB(const Standard_Boolean theFlag) with TRUE value.
To enable OBB usage in DRAW it is necessary to use the command:
buseobb 1
2017-11-02 14:39:00 +03:00
emv
eea21625fb 0029237: Improve performance of Boolean Operations
In order to improve performance of Boolean Operations on the relatively fast cases the following improvements have been made:
1. Initialization of the FaceInfo information for the faces participating in Face/Face interference, even when the gluing is ON, to take into account intersection of their sub-shapes.
2. Code simplification & duplication removal - the methods BOPAlgo_ShellSplitter::MakeConnexityBlocks and BOPAlgo_WireSplitter::MakeConnexityBlocks have been unified into BOPTools_AlgoTools::MakeConnexityBlocks.
3. Avoid unnecessary bounding box computation for solids during DS initialization. The bounding boxes for solids will be computed during the building stage to find faces located inside solids.
   For the shape self-interference check (performed by the BOPAlgo_CheckerSI), the bounding box is still computed, as it is necessary to resolve Shape/Solid intersections.
4. Use only three sample points to check coincidence of line and plane.
5. Perform necessity of planes intersection only when the gluing is off.
6. Avoid repeated initialization of 2D classifier while building splits of the faces.
7. Post treat stage:
7.1. Method CorrectWires: Save edge's data (PCurve, parameter of the vertex, range) to avoid its recalculation.
7.2. Method CheckEdge: While checking vertices on edges avoid unnecessary calculation of their location.
8. Provide possibility to disable the classification of the input solids on the inverted status (to be the holes in the space).
9. Avoid building of bounding boxes for faces/solids during splitting of the input arguments for their classification relatively hole faces/shells if there are no holes created.
10. Avoid rebuilding of the faces/solids from arguments which does not acquire any inside parts from other arguments during the operation by using their draft versions as their splits.

Test cases for the issue.
Correction of the test cases boolean gdml_public A9 and bugs modalg_7 bug28485 as they are improvements.
Additional test case for the issue #28485 as it is fixed by the current changes.
2017-11-02 07:07:01 +03:00
emv
b542b3d6a1 0029188: Null shape is produced by 3D offset algorithm (mode="Complete", Join Type="Intersection")
The following improvements have been made in the 3D offset algorithm for mode "Complete" and Join type "Intersection":
- RemoveInsideFaces() - Removal of the invalid parts outside of the solids built from the splits of offset faces is now performed. It helps to avoid their rebuilding and speed-up the computation.
- FindVerticesToAvoid() - Strengthening the criteria for the vertices to be avoided in the new splits.

Test cases for the issue.
Adjustment of the test cases to current behavior.
2017-10-16 15:55:28 +03:00
emv
788cb92681 0029135: 3D Offset algorithm produces a NULL shape
UpdateValidEdges in BRepOffset_MakeOffset_1 - Perform the filtering of splits of the edges in two stages:
1. Separate filtering of the connected blocks using localized bounding edges taken only from the splits of offset faces from the block;
2. Combined treatment of the remaining splits using bounding edges from the splits of all offset faces.
2017-10-06 07:06:29 +03:00
83 changed files with 2856 additions and 1515 deletions

View File

@@ -2718,6 +2718,38 @@ To enable the safe processing mode for the operation in DRAW, it is necessary to
bnondestructive 1
~~~~
@subsection occt_algorithms_11a_4 Disabling check of the input solids for inverted status
By default, all input solids are checked for inverted status, i.e. the solids are classified to understand if they are holes in the space (negative volumes) or normal solids (positive volumes). The possibility to disable the check of the input solids for inverted status is the advanced option in Boolean Operation component. This option can be applied to all Basic operations such as General Fuse, Splitting, Boolean, Section, Maker Volume, Cells building.
This option allows avoiding time-consuming classification of the input solids and operate with them as with positive volumes, saving up to 10 percent of time on the cases with big number of input solids.
The classification should be disabled only if the user is sure that there are no negative volumes among the input solids, otherwise the result may be invalid.
@subsubsection occt_algorithms_11a_4_1 Usage
#### API level
To enable/disable the classification of the input solids it is necessary to call *SetCheckInverted()* method with the appropriate value:
~~~~
BOPAlgo_Builder aGF;
//
....
// disabling the classification of the input solid
aGF.SetCheckInverted(Standard_False);
//
....
~~~~
#### TCL level
To enable/disable the classification of the solids in DRAW, it is necessary to call the *bcheckinverted* command with appropriate value:
* 0 - disabling the classification;
* 1 - default value, enabling the classification.
~~~~
bcheckinverted 0
~~~~
@section occt_algorithms_ers Errors and warnings reporting system
The chapter describes the Error/Warning reporting system of the algorithms in the Boolean Component.

View File

@@ -411,6 +411,7 @@ void BOPAlgo_BOP::Perform()
pPF->SetFuzzyValue(myFuzzyValue);
pPF->SetNonDestructive(myNonDestructive);
pPF->SetGlue(myGlue);
pPF->SetUseOBB(myUseOBB);
//
pPF->Perform();
//

View File

@@ -286,6 +286,7 @@ void BOPAlgo_Builder::Perform()
pPF->SetFuzzyValue(myFuzzyValue);
pPF->SetNonDestructive(myNonDestructive);
pPF->SetGlue(myGlue);
pPF->SetUseOBB(myUseOBB);
//
pPF->Perform();
//
@@ -303,6 +304,7 @@ void BOPAlgo_Builder::PerformWithFiller(const BOPAlgo_PaveFiller& theFiller)
myNonDestructive = theFiller.NonDestructive();
myFuzzyValue = theFiller.FuzzyValue();
myGlue = theFiller.Glue();
myUseOBB = theFiller.UseOBB();
PerformInternal(theFiller);
}
//=======================================================================

View File

@@ -25,6 +25,7 @@
#include <BOPCol_DataMapOfShapeListOfShape.hxx>
#include <BOPCol_DataMapOfShapeShape.hxx>
#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
#include <BOPCol_IndexedDataMapOfShapeShape.hxx>
#include <BOPCol_ListOfShape.hxx>
#include <BOPCol_MapOfShape.hxx>
#include <BOPCol_MapOfOrientedShape.hxx>
@@ -50,6 +51,7 @@
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopLoc_Location.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Iterator.hxx>
@@ -69,65 +71,7 @@ static
static
void MakeInternalWires(const BOPCol_IndexedMapOfShape& ,
BOPCol_ListOfShape& );
static
void GetWire(const TopoDS_Shape& ,
TopoDS_Shape& );
//
//
//=======================================================================
//class : BOPAlgo_ShapeBox2D
//purpose : Auxiliary class
//=======================================================================
class BOPAlgo_ShapeBox2D {
public:
BOPAlgo_ShapeBox2D() {
myIsHole=Standard_False;
};
//
~BOPAlgo_ShapeBox2D() {
};
//
void SetShape(const TopoDS_Shape& aS) {
myShape=aS;
};
//
const TopoDS_Shape& Shape()const {
return myShape;
};
//
void SetBox2D(const Bnd_Box2d& aBox2D) {
myBox2D=aBox2D;
};
//
const Bnd_Box2d& Box2D()const {
return myBox2D;
};
//
void SetIsHole(const Standard_Boolean bFlag) {
myIsHole=bFlag;
};
//
Standard_Boolean IsHole()const {
return myIsHole;
};
//
protected:
Standard_Boolean myIsHole;
TopoDS_Shape myShape;
Bnd_Box2d myBox2D;
};
//
typedef NCollection_IndexedDataMap
<Standard_Integer,
BOPAlgo_ShapeBox2D,
TColStd_MapIntegerHasher> BOPAlgo_IndexedDataMapOfIntegerShapeBox2D;
typedef NCollection_IndexedDataMap
<TopoDS_Shape,
TopoDS_Shape,
TopTools_ShapeMapHasher> BOPCol_IndexedDataMapOfShapeShape;
//
//=======================================================================
//function :
//purpose :
@@ -436,239 +380,198 @@ void BOPAlgo_BuilderFace::PerformLoops()
//=======================================================================
void BOPAlgo_BuilderFace::PerformAreas()
{
Standard_Boolean bIsGrowth, bIsHole;
Standard_Integer k, aNbS, aNbHoles, aNbDMISB, m, aNbMSH, aNbInOutMap;
Standard_Real aTol;
TopLoc_Location aLoc;
Handle(Geom_Surface) aS;
BRep_Builder aBB;
TopoDS_Face aFace;
BOPCol_ListIteratorOfListOfInteger aItLI;
BOPCol_IndexedMapOfShape aMHE;
BOPCol_ListIteratorOfListOfShape aIt1;
BOPCol_IndexedDataMapOfShapeListOfShape aMSH;
BOPCol_IndexedDataMapOfShapeShape aInOutMap;
BOPAlgo_IndexedDataMapOfIntegerShapeBox2D aDMISB(100);
//
BOPCol_Box2DBndTreeSelector aSelector;
BOPCol_Box2DBndTree aBBTree;
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box2d> aTreeFiller(aBBTree);
//
aNbHoles=0;
//
aTol=BRep_Tool::Tolerance(myFace);
aS=BRep_Tool::Surface(myFace, aLoc);
//
myAreas.Clear();
//
if (myLoops.IsEmpty()) {
if (myContext->IsInfiniteFace(myFace)) {
BRep_Builder aBB;
// Location of the myFace
TopLoc_Location aLoc;
// Get surface from myFace
const Handle(Geom_Surface)& aS = BRep_Tool::Surface(myFace, aLoc);
// Get tolerance of myFace
Standard_Real aTol = BRep_Tool::Tolerance(myFace);
// Check if there are no loops at all
if (myLoops.IsEmpty())
{
if (myContext->IsInfiniteFace(myFace))
{
TopoDS_Face aFace;
aBB.MakeFace(aFace, aS, aLoc, aTol);
if (BRep_Tool::NaturalRestriction(myFace)) {
if (BRep_Tool::NaturalRestriction(myFace))
aBB.NaturalRestriction(aFace, Standard_True);
}
myAreas.Append(aFace);
myAreas.Append(aFace);
}
return;
}
//
// 1. Growthes and Holes -> aDMISB: [Index/ShapeBox2D]
aIt1.Initialize(myLoops);
for (k=0 ; aIt1.More(); aIt1.Next(), ++k) {
Bnd_Box2d aBox2D;
//
const TopoDS_Shape& aWire=aIt1.Value();
//
// The new faces
BOPCol_ListOfShape aNewFaces;
// The hole faces which has to be classified relatively new faces
BOPCol_IndexedMapOfShape aHoleFaces;
// Map of the edges of the hole faces for quick check of the growths.
// If the analyzed wire contains any of the edges from the hole faces
// it is considered as growth.
BOPCol_IndexedMapOfShape aMHE;
// Analyze the new wires - classify them to be the holes and growths
BOPCol_ListIteratorOfListOfShape aItLL(myLoops);
for (; aItLL.More(); aItLL.Next())
{
const TopoDS_Shape& aWire = aItLL.Value();
TopoDS_Face aFace;
aBB.MakeFace(aFace, aS, aLoc, aTol);
aBB.Add (aFace, aWire);
BRepTools::AddUVBounds(aFace, aBox2D);
//
bIsGrowth=IsGrowthWire(aWire, aMHE);
if (bIsGrowth) {
bIsHole=Standard_False;
aBB.Add(aFace, aWire);
Standard_Boolean bIsGrowth = IsGrowthWire(aWire, aMHE);
if (!bIsGrowth)
{
// Fast check did not give the result, run classification
IntTools_FClass2d& aClsf = myContext->FClass2d(aFace);
bIsGrowth = !aClsf.IsHole();
}
else{
// check if a wire is a hole
IntTools_FClass2d& aClsf=myContext->FClass2d(aFace);
aClsf.Init(aFace, aTol);
//
bIsHole=aClsf.IsHole();
if (bIsHole) {
BOPTools::MapShapes(aWire, TopAbs_EDGE, aMHE);
//
bIsHole=Standard_True;
}
else {
bIsHole=Standard_False;
}
// Save the face
if (bIsGrowth)
{
aNewFaces.Append(aFace);
}
//
BOPAlgo_ShapeBox2D aSB2D;
//
aSB2D.SetShape(aFace);
aSB2D.SetBox2D(aBox2D);
aSB2D.SetIsHole(bIsHole);
//
aDMISB.Add(k, aSB2D);
}// for (k=0 ; aIt1.More(); aIt1.Next(), ++k) {
//
// 2. Prepare TreeFiller
aNbDMISB=aDMISB.Extent();
for (m=1; m<=aNbDMISB; ++m) {
k=aDMISB.FindKey(m);
const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
//
bIsHole=aSB2D.IsHole();
if (bIsHole) {
const Bnd_Box2d& aBox2D=aSB2D.Box2D();
aTreeFiller.Add(k, aBox2D);
++aNbHoles;
else
{
aHoleFaces.Add(aFace);
BOPTools::MapShapes(aWire, TopAbs_EDGE, aMHE);
}
}
//
// 3. Shake TreeFiller
if (aHoleFaces.IsEmpty())
{
// No holes, stop the analysis
myAreas.Append(aNewFaces);
}
// Classify holes relatively faces
// Prepare tree filler with the boxes of the hole faces
BOPCol_Box2DBndTree aBBTree;
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box2d> aTreeFiller(aBBTree);
Standard_Integer i, aNbH = aHoleFaces.Extent();
for (i = 1; i <= aNbH; ++i)
{
const TopoDS_Face& aHFace = TopoDS::Face(aHoleFaces(i));
//
Bnd_Box2d aBox;
BRepTools::AddUVBounds(aHFace, aBox);
aTreeFiller.Add(i, aBox);
}
// Shake TreeFiller
aTreeFiller.Fill();
//
// 4. Find outer growth shell that is most close
// to each hole shell
for (m=1; m<=aNbDMISB; ++m) {
const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
bIsHole=aSB2D.IsHole();
if (bIsHole) {
continue;
}
//
const Bnd_Box2d& aBox2DF=aSB2D.Box2D();
const TopoDS_Shape aF=aSB2D.Shape();
//
aSelector.Clear();
aSelector.SetBox(aBox2DF);
//
aNbS = aBBTree.Select(aSelector);
if (!aNbS) {
continue;
}
//
const BOPCol_ListOfInteger& aLI=aSelector.Indices();
//
aItLI.Initialize(aLI);
for (; aItLI.More(); aItLI.Next()) {
k=aItLI.Value();
const BOPAlgo_ShapeBox2D& aSB2Dk=aDMISB.FindFromKey(k);
const TopoDS_Shape& aHole=aSB2Dk.Shape();
//
if (!IsInside(aHole, aF, myContext)){
// Find outer growth face that is most close to each hole face
BOPCol_IndexedDataMapOfShapeShape aHoleFaceMap;
BOPCol_ListIteratorOfListOfShape aItLS(aNewFaces);
for (; aItLS.More(); aItLS.Next())
{
const TopoDS_Face& aFace = TopoDS::Face(aItLS.Value());
// Build box
Bnd_Box2d aBox;
BRepTools::AddUVBounds(aFace, aBox);
BOPCol_Box2DBndTreeSelector aSelector;
aSelector.SetBox(aBox);
aBBTree.Select(aSelector);
const BOPCol_ListOfInteger& aLI = aSelector.Indices();
BOPCol_ListIteratorOfListOfInteger aItLI(aLI);
for (; aItLI.More(); aItLI.Next())
{
Standard_Integer k = aItLI.Value();
const TopoDS_Shape& aHole = aHoleFaces(k);
// Check if it is inside
if (!IsInside(aHole, aFace, myContext))
continue;
}
//
if (aInOutMap.Contains(aHole)){
TopoDS_Shape& aF2=aInOutMap.ChangeFromKey(aHole);
if (IsInside(aF, aF2, myContext)) {
aF2=aF;
// Save the relation
TopoDS_Shape* pFaceWas = aHoleFaceMap.ChangeSeek(aHole);
if (pFaceWas)
{
if (IsInside(aFace, *pFaceWas, myContext))
{
*pFaceWas = aFace;
}
}
else{
aInOutMap.Add(aHole, aF);
else
{
aHoleFaceMap.Add(aHole, aFace);
}
}
}// for (m=1; m<=aNbDMISB; ++m)
//
// 5.1 Map [Face/Holes] -> aMSH
aNbInOutMap=aInOutMap.Extent();
for (m=1; m<=aNbInOutMap; ++m) {
const TopoDS_Shape& aHole=aInOutMap.FindKey(m);
const TopoDS_Shape& aF=aInOutMap.FindFromIndex(m);
//
if (aMSH.Contains(aF)) {
BOPCol_ListOfShape& aLH=aMSH.ChangeFromKey(aF);
aLH.Append(aHole);
}
else {
BOPCol_ListOfShape aLH;
aLH.Append(aHole);
aMSH.Add(aF, aLH);
}
}
//
// 5.2. Add unused holes to the original face
if (aNbHoles != aNbInOutMap) {
// Make the back map from faces to holes
BOPCol_IndexedDataMapOfShapeListOfShape aFaceHolesMap;
aNbH = aHoleFaceMap.Extent();
for (i = 1; i <= aNbH; ++i)
{
const TopoDS_Shape& aHole = aHoleFaceMap.FindKey(i);
const TopoDS_Shape& aFace = aHoleFaceMap(i);
//
BOPCol_ListOfShape* pLHoles = aFaceHolesMap.ChangeSeek(aFace);
if (!pLHoles)
pLHoles = &aFaceHolesMap(aFaceHolesMap.Add(aFace, BOPCol_ListOfShape()));
pLHoles->Append(aHole);
}
// Add unused holes to the original face
if (aHoleFaces.Extent() != aHoleFaceMap.Extent())
{
Bnd_Box aBoxF;
BRepBndLib::Add(myFace, aBoxF);
if (aBoxF.IsOpenXmin() || aBoxF.IsOpenXmax() ||
aBoxF.IsOpenYmin() || aBoxF.IsOpenYmax() ||
aBoxF.IsOpenZmin() || aBoxF.IsOpenZmax()) {
//
BOPCol_ListOfShape anUnUsedHoles;
for (m = 1; m <= aNbDMISB; ++m) {
const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
if (aSB2D.IsHole()) {
const TopoDS_Shape& aHole = aSB2D.Shape();
if (!aInOutMap.Contains(aHole)) {
anUnUsedHoles.Append(aHole);
}
}
aBoxF.IsOpenZmin() || aBoxF.IsOpenZmax())
{
TopoDS_Face aFace;
aBB.MakeFace(aFace, aS, aLoc, aTol);
BOPCol_ListOfShape& anUnUsedHoles = aFaceHolesMap(aFaceHolesMap.Add(aFace, BOPCol_ListOfShape()));
aNbH = aHoleFaces.Extent();
for (i = 1; i <= aNbH; ++i)
{
const TopoDS_Shape& aHole = aHoleFaces(i);
if (!aHoleFaceMap.Contains(aHole))
anUnUsedHoles.Append(aHole);
}
//
if (anUnUsedHoles.Extent()) {
aBB.MakeFace(aFace, aS, aLoc, aTol);
aMSH.Add(aFace, anUnUsedHoles);
//
BOPAlgo_ShapeBox2D aSB2D;
//
aSB2D.SetShape(aFace);
aSB2D.SetIsHole(Standard_False);
//
aDMISB.Add(aNbDMISB, aSB2D);
++aNbDMISB;
// Save it
aNewFaces.Append(aFace);
}
}
// Add Holes to Faces and add them to myAreas
aItLS.Initialize(aNewFaces);
for ( ; aItLS.More(); aItLS.Next())
{
TopoDS_Face& aFace = *(TopoDS_Face*)&aItLS.Value();
const BOPCol_ListOfShape* pLHoles = aFaceHolesMap.Seek(aFace);
if (pLHoles)
{
// update faces with the holes
BOPCol_ListIteratorOfListOfShape aItLH(*pLHoles);
for (; aItLH.More(); aItLH.Next())
{
const TopoDS_Shape& aFHole = aItLH.Value();
// The hole face contains only one wire
TopoDS_Iterator aItW(aFHole);
aBB.Add(aFace, aItW.Value());
}
// update classifier
myContext->FClass2d(aFace).Init(aFace, aTol);
}
}
//
// 6. Add aHoles to Faces
aNbMSH=aMSH.Extent();
for (m=1; m<=aNbMSH; ++m) {
TopoDS_Face aF=(*(TopoDS_Face *)(&aMSH.FindKey(m)));
const BOPCol_ListOfShape& aLH=aMSH.FindFromIndex(m);
//
aIt1.Initialize(aLH);
for (; aIt1.More(); aIt1.Next()) {
TopoDS_Shape aWHole;
//
const TopoDS_Shape& aFHole=aIt1.Value();
GetWire(aFHole, aWHole);
aBB.Add (aF, aWHole);
}
//
// update classifier
aTol=BRep_Tool::Tolerance(aF);
IntTools_FClass2d& aClsf=myContext->FClass2d(aF);
aClsf.Init(aF, aTol);
}
//
// 7. Fill myAreas
// NB:These aNewFaces are draft faces that
// do not contain any internal shapes
for (m=1; m<=aNbDMISB; ++m) {
const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
bIsHole=aSB2D.IsHole();
if (!bIsHole) {
const TopoDS_Shape aF=aSB2D.Shape();
myAreas.Append(aF);
}
}
}
//=======================================================================
//function : GetWire
//purpose :
//=======================================================================
void GetWire(const TopoDS_Shape& aF, TopoDS_Shape& aW)
{
TopoDS_Shape aWx;
TopoDS_Iterator aIt;
//
aIt.Initialize(aF);
for (; aIt.More(); aIt.Next()) {
aW=aIt.Value();
// The face is just a draft that does not contain any internal shapes
myAreas.Append(aFace);
}
}
//=======================================================================
@@ -851,18 +754,14 @@ Standard_Boolean IsInside(const TopoDS_Shape& theHole,
Standard_Boolean IsGrowthWire(const TopoDS_Shape& theWire,
const BOPCol_IndexedMapOfShape& theMHE)
{
Standard_Boolean bRet;
TopoDS_Iterator aIt;
//
bRet=Standard_False;
if (theMHE.Extent()) {
aIt.Initialize(theWire);
for(; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aE=aIt.Value();
if (theMHE.Contains(aE)) {
return !bRet;
}
if (theMHE.Extent())
{
TopoDS_Iterator aIt(theWire);
for(; aIt.More(); aIt.Next())
{
if (theMHE.Contains(aIt.Value()))
return Standard_True;
}
}
return bRet;
return Standard_False;
}

View File

@@ -77,57 +77,6 @@ static
void MakeInternalShells(const BOPCol_IndexedMapOfShape& ,
BOPCol_ListOfShape& );
//=======================================================================
//class : BOPAlgo_BuilderSolid_ShapeBox
//purpose : Auxiliary class
//=======================================================================
class BOPAlgo_BuilderSolid_ShapeBox {
public:
BOPAlgo_BuilderSolid_ShapeBox() {
myIsHole=Standard_False;
};
//
~BOPAlgo_BuilderSolid_ShapeBox() {
};
//
void SetShape(const TopoDS_Shape& aS) {
myShape=aS;
};
//
const TopoDS_Shape& Shape()const {
return myShape;
};
//
void SetBox(const Bnd_Box& aBox) {
myBox=aBox;
};
//
const Bnd_Box& Box()const {
return myBox;
};
//
void SetIsHole(const Standard_Boolean bFlag) {
myIsHole=bFlag;
};
//
Standard_Boolean IsHole()const {
return myIsHole;
};
//
protected:
Standard_Boolean myIsHole;
TopoDS_Shape myShape;
Bnd_Box myBox;
};
//
typedef NCollection_DataMap
<Standard_Integer,
BOPAlgo_BuilderSolid_ShapeBox,
TColStd_MapIntegerHasher> BOPAlgo_DataMapOfIntegerBSSB;
//
typedef BOPAlgo_DataMapOfIntegerBSSB::Iterator
BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB;
//
//=======================================================================
//function : BOPAlgo_FacePnt
//purpose :
@@ -300,6 +249,9 @@ void BOPAlgo_BuilderSolid::Perform()
{
GetReport()->Clear();
//
if (myShapes.IsEmpty())
return;
if (myContext.IsNull()) {
myContext=new IntTools_Context;
}
@@ -572,178 +524,158 @@ void BOPAlgo_BuilderSolid::PerformLoops()
//=======================================================================
void BOPAlgo_BuilderSolid::PerformAreas()
{
Standard_Boolean bIsGrowth, bIsHole;
Standard_Integer i, k, aNbInOut, aNbMSH;
BRep_Builder aBB;
BOPCol_ListIteratorOfListOfShape aItLS;
BOPCol_ListOfShape aNewSolids, aHoleShells;
BOPCol_IndexedDataMapOfShapeShape aInOutMap;
BOPCol_IndexedMapOfShape aMHF;
BOPCol_ListIteratorOfListOfInteger aItLI;
BOPCol_BoxBndTreeSelector aSelector;
BOPCol_BoxBndTree aBBTree;
NCollection_UBTreeFiller
<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
BOPAlgo_DataMapOfIntegerBSSB aDMISB(100);
BOPCol_IndexedDataMapOfShapeListOfShape aMSH;
BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB aItDMISB;
//
myAreas.Clear();
//
// Draft solids [aNewSolids]
aItLS.Initialize(myLoops);
for (k=0; aItLS.More(); aItLS.Next(), ++k) {
TopoDS_Solid aSolid;
Bnd_Box aBox;
BOPAlgo_BuilderSolid_ShapeBox aSB;
//
const TopoDS_Shape& aShell = aItLS.Value();
aSB.SetShape(aShell);
//
BRepBndLib::Add(aShell, aBox);
bIsHole=Standard_False;
//
bIsGrowth=IsGrowthShell(aShell, aMHF);
if (bIsGrowth) {
// make a growth solid from a shell
BRep_Builder aBB;
// The new solids
BOPCol_ListOfShape aNewSolids;
// The hole shells which has to be classified relatively new solids
BOPCol_IndexedMapOfShape aHoleShells;
// Map of the faces of the hole shells for quick check of the growths.
// If the analyzed shell contains any of the hole faces, it is considered as growth.
BOPCol_IndexedMapOfShape aMHF;
// Analyze the shells
BOPCol_ListIteratorOfListOfShape aItLL(myLoops);
for (; aItLL.More(); aItLL.Next())
{
const TopoDS_Shape& aShell = aItLL.Value();
Standard_Boolean bIsGrowth = IsGrowthShell(aShell, aMHF);
if (!bIsGrowth)
{
// Fast check did not give the result, run classification
bIsGrowth = !IsHole(aShell, myContext);
}
// Save the solid
if (bIsGrowth)
{
TopoDS_Solid aSolid;
aBB.MakeSolid(aSolid);
aBB.Add (aSolid, aShell);
//
aNewSolids.Append (aSolid);
aSB.SetShape(aSolid);
}
else{
// check if a shell is a hole
bIsHole=IsHole(aShell, myContext);
if (bIsHole) {
aHoleShells.Append(aShell);
BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF);
aSB.SetShape(aShell);
}
else {
// make a growth solid from a shell
aBB.MakeSolid(aSolid);
aBB.Add (aSolid, aShell);
//
aNewSolids.Append (aSolid);
aSB.SetShape(aSolid);
}
}
//
aSB.SetBox(aBox);
aSB.SetIsHole(bIsHole);
aDMISB.Bind(k, aSB);
}
//
// 2. Prepare TreeFiller
aItDMISB.Initialize(aDMISB);
for (; aItDMISB.More(); aItDMISB.Next()) {
k=aItDMISB.Key();
const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
//
bIsHole=aSB.IsHole();
if (bIsHole) {
const Bnd_Box& aBox=aSB.Box();
aTreeFiller.Add(k, aBox);
else
{
aHoleShells.Add(aShell);
BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF);
}
}
//
// 3. Shake TreeFiller
if (aHoleShells.IsEmpty())
{
// No holes, stop the analysis
myAreas.Append(aNewSolids);
return;
}
// Classify holes relatively solids
// Prepare tree filler with the boxes of the hole shells
BOPCol_BoxBndTree aBBTree;
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
Standard_Integer i, aNbH = aHoleShells.Extent();
for (i = 1; i <= aNbH; ++i)
{
const TopoDS_Shape& aHShell = aHoleShells(i);
//
Bnd_Box aBox;
BRepBndLib::Add(aHShell, aBox);
aTreeFiller.Add(i, aBox);
}
// Shake TreeFiller
aTreeFiller.Fill();
//
// 4. Find outer growth shell that is most close
// to each hole shell
aItDMISB.Initialize(aDMISB);
for (; aItDMISB.More(); aItDMISB.Next()) {
k=aItDMISB.Key();
const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
bIsHole=aSB.IsHole();
if (bIsHole) {
continue;
}
//
const TopoDS_Shape aSolid=aSB.Shape();
const Bnd_Box& aBoxSolid=aSB.Box();
//
aSelector.Clear();
aSelector.SetBox(aBoxSolid);
//
// Find outer growth shell that is most close to each hole shell
BOPCol_IndexedDataMapOfShapeShape aHoleSolidMap;
BOPCol_ListIteratorOfListOfShape aItLS(aNewSolids);
for (; aItLS.More(); aItLS.Next())
{
const TopoDS_Shape& aSolid = aItLS.Value();
// Build box
Bnd_Box aBox;
BRepBndLib::Add(aSolid, aBox);
BOPCol_BoxBndTreeSelector aSelector;
aSelector.SetBox(aBox);
aBBTree.Select(aSelector);
//
const BOPCol_ListOfInteger& aLI=aSelector.Indices();
//
aItLI.Initialize(aLI);
for (; aItLI.More(); aItLI.Next()) {
k=aItLI.Value();
const BOPAlgo_BuilderSolid_ShapeBox& aSBk=aDMISB.Find(k);
const TopoDS_Shape& aHole=aSBk.Shape();
//
if (!IsInside(aHole, aSolid, myContext)){
const BOPCol_ListOfInteger& aLI = aSelector.Indices();
BOPCol_ListIteratorOfListOfInteger aItLI(aLI);
for (; aItLI.More(); aItLI.Next())
{
Standard_Integer k = aItLI.Value();
const TopoDS_Shape& aHole = aHoleShells(k);
// Check if it is inside
if (!IsInside(aHole, aSolid, myContext))
continue;
}
//
if (aInOutMap.Contains (aHole)){
const TopoDS_Shape& aSolidWas = aInOutMap.FindFromKey(aHole);
if (IsInside(aSolid, aSolidWas, myContext)) {
aInOutMap.ChangeFromKey(aHole) = aSolid;
// Save the relation
TopoDS_Shape* pSolidWas = aHoleSolidMap.ChangeSeek(aHole);
if (pSolidWas)
{
if (IsInside(aSolid, *pSolidWas, myContext))
{
*pSolidWas = aSolid;
}
}
else{
aInOutMap.Add(aHole, aSolid);
else
{
aHoleSolidMap.Add(aHole, aSolid);
}
}
}//for (i = 1; i <= aNbDMISB; ++i) {
//
// 5. Map [Solid/Holes] -> aMSH
aNbInOut = aInOutMap.Extent();
for (i = 1; i <= aNbInOut; ++i) {
const TopoDS_Shape& aHole = aInOutMap.FindKey(i);
const TopoDS_Shape& aSolid = aInOutMap(i);
//
if (aMSH.Contains(aSolid)) {
BOPCol_ListOfShape& aLH = aMSH.ChangeFromKey(aSolid);
aLH.Append(aHole);
}
else {
BOPCol_ListOfShape aLH;
aLH.Append(aHole);
aMSH.Add(aSolid, aLH);
}
}
//
// 6. Add aHoles to Solids
aNbMSH = aMSH.Extent();
for (i = 1; i <= aNbMSH; ++i) {
TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&(aMSH.FindKey(i))));
const BOPCol_ListOfShape& aLH = aMSH(i);
//
aItLS.Initialize(aLH);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aHole = aItLS.Value();
aBB.Add (aSolid, aHole);
}
//
// update classifier
BRepClass3d_SolidClassifier& aSC=
myContext->SolidClassifier(aSolid);
aSC.Load(aSolid);
// Make the back map from solids to holes
BOPCol_IndexedDataMapOfShapeListOfShape aSolidHolesMap;
aNbH = aHoleSolidMap.Extent();
for (i = 1; i <= aNbH; ++i)
{
const TopoDS_Shape& aHole = aHoleSolidMap.FindKey(i);
const TopoDS_Shape& aSolid = aHoleSolidMap(i);
//
BOPCol_ListOfShape* pLHoles = aSolidHolesMap.ChangeSeek(aSolid);
if (!pLHoles)
pLHoles = &aSolidHolesMap(aSolidHolesMap.Add(aSolid, BOPCol_ListOfShape()));
pLHoles->Append(aHole);
}
//
// 7. These aNewSolids are draft solids that
// do not contain any internal shapes
// Add Holes to Solids and add them to myAreas
aItLS.Initialize(aNewSolids);
for ( ; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aSx=aItLS.Value();
myAreas.Append(aSx);
for ( ; aItLS.More(); aItLS.Next())
{
TopoDS_Solid& aSolid = *(TopoDS_Solid*)&aItLS.Value();
const BOPCol_ListOfShape* pLHoles = aSolidHolesMap.Seek(aSolid);
if (pLHoles)
{
// update solid
BOPCol_ListIteratorOfListOfShape aItLH(*pLHoles);
for (; aItLH.More(); aItLH.Next())
{
const TopoDS_Shape& aHole = aItLH.Value();
aBB.Add(aSolid, aHole);
}
// update classifier
myContext->SolidClassifier(aSolid).Load(aSolid);
}
myAreas.Append(aSolid);
}
// Add holes that outside the solids to myAreas
aItLS.Initialize(aHoleShells);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aHole = aItLS.Value();
if (!aInOutMap.Contains(aHole)){
aNbH = aHoleShells.Extent();
for (i = 1; i <= aNbH; ++i)
{
const TopoDS_Shape& aHole = aHoleShells(i);
if (!aHoleSolidMap.Contains(aHole))
{
TopoDS_Solid aSolid;
//
aBB.MakeSolid(aSolid);
aBB.Add (aSolid, aHole);
//
@@ -1073,18 +1005,14 @@ Standard_Boolean IsInside(const TopoDS_Shape& theS1,
Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
const BOPCol_IndexedMapOfShape& theMHF)
{
Standard_Boolean bRet;
TopoDS_Iterator aIt;
//
bRet=Standard_False;
if (theMHF.Extent()) {
aIt.Initialize(theShell);
for(; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value();
if (theMHF.Contains(aF)) {
return !bRet;
}
if (theMHF.Extent())
{
TopoDS_Iterator aIt(theShell);
for(; aIt.More(); aIt.Next())
{
if (theMHF.Contains(aIt.Value()))
return Standard_True;
}
}
return bRet;
return Standard_False;
}

View File

@@ -51,6 +51,7 @@
#include <Precision.hxx>
#include <IntTools_Context.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
@@ -62,6 +63,11 @@ static
Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
const BOPDS_FaceInfo& aFI2);
//
static
TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
const BOPCol_DataMapOfShapeListOfShape& theImages,
Handle(IntTools_Context)& theCtx);
//
typedef BOPCol_NCVector<TopoDS_Shape> BOPAlgo_VectorOfShape;
//
typedef BOPCol_NCVector<BOPAlgo_VectorOfShape> \
@@ -240,7 +246,6 @@ void BOPAlgo_Builder::BuildSplitFaces()
{
Standard_Boolean bHasFaceInfo, bIsClosed, bIsDegenerated, bToReverse;
Standard_Integer i, j, k, aNbS, aNbPBIn, aNbPBOn, aNbPBSc, aNbAV, nSp;
Standard_Size aNbBF;
TopoDS_Face aFF, aFSD;
TopoDS_Edge aSp, aEE;
TopAbs_Orientation anOriF, anOriE;
@@ -249,7 +254,6 @@ void BOPAlgo_Builder::BuildSplitFaces()
BOPCol_ListOfInteger aLIAV;
BOPCol_MapOfShape aMFence;
Handle(NCollection_BaseAllocator) aAllocator;
BOPCol_ListOfShape aLFIm(myAllocator);
BOPAlgo_VectorOfBuilderFace aVBF;
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~scope f
@@ -259,6 +263,10 @@ void BOPAlgo_Builder::BuildSplitFaces()
BOPCol_ListOfShape aLE(aAllocator);
BOPCol_MapOfShape aMDE(100, aAllocator);
//
// Build temporary map of faces images to avoid rebuilding
// of the faces without any IN or section edges
BOPCol_IndexedDataMapOfShapeListOfShape aFacesIm;
//
aNbS=myDS->NbSourceShapes();
//
for (i=0; i<aNbS; ++i) {
@@ -292,17 +300,32 @@ void BOPAlgo_Builder::BuildSplitFaces()
if (!aNbPBIn && !aNbPBOn && !aNbPBSc && !aNbAV) { // not compete
continue;
}
//
if (!aNbPBIn && !aNbPBSc)
{
// No internal parts for the face, so just build the draft face
// and keep it to pass directly into result.
// If the original face has any internal edges, the draft face
// will be null, as the internal edges may split the face on parts
// (as in the case "bugs modalg_5 bug25245_1").
// The BuilderFace algorithm will be called in this case.
TopoDS_Face aFD = BuildDraftFace(aF, myImages, myContext);
if (!aFD.IsNull())
{
aFacesIm(aFacesIm.Add(aF, BOPCol_ListOfShape())).Append(aFD);
continue;
}
}
aMFence.Clear();
//
anOriF=aF.Orientation();
aFF=aF;
aFF.Orientation(TopAbs_FORWARD);
//
// 1. Fill the egdes set for the face aFF -> LE
// 1. Fill the edges set for the face aFF -> LE
aLE.Clear();
//
//
// 1.1 Bounding edges
aExp.Init(aFF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
@@ -426,33 +449,33 @@ void BOPAlgo_Builder::BuildSplitFaces()
//
}// for (i=0; i<aNbS; ++i) {
//
aNbBF=aVBF.Extent();
//
//===================================================
BOPAlgo_BuilderFaceCnt::Perform(myRunParallel, aVBF);
//===================================================
//
for (k=0; k<(Standard_Integer)aNbBF; ++k) {
aLFIm.Clear();
Standard_Integer aNbBF = aVBF.Extent();
for (k = 0; k < aNbBF; ++k)
{
BOPAlgo_BuilderFace& aBF = aVBF(k);
aFacesIm.Add(aBF.Face(), aBF.Areas());
}
aNbBF = aFacesIm.Extent();
for (k = 1; k <= aNbBF; ++k)
{
const TopoDS_Face& aF = TopoDS::Face(aFacesIm.FindKey(k));
anOriF = aF.Orientation();
const BOPCol_ListOfShape& aLFR = aFacesIm(k);
//
BOPAlgo_BuilderFace& aBF=aVBF(k);
TopoDS_Face aF=aBF.Face();
anOriF=aBF.Orientation();
aF.Orientation(anOriF);
//
const BOPCol_ListOfShape& aLFR=aBF.Areas();
BOPCol_ListOfShape* pLFIm = mySplits.Bound(aF, BOPCol_ListOfShape());
aIt.Initialize(aLFR);
for (; aIt.More(); aIt.Next()) {
TopoDS_Shape& aFR=aIt.ChangeValue();
if (anOriF==TopAbs_REVERSED) {
if (anOriF==TopAbs_REVERSED)
aFR.Orientation(TopAbs_REVERSED);
}
//aFR.Orientation(anOriF);
aLFIm.Append(aFR);
pLFIm->Append(aFR);
}
//
mySplits.Bind(aF, aLFIm);
}// for (k=0; k<aNbBF; ++k) {
}
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~scope t
}
@@ -770,3 +793,98 @@ Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
}
return bRet;
}
//=======================================================================
//function : BuildDraftFace
//purpose : Build draft faces, updating the bounding edges,
// according to the information stored into the <theImages> map
//=======================================================================
TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
const BOPCol_DataMapOfShapeListOfShape& theImages,
Handle(IntTools_Context)& theCtx)
{
BRep_Builder aBB;
// Take the information from the original face
TopLoc_Location aLoc;
const Handle(Geom_Surface)& aS = BRep_Tool::Surface(theFace, aLoc);
const Standard_Real aTol = BRep_Tool::Tolerance(theFace);
// Make the new face, without any wires
TopoDS_Face aDraftFace;
aBB.MakeFace(aDraftFace, aS, aLoc, aTol);
// Update wires of the original face and add them to draft face
TopoDS_Iterator aItW(theFace.Oriented(TopAbs_FORWARD));
for (; aItW.More(); aItW.Next())
{
const TopoDS_Shape& aW = aItW.Value();
if (aW.ShapeType() != TopAbs_WIRE)
continue;
// Rebuild wire using images of edges
TopoDS_Iterator aItE(aW.Oriented(TopAbs_FORWARD));
if (!aItE.More())
continue;
TopoDS_Wire aNewWire;
aBB.MakeWire(aNewWire);
for (; aItE.More(); aItE.Next())
{
const TopoDS_Edge& aE = TopoDS::Edge(aItE.Value());
TopAbs_Orientation anOriE = aE.Orientation();
if (anOriE == TopAbs_INTERNAL)
{
// The internal edges could split the original face on halves.
// Thus, use the BuilderFace algorithm to build the new face.
TopoDS_Face aNull;
return aNull;
}
const BOPCol_ListOfShape* pLEIm = theImages.Seek(aE);
if (!pLEIm)
{
aBB.Add(aNewWire, aE);
continue;
}
// Check if the original edge is degenerated
Standard_Boolean bIsDegenerated = BRep_Tool::Degenerated(aE);
// Check if the original edge is closed on the face
Standard_Boolean bIsClosed = BRep_Tool::IsClosed(aE, theFace);
BOPCol_ListIteratorOfListOfShape aItLEIm(*pLEIm);
for (; aItLEIm.More(); aItLEIm.Next())
{
TopoDS_Edge& aSp = TopoDS::Edge(aItLEIm.Value());
aSp.Orientation(anOriE);
if (bIsDegenerated)
{
aBB.Add(aNewWire, aSp);
continue;
}
// Check closeness of the split edge and if it is not
// make the second PCurve
if (bIsClosed && !BRep_Tool::IsClosed(aSp, theFace))
BOPTools_AlgoTools3D::DoSplitSEAMOnFace(aSp, theFace);
// Check if the split should be reversed
if (BOPTools_AlgoTools::IsSplitToReverse(aSp, aE, theCtx))
aSp.Reverse();
aBB.Add(aNewWire, aSp);
}
}
aNewWire.Orientation(aW.Orientation());
aNewWire.Closed(BRep_Tool::IsClosed(aNewWire));
aBB.Add(aDraftFace, aNewWire);
}
if (theFace.Orientation() == TopAbs_REVERSED)
aDraftFace.Reverse();
return aDraftFace;
}

View File

@@ -222,12 +222,11 @@ class BOPAlgo_FillIn3DParts : public BOPAlgo_Algo {
const Handle(NCollection_BaseAllocator)& );
void MakeConnexityBlock
(const BOPCol_ListOfShape& ,
(const TopoDS_Face& ,
const BOPCol_IndexedMapOfShape& ,
const BOPCol_MapOfShape& ,
const BOPCol_IndexedDataMapOfShapeListOfShape& ,
BOPCol_ListOfShape& ,
const Handle(NCollection_BaseAllocator)& );
BOPCol_MapOfShape& ,
BOPCol_ListOfShape& );
//
protected:
TopoDS_Solid mySolid;
@@ -257,14 +256,13 @@ void BOPAlgo_FillIn3DParts::Perform()
//
Standard_Integer aNbFP, k, nFP, iIsIN;
Standard_Real aTolPC;
BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1;
BOPCol_ListIteratorOfListOfInteger aItLI;
BOPCol_ListIteratorOfListOfShape aItLS;
BOPCol_BoxBndTreeSelector aSelector;
//
aAlr1=
NCollection_BaseAllocator::CommonBaseAllocator();
//
BOPCol_ListOfShape aLFP(aAlr1);
BOPCol_ListOfShape aLCBF(aAlr1);
BOPCol_MapOfShape aMFDone(100, aAlr1);
BOPCol_IndexedMapOfShape aME(100, aAlr1);
@@ -334,28 +332,16 @@ void BOPAlgo_FillIn3DParts::Perform()
iIsIN=BOPTools_AlgoTools::IsInternalFace
(aFP, myDraftSolid, aMEF, aTolPC, myContext);
//
aLFP.Clear();
aLFP.Append(aFP);
//
aItLI1.Initialize(aLIFP);
for (; aItLI1.More(); aItLI1.Next()) {
const TopoDS_Shape& aFx=aVSB(aItLI1.Value()).Shape();
if (!aMFDone.Contains(aFx)) {
aLFP.Append(aFx);
}
}
//
// Make connexity blocks of faces, avoiding passing through the
// borders of the solid.
// It helps to reduce significantly the number of classified faces.
aLCBF.Clear();
MakeConnexityBlock(aFP, aME, aMEFP, aMFDone, aLCBF);
//
MakeConnexityBlock(aLFP, aME, aMFDone, aMEFP, aLCBF, aAlr1);
//
aItLS.Initialize(aLCBF);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aFx=aItLS.Value();
aMFDone.Add(aFx);
if (iIsIN) {
myLFIN.Append(aFx);
}
if (iIsIN) {
aItLS.Initialize(aLCBF);
for (; aItLS.More(); aItLS.Next())
myLFIN.Append(aItLS.Value());
}
} // for (k=0; k<aNbFP; ++k) {
}
@@ -379,16 +365,10 @@ void BOPAlgo_FillIn3DParts::MapEdgesAndFaces
for (; myItW.More(); myItW.Next()) {
const TopoDS_Shape& aE=myItW.Value();
//
if (aMEF.Contains(aE)) {
BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
aLF.Append(aF);
}
else {
BOPCol_ListOfShape aLS(theAllocator);
//
aLS.Append(aF);
aMEF.Add(aE, aLS);
}
BOPCol_ListOfShape* pLF = aMEF.ChangeSeek(aE);
if (!pLF)
pLF = &aMEF(aMEF.Add(aE, BOPCol_ListOfShape(theAllocator)));
pLF->Append(aF);
}
}
}
@@ -396,84 +376,44 @@ void BOPAlgo_FillIn3DParts::MapEdgesAndFaces
// function: MakeConnexityBlock
// purpose:
//=======================================================================
void BOPAlgo_FillIn3DParts::MakeConnexityBlock
(const BOPCol_ListOfShape& theLFIn,
void BOPAlgo_FillIn3DParts::MakeConnexityBlock
(const TopoDS_Face& theFStart,
const BOPCol_IndexedMapOfShape& theMEAvoid,
const BOPCol_MapOfShape& aMFDone,
const BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
BOPCol_ListOfShape& theLCB,
const Handle(NCollection_BaseAllocator)& theAlr)
const BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
BOPCol_MapOfShape& theMFDone,
BOPCol_ListOfShape& theLCB)
{
Standard_Integer aNbF, aNbAdd1, aNbAdd, i;
BOPCol_ListIteratorOfListOfShape aIt;
//
BOPCol_IndexedMapOfShape aMCB(100, theAlr);
BOPCol_IndexedMapOfShape aMAdd(100, theAlr);
BOPCol_IndexedMapOfShape aMAdd1(100, theAlr);
//
aNbF=theLFIn.Extent();
//
// 2. aMCB
const TopoDS_Shape& aF1=theLFIn.First();
aMAdd.Add(aF1);
//
for(;;) {
aMAdd1.Clear();
aNbAdd = aMAdd.Extent();
for (i=1; i<=aNbAdd; ++i) {
const TopoDS_Shape& aF=aMAdd(i);
//
myItF.Initialize(aF);
for (; myItF.More(); myItF.Next()) {
const TopoDS_Shape& aW=myItF.Value();
if (aW.ShapeType()!=TopAbs_WIRE) {
// Add start element
theLCB.Append(theFStart);
BOPCol_ListIteratorOfListOfShape aItCB(theLCB);
for (; aItCB.More(); aItCB.Next())
{
const TopoDS_Shape& aF = aItCB.Value();
myItF.Initialize(aF);
for (; myItF.More(); myItF.Next())
{
const TopoDS_Shape& aW = myItF.Value();
if (aW.ShapeType() != TopAbs_WIRE)
continue;
myItW.Initialize(aW);
for (; myItW.More(); myItW.Next())
{
const TopoDS_Shape& aE = myItW.Value();
if (theMEAvoid.Contains(aE))
continue;
const BOPCol_ListOfShape& aLF = theMEF.FindFromKey(aE);
BOPCol_ListIteratorOfListOfShape aItLF(aLF);
for (; aItLF.More(); aItLF.Next())
{
const TopoDS_Shape& aFx = aItLF.Value();
if (!aFx.IsSame(aF) && theMFDone.Add(aFx))
theLCB.Append(aFx);
}
//
myItW.Initialize(aW);
for (; myItW.More(); myItW.Next()) {
const TopoDS_Shape& aE=myItW.Value();
if (theMEAvoid.Contains(aE)){
continue;
}
//
const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
aIt.Initialize(aLF);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aFx=aIt.Value();
if (aFx.IsSame(aF)) {
continue;
}
if (aMCB.Contains(aFx)) {
continue;
}
if (aMFDone.Contains(aFx)) {
continue;
}
aMAdd1.Add(aFx);
}
}// for (; myItW.More(); myItW.Next()) {
}// for (; myItF.More(); myItF.Next()) {
aMCB.Add(aF);
}// for (i=1; i<=aNbAdd; ++i) {
//
aNbAdd1=aMAdd1.Extent();
if (!aNbAdd1) {
break;
}
}
//
aMAdd.Clear();
for (i=1; i<=aNbAdd1; ++i) {
const TopoDS_Shape& aFAdd=aMAdd1(i);
aMAdd.Add(aFAdd);
}
//
}//while(1) {
//
aNbF=aMCB.Extent();
for (i=1; i<=aNbF; ++i) {
const TopoDS_Shape& aF=aMCB(i);
theLCB.Append(aF);
}
}
//
@@ -616,7 +556,7 @@ void BOPAlgo_Builder::FillIn3DParts
BOPAlgo_VectorOfFillIn3DParts aVFIP;
//
for (i=0; i<aNbS; ++i) {
const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
BOPDS_ShapeInfo& aSI=myDS->ChangeShapeInfo(i);
if (aSI.ShapeType()!=TopAbs_SOLID) {
continue;
}
@@ -636,8 +576,9 @@ void BOPAlgo_Builder::FillIn3DParts
}
//
// 2.1 Bounding box for the solid aS [ aBoxS ]
Bnd_Box aBoxS;
aBoxS=aSI.Box();
Bnd_Box& aBoxS = aSI.ChangeBox();
if (aBoxS.IsVoid())
myDS->BuildBndBoxSolid(i, aBoxS, myCheckInverted);
//
// 2.2 Build Draft Solid [aSD]
BOPCol_ListOfShape aLIF;
@@ -830,34 +771,41 @@ void BOPAlgo_Builder::BuildSplitSolids
//
} //for (i=1; i<=aNbS; ++i)
//
// 1. Build solids for interferred source solids
for (i=0; i<aNbS; ++i) {
const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
//
if (aSI.ShapeType()!=TopAbs_SOLID) {
// Build temporary map of solids images to avoid rebuilding
// of the solids without internal faces
BOPCol_IndexedDataMapOfShapeListOfShape aSolidsIm;
// 1. Build solids for interfered source solids
for (i = 0; i < aNbS; ++i) {
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
if (aSI.ShapeType() != TopAbs_SOLID)
continue;
}
//
const TopoDS_Shape& aS=aSI.Shape();
const TopoDS_Shape& aS = aSI.Shape();
const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
if(!theDraftSolids.IsBound(aS)) {
if (!theDraftSolids.IsBound(aS))
continue;
const TopoDS_Shape& aSD = theDraftSolids.Find(aS);
const BOPCol_ListOfShape* pLFIN = theInParts.Seek(aS);
if (!pLFIN)
{
aSolidsIm(aSolidsIm.Add(aS, BOPCol_ListOfShape())).Append(aSD);
continue;
}
const TopoDS_Shape& aSD=theDraftSolids.Find(aS);
const BOPCol_ListOfShape& aLFIN=
(theInParts.IsBound(aS)) ? theInParts.Find(aS) : aLSEmpty;
aSFS.Clear();
//
// 1.1 Fill Shell Faces Set
aSFS.Clear();
aExp.Init(aSD, TopAbs_FACE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aF=aExp.Current();
const TopoDS_Shape& aF = aExp.Current();
aSFS.Append(aF);
}
//
aIt.Initialize(aLFIN);
// 1.2 Fill internal faces
aIt.Initialize(*pLFIN);
for (; aIt.More(); aIt.Next()) {
TopoDS_Shape aF=aIt.Value();
TopoDS_Shape aF = aIt.Value();
//
aF.Orientation(TopAbs_FORWARD);
aSFS.Append(aF);
@@ -865,7 +813,7 @@ void BOPAlgo_Builder::BuildSplitSolids
aSFS.Append(aF);
}
//
// 1.3 Build new solids
// 1.3 Build new solids
BOPAlgo_BuilderSolid& aBS=aVBS.Append1();
aBS.SetSolid(aSolid);
aBS.SetShapes(aSFS);
@@ -881,10 +829,18 @@ void BOPAlgo_Builder::BuildSplitSolids
BOPAlgo_BuilderSolidCnt::Perform(myRunParallel, aVBS);
//===================================================
//
for (k=0; k<aNbBS; ++k) {
BOPAlgo_BuilderSolid& aBS=aVBS(k);
const TopoDS_Solid& aS=aBS.Solid();
const BOPCol_ListOfShape& aLSR=aBS.Areas();
for (k = 0; k < aNbBS; ++k)
{
BOPAlgo_BuilderSolid& aBS = aVBS(k);
aSolidsIm.Add(aBS.Solid(), aBS.Areas());
}
//
// Add new solids to images map
aNbBS = aSolidsIm.Extent();
for (k = 1; k <= aNbBS; ++k)
{
const TopoDS_Shape& aS = aSolidsIm.FindKey(k);
const BOPCol_ListOfShape& aLSR = aSolidsIm(k);
//
if (!myImages.IsBound(aS)) {
BOPCol_ListOfShape* pLSx = myImages.Bound(aS, BOPCol_ListOfShape());

View File

@@ -159,16 +159,16 @@ void BOPAlgo_CheckerSI::Init()
myDS->SetArguments(myArguments);
myDS->Init(myFuzzyValue);
//
// 2.myIterator
// 2 myContext
myContext=new IntTools_Context;
//
// 3.myIterator
BOPDS_PIteratorSI theIterSI=new BOPDS_IteratorSI(myAllocator);
theIterSI->SetDS(myDS);
theIterSI->Prepare();
theIterSI->Prepare(myContext, myUseOBB);
theIterSI->UpdateByLevelOfCheck(myLevelOfCheck);
//
myIterator=theIterSI;
//
// 3 myContext
myContext=new IntTools_Context;
}
//=======================================================================
//function : Perform

View File

@@ -94,6 +94,7 @@ void BOPAlgo_MakerVolume::Perform()
pPF->SetFuzzyValue(myFuzzyValue);
pPF->SetNonDestructive(myNonDestructive);
pPF->SetGlue(myGlue);
pPF->SetUseOBB(myUseOBB);
pPF->Perform();
//
myEntryPoint = 1;

View File

@@ -50,7 +50,9 @@ BOPAlgo_Options::BOPAlgo_Options()
myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
myReport(new Message_Report),
myRunParallel(myGlobalRunParallel),
myFuzzyValue(Precision::Confusion())
myFuzzyValue(Precision::Confusion()),
myCheckInverted(Standard_True),
myUseOBB(Standard_False)
{
BOPAlgo_LoadMessages();
}
@@ -65,7 +67,9 @@ BOPAlgo_Options::BOPAlgo_Options
myAllocator(theAllocator),
myReport(new Message_Report),
myRunParallel(myGlobalRunParallel),
myFuzzyValue(Precision::Confusion())
myFuzzyValue(Precision::Confusion()),
myCheckInverted(Standard_True),
myUseOBB(Standard_False)
{
BOPAlgo_LoadMessages();
}

View File

@@ -32,6 +32,12 @@ class Message_ProgressIndicator;
//! touching or coinciding cases;
//! - *Progress indicator* - provides interface to track the progress of
//! operation and stop the operation by user's break.
//! - *Disabling the check for inverted solids* - Disables/Enables the check of the input solids
//! for inverted status (holes in the space). The default value is TRUE,
//! i.e. the check is performed. Setting this flag to FALSE for inverted solids,
//! most likely will lead to incorrect results.
//! - *Using the Oriented Bounding Boxes* - Allows using the Oriented Bounding Boxes of the shapes
//! for filtering the intersections.
//!
class BOPAlgo_Options
{
@@ -156,6 +162,37 @@ public:
//! Set the Progress Indicator object.
Standard_EXPORT void SetProgressIndicator(const Handle(Message_ProgressIndicator)& theObj);
public:
//!@name Check input solids for inverted status
//! Enables/Disables the check of the input solids for inverted status
void SetCheckInverted(const Standard_Boolean theCheck)
{
myCheckInverted = theCheck;
}
//! Returns the flag defining whether the check for input solids on inverted status
//! should be performed or not.
Standard_Boolean CheckInverted() const
{
return myCheckInverted;
}
public:
//!@name Usage of Oriented Bounding boxes
//! Enables/Disables the usage of OBB
void SetUseOBB(const Standard_Boolean theUseOBB)
{
myUseOBB = theUseOBB;
}
//! Returns the flag defining usage of OBB
Standard_Boolean UseOBB() const
{
return myUseOBB;
}
protected:
//! Breaks the execution if the break signal
@@ -169,6 +206,8 @@ protected:
Standard_Boolean myRunParallel;
Standard_Real myFuzzyValue;
Handle(Message_ProgressIndicator) myProgressIndicator;
Standard_Boolean myCheckInverted;
Standard_Boolean myUseOBB;
};

View File

@@ -211,14 +211,14 @@ void BOPAlgo_PaveFiller::Init()
myDS->SetArguments(myArguments);
myDS->Init(myFuzzyValue);
//
// 2.myIterator
// 2 myContext
myContext=new IntTools_Context;
//
// 3.myIterator
myIterator=new BOPDS_Iterator(myAllocator);
myIterator->SetRunParallel(myRunParallel);
myIterator->SetDS(myDS);
myIterator->Prepare();
//
// 3 myContext
myContext=new IntTools_Context;
myIterator->Prepare(myContext, myUseOBB);
//
// 4 NonDestructive flag
SetNonDestructive();

View File

@@ -198,34 +198,56 @@ void BOPAlgo_PaveFiller::PerformFF()
//
for (; myIterator->More(); myIterator->Next()) {
myIterator->Value(nF1, nF2);
//
const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
//
if (aMIFence.Add(nF1)) {
myDS->UpdateFaceInfoOn(nF1);
myDS->UpdateFaceInfoIn(nF1);
}
if (aMIFence.Add(nF2)) {
myDS->UpdateFaceInfoOn(nF2);
myDS->UpdateFaceInfoIn(nF2);
}
//
const BRepAdaptor_Surface& aBAS1 = myContext->SurfaceAdaptor(aF1);
const BRepAdaptor_Surface& aBAS2 = myContext->SurfaceAdaptor(aF2);
if (aBAS1.GetType() == GeomAbs_Plane &&
aBAS2.GetType() == GeomAbs_Plane) {
// Check if the planes are really interfering
Standard_Boolean bToIntersect = CheckPlanes(nF1, nF2);
if (!bToIntersect) {
BOPDS_InterfFF& aFF=aFFs.Append1();
aFF.SetIndices(nF1, nF2);
aFF.Init(0, 0);
continue;
// Update/Initialize FaceInfo structure for first face
if (myDS->HasFaceInfo(nF1))
{
if (aMIFence.Add(nF1))
{
myDS->UpdateFaceInfoOn(nF1);
myDS->UpdateFaceInfoIn(nF1);
}
}
else if (myDS->HasInterfShapeSubShapes(nF2, nF1))
{
myDS->ChangeFaceInfo(nF1);
aMIFence.Add(nF1);
}
// Update/Initialize FaceInfo structure for second face
if (myDS->HasFaceInfo(nF2))
{
if (aMIFence.Add(nF2))
{
myDS->UpdateFaceInfoOn(nF2);
myDS->UpdateFaceInfoIn(nF2);
}
}
else if (myDS->HasInterfShapeSubShapes(nF1, nF2))
{
myDS->ChangeFaceInfo(nF2);
aMIFence.Add(nF2);
}
//
if (myGlue == BOPAlgo_GlueOff) {
if (myGlue == BOPAlgo_GlueOff)
{
const TopoDS_Face& aF1 = (*(TopoDS_Face *)(&myDS->Shape(nF1)));
const TopoDS_Face& aF2 = (*(TopoDS_Face *)(&myDS->Shape(nF2)));
//
const BRepAdaptor_Surface& aBAS1 = myContext->SurfaceAdaptor(aF1);
const BRepAdaptor_Surface& aBAS2 = myContext->SurfaceAdaptor(aF2);
if (aBAS1.GetType() == GeomAbs_Plane &&
aBAS2.GetType() == GeomAbs_Plane) {
// Check if the planes are really interfering
Standard_Boolean bToIntersect = CheckPlanes(nF1, nF2);
if (!bToIntersect) {
BOPDS_InterfFF& aFF = aFFs.Append1();
aFF.SetIndices(nF1, nF2);
aFF.Init(0, 0);
continue;
}
}
//
BOPAlgo_FaceFace& aFaceFace=aVFaceFace.Append1();
//
aFaceFace.SetIndices(nF1, nF2);

View File

@@ -42,12 +42,6 @@ static
void RefineShell(TopoDS_Shell& theShell,
const BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
BOPCol_ListOfShape& aLShX);
//
static
void MapEdgesAndFaces
(const TopoDS_Shape& aF,
BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
const Handle(NCollection_BaseAllocator)& theAllocator);
//=======================================================================
//class : BOPAlgo_CBK
@@ -152,162 +146,12 @@ void BOPAlgo_ShellSplitter::Perform()
{
GetReport()->Clear();
//
MakeConnexityBlocks();
if (HasErrors()) {
return;
}
BOPTools_AlgoTools::MakeConnexityBlocks
(myStartShapes, TopAbs_EDGE, TopAbs_FACE, myLCB);
//
MakeShells();
}
//=======================================================================
//function : MakeConnexityBlocks
//purpose :
//=======================================================================
void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
{
Standard_Boolean bRegular;
Standard_Integer i, j, aNbE, aNbES, aNbEP, k, aNbCB;
TopoDS_Shape aFR;
TopoDS_Iterator aItF, aItW;
BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, myAllocator);
BOPCol_IndexedMapOfShape aMEP(100, myAllocator);
BOPCol_IndexedMapOfShape aMFC(100, myAllocator);
BOPCol_MapOfShape aMER(100, myAllocator);
BOPCol_MapOfShape aMFP(100, myAllocator);
BOPCol_IndexedMapOfShape aMEAdd(100, myAllocator);
BOPCol_MapOfShape aMES(100, myAllocator);
BOPCol_ListIteratorOfListOfShape aIt;
//
myLCB.Clear();
//
const BOPCol_ListOfShape& aLSE=myStartShapes;
aIt.Initialize(aLSE);
for (i=1; aIt.More(); aIt.Next(), ++i) {
const TopoDS_Shape& aSE=aIt.Value();
if (!aMEP.Contains(aSE)) {
aMEP.Add(aSE);
MapEdgesAndFaces(aSE, aMEF, myAllocator);
}
else {
aMER.Add(aSE);
}
}
//
// 2
aNbE=aMEF.Extent();
for (i=1; i<=aNbE; ++i) {
aNbES=aMES.Extent();
if (aNbES==aNbE) {
break;
}
//
const TopoDS_Shape& aE=aMEF.FindKey(i);
//
if (!aMES.Add(aE)) {
continue;
}
// aMES - globally processed edges
//
//------------------------------------- goal: aMEC
aMFC.Clear(); // aMEC - edges of CB
aMEP.Clear(); // aMVP - edges to process right now
aMEAdd.Clear(); // aMVAdd edges to process on next step of for(;;) {
//
aMEP.Add(aE);
//
for(;;) {
aNbEP=aMEP.Extent();
for (k=1; k<=aNbEP; ++k) {
const TopoDS_Shape& aEP=aMEP(k);
const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aEP);
aIt.Initialize(aLF);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value();
if (aMFC.Add(aF)) {
aItF.Initialize(aF);
while (aItF.More()) {
const TopoDS_Shape& aW=aItF.Value();
if (aW.ShapeType()!=TopAbs_WIRE) {
aItF.Next();
continue;
}
//
aItW.Initialize(aW);
while (aItW.More()) {
const TopoDS_Shape& aEF=aItW.Value();
//
if (aMES.Add(aEF)) {
aMEAdd.Add(aEF);
}
//
aItW.Next();
}
//
aItF.Next();
}
}
}
}
//
aNbEP=aMEAdd.Extent();
if (!aNbEP) {
break; // from for(;;) {
}
//
aMEP.Clear();
//
for (k=1; k<=aNbEP; ++k) {
const TopoDS_Shape& aEF=aMEAdd(k);
aMEP.Add(aEF);
}
aMEAdd.Clear();
}// for(;;) {
//
//-------------------------------------
BOPTools_ConnexityBlock aCB(myAllocator);
//
BOPCol_ListOfShape& aLECB=aCB.ChangeShapes();
BOPCol_IndexedDataMapOfShapeListOfShape aMEFR(100, myAllocator);
//
bRegular=Standard_True;
aNbCB = aMFC.Extent();
for (j=1; j<=aNbCB; ++j) {
aFR = aMFC(j);
//
if (aMER.Contains(aFR)) {
aFR.Orientation(TopAbs_FORWARD);
aLECB.Append(aFR);
aFR.Orientation(TopAbs_REVERSED);
aLECB.Append(aFR);
bRegular=Standard_False;
}
else {
aLECB.Append(aFR);
}
//
if (bRegular) {
MapEdgesAndFaces(aFR, aMEFR, myAllocator);
}
}
//
if (bRegular) {
Standard_Integer aNbER, aNbFR;
//
aNbER=aMEFR.Extent();
for (k=1; k<=aNbER; ++k) {
const BOPCol_ListOfShape& aLFR=aMEFR(k);
aNbFR=aLFR.Extent();
if (aNbFR>2) {
bRegular=!bRegular;
break;
}
}
}
//
aCB.SetRegular(bRegular);
myLCB.Append(aCB);
}
}
//=======================================================================
//function : SplitBlock
//purpose :
@@ -750,43 +594,3 @@ void MakeShell(const BOPCol_ListOfShape& aLS,
//
BOPTools_AlgoTools::OrientFacesOnShell(aShell);
}
//=======================================================================
// function: MapEdgesAndFaces
// purpose:
//=======================================================================
void MapEdgesAndFaces
(const TopoDS_Shape& aF,
BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
const Handle(NCollection_BaseAllocator)& theAllocator)
{
TopoDS_Iterator aItF, aItW;
//
aItF.Initialize(aF);
while (aItF.More()) {
const TopoDS_Shape& aW=aItF.Value();
if (aW.ShapeType()!=TopAbs_WIRE) {
aItF.Next();
continue;
}
//
aItW.Initialize(aW);
while (aItW.More()) {
const TopoDS_Shape& aE=aItW.Value();
//
if (aMEF.Contains(aE)) {
BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
aLF.Append(aF);
}
else {
BOPCol_ListOfShape aLS(theAllocator);
//
aLS.Append(aF);
aMEF.Add(aE, aLS);
}
//
aItW.Next();
}
//
aItF.Next();
}
}

View File

@@ -61,8 +61,6 @@ Standard_EXPORT virtual ~BOPAlgo_ShellSplitter();
protected:
Standard_EXPORT void MakeConnexityBlocks();
Standard_EXPORT void MakeShells();

View File

@@ -131,6 +131,7 @@ void BOPAlgo_Splitter::Perform()
pPF->SetFuzzyValue(myFuzzyValue);
pPF->SetNonDestructive(myNonDestructive);
pPF->SetGlue(myGlue);
pPF->SetUseOBB(myUseOBB);
//
pPF->Perform();
//

View File

@@ -24,6 +24,7 @@
#include <BOPCol_NCVector.hxx>
#include <BOPCol_Parallel.hxx>
#include <BOPTools.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS.hxx>
@@ -124,153 +125,12 @@ void BOPAlgo_WireSplitter::Perform()
myContext = new IntTools_Context;
}
//
MakeConnexityBlocks();
BOPTools_AlgoTools::MakeConnexityBlocks
(myWES->StartElements(), TopAbs_VERTEX, TopAbs_EDGE, myLCB);
MakeWires();
}
//=======================================================================
//function : MakeConnexityBlocks
//purpose :
//=======================================================================
void BOPAlgo_WireSplitter::MakeConnexityBlocks()
{
Standard_Boolean bRegular, bClosed;
Standard_Integer i, j, aNbV, aNbVS, aNbVP, k;
TopoDS_Iterator aItE;
TopoDS_Shape aER;
BOPCol_ListIteratorOfListOfShape aIt;
//
BOPCol_IndexedDataMapOfShapeListOfShape aMVE(100, myAllocator);
BOPCol_IndexedMapOfShape aMVP(100, myAllocator);
BOPCol_IndexedMapOfShape aMEC(100, myAllocator);
BOPCol_MapOfShape aMER(100, myAllocator);
BOPCol_MapOfShape aMEP(100, myAllocator);
BOPCol_IndexedMapOfShape aMVAdd(100, myAllocator);
BOPCol_MapOfShape aMVS(100, myAllocator);
//
myLCB.Clear();
//
const BOPCol_ListOfShape& aLSE=myWES->StartElements();
aIt.Initialize(aLSE);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aE=aIt.Value();
if (aMEP.Add(aE)) {
BOPTools::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
}
else {
aMER.Add(aE);
}
}
//
// 2
aNbV=aMVE.Extent();
for (i=1; i<=aNbV; ++i) {
aNbVS=aMVS.Extent();
if (aNbVS==aNbV) {
break;
}
//
const TopoDS_Shape& aV=aMVE.FindKey(i);
//
if (!aMVS.Add(aV)) {
continue;
}
// aMVS - globally processed vertices
//
//------------------------------------- goal: aMEC
aMEC.Clear(); // aMEC - edges of CB
aMVP.Clear(); // aMVP - vertices to process right now
aMVAdd.Clear(); // aMVAdd vertices to process on next step of while(1)
//
aMVP.Add(aV);
//
for(;;) {
aNbVP=aMVP.Extent();
for (k=1; k<=aNbVP; ++k) {
const TopoDS_Shape& aVP=aMVP(k);
const BOPCol_ListOfShape& aLE=aMVE.FindFromKey(aVP);
aIt.Initialize(aLE);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aE=aIt.Value();
if (aMEC.Add(aE)) {
aItE.Initialize(aE);
for (; aItE.More(); aItE.Next()) {
const TopoDS_Shape& aVE=aItE.Value();
if (aMVS.Add(aVE)) {
aMVAdd.Add(aVE);
}
}
}
}
}//for (k=1; k<=aNbVP; ++k) {
//
aNbVP=aMVAdd.Extent();
if (!aNbVP) {
break; // from while(1)
}
//
aMVP.Clear();
//
for (k=1; k<=aNbVP; ++k) {
const TopoDS_Shape& aVE=aMVAdd(k);
aMVP.Add(aVE);
}
aMVAdd.Clear();
}// while(1) {
//-------------------------------------
BOPTools_ConnexityBlock aCB(myAllocator);
BOPCol_ListOfShape& aLEC=aCB.ChangeShapes();
BOPCol_IndexedDataMapOfShapeListOfShape aMVER(100, myAllocator);
//
bRegular=Standard_True;
Standard_Integer aNbCB = aMEC.Extent();
for (j = 1; j <= aNbCB; j++) {
aER = aMEC(j);
//
if (aMER.Contains(aER)) {
aER.Orientation(TopAbs_FORWARD);
aLEC.Append(aER);
aER.Orientation(TopAbs_REVERSED);
aLEC.Append(aER);
bRegular=Standard_False;
}
else {
aLEC.Append(aER);
}
//
if (bRegular) {
BOPTools::MapShapesAndAncestors(aER, TopAbs_VERTEX, TopAbs_EDGE, aMVER);
}
}
//
if (bRegular) {
Standard_Integer aNbVR, aNbER;
//
aNbVR=aMVER.Extent();
for (k=1; k<=aNbVR; ++k) {
const BOPCol_ListOfShape& aLER=aMVER(k);
aNbER=aLER.Extent();
if (aNbER==1) {
const TopoDS_Edge& aEx=TopoDS::Edge(aER);
bClosed=BRep_Tool::IsClosed(aEx, myWES->Face());
if (!bClosed) {
bRegular=!bRegular;
break;
}
}
if (aNbER>2) {
bRegular=!bRegular;
break;
}
}
}
//
aCB.SetRegular(bRegular);
myLCB.Append(aCB);
}
}
/////////////////////////////////////////////////////////////////////////
class BOPAlgo_WS_ConnexityBlock {
public:

View File

@@ -70,8 +70,6 @@ protected:
Standard_EXPORT virtual void CheckData() Standard_OVERRIDE;
Standard_EXPORT void MakeConnexityBlocks();
Standard_EXPORT void MakeWires();
BOPAlgo_PWireEdgeSet myWES;

View File

@@ -545,58 +545,64 @@ void BOPDS_DS::Init(const Standard_Real theFuzz)
}//if (aTS==TopAbs_FACE) {
}//for (j=0; j<myNbSourceShapes; ++j) {
//
// 2.4 Solids
for (j=0; j<myNbSourceShapes; ++j) {
BOPDS_ShapeInfo& aSI=ChangeShapeInfo(j);
//
aTS=aSI.ShapeType();
if (aTS!=TopAbs_SOLID) {
continue;
}
Bnd_Box& aBox=aSI.ChangeBox();
BuildBndBoxSolid(j, aBox);
//
//
// update sub-shapes by BRep comprising ones
aMI.Clear();
BOPCol_ListOfInteger& aLI1=aSI.ChangeSubShapes();
//
aIt1.Initialize(aLI1);
for (; aIt1.More(); aIt1.Next()) {
n1=aIt1.Value();
BOPDS_ShapeInfo& aSI1=ChangeShapeInfo(n1);
if (aSI1.ShapeType()!=TopAbs_SHELL) {
// For the check mode we need to compute the bounding box for solid.
// Otherwise, it will be computed on the building stage
Standard_Boolean bCheckMode = (myArguments.Extent() == 1);
if (bCheckMode)
{
// 2.4 Solids
for (j=0; j<myNbSourceShapes; ++j) {
BOPDS_ShapeInfo& aSI=ChangeShapeInfo(j);
//
aTS=aSI.ShapeType();
if (aTS!=TopAbs_SOLID) {
continue;
}
Bnd_Box& aBox=aSI.ChangeBox();
BuildBndBoxSolid(j, aBox);
//
const BOPCol_ListOfInteger& aLI2=aSI1.SubShapes();
aIt2.Initialize(aLI2);
for (; aIt2.More(); aIt2.Next()) {
n2=aIt2.Value();
BOPDS_ShapeInfo& aSI2=ChangeShapeInfo(n2);
if (aSI2.ShapeType()!=TopAbs_FACE) {
//
// update sub-shapes by BRep comprising ones
aMI.Clear();
BOPCol_ListOfInteger& aLI1=aSI.ChangeSubShapes();
//
aIt1.Initialize(aLI1);
for (; aIt1.More(); aIt1.Next()) {
n1=aIt1.Value();
BOPDS_ShapeInfo& aSI1=ChangeShapeInfo(n1);
if (aSI1.ShapeType()!=TopAbs_SHELL) {
continue;
}
//
aMI.Add(n2);
//
const BOPCol_ListOfInteger& aLI3=aSI2.SubShapes();
aIt3.Initialize(aLI3);
for (; aIt3.More(); aIt3.Next()) {
n3=aIt3.Value();
aMI.Add(n3);
const BOPCol_ListOfInteger& aLI2=aSI1.SubShapes();
aIt2.Initialize(aLI2);
for (; aIt2.More(); aIt2.Next()) {
n2=aIt2.Value();
BOPDS_ShapeInfo& aSI2=ChangeShapeInfo(n2);
if (aSI2.ShapeType()!=TopAbs_FACE) {
continue;
}
//
aMI.Add(n2);
//
const BOPCol_ListOfInteger& aLI3=aSI2.SubShapes();
aIt3.Initialize(aLI3);
for (; aIt3.More(); aIt3.Next()) {
n3=aIt3.Value();
aMI.Add(n3);
}
}
}
}
//
aLI1.Clear();
aItMI.Initialize(aMI);
for (; aItMI.More(); aItMI.Next()) {
n1=aItMI.Value();
aLI1.Append(n1);
}
aMI.Clear();
}//for (j=0; j<myNbSourceShapes; ++j) {
//
aLI1.Clear();
aItMI.Initialize(aMI);
for (; aItMI.More(); aItMI.Next()) {
n1=aItMI.Value();
aLI1.Append(n1);
}
aMI.Clear();
}//for (j=0; j<myNbSourceShapes; ++j) {
}
//
aMI.Clear();
//-----------------------------------------------------
@@ -1866,7 +1872,8 @@ Standard_Real ComputeParameter(const TopoDS_Vertex& aV,
//purpose :
//=======================================================================
void BOPDS_DS::BuildBndBoxSolid(const Standard_Integer theIndex,
Bnd_Box& aBoxS)
Bnd_Box& aBoxS,
const Standard_Boolean theCheckInverted)
{
Standard_Boolean bIsOpenBox, bIsInverted;
Standard_Integer nSh, nFc;
@@ -1930,7 +1937,7 @@ void BOPDS_DS::BuildBndBoxSolid(const Standard_Integer theIndex,
if (bIsOpenBox) {
aBoxS.SetWhole();
}
else {
else if (theCheckInverted) {
bIsInverted=BOPTools_AlgoTools::IsInvertedSolid(aSolid);
if (bIsInverted) {
aBoxS.SetWhole();

View File

@@ -468,6 +468,13 @@ Standard_EXPORT virtual ~BOPDS_DS();
//! of the existing vertices have been increased.
Standard_EXPORT Standard_Boolean IsValidShrunkData(const Handle(BOPDS_PaveBlock)& thePB);
//! Computes bounding box <theBox> for the solid with DS-index <theIndex>.
//! The flag <theCheckInverted> enables/disables the check of the solid
//! for inverted status. By default the solids will be checked.
Standard_EXPORT void BuildBndBoxSolid (const Standard_Integer theIndex,
Bnd_Box& theBox,
const Standard_Boolean theCheckInverted = Standard_True);
protected:
@@ -485,10 +492,6 @@ protected:
const Standard_Real theFuzz);
//! Computes bouding box <theBox> for the solid with DS-index <theIndex>
Standard_EXPORT void BuildBndBoxSolid (const Standard_Integer theIndex, Bnd_Box& theBox);
BOPCol_BaseAllocator myAllocator;
BOPCol_ListOfShape myArguments;
Standard_Integer myNbShapes;

View File

@@ -29,6 +29,12 @@
#include <NCollection_UBTreeFiller.hxx>
#include <TopoDS_Shape.hxx>
#include <algorithm>
#include <IntTools_Context.hxx>
#include <IntTools_OBB.hxx>
#ifdef DEBUG_OBB
#include <IntTools_Tools.hxx>
#endif
/////////////////////////////////////////////////////////////////////////
//=======================================================================
@@ -240,7 +246,8 @@ void BOPDS_Iterator::Value(Standard_Integer& theI1,
// function: Prepare
// purpose:
//=======================================================================
void BOPDS_Iterator::Prepare()
void BOPDS_Iterator::Prepare(Handle(IntTools_Context)& theCtx,
const Standard_Boolean theCheckOBB)
{
Standard_Integer i, aNbInterfTypes;
//
@@ -253,14 +260,15 @@ void BOPDS_Iterator::Prepare()
if (myDS==NULL){
return;
}
Intersect();
Intersect(theCtx, theCheckOBB);
}
//
//=======================================================================
// function: Intersect
// purpose:
//=======================================================================
void BOPDS_Iterator::Intersect()
void BOPDS_Iterator::Intersect(Handle(IntTools_Context)& theCtx,
const Standard_Boolean theCheckOBB)
{
Standard_Integer i, j, iX, i1, i2, iR, aNb, aNbR;
Standard_Integer iTi, iTj;
@@ -304,7 +312,7 @@ void BOPDS_Iterator::Intersect()
i1 = aR.First();
i2 = aR.Last();
for (i = i1; i <= i2; ++i) {
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
BOPDS_ShapeInfo& aSI = myDS->ChangeShapeInfo(i);
//
if (!aSI.IsInterfering() || (aSI.ShapeType() == TopAbs_SOLID)) {
continue;
@@ -327,7 +335,7 @@ void BOPDS_Iterator::Intersect()
continue;// same range
}
//
const BOPDS_ShapeInfo& aSJ = myDS->ShapeInfo(j);
BOPDS_ShapeInfo& aSJ = myDS->ChangeShapeInfo(j);
aTj = aSJ.ShapeType();
iTj = BOPDS_Tools::TypeToInteger(aTj);
//
@@ -339,6 +347,19 @@ void BOPDS_Iterator::Intersect()
//
BOPDS_Pair aPair(i, j);
if (aMPFence.Add(aPair)) {
if (theCheckOBB)
{
IntTools_OBB& anOBBi = theCtx->OBB(aSI.Shape(), aSI.Box().GetGap());
IntTools_OBB& anOBBj = theCtx->OBB(aSJ.Shape(), aSJ.Box().GetGap());
#ifdef DEBUG_OBB
TopoDS_Shape aBox1 = IntTools_Tools::GetOBBShapeBox(anOBBi);
TopoDS_Shape aBox2 = IntTools_Tools::GetOBBShapeBox(anOBBj);
#endif
if (anOBBi.IsOut(anOBBj))
continue;
}
iX = BOPDS_Tools::TypeToInteger(aTi, aTj);
myLists(iX).Append(aPair);
}// if (aMPFence.Add(aPair)) {

View File

@@ -30,7 +30,7 @@
#include <Standard_Boolean.hxx>
#include <TopAbs_ShapeEnum.hxx>
class BOPDS_DS;
class IntTools_Context;
//! The class BOPDS_Iterator is
@@ -81,7 +81,8 @@ public:
//! Perform the intersection algorithm and prepare
//! the results to be used
Standard_EXPORT virtual void Prepare();
Standard_EXPORT virtual void Prepare(Handle(IntTools_Context)& theCtx,
const Standard_Boolean theCheckOBB = Standard_False);
//! Returns the number of intersections founded
Standard_EXPORT Standard_Integer ExpectedLength() const;
@@ -99,7 +100,8 @@ public:
protected:
Standard_EXPORT virtual void Intersect();
Standard_EXPORT virtual void Intersect(Handle(IntTools_Context)& theCtx,
const Standard_Boolean theCheckOBB = Standard_False);
BOPCol_BaseAllocator myAllocator;
Standard_Integer myLength;

View File

@@ -33,6 +33,8 @@
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <IntTools_Context.hxx>
#include <IntTools_OBB.hxx>
//
//=======================================================================
@@ -78,7 +80,8 @@ void BOPDS_IteratorSI::UpdateByLevelOfCheck(const Standard_Integer theLevel)
// function: Intersect
// purpose:
//=======================================================================
void BOPDS_IteratorSI::Intersect()
void BOPDS_IteratorSI::Intersect(Handle(IntTools_Context)& theCtx,
const Standard_Boolean theCheckOBB)
{
Standard_Integer i, j, iX, aNbS;
Standard_Integer iTi, iTj;
@@ -138,6 +141,15 @@ void BOPDS_IteratorSI::Intersect()
//
BOPDS_Pair aPair(i, j);
if (aMPFence.Add(aPair)) {
if (theCheckOBB)
{
IntTools_OBB& anOBBi = theCtx->OBB(aSI.Shape(), aSI.Box().GetGap());
IntTools_OBB& anOBBj = theCtx->OBB(aSJ.Shape(), aSJ.Box().GetGap());
if (anOBBi.IsOut(anOBBj))
continue;
}
iX = BOPDS_Tools::TypeToInteger(aTi, aTj);
myLists(iX).Append(aPair);
}// if (aMPKXB.Add(aPKXB)) {

View File

@@ -68,7 +68,8 @@ Standard_EXPORT virtual ~BOPDS_IteratorSI();
protected:
Standard_EXPORT virtual void Intersect() Standard_OVERRIDE;
Standard_EXPORT virtual void Intersect(Handle(IntTools_Context)& theCtx,
const Standard_Boolean theCheckOBB = Standard_False) Standard_OVERRIDE;

View File

@@ -133,6 +133,8 @@ Standard_Integer bapibop(Draw_Interpretor& di,
pBuilder->SetFuzzyValue(aFuzzyValue);
pBuilder->SetNonDestructive(bNonDestructive);
pBuilder->SetGlue(aGlue);
pBuilder->SetCheckInverted(BOPTest_Objects::CheckInverted());
pBuilder->SetUseOBB(BOPTest_Objects::UseOBB());
//
pBuilder->Build();
//
@@ -193,6 +195,8 @@ Standard_Integer bapibuild(Draw_Interpretor& di,
aBuilder.SetFuzzyValue(aFuzzyValue);
aBuilder.SetNonDestructive(bNonDestructive);
aBuilder.SetGlue(aGlue);
aBuilder.SetCheckInverted(BOPTest_Objects::CheckInverted());
aBuilder.SetUseOBB(BOPTest_Objects::UseOBB());
//
aBuilder.Build();
//
@@ -257,6 +261,8 @@ Standard_Integer bapisplit(Draw_Interpretor& di,
aSplitter.SetFuzzyValue(BOPTest_Objects::FuzzyValue());
aSplitter.SetNonDestructive(BOPTest_Objects::NonDestructive());
aSplitter.SetGlue(BOPTest_Objects::Glue());
aSplitter.SetCheckInverted(BOPTest_Objects::CheckInverted());
aSplitter.SetUseOBB(BOPTest_Objects::UseOBB());
//
// performing operation
aSplitter.Build();

View File

@@ -158,6 +158,7 @@ Standard_Integer bop(Draw_Interpretor& di,
pPF->SetRunParallel(bRunParallel);
pPF->SetNonDestructive(bNonDestructive);
pPF->SetGlue(aGlue);
pPF->SetUseOBB(BOPTest_Objects::UseOBB());
//
pPF->Perform();
BOPTest::ReportAlerts(*pPF);
@@ -250,6 +251,7 @@ Standard_Integer bopsmt(Draw_Interpretor& di,
aBOP.AddTool(aS2);
aBOP.SetOperation(aOp);
aBOP.SetRunParallel (bRunParallel);
aBOP.SetCheckInverted(BOPTest_Objects::CheckInverted());
//
aBOP.PerformWithFiller(*pPF);
BOPTest::ReportAlerts(aBOP);
@@ -310,6 +312,7 @@ Standard_Integer bopsection(Draw_Interpretor& di,
aBOP.AddArgument(aS1);
aBOP.AddArgument(aS2);
aBOP.SetRunParallel (bRunParallel);
aBOP.SetCheckInverted(BOPTest_Objects::CheckInverted());
//
aBOP.PerformWithFiller(*pPF);
BOPTest::ReportAlerts(aBOP);
@@ -425,6 +428,7 @@ Standard_Integer bsection(Draw_Interpretor& di,
aSec.SetRunParallel(bRunParallel);
aSec.SetNonDestructive(bNonDestructive);
aSec.SetGlue(aGlue);
aSec.SetUseOBB(BOPTest_Objects::UseOBB());
//
aSec.Build();
//
@@ -494,6 +498,7 @@ Standard_Integer bsmt (Draw_Interpretor& di,
aPF.SetRunParallel(bRunParallel);
aPF.SetNonDestructive(bNonDestructive);
aPF.SetGlue(aGlue);
aPF.SetUseOBB(BOPTest_Objects::UseOBB());
//
aPF.Perform();
BOPTest::ReportAlerts(aPF);
@@ -508,6 +513,7 @@ Standard_Integer bsmt (Draw_Interpretor& di,
aBOP.AddTool(aS2);
aBOP.SetOperation(aOp);
aBOP.SetRunParallel(bRunParallel);
aBOP.SetCheckInverted(BOPTest_Objects::CheckInverted());
//
aBOP.PerformWithFiller(aPF);
BOPTest::ReportAlerts(aBOP);
@@ -815,6 +821,7 @@ Standard_Integer mkvolume(Draw_Interpretor& di, Standard_Integer n, const char**
aMV.SetNonDestructive(bNonDestructive);
aMV.SetAvoidInternalShapes(bAvoidInternal);
aMV.SetGlue(aGlue);
aMV.SetUseOBB(BOPTest_Objects::UseOBB());
//
aMV.Perform();
BOPTest::ReportAlerts(aMV);

View File

@@ -111,6 +111,8 @@ Standard_Integer bcbuild(Draw_Interpretor& di,
aCBuilder.SetFuzzyValue(aTol);
aCBuilder.SetNonDestructive(bNonDestructive);
aCBuilder.SetGlue(aGlue);
aCBuilder.SetCheckInverted(BOPTest_Objects::CheckInverted());
aCBuilder.SetUseOBB(BOPTest_Objects::UseOBB());
//
aCBuilder.PerformWithFiller(aPF);
BOPTest::ReportAlerts(aCBuilder);

View File

@@ -40,6 +40,7 @@
#include <BOPCol_DataMapOfShapeShape.hxx>
#include <BOPCol_DataMapOfShapeListOfShape.hxx>
#include <IntTools_Context.hxx>
static
void GetTypeByName(const char* theName,
@@ -239,9 +240,11 @@ Standard_Integer bopiterator (Draw_Interpretor& di,
char buf[64], aST1[10], aST2[10];
BOPDS_Iterator aIt;
//
Handle(IntTools_Context) aCtx = new IntTools_Context();
BOPDS_DS& aDS = *pDS;
aIt.SetDS(&aDS);
aIt.Prepare();
aIt.Prepare(aCtx, BOPTest_Objects::UseOBB());
//
if (n == 1) {
// type has not been defined. show all pairs

View File

@@ -55,6 +55,8 @@ class BOPTest_Session {
myFuzzyValue = 0.;
myGlue = BOPAlgo_GlueOff;
myDrawWarnShapes = Standard_False;
myCheckInverted = Standard_True;
myUseOBB = Standard_False;
};
//
// Clear
@@ -142,6 +144,21 @@ class BOPTest_Session {
return myDrawWarnShapes;
};
//
void SetCheckInverted(const Standard_Boolean bCheck) {
myCheckInverted = bCheck;
};
//
Standard_Boolean CheckInverted() const {
return myCheckInverted;
};
//
void SetUseOBB(const Standard_Boolean bUse) {
myUseOBB = bUse;
};
//
Standard_Boolean UseOBB() const {
return myUseOBB;
};
protected:
//
BOPTest_Session(const BOPTest_Session&);
@@ -160,6 +177,8 @@ protected:
Standard_Real myFuzzyValue;
BOPAlgo_GlueEnum myGlue;
Standard_Boolean myDrawWarnShapes;
Standard_Boolean myCheckInverted;
Standard_Boolean myUseOBB;
};
//
//=======================================================================
@@ -370,6 +389,38 @@ Standard_Boolean BOPTest_Objects::DrawWarnShapes()
return GetSession().DrawWarnShapes();
}
//=======================================================================
//function : SetCheckInverted
//purpose :
//=======================================================================
void BOPTest_Objects::SetCheckInverted(const Standard_Boolean bCheck)
{
GetSession().SetCheckInverted(bCheck);
}
//=======================================================================
//function : CheckInverted
//purpose :
//=======================================================================
Standard_Boolean BOPTest_Objects::CheckInverted()
{
return GetSession().CheckInverted();
}
//=======================================================================
//function : SetUseOBB
//purpose :
//=======================================================================
void BOPTest_Objects::SetUseOBB(const Standard_Boolean bUseOBB)
{
GetSession().SetUseOBB(bUseOBB);
}
//=======================================================================
//function : UseOBB
//purpose :
//=======================================================================
Standard_Boolean BOPTest_Objects::UseOBB()
{
return GetSession().UseOBB();
}
//=======================================================================
//function : Allocator1
//purpose :
//=======================================================================

View File

@@ -87,6 +87,14 @@ public:
Standard_EXPORT static Standard_Boolean DrawWarnShapes();
Standard_EXPORT static void SetCheckInverted(const Standard_Boolean bCheck);
Standard_EXPORT static Standard_Boolean CheckInverted();
Standard_EXPORT static void SetUseOBB(const Standard_Boolean bUseOBB);
Standard_EXPORT static Standard_Boolean UseOBB();
protected:
private:

View File

@@ -27,6 +27,8 @@ static Standard_Integer bnondestructive(Draw_Interpretor&, Standard_Integer, con
static Standard_Integer bfuzzyvalue(Draw_Interpretor&, Standard_Integer, const char**);
static Standard_Integer bGlue(Draw_Interpretor&, Standard_Integer, const char**);
static Standard_Integer bdrawwarnshapes(Draw_Interpretor&, Standard_Integer, const char**);
static Standard_Integer bcheckinverted(Draw_Interpretor&, Standard_Integer, const char**);
static Standard_Integer buseobb(Draw_Interpretor&, Standard_Integer, const char**);
//=======================================================================
//function : OptionCommands
@@ -48,6 +50,10 @@ void BOPTest::OptionCommands(Draw_Interpretor& theCommands)
theCommands.Add("bdrawwarnshapes", "Defines whether to draw warning shapes or not\n"
"Usage: bdrawwarnshapes [0 (do not draw) / 1 (draw warning shapes)",
__FILE__, bdrawwarnshapes, g);
theCommands.Add("bcheckinverted", "Defines whether to check the input solids on inverted status or not\n"
"Usage: bcheckinverted [0 (off) / 1 (on)]", __FILE__, bcheckinverted, g);
theCommands.Add("buseobb", "Enables/disables the usage of OBB\n"
"Usage: buseobb [0 (off) / 1 (on)]", __FILE__, buseobb, g);
}
//=======================================================================
//function : boptions
@@ -72,6 +78,8 @@ Standard_Integer boptions(Draw_Interpretor& di,
aFuzzyValue = BOPTest_Objects::FuzzyValue();
aGlue = BOPTest_Objects::Glue();
Standard_Boolean bDrawWarnShapes = BOPTest_Objects::DrawWarnShapes();
Standard_Boolean bCheckInverted = BOPTest_Objects::CheckInverted();
Standard_Boolean bUseOBB = BOPTest_Objects::UseOBB();
//
Sprintf(buf, " RunParallel: %d\n", bRunParallel);
di << buf;
@@ -84,6 +92,10 @@ Standard_Integer boptions(Draw_Interpretor& di,
di << buf;
Sprintf(buf, " Draw Warning Shapes: %s\n", bDrawWarnShapes ? "Yes" : "No");
di << buf;
Sprintf(buf, " Check for inverted solids: %s\n", bCheckInverted ? "Yes" : "No");
di << buf;
Sprintf(buf, " Use OBB:%s\n", bUseOBB ? "Yes" : "No");
di << buf;
//
return 0;
}
@@ -209,3 +221,39 @@ Standard_Integer bdrawwarnshapes(Draw_Interpretor& di,
BOPTest_Objects::SetDrawWarnShapes(iDraw != 0);
return 0;
}
//=======================================================================
//function : bcheckinverted
//purpose :
//=======================================================================
Standard_Integer bcheckinverted(Draw_Interpretor& di,
Standard_Integer n,
const char** a)
{
if (n != 2) {
di.PrintHelp(a[0]);
return 1;
}
//
Standard_Integer iCheck = Draw::Atoi(a[1]);
BOPTest_Objects::SetCheckInverted(iCheck != 0);
return 0;
}
//=======================================================================
//function : buseobb
//purpose :
//=======================================================================
Standard_Integer buseobb(Draw_Interpretor& di,
Standard_Integer n,
const char** a)
{
if (n != 2) {
di.PrintHelp(a[0]);
return 1;
}
//
Standard_Integer iUse = Draw::Atoi(a[1]);
BOPTest_Objects::SetUseOBB(iUse != 0);
return 0;
}

View File

@@ -115,6 +115,7 @@ Standard_Integer bfillds(Draw_Interpretor& di,
aPF.SetNonDestructive(bNonDestructive);
aPF.SetFuzzyValue(aTol);
aPF.SetGlue(aGlue);
aPF.SetUseOBB(BOPTest_Objects::UseOBB());
//
OSD_Timer aTimer;
aTimer.Start();
@@ -188,6 +189,7 @@ Standard_Integer bbuild(Draw_Interpretor& di,
}
}
aBuilder.SetRunParallel(bRunParallel);
aBuilder.SetCheckInverted(BOPTest_Objects::CheckInverted());
//
//
OSD_Timer aTimer;
@@ -298,6 +300,7 @@ Standard_Integer bbop(Draw_Interpretor& di,
}
//
pBuilder->SetRunParallel(bRunParallel);
pBuilder->SetCheckInverted(BOPTest_Objects::CheckInverted());
//
OSD_Timer aTimer;
aTimer.Start();
@@ -363,6 +366,7 @@ Standard_Integer bsplit(Draw_Interpretor& di,
pSplitter->SetRunParallel(BOPTest_Objects::RunParallel());
pSplitter->SetNonDestructive(BOPTest_Objects::NonDestructive());
pSplitter->SetFuzzyValue(BOPTest_Objects::FuzzyValue());
pSplitter->SetCheckInverted(BOPTest_Objects::CheckInverted());
//
// measure the time of the operation
OSD_Timer aTimer;

View File

@@ -71,38 +71,28 @@ void BOPTools::MapShapesAndAncestors
(const TopoDS_Shape& S,
const TopAbs_ShapeEnum TS,
const TopAbs_ShapeEnum TA,
BOPCol_IndexedDataMapOfShapeListOfShape& aMEF)
BOPCol_IndexedDataMapOfShapeListOfShape& Map)
{
TopExp_Explorer aExS, aExA;
//
// visit ancestors
aExA.Init(S, TA);
while (aExA.More()) {
TopExp_Explorer aExA(S, TA);
for (; aExA.More(); aExA.Next())
{
// visit shapes
const TopoDS_Shape& aF = aExA.Current();
const TopoDS_Shape& anAnc = aExA.Current();
//
aExS.Init(aF, TS);
while (aExS.More()) {
const TopoDS_Shape& aE= aExS.Current();
if (aMEF.Contains(aE)) {
aMEF.ChangeFromKey(aE).Append(aF);
}
else {
BOPCol_ListOfShape aLS;
aLS.Append(aF);
aMEF.Add(aE, aLS);
}
aExS.Next();
TopExp_Explorer aExS(anAnc, TS);
for (; aExS.More(); aExS.Next())
{
const TopoDS_Shape& aSS = aExS.Current();
BOPCol_ListOfShape* pLA = Map.ChangeSeek(aSS);
if (!pLA)
pLA = &Map(Map.Add(aSS, BOPCol_ListOfShape()));
pLA->Append(anAnc);
}
aExA.Next();
}
//
// visit shapes not under ancestors
aExS.Init(S, TS, TA);
while (aExS.More()) {
const TopoDS_Shape& aE=aExS.Current();
BOPCol_ListOfShape aLS;
aMEF.Add(aE, aLS);
aExS.Next();
}
TopExp_Explorer aExS(S, TS, TA);
for (; aExS.More(); aExS.Next())
Map.Add(aExS.Current(), BOPCol_ListOfShape());
}

View File

@@ -120,52 +120,149 @@ static
//=======================================================================
void BOPTools_AlgoTools::MakeConnexityBlocks
(const TopoDS_Shape& theS,
const TopAbs_ShapeEnum theType1,
const TopAbs_ShapeEnum theType2,
BOPCol_ListOfShape& theLCB)
const TopAbs_ShapeEnum theConnectionType,
const TopAbs_ShapeEnum theElementType,
BOPCol_ListOfListOfShape& theLCB,
BOPCol_IndexedDataMapOfShapeListOfShape& theConnectionMap)
{
// Map shapes to find connected elements
BOPCol_IndexedDataMapOfShapeListOfShape aDMSLS;
BOPTools::MapShapesAndAncestors(theS, theType1, theType2, aDMSLS);
BOPTools::MapShapesAndAncestors(theS, theConnectionType, theElementType, theConnectionMap);
// Fence map
BOPCol_MapOfShape aMFence;
Standard_Integer i;
BRep_Builder aBB;
//
TopExp_Explorer aExp(theS, theType2);
for (; aExp.More(); aExp.Next()) {
TopExp_Explorer aExp(theS, theElementType);
for (; aExp.More(); aExp.Next())
{
const TopoDS_Shape& aS = aExp.Current();
if (!aMFence.Add(aS)) {
continue;
}
// The block
BOPCol_IndexedMapOfShape aMBlock;
TopoDS_Compound aBlock;
aBB.MakeCompound(aBlock);
BOPCol_ListOfShape aLBlock;
// Start the block
aMBlock.Add(aS);
aBB.Add(aBlock, aS);
aLBlock.Append(aS);
// Look for connected parts
for (i = 1; i <= aMBlock.Extent(); ++i) {
const TopoDS_Shape& aS1 = aMBlock(i);
TopExp_Explorer aExpSS(aS1, theType1);
for (; aExpSS.More(); aExpSS.Next()) {
BOPCol_ListIteratorOfListOfShape aItB(aLBlock);
for (; aItB.More(); aItB.Next())
{
const TopoDS_Shape& aS1 = aItB.Value();
TopExp_Explorer aExpSS(aS1, theConnectionType);
for (; aExpSS.More(); aExpSS.Next())
{
const TopoDS_Shape& aSubS = aExpSS.Current();
const BOPCol_ListOfShape& aLS = aDMSLS.FindFromKey(aSubS);
const BOPCol_ListOfShape& aLS = theConnectionMap.FindFromKey(aSubS);
BOPCol_ListIteratorOfListOfShape aItLS(aLS);
for (; aItLS.More(); aItLS.Next()) {
for (; aItLS.More(); aItLS.Next())
{
const TopoDS_Shape& aS2 = aItLS.Value();
if (aMFence.Add(aS2)) {
aMBlock.Add(aS2);
aBB.Add(aBlock, aS2);
}
if (aMFence.Add(aS2))
aLBlock.Append(aS2);
}
}
}
// Add the block into result
theLCB.Append(aLBlock);
}
}
//=======================================================================
// function: MakeConnexityBlocks
// purpose:
//=======================================================================
void BOPTools_AlgoTools::MakeConnexityBlocks
(const TopoDS_Shape& theS,
const TopAbs_ShapeEnum theConnectionType,
const TopAbs_ShapeEnum theElementType,
BOPCol_ListOfShape& theLCB)
{
BOPCol_ListOfListOfShape aLBlocks;
BOPCol_IndexedDataMapOfShapeListOfShape aCMap;
BOPTools_AlgoTools::MakeConnexityBlocks(theS, theConnectionType, theElementType, aLBlocks, aCMap);
// Make compound from each block
BOPCol_ListIteratorOfListOfListOfShape aItB(aLBlocks);
for (; aItB.More(); aItB.Next())
{
const BOPCol_ListOfShape& aLB = aItB.Value();
TopoDS_Compound aBlock;
BRep_Builder().MakeCompound(aBlock);
for (BOPCol_ListIteratorOfListOfShape it(aLB); it.More(); it.Next())
BRep_Builder().Add(aBlock, it.Value());
theLCB.Append(aBlock);
}
}
//=======================================================================
// function: MakeConnexityBlocks
// purpose:
//=======================================================================
void BOPTools_AlgoTools::MakeConnexityBlocks
(const BOPCol_ListOfShape& theLS,
const TopAbs_ShapeEnum theConnectionType,
const TopAbs_ShapeEnum theElementType,
BOPTools_ListOfConnexityBlock& theLCB)
{
BRep_Builder aBB;
// Make connexity blocks from start elements
TopoDS_Compound aCStart;
aBB.MakeCompound(aCStart);
BOPCol_MapOfShape aMFence, aMNRegular;
BOPCol_ListIteratorOfListOfShape aItL(theLS);
for (; aItL.More(); aItL.Next())
{
const TopoDS_Shape& aS = aItL.Value();
if (aMFence.Add(aS))
aBB.Add(aCStart, aS);
else
aMNRegular.Add(aS);
}
BOPCol_ListOfListOfShape aLCB;
BOPCol_IndexedDataMapOfShapeListOfShape aCMap;
BOPTools_AlgoTools::MakeConnexityBlocks(aCStart, theConnectionType, theElementType, aLCB, aCMap);
// Save the blocks and check their regularity
BOPCol_ListIteratorOfListOfListOfShape aItB(aLCB);
for (; aItB.More(); aItB.Next())
{
const BOPCol_ListOfShape& aBlock = aItB.Value();
BOPTools_ConnexityBlock aCB;
BOPCol_ListOfShape& aLCS = aCB.ChangeShapes();
Standard_Boolean bRegular = Standard_True;
for (BOPCol_ListIteratorOfListOfShape it(aBlock); it.More(); it.Next())
{
TopoDS_Shape aS = it.Value();
if (aMNRegular.Contains(aS))
{
bRegular = Standard_False;
aS.Orientation(TopAbs_FORWARD);
aLCS.Append(aS);
aS.Orientation(TopAbs_REVERSED);
aLCS.Append(aS);
}
else
{
aLCS.Append(aS);
if (bRegular)
{
// Check if there are no multi-connected shapes
for (TopExp_Explorer ex(aS, theConnectionType); ex.More() && bRegular; ex.Next())
bRegular = (aCMap.FindFromKey(ex.Current()).Extent() == 2);
}
}
}
aCB.SetRegular(bRegular);
theLCB.Append(aCB);
}
}
//=======================================================================
// function: OrientEdgesOnWire
// purpose: Reorient edges on wire for correct ordering

View File

@@ -28,7 +28,9 @@
#include <Standard_Boolean.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <BOPTools_ListOfCoupleOfShape.hxx>
#include <BOPTools_ListOfConnexityBlock.hxx>
#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
#include <BOPCol_ListOfListOfShape.hxx>
#include <TopAbs_State.hxx>
#include <BOPCol_IndexedMapOfShape.hxx>
#include <BOPCol_BaseAllocator.hxx>
@@ -188,11 +190,34 @@ public:
//! theMapAvoid - set of edges to avoid for
//! the treatment
Standard_EXPORT static void MakeConnexityBlock (BOPCol_ListOfShape& theLS, BOPCol_IndexedMapOfShape& theMapAvoid, BOPCol_ListOfShape& theLSCB, const BOPCol_BaseAllocator& theAllocator);
//! For the compound theS build the blocks
//! theLCB (as list of compounds)
//! in terms of connexity by the shapes of theType
Standard_EXPORT static void MakeConnexityBlocks (const TopoDS_Shape& theS, const TopAbs_ShapeEnum theType1, const TopAbs_ShapeEnum theType2, BOPCol_ListOfShape& theLCB);
//! For the compound <theS> builds the blocks (compounds) of
//! elements of type <theElementType> connected through the shapes
//! of the type <theConnectionType>.
//! The blocks are stored into the list <theLCB>.
Standard_EXPORT static void MakeConnexityBlocks(const TopoDS_Shape& theS,
const TopAbs_ShapeEnum theConnectionType,
const TopAbs_ShapeEnum theElementType,
BOPCol_ListOfShape& theLCB);
//! For the compound <theS> builds the blocks (compounds) of
//! elements of type <theElementType> connected through the shapes
//! of the type <theConnectionType>.
//! The blocks are stored into the list of lists <theLCB>.
//! Returns also the connection map <theConnectionMap>, filled during operation.
Standard_EXPORT static void MakeConnexityBlocks(const TopoDS_Shape& theS,
const TopAbs_ShapeEnum theConnectionType,
const TopAbs_ShapeEnum theElementType,
BOPCol_ListOfListOfShape& theLCB,
BOPCol_IndexedDataMapOfShapeListOfShape& theConnectionMap);
//! Makes connexity blocks of elements of the given type with the given type of the
//! connecting elements. The blocks are checked on regularity (multi-connectivity)
//! and stored to the list of blocks <theLCB>.
Standard_EXPORT static void MakeConnexityBlocks(const BOPCol_ListOfShape& theLS,
const TopAbs_ShapeEnum theConnectionType,
const TopAbs_ShapeEnum theElementType,
BOPTools_ListOfConnexityBlock& theLCB);
//! Correctly orients edges on the wire
Standard_EXPORT static void OrientEdgesOnWire (TopoDS_Shape& theWire);

View File

@@ -66,9 +66,6 @@
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
static
Standard_Boolean CheckEdgeLength (const TopoDS_Edge& );
static
Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& ,
const TopoDS_Face& ,
@@ -132,9 +129,6 @@ Standard_Boolean BOPTools_AlgoTools2D::EdgeTangent
if (isdgE) {
return Standard_False;
}
if (!CheckEdgeLength(anEdge)) {
return Standard_False;
}
Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last);
gp_Pnt aP;
@@ -686,44 +680,6 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace
}
}
//=======================================================================
//function : CheckEdgeLength
//purpose :
//=======================================================================
Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E)
{
BRepAdaptor_Curve BC(E);
BOPCol_IndexedMapOfShape aM;
BOPTools::MapShapes(E, TopAbs_VERTEX, aM);
Standard_Integer i, anExtent, aN=10;
Standard_Real ln=0., d, t, f, l, dt;
anExtent=aM.Extent();
if (anExtent!=1)
return Standard_True;
gp_Pnt p1, p2;
f = BC.FirstParameter();
l = BC.LastParameter();
dt=(l-f)/aN;
BC.D0(f, p1);
for (i=1; i<=aN; i++) {
t=f+i*dt;
if (i==aN)
BC.D0(l, p2);
else
BC.D0(t, p2);
d=p1.Distance(p2);
ln+=d;
p1=p2;
}
//
return (ln > Precision::Confusion());
}
//=======================================================================
//function : BRep_Tool_CurveOnSurface
//purpose :

View File

@@ -113,14 +113,6 @@ static
const Standard_Real aTol,
const BOPCol_IndexedMapOfShape& aMapToAvoid);
static
Standard_Real IntersectCurves2d(const TopoDS_Vertex& theV,
const TopoDS_Face& theF,
const Handle(Geom_Surface)& theS,
const TopoDS_Edge& theE1,
const TopoDS_Edge& theE2,
NCollection_DataMap<TopoDS_Shape, Standard_Real>& theMapEdgeLen);
//=======================================================================
//class : BOPTools_CPC
//purpose :
@@ -477,55 +469,43 @@ void CheckEdge (const TopoDS_Edge& Ed,
const Standard_Real aMaxTol,
const BOPCol_IndexedMapOfShape& aMapToAvoid)
{
Standard_Real aTolE, aTol, aD2, aNewTolerance, dd;
gp_Pnt aPC;
TopLoc_Location L;
TopoDS_Edge aE;
TopoDS_Vertex aV;
TopoDS_Iterator aItS;
//
TopAbs_Orientation aOrV;
BRep_ListIteratorOfListOfPointRepresentation aItPR;
BRep_ListIteratorOfListOfCurveRepresentation aItCR;
//
aE=Ed;
TopoDS_Edge aE = Ed;
aE.Orientation(TopAbs_FORWARD);
aTolE=BRep_Tool::Tolerance(aE);
Standard_Real aTolE = BRep_Tool::Tolerance(aE);
//
Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
//
aItS.Initialize(aE);
const TopLoc_Location& Eloc = aE.Location();
TopoDS_Iterator aItS(aE);
for (; aItS.More(); aItS.Next()) {
aV= TopoDS::Vertex(aItS.Value());
const TopoDS_Vertex& aV= TopoDS::Vertex(aItS.Value());
//
Handle(BRep_TVertex)& TV=*((Handle(BRep_TVertex)*)&aV.TShape());
const gp_Pnt& aPV = TV->Pnt();
//
aTol=BRep_Tool::Tolerance(aV);
Standard_Real aTol=BRep_Tool::Tolerance(aV);
aTol=Max(aTol, aTolE);
dd=0.1*aTol;
Standard_Real dd=0.1*aTol;
aTol*=aTol;
//
const TopLoc_Location& Eloc = aE.Location();
//
aItCR.Initialize(TE->Curves());
BRep_ListIteratorOfListOfCurveRepresentation aItCR(TE->Curves());
while (aItCR.More()) {
const Handle(BRep_CurveRepresentation)& aCR = aItCR.Value();
const TopLoc_Location& loc = aCR->Location();
L = (Eloc * loc).Predivided(aV.Location());
//
if (aCR->IsCurve3D()) {
const Handle(Geom_Curve)& aC = aCR->Curve3D();
if (!aC.IsNull()) {
aItPR.Initialize(TV->Points());
TopLoc_Location L = (Eloc * aCR->Location()).Predivided(aV.Location());
BRep_ListIteratorOfListOfPointRepresentation aItPR(TV->Points());
while (aItPR.More()) {
const Handle(BRep_PointRepresentation)& aPR=aItPR.Value();
if (aPR->IsPointOnCurve(aC, L)) {
aPC = aC->Value(aPR->Parameter());
gp_Pnt aPC = aC->Value(aPR->Parameter());
aPC.Transform(L.Transformation());
aD2=aPV.SquareDistance(aPC);
Standard_Real aD2=aPV.SquareDistance(aPC);
if (aD2 > aTol) {
aNewTolerance=sqrt(aD2)+dd;
Standard_Real aNewTolerance=sqrt(aD2)+dd;
if (aNewTolerance<aMaxTol)
UpdateShape(aV, aNewTolerance, aMapToAvoid);
}
@@ -533,10 +513,10 @@ void CheckEdge (const TopoDS_Edge& Ed,
aItPR.Next();
}
//
aOrV=aV.Orientation();
TopAbs_Orientation aOrV=aV.Orientation();
if (aOrV==TopAbs_FORWARD || aOrV==TopAbs_REVERSED) {
Handle(BRep_GCurve) aGC (Handle(BRep_GCurve)::DownCast (aCR));
gp_Pnt aPC;
if (aOrV==TopAbs_FORWARD) {
aPC=aC->Value(aGC->First());
}
@@ -545,9 +525,9 @@ void CheckEdge (const TopoDS_Edge& Ed,
}
aPC.Transform(L.Transformation());
//
aD2=aPV.SquareDistance(aPC);
Standard_Real aD2=aPV.SquareDistance(aPC);
if (aD2 > aTol) {
aNewTolerance=sqrt(aD2)+dd;
Standard_Real aNewTolerance=sqrt(aD2)+dd;
if (aNewTolerance<aMaxTol)
UpdateShape(aV, aNewTolerance, aMapToAvoid);
}
@@ -558,80 +538,6 @@ void CheckEdge (const TopoDS_Edge& Ed,
}// while (itcr.More()) {
} // for (; aVExp.More(); aVExp.Next()) {
}
//=======================================================================
// Function : CorrectWires
// purpose :
//=======================================================================
void CorrectWires(const TopoDS_Face& aFx,
const BOPCol_IndexedMapOfShape& aMapToAvoid)
{
Standard_Integer i, aNbV;
Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT;
gp_Pnt aP, aPV;
gp_Pnt2d aP2D;
TopoDS_Face aF;
TopTools_IndexedDataMapOfShapeListOfShape aMVE;
TopTools_ListIteratorOfListOfShape aIt, aIt1;
//
aF=aFx;
aF.Orientation(TopAbs_FORWARD);
const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
//
TopExp::MapShapesAndAncestors(aF,
TopAbs_VERTEX,
TopAbs_EDGE,
aMVE);
NCollection_DataMap<TopoDS_Shape, Standard_Real> aMapEdgeLen;
aNbV=aMVE.Extent();
for (i=1; i<=aNbV; ++i) {
const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMVE.FindKey(i));
aPV=BRep_Tool::Pnt(aV);
aTol=BRep_Tool::Tolerance(aV);
aTol2=aTol*aTol;
//
aD2max=-1.;
const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i);
aIt.Initialize(aLE);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
const Handle(Geom2d_Curve)& aC2D=
BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
aT=BRep_Tool::Parameter(aV, aE);
//
aC2D->D0(aT, aP2D);
aS->D0(aP2D.X(), aP2D.Y(), aP);
aD2=aPV.SquareDistance(aP);
if (aD2>aD2max) {
aD2max=aD2;
}
}
//
//check wires on self interference by intersecting 2d curves of the edges
aIt.Initialize(aLE);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Edge& aE1 = *(TopoDS_Edge*)&aIt.Value();
//
aIt1 = aIt;
for (aIt1.Next(); aIt1.More(); aIt1.Next()) {
const TopoDS_Edge& aE2 = *(TopoDS_Edge*)&aIt1.Value();
//
if (aE1.IsSame(aE2)) {
continue;
}
//
aD2 = IntersectCurves2d(aV, aF, aS, aE1, aE2, aMapEdgeLen);
if (aD2 > aD2max) {
aD2max = aD2;
}
}
}
//
if (aD2max>aTol2) {
aTol = 1.01 * sqrt(aD2max);
UpdateShape(aV, aTol, aMapToAvoid);
}
}// for (i=1; i<=aNbV; ++i) {
}
//=======================================================================
// Function : MapEdgeLength
@@ -653,35 +559,48 @@ static Standard_Real MapEdgeLength(const TopoDS_Edge& theEdge,
}
return *pLen;
}
//=======================================================================
// Function : EdgeData
// purpose : Structure to store edge data
//=======================================================================
namespace {
struct EdgeData {
const TopoDS_Edge* Edge; // Edge
Standard_Real VParameter; // Parameter of the vertex on the edge
Geom2dAdaptor_Curve GAdaptor; // 2D adaptor for PCurve of the edge on the face
Standard_Real First; // First parameter in the range
Standard_Real Last; // Last parameter in the rage
};
}
//=======================================================================
// Function : IntersectCurves2d
// purpose : Intersect 2d curves of edges
//=======================================================================
Standard_Real IntersectCurves2d(const TopoDS_Vertex& theV,
const TopoDS_Face& theF,
const Handle(Geom_Surface)& theS,
const TopoDS_Edge& theE1,
const TopoDS_Edge& theE2,
NCollection_DataMap<TopoDS_Shape, Standard_Real>& theMapEdgeLen)
static
Standard_Real IntersectCurves2d(const TopoDS_Vertex& theV,
const Handle(Geom_Surface)& theS,
const EdgeData& theEData1,
const EdgeData& theEData2,
NCollection_DataMap<TopoDS_Shape, Standard_Real>& theMapEdgeLen)
{
Standard_Real aT11, aT12, aT21, aT22, aTol2d, aMaxDist;
Geom2dInt_GInter anInter;
// Range of the first edge
Standard_Real aT11 = theEData1.First;
Standard_Real aT12 = theEData1.Last;
// Range of the second edge
Standard_Real aT21 = theEData2.First;
Standard_Real aT22 = theEData2.Last;
Standard_Real aMaxDist = 0.;
Standard_Real aTol2d = 1.e-10;
//
aMaxDist = 0.;
aTol2d = 1.e-10;
IntRes2d_Domain aDom1(theEData1.GAdaptor.Value(aT11), aT11, aTol2d,
theEData1.GAdaptor.Value(aT12), aT12, aTol2d);
IntRes2d_Domain aDom2(theEData2.GAdaptor.Value(aT21), aT21, aTol2d,
theEData2.GAdaptor.Value(aT22), aT22, aTol2d);
//
const Handle(Geom2d_Curve)& aC2D1=
BRep_Tool::CurveOnSurface(theE1, theF, aT11, aT12);
const Handle(Geom2d_Curve)& aC2D2=
BRep_Tool::CurveOnSurface(theE2, theF, aT21, aT22);
//
Geom2dAdaptor_Curve aGAC1(aC2D1), aGAC2(aC2D2);
IntRes2d_Domain aDom1(aC2D1->Value(aT11), aT11, aTol2d,
aC2D1->Value(aT12), aT12, aTol2d);
IntRes2d_Domain aDom2(aC2D2->Value(aT21), aT21, aTol2d,
aC2D2->Value(aT22), aT22, aTol2d);
//
anInter.Perform(aGAC1, aDom1, aGAC2, aDom2, aTol2d, aTol2d);
anInter.Perform(theEData1.GAdaptor, aDom1, theEData2.GAdaptor, aDom2, aTol2d, aTol2d);
if (!anInter.IsDone() || (!anInter.NbSegments() && !anInter.NbPoints())) {
return aMaxDist;
}
@@ -694,8 +613,8 @@ Standard_Real IntersectCurves2d(const TopoDS_Vertex& theV,
NCollection_List<IntRes2d_IntersectionPoint>::Iterator aItLP;
//
aPV = BRep_Tool::Pnt(theV);
aT1 = BRep_Tool::Parameter(theV, theE1);
aT2 = BRep_Tool::Parameter(theV, theE2);
aT1 = theEData1.VParameter;
aT2 = theEData2.VParameter;
//
aHalfR1 = (aT12 - aT11) / 2.;
aHalfR2 = (aT22 - aT21) / 2.;
@@ -716,8 +635,8 @@ Standard_Real IntersectCurves2d(const TopoDS_Vertex& theV,
}
//
// evaluate the length of the smallest edge, so that not to return too large distance
Standard_Real aLen1 = MapEdgeLength(theE1, theMapEdgeLen);
Standard_Real aLen2 = MapEdgeLength(theE2, theMapEdgeLen);
Standard_Real aLen1 = MapEdgeLength(*theEData1.Edge, theMapEdgeLen);
Standard_Real aLen2 = MapEdgeLength(*theEData1.Edge, theMapEdgeLen);
const Standard_Real MaxEdgePartCoveredByVertex = 0.3;
Standard_Real aMaxThresDist = Min(aLen1, aLen2) * MaxEdgePartCoveredByVertex;
aMaxThresDist *= aMaxThresDist;
@@ -750,6 +669,86 @@ Standard_Real IntersectCurves2d(const TopoDS_Vertex& theV,
//
return aMaxDist;
}
//=======================================================================
// Function : CorrectWires
// purpose :
//=======================================================================
void CorrectWires(const TopoDS_Face& aFx,
const BOPCol_IndexedMapOfShape& aMapToAvoid)
{
Standard_Integer i, aNbV;
Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT;
gp_Pnt aP, aPV;
gp_Pnt2d aP2D;
TopoDS_Face aF;
TopTools_IndexedDataMapOfShapeListOfShape aMVE;
TopTools_ListIteratorOfListOfShape aIt;
//
aF=aFx;
aF.Orientation(TopAbs_FORWARD);
const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
//
TopExp::MapShapesAndAncestors(aF,
TopAbs_VERTEX,
TopAbs_EDGE,
aMVE);
NCollection_DataMap<TopoDS_Shape, Standard_Real> aMapEdgeLen;
aNbV=aMVE.Extent();
for (i=1; i<=aNbV; ++i) {
const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMVE.FindKey(i));
aPV=BRep_Tool::Pnt(aV);
aTol=BRep_Tool::Tolerance(aV);
aTol2=aTol*aTol;
//
aD2max=-1.;
// Save edge's data to avoid its recalculation during intersection of 2d curves
NCollection_List<EdgeData> aLEPars;
const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i);
aIt.Initialize(aLE);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
const Handle(Geom2d_Curve)& aC2D=
BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
aT=BRep_Tool::Parameter(aV, aE);
//
aC2D->D0(aT, aP2D);
aS->D0(aP2D.X(), aP2D.Y(), aP);
aD2=aPV.SquareDistance(aP);
if (aD2>aD2max) {
aD2max=aD2;
}
EdgeData anEData = {&aE, aT, Geom2dAdaptor_Curve(aC2D), aT1, aT2};
aLEPars.Append(anEData);
}
//
//check wires on self interference by intersecting 2d curves of the edges
NCollection_List<EdgeData>::Iterator aItE1(aLEPars);
for (; aItE1.More(); aItE1.Next()) {
const EdgeData& aEData1 = aItE1.Value();
const TopoDS_Shape& aE1 = *aEData1.Edge;
NCollection_List<EdgeData>::Iterator aItE2 = aItE1;
for (aItE2.Next(); aItE2.More(); aItE2.Next()) {
const EdgeData& aEData2 = aItE2.Value();
const TopoDS_Shape& aE2 = *aEData2.Edge;
if (aE1.IsSame(aE2))
continue;
aD2 = IntersectCurves2d(aV, aS, aEData1, aEData2, aMapEdgeLen);
if (aD2 > aD2max) {
aD2max = aD2;
}
}
}
//
if (aD2max>aTol2) {
aTol = 1.01 * sqrt(aD2max);
UpdateShape(aV, aTol, aMapToAvoid);
}
}// for (i=1; i<=aNbV; ++i) {
}
//=======================================================================
// Function : CorrectEdgeTolerance
// purpose : Correct tolerances for Edge

View File

@@ -55,6 +55,8 @@ public:
using BOPAlgo_Options::ClearWarnings;
using BOPAlgo_Options::GetReport;
using BOPAlgo_Options::SetProgressIndicator;
using BOPAlgo_Options::SetCheckInverted;
using BOPAlgo_Options::SetUseOBB;
protected:

View File

@@ -311,6 +311,7 @@ void BRepAlgoAPI_BooleanOperation::Build()
myDSFiller->SetFuzzyValue(myFuzzyValue);
myDSFiller->SetNonDestructive(myNonDestructive);
myDSFiller->SetGlue(myGlue);
myDSFiller->SetUseOBB(myUseOBB);
//
SetAttributes();
//
@@ -353,6 +354,7 @@ void BRepAlgoAPI_BooleanOperation::Build()
//
myBuilder->SetRunParallel(myRunParallel);
myBuilder->SetProgressIndicator(myProgressIndicator);
myBuilder->SetCheckInverted(myCheckInverted);
//
myBuilder->PerformWithFiller(*myDSFiller);
//

View File

@@ -143,6 +143,7 @@ void BRepAlgoAPI_BuilderAlgo::Build()
myDSFiller->SetFuzzyValue(myFuzzyValue);
myDSFiller->SetNonDestructive(myNonDestructive);
myDSFiller->SetGlue(myGlue);
myDSFiller->SetUseOBB(myUseOBB);
//
myDSFiller->Perform();
//
@@ -163,6 +164,7 @@ void BRepAlgoAPI_BuilderAlgo::Build()
//
myBuilder->SetRunParallel(myRunParallel);
myBuilder->SetProgressIndicator(myProgressIndicator);
myBuilder->SetCheckInverted(myCheckInverted);
//
myBuilder->PerformWithFiller(*myDSFiller);
//

View File

@@ -98,6 +98,7 @@ void BRepAlgoAPI_Splitter::Build()
myDSFiller->SetFuzzyValue(myFuzzyValue);
myDSFiller->SetNonDestructive(myNonDestructive);
myDSFiller->SetGlue(myGlue);
myDSFiller->SetUseOBB(myUseOBB);
//
myDSFiller->Perform();
//
@@ -121,6 +122,7 @@ void BRepAlgoAPI_Splitter::Build()
//
myBuilder->SetRunParallel(myRunParallel);
myBuilder->SetProgressIndicator(myProgressIndicator);
myBuilder->SetCheckInverted(myCheckInverted);
//
myBuilder->PerformWithFiller(*myDSFiller);
//

File diff suppressed because it is too large Load Diff

View File

@@ -55,6 +55,8 @@ IntTools_MapOfSurfaceSample.hxx
IntTools_MarkedRangeSet.cxx
IntTools_MarkedRangeSet.hxx
IntTools_MarkedRangeSet.lxx
IntTools_OBB.cxx
IntTools_OBB.hxx
IntTools_PntOn2Faces.cxx
IntTools_PntOn2Faces.hxx
IntTools_PntOnFace.cxx

View File

@@ -35,6 +35,7 @@
#include <IntTools_FClass2d.hxx>
#include <IntTools_SurfaceRangeLocalizeData.hxx>
#include <IntTools_Tools.hxx>
#include <IntTools_OBB.hxx>
#include <Precision.hxx>
#include <Standard_Type.hxx>
#include <TopAbs_State.hxx>
@@ -65,6 +66,7 @@ IntTools_Context::IntTools_Context()
myProjSDataMap(100, myAllocator),
myBndBoxDataMap(100, myAllocator),
mySurfAdaptorMap(100, myAllocator),
myOBBMap(100, myAllocator),
myCreateFlag(0),
myPOnSTolerance(1.e-12)
{
@@ -86,6 +88,7 @@ IntTools_Context::IntTools_Context
myProjSDataMap(100, myAllocator),
myBndBoxDataMap(100, myAllocator),
mySurfAdaptorMap(100, myAllocator),
myOBBMap(100, myAllocator),
myCreateFlag(1),
myPOnSTolerance(1.e-12)
{
@@ -183,6 +186,16 @@ IntTools_Context::~IntTools_Context()
myAllocator->Free(anAdr);
}
mySurfAdaptorMap.Clear();
//
IntTools_OBB* pOBB;
aIt.Initialize(myOBBMap);
for (; aIt.More(); aIt.Next()) {
anAdr=aIt.Value();
pOBB=(IntTools_OBB*)anAdr;
(*pOBB).~IntTools_OBB();
myAllocator->Free(anAdr);
}
myOBBMap.Clear();
}
//=======================================================================
//function : BndBox
@@ -472,6 +485,35 @@ Geom2dHatch_Hatcher& IntTools_Context::Hatcher(const TopoDS_Face& aF)
return *pHatcher;
}
//=======================================================================
//function : OBB
//purpose :
//=======================================================================
IntTools_OBB& IntTools_Context::OBB(const TopoDS_Shape& aS,
const Standard_Real theFuzzy)
{
Standard_Address anAdr;
IntTools_OBB* pBox;
//
if (!myOBBMap.IsBound(aS))
{
pBox = (IntTools_OBB*)myAllocator->Allocate(sizeof(IntTools_OBB));
new (pBox) IntTools_OBB();
//
IntTools_OBB &aBox = *pBox;
IntTools_Tools::BuildOBB(aS, theFuzzy, aBox);
//
anAdr = (Standard_Address)pBox;
myOBBMap.Bind(aS, anAdr);
}
else
{
anAdr = myOBBMap.Find(aS);
pBox = (IntTools_OBB*)anAdr;
}
return *pBox;
}
//=======================================================================
//function : SurfaceData
//purpose :

View File

@@ -44,7 +44,7 @@ class gp_Pnt2d;
class IntTools_Curve;
class Bnd_Box;
class TopoDS_Shape;
class IntTools_OBB;
//! The intersection Context contains geometrical
//! and topological toolkit (classifiers, projectors, etc).
@@ -98,6 +98,10 @@ Standard_EXPORT virtual ~IntTools_Context();
//! Returns a reference to surface adaptor for given face
Standard_EXPORT BRepAdaptor_Surface& SurfaceAdaptor (const TopoDS_Face& theFace);
//! Returns a reference to surface adaptor for given face
Standard_EXPORT IntTools_OBB& OBB(const TopoDS_Shape& theShape,
const Standard_Real theFuzzy = Precision::Confusion());
//! Computes the boundaries of the face using surface adaptor
Standard_EXPORT void UVBounds (const TopoDS_Face& theFace,
Standard_Real& UMin,
@@ -250,6 +254,7 @@ protected:
BOPCol_DataMapOfShapeAddress myProjSDataMap;
BOPCol_DataMapOfShapeAddress myBndBoxDataMap;
BOPCol_DataMapOfShapeAddress mySurfAdaptorMap;
BOPCol_DataMapOfShapeAddress myOBBMap; //! Map of oriented bounding boxes
Standard_Integer myCreateFlag;
Standard_Real myPOnSTolerance;

View File

@@ -222,7 +222,11 @@ Standard_Boolean IntTools_EdgeFace::IsCoincident()
//
GeomAPI_ProjectPointOnSurf& aProjector=myContext->ProjPS(myFace);
const Standard_Integer aNbSeg=23;
Standard_Integer aNbSeg=23;
if (myC.GetType() == GeomAbs_Line &&
myS.GetType() == GeomAbs_Plane)
aNbSeg = 2; // Check only three points for Line/Plane intersection
const Standard_Real aTresh=0.5;
const Standard_Integer aTreshIdxF = RealToInt((aNbSeg+1)*0.25),
aTreshIdxL = RealToInt((aNbSeg+1)*0.75);

View File

@@ -0,0 +1,125 @@
// Created by: Eugeny MALTCHIKOV
// Copyright (c) 2017 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <IntTools_OBB.hxx>
#include <Bnd_B3d.hxx>
// =======================================================================
// function : IsOut
// purpose :
// =======================================================================
Standard_Boolean IntTools_OBB::IsOut(const IntTools_OBB& theOther) const
{
if (IsVoid() || theOther.IsVoid())
return Standard_False;
if (myIsAABox && theOther.myIsAABox)
{
// Both boxes are axis aligned - PMax points should be defined in this case.
// Use Bnd_B3d::IsOut method to check if the boxes are interfering
Bnd_B3d myB3d(myCenter, gp_Vec(myPMin, myCenter).XYZ());
Bnd_B3d otherB3d(theOther.myCenter, gp_Vec(theOther.myPMin, theOther.myCenter).XYZ());
return myB3d.IsOut(otherB3d);
}
// According to the Separating Axis Theorem for Oriented Bounding Boxes
// it is necessary to check the 15 separating axes:
// - 6 axes of the boxes;
// - 9 cross products of the axes of the boxes.
// If any of these axes is valid, the boxes do not interfere.
// The algorithm is following:
// 1. For the analyzed axis L:
// 2. Half of boxes vertices are projected onto the axis.
// 3. The projection segments for each box are computed.
// The length of the segment will be:
// Abs((HDimX*DirX).Dot(L)) + Abs((HDimY*DirY).Dot(L)) + Abs((HDimZ*DirZ).Dot(L))
// 3. It is necessary to check if the distance between centers of the boxes
// projected onto the axis is more than the sum of the lengths
// of the projection segments:
// isOut = (theCenter2 - theCenter1).Dot(L) > (Length1 + Length2);
// Precomputed difference between centers
gp_XYZ D = theOther.myCenter - myCenter;
// Check the axes of the this box, i.e. L is one of myAxes
// Since the Dot product of two of these directions is null, it could be skipped:
// myXDirection.Dot(myYDirection) = 0
for (Standard_Integer i = 0; i < 3; ++i)
{
// Length of the first segment
Standard_Real aLSegm1 = myHDims[i];
// Length of the second segment
Standard_Real aLSegm2 = 0;
for (Standard_Integer j = 0; j < 3; ++j)
aLSegm2 += Abs(theOther.myAxesMultiplied[j].Dot(myAxes[i]));
// Distance between projected centers
Standard_Real aDistCC = Abs(D.Dot(myAxes[i]));
if (aDistCC > aLSegm1 + aLSegm2)
return Standard_True;
}
// Check the axes of the Other box, i.e. L is one of theOther.myAxes
for (Standard_Integer i = 0; i < 3; ++i)
{
// Length of the first segment
Standard_Real aLSegm1 = 0.;
for (Standard_Integer j = 0; j < 3; ++j)
aLSegm1 += Abs(myAxesMultiplied[j].Dot(theOther.myAxes[i]));
// Length of the second segment
Standard_Real aLSegm2 = theOther.myHDims[i];
// Distance between projected centers
Standard_Real aDistCC = Abs(D.Dot(theOther.myAxes[i]));
if (aDistCC > aLSegm1 + aLSegm2)
return Standard_True;
}
// Check the axes produced by the cross products
for (Standard_Integer i = 0; i < 3; ++i)
{
for (Standard_Integer j = 0; j < 3; ++j)
{
// Separating axis
gp_XYZ L = myAxes[i].Crossed(theOther.myAxes[j]);
// Length of the first segment
Standard_Real aLSegm1 = 0.;
for (Standard_Integer k = 0; k < 3; ++k)
aLSegm1 += Abs(myAxesMultiplied[k].Dot(L));
// Length of the second segment
Standard_Real aLSegm2 = 0.;
for (Standard_Integer k = 0; k < 3; ++k)
aLSegm2 += Abs(theOther.myAxesMultiplied[k].Dot(L));
// Distance between projected centers
Standard_Real aDistCC = Abs(D.Dot(L));
if (aDistCC > aLSegm1 + aLSegm2)
return Standard_True;
}
}
return Standard_False;
}

View File

@@ -0,0 +1,199 @@
// Created by: Eugeny MALTCHIKOV
// Copyright (c) 2017 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _IntTools_OBB_HeaderFile
#define _IntTools_OBB_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <Standard_Real.hxx>
#include <Standard_Boolean.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <gp_XYZ.hxx>
//! The class describes the Oriented Bounding Box (OBB).
//! It is defined by a center of the box, the axes and the halves
//! of its three dimensions.
//! The OBB are used as a second step, after intersection of the
//! axes aligned boxes, for filtering the time-consuming interfering pairs
//! in Boolean Operations.
class IntTools_OBB
{
public:
DEFINE_STANDARD_ALLOC
//! Empty constructor
IntTools_OBB()
:
myIsAABox(Standard_False)
{
myHDims[0] = 0.;
myHDims[1] = 0.;
myHDims[2] = 0.;
}
//! Constructor taking all defining parameters
IntTools_OBB(const gp_Pnt& theCenter,
const gp_Dir& theXDirection,
const gp_Dir& theYDirection,
const gp_Dir& theZDirection,
const Standard_Real theHXSize,
const Standard_Real theHYSize,
const Standard_Real theHZSize)
:
myCenter (theCenter.XYZ()),
myIsAABox(Standard_False)
{
myAxes[0] = theXDirection.XYZ();
myAxes[1] = theYDirection.XYZ();
myAxes[2] = theZDirection.XYZ();
myHDims[0] = theHXSize;
myHDims[1] = theHYSize;
myHDims[2] = theHZSize;
myAxesMultiplied[0] = myAxes[0].Multiplied(myHDims[0]);
myAxesMultiplied[1] = myAxes[1].Multiplied(myHDims[1]);
myAxesMultiplied[2] = myAxes[2].Multiplied(myHDims[2]);
}
//! Sets the center of OBB
void SetCenter(const gp_Pnt& theCenter)
{
myCenter = theCenter.XYZ();
}
//! Returns the center of OBB
const gp_XYZ& Center() const
{
return myCenter;
}
//! Sets the X component of OBB - direction and size
void SetXComponent(const gp_Dir& theXDirection,
const Standard_Real theHXSize)
{
myAxes[0] = theXDirection.XYZ();
myHDims[0] = theHXSize;
myAxesMultiplied[0] = myAxes[0].Multiplied(myHDims[0]);
}
//! Returns the X Direction of OBB
const gp_XYZ& XDirection() const
{
return myAxes[0];
}
//! Returns the X Dimension of OBB
Standard_Real HXSize() const
{
return myHDims[0];
}
//! Sets the Y component of OBB - direction and size
void SetYComponent(const gp_Dir& theYDirection,
const Standard_Real theHYSize)
{
myAxes[1] = theYDirection.XYZ();
myHDims[1] = theHYSize;
myAxesMultiplied[1] = myAxes[1].Multiplied(myHDims[1]);
}
//! Returns the Y Direction of OBB
const gp_XYZ& YDirection() const
{
return myAxes[1];
}
//! Returns the Y Dimension of OBB
Standard_Real HYSize() const
{
return myHDims[1];
}
//! Sets the Z component of OBB - direction and size
void SetZComponent(const gp_Dir& theZDirection,
const Standard_Real theHZSize)
{
myAxes[2] = theZDirection.XYZ();
myHDims[2] = theHZSize;
myAxesMultiplied[2] = myAxes[2].Multiplied(myHDims[2]);
}
//! Returns the Z Direction of OBB
const gp_XYZ& ZDirection() const
{
return myAxes[2];
}
//! Returns the Z Dimension of OBB
Standard_Real HZSize() const
{
return myHDims[2];
}
//! Checks if the box is empty.
Standard_Boolean IsVoid() const
{
return (((myHDims[0] + myHDims[1] + myHDims[2]) < gp::Resolution()) && !myIsAABox);
}
//! Sets the flag for axes aligned box
void SetAABox(const Standard_Boolean& theFlag)
{
myIsAABox = theFlag;
}
//! Returns TRUE if the box is axes aligned
Standard_Boolean IsAABox() const
{
return myIsAABox;
}
//! Sets the min point
void SetMinPoint(const gp_Pnt& theMin)
{
myPMin = theMin.XYZ();
}
//! Returns the min point of the box
const gp_XYZ& MinPoint() const
{
return myPMin;
}
//! Check if the box do not interfere the other box.
Standard_EXPORT Standard_Boolean IsOut(const IntTools_OBB& theOther) const;
private:
// OBB definition
gp_XYZ myCenter; //! Center of the OBB
gp_XYZ myAxes[3]; //! The axes of the box
Standard_Real myHDims[3]; //! Half-size dimensions of the OBB
gp_XYZ myAxesMultiplied[3]; //! Multiplied axes to avoid their recalculation in IsOut method
Standard_Boolean myIsAABox; //! To be set if the OBB is axis aligned box;
gp_XYZ myPMin; //! Min point of the box.
};
#endif

View File

@@ -56,6 +56,18 @@
#include <TopoDS_Wire.hxx>
#include <TopTools_IndexedDataMapOfShapeShape.hxx>
#include <gp_Ax3.hxx>
#include <BRepGProp.hxx>
#include <BRepBndLib.hxx>
#include <GProp_GProps.hxx>
#include <GProp_PrincipalProps.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <IntTools_OBB.hxx>
#ifdef DEBUG_OBB
#include <BRepPrimAPI_MakeBox.hxx>
#endif
static
void ParabolaTolerance(const Handle(Geom_Curve)& ,
const Standard_Real ,
@@ -840,3 +852,113 @@ Standard_Real IntTools_Tools::ComputeIntRange(const Standard_Real theTol1,
//
return aDt;
}
//=======================================================================
// Function : BuildOBB
// purpose :
//=======================================================================
void IntTools_Tools::BuildOBB(const TopoDS_Shape& theS,
const Standard_Real theFuzzy,
IntTools_OBB& theOBB)
{
// Compute the transformation matrix to obtain more tight bounding box
GProp_GProps G;
switch (theS.ShapeType())
{
case TopAbs_VERTEX:
{
// Just make the AA box
const gp_Pnt& aP = BRep_Tool::Pnt(TopoDS::Vertex(theS));
Bnd_Box aBox;
aBox.Add(aP);
aBox.SetGap(BRep_Tool::Tolerance(TopoDS::Vertex(theS)) + theFuzzy);
theOBB.SetCenter(aP);
theOBB.SetXComponent(gp_Dir(1, 0, 0), aBox.GetGap());
theOBB.SetYComponent(gp_Dir(0, 1, 0), aBox.GetGap());
theOBB.SetZComponent(gp_Dir(0, 0, 1), aBox.GetGap());
theOBB.SetAABox(Standard_True);
theOBB.SetMinPoint(aBox.CornerMin());
return;
}
case TopAbs_EDGE:
BRepGProp::LinearProperties(theS, G, Standard_True);
break;
case TopAbs_FACE:
BRepGProp::SurfaceProperties(theS, G, Standard_True);
break;
case TopAbs_SOLID:
BRepGProp::VolumeProperties(theS, G, Standard_True);
break;
default:
break;
}
// Coordinate system in which the shape will have the optimal bounding box
gp_Ax3 aLocCoordSys(G.CentreOfMass(),
G.PrincipalProperties().ThirdAxisOfInertia(),
G.PrincipalProperties().FirstAxisOfInertia());
// Transform the shape to the local coordinate system
gp_Trsf aTrsf;
aTrsf.SetTransformation(aLocCoordSys);
BRepBuilderAPI_Transform aTransformer(theS, aTrsf);
if (aTransformer.IsDone())
{
const TopoDS_Shape& aST = aTransformer.Shape();
// Build the bounding box for oriented shape
Bnd_Box anOBB;
BRepBndLib::Add(aST, anOBB);
anOBB.SetGap(theFuzzy);
// Create the OBB box
gp_Pnt aPMin = anOBB.CornerMin();
gp_Pnt aPMax = anOBB.CornerMax();
// Compute the center of the box
gp_XYZ aCenter = (aPMin.XYZ() + aPMax.XYZ()) / 2.;
aTrsf.Inverted().Transforms(aCenter);
// Compute the half diagonal size of the box
gp_XYZ anOBBHSize = (aPMax.XYZ() - aPMin.XYZ()) / 2.;
// Make transformation
const Standard_Real * aMat = &aTrsf.Inverted().HVectorialPart().Value(1, 1);
// Compute axes directions of the box
gp_XYZ aXDir(aMat[0], aMat[3], aMat[6]);
gp_XYZ aYDir(aMat[1], aMat[4], aMat[7]);
gp_XYZ aZDir(aMat[2], aMat[5], aMat[8]);
theOBB.SetCenter(aCenter);
theOBB.SetXComponent(aXDir, anOBBHSize.X());
theOBB.SetYComponent(aYDir, anOBBHSize.Y());
theOBB.SetZComponent(aZDir, anOBBHSize.Z());
gp_XYZ aPMinXYZ = aPMin.XYZ();
aTrsf.Inverted().Transforms(aPMinXYZ);
theOBB.SetMinPoint(aPMinXYZ);
#ifdef DEBUG_OBB
// Get the obtained box
GetOBBShapeBox(theOBB);
#endif
}
}
#ifdef DEBUG_OBB
//=======================================================================
// Function : GetOBBShapeBox
// purpose :
//=======================================================================
TopoDS_Shape IntTools_Tools::GetOBBShapeBox(const IntTools_OBB& theOBB)
{
gp_Ax2 axis(theOBB.MinPoint(), theOBB.ZDirection());
axis.SetXDirection(theOBB.XDirection());
BRepPrimAPI_MakeBox aSMaker(axis, 2 * theOBB.HXSize(), 2 * theOBB.HYSize(), 2 * theOBB.HZSize());
const TopoDS_Shape& aSolid = aSMaker.Solid();
return aSolid;
}
#endif

View File

@@ -42,7 +42,7 @@ class gp_Lin;
class gp_Pln;
class Geom2d_Curve;
class Geom_Surface;
class IntTools_OBB;
//! The class contains handy static functions
@@ -183,6 +183,16 @@ public:
const Standard_Real theAngle);
//! Computes the Oriented Bounding box for the shape
Standard_EXPORT static void BuildOBB(const TopoDS_Shape& theS,
const Standard_Real theFuzzy,
IntTools_OBB& theOBB);
#ifdef DEBUG_OBB
//! Get the solid built from the OBB box
Standard_EXPORT static TopoDS_Shape GetOBBShapeBox(const IntTools_OBB& theOBB);
#endif
protected:

View File

@@ -1,5 +1,3 @@
puts "TODO ?OCC26018 ALL: Faulty shapes in variables faulty_1 to faulty_"
# test script for freeform_revol_01.prt.1.gdml file
compound result

View File

@@ -0,0 +1,28 @@
puts "========"
puts "OCC28485"
puts "========"
puts ""
##################################################################################
# Fuse of two shapes using gluing and non-destructive options gives invalid result
##################################################################################
restore [locate_data_file bug28485_parts.brep] a
explode a
bnondestructive 1
brunparallel 1
bfuzzyvalue 0
bglue 1
bclearobjects
bcleartools
baddobjects a_1
baddtools a_2
bfillds
bbop result 1
checkshape result
checknbshapes result -wire 324 -face 310 -shell 1 -solid 1
checkprops result -s 103610 -v 111128
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,28 @@
puts "========"
puts "OCC28485"
puts "========"
puts ""
##################################################################################
# Fuse of two shapes using gluing and non-destructive options gives invalid result
##################################################################################
box b1 10 10 10
box b2 10 2 2 6 6 6
nurbsconvert b1 b1
nurbsconvert b2 b2
bnondestructive 1
brunparallel 1
bfuzzyvalue 0
bglue 1
bclearobjects
bcleartools
baddobjects b1
baddtools b2
bfillds
bbop result 1
checkshape result
checknbshapes result -vertex 16 -edge 24 -wire 12 -face 11 -shell 1 -solid 1
checkprops result -s 744 -v 1216

View File

@@ -1,5 +1,6 @@
puts "TODO CR27414 ALL: Error : The area of result shape is"
puts "TODO CR27414 ALL: Error : The volume of result shape is"
puts "TODO OCC27414 ALL: Error: The command cannot be built"
puts "TODO OCC27414 ALL: gives an empty result"
puts "TODO OCC27414 ALL: TEST INCOMPLETE"
restore [locate_data_file bug26917_dom-7724_trim3.brep] s

View File

@@ -1,5 +1,6 @@
puts "TODO CR27414 ALL: Error : The area of result shape is"
puts "TODO CR27414 ALL: Error : The volume of result shape is"
puts "TODO OCC27414 ALL: Error: The command cannot be built"
puts "TODO OCC27414 ALL: gives an empty result"
puts "TODO OCC27414 ALL: TEST INCOMPLETE"
restore [locate_data_file bug26917_dom-7724_trim9.brep] s

View File

@@ -0,0 +1,10 @@
restore [locate_data_file bug29135_offset.input.fail_1.brep] s
OFFSETSHAPE 1 {} $calcul $type
checkprops result -v 6.89371e+007 -s 4.41612e+006
unifysamedom result_unif result
checknbshapes result_unif -face 1514 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,10 @@
restore [locate_data_file bug29135_offset.input.fail_1.brep] s
OFFSETSHAPE 3 {} $calcul $type
checkprops result -v 7.76896e+007 -s 4.33462e+006
unifysamedom result_unif result
checknbshapes result_unif -face 1516 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,10 @@
restore [locate_data_file bug29135_offset.input.fail_1.brep] s
OFFSETSHAPE 5 {} $calcul $type
checkprops result -v 8.62708e+007 -s 4.23599e+006
unifysamedom result_unif result
checknbshapes result_unif -face 1504 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,10 @@
restore [locate_data_file bug29135_offset.input.fail_1_trim.brep] s
OFFSETSHAPE 1 {} $calcul $type
checkprops result -v 770085 -s 101331
unifysamedom result_unif result
checknbshapes result_unif -face 50 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,10 @@
restore [locate_data_file bug29135_offset.input.fail_1_trim.brep] s
OFFSETSHAPE 3 {} $calcul $type
checkprops result -v 984252 -s 112873
unifysamedom result_unif result
checknbshapes result_unif -face 50 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,10 @@
restore [locate_data_file bug29135_offset.input.fail_1_trim.brep] s
OFFSETSHAPE 5 {} $calcul $type
checkprops result -v 1.22084e+006 -s 123525
unifysamedom result_unif result
checknbshapes result_unif -face 50 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,12 @@
restore [locate_data_file bug29188_offset.input.fail_2.brep] s
offsetparameter 1.e-7 c i r
offsetload s 1
offsetperform result
checkprops result -s 3.8337e+006 -v 9.03404e+007
unifysamedom result_unif result
checknbshapes result_unif -vertex 2424 -edge 3636 -wire 1214 -face 1214 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,12 @@
restore [locate_data_file bug29188_offset.input.fail_2.brep] s
offsetparameter 1.e-7 c i r
offsetload s 2
offsetperform result
checkprops result -s 3.78989e+006 -v 9.41523e+007
unifysamedom result_unif result
checknbshapes result_unif -vertex 2414 -edge 3621 -wire 1209 -face 1209 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,12 @@
restore [locate_data_file bug29188_offset.input.fail_2.brep] s
offsetparameter 1.e-7 c i r
offsetload s 4
offsetperform result
checkprops result -s 3.59077e+006 -v 1.01607e+008
unifysamedom result_unif result
checknbshapes result_unif -vertex 760 -edge 1140 -wire 382 -face 382 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,12 @@
restore [locate_data_file bug29188_offset.input.fail_2_trim1.brep] s
offsetparameter 1.e-7 c i r
offsetload s 1
offsetperform result
checkprops result -s 14593.4 -v 73831.6
unifysamedom result_unif result
checknbshapes result_unif -vertex 18 -edge 27 -wire 11 -face 11 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,12 @@
restore [locate_data_file bug29188_offset.input.fail_2_trim1.brep] s
offsetparameter 1.e-7 c i r
offsetload s 2
offsetperform result
checkprops result -s 15689.6 -v 88931
unifysamedom result_unif result
checknbshapes result_unif -vertex 12 -edge 18 -wire 8 -face 8 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,12 @@
restore [locate_data_file bug29188_offset.input.fail_2_trim1.brep] s
offsetparameter 1.e-7 c i r
offsetload s 15
offsetperform result
checkprops result -s 38954.1 -v 435324
unifysamedom result_unif result
checknbshapes result_unif -vertex 12 -edge 18 -wire 8 -face 8 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,12 @@
restore [locate_data_file bug29188_offset.input.fail_2_trim2.brep] s
offsetparameter 1.e-7 c i r
offsetload s 1
offsetperform result
checkprops result -s 7573.52 -v 22082
unifysamedom result_unif result
checknbshapes result_unif -vertex 16 -edge 24 -wire 10 -face 10 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,12 @@
restore [locate_data_file bug29188_offset.input.fail_2_trim2.brep] s
offsetparameter 1.e-7 c i r
offsetload s 4
offsetperform result
checkprops result -s 11270.1 -v 50239.3
unifysamedom result_unif result
checknbshapes result_unif -vertex 14 -edge 21 -wire 9 -face 9 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,12 @@
restore [locate_data_file bug29188_offset.input.fail_2_trim2.brep] s
offsetparameter 1.e-7 c i r
offsetload s 15
offsetperform result
checkprops result -s 29345 -v 268160
unifysamedom result_unif result
checknbshapes result_unif -vertex 12 -edge 18 -wire 8 -face 8 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,27 @@
restore [locate_data_file bug29188_xm6_trim.brep] s
offsetparameter 1.e-7 c i r
offsetload s 4
foreach f [explode s f] {
mksurface surf $f
set found [regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
if {$found && abs(abs($z) - 1) < 1.e-7} {
offsetonface $f 3
} else {
if { y < -0.7 } {
offsetonface $f 5
} else {
if { y > 0.7 } {
offsetonface $f 3
}
}
}
}
offsetperform result
checkprops result -s 34789.1 -v 364306
unifysamedom result_unif result
checknbshapes result_unif -vertex 26 -edge 39 -wire 15 -face 15 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,19 @@
restore [locate_data_file bug29188_xb4_trim.brep] s
offsetparameter 1.e-7 c i r
offsetload s 10
foreach f [explode s f] {
mksurface surf $f
set found [regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
if {$found && abs(abs($z) - 1) < 1.e-7} {
offsetonface $f 0
}
}
offsetperform result
checkprops result -s 83647.4 -v 1.00827e+006
unifysamedom result_unif result
checknbshapes result_unif -vertex 31 -edge 47 -wire 18 -face 18 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,12 @@
restore [locate_data_file bug29188_zt8_trim.brep] s
offsetparameter 1.e-7 c i r
offsetload s 5
offsetperform result
checkprops result -s 43255.5 -v 461843
unifysamedom result_unif result
checknbshapes result_unif -vertex 14 -edge 21 -wire 9 -face 9 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,12 @@
restore [locate_data_file bug29188_zt8_trim.brep] s
offsetparameter 1.e-7 c i r
offsetload s 10
offsetperform result
checkprops result -s 56967.2 -v 711670
unifysamedom result_unif result
checknbshapes result_unif -vertex 14 -edge 21 -wire 9 -face 9 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -1,12 +1,12 @@
puts "TODO OCC27414 ALL: Error: The command cannot be built"
puts "TODO OCC27414 ALL: gives an empty result"
puts "TODO OCC27414 ALL: TEST INCOMPLETE"
restore [locate_data_file bug26917_t114_c2.recipe.brep] s
OFFSETSHAPE 35 {} $calcul $type
offsetparameter 1.e-7 c i r
offsetload s 35
offsetperform result
checkprops result -v 7.93275e+008
checkprops result -s 6.15377e+006
checkprops result -s 6.15377e+006 -v 7.93275e+008
checknbshapes result -shell 1
unifysamedom result_unif result
checknbshapes result_unif -vertex 64 -edge 96 -wire 34 -face 34 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -1,12 +1,12 @@
puts "TODO OCC27414 ALL: Error: The command cannot be built"
puts "TODO OCC27414 ALL: gives an empty result"
puts "TODO OCC27414 ALL: TEST INCOMPLETE"
restore [locate_data_file bug26917_t115_c2.recipe.brep] s
OFFSETSHAPE 35 {} $calcul $type
offsetparameter 1.e-7 c i r
offsetload s 35
offsetperform result
checkprops result -v 7.93275e+008
checkprops result -s 6.15377e+006
checkprops result -s 6.15377e+006 -v 7.93275e+008
checknbshapes result -shell 1
unifysamedom result_unif result
checknbshapes result_unif -vertex 64 -edge 96 -wire 34 -face 34 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -1,12 +1,12 @@
puts "TODO OCC27414 ALL: Error: The command cannot be built"
puts "TODO OCC27414 ALL: gives an empty result"
puts "TODO OCC27414 ALL: TEST INCOMPLETE"
restore [locate_data_file bug26917_t116_c2.recipe.brep] s
OFFSETSHAPE 35 {} $calcul $type
offsetparameter 1.e-7 c i r
offsetload s 35
offsetperform result
checkprops result -v 8.96742e+008
checkprops result -s 6.85555e+006
checkprops result -s 6.85555e+006 -v 8.96742e+008
checknbshapes result -shell 1
unifysamedom result_unif result
checknbshapes result_unif -vertex 64 -edge 96 -wire 34 -face 34 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -1,12 +1,12 @@
puts "TODO OCC27414 ALL: Error: The command cannot be built"
puts "TODO OCC27414 ALL: gives an empty result"
puts "TODO OCC27414 ALL: TEST INCOMPLETE"
restore [locate_data_file bug26917_t130_c2.recipe.brep] s
OFFSETSHAPE 35 {} $calcul $type
offsetparameter 1.e-7 c i r
offsetload s 35
offsetperform result
checkprops result -v 6.89789e+008
checkprops result -s 5.45195e+006
checkprops result -s 5.45195e+006 -v 6.89789e+008
checknbshapes result -shell 1
unifysamedom result_unif result
checknbshapes result_unif -vertex 64 -edge 96 -wire 34 -face 34 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -1,12 +1,12 @@
puts "TODO OCC27414 ALL: Error: The command cannot be built"
puts "TODO OCC27414 ALL: gives an empty result"
puts "TODO OCC27414 ALL: TEST INCOMPLETE"
restore [locate_data_file bug26917_t137_c2.recipe.brep] s
OFFSETSHAPE 35 {} $calcul $type
offsetparameter 1.e-7 c i r
offsetload s 35
offsetperform result
checkprops result -v 8.96742e+008
checkprops result -s 6.85555e+006
checkprops result -s 6.85555e+006 -v 8.96742e+008
checknbshapes result -shell 1
unifysamedom result_unif result
checknbshapes result_unif -vertex 64 -edge 96 -wire 34 -face 34 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -1,12 +1,12 @@
puts "TODO OCC27414 ALL: Error: The command cannot be built"
puts "TODO OCC27414 ALL: gives an empty result"
puts "TODO OCC27414 ALL: TEST INCOMPLETE"
restore [locate_data_file bug26917_t114_c2.recipe_art1.brep] s
OFFSETSHAPE 2 {} $calcul $type
offsetparameter 1.e-7 c i r
offsetload s 2
offsetperform result
checkprops result -v 475
checkprops result -s 454.58
checkprops result -s 454.58 -v 475
checknbshapes result -shell 1
unifysamedom result_unif result
checknbshapes result_unif -vertex 14 -edge 21 -wire 9 -face 9 -shell 1
checkview -display result_unif -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,46 @@
puts "======="
puts "0029237"
puts "======="
puts ""
##################################################
# Improve performance of Boolean Operations
##################################################
brestore [locate_data_file bug29237_tc_43.1_lhs.brep] a
brestore [locate_data_file bug29237_tc_43.1_rhs.brep] b
bglue 1
bcheckinverted 0
bclearobjects
bcleartools
baddobjects a
baddtools b
# start chronometer
dchrono cpu restart
bfillds
bcbuild r
# build the result of cut
bcremoveall
bcadd rcut a 1 b 0
# build the result of common
bcremoveall
bcadd rcommon a 1 b 1
# stop chronometer
dchrono cpu stop counter OCC29237
# check the result of CUT
checkshape rcut
checknbshapes rcut -vertex 640 -edge 1760 -wire 842 -face 842 -shell 1 -solid 1
checkprops rcut -s 3.4136e+006 -v 2.9712e+007
# check the result of COMMON
checkshape rcommon
checknbshapes rcommon -vertex 616 -edge 1484 -wire 882 -face 882 -shell 147 -solid 147
checkprops rcommon -s 2.13392e+006 -v 1.6448e+007

View File

@@ -0,0 +1,46 @@
puts "======="
puts "0029237"
puts "======="
puts ""
##################################################
# Improve performance of Boolean Operations
##################################################
brestore [locate_data_file bug29237_dom8364_s32_c2.lhs.brep] a
brestore [locate_data_file bug29237_dom8364_s32_c2.rhs.brep] b
bglue 1
bcheckinverted 0
bclearobjects
bcleartools
baddobjects a
baddtools b
# start chronometer
dchrono cpu restart
bfillds
bcbuild r
# build the result of cut
bcremoveall
bcadd rcut a 1 b 0
# build the result of common
bcremoveall
bcadd rcommon a 1 b 1
# stop chronometer
dchrono cpu stop counter OCC29237
# check the result of CUT
checkshape rcut
checknbshapes rcut -vertex 7374 -edge 13894 -wire 4944 -face 4711 -shell 29 -solid 29
checkprops rcut -s 5.81474e+006 -v 1.32791e+007
# check the result of COMMON
checkshape rcommon
checknbshapes rcommon -vertex 6454 -edge 9662 -wire 4462 -face 4462 -shell 627 -solid 627
checkprops rcommon -s 1.81935e+006 -v 1.6368e+006

View File

@@ -0,0 +1,46 @@
puts "======="
puts "0029237"
puts "======="
puts ""
##################################################
# Improve performance of Boolean Operations
##################################################
brestore [locate_data_file bug29237_no_overlap.lhs.brep] a
brestore [locate_data_file bug29237_no_overlap.rhs.brep] b
bglue 1
bcheckinverted 0
bclearobjects
bcleartools
baddobjects a
baddtools b
# start chronometer
dchrono cpu restart
bfillds
bcbuild r
# build the result of cut
bcremoveall
bcadd rcut a 1 b 0
# build the result of common
bcremoveall
bcadd rcommon a 1 b 1
# stop chronometer
dchrono cpu stop counter OCC29237
# check the result of CUT
checkshape rcut
checknbshapes rcut -vertex 1294 -edge 3074 -wire 1842 -face 1842 -shell 301 -solid 301
checkprops rcut -s 2.59678e+006 -v 1.5346e+007
# check the result of COMMON
checkshape rcommon
checknbshapes rcommon -vertex 0 -edge 0 -wire 0 -face 0 -shell 0 -solid 0
checkprops rcommon -s empty -v empty