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

Fix for regressions for case infinite box ( case 46)

This commit is contained in:
gka
2014-10-30 19:03:55 +03:00
parent 097a0cae0f
commit 3796cb32b2
4 changed files with 431 additions and 354 deletions

View File

@@ -74,6 +74,7 @@ is
class CheckerSI; class CheckerSI;
class ArgumentAnalyzer; class ArgumentAnalyzer;
class CheckResult; class CheckResult;
class ShellSplitter;
-- --
-- pointers -- pointers
-- --

View File

@@ -57,6 +57,8 @@
#include <BOPCol_DataMapOfShapeShape.hxx> #include <BOPCol_DataMapOfShapeShape.hxx>
#include <BOPCol_DataMapOfShapeListOfShape.hxx> #include <BOPCol_DataMapOfShapeListOfShape.hxx>
#include <BOPCol_MapOfShape.hxx> #include <BOPCol_MapOfShape.hxx>
#include <BRepBndLib.hxx>
#include <Bnd_Box.hxx>
static static
@@ -444,6 +446,7 @@ TopAbs_Orientation BOPAlgo_BuilderFace::Orientation()const
} }
// //
// 2. Find outer growth shell that is most close to each hole shell // 2. Find outer growth shell that is most close to each hole shell
BOPCol_ListOfShape anUnUsedHoles;
aIt2.Initialize(aHoleWires); aIt2.Initialize(aHoleWires);
for (; aIt2.More(); aIt2.Next()) { for (; aIt2.More(); aIt2.Next()) {
const TopoDS_Shape& aHole = aIt2.Value(); const TopoDS_Shape& aHole = aIt2.Value();
@@ -481,8 +484,26 @@ TopAbs_Orientation BOPAlgo_BuilderFace::Orientation()const
aMSH.Bind(aF, aLH); aMSH.Bind(aF, aLH);
} }
} }
else {
anUnUsedHoles.Append(aHole);
}
}// for (; aIt2.More(); aIt2.Next()) }// for (; aIt2.More(); aIt2.Next())
// //
if (anUnUsedHoles.Extent()) {
// add the infinite face to new faces
Bnd_Box aBox;
BRepBndLib::Add(myFace, aBox);
if (aBox.IsOpenXmin() || aBox.IsOpenXmax() ||
aBox.IsOpenYmin() || aBox.IsOpenYmax() ||
aBox.IsOpenZmin() || aBox.IsOpenZmax()) {
TopoDS_Face aFace;
aBB.MakeFace(aFace, aS, aLoc, aTol);
//
aNewFaces.Append(aFace);
aMSH.Bind(aFace, anUnUsedHoles);
}
}
//
// 3. Add aHoles to Faces // 3. Add aHoles to Faces
aItMSH.Initialize(aMSH); aItMSH.Initialize(aMSH);
for (; aItMSH.More(); aItMSH.Next()) { for (; aItMSH.More(); aItMSH.Next()) {

View File

@@ -6,29 +6,35 @@
// //
// This file is part of Open CASCADE Technology software library. // This file is part of Open CASCADE Technology software library.
// //
// This library is free software; you can redistribute it and / or modify it // This library is free software; you can redistribute it and/or modify it under
// under the terms of the GNU Lesser General Public version 2.1 as published // 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 // 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 // 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. // distribution for complete text of the license and disclaimer of any warranty.
// //
// Alternatively, this file may be used under the terms of Open CASCADE // Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement. // commercial license or contractual agreement.
//
#include <BOPAlgo_BuilderSolid.ixx> #include <BOPAlgo_BuilderSolid.ixx>
//
#include <NCollection_List.hxx>
#include <NCollection_DataMap.hxx>
#include <NCollection_UBTreeFiller.hxx>
//
#include <gp_Pnt2d.hxx> #include <gp_Pnt2d.hxx>
#include <gp_Pln.hxx> #include <gp_Pln.hxx>
#include <gp_Vec.hxx> #include <gp_Vec.hxx>
#include <gp_Dir.hxx> #include <gp_Dir.hxx>
#include <gp_Pnt.hxx> #include <gp_Pnt.hxx>
//
#include <TColStd_MapIntegerHasher.hxx>
//
#include <Geom_Curve.hxx> #include <Geom_Curve.hxx>
#include <Geom_Surface.hxx> #include <Geom_Surface.hxx>
#include <Geom2d_Curve.hxx> #include <Geom2d_Curve.hxx>
//
#include <TopAbs.hxx> #include <TopAbs.hxx>
//
#include <TopoDS_Iterator.hxx> #include <TopoDS_Iterator.hxx>
#include <TopoDS_Face.hxx> #include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx> #include <TopoDS_Shape.hxx>
@@ -40,25 +46,32 @@
#include <BRep_Builder.hxx> #include <BRep_Builder.hxx>
#include <BRep_Tool.hxx> #include <BRep_Tool.hxx>
#include <BRepTools.hxx> //
#include <BRepClass3d_SolidClassifier.hxx>
#include <TopExp.hxx> #include <TopExp.hxx>
#include <TopExp_Explorer.hxx> #include <TopExp_Explorer.hxx>
// //
#include <BOPTools_AlgoTools.hxx> #include <BRepBndLib.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
//
#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx> #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
#include <BOPTools.hxx>
#include <BOPCol_ListOfShape.hxx> #include <BOPCol_ListOfShape.hxx>
#include <BOPCol_MapOfOrientedShape.hxx> #include <BOPCol_MapOfOrientedShape.hxx>
//
#include <NCollection_List.hxx>
//
#include <BOPCol_DataMapOfShapeShape.hxx> #include <BOPCol_DataMapOfShapeShape.hxx>
#include <BOPCol_DataMapOfShapeListOfShape.hxx> #include <BOPCol_DataMapOfShapeListOfShape.hxx>
#include <BOPInt_Context.hxx>
#include <BOPTools_CoupleOfShape.hxx>
#include <BOPCol_MapOfShape.hxx> #include <BOPCol_MapOfShape.hxx>
#include <BOPCol_ListOfInteger.hxx>
//
#include <BOPDS_BoxBndTree.hxx>
#include <BOPTools.hxx>
#include <BOPTools_CoupleOfShape.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BOPTools_AlgoTools3D.hxx>
//
#include <BOPInt_Context.hxx>
//
#include <BOPAlgo_ShellSplitter.hxx>
#include <BOPCol_DataMapOfIntegerShape.hxx>
static static
Standard_Boolean IsGrowthShell(const TopoDS_Shape& , Standard_Boolean IsGrowthShell(const TopoDS_Shape& ,
@@ -74,14 +87,63 @@ static
void MakeInternalShells(const BOPCol_MapOfShape& , void MakeInternalShells(const BOPCol_MapOfShape& ,
BOPCol_ListOfShape& ); BOPCol_ListOfShape& );
static //=======================================================================
Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell); //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 : //function :
//purpose : //purpose :
//======================================================================= //=======================================================================
BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid() BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid()
: :
BOPAlgo_BuilderArea() BOPAlgo_BuilderArea()
{ {
@@ -90,7 +152,8 @@ static
//function : //function :
//purpose : //purpose :
//======================================================================= //=======================================================================
BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid(const Handle(NCollection_BaseAllocator)& theAllocator) BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid
(const Handle(NCollection_BaseAllocator)& theAllocator)
: :
BOPAlgo_BuilderArea(theAllocator) BOPAlgo_BuilderArea(theAllocator)
{ {
@@ -99,20 +162,18 @@ static
//function : ~ //function : ~
//purpose : //purpose :
//======================================================================= //=======================================================================
BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid() BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid()
{ {
} }
//======================================================================= //=======================================================================
//function : Perform //function : Perform
//purpose : //purpose :
//======================================================================= //=======================================================================
void BOPAlgo_BuilderSolid::Perform() void BOPAlgo_BuilderSolid::Perform()
{ {
myErrorStatus=0; myErrorStatus=0;
// //
if (myContext.IsNull()) { if (myContext.IsNull()) {
//myErrorStatus=11;// Null Context
//return;
myContext=new BOPInt_Context; myContext=new BOPInt_Context;
} }
// //
@@ -127,7 +188,6 @@ static
aBB.Add(aC, aF); aBB.Add(aC, aF);
} }
// //
//
PerformShapesToAvoid(); PerformShapesToAvoid();
if (myErrorStatus) { if (myErrorStatus) {
return; return;
@@ -137,10 +197,12 @@ static
if (myErrorStatus) { if (myErrorStatus) {
return; return;
} }
//
PerformAreas(); PerformAreas();
if (myErrorStatus) { if (myErrorStatus) {
return; return;
} }
//
PerformInternalShapes(); PerformInternalShapes();
if (myErrorStatus) { if (myErrorStatus) {
return; return;
@@ -150,7 +212,7 @@ static
//function :PerformShapesToAvoid //function :PerformShapesToAvoid
//purpose : //purpose :
//======================================================================= //=======================================================================
void BOPAlgo_BuilderSolid::PerformShapesToAvoid() void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
{ {
Standard_Boolean bFound; Standard_Boolean bFound;
Standard_Integer i, iCnt, aNbE, aNbF; Standard_Integer i, iCnt, aNbE, aNbF;
@@ -171,7 +233,10 @@ static
for (; aIt.More(); aIt.Next()) { for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value(); const TopoDS_Shape& aF=aIt.Value();
if (!myShapesToAvoid.Contains(aF)) { if (!myShapesToAvoid.Contains(aF)) {
BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF); BOPTools::MapShapesAndAncestors(aF,
TopAbs_EDGE,
TopAbs_FACE,
aMEF);
} }
} }
aNbE=aMEF.Extent(); aNbE=aMEF.Extent();
@@ -221,151 +286,51 @@ static
break; break;
} }
// //
}//while (1) }//for(;;) {
} }
//======================================================================= //=======================================================================
//function : PerformLoops //function : PerformLoops
//purpose : //purpose :
//======================================================================= //=======================================================================
void BOPAlgo_BuilderSolid::PerformLoops() void BOPAlgo_BuilderSolid::PerformLoops()
{ {
myErrorStatus=0; Standard_Integer iErr;
BOPCol_ListIteratorOfListOfShape aIt;
TopoDS_Iterator aItS;
BOPCol_MapIteratorOfMapOfOrientedShape aItM;
BOPAlgo_ShellSplitter aSSp;
// //
myErrorStatus=0;
myLoops.Clear(); myLoops.Clear();
// //
Standard_Integer aNbLF, aNbOff, aNbFP, aNbFA; // 1. Shells Usual
Standard_Integer i; aIt.Initialize (myShapes);
TopAbs_Orientation anOr; for (; aIt.More(); aIt.Next()) {
TopoDS_Edge aEL; const TopoDS_Shape& aF=aIt.Value();
BRep_Builder aBB; if (!myShapesToAvoid.Contains(aF)) {
TopoDS_Iterator aItS; aSSp.AddStartElement(aF);
}
}
// //
BOPCol_ListIteratorOfListOfShape aItF, aIt; aSSp.Perform();
BOPCol_MapIteratorOfMapOfOrientedShape aItM; iErr=aSSp.ErrorStatus();
BOPTools_CoupleOfShape aCSOff; if (iErr) {
// return;
BOPCol_MapOfOrientedShape AddedFacesMap; }
BOPCol_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
// //
const BOPCol_ListOfShape& aLSh=aSSp.Shells();
aIt.Initialize (aLSh);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aSh=aIt.Value();
myLoops.Append(aSh);
}
//================================================= //=================================================
// //
// 1. Shells Usual // 2. Post Treatment
// Standard_Integer aNbFA;
aItF.Initialize (myShapes); BRep_Builder aBB;
for (; aItF.More(); aItF.Next()) { BOPCol_MapOfOrientedShape AddedFacesMap;
const TopoDS_Shape& aFF = aItF.Value(); BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
}
//
aItF.Initialize (myShapes);
for (i=1; aItF.More(); aItF.Next(), ++i) {
const TopoDS_Shape& aFF = aItF.Value();
if (myShapesToAvoid.Contains(aFF)) {
continue;
}
if (!AddedFacesMap.Add(aFF)) {
continue;
}
//
// make a new shell
TopoDS_Shell aShell;
aBB.MakeShell(aShell);
aBB.Add(aShell, aFF);
//
aMEFP.Clear();
BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
//
// loop on faces added to Shell; add their neighbor faces to Shell and so on
TopoDS_Iterator aItAddedF (aShell);
for (; aItAddedF.More(); aItAddedF.Next()) {
const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value()));
//
// loop on edges of aF; find a good neighbor face of aF by aE
TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
for (; aEdgeExp.More(); aEdgeExp.Next()) {
const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
//
//1
if (aMEFP.Contains(aE)) {
const BOPCol_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
aNbFP=aLFP.Extent();
if (aNbFP>1) {
continue;
}
}
//2
anOr=aE.Orientation();
if (anOr==TopAbs_INTERNAL) {
continue;
}
//3
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
// candidate faces list
const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
aNbLF=aLF.Extent();
if (!aNbLF) {
continue;
}
//
// try to select one of neighbors
// check if a face already added to Shell shares E
Standard_Boolean bFound;
BOPCol_ListIteratorOfListOfShape aItLF;
BOPTools_ListOfCoupleOfShape aLCSOff;
//
aItLF.Initialize(aLF);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
if (myShapesToAvoid.Contains(aFL)) {
continue;
}
if (aF.IsSame(aFL)) {
continue;
}
if (AddedFacesMap.Contains(aFL)){
continue;
}
//
bFound=BOPTools_AlgoTools::GetEdgeOff(aE, aFL, aEL);
if (!bFound) {
continue;
}
//
aCSOff.SetShape1(aEL);
aCSOff.SetShape2(aFL);
aLCSOff.Append(aCSOff);
}//for (; aItLF.More(); aItLF.Next()) {
//
aNbOff=aLCSOff.Extent();
if (!aNbOff){
continue;
}
//
TopoDS_Face aSelF;
if (aNbOff==1) {
aSelF=(*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
}
else if (aNbOff>1){
BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, myContext);
}
//
if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
aBB.Add(aShell, aSelF);
BOPTools::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
}
} // for (; aEdgeExp.More(); aEdgeExp.Next()) {
} //for (; aItAddedF.More(); aItAddedF.Next()) {
//
if (IsClosedShell(aShell)) {
myLoops.Append(aShell);
}
} // for (; aItF.More(); aItF.Next()) {
//
// Post Treatment
BOPCol_MapOfOrientedShape aMP; BOPCol_MapOfOrientedShape aMP;
// //
// a. collect all edges that are in loops // a. collect all edges that are in loops
@@ -396,8 +361,7 @@ static
} }
//================================================= //=================================================
// //
// 2.Internal Shells // 3.Internal Shells
//
myLoopsInternal.Clear(); myLoopsInternal.Clear();
// //
aEFMap.Clear(); aEFMap.Clear();
@@ -408,7 +372,9 @@ static
aItM.Initialize(myShapesToAvoid); aItM.Initialize(myShapesToAvoid);
for (; aItM.More(); aItM.Next()) { for (; aItM.More(); aItM.Next()) {
const TopoDS_Shape& aFF=aItM.Key(); const TopoDS_Shape& aFF=aItM.Key();
BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap); BOPTools::MapShapesAndAncestors(aFF,
TopAbs_EDGE, TopAbs_FACE,
aEFMap);
} }
// //
aItM.Initialize(myShapesToAvoid); aItM.Initialize(myShapesToAvoid);
@@ -431,15 +397,16 @@ static
for (; aEdgeExp.More(); aEdgeExp.Next()) { for (; aEdgeExp.More(); aEdgeExp.Next()) {
const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current())); const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE); const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
aItF.Initialize(aLF); aIt.Initialize(aLF);
for (; aItF.More(); aItF.Next()) { for (; aIt.More(); aIt.Next()) {
const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItF.Value())); const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aIt.Value()));
if (AddedFacesMap.Add(aFL)){ if (AddedFacesMap.Add(aFL)){
aBB.Add(aShell, aFL); aBB.Add(aShell, aFL);
} }
} }
} }
} }
aShell.Closed (BRep_Tool::IsClosed (aShell));
myLoopsInternal.Append(aShell); myLoopsInternal.Append(aShell);
} }
} }
@@ -447,85 +414,141 @@ static
//function : PerformAreas //function : PerformAreas
//purpose : //purpose :
//======================================================================= //=======================================================================
void BOPAlgo_BuilderSolid::PerformAreas() void BOPAlgo_BuilderSolid::PerformAreas()
{ {
myErrorStatus=0; Standard_Boolean bIsGrowth, bIsHole;
// Standard_Integer k,aNbHoles;
Standard_Boolean bIsGrowthShell, bIsHole;
BRep_Builder aBB; BRep_Builder aBB;
TopoDS_Shape anInfinitePointShape; BOPCol_ListIteratorOfListOfShape aItLS;
BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
//
BOPCol_ListOfShape aNewSolids, aHoleShells; BOPCol_ListOfShape aNewSolids, aHoleShells;
BOPCol_DataMapOfShapeShape aInOutMap; BOPCol_DataMapOfShapeShape aInOutMap;
BOPCol_DataMapOfShapeListOfShape aMSH;
BOPCol_IndexedMapOfShape aMHF; BOPCol_IndexedMapOfShape aMHF;
BOPCol_ListIteratorOfListOfInteger aItLI;
BOPDS_BoxBndTreeSelector aSelector;
BOPDS_BoxBndTree aBBTree;
NCollection_UBTreeFiller
<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
BOPAlgo_DataMapOfIntegerBSSB aDMISB(100);
BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB aItDMISB;
BOPCol_DataMapOfShapeListOfShape aMSH;
BOPCol_DataMapIteratorOfDataMapOfShapeShape aItDMSS;
BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
//
myErrorStatus=0;
// //
myAreas.Clear(); myAreas.Clear();
// //
// Draft solids [aNewSolids] // Draft solids [aNewSolids]
aShellIt.Initialize(myLoops); aItLS.Initialize(myLoops);
for ( ; aShellIt.More(); aShellIt.Next()) { for (k=0; aItLS.More(); aItLS.Next(), ++k) {
const TopoDS_Shape& aShell = aShellIt.Value(); TopoDS_Solid aSolid;
Bnd_Box aBox;
BOPAlgo_BuilderSolid_ShapeBox aSB;
// //
bIsGrowthShell=IsGrowthShell(aShell, aMHF); const TopoDS_Shape& aShell = aItLS.Value();
if (bIsGrowthShell) { aSB.SetShape(aShell);
//
BRepBndLib::Add(aShell, aBox);
bIsHole=Standard_False;
//
bIsGrowth=IsGrowthShell(aShell, aMHF);
if (bIsGrowth) {
// make a growth solid from a shell // make a growth solid from a shell
TopoDS_Solid Solid; aBB.MakeSolid(aSolid);
aBB.MakeSolid(Solid); aBB.Add (aSolid, aShell);
aBB.Add (Solid, aShell);
// //
aNewSolids.Append (Solid); aNewSolids.Append (aSolid);
aSB.SetShape(aSolid);
} }
else{ else{
// check if a shell is a hole // check if a shell is a hole
//XX
bIsHole=IsHole(aShell, myContext); bIsHole=IsHole(aShell, myContext);
//XX
if (bIsHole) { if (bIsHole) {
aHoleShells.Append(aShell); aHoleShells.Append(aShell);
BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF); BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF);
aSB.SetShape(aShell);
} }
else { else {
// make a growth solid from a shell // make a growth solid from a shell
TopoDS_Solid Solid; aBB.MakeSolid(aSolid);
aBB.MakeSolid(Solid); aBB.Add (aSolid, aShell);
aBB.Add (Solid, aShell);
// //
aNewSolids.Append (Solid); aNewSolids.Append (aSolid);
} aSB.SetShape(aSolid);
} }
} }
// //
// 2. Find outer growth shell that is most close to each hole shell aSB.SetBox(aBox);
aShellIt.Initialize(aHoleShells); aSB.SetIsHole(bIsHole);
for (; aShellIt.More(); aShellIt.Next()) { aDMISB.Bind(k, aSB);
const TopoDS_Shape& aHole = aShellIt.Value(); }
// //
aSolidIt.Initialize(aNewSolids); // 2. Prepare TreeFiller
for ( ; aSolidIt.More(); aSolidIt.Next()) { aItDMISB.Initialize(aDMISB);
const TopoDS_Shape& aSolid = aSolidIt.Value(); 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);
}
}
//
// 3. 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);
//
aNbHoles=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)){ if (!IsInside(aHole, aSolid, myContext)){
continue; continue;
} }
// //
if ( aInOutMap.IsBound (aHole)){ if (aInOutMap.IsBound (aHole)){
const TopoDS_Shape& aSolid2 = aInOutMap(aHole); const TopoDS_Shape& aHole2=aInOutMap(aHole);
if (IsInside(aSolid, aSolid2, myContext)) { if (IsInside(aHole, aHole2, myContext)) {
aInOutMap.UnBind(aHole); aInOutMap.UnBind(aHole);
aInOutMap.Bind (aHole, aSolid); aInOutMap.Bind (aHole, aSolid);
} }
} }
else{ else{
aInOutMap.Bind (aHole, aSolid); aInOutMap.Bind(aHole, aSolid);
} }
} }
}//for (; aItDMISB.More(); aItDMISB.Next()) {
//
// 5. Map [Solid/Holes] -> aMSH
aItDMSS.Initialize(aInOutMap);
for (; aItDMSS.More(); aItDMSS.Next()) {
const TopoDS_Shape& aHole=aItDMSS.Key();
const TopoDS_Shape& aSolid=aItDMSS.Value();
// //
// Add aHole to a map Solid/ListOfHoles [aMSH]
if (aInOutMap.IsBound(aHole)){
const TopoDS_Shape& aSolid=aInOutMap(aHole);
if (aMSH.IsBound(aSolid)) { if (aMSH.IsBound(aSolid)) {
BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aSolid); BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
aLH.Append(aHole); aLH.Append(aHole);
@@ -535,43 +558,41 @@ static
aLH.Append(aHole); aLH.Append(aHole);
aMSH.Bind(aSolid, aLH); aMSH.Bind(aSolid, aLH);
} }
//aBB.Add (aSolid, aHole);
} }
}// for (; aShellIt.More(); aShellIt.Next()) {
// //
// 3. Add aHoles to Solids // 6. Add aHoles to Solids
aItMSH.Initialize(aMSH); aItMSH.Initialize(aMSH);
for (; aItMSH.More(); aItMSH.Next()) { for (; aItMSH.More(); aItMSH.Next()) {
TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&aItMSH.Key())); TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&aItMSH.Key()));
// //
const BOPCol_ListOfShape& aLH=aItMSH.Value(); const BOPCol_ListOfShape& aLH=aItMSH.Value();
aShellIt.Initialize(aLH); aItLS.Initialize(aLH);
for (; aShellIt.More(); aShellIt.Next()) { for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aHole = aShellIt.Value(); const TopoDS_Shape& aHole = aItLS.Value();
aBB.Add (aSolid, aHole); aBB.Add (aSolid, aHole);
} }
// //
// update classifier // update classifier
BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid); BRepClass3d_SolidClassifier& aSC=
myContext->SolidClassifier(aSolid);
aSC.Load(aSolid); aSC.Load(aSolid);
// //
} }
// //
// These aNewSolids are draft solids that // 7. These aNewSolids are draft solids that
// do not contain any internal shapes // do not contain any internal shapes
// aItLS.Initialize(aNewSolids);
aShellIt.Initialize(aNewSolids); for ( ; aItLS.More(); aItLS.Next()) {
for ( ; aShellIt.More(); aShellIt.Next()) { const TopoDS_Shape& aSx=aItLS.Value();
const TopoDS_Shape& aSx = aShellIt.Value();
myAreas.Append(aSx); myAreas.Append(aSx);
} }
// Add holes that outside the solids to myAreas // Add holes that outside the solids to myAreas
aShellIt.Initialize(aHoleShells); aItLS.Initialize(aHoleShells);
for (; aShellIt.More(); aShellIt.Next()) { for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aHole = aShellIt.Value(); const TopoDS_Shape& aHole = aItLS.Value();
if (!aInOutMap.IsBound(aHole)){ if (!aInOutMap.IsBound(aHole)){
TopoDS_Solid aSolid; TopoDS_Solid aSolid;
//
aBB.MakeSolid(aSolid); aBB.MakeSolid(aSolid);
aBB.Add (aSolid, aHole); aBB.Add (aSolid, aHole);
// //
@@ -583,7 +604,7 @@ static
//function : PerformInternalShapes //function : PerformInternalShapes
//purpose : //purpose :
//======================================================================= //=======================================================================
void BOPAlgo_BuilderSolid::PerformInternalShapes() void BOPAlgo_BuilderSolid::PerformInternalShapes()
{ {
myErrorStatus=0; myErrorStatus=0;
// //
@@ -592,95 +613,169 @@ static
return; return;
} }
// //
Standard_Integer k, aNbVFS, aNbSLF, aNbF, aNbA;
BRep_Builder aBB; BRep_Builder aBB;
TopoDS_Iterator aIt; TopoDS_Iterator aIt;
BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt; TopExp_Explorer aExp;
BOPCol_MapIteratorOfMapOfShape aItMF; BOPCol_ListIteratorOfListOfShape aItLS;
// BOPCol_MapOfShape aMFs;
BOPCol_MapOfShape aMF, aMFP, aMFx;
BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
BOPCol_ListOfShape aLSI; BOPCol_ListOfShape aLSI;
BOPCol_ListIteratorOfListOfInteger aItLI;
BOPDS_BoxBndTreeSelector aSelector;
BOPDS_BoxBndTree aBBTree;
NCollection_UBTreeFiller
<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
BOPCol_DataMapOfIntegerShape aDMIS;
// //
// 1. All internal faces aNbA=myAreas.Extent();
aShellIt.Initialize(myLoopsInternal); //
for (; aShellIt.More(); aShellIt.Next()) { // 1. Prepare tree filler
const TopoDS_Shape& aShell=aShellIt.Value(); k = 0;
aItLS.Initialize(myLoopsInternal);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aShell=aItLS.Value();
aIt.Initialize(aShell); aIt.Initialize(aShell);
for (; aIt.More(); aIt.Next()) { for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value(); const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value());
aMF.Add(aF);
}
}
aNbFI=aMF.Extent();
// //
// 2 Process solids if (aMFs.Add(aF)) {
aSolidIt.Initialize(myAreas); if (aNbA) {
for ( ; aSolidIt.More(); aSolidIt.Next()) { Bnd_Box aBox;
TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aSolidIt.Value())); BRepBndLib::Add(aF, aBox);
// aDMIS.Bind(k, aF);
TopExp_Explorer anExpSol(aSolid, TopAbs_FACE);; aTreeFiller.Add(k++, aBox);
for (; anExpSol.More(); anExpSol.Next()) { }
const TopoDS_Shape& aF = anExpSol.Current();
TopoDS_Shape aFF=aF;
//
aFF.Orientation(TopAbs_FORWARD);
aMFx.Add(aFF);
aFF.Orientation(TopAbs_REVERSED);
aMFx.Add(aFF);
}
aMEF.Clear();
BOPTools::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF);
//
// 2.1 Separate faces to process aMFP
aMFP.Clear();
aItMF.Initialize(aMF);
for (; aItMF.More(); aItMF.Next()) {
const TopoDS_Face& aF=(*(TopoDS_Face*)(&aItMF.Key()));
if (!aMFx.Contains(aF)) {
if (BOPTools_AlgoTools::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext)) {
aMFP.Add(aF);
} }
} }
} }
aMFx.Clear();
// //
// 2.2 Make Internal Shells if (!aNbA) {
aLSI.Clear(); // 7b. "Rest" faces treatment
MakeInternalShells(aMFP, aLSI); TopoDS_Solid aSolid;
aBB.MakeSolid(aSolid);
// //
// 2.3 Add them to aSolid MakeInternalShells(aMFs, aLSI);
aShellIt.Initialize(aLSI); //
for (; aShellIt.More(); aShellIt.Next()) { aItLS.Initialize(aLSI);
const TopoDS_Shape& aSI=aShellIt.Value(); for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aSI=aItLS.Value();
aBB.Add (aSolid, aSI); aBB.Add (aSolid, aSI);
} }
myAreas.Append(aSolid);
// //
// 2.4 Remove faces aMFP from aMF return; // =>
aItMF.Initialize(aMFP); }//if (!aNbA) {
for (; aItMF.More(); aItMF.Next()) { //
const TopoDS_Shape& aF=aItMF.Key(); //2. fill tree filler
aMF.Remove(aF); aTreeFiller.Fill();
//
// 3. Face/Solid candidates: aVFS
BOPCol_IndexedDataMapOfShapeListOfShape aMSLF;
BOPCol_MapOfShape aMFProcessed;
//
aItLS.Initialize(myAreas);
for (; aItLS.More(); aItLS.Next()) {
Bnd_Box aBox;
//
TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aItLS.Value()));
BRepBndLib::Add(aSolid, aBox);
//
aMFs.Clear();
aExp.Init(aSolid, TopAbs_FACE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aFs=aExp.Current();
aMFs.Add(aFs);
} }
// //
aNbFI=aMF.Extent(); aSelector.Clear();
if (!aNbFI) { aSelector.SetBox(aBox);
break; //
aNbF=aBBTree.Select(aSelector);
//
const BOPCol_ListOfInteger& aLI=aSelector.Indices();
aItLI.Initialize(aLI);
for (; aItLI.More(); aItLI.Next()) {
k=aItLI.Value();
const TopoDS_Face& aF = *(TopoDS_Face*)&aDMIS.Find(k);
if (aMFs.Contains(aF)) {
continue;
} }
} //for ( ; aSolidIt.More(); aSolidIt.Next()) { //
gp_Pnt aP;
gp_Pnt2d aP2D;
//
BOPTools_AlgoTools3D::PointInFace(aF, aP, aP2D, myContext);
//
TopAbs_State aState=BOPTools_AlgoTools::ComputeState(aP, aSolid,
Precision::Confusion(),
myContext);
if (aState==TopAbs_IN) {
if (aMSLF.Contains(aSolid)) {
BOPCol_ListOfShape& aLF=aMSLF.ChangeFromKey(aSolid);
aLF.Append(aF);
}
else {
BOPCol_ListOfShape aLF;
//
aLF.Append(aF);
aMSLF.Add(aSolid, aLF);
}
}
}
}// for (k=0; k < aNbVE; ++k) {
//
// 6. Update Solids by internal Faces
aNbSLF=aMSLF.Extent();
for (k=1; k <= aNbSLF; ++k) {
const TopoDS_Shape& aSolid=aMSLF.FindKey(k);
TopoDS_Shape *pSolid=(TopoDS_Shape*)&aSolid;
//
const BOPCol_ListOfShape& aLF=aMSLF(k);
//
aMFs.Clear();
aItLS.Initialize(aLF);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aF=aItLS.Value();
aMFs.Add(aF);
aMFProcessed.Add(aF);
}
//
aLSI.Clear();
MakeInternalShells(aMFs, aLSI);
//
aItLS.Initialize(aLSI);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aSI=aItLS.Value();
aBB.Add (*pSolid, aSI);
}
}
//
// 7. "Rest" faces treatment (if there are)
aMFs.Clear();
aNbVFS = aDMIS.Extent();
for (k=0; k < aNbVFS; ++k) {
const TopoDS_Face& aF=*(TopoDS_Face*)&aDMIS.Find(k);
if (!aMFProcessed.Contains(aF)) {
aMFs.Add(aF);
}
}
//
aNbFI=aMFs.Extent();
if (aNbFI) { if (aNbFI) {
TopoDS_Solid aSolid; TopoDS_Solid aSolid;
aBB.MakeSolid(aSolid); aBB.MakeSolid(aSolid);
// //
MakeInternalShells(aMF, aLSI); aLSI.Clear();
aShellIt.Initialize(aLSI); MakeInternalShells(aMFs, aLSI);
for (; aShellIt.More(); aShellIt.Next()) { //
const TopoDS_Shape& aSI=aShellIt.Value(); aItLS.Initialize(aLSI);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aSI=aItLS.Value();
aBB.Add (aSolid, aSI); aBB.Add (aSolid, aSI);
} }
myAreas.Append(aSolid); myAreas.Append(aSolid);
} }
} }
//======================================================================= //=======================================================================
//function : MakeInternalShells //function : MakeInternalShells
//purpose : //purpose :
@@ -698,7 +793,9 @@ void MakeInternalShells(const BOPCol_MapOfShape& theMF,
aItM.Initialize(theMF); aItM.Initialize(theMF);
for (; aItM.More(); aItM.Next()) { for (; aItM.More(); aItM.Next()) {
const TopoDS_Shape& aF=aItM.Key(); const TopoDS_Shape& aF=aItM.Key();
BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF); BOPTools::MapShapesAndAncestors(aF,
TopAbs_EDGE, TopAbs_FACE,
aMEF);
} }
// //
aItM.Initialize(theMF); aItM.Initialize(theMF);
@@ -732,6 +829,7 @@ void MakeInternalShells(const BOPCol_MapOfShape& theMF,
} }
} }
} }
aShell.Closed (BRep_Tool::IsClosed (aShell));
theShells.Append(aShell); theShells.Append(aShell);
} }
} }
@@ -772,7 +870,9 @@ Standard_Boolean IsInside(const TopoDS_Shape& theS1,
BOPCol_IndexedMapOfShape aBounds; BOPCol_IndexedMapOfShape aBounds;
BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds); BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds);
const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current())); const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current()));
aState=BOPTools_AlgoTools::ComputeState(aF, *pS2, 1.e-14, aBounds, theContext); aState=BOPTools_AlgoTools::ComputeState(aF, *pS2,
Precision::Confusion(),
aBounds, theContext);
} }
return (aState==TopAbs_IN); return (aState==TopAbs_IN);
} }
@@ -798,42 +898,3 @@ Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
} }
return bRet; return bRet;
} }
//=======================================================================
//function : IsClosedShell
//purpose :
//=======================================================================
Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
{
Standard_Integer aNbE;
Standard_Boolean bRet;
TopoDS_Iterator aIt;
TopExp_Explorer aExp;
//
BOPCol_MapOfShape aM;
//
bRet=Standard_False;
aIt.Initialize(theShell);
for(; aIt.More(); aIt.Next()) {
const TopoDS_Face& aF=(*(TopoDS_Face*)(&aIt.Value()));
aExp.Init(aF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
if (aE.Orientation()==TopAbs_INTERNAL) {
continue;
}
if (!aM.Add(aE)) {
aM.Remove(aE);
}
}
}
//
aNbE=aM.Extent();
if (!aNbE) {
bRet=!bRet;
}
return bRet;
}

View File

@@ -66,7 +66,7 @@ GeomAbs_SurfaceType IntCurvesFace_Intersector::SurfaceType() const
//======================================================================= //=======================================================================
IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face, IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
const Standard_Real aTol) const Standard_Real aTol)
: :
Tol(aTol), Tol(aTol),
done(Standard_False), done(Standard_False),
nbpnt(0), nbpnt(0),
@@ -95,7 +95,7 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
Standard_Boolean bFlag; Standard_Boolean bFlag;
// //
{ {
Standard_Real dU, dV, dA, dB, aR, aTresh; Standard_Real dU, dV, dA, dB, aTresh;
bFlag=Standard_True; bFlag=Standard_True;
// //
aTresh=100.; aTresh=100.;
@@ -108,15 +108,9 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
dB=dU; dB=dU;
} }
// //
aR=dA/dB; if (dB < Precision::PConfusion() || dA > dB * aTresh) {
if (dB<Precision::PConfusion()) {
bFlag=!bFlag; bFlag=!bFlag;
} }
else {
if (aR>aTresh) {
bFlag=!bFlag;
}
}
} }
// //
if (bFlag) { if (bFlag) {