mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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());
|
||||
|
@@ -50,7 +50,8 @@ BOPAlgo_Options::BOPAlgo_Options()
|
||||
myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
|
||||
myReport(new Message_Report),
|
||||
myRunParallel(myGlobalRunParallel),
|
||||
myFuzzyValue(Precision::Confusion())
|
||||
myFuzzyValue(Precision::Confusion()),
|
||||
myCheckInverted(Standard_True)
|
||||
{
|
||||
BOPAlgo_LoadMessages();
|
||||
}
|
||||
@@ -65,7 +66,8 @@ BOPAlgo_Options::BOPAlgo_Options
|
||||
myAllocator(theAllocator),
|
||||
myReport(new Message_Report),
|
||||
myRunParallel(myGlobalRunParallel),
|
||||
myFuzzyValue(Precision::Confusion())
|
||||
myFuzzyValue(Precision::Confusion()),
|
||||
myCheckInverted(Standard_True)
|
||||
{
|
||||
BOPAlgo_LoadMessages();
|
||||
}
|
||||
|
@@ -32,6 +32,10 @@ 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.
|
||||
//!
|
||||
class BOPAlgo_Options
|
||||
{
|
||||
@@ -156,6 +160,22 @@ 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;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//! Breaks the execution if the break signal
|
||||
@@ -169,6 +189,7 @@ protected:
|
||||
Standard_Boolean myRunParallel;
|
||||
Standard_Real myFuzzyValue;
|
||||
Handle(Message_ProgressIndicator) myProgressIndicator;
|
||||
Standard_Boolean myCheckInverted;
|
||||
|
||||
};
|
||||
|
||||
|
@@ -207,34 +207,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);
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
||||
|
@@ -61,8 +61,6 @@ Standard_EXPORT virtual ~BOPAlgo_ShellSplitter();
|
||||
|
||||
protected:
|
||||
|
||||
Standard_EXPORT void MakeConnexityBlocks();
|
||||
|
||||
Standard_EXPORT void MakeShells();
|
||||
|
||||
|
||||
|
@@ -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:
|
||||
|
@@ -70,8 +70,6 @@ protected:
|
||||
|
||||
Standard_EXPORT virtual void CheckData() Standard_OVERRIDE;
|
||||
|
||||
Standard_EXPORT void MakeConnexityBlocks();
|
||||
|
||||
Standard_EXPORT void MakeWires();
|
||||
|
||||
BOPAlgo_PWireEdgeSet myWES;
|
||||
|
Reference in New Issue
Block a user