BOPAlgo_PaveFiller: Add method for forced Edge/Face intersection to look for additional cases of coincidence.
BOPAlgo_BuilderSolid: Avoid creating solids from unclassified faces as such solids will be useless. Just warn user about unclassified faces.
.BOPAlgo_AlertRemovalOfIBForEdgesFailed
Warning: Removal of internal boundaries among Edges has failed
+
+.BOPAlgo_AlertSolidBuilderUnusedFaces
+Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation
//! Some edges are too small and have no valid range
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertTooSmallEdge)
+//! Some of the faces passed to the Solid Builder algorithm have not been classified
+//! and not used for solids creation
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertSolidBuilderUnusedFaces)
#endif // _BOPAlgo_Alerts_HeaderFile
#include <BOPAlgo_BuilderSolid.hxx>
#include <BOPAlgo_ShellSplitter.hxx>
#include <BOPAlgo_Alerts.hxx>
+#include <BOPAlgo_Tools.hxx>
#include <BOPCol_BoxBndTree.hxx>
#include <BOPCol_DataMapOfShapeListOfShape.hxx>
#include <BOPCol_DataMapOfShapeShape.hxx>
//
typedef BOPAlgo_DataMapOfIntegerBSSB::Iterator
BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB;
-//
-//=======================================================================
-//function : BOPAlgo_FacePnt
-//purpose :
-//=======================================================================
-class BOPAlgo_FacePnt {
- public:
- BOPAlgo_FacePnt() {
- }
- //
- virtual ~BOPAlgo_FacePnt() {
- }
- //
- void SetFace(const TopoDS_Face& aFace) {
- myFace=aFace;
- }
- //
- const TopoDS_Face& Face()const {
- return myFace;
- }
- //
- void SetPnt(const gp_Pnt& aPnt) {
- myPnt=aPnt;
- }
- //
- const gp_Pnt& Pnt()const {
- return myPnt;
- }
- //
- protected:
- gp_Pnt myPnt;
- TopoDS_Face myFace;
-};
-//
-typedef BOPCol_NCVector
- <BOPAlgo_FacePnt> BOPAlgo_VectorOfFacePnt;
-//
-//=======================================================================
-//function : BOPAlgo_FaceSolid
-//purpose :
-//=======================================================================
-class BOPAlgo_FaceSolid : public BOPAlgo_Algo {
- public:
- DEFINE_STANDARD_ALLOC
- BOPAlgo_FaceSolid() :
- myIsInternalFace(Standard_False) {
- }
- //
- virtual ~BOPAlgo_FaceSolid() {
- }
- //
- void SetFace(const TopoDS_Face& aFace) {
- myFace=aFace;
- }
- //
- const TopoDS_Face& Face()const {
- return myFace;
- }
- //
- void SetSolid(const TopoDS_Solid& aSolid) {
- mySolid=aSolid;
- }
- //
- const TopoDS_Solid& Solid()const {
- return mySolid;
- }
- //
- void SetPnt(const gp_Pnt& aPnt) {
- myPnt=aPnt;
- }
- //
- const gp_Pnt& Pnt()const {
- return myPnt;
- }
- void SetContext(const Handle(IntTools_Context)& aContext) {
- myContext=aContext;
- }
- //
- const Handle(IntTools_Context)& Context()const {
- return myContext;
- }
- //
- Standard_Boolean IsInternalFace() const {
- return myIsInternalFace;
- }
- //
- virtual void Perform () {
- TopAbs_State aState;
- //
- BOPAlgo_Algo::UserBreak();
- //
- aState=BOPTools_AlgoTools::ComputeState(myPnt, mySolid,
- Precision::Confusion(),
- myContext);
- //
- myIsInternalFace=(aState==TopAbs_IN);
- }
- //
- protected:
- Standard_Boolean myIsInternalFace;
- gp_Pnt myPnt;
- TopoDS_Face myFace;
- TopoDS_Solid mySolid;
- Handle(IntTools_Context) myContext;
-};
-//=======================================================================
-typedef BOPCol_NCVector
- <BOPAlgo_FaceSolid> BOPAlgo_VectorOfFaceSolid;
-//
-typedef BOPCol_ContextFunctor
- <BOPAlgo_FaceSolid,
- BOPAlgo_VectorOfFaceSolid,
- Handle(IntTools_Context),
- IntTools_Context> BOPAlgo_FaceSolidFunctor;
-//
-typedef BOPCol_ContextCnt
- <BOPAlgo_FaceSolidFunctor,
- BOPAlgo_VectorOfFaceSolid,
- Handle(IntTools_Context)> BOPAlgo_FaceSolidCnt;
-//
//=======================================================================
//=======================================================================
return;
}
//
- Standard_Boolean bIsInternalFace;
- Standard_Integer k, aNbVFS, aNbSLF, aNbVFP, aNbA;
BRep_Builder aBB;
- TopoDS_Iterator aIt;
- TopExp_Explorer aExp;
BOPCol_ListIteratorOfListOfShape aItLS;
BOPCol_IndexedMapOfShape aMFs;
BOPCol_ListOfShape aLSI;
- BOPAlgo_VectorOfFaceSolid aVFS;
- BOPAlgo_VectorOfFacePnt aVFP;
BOPCol_ListIteratorOfListOfInteger aItLI;
- BOPCol_BoxBndTreeSelector aSelector;
- BOPCol_BoxBndTree aBBTree;
- NCollection_UBTreeFiller
- <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
//
- aNbA=myAreas.Extent();
+ Standard_Integer aNbA = myAreas.Extent();
//
- // 1. aVFP
+ // Fill Tree with boxes
aItLS.Initialize(myLoopsInternal);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aShell=aItLS.Value();
- aIt.Initialize(aShell);
+ TopoDS_Iterator aIt(aShell);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value());
//
- if (!aMFs.Contains(aF)) {
+ if (!aMFs.Contains(aF))
+ {
aMFs.Add(aF);
- //
- gp_Pnt aP;
- gp_Pnt2d aP2D;
- //
- if (aNbA) {
- BOPTools_AlgoTools3D::PointInFace(aF, aP, aP2D, myContext);
- }
- //
- BOPAlgo_FacePnt& aFP=aVFP.Append1();
- aFP.SetFace(aF);
- aFP.SetPnt(aP);
}
}
}
- //
+
if (!aNbA) {
// 7b. "Rest" faces treatment
TopoDS_Solid aSolid;
return; // =>
}//if (!aNbA) {
//
- // 2. Prepare TreeFiller
- aNbVFP=aVFP.Extent();
- for(k=0; k<aNbVFP; ++k) {
- Bnd_Box aBox;
- //
- const BOPAlgo_FacePnt& aFP=aVFP(k);
- const TopoDS_Face& aF=aFP.Face();
- //
- BRepBndLib::Add(aF, aBox);
- aTreeFiller.Add(k, aBox);
- }
- //
- aTreeFiller.Fill();
- //
- // 3. Face/Solid candidates: aVFS
- 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);
- }
- //
- aSelector.Clear();
- 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_FacePnt& aFP=aVFP(k);
- const TopoDS_Face& aF=aFP.Face();
- if (aMFs.Contains(aF)) {
- continue;
- }
- //
- const gp_Pnt& aP=aFP.Pnt();
- //
- BOPAlgo_FaceSolid& aFS=aVFS.Append1();
- aFS.SetPnt(aP);
- aFS.SetFace(aF);
- aFS.SetSolid(aSolid);
- }
- }
- //
- aNbVFS=aVFS.Extent();
- if (!aNbVFS) {
- return;
- }
- // 4. Refine candidates
- //=============================================================
- BOPAlgo_FaceSolidCnt::Perform(myRunParallel, aVFS, myContext);
- //=============================================================
- //
- // 5. Solid/Faces: aMSLF
- BOPCol_IndexedDataMapOfShapeListOfShape aMSLF;
- BOPCol_MapOfShape aMFProcessed;
- //
- for (k=0; k < aNbVFS; ++k) {
- const BOPAlgo_FaceSolid& aFS=aVFS(k);
- //
- const TopoDS_Solid& aSolid=aFS.Solid();
- const TopoDS_Face& aF=aFS.Face();
- //
- bIsInternalFace=aFS.IsInternalFace();
- if (!bIsInternalFace) {
+
+ // Prepare list of faces to classify
+ TopTools_ListOfShape aLFaces;
+ Standard_Integer i, aNbF = aMFs.Extent();
+ for (i = 1; i <= aNbF; ++i)
+ aLFaces.Append(aMFs(i));
+
+ // Map of solids with IN faces
+ TopTools_IndexedDataMapOfShapeListOfShape aMSLF;
+
+ // Perform classification
+ BOPAlgo_Tools::ClassifyFaces(aLFaces, myAreas, myRunParallel, myContext, aMSLF);
+
+ // Update Solids by internal Faces
+
+ BOPCol_MapOfShape aMFDone;
+
+ Standard_Integer aNbS = aMSLF.Extent();
+ for (i = 1; i <= aNbS; ++i)
+ {
+ const TopoDS_Shape& aSolid = aMSLF.FindKey(i);
+ TopoDS_Shape *pSolid = (TopoDS_Shape*)&aSolid;
+
+ const TopTools_ListOfShape& aLF = aMSLF(i);
+ if (aLF.IsEmpty())
continue;
- }
- //
- 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();
+
+ TopTools_IndexedMapOfShape aMF;
aItLS.Initialize(aLF);
- for (; aItLS.More(); aItLS.Next()) {
- const TopoDS_Shape& aF=aItLS.Value();
- aMFs.Add(aF);
- aMFProcessed.Add(aF);
+ for (; aItLS.More(); aItLS.Next())
+ {
+ const TopoDS_Shape& aF = aItLS.Value();
+ aMF.Add(aF);
+ aMFDone.Add(aF);
}
//
aLSI.Clear();
- MakeInternalShells(aMFs, aLSI);
+ MakeInternalShells(aMF, aLSI);
//
aItLS.Initialize(aLSI);
- for (; aItLS.More(); aItLS.Next()) {
- const TopoDS_Shape& aSI=aItLS.Value();
+ for (; aItLS.More(); aItLS.Next())
+ {
+ const TopoDS_Shape& aSI = aItLS.Value();
aBB.Add (*pSolid, aSI);
}
}
- //
- // 7. "Rest" faces treatment (if there are)
- aMFs.Clear();
- for (k=0; k < aNbVFS; ++k) {
- const BOPAlgo_FaceSolid& aFS=aVFS(k);
- //
- const TopoDS_Face& aF=aFS.Face();
- if (!aMFProcessed.Contains(aF)) {
- aMFs.Add(aF);
- }
+
+ // Find all unclassified faces and warn the user about them.
+ TopTools_IndexedMapOfShape aMFUnUsed;
+
+ for (i = 1; i <= aNbF; ++i)
+ {
+ const TopoDS_Shape& aF = aMFs(i);
+ if (!aMFDone.Contains(aF))
+ aMFUnUsed.Add(aF);
}
- //
- aNbFI=aMFs.Extent();
- if (aNbFI) {
- TopoDS_Solid aSolid;
- aBB.MakeSolid(aSolid);
- //
+
+ if (aMFUnUsed.Extent())
+ {
aLSI.Clear();
MakeInternalShells(aMFs, aLSI);
- //
- aItLS.Initialize(aLSI);
- for (; aItLS.More(); aItLS.Next()) {
+
+ //TopoDS_Solid aShape;
+ //aBB.MakeSolid (aShape);
+ TopoDS_Compound aShape;
+ aBB.MakeCompound (aShape);
+
+ aItLS.Initialize (aLSI);
+ for (; aItLS.More(); aItLS.Next())
+ {
const TopoDS_Shape& aSI=aItLS.Value();
- aBB.Add (aSolid, aSI);
+ aBB.Add (aShape, aSI);
}
- myAreas.Append(aSolid);
+ //myAreas.Append (aShape);
+ AddWarning (new BOPAlgo_AlertSolidBuilderUnusedFaces (aShape));
}
}
//=======================================================================
//
#include <Precision.hxx>
//
+#include <NCollection_IncAllocator.hxx>
#include <NCollection_UBTreeFiller.hxx>
//
#include <Bnd_Box.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <BRepBndLib.hxx>
//
+#include <BOPAlgo_Tools.hxx>
+//
#include <BOPCol_IndexedMapOfShape.hxx>
#include <BOPCol_MapOfShape.hxx>
+#include <BOPCol_IndexedDataMapOfShapeBox.hxx>
#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
+#include <BOPCol_IndexedDataMapOfShapeShape.hxx>
#include <BOPCol_ListOfShape.hxx>
#include <BOPCol_BoxBndTree.hxx>
#include <BOPCol_ListOfInteger.hxx>
typedef BOPCol_NCVector<BOPAlgo_ShapeBox> BOPAlgo_VectorOfShapeBox;
//
//=======================================================================
-// class: BOPAlgo_FillIn3DParts
-//
-//=======================================================================
-//class : BOPAlgo_FillIn3DParts
-//purpose :
-//=======================================================================
-class BOPAlgo_FillIn3DParts : public BOPAlgo_Algo {
- public:
- DEFINE_STANDARD_ALLOC
-
- BOPAlgo_FillIn3DParts(){
- myHasImage=Standard_False;
- myBBTree=NULL;
- myVSB=NULL;
- };
- //
- virtual ~BOPAlgo_FillIn3DParts(){
- };
- //
- void SetSolid(const TopoDS_Solid& aS) {
- mySolid=aS;
- };
- //
- const TopoDS_Solid& Solid()const {
- return mySolid;
- };
- //
- void SetDraftSolid(const TopoDS_Solid& aS) {
- myDraftSolid=aS;
- };
- //
- const TopoDS_Solid& DraftSolid()const {
- return myDraftSolid;
- };
- //
- void SetHasImage(const Standard_Boolean bFlag) {
- myHasImage=bFlag;
- };
- //
- Standard_Boolean HasImage()const {
- return myHasImage;
- };
- //
- void SetBoxS(const Bnd_Box& aBox) {
- myBoxS=aBox;
- };
- //
- const Bnd_Box& BoxS()const {
- return myBoxS;
- };
- //
- void SetLIF(const BOPCol_ListOfShape& aLIF) {
- myLIF=aLIF;
- };
- //
- const BOPCol_ListOfShape& LIF()const {
- return myLIF;
- };
- //
- void SetBBTree(const BOPCol_BoxBndTree& aBBTree) {
- myBBTree=(BOPCol_BoxBndTree*)&aBBTree;
- };
- //
- void SetVSB(const BOPAlgo_VectorOfShapeBox& aVSB) {
- myVSB=(BOPAlgo_VectorOfShapeBox*)&aVSB;
- };
- //
- //
- void SetContext(const Handle(IntTools_Context)& aContext) {
- myContext=aContext;
- }
- //
- const Handle(IntTools_Context)& Context()const {
- return myContext;
- }
- //
- virtual void Perform();
- //
-
- //
- const BOPCol_ListOfShape& LFIN()const {
- return myLFIN;
- };
-
- protected:
- void MapEdgesAndFaces
- (const TopoDS_Shape& ,
- BOPCol_IndexedDataMapOfShapeListOfShape& ,
- const Handle(NCollection_BaseAllocator)& );
-
- void MakeConnexityBlock
- (const BOPCol_ListOfShape& ,
- const BOPCol_IndexedMapOfShape& ,
- const BOPCol_MapOfShape& ,
- const BOPCol_IndexedDataMapOfShapeListOfShape& ,
- BOPCol_ListOfShape& ,
- const Handle(NCollection_BaseAllocator)& );
- //
- protected:
- TopoDS_Solid mySolid;
- TopoDS_Solid myDraftSolid;
- Standard_Boolean myHasImage;
- Bnd_Box myBoxS;
- BOPCol_ListOfShape myLIF;
- BOPCol_ListOfShape myLFIN;
- //
- BOPCol_BoxBndTree* myBBTree;
- BOPAlgo_VectorOfShapeBox* myVSB;
- //
- TopoDS_Iterator myItF;
- TopoDS_Iterator myItW;
-
- Handle(IntTools_Context) myContext;
-};
-
-//=======================================================================
-//function : BOPAlgo_FillIn3DParts::Perform
-//purpose :
-//=======================================================================
-void BOPAlgo_FillIn3DParts::Perform()
-{
- Handle(NCollection_BaseAllocator) aAlr1;
- BOPAlgo_Algo::UserBreak();
- //
- Standard_Integer aNbFP, k, nFP, iIsIN;
- Standard_Real aTolPC;
- BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1;
- 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);
- BOPCol_IndexedMapOfShape aMF(100, aAlr1);
- BOPCol_IndexedDataMapOfShapeListOfShape aMEFP(100, aAlr1);
- BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, aAlr1);
- //
- aTolPC=Precision::Confusion();
- myLFIN.Clear();
- BOPAlgo_VectorOfShapeBox& aVSB=*myVSB;
- //
- // 1. aMEF - EF map for myDraftSolid
- BOPTools::MapShapesAndAncestors(myDraftSolid,
- TopAbs_EDGE,
- TopAbs_FACE,
- aMEF);
-
- //
- // 2. Faces from myDraftSolid and its own internal faces => aMF
- BOPTools::MapShapes(myDraftSolid, TopAbs_FACE, aMF);
- aItLS.Initialize(myLIF);
- for (; aItLS.More(); aItLS.Next()) {
- const TopoDS_Shape& aFI=aItLS.Value();
- aMF.Add(aFI);
- }
- // aME - Edges from DraftSolid [i.e. edges to stop]
- BOPTools::MapShapes(myDraftSolid, TopAbs_EDGE, aME);
- //
- // 3. Select boxes of faces that are not out of aBoxS
- aSelector.Clear();
- aSelector.SetBox(myBoxS);
- //
- aNbFP=myBBTree->Select(aSelector);
- const BOPCol_ListOfInteger& aLIFPx=aSelector.Indices();
- //
- // 4. aIVec, aLIFP - faces to process
- BOPCol_ListOfInteger aLIFP(aAlr1);
- BOPCol_NCVector<Standard_Integer> aIVec(256, aAlr1);
- //
- k=0;
- aItLI.Initialize(aLIFPx);
- for (; aItLI.More(); aItLI.Next()) {
- nFP=aItLI.Value();
- const TopoDS_Shape& aFP=aVSB(nFP).Shape();
- if (!aMF.Contains(aFP)) {
- MapEdgesAndFaces(aFP, aMEFP, aAlr1);
- aLIFP.Append(nFP);
- aIVec.Append1()=nFP;
- ++k;
- }
- }
- aNbFP=k;
- //
- // sort indices
- std::sort(aIVec.begin(), aIVec.end());
- //
- // 5. Collect faces that are IN mySolid [ myLFIN ]
- for (k=0; k<aNbFP; ++k) {
- nFP = aIVec(k);
- const BOPAlgo_ShapeBox& aSBF=aVSB(nFP);
- const TopoDS_Face& aFP=(*(TopoDS_Face*)&aSBF.Shape());
- //
- if (!aMFDone.Add(aFP)) {
- continue;
- }
- //
- 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);
- }
- }
- //
- aLCBF.Clear();
- //
- 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);
- }
- }
- } // for (k=0; k<aNbFP; ++k) {
-}
-//=======================================================================
-// function: MapEdgesAndFaces
-// purpose:
-//=======================================================================
-void BOPAlgo_FillIn3DParts::MapEdgesAndFaces
- (const TopoDS_Shape& aF,
- BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
- const Handle(NCollection_BaseAllocator)& theAllocator)
-{
- 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 (aMEF.Contains(aE)) {
- BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
- aLF.Append(aF);
- }
- else {
- BOPCol_ListOfShape aLS(theAllocator);
- //
- aLS.Append(aF);
- aMEF.Add(aE, aLS);
- }
- }
- }
-}
-//=======================================================================
-// function: MakeConnexityBlock
-// purpose:
-//=======================================================================
-void BOPAlgo_FillIn3DParts::MakeConnexityBlock
- (const BOPCol_ListOfShape& theLFIn,
- const BOPCol_IndexedMapOfShape& theMEAvoid,
- const BOPCol_MapOfShape& aMFDone,
- const BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
- BOPCol_ListOfShape& theLCB,
- const Handle(NCollection_BaseAllocator)& theAlr)
-{
- 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) {
- continue;
- }
- //
- 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);
- }
-}
-//
-typedef BOPCol_NCVector<BOPAlgo_FillIn3DParts> \
- BOPAlgo_VectorOfFillIn3DParts;
-//
-typedef BOPCol_ContextFunctor
- <BOPAlgo_FillIn3DParts,
- BOPAlgo_VectorOfFillIn3DParts,
- Handle(IntTools_Context),
- IntTools_Context> BOPCol_FillIn3DPartsFunctor;
-//
-typedef BOPCol_ContextCnt
- <BOPCol_FillIn3DPartsFunctor,
- BOPAlgo_VectorOfFillIn3DParts,
- Handle(IntTools_Context)> BOPAlgo_FillIn3DPartsCnt;
-//
-//=======================================================================
// class: BOPAlgo_Builder
//
//=======================================================================
BOPCol_DataMapOfShapeShape& theDraftSolids,
const BOPCol_BaseAllocator& )
{
- Standard_Boolean bHasImage;
- Standard_Integer i, k, aNbS, aNbLIF, aNbFIN, aNbVSB, aNbVFIP;
- Handle(NCollection_BaseAllocator) aAlr0;
- TopoDS_Solid aSD;
- TopoDS_Iterator aIt;
- BRep_Builder aBB;
- //
- BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1;
- BOPCol_ListIteratorOfListOfShape aItLS;
- //
- aAlr0=
- NCollection_BaseAllocator::CommonBaseAllocator();
- //
- BOPCol_MapOfShape aMFence(100, aAlr0);
- BOPAlgo_VectorOfShapeBox aVSB(256, aAlr0);
- //
- theDraftSolids.Clear();
- //
- // 1. aVSB vector Index/FaceBox
- aNbS=myDS->NbSourceShapes();
- for (i=0; i<aNbS; ++i) {
- const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
- if (aSI.ShapeType()!=TopAbs_FACE) {
+ Handle(NCollection_BaseAllocator) anAlloc = new NCollection_IncAllocator;
+
+ // Find all faces that are IN solids
+
+ // Store boxes of the shapes into a map
+ BOPCol_IndexedDataMapOfShapeBox aShapeBoxMap(1, anAlloc);
+
+ // Fence map
+ BOPCol_MapOfShape aMFence(1, anAlloc);
+
+ // Get all faces
+ TopTools_ListOfShape aLFaces(anAlloc);
+
+ Standard_Integer i, aNbS = myDS->NbSourceShapes();
+ for (i = 0; i < aNbS; ++i)
+ {
+ const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
+ if (aSI.ShapeType() != TopAbs_FACE)
continue;
- }
- //
- const TopoDS_Shape& aS=aSI.Shape();
- //
- if (myImages.IsBound(aS)) {
- const BOPCol_ListOfShape& aLS=myImages.Find(aS);
- aItLS.Initialize(aLS);
- for (; aItLS.More(); aItLS.Next()) {
- const TopoDS_Shape& aSx=aItLS.Value();
- if (!aMFence.Add(aSx)) {
- continue;
- }
- Bnd_Box aBox;
- BRepBndLib::Add(aSx, aBox);
- aBox.SetGap(aBox.GetGap() + Precision::Confusion());
- //
- BOPAlgo_ShapeBox& aSB=aVSB.Append1();
- aSB.SetShape(aSx);
- aSB.SetBox(aBox);
+
+ const TopoDS_Shape& aS = aSI.Shape();
+ const TopTools_ListOfShape* pLSIm = myImages.Seek(aS);
+
+ if (pLSIm)
+ {
+ TopTools_ListIteratorOfListOfShape aItLSIm(*pLSIm);
+ for (; aItLSIm.More(); aItLSIm.Next())
+ {
+ const TopoDS_Shape& aSIm = aItLSIm.Value();
+ if (aMFence.Add(aSIm))
+ aLFaces.Append(aSIm);
}
}
- else {
- const Bnd_Box& aBox=aSI.Box();
- //
- BOPAlgo_ShapeBox& aSB=aVSB.Append1();
- aSB.SetShape(aS);
- aSB.SetBox(aBox);
+ else
+ {
+ aLFaces.Append(aS);
+ aShapeBoxMap.Add(aS, aSI.Box());
}
- }//for (i=0; i<aNbS; ++i) {
- aMFence.Clear();
- //
- // 1.2. Prepare TreeFiller
- BOPCol_BoxBndTree aBBTree;
- NCollection_UBTreeFiller <Standard_Integer, Bnd_Box>
- aTreeFiller(aBBTree);
- //
- aNbVSB=aVSB.Extent();
- for (k=0; k<aNbVSB; ++k) {
- const BOPAlgo_ShapeBox& aSBk=aVSB(k);
- const Bnd_Box& aBk=aSBk.Box();
- //
- aTreeFiller.Add(k, aBk);
}
- //
- // 1.3. Shake TreeFiller
- aTreeFiller.Fill();
- //
- //---------------------------------------------
- // 2. Solids
- BOPAlgo_VectorOfFillIn3DParts aVFIP;
- //
- for (i=0; i<aNbS; ++i) {
- const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
- if (aSI.ShapeType()!=TopAbs_SOLID) {
+
+ BRep_Builder aBB;
+
+ // Get all solids
+ TopTools_ListOfShape aLSolids(anAlloc);
+ // Keep INTERNAL faces of the solids
+ BOPCol_DataMapOfShapeListOfShape aSolidsIF(1, anAlloc);
+ // Draft solids
+ BOPCol_IndexedDataMapOfShapeShape aDraftSolid(1, anAlloc);
+
+ for (i = 0; i < aNbS; ++i)
+ {
+ BOPDS_ShapeInfo& aSI = myDS->ChangeShapeInfo(i);
+ if (aSI.ShapeType() != TopAbs_SOLID)
continue;
- }
- //
- const TopoDS_Shape& aS=aSI.Shape();
- const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
- //
- // 2.0 Flag bHasImage
- bHasImage=Standard_False;
- aIt.Initialize(aS);
- for (; aIt.More(); aIt.Next()) {
- const TopoDS_Shape& aShell=aIt.Value();
- bHasImage=myImages.IsBound(aShell);
- if (bHasImage){
- break;
- }
- }
- //
- // 2.1 Bounding box for the solid aS [ aBoxS ]
- Bnd_Box aBoxS;
- aBoxS=aSI.Box();
- //
- // 2.2 Build Draft Solid [aSD]
- BOPCol_ListOfShape aLIF;
+
+ const TopoDS_Shape& aS = aSI.Shape();
+ const TopoDS_Solid& aSolid = (*(TopoDS_Solid*)(&aS));
//
+ // Bounding box for the solid aS
+ const Bnd_Box& aBoxS = aSI.Box();
+
+ // Build Draft Solid
+ TopTools_ListOfShape aLIF;
+ TopoDS_Solid aSD;
aBB.MakeSolid(aSD);
BuildDraftSolid(aSolid, aSD, aLIF);
- //
- BOPAlgo_FillIn3DParts& aFIP=aVFIP.Append1();
- //
- aFIP.SetSolid(aSolid);
- aFIP.SetDraftSolid(aSD);
- aFIP.SetHasImage(bHasImage);
- aFIP.SetBoxS(aBoxS);
- aFIP.SetLIF(aLIF);
- aFIP.SetBBTree(aBBTree);
- aFIP.SetVSB(aVSB);
- }//for (i=0; i<aNbS; ++i) {
- //
- aNbVFIP=aVFIP.Extent();
- //================================================================
- BOPAlgo_FillIn3DPartsCnt::Perform(myRunParallel, aVFIP, myContext);
- //================================================================
- for (k=0; k<aNbVFIP; ++k) {
- BOPAlgo_FillIn3DParts& aFIP=aVFIP(k);
- bHasImage=aFIP.HasImage();
- const TopoDS_Solid& aSolid=aFIP.Solid();
- const TopoDS_Solid& aSDraft =aFIP.DraftSolid();
- const BOPCol_ListOfShape& aLFIN=aFIP.LFIN();
- const BOPCol_ListOfShape& aLIF=aFIP.LIF();
- //
- aNbLIF=aLIF.Extent();
- //
- // Store the results in theInParts, theDraftSolids
- BOPCol_ListOfShape aLFINx;
- //
- aNbFIN=aLFIN.Extent();
- if (aNbFIN || aNbLIF) {
- aItLS.Initialize(aLFIN);
- for (; aItLS.More(); aItLS.Next()) {
- const TopoDS_Shape& aFI=aItLS.Value();
- aLFINx.Append(aFI);
- }
- aItLS.Initialize(aLIF);
- for (; aItLS.More(); aItLS.Next()) {
- const TopoDS_Shape& aFI=aItLS.Value();
- aLFINx.Append(aFI);
- }
- theInParts.Bind(aSolid, aLFINx);
+
+ aLSolids.Append(aSD);
+ aSolidsIF.Bind(aSD, aLIF);
+ aShapeBoxMap.Add(aSD, aBoxS);
+ aDraftSolid.Add(aS, aSD);
+ }
+
+ // Perform classification of the faces
+ TopTools_IndexedDataMapOfShapeListOfShape anInParts;
+
+ BOPAlgo_Tools::ClassifyFaces(aLFaces, aLSolids, myRunParallel,
+ myContext, anInParts, &aShapeBoxMap, &aSolidsIF);
+
+ // Analyze the results of classification
+ Standard_Integer aNbSol = aDraftSolid.Extent();
+ for (i = 1; i <= aNbSol; ++i)
+ {
+ const TopoDS_Solid& aSolid = TopoDS::Solid(aDraftSolid.FindKey(i));
+ const TopoDS_Solid& aSDraft = TopoDS::Solid(aDraftSolid(i));
+ const TopTools_ListOfShape& aLInFaces = anInParts.FindFromKey(aSDraft);
+ const TopTools_ListOfShape& aLInternal = aSolidsIF.Find(aSDraft);
+
+ Standard_Integer aNbIN = aLInFaces.Extent();
+
+ if (!aNbIN)
+ {
+ Standard_Boolean bHasImage = Standard_False;
+ // Check if the shells of the solid have image
+ for (TopoDS_Iterator it(aSolid); it.More() && !bHasImage; it.Next())
+ bHasImage = myImages.IsBound(it.Value());
+
+ if (!bHasImage)
+ // no need to split the solid
+ continue;
}
- //
- if (aNbFIN || bHasImage) {
- theDraftSolids.Bind(aSolid, aSDraft);
+
+ theDraftSolids.Bind(aSolid, aSDraft);
+
+ Standard_Integer aNbInt = aLInternal.Extent();
+ if (aNbInt || aNbIN)
+ {
+ // Combine the lists
+ TopTools_ListOfShape *pLIN = theInParts.Bound(aSolid, TopTools_ListOfShape());
+
+ TopTools_ListIteratorOfListOfShape aItLS(aLInFaces);
+ for (; aItLS.More(); aItLS.Next())
+ pLIN->Append(aItLS.Value());
+
+ aItLS.Initialize(aLInternal);
+ for (; aItLS.More(); aItLS.Next())
+ pLIN->Append(aItLS.Value());
}
}
}
BOPAlgo_PaveFiller::BOPAlgo_PaveFiller
(const Handle(NCollection_BaseAllocator)& theAllocator)
:
- BOPAlgo_Algo(theAllocator)
+ BOPAlgo_Algo(theAllocator),
+ myFPBDone(1, theAllocator)
{
myDS = NULL;
myIterator = NULL;
UpdatePaveBlocksWithSDVertices();
UpdateInterfsWithSDVertices();
//
+ // Force intersection of edges after increase
+ // of the tolerance values of their vertices
+ //ForceInterfEE();
+ // Force Edge/Face intersection after increase
+ // of the tolerance values of their vertices
+ ForceInterfEF();
+ //
// 22
PerformFF();
if (HasErrors()) {
Bnd_Box,
TColStd_MapTransientHasher> BOPAlgo_DataMapOfPaveBlockBndBox;
+ typedef NCollection_DataMap
+ <Standard_Integer,
+ BOPDS_MapOfPaveBlock> BOPAlgo_DataMapOfIntegerMapOfPaveBlock;
//! Sets non-destructive mode automatically if an argument
//! contains a locked sub-shape (see TopoDS_Shape::Locked()).
//! In case self-interference is found the warning is added.
Standard_EXPORT void CheckSelfInterference();
+ //! The method looks for the additional common blocks among pairs of edges
+ //! with the same bounding vertices.
+ Standard_EXPORT void ForceInterfEE();
+
+ //! The method looks for the additional edge/face common blocks
+ //! among pairs of edge/face having the same vertices.
+ Standard_EXPORT void ForceInterfEF();
+
+ //! Performs intersection of given pave blocks
+ //! with all faces from arguments.
+ Standard_EXPORT void ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB,
+ const Standard_Boolean theAddInterf);
+
BOPCol_ListOfShape myArguments;
BOPDS_PDS myDS;
Standard_Boolean myAvoidBuildPCurve;
BOPAlgo_GlueEnum myGlue;
+ BOPAlgo_DataMapOfIntegerMapOfPaveBlock myFPBDone; //!< Fence map of intersected faces and pave blocks
+
private:
}
return bValid;
}
+
+#include <NCollection_IncAllocator.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+
+//=======================================================================
+//function : ForceInterfEE
+//purpose :
+//=======================================================================
+void BOPAlgo_PaveFiller::ForceInterfEE()
+{
+ // Now that we have vertices increased and unified, try to find additional
+ // common blocks among the pairs of edges.
+ // Since all real intersections should have already happened, here we
+ // are interested in common blocks only, thus we need to check only
+ // those pairs of pave blocks with the same bounding vertices.
+
+ Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
+
+ // Initialize pave blocks for all vertices which participated in intersections
+ const Standard_Integer aNbS = myDS->NbSourceShapes();
+ for (Standard_Integer i = 0; i < aNbS; ++i)
+ {
+ const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
+ if (aSI.ShapeType() == TopAbs_VERTEX)
+ {
+ if (myDS->HasInterf(i))
+ myDS->InitPaveBlocksForVertex(i);
+ }
+ }
+
+ // Fill the connection map from bounding vertices to pave blocks
+ // having those bounding vertices
+ NCollection_IndexedDataMap<BOPDS_Pair,
+ BOPDS_ListOfPaveBlock,
+ BOPDS_PairMapHasher> aPBMap(1, anAlloc);
+ // Fence map of pave blocks
+ BOPDS_MapOfPaveBlock aMPBFence(1, anAlloc);
+
+ for (Standard_Integer i = 0; i < aNbS; ++i)
+ {
+ const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
+ if (aSI.ShapeType() != TopAbs_EDGE)
+ // Not an edge
+ continue;
+
+ if (!aSI.HasReference())
+ // Edge has no pave blocks
+ continue;
+
+ if (aSI.HasFlag())
+ // Degenerated edge
+ continue;
+
+ const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(i);
+ BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
+ for (; aItLPB.More(); aItLPB.Next())
+ {
+ const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
+ const Handle(BOPDS_PaveBlock)& aPBR = myDS->RealPaveBlock(aPB);
+ if (!aMPBFence.Add(aPBR))
+ continue;
+
+ // Get indices
+ Standard_Integer nV1, nV2;
+ aPBR->Indices(nV1, nV2);
+
+ // Add pave block to a map
+ BOPDS_Pair aPair(nV1, nV2);
+ BOPDS_ListOfPaveBlock *pList = aPBMap.ChangeSeek(aPair);
+ if (!pList)
+ pList = &aPBMap(aPBMap.Add(aPair, BOPDS_ListOfPaveBlock(anAlloc)));
+ pList->Append(aPBR);
+ }
+ }
+
+ Standard_Integer aNbPB = aPBMap.Extent();
+ if (!aNbPB)
+ return;
+
+ const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1);
+
+ // Prepare pave blocks with the same vertices for intersection.
+ BOPAlgo_VectorOfEdgeEdge aVEdgeEdge;
+
+ for (Standard_Integer i = 1; i <= aNbPB; ++i)
+ {
+ const BOPDS_ListOfPaveBlock& aLPB = aPBMap(i);
+ if (aLPB.Extent() < 2)
+ continue;
+
+ const BOPDS_Pair& aPair = aPBMap.FindKey(i);
+ Standard_Integer nV1, nV2;
+ aPair.Indices(nV1, nV2);
+
+ const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1));
+ const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2));
+
+ // Use the max tolerance of vertices as Fuzzy value for intersection of edges.
+ // In the Self-Interference check mode we are interested in real
+ // intersections only, so use only the real tolerance of edges,
+ // no need to use the extended tolerance.
+ Standard_Real aTolAdd = (bSICheckMode ? myFuzzyValue :
+ 2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2)));
+
+ // All possible pairs combined from the list <aLPB> should be checked
+ BOPDS_ListIteratorOfListOfPaveBlock aItLPB1(aLPB);
+ for (; aItLPB1.More(); aItLPB1.Next())
+ {
+ const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB1.Value();
+ const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPB1);
+ const Standard_Integer nE1 = aPB1->OriginalEdge();
+ const Standard_Integer iR1 = myDS->Rank(nE1);
+ const TopoDS_Edge& aE1 = TopoDS::Edge(myDS->Shape(nE1));
+ Standard_Real aT11, aT12;
+ aPB1->Range(aT11, aT12);
+ BRepAdaptor_Curve aBAC1(aE1);
+ gp_Pnt aPm;
+ gp_Vec aVTgt1;
+ aBAC1.D1((aT11 + aT12) * 0.5, aPm, aVTgt1);
+ if (aVTgt1.SquareMagnitude() < gp::Resolution())
+ continue;
+ aVTgt1.Normalize();
+
+ BOPDS_ListIteratorOfListOfPaveBlock aItLPB2 = aItLPB1;
+ for (aItLPB2.Next(); aItLPB2.More(); aItLPB2.Next())
+ {
+ const Handle(BOPDS_PaveBlock)& aPB2 = aItLPB2.Value();
+ const Handle(BOPDS_CommonBlock)& aCB2 = myDS->CommonBlock(aPB2);
+ const Standard_Integer nE2 = aPB2->OriginalEdge();
+ const Standard_Integer iR2 = myDS->Rank(nE2);
+
+ // Check that the edges came from different arguments
+ if (iR1 == iR2)
+ {
+ // If the sharing of the vertices is not original, but has been acquired
+ // during the operation, check the coincidence of the edges even if
+ // they came from the same argument
+ if ((!myDS->IsNewShape(nV1) && (myDS->Rank(nV1) == iR1)) ||
+ (!myDS->IsNewShape(nV2) && (myDS->Rank(nV2) == iR2)))
+ continue;
+ }
+
+ // Check that the Pave blocks do not form the Common block already
+ if (!aCB1.IsNull() && !aCB2.IsNull())
+ {
+ if (aCB1 == aCB2)
+ continue;
+ }
+
+ const TopoDS_Edge& aE2 = TopoDS::Edge(myDS->Shape(nE2));
+ Standard_Real aT21, aT22;
+ aPB2->Range(aT21, aT22);
+
+ // Check the angle between edges in the middle point.
+ // If the angle is more than 10 degrees, do not use the additional
+ // tolerance, as it may lead to undesired unification of edges
+ Standard_Boolean bUseAddTol = Standard_True;
+ {
+ BRepAdaptor_Curve aBAC2(aE2);
+ if (aBAC1.GetType() != GeomAbs_Line ||
+ aBAC2.GetType() != GeomAbs_Line)
+ {
+ GeomAPI_ProjectPointOnCurve& aProjPC = myContext->ProjPC(aE2);
+ aProjPC.Perform(aPm);
+ if (!aProjPC.NbPoints())
+ continue;
+
+ gp_Pnt aPm2;
+ gp_Vec aVTgt2;
+ aBAC2.D1(aProjPC.LowerDistanceParameter(), aPm2, aVTgt2);
+ if (aVTgt2.SquareMagnitude() < gp::Resolution())
+ continue;
+
+ // The angle should be close to zero
+ Standard_Real aCos = aVTgt1.Dot (aVTgt2.Normalized());
+ if (Abs(aCos) < 0.9848)
+ bUseAddTol = Standard_False;
+ }
+ }
+
+ // Add pair for intersection
+ BOPAlgo_EdgeEdge& anEdgeEdge = aVEdgeEdge.Append1();
+ anEdgeEdge.UseQuickCoincidenceCheck(Standard_True);
+ anEdgeEdge.SetPaveBlock1(aPB1);
+ anEdgeEdge.SetPaveBlock2(aPB2);
+ anEdgeEdge.SetEdge1(aE1, aT11, aT12);
+ anEdgeEdge.SetEdge2(aE2, aT21, aT22);
+ //anEdgeEdge.SetBoxes (myDS->ShapeInfo(nE1).Box(), myDS->ShapeInfo (nE2).Box());
+ if (bUseAddTol)
+ anEdgeEdge.SetFuzzyValue(myFuzzyValue + aTolAdd);
+ else
+ anEdgeEdge.SetFuzzyValue(myFuzzyValue);
+ anEdgeEdge.SetProgressIndicator(myProgressIndicator);
+ }
+ }
+ }
+
+ Standard_Integer aNbPairs = aVEdgeEdge.Length();
+ if (!aNbPairs)
+ return;
+
+ aPBMap.Clear();
+ aMPBFence.Clear();
+ anAlloc->Reset();
+
+ // Perform intersection of the found pairs
+ BOPAlgo_EdgeEdgeCnt::Perform (myRunParallel, aVEdgeEdge);
+
+ BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE();
+ if (aEEs.IsEmpty())
+ aEEs.SetIncrement(10);
+
+ // Analyze the results of intersection looking for TopAbs_EDGE
+ // intersection type only.
+
+ BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock aMPBLPB(1, anAlloc);
+
+ for (Standard_Integer i = 0; i < aNbPairs; ++i)
+ {
+ BOPAlgo_EdgeEdge& anEdgeEdge = aVEdgeEdge(i);
+ if (!anEdgeEdge.IsDone() || anEdgeEdge.HasErrors())
+ {
+ // Warn about failed intersection of sub-shapes
+ //const TopoDS_Shape& aE1 = myDS->Shape(anEdgeEdge.PaveBlock1()->OriginalEdge());
+ //const TopoDS_Shape& aE2 = myDS->Shape(anEdgeEdge.PaveBlock2()->OriginalEdge());
+ //AddIntersectionFailedWarning(aE1, aE2);
+ continue;
+ }
+
+ const IntTools_SequenceOfCommonPrts& aCParts = anEdgeEdge.CommonParts();
+ if (aCParts.Length() != 1)
+ continue;
+
+ const IntTools_CommonPrt& aCP = aCParts(1);
+ if (aCP.Type() != TopAbs_EDGE)
+ continue;
+
+ Handle(BOPDS_PaveBlock) aPB[] = {anEdgeEdge.PaveBlock1(), anEdgeEdge.PaveBlock2()};
+ const Standard_Integer nE1 = aPB[0]->OriginalEdge();
+ const Standard_Integer nE2 = aPB[1]->OriginalEdge();
+
+ if (myDS->Rank(nE1) == myDS->Rank(nE2))
+ {
+ // Add acquired self-interference warning
+ //TopoDS_Compound aWC;
+ //BRep_Builder().MakeCompound(aWC);
+ //BRep_Builder().Add(aWC, myDS->Shape(nE1));
+ //BRep_Builder().Add(aWC, myDS->Shape(nE2));
+ //AddWarning(new BOPAlgo_AlertAcquiredSelfIntersection(aWC));
+ }
+
+ BOPDS_InterfEE& aEE = aEEs.Append1();
+ aEE.SetIndices(nE1, nE2);
+ aEE.SetCommonPart(aCP);
+ myDS->AddInterf(nE1, nE2);
+
+ // Fill map for common blocks creation
+ for (Standard_Integer j = 0; j < 2; ++j)
+ {
+ if (myDS->IsCommonBlock(aPB[j]))
+ {
+ const BOPDS_ListOfPaveBlock& aLPBCB = myDS->CommonBlock(aPB[j])->PaveBlocks();
+ BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPBCB);
+ for (; aItLPB.More(); aItLPB.Next())
+ BOPAlgo_Tools::FillMap<Handle(BOPDS_PaveBlock),
+ TColStd_MapTransientHasher>(aPB[j], aItLPB.Value(), aMPBLPB, anAlloc);
+ }
+ }
+ BOPAlgo_Tools::FillMap<Handle(BOPDS_PaveBlock),
+ TColStd_MapTransientHasher>(aPB[0], aPB[1], aMPBLPB, anAlloc);
+ }
+
+ // Create new common blocks of coinciding pairs.
+ BOPAlgo_Tools::PerformCommonBlocks(aMPBLPB, anAlloc, myDS);
+}
#include <BOPAlgo_PaveFiller.hxx>
#include <BOPAlgo_Alerts.hxx>
#include <BOPAlgo_Tools.hxx>
+#include <BOPCol_BoxBndTree.hxx>
#include <BOPCol_MapOfInteger.hxx>
#include <BOPCol_NCVector.hxx>
#include <BOPCol_Parallel.hxx>
#include <BOPDS_Pave.hxx>
#include <BOPDS_PaveBlock.hxx>
#include <BOPTools_AlgoTools.hxx>
+#include <BOPTools_AlgoTools2D.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
+#include <GeomAPI_ProjectPointOnSurf.hxx>
#include <gp_Pnt.hxx>
#include <IntTools_CommonPrt.hxx>
#include <IntTools_Context.hxx>
#include <IntTools_Range.hxx>
#include <IntTools_SequenceOfCommonPrts.hxx>
#include <IntTools_Tools.hxx>
+#include <NCollection_IncAllocator.hxx>
+#include <NCollection_UBTreeFiller.hxx>
#include <Precision.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Vertex.hxx>
+
//=======================================================================
//class : BOPAlgo_EdgeFace
//purpose :
BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange);
aEdgeFace.SetRange (aPBRange);
aEdgeFace.SetProgressIndicator(myProgressIndicator);
- //
+
+ // Save the pair to avoid their forced intersection
+ BOPDS_MapOfPaveBlock* pMPB = myFPBDone.ChangeSeek(nF);
+ if (!pMPB)
+ pMPB = myFPBDone.Bound(nF, BOPDS_MapOfPaveBlock());
+ pMPB->Add(aPB);
}//for (; aIt.More(); aIt.Next()) {
}//for (; myIterator->More(); myIterator->Next()) {
//
}
}
}
+
+//=======================================================================
+//function : ForceInterfEF
+//purpose :
+//=======================================================================
+void BOPAlgo_PaveFiller::ForceInterfEF()
+{
+ if (!myIsPrimary)
+ return;
+
+ // Now that we have vertices increased and unified, try to find additional
+ // edge/face common blocks among the pairs of edge/face.
+ // Here, we are interested in common blocks only, as all real intersections
+ // should have happened already. Thus, we need to check only those pairs
+ // of edge/face which have the same vertices.
+
+ // Collect all pave blocks
+ BOPDS_IndexedMapOfPaveBlock aMPB;
+ const Standard_Integer aNbS = myDS->NbSourceShapes();
+ for (Standard_Integer nE = 0; nE < aNbS; ++nE)
+ {
+ const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nE);
+ if (aSI.ShapeType() != TopAbs_EDGE)
+ // Not an edge
+ continue;
+
+ if (!aSI.HasReference())
+ // Edge has no pave blocks
+ continue;
+
+ if (aSI.HasFlag())
+ // Degenerated edge
+ continue;
+
+ const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(nE);
+ BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
+ for (; aItLPB.More(); aItLPB.Next())
+ {
+ const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
+ const Handle(BOPDS_PaveBlock)& aPBR = myDS->RealPaveBlock(aPB);
+ aMPB.Add(aPBR);
+ }
+ }
+
+ // Perform intersection of collected pave blocks with faces
+ ForceInterfEF(aMPB, Standard_True);
+}
+
+//=======================================================================
+//function : ForceInterfEF
+//purpose :
+//=======================================================================
+void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB,
+ const Standard_Boolean theAddInterf)
+{
+ if (theMPB.IsEmpty())
+ return;
+
+ // Fill the tree with bounding boxes of the pave blocks
+ NCollection_UBTree<Standard_Integer, Bnd_Box> aBBTree;
+ NCollection_UBTreeFiller<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
+
+ Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
+ BOPDS_IndexedMapOfPaveBlock aPBMap(1, anAlloc);
+
+ Standard_Integer aNbPB = theMPB.Extent();
+ for (Standard_Integer iPB = 1; iPB <= aNbPB; ++iPB)
+ {
+ Handle(BOPDS_PaveBlock) aPB = theMPB(iPB);
+ if (!aPB->HasShrunkData() || !myDS->IsValidShrunkData(aPB))
+ {
+ FillShrunkData(aPB);
+ if (!aPB->HasShrunkData())
+ continue;
+ }
+
+ Standard_Real f, l;
+ Bnd_Box aPBBox;
+ Standard_Boolean isSplit;
+ aPB->ShrunkData(f, l, aPBBox, isSplit);
+
+ aTreeFiller.Add(aPBMap.Add(aPB), aPBBox);
+ }
+
+ // Shake the tree
+ aTreeFiller.Fill();
+
+ const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1);
+
+ // Find pairs of Face/PaveBlock containing the same vertices
+ // and prepare those pairs for intersection.
+ BOPAlgo_VectorOfEdgeFace aVEdgeFace;
+
+ const Standard_Integer aNbS = myDS->NbSourceShapes();
+ for (Standard_Integer nF = 0; nF < aNbS; ++nF)
+ {
+ const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF);
+ if (aSI.ShapeType() != TopAbs_FACE)
+ // Not a face
+ continue;
+
+ if (!aSI.HasReference())
+ // Face has no face info
+ continue;
+
+ const Bnd_Box& aBoxF = aSI.Box();
+ BOPCol_BoxBndTreeSelector aSelector;
+ aSelector.SetBox(aBoxF);
+
+ if (!aBBTree.Select(aSelector))
+ continue;
+
+ const TopoDS_Face& aF = TopoDS::Face(aSI.Shape());
+ const BOPDS_FaceInfo& aFI = myDS->FaceInfo(nF);
+ // Vertices of the face
+ BOPCol_MapOfInteger aMVF;
+ const BOPCol_MapOfInteger* pMVF[] = { &aFI.VerticesOn(),
+ &aFI.VerticesIn(),
+ &aFI.VerticesSc() };
+ for (Standard_Integer iM = 0; iM < 3; ++iM)
+ {
+ BOPCol_MapIteratorOfMapOfInteger itM(*pMVF[iM]);
+ for (; itM.More(); itM.Next())
+ aMVF.Add(itM.Value());
+ }
+
+ // Pave Blocks of the face
+ const BOPDS_IndexedMapOfPaveBlock* pMPBF[] = { &aFI.PaveBlocksOn(),
+ &aFI.PaveBlocksIn(),
+ &aFI.PaveBlocksSc() };
+ for (Standard_Integer iM = 0; iM < 3; ++iM)
+ {
+ const Standard_Integer aNb = pMPBF[iM]->Extent();
+ for (Standard_Integer iPB = 1; iPB <= aNb; ++iPB)
+ {
+ const Handle(BOPDS_PaveBlock)& aPB = pMPBF[iM]->FindKey(iPB);
+ aMVF.Add(aPB->Pave1().Index());
+ aMVF.Add(aPB->Pave2().Index());
+ }
+ }
+
+ // Projection tool
+ GeomAPI_ProjectPointOnSurf& aProjPS = myContext->ProjPS(aF);
+ BRepAdaptor_Surface& aSurfAdaptor = myContext->SurfaceAdaptor (aF);
+
+ // Iterate on pave blocks and combine pairs containing
+ // the same vertices
+ const BOPCol_ListOfInteger& aLIPB = aSelector.Indices();
+ BOPCol_ListOfInteger::Iterator itLIPB(aLIPB);
+ for (; itLIPB.More(); itLIPB.Next())
+ {
+ const Handle(BOPDS_PaveBlock)& aPB = aPBMap(itLIPB.Value());
+ if (pMPBF[0]->Contains(aPB) ||
+ pMPBF[1]->Contains(aPB) ||
+ pMPBF[2]->Contains(aPB))
+ continue;
+
+ // Check if the face contains both vertices of the pave block
+ Standard_Integer nV1, nV2;
+ aPB->Indices(nV1, nV2);
+ if (!aMVF.Contains(nV1) || !aMVF.Contains(nV2))
+ // Face does not contain the vertices
+ continue;
+
+ // Get the edge
+ Standard_Integer nE;
+ if (!aPB->HasEdge(nE))
+ {
+ nE = aPB->OriginalEdge();
+ if (nE < 0)
+ continue;
+
+ // Make sure that the edge and face came from different arguments
+ if (myDS->Rank(nF) == myDS->Rank(nE))
+ continue;
+ }
+
+ const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
+ BRepAdaptor_Curve aBAC(aE);
+
+ // Check directions coincidence at middle point on the edge
+ // and projection of that point on the face.
+ // If the angle between tangent vector to the curve and normal
+ // of the face is not in the range of 65 - 115 degrees, do not use the additional
+ // tolerance, as it may lead to undesired unification of edge with the face.
+ Standard_Boolean bUseAddTol = Standard_True;
+
+ Standard_Real aTS[2];
+ Bnd_Box aPBBox;
+ Standard_Boolean isSplit;
+ aPB->ShrunkData(aTS[0], aTS[1], aPBBox, isSplit);
+
+ // Middle point
+ gp_Pnt aPOnE;
+ // Tangent vector in the middle point
+ gp_Vec aVETgt;
+ aBAC.D1(BOPTools_AlgoTools2D::IntermediatePoint(aTS[0], aTS[1]), aPOnE, aVETgt);
+ if (aVETgt.SquareMagnitude() < gp::Resolution())
+ continue;
+
+ aProjPS.Perform(aPOnE);
+ if (!aProjPS.NbPoints())
+ continue;
+
+ // Check the distance in the middle point, using the max vertices
+ // tolerance as the criteria.
+ const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1));
+ const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2));
+
+ // In the Self-Interference check mode we are interested in real
+ // intersections only, so use only the real tolerance of edges,
+ // no need to use the extended tolerance.
+ Standard_Real aTolCheck = (bSICheckMode ? myFuzzyValue :
+ 2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2)));
+
+ if (aProjPS.LowerDistance() > aTolCheck + myFuzzyValue)
+ continue;
+
+ Standard_Real U, V;
+ aProjPS.LowerDistanceParameters(U, V);
+ if (!myContext->IsPointInFace(aF, gp_Pnt2d(U, V)))
+ continue;
+
+ if (aSurfAdaptor.GetType() != GeomAbs_Plane ||
+ aBAC.GetType() != GeomAbs_Line)
+ {
+ gp_Pnt aPOnS = aProjPS.NearestPoint();
+ gp_Vec aVFNorm(aPOnS, aPOnE);
+ if (aVFNorm.SquareMagnitude() > gp::Resolution())
+ {
+ // Angle between vectors should be close to 90 degrees.
+ // We allow deviation of 10 degrees.
+ Standard_Real aCos = aVFNorm.Normalized().Dot (aVETgt.Normalized());
+ if (Abs(aCos) > 0.17365)
+ bUseAddTol = Standard_False;
+ }
+ }
+
+ // Compute an addition to Fuzzy value
+ Standard_Real aTolAdd = 0.0;
+ if (bUseAddTol)
+ {
+ // Compute the distance from the bounding points of the edge
+ // to the face and use the maximal of these distances as a
+ // fuzzy tolerance for the intersection.
+ // Use the maximal tolerance of the pave block's vertices
+ // as a max criteria for the computed distance.
+
+ for (Standard_Integer iP = 0; iP < 2; ++iP)
+ {
+ gp_Pnt aP = aBAC.Value(aTS[iP]);
+ aProjPS.Perform(aP);
+ if (aProjPS.NbPoints())
+ {
+ Standard_Real aDistEF = aProjPS.LowerDistance();
+ if (aDistEF < aTolCheck && aDistEF > aTolAdd)
+ aTolAdd = aDistEF;
+ }
+ }
+ if (aTolAdd > 0.)
+ {
+ aTolAdd -= (BRep_Tool::Tolerance(aE) + BRep_Tool::Tolerance(aF));
+ if (aTolAdd < 0.)
+ aTolAdd = 0.;
+ }
+ }
+
+ Standard_Boolean bIntersect = aTolAdd > 0;
+ if (!bIntersect)
+ {
+ const BOPDS_MapOfPaveBlock* pMPB = myFPBDone.Seek(nF);
+ bIntersect = !pMPB || !(pMPB->Contains(aPB));
+ }
+
+ if (bIntersect)
+ {
+ // Prepare pair for intersection
+ BOPAlgo_EdgeFace& aEdgeFace = aVEdgeFace.Append1();
+ aEdgeFace.SetIndices(nE, nF);
+ aEdgeFace.SetPaveBlock(aPB);
+ aEdgeFace.SetEdge(aE);
+ aEdgeFace.SetFace(aF);
+ //aEdgeFace.SetBoxes (myDS->ShapeInfo(nE).Box(), myDS->ShapeInfo (nF).Box());
+ aEdgeFace.SetFuzzyValue(myFuzzyValue + aTolAdd);
+ aEdgeFace.UseQuickCoincidenceCheck(Standard_True);
+ aEdgeFace.SetRange(IntTools_Range(aPB->Pave1().Parameter(), aPB->Pave2().Parameter()));
+ aEdgeFace.SetProgressIndicator(myProgressIndicator);
+ }
+ }
+ }
+
+ Standard_Integer aNbEFs = aVEdgeFace.Length();
+ if (!aNbEFs)
+ return;
+
+ aPBMap.Clear();
+ anAlloc->Reset();
+
+ // Perform intersection of the found pairs
+ BOPAlgo_EdgeFaceCnt::Perform (myRunParallel, aVEdgeFace, myContext);
+
+ BOPDS_VectorOfInterfEF& aEFs = myDS->InterfEF();
+ if (theAddInterf && aEFs.IsEmpty())
+ aEFs.SetIncrement(10);
+
+ // Analyze the results of intersection looking for TopAbs_EDGE
+ // intersection type only.
+
+ // Collect all pairs for common block creation
+ BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(1, anAlloc);
+
+ for (Standard_Integer i = 0; i < aNbEFs; ++i)
+ {
+ BOPAlgo_EdgeFace& anEdgeFace = aVEdgeFace(i);
+ if (!anEdgeFace.IsDone() || anEdgeFace.HasErrors())
+ continue;
+
+ const IntTools_SequenceOfCommonPrts& aCParts = anEdgeFace.CommonParts();
+ if (aCParts.Length() != 1)
+ continue;
+
+ const IntTools_CommonPrt& aCP = aCParts(1);
+ if (aCP.Type() != TopAbs_EDGE)
+ continue;
+
+ Standard_Integer nE, nF;
+ anEdgeFace.Indices(nE, nF);
+ if (theAddInterf)
+ {
+ // Add interference
+ BOPDS_InterfEF& aEF = aEFs.Append1();
+ aEF.SetIndices(nE, nF);
+ aEF.SetCommonPart(aCP);
+ myDS->AddInterf(nE, nF);
+ }
+
+ const Handle(BOPDS_PaveBlock)& aPB = anEdgeFace.PaveBlock();
+ // Update face information with new IN pave block
+ myDS->ChangeFaceInfo(nF).ChangePaveBlocksIn().Add(aPB);
+ if (theAddInterf)
+ // Fill map for common blocks creation
+ BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, anAlloc);
+ }
+
+ if (aMPBLI.Extent())
+ // Create new common blocks for coinciding pairs
+ BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, anAlloc, myDS);
+}
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
+#include <TopoDS_Solid.hxx>
#include <BOPCol_BoxBndTree.hxx>
#include <BOPCol_IndexedMapOfShape.hxx>
#include <BOPCol_NCVector.hxx>
#include <BOPCol_Parallel.hxx>
+#include <BRepBndLib.hxx>
+
#include <TopExp_Explorer.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BOPTools_AlgoTools2D.hxx>
+#include <NCollection_IncAllocator.hxx>
#include <NCollection_UBTreeFiller.hxx>
#include <IntTools_Context.hxx>
+#include <algorithm>
+
typedef NCollection_IndexedDataMap
<TopoDS_Shape, gp_Dir, TopTools_ShapeMapHasher> BOPAlgo_IndexedDataMapOfShapeDir;
typedef NCollection_IndexedDataMap
}
}
}
+//=======================================================================
+// Classification of the faces relatively solids
+//=======================================================================
+
+//=======================================================================
+//class : BOPAlgo_ShapeBox
+//purpose : Auxiliary class defining ShapeBox structure
+//=======================================================================
+class BOPAlgo_ShapeBox
+{
+public:
+ //! Empty constructor
+ BOPAlgo_ShapeBox() {};
+ //! Sets the shape
+ void SetShape(const TopoDS_Shape& theS)
+ {
+ myShape = theS;
+ };
+ //! Returns the shape
+ const TopoDS_Shape& Shape() const
+ {
+ return myShape;
+ };
+ //! Sets the bounding box
+ void SetBox(const Bnd_Box& theBox)
+ {
+ myBox = theBox;
+ };
+ //! Returns the bounding box
+ const Bnd_Box& Box() const
+ {
+ return myBox;
+ };
+private:
+ TopoDS_Shape myShape;
+ Bnd_Box myBox;
+};
+// Vector of ShapeBox
+typedef BOPCol_NCVector<BOPAlgo_ShapeBox> BOPAlgo_VectorOfShapeBox;
+
+//=======================================================================
+//class : BOPAlgo_FillIn3DParts
+//purpose : Auxiliary class for faces classification in parallel mode
+//=======================================================================
+class BOPAlgo_FillIn3DParts : public BOPAlgo_Algo
+{
+public:
+ DEFINE_STANDARD_ALLOC
+
+ //! Constructor
+ BOPAlgo_FillIn3DParts()
+ {
+ myBBTree = NULL;
+ myVShapeBox = NULL;
+ };
+
+ //! Destructor
+ virtual ~BOPAlgo_FillIn3DParts() {};
+
+ //! Sets the solid
+ void SetSolid(const TopoDS_Solid& theSolid)
+ {
+ mySolid = theSolid;
+ };
+
+ //! Returns the solid
+ const TopoDS_Solid& Solid() const
+ {
+ return mySolid;
+ };
+
+ //! Sets the box for the solid
+ void SetBoxS(const Bnd_Box& theBox)
+ {
+ myBoxS = theBox;
+ };
+
+ //! Returns the solid's box
+ const Bnd_Box& BoxS() const
+ {
+ return myBoxS;
+ };
+
+ //! Sets own INTERNAL faces of the solid
+ void SetOwnIF(const BOPCol_ListOfShape& theLIF)
+ {
+ myOwnIF = theLIF;
+ };
+
+ //! Returns own INTERNAL faces of the solid
+ const BOPCol_ListOfShape& OwnIF() const
+ {
+ return myOwnIF;
+ };
+
+ //! Sets the Bounding Box tree
+ void SetBBTree(const BOPCol_BoxBndTree& theBBTree)
+ {
+ myBBTree = (BOPCol_BoxBndTree*)&theBBTree;
+ };
+
+ //! Sets the ShapeBox structure
+ void SetShapeBoxVector(const BOPAlgo_VectorOfShapeBox& theShapeBox)
+ {
+ myVShapeBox = (BOPAlgo_VectorOfShapeBox*)&theShapeBox;
+ };
+
+ //! Sets the context
+ void SetContext(const Handle(IntTools_Context)& theContext)
+ {
+ myContext = theContext;
+ }
+
+ //! Returns the context
+ const Handle(IntTools_Context)& Context() const
+ {
+ return myContext;
+ }
+
+ //! Performs the classification
+ virtual void Perform();
+
+ //! Returns the faces classified as IN for solid
+ const BOPCol_ListOfShape& InFaces() const
+ {
+ return myInFaces;
+ };
+
+private:
+
+ //! Prepares Edge-Face connection map of the given shape
+ void MapEdgesAndFaces(const TopoDS_Shape& theF,
+ BOPCol_IndexedDataMapOfShapeListOfShape& theEFMap,
+ const Handle(NCollection_BaseAllocator)& theAlloc);
+
+ //! Makes the connexity block of faces using the connection map
+ void MakeConnexityBlock(const TopoDS_Face& theF,
+ const BOPCol_IndexedMapOfShape& theMEToAvoid,
+ const BOPCol_IndexedDataMapOfShapeListOfShape& theEFMap,
+ BOPCol_MapOfShape& theMFDone,
+ BOPCol_ListOfShape& theLCB,
+ TopoDS_Face& theFaceToClassify);
+
+ TopoDS_Solid mySolid; //! Solid
+ Bnd_Box myBoxS; // Bounding box of the solid
+ BOPCol_ListOfShape myOwnIF; //! Own INTERNAL faces of the solid
+ BOPCol_ListOfShape myInFaces; //! Faces classified as IN
+
+ BOPCol_BoxBndTree* myBBTree; //! UB tree of bounding boxes
+ BOPAlgo_VectorOfShapeBox* myVShapeBox; //! ShapeBoxMap
+
+ TopoDS_Iterator myItF; //! Iterators
+ TopoDS_Iterator myItW;
+
+ Handle(IntTools_Context) myContext; //! Context
+};
+
+//=======================================================================
+//function : BOPAlgo_FillIn3DParts::Perform
+//purpose :
+//=======================================================================
+void BOPAlgo_FillIn3DParts::Perform()
+{
+ BOPAlgo_Algo::UserBreak();
+
+ myInFaces.Clear();
+
+ // 1. Select boxes of faces that are not out of aBoxS
+ BOPCol_BoxBndTreeSelector aSelector;
+ aSelector.SetBox(myBoxS);
+ //
+ if (!myBBTree->Select(aSelector))
+ return;
+
+ const BOPCol_ListOfInteger& aLIFP = aSelector.Indices();
+
+ // 2. Fill maps of edges and faces of the solid
+
+ Handle(NCollection_BaseAllocator) anAlloc = new NCollection_IncAllocator;
+
+ BOPAlgo_VectorOfShapeBox& aVShapeBox = *myVShapeBox;
+
+ BOPCol_IndexedMapOfShape aMSE(1, anAlloc), aMSF(1, anAlloc);
+ BOPTools::MapShapes(mySolid, TopAbs_EDGE, aMSE);
+ BOPTools::MapShapes(mySolid, TopAbs_FACE, aMSF);
+
+ // Check if the Solid contains any faces
+ Standard_Boolean bIsEmpty = aMSF.IsEmpty();
+
+ // Add own internal faces of the solid into aMSF
+ BOPCol_ListIteratorOfListOfShape aItLS(myOwnIF);
+ for (; aItLS.More(); aItLS.Next())
+ aMSF.Add(aItLS.Value());
+
+ // 3. aIVec - faces to process.
+ // Filter the selected faces with faces of the solid.
+ BOPCol_NCVector<Standard_Integer> aIVec(256, anAlloc);
+
+ BOPCol_ListIteratorOfListOfInteger aItLI(aLIFP);
+ for (; aItLI.More(); aItLI.Next()) {
+ Standard_Integer nFP = aItLI.Value();
+ const TopoDS_Shape& aFP = aVShapeBox(nFP).Shape();
+ if (!aMSF.Contains(aFP))
+ aIVec.Append1() = nFP;
+ }
+
+ // 4. Classify faces relatively solid.
+ // Store faces that are IN mySolid into <myInFaces>
+
+ Standard_Integer k, aNbFP = aIVec.Length();
+ // Sort indices if necessary
+ if (aNbFP > 1)
+ std::sort(aIVec.begin(), aIVec.end());
+
+ if (bIsEmpty)
+ {
+ // The solid is empty as it does not contain any faces.
+ // It could happen when the input solid consists of INTERNAL faces only.
+ // Classification of any point relatively empty solid would always give IN status.
+ // Thus, we consider all selected faces as IN without real classification.
+ for (k = 0; k < aNbFP; ++k)
+ myInFaces.Append(aVShapeBox(aIVec(k)).Shape());
+
+ return;
+ }
+
+ // Prepare EF map of faces to process for building connexity blocks
+ BOPCol_IndexedDataMapOfShapeListOfShape aMEFP(1, anAlloc);
+ if (aNbFP > 1)
+ {
+ for (k = 0; k < aNbFP; ++k)
+ MapEdgesAndFaces(aVShapeBox(aIVec(k)).Shape(), aMEFP, anAlloc);
+ }
+
+ // Map of Edge-Face connection, necessary for solid classification.
+ // It will be filled when first classification is performed.
+ BOPCol_IndexedDataMapOfShapeListOfShape aMEFDS(1, anAlloc);
+
+ // Fence map to avoid processing of the same faces twice
+ BOPCol_MapOfShape aMFDone(1, anAlloc);
+
+ for (k = 0; k < aNbFP; ++k)
+ {
+ Standard_Integer nFP = aIVec(k);
+ const TopoDS_Face& aFP = (*(TopoDS_Face*)&aVShapeBox(nFP).Shape());
+ if (!aMFDone.Add(aFP))
+ continue;
+
+ // Make connexity blocks of faces, avoiding passing through the
+ // borders of the solid. It helps to reduce significantly the
+ // number of classified faces.
+ BOPCol_ListOfShape aLCBF(anAlloc);
+ // The most appropriate face for classification
+ TopoDS_Face aFaceToClassify;
+ MakeConnexityBlock(aFP, aMSE, aMEFP, aMFDone, aLCBF, aFaceToClassify);
+
+ if (!myBoxS.IsWhole())
+ {
+ // First, try fast classification of the whole block by additional
+ // check on bounding boxes - check that bounding boxes of all vertices
+ // of the block interfere with the box of the solid.
+ // If not, the faces are out.
+ Standard_Boolean bOut = Standard_False;
+ aItLS.Initialize(aLCBF);
+ for (; aItLS.More() && !bOut; aItLS.Next())
+ {
+ TopExp_Explorer anExpV(aItLS.Value(), TopAbs_VERTEX);
+ for (; anExpV.More() && !bOut; anExpV.Next())
+ {
+ const TopoDS_Vertex& aV = TopoDS::Vertex(anExpV.Current());
+ Bnd_Box aBBV;
+ aBBV.Add(BRep_Tool::Pnt(aV));
+ aBBV.SetGap(BRep_Tool::Tolerance(aV));
+ bOut = myBoxS.IsOut(aBBV);
+ }
+ }
+ if (bOut)
+ continue;
+ }
+
+ if (aFaceToClassify.IsNull())
+ aFaceToClassify = aFP;
+
+ if (aMEFDS.IsEmpty())
+ // Fill EF map for Solid
+ BOPTools::MapShapesAndAncestors(mySolid, TopAbs_EDGE, TopAbs_FACE, aMEFDS);
+
+ // All vertices are interfere with the solids box, run classification.
+ Standard_Boolean bIsIN = BOPTools_AlgoTools::IsInternalFace
+ (aFaceToClassify, mySolid, aMEFDS, Precision::Confusion(), myContext);
+ if (bIsIN)
+ {
+ aItLS.Initialize(aLCBF);
+ for (; aItLS.More(); aItLS.Next())
+ myInFaces.Append(aItLS.Value());
+ }
+ }
+}
+//=======================================================================
+// function: MapEdgesAndFaces
+// purpose:
+//=======================================================================
+void BOPAlgo_FillIn3DParts::MapEdgesAndFaces(const TopoDS_Shape& theF,
+ BOPCol_IndexedDataMapOfShapeListOfShape& theEFMap,
+ const Handle(NCollection_BaseAllocator)& theAllocator)
+{
+ myItF.Initialize(theF);
+ 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();
+
+ BOPCol_ListOfShape* pLF = theEFMap.ChangeSeek(aE);
+ if (!pLF)
+ pLF = &theEFMap(theEFMap.Add(aE, BOPCol_ListOfShape(theAllocator)));
+ pLF->Append(theF);
+ }
+ }
+}
+//=======================================================================
+// function: MakeConnexityBlock
+// purpose:
+//=======================================================================
+void BOPAlgo_FillIn3DParts::MakeConnexityBlock(const TopoDS_Face& theFStart,
+ const BOPCol_IndexedMapOfShape& theMEAvoid,
+ const BOPCol_IndexedDataMapOfShapeListOfShape& theEFMap,
+ BOPCol_MapOfShape& theMFDone,
+ BOPCol_ListOfShape& theLCB,
+ TopoDS_Face& theFaceToClassify)
+{
+ // Add start element
+ theLCB.Append(theFStart);
+ if (theEFMap.IsEmpty())
+ return;
+
+ 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))
+ {
+ if (theFaceToClassify.IsNull())
+ theFaceToClassify = TopoDS::Face(aF);
+ continue;
+ }
+
+ const BOPCol_ListOfShape* pLF = theEFMap.Seek(aE);
+ if (!pLF)
+ continue;
+ BOPCol_ListIteratorOfListOfShape aItLF(*pLF);
+ for (; aItLF.More(); aItLF.Next())
+ {
+ const TopoDS_Shape& aFToAdd = aItLF.Value();
+ if (theMFDone.Add(aFToAdd))
+ theLCB.Append(aFToAdd);
+ }
+ }
+ }
+ }
+}
+
+// Vector of solid classifiers
+typedef BOPCol_NCVector<BOPAlgo_FillIn3DParts> BOPAlgo_VectorOfFillIn3DParts;
+
+// Functors to perform classification
+typedef BOPCol_ContextFunctor<BOPAlgo_FillIn3DParts,
+ BOPAlgo_VectorOfFillIn3DParts,
+ Handle(IntTools_Context),
+ IntTools_Context> BOPAlgo_FillIn3DPartsFunctor;
+
+typedef BOPCol_ContextCnt<BOPAlgo_FillIn3DPartsFunctor,
+ BOPAlgo_VectorOfFillIn3DParts,
+ Handle(IntTools_Context)> BOPAlgo_FillIn3DPartsCnt;
+
+namespace {
+ static void buildBoxForSolid (const TopoDS_Solid& theSolid,
+ Bnd_Box& theBox)
+ {
+ Standard_Boolean bIsOpenBox = Standard_False;
+ for (TopoDS_Iterator itS (theSolid); itS.More() && !bIsOpenBox; itS.Next())
+ {
+ const TopoDS_Shell& aShell = TopoDS::Shell (itS.Value());
+ bIsOpenBox = BOPTools_AlgoTools::IsOpenShell (aShell);
+
+ if (bIsOpenBox)
+ break;
+
+ for (TopoDS_Iterator itF (aShell); itF.More(); itF.Next())
+ {
+ const TopoDS_Face& aF = TopoDS::Face (itF.Value());
+
+ Bnd_Box aBoxF;
+ BRepBndLib::Add (aF, aBoxF);
+
+ bIsOpenBox = (aBoxF.IsOpenXmin() || aBoxF.IsOpenXmax() ||
+ aBoxF.IsOpenYmin() || aBoxF.IsOpenYmax() ||
+ aBoxF.IsOpenZmin() || aBoxF.IsOpenZmax());
+
+ if (bIsOpenBox)
+ break;
+
+ theBox.Add (aBoxF);
+ }
+ }
+ if (bIsOpenBox || BOPTools_AlgoTools::IsInvertedSolid (theSolid))
+ theBox.SetWhole();
+ }
+}
+
+//=======================================================================
+//function : ClassifyFaces
+//purpose :
+//=======================================================================
+void BOPAlgo_Tools::ClassifyFaces(const BOPCol_ListOfShape& theFaces,
+ const BOPCol_ListOfShape& theSolids,
+ const Standard_Boolean theRunParallel,
+ Handle(IntTools_Context)& theContext,
+ BOPCol_IndexedDataMapOfShapeListOfShape& theInParts,
+ const BOPCol_IndexedDataMapOfShapeBox* theBoxes,
+ const BOPCol_DataMapOfShapeListOfShape* theSolidsIF)
+{
+ Handle(NCollection_BaseAllocator) anAlloc = new NCollection_IncAllocator;
+
+ // Fill the vector of shape box with faces and its bounding boxes
+ BOPAlgo_VectorOfShapeBox aVSB(256, anAlloc);
+
+ BOPCol_ListIteratorOfListOfShape aItLF(theFaces);
+ for (; aItLF.More(); aItLF.Next())
+ {
+ const TopoDS_Shape& aF = aItLF.Value();
+ // Append face to the vector of shape box
+ BOPAlgo_ShapeBox& aSB = aVSB.Append1();
+ aSB.SetShape(aF);
+
+ Bnd_Box aBox;
+ if (theBoxes)
+ {
+ const Bnd_Box* pBox = theBoxes->Seek (aF);
+ if (pBox)
+ aBox = *pBox;
+ }
+
+ if (aBox.IsVoid())
+ {
+ // Build the bounding box
+ BRepBndLib::Add(aF, aBox);
+ }
+ aSB.SetBox(aBox);
+ }
+
+ // Prepare UB tree of bounding boxes of the faces to classify
+ // taking the bounding boxes from the just prepared vector
+ BOPCol_BoxBndTree aBBTree;
+ NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
+
+ Standard_Integer aNbF = aVSB.Length();
+ for (Standard_Integer i = 0; i < aNbF; ++i)
+ {
+ aTreeFiller.Add(i, aVSB(i).Box());
+ }
+
+ // Shake tree filler
+ aTreeFiller.Fill();
+
+ // Prepare vector of solids to classify
+ BOPAlgo_VectorOfFillIn3DParts aVFIP;
+
+ BOPCol_ListIteratorOfListOfShape aItLS(theSolids);
+ for (; aItLS.More(); aItLS.Next())
+ {
+ const TopoDS_Solid& aSolid = TopoDS::Solid(aItLS.Value());
+
+ // Build the bounding box for the solid
+ Bnd_Box aBox;
+ if (theBoxes)
+ {
+ const Bnd_Box* pBox = theBoxes->Seek (aSolid);
+ if (pBox)
+ aBox = *pBox;
+ }
+ if (aBox.IsVoid())
+ {
+ buildBoxForSolid (aSolid, aBox);
+ }
+
+ // Append solid to the vector
+ BOPAlgo_FillIn3DParts& aFIP = aVFIP.Append1();
+ aFIP.SetSolid(aSolid);
+ aFIP.SetBoxS(aBox);
+
+ if (theSolidsIF)
+ {
+ const BOPCol_ListOfShape* pLIF = theSolidsIF->Seek(aSolid);
+ if (pLIF)
+ aFIP.SetOwnIF(*pLIF);
+ }
+
+ aFIP.SetBBTree(aBBTree);
+ aFIP.SetShapeBoxVector(aVSB);
+ }
+
+ // Perform classification
+ //================================================================
+ BOPAlgo_FillIn3DPartsCnt::Perform(theRunParallel, aVFIP, theContext);
+ //================================================================
+
+ // Analyze the results and fill the resulting map
+
+ Standard_Integer aNbS = aVFIP.Length();
+ for (Standard_Integer i = 0; i < aNbS; ++i)
+ {
+ BOPAlgo_FillIn3DParts& aFIP = aVFIP(i);
+ const TopoDS_Shape& aS = aFIP.Solid();
+ const BOPCol_ListOfShape& aLFIn = aFIP.InFaces();
+ theInParts.Add(aS, aLFIn);
+ }
+}
#include <BOPCol_BaseAllocator.hxx>
#include <BOPDS_IndexedDataMapOfPaveBlockListOfInteger.hxx>
+#include <BOPCol_DataMapOfShapeListOfShape.hxx>
+#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
+#include <BOPCol_IndexedDataMapOfShapeBox.hxx>
#include <BOPCol_IndexedDataMapOfShapeReal.hxx>
#include <BOPCol_ListOfListOfShape.hxx>
#include <BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock.hxx>
const Standard_Real theFuzzyValue,
BOPCol_ListOfListOfShape& theChains);
+ //! Classifies the faces <theFaces> relatively solids <theSolids>.
+ //! The IN faces for solids are stored into output data map <theInParts>.
+ //!
+ //! The map <theSolidsIF> contains INTERNAL faces of the solids, to avoid
+ //! their additional classification.
+ //!
+ //! Firstly, it checks the intersection of bounding boxes of the shapes.
+ //! If the Box is not stored in the <theShapeBoxMap> map, it builds the box.
+ //! If the bounding boxes of solid and face are interfering the classification is performed.
+ //!
+ //! It is assumed that all faces and solids are already intersected and
+ //! do not have any geometrically coinciding parts without topological
+ //! sharing of these parts
+ Standard_EXPORT static void ClassifyFaces(const BOPCol_ListOfShape& theFaces,
+ const BOPCol_ListOfShape& theSolids,
+ const Standard_Boolean theRunParallel,
+ Handle(IntTools_Context)& theContext,
+ BOPCol_IndexedDataMapOfShapeListOfShape& theInParts,
+ const BOPCol_IndexedDataMapOfShapeBox* theBoxes = 0,
+ const BOPCol_DataMapOfShapeListOfShape* theSolidsIF = 0);
+
};
#endif // _BOPAlgo_Tools_HeaderFile
# Original bug : buc60127
# Date : 18mar98
-puts "TODO #22911 ALL: Faulty shapes in variables faulty_1 to faulty_"
-puts "TODO #22911 ALL: Error : The area of result shape is"
-
restore [locate_data_file buc60127-part.rle] part
restore [locate_data_file buc60127-tool.rle] tool
+# fix the part shape
+
+explode part f
+# fix inner cylinder
+mksurface c_in part_1
+trim c_in c_in
+mkface f_in c_in 0 2*pi 0 150
+
+# fix side faces
+mksurface s1 part_3
+mksurface s2 part_4
+mkface f1 s1 -10 10 -10 10
+mkface f2 s2 -10 10 -10 10
+
+# fix solid
+mkvolume r part_2 f_in f1 f2
+explode r so
+copy r_1 part
+
bcut result part tool
-checkprops result -s 0
-checkview -display result -2d -s -otherwise { part tool } -path ${imagedir}/${test_image}.png
+checkshape result
+checkprops result -s 5382.41 -v 2643.38
+checknbshapes result -wire 14 -face 11 -shell 1 -solid 1
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
bfuse result a b
-checkprops result -s 8636.79
-checkview -display result -2d -otherwise { a b } -s -path ${imagedir}/${test_image}.png
\ No newline at end of file
+checkshape result
+checkprops result -s 8231.06 -v 30472.5
+checknbshapes result -wire 9 -face 9 -shell 1 -solid 1
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
# pro10658
-puts "TODO ALL: Error : The area of result shape is"
restore [locate_data_file CTO900_pro10658a.rle] a
restore [locate_data_file pro10658b.rle] b
bfuse result a b
-checkprops result -s 8231.06
-checkview -display result -2d -otherwise { a b } -s -path ${imagedir}/${test_image}.png
\ No newline at end of file
+checkshape result
+checkprops result -s 8231.06 -v 30472.5
+checknbshapes result -wire 9 -face 9 -shell 1 -solid 1
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
-puts "TODO #22911 ALL: Error : The area of result shape is"
-puts "TODO OCC25735 ALL: Faulty shapes in variables faulty_1 to"
-
restore [locate_data_file a102] a
restore [locate_data_file b136] b
+# fix the second shape
+fixshape b b
+# revert the tolerance
+settolerance b 0.003
+
bop a b
bopfuse result
-checkprops result -s 0
-checkview -display result -2d -otherwise { a b } -s -path ${imagedir}/${test_image}.png
+checkshape result
+checknbshapes result -vertex 16 -edge 28 -wire 13 -face 13 -shell 1 -solid 1
+checkprops result -s 20777.6 -v 173396
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
bsection result object tool
-checkprops result -l 11.8242
+checkprops result -l 16.4762
checksection result
checkview -display result -2d -otherwise { object tool } -l -path ${imagedir}/${test_image}.png
-puts "TODO OCC27014 ALL: Error : result is WRONG because number of .* entities in shape"
-
puts "============"
puts "OCC26619"
puts "============"
bop h0 f0
bopsection result
-checkprops result -l 142.264
-
-set nbshapes_expected "
-Number of shapes in shape
- VERTEX : 46
- EDGE : 46
- WIRE : 0
- FACE : 0
- SHELL : 0
- SOLID : 0
- COMPSOLID : 0
- COMPOUND : 1
- SHAPE : 93
-"
-checknbshapes result -ref ${nbshapes_expected} -t -m "result"
+checkprops result -l 150.232
+
+checknbshapes result -vertex 45 -edge 45 -t -m "result"
regexp {Tolerance +MAX=([-0-9.+eE]+)} [tolerance h0] full MaxTolerance2
checkreal "MaxTolerance" ${MaxTolerance2} ${expected_MaxTolerance} ${tol_abs_MaxTolerance} ${tol_rel_MaxTolerance}
checkview -display result -2d -path ${imagedir}/${test_image}.png
+
+if {[regexp "alone_1" [checksection result]]} {
+ puts "Error: the section is not closed"
+}
\ No newline at end of file
puts "TODO 0026789 ALL: Error : The area of result shape is"
puts "TODO 0026789 ALL: Error : The volume of result shape is"
-puts "TODO 0026789 ALL: Error : is WRONG because number of SOLID entities in shape"
-puts "TODO 0026789 ALL: Error : is WRONG because number of SHELL entities in shape"
-puts "TODO 0026789 ALL: Faulty shapes in variables faulty_"
+puts "TODO 0026789 ALL: Error : is WRONG because number of"
puts "========"
puts "OCC26789"
+++ /dev/null
-puts "TODO OCC25983 ALL: Faulty shapes in variables faulty_1 to faulty_"
-
-puts "========"
-puts "OCC25983"
-puts "========"
-puts ""
-##########################################
-# Fusion of sweep and its mirror invalid
-##########################################
-
-restore [locate_data_file bug25983_deform-fusion1-tcl-BSpline.brep] BSpline
-wire Knurling-0-spine BSpline
-mksweep Knurling-0-spine
-setsweep -FR
-polyline DWire 0 0 0 1 -0.9999999999999998 0 1.0000000000000002 0.9999999999999998 0 0 0 0
-trotate DWire 0 0 0 1 0 0 134.99999999999693
-ttranslate DWire 9 0 0
-addsweep DWire
-buildsweep Knurling -C -S
-copy Knurling Clone
-tmirror Clone 0 0 0 1 0 0
-bfuse result Knurling Clone
-
-checkshape result
--- /dev/null
+puts "TODO OCC25983 ALL: Error : is WRONG because number of"
+puts "TODO OCC25983 ALL: Error : The area of result shape is"
+puts "TODO OCC25983 ALL: Error : The volume of result shape is"
+
+puts "========"
+puts "OCC25983"
+puts "========"
+puts ""
+##########################################
+# Fusion of sweep and its mirror invalid
+##########################################
+
+restore [locate_data_file bug25983_deform-fusion1-tcl-BSpline.brep] BSpline
+wire Knurling-0-spine BSpline
+mksweep Knurling-0-spine
+setsweep -FR
+polyline DWire 0 0 0 1 -0.9999999999999998 0 1.0000000000000002 0.9999999999999998 0 0 0 0
+trotate DWire 0 0 0 1 0 0 134.99999999999693
+ttranslate DWire 9 0 0
+addsweep DWire
+buildsweep Knurling -C -S
+copy Knurling Clone
+tmirror Clone 0 0 0 1 0 0
+bfuse result Knurling Clone
+
+checkshape result
+checknbshapes result -wire 24 -face 24 -shell 1 -solid 1
+checkprops result -s 262.476 -v 54.0383
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
--- /dev/null
+puts "========"
+puts "OCC25983"
+puts "========"
+puts ""
+##########################################
+# Fusion of sweep and its mirror invalid
+##########################################
+
+restore [locate_data_file bug25983_deform-fusion1-tcl-BSpline.brep] BSpline
+wire Knurling-0-spine BSpline
+mksweep Knurling-0-spine
+setsweep -FR
+polyline DWire 0 0 0 1 -0.9999999999999998 0 1.0000000000000002 0.9999999999999998 0 0 0 0
+trotate DWire 0 0 0 1 0 0 134.99999999999693
+ttranslate DWire 9 0 0
+addsweep DWire
+buildsweep Knurling -C -S
+copy Knurling Clone
+tmirror Clone 0 0 0 1 0 0
+
+bfuzzyvalue 1.e-3
+bfuse result Knurling Clone
+
+checkshape result
+checknbshapes result -wire 24 -face 24 -shell 1 -solid 1
+checkprops result -s 262.476 -v 54.0383
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
bop h0 f0
bopsection result
-checkprops result -l 142.264
+checkprops result -l 150.23
set nbshapes_expected "
Number of shapes in shape
--- /dev/null
+puts "============================================================================================="
+puts "0031662: Modeling Algorithms - Incomplete result of section operation"
+puts "============================================================================================="
+puts ""
+
+restore [locate_data_file bug31662_Surface_0.brep] s0
+restore [locate_data_file bug31662_Surface_1.brep] s1
+
+bclearobjects
+bcleartools
+baddobjects s0
+baddtools s1
+bfillds
+
+bbop r4 4
+
+checkshape r4
+checksection r4 -r 0
+checkprops r4 -l 70.3856
+
+bbuild rgf
+
+checkshape rgf
+checknbshapes rgf -wire 363 -face 363 -shell 2 -solid 0
+
+mkvolume result rgf -ni
+
+checkshape result
+checknbshapes result -wire 254 -face 254 -shell 1 -solid 1
+checkprops result -s 668.352 -v 774.749
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
-puts "TODO OCC22033 ALL: Faulty shapes in variables faulty_1 to faulty_"
+#puts "TODO OCC22033 ALL: Faulty shapes in variables faulty_1 to faulty_"
if { [regexp {Debug mode} [dversion]] } {
puts "TODO OCC22033 ALL: TEST INCOMPLETE"
puts "TODO OCC22033 ALL: Exception"
-puts "TODO CR25432 ALL: Error : The area of result shape is"
-
puts "================"
puts "OCC26"
puts "================"
bfuse result a_2 a_1
-checkprops result -s 41539.9
+checkprops result -s 41539.9 -v 348665
+checknbshapes result -wire 44 -face 41 -shell 1 -solid 1
checkview -display result -2d -path ${imagedir}/${test_image}.png