From: emv Date: Thu, 18 Apr 2019 12:34:37 +0000 (+0300) Subject: 0030656: Modeling Algorithms - Change Boolean Operations algorithm to use BVH tree... X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=06b59f24f44c7b7b9810a272c005d3f88e855d13;p=occt-copy.git 0030656: Modeling Algorithms - Change Boolean Operations algorithm to use BVH tree instead of UBTree Switching the Boolean Operations algorithm to use the BVH tree instead of UB tree as selection of the elements from BVH tree is usually faster. --- diff --git a/samples/tcl/ANC101.tcl b/samples/tcl/ANC101.tcl index 9944fe7d2c..9873f50409 100644 --- a/samples/tcl/ANC101.tcl +++ b/samples/tcl/ANC101.tcl @@ -264,11 +264,11 @@ bfuse _model _model t_s explode _model e # Make a weld at joint edges of platform and wedge -blend _model _model 2 _model_26 blend _model _model 2 _model_27 blend _model _model 2 _model_28 blend _model _model 2 _model_29 -blend _model _model 2 _model_31 +blend _model _model 2 _model_30 +blend _model _model 2 _model_32 # Cylinder on wedge blend result _model 2 _model_161 diff --git a/src/BOPAlgo/BOPAlgo_BuilderFace.cxx b/src/BOPAlgo/BOPAlgo_BuilderFace.cxx index 2caa3ff564..43078d15d0 100644 --- a/src/BOPAlgo/BOPAlgo_BuilderFace.cxx +++ b/src/BOPAlgo/BOPAlgo_BuilderFace.cxx @@ -24,7 +24,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -38,8 +39,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -443,32 +443,33 @@ void BOPAlgo_BuilderFace::PerformAreas() { // No holes, stop the analysis myAreas.Append(aNewFaces); + return; } // Classify holes relatively faces // Prepare tree filler with the boxes of the hole faces - NCollection_UBTree aBBTree; - NCollection_UBTreeFiller aTreeFiller(aBBTree); - + Handle(BOPTools_Box2dTree) aBoxTree = new BOPTools_Box2dTree(); Standard_Integer i, aNbH = aHoleFaces.Extent(); + aBoxTree->SetSize (aNbH); for (i = 1; i <= aNbH; ++i) { const TopoDS_Face& aHFace = TopoDS::Face(aHoleFaces(i)); // Bnd_Box2d aBox; BRepTools::AddUVBounds(aHFace, aBox); - aTreeFiller.Add(i, aBox); + aBoxTree->Add(i, Bnd_Tools::Bnd2BVH (aBox)); } - // Shake TreeFiller - aTreeFiller.Fill(); + // Build BVH + aBoxTree->Build(); // Find outer growth face that is most close to each hole face TopTools_IndexedDataMapOfShapeShape aHoleFaceMap; // Selector - BOPTools_BoxSelector aSelector; + BOPTools_Box2dTreeSelector aSelector; + aSelector.SetBVHSet (aBoxTree.get()); TopTools_ListIteratorOfListOfShape aItLS(aNewFaces); for (; aItLS.More(); aItLS.Next()) @@ -480,8 +481,8 @@ void BOPAlgo_BuilderFace::PerformAreas() BRepTools::AddUVBounds(aFace, aBox); aSelector.Clear(); - aSelector.SetBox(aBox); - aBBTree.Select(aSelector); + aSelector.SetBox(Bnd_Tools::Bnd2BVH (aBox)); + aSelector.Select(); const TColStd_ListOfInteger& aLI = aSelector.Indices(); TColStd_ListIteratorOfListOfInteger aItLI(aLI); diff --git a/src/BOPAlgo/BOPAlgo_BuilderSolid.cxx b/src/BOPAlgo/BOPAlgo_BuilderSolid.cxx index bcff591cd7..2fe16d3acd 100644 --- a/src/BOPAlgo/BOPAlgo_BuilderSolid.cxx +++ b/src/BOPAlgo/BOPAlgo_BuilderSolid.cxx @@ -21,9 +21,10 @@ #include #include #include -#include +#include #include #include +#include #include #include #include @@ -39,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -444,23 +444,22 @@ void BOPAlgo_BuilderSolid::PerformAreas() // Classify holes relatively solids // Prepare tree filler with the boxes of the hole shells - BOPTools_BoxBndTree aBBTree; - NCollection_UBTreeFiller aTreeFiller(aBBTree); - + Handle(BOPTools_BoxTree) aBBTree = new BOPTools_BoxTree(); Standard_Integer i, aNbH = aHoleShells.Extent(); + aBBTree->SetSize (aNbH); for (i = 1; i <= aNbH; ++i) { const TopoDS_Shape& aHShell = aHoleShells(i); // Bnd_Box aBox; BRepBndLib::Add(aHShell, aBox); - aTreeFiller.Add(i, aBox); + aBBTree->Add(i, Bnd_Tools::Bnd2BVH(aBox)); myBoxes.Bind(aHShell, aBox); } // Shake TreeFiller - aTreeFiller.Fill(); + aBBTree->Build(); // Find outer growth shell that is most close to each hole shell TopTools_IndexedDataMapOfShapeShape aHoleSolidMap; @@ -476,9 +475,10 @@ void BOPAlgo_BuilderSolid::PerformAreas() myBoxes.Bind(aSolid, aBox); - BOPTools_BoxBndTreeSelector aSelector; - aSelector.SetBox(aBox); - aBBTree.Select(aSelector); + BOPTools_BoxTreeSelector aSelector; + aSelector.SetBox(Bnd_Tools::Bnd2BVH(aBox)); + aSelector.SetBVHSet (aBBTree.get()); + aSelector.Select(); const TColStd_ListOfInteger& aLI = aSelector.Indices(); TColStd_ListIteratorOfListOfInteger aItLI(aLI); diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller.cxx index 3572a73eab..9d032c157a 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller.cxx @@ -284,7 +284,7 @@ void BOPAlgo_PaveFiller::PerformInternal() // MakeSplitEdges(); if (HasErrors()) { - return; + return; } // UpdatePaveBlocksWithSDVertices(); diff --git a/src/BOPAlgo/BOPAlgo_Tools.cxx b/src/BOPAlgo/BOPAlgo_Tools.cxx index ac65629892..b7b0918218 100644 --- a/src/BOPAlgo/BOPAlgo_Tools.cxx +++ b/src/BOPAlgo/BOPAlgo_Tools.cxx @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -45,7 +46,6 @@ #include #include #include -#include #include #include #include @@ -957,14 +957,14 @@ typedef BOPTools_Cnt BOPAlgo_TNVCnt; //======================================================================= -class BOPAlgo_TNV : public BOPTools_BoxBndTreeSelector{ +class BOPAlgo_TNV : public BOPTools_BoxTreeSelector{ public: BOPAlgo_TNV() - : BOPTools_BoxBndTreeSelector(), - myTol (0.), myFuzzyValue(0.), myTree(NULL), myVecTNV(NULL) { + : BOPTools_BoxTreeSelector(), + myTol (0.), myFuzzyValue(0.), myVecTNV(NULL) { }; // - ~BOPAlgo_TNV(){ + virtual ~BOPAlgo_TNV(){ }; // void SetVertex(const TopoDS_Vertex& aV) { @@ -976,10 +976,6 @@ class BOPAlgo_TNV : public BOPTools_BoxBndTreeSelector{ return myV; } // - void SetTree(BOPTools_BoxBndTree& aTree) { - myTree=&aTree; - } - // void SetTolerance(const Standard_Real theTol) { myTol = theTol; } @@ -1000,19 +996,24 @@ class BOPAlgo_TNV : public BOPTools_BoxBndTreeSelector{ myVecTNV = &theVec; } // - virtual Standard_Boolean Accept(const Standard_Integer& theIndex) + virtual Standard_Boolean Accept(const Standard_Integer theIndex, + const Standard_Boolean& theIsInside) override { - const BOPAlgo_TNV& aTNV = myVecTNV->Value(theIndex - 1); - Standard_Real aTolSum2 = myTol + aTNV.Tolerance() + myFuzzyValue; - aTolSum2 *= aTolSum2; - Standard_Real aD2 = myPnt.SquareDistance(aTNV.Pnt()); - if (aD2 < aTolSum2) - return BOPTools_BoxBndTreeSelector::Accept(theIndex); + if (theIsInside || !RejectElement (theIndex)) + { + const Standard_Integer anInd = myBVHSet->Element (theIndex); + const BOPAlgo_TNV& aTNV = myVecTNV->Value(anInd - 1); + Standard_Real aTolSum2 = myTol + aTNV.Tolerance() + myFuzzyValue; + aTolSum2 *= aTolSum2; + Standard_Real aD2 = myPnt.SquareDistance(aTNV.Pnt()); + if (aD2 < aTolSum2) + return BOPTools_BoxTreeSelector::Accept(theIndex, Standard_True); + } return Standard_False; } // void Perform() { - myTree->Select(*this); + Select(); } // protected: @@ -1020,7 +1021,6 @@ class BOPAlgo_TNV : public BOPTools_BoxBndTreeSelector{ Standard_Real myFuzzyValue; gp_Pnt myPnt; TopoDS_Vertex myV; - BOPTools_BoxBndTree *myTree; const BOPAlgo_VectorOfTNV *myVecTNV; }; // @@ -1044,9 +1044,8 @@ void BOPAlgo_Tools::IntersectVertices(const TopTools_IndexedDataMapOfShapeReal& } // // Use unbalanced binary tree of bounding boxes for sorting of the vertices. - BOPTools_BoxBndTree aBBTree; - NCollection_UBTreeFiller aTreeFiller(aBBTree); + Handle(BOPTools_BoxTree) aBBTree = new BOPTools_BoxTree(); + aBBTree->SetSize (aNbV); // Perform intersection of the vertices BOPAlgo_VectorOfTNV aVTNV; // @@ -1064,18 +1063,18 @@ void BOPAlgo_Tools::IntersectVertices(const TopTools_IndexedDataMapOfShapeReal& aBox.Add(BRep_Tool::Pnt(aV)); aBox.SetGap(aTol + aTolAdd); // - aTreeFiller.Add(i, aBox); + aBBTree->Add(i, Bnd_Tools::Bnd2BVH(aBox)); // BOPAlgo_TNV& aTNV=aVTNV.Appended(); - aTNV.SetTree(aBBTree); - aTNV.SetBox(aBox); + aTNV.SetBVHSet (aBBTree.get()); + aTNV.SetBox(Bnd_Tools::Bnd2BVH(aBox)); aTNV.SetVertex(aV); aTNV.SetTolerance(aTol); aTNV.SetFuzzyValue(theFuzzyValue); aTNV.SetVectorOfTNV(aVTNV); } // Shake the tree - aTreeFiller.Fill(); + aBBTree->Build(); // // Perform intersection BOPAlgo_TNVCnt::Perform(theRunParallel, aVTNV); @@ -1232,9 +1231,9 @@ public: }; //! Sets the Bounding Box tree - void SetBBTree(const BOPTools_BoxBndTree& theBBTree) + void SetBBTree(const Handle(BOPTools_BoxTree)& theBBTree) { - myBBTree = (BOPTools_BoxBndTree*)&theBBTree; + myBBTree = theBBTree; }; //! Sets the ShapeBox structure @@ -1284,7 +1283,7 @@ private: TopTools_ListOfShape myOwnIF; //! Own INTERNAL faces of the solid TopTools_ListOfShape myInFaces; //! Faces classified as IN - BOPTools_BoxBndTree* myBBTree; //! UB tree of bounding boxes + Handle(BOPTools_BoxTree) myBBTree; //! UB tree of bounding boxes BOPAlgo_VectorOfShapeBox* myVShapeBox; //! ShapeBoxMap TopoDS_Iterator myItF; //! Iterators @@ -1304,10 +1303,11 @@ void BOPAlgo_FillIn3DParts::Perform() myInFaces.Clear(); // 1. Select boxes of faces that are not out of aBoxS - BOPTools_BoxBndTreeSelector aSelector; - aSelector.SetBox(myBoxS); + BOPTools_BoxTreeSelector aSelector; + aSelector.SetBox(Bnd_Tools::Bnd2BVH(myBoxS)); + aSelector.SetBVHSet (myBBTree.get()); // - if (!myBBTree->Select(aSelector)) + if (!aSelector.Select()) return; const TColStd_ListOfInteger& aLIFP = aSelector.Indices(); @@ -1567,17 +1567,16 @@ void BOPAlgo_Tools::ClassifyFaces(const TopTools_ListOfShape& theFaces, // Prepare UB tree of bounding boxes of the faces to classify // taking the bounding boxes from the just prepared vector - BOPTools_BoxBndTree aBBTree; - NCollection_UBTreeFiller aTreeFiller(aBBTree); + Handle(BOPTools_BoxTree) aBBTree = new BOPTools_BoxTree(); Standard_Integer aNbF = aVSB.Length(); for (Standard_Integer i = 0; i < aNbF; ++i) { - aTreeFiller.Add(i, aVSB(i).Box()); + aBBTree->Add(i, Bnd_Tools::Bnd2BVH(aVSB(i).Box())); } // Shake tree filler - aTreeFiller.Fill(); + aBBTree->Build(); // Prepare vector of solids to classify BOPAlgo_VectorOfFillIn3DParts aVFIP; diff --git a/src/BOPDS/BOPDS_Iterator.cxx b/src/BOPDS/BOPDS_Iterator.cxx index 7a196c1ae4..d0a25d0d8d 100644 --- a/src/BOPDS/BOPDS_Iterator.cxx +++ b/src/BOPDS/BOPDS_Iterator.cxx @@ -18,62 +18,20 @@ #include #include +#include #include #include #include #include #include #include -#include +#include #include #include -#include #include #include #include -///////////////////////////////////////////////////////////////////////// -//======================================================================= -//class : BOPDS_TreeSelector -//purpose : -//======================================================================= -class BOPDS_TSR : public BOPTools_BoxBndTreeSelector{ - public: - BOPDS_TSR() : - BOPTools_BoxBndTreeSelector(), - myHasBRep(Standard_False), - myTree(NULL) { - } - // - virtual ~BOPDS_TSR() { - } - // - void SetHasBRep(const Standard_Boolean bFlag) { - myHasBRep=bFlag; - } - // - void SetTree(BOPTools_BoxBndTree& aTree) { - myTree=&aTree; - } - // - void Perform() { - if (myHasBRep) { - myTree->Select(*this); - } - } - // - protected: - Standard_Boolean myHasBRep; - BOPTools_BoxBndTree *myTree; -}; -// -//======================================================================= -typedef NCollection_Vector BOPDS_VectorOfTSR; -typedef BOPTools_Functor BOPDS_TSRFunctor; -typedef BOPTools_Cnt BOPDS_TSRCnt; -///////////////////////////////////////////////////////////////////////// - - //======================================================================= //function : //purpose : @@ -268,101 +226,80 @@ void BOPDS_Iterator::Intersect(const Handle(IntTools_Context)& theCtx, const Standard_Boolean theCheckOBB, const Standard_Real theFuzzyValue) { - Standard_Integer i, j, iX, i1, i2, iR, aNb, aNbR; - Standard_Integer iTi, iTj; - TopAbs_ShapeEnum aTi, aTj; - // - BOPTools_BoxBndTree aBBTree; - NCollection_UBTreeFiller aTreeFiller(aBBTree); - // - aNb = myDS->NbSourceShapes(); - BOPDS_VectorOfTSR aVTSR(aNb); - // - for (i=0; iShapeInfo(i); - Standard_Boolean bHasBrep = aSI.IsInterfering() && !(aSI.ShapeType() == TopAbs_SOLID); - // - BOPDS_TSR& aTSR=aVTSR.Appended(); - // - aTSR.SetHasBRep(bHasBrep); - if (!bHasBrep) { + const Standard_Integer aNb = myDS->NbSourceShapes(); + + // Prepare BVH + Handle(BOPTools_BoxTree) aBoxTree = new BOPTools_BoxTree(); + aBoxTree->SetSize (aNb); + for (Standard_Integer i = 0; i < aNb; ++i) + { + const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); + if (!aSI.HasBRep()) continue; - } - // - const Bnd_Box& aBoxEx=aSI.Box(); - aTSR.SetTree(aBBTree); - aTSR.SetBox(aBoxEx); - // - aTreeFiller.Add(i, aBoxEx); + const Bnd_Box& aBox = aSI.Box(); + aBoxTree->Add (i, Bnd_Tools::Bnd2BVH (aBox)); } - // - aTreeFiller.Fill(); - // - //=========================================== - BOPDS_TSRCnt::Perform(myRunParallel, aVTSR); - //=========================================== - // - BOPDS_MapOfPair aMPFence; - // - aNbR = myDS->NbRanges() - 1; - for (iR = 0; iR < aNbR; ++iR) { - const BOPDS_IndexRange& aR = myDS->Range(iR); - i1 = aR.First(); - i2 = aR.Last(); - for (i = i1; i <= i2; ++i) { - const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); - // - if (!aSI.IsInterfering() || (aSI.ShapeType() == TopAbs_SOLID)) { + + // Build BVH + aBoxTree->Build(); + + // Select pairs of shapes with interfering bounding boxes + BOPTools_BoxPairSelector aPairSelector; + aPairSelector.SetBVHSets (aBoxTree.get(), aBoxTree.get()); + aPairSelector.SetSame (Standard_True); + aPairSelector.Select(); + aPairSelector.Sort(); + + // Treat the selected pairs + const std::vector& aPairs = aPairSelector.Pairs(); + const Standard_Integer aNbPairs = static_cast (aPairs.size()); + + Standard_Integer iPair = 0; + + const Standard_Integer aNbR = myDS->NbRanges(); + for (Standard_Integer iR = 0; iR < aNbR; ++iR) + { + const BOPDS_IndexRange& aRange = myDS->Range(iR); + + for (; iPair < aNbPairs; ++iPair) + { + const BOPTools_BoxPairSelector::PairIDs& aPair = aPairs[iPair]; + if (!aRange.Contains (aPair.ID1)) + // Go to the next range + break; + + if (aRange.Contains (aPair.ID2)) + // Go to the next pair continue; - } - // - BOPDS_TSR& aTSRi = aVTSR(i); - const TColStd_ListOfInteger& aLI = aTSRi.Indices(); - Standard_Integer aNbSD = aLI.Extent(); - if (!aNbSD) { + + const BOPDS_ShapeInfo& aSI1 = myDS->ShapeInfo (aPair.ID1); + const BOPDS_ShapeInfo& aSI2 = myDS->ShapeInfo (aPair.ID2); + + const TopAbs_ShapeEnum aType1 = aSI1.ShapeType(); + const TopAbs_ShapeEnum aType2 = aSI2.ShapeType(); + + Standard_Integer iType1 = BOPDS_Tools::TypeToInteger (aType1); + Standard_Integer iType2 = BOPDS_Tools::TypeToInteger (aType2); + + // avoid interfering of the same shapes and shape with its sub-shapes + if (((iType1 < iType2) && aSI1.HasSubShape (aPair.ID2)) || + ((iType1 > iType2) && aSI2.HasSubShape (aPair.ID1))) continue; - } - // - aTi = aSI.ShapeType(); - iTi = BOPDS_Tools::TypeToInteger(aTi); - // - TColStd_ListIteratorOfListOfInteger aIt(aLI); - for (; aIt.More(); aIt.Next()) { - j = aIt.Value(); // DS index - if (j >= i1 && j <= i2) { - continue;// same range - } - // - const BOPDS_ShapeInfo& aSJ = myDS->ShapeInfo(j); - aTj = aSJ.ShapeType(); - iTj = BOPDS_Tools::TypeToInteger(aTj); - // - // avoid interfering of the same shapes and shape with its sub-shapes - if (((iTi < iTj) && aSI.HasSubShape(j)) || - ((iTi > iTj) && aSJ.HasSubShape(i))) { - continue; - } - // - BOPDS_Pair aPair(i, j); - if (aMPFence.Add(aPair)) { - if (theCheckOBB) - { - // Check intersection of Oriented bounding boxes of the shapes - Bnd_OBB& anOBBi = theCtx->OBB(aSI.Shape(), theFuzzyValue); - Bnd_OBB& anOBBj = theCtx->OBB(aSJ.Shape(), theFuzzyValue); - if (anOBBi.IsOut(anOBBj)) - continue; - } + if (theCheckOBB) + { + // Check intersection of Oriented bounding boxes of the shapes + Bnd_OBB& anOBB1 = theCtx->OBB (aSI1.Shape(), theFuzzyValue); + Bnd_OBB& anOBB2 = theCtx->OBB (aSI2.Shape(), theFuzzyValue); - iX = BOPDS_Tools::TypeToInteger(aTi, aTj); - myLists(iX).Append(aPair); - }// if (aMPFence.Add(aPair)) { - }// for (; aIt.More(); aIt.Next()) { - }//for (i=i1; i<=i2; ++i) { - }//for (iR=1; iR #include +#include #include #include #include @@ -21,11 +22,10 @@ #include #include #include -#include +#include #include #include #include -#include #include #include #include @@ -87,11 +87,9 @@ void BOPDS_IteratorSI::Intersect(const Handle(IntTools_Context)& theCtx, Standard_Integer iTi, iTj; TopAbs_ShapeEnum aTi, aTj; // - BOPTools_BoxBndTreeSelector aSelector; - BOPTools_BoxBndTree aBBTree; - NCollection_UBTreeFiller aTreeFiller(aBBTree); - // + Handle(BOPTools_BoxTree) aBBTree = new BOPTools_BoxTree(); aNbS = myDS->NbSourceShapes(); + aBBTree->SetSize (aNbS); for (i=0; iShapeInfo(i); if (!aSI.IsInterfering()) { @@ -99,10 +97,10 @@ void BOPDS_IteratorSI::Intersect(const Handle(IntTools_Context)& theCtx, } // const Bnd_Box& aBoxEx = aSI.Box(); - aTreeFiller.Add(i, aBoxEx); + aBBTree->Add(i, Bnd_Tools::Bnd2BVH(aBoxEx)); } // - aTreeFiller.Fill(); + aBBTree->Build(); // BOPDS_MapOfPair aMPFence; // @@ -114,10 +112,11 @@ void BOPDS_IteratorSI::Intersect(const Handle(IntTools_Context)& theCtx, // const Bnd_Box& aBoxEx = aSI.Box(); // - aSelector.Clear(); - aSelector.SetBox(aBoxEx); + BOPTools_BoxTreeSelector aSelector; + aSelector.SetBox (Bnd_Tools::Bnd2BVH (aBoxEx)); + aSelector.SetBVHSet (aBBTree.get()); // - Standard_Integer aNbSD = aBBTree.Select(aSelector); + Standard_Integer aNbSD = aSelector.Select(); if (!aNbSD) { continue; } diff --git a/src/BOPDS/BOPDS_ShapeInfo.lxx b/src/BOPDS/BOPDS_ShapeInfo.lxx index f528d35ac1..3acaa2b6e2 100644 --- a/src/BOPDS/BOPDS_ShapeInfo.lxx +++ b/src/BOPDS/BOPDS_ShapeInfo.lxx @@ -126,18 +126,7 @@ inline TColStd_ListOfInteger& BOPDS_ShapeInfo::ChangeSubShapes() inline Standard_Boolean BOPDS_ShapeInfo::HasSubShape (const Standard_Integer theI)const { - Standard_Boolean bRet; - TColStd_ListIteratorOfListOfInteger aIt; - // - bRet=Standard_False; - aIt.Initialize(mySubShapes); - for (; aIt.More(); aIt.Next()) { - bRet=(theI==aIt.Value()); - if (bRet) { - return bRet; - } - } - return bRet; + return mySubShapes.Contains (theI); } //======================================================================= //function : HasReference diff --git a/src/BOPDS/BOPDS_SubIterator.cxx b/src/BOPDS/BOPDS_SubIterator.cxx index 18ec0e5d2e..58f900d86e 100644 --- a/src/BOPDS/BOPDS_SubIterator.cxx +++ b/src/BOPDS/BOPDS_SubIterator.cxx @@ -16,14 +16,13 @@ #include #include +#include #include #include #include -#include - -#include +#include #include @@ -118,9 +117,9 @@ void BOPDS_SubIterator::Initialize() void BOPDS_SubIterator::Intersect() { Standard_Integer i, j, iTi, iTj; - BOPTools_BoxBndTree aBBTree; - NCollection_UBTreeFiller aTreeFiller(aBBTree); - // + Handle(BOPTools_BoxTree) aBBTree = new BOPTools_BoxTree(); + aBBTree->SetSize (mySubSet1->Extent()); + TColStd_ListIteratorOfListOfInteger aIt(*mySubSet1); for (; aIt.More(); aIt.Next()) { i = aIt.Value(); @@ -128,10 +127,10 @@ void BOPDS_SubIterator::Initialize() const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); const Bnd_Box& aBoxEx = aSI.Box(); // - aTreeFiller.Add(i, aBoxEx); + aBBTree->Add(i, Bnd_Tools::Bnd2BVH (aBoxEx)); } // - aTreeFiller.Fill(); + aBBTree->Build(); // BOPDS_MapOfPair aMPKFence; // @@ -142,9 +141,10 @@ void BOPDS_SubIterator::Initialize() const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); const Bnd_Box& aBoxEx = aSI.Box(); // - BOPTools_BoxBndTreeSelector aSelector; - aSelector.SetBox(aBoxEx); - Standard_Integer aNbSD = aBBTree.Select(aSelector); + BOPTools_BoxTreeSelector aSelector; + aSelector.SetBox(Bnd_Tools::Bnd2BVH(aBoxEx)); + aSelector.SetBVHSet (aBBTree.get()); + Standard_Integer aNbSD = aSelector.Select(); if (!aNbSD) { continue; } diff --git a/src/BOPTools/BOPTools_BoxBndTree.hxx b/src/BOPTools/BOPTools_BoxBndTree.hxx deleted file mode 100644 index 419ab6a11b..0000000000 --- a/src/BOPTools/BOPTools_BoxBndTree.hxx +++ /dev/null @@ -1,26 +0,0 @@ -// Created by: Eugeny MALTCHIKOV -// Copyright (c) 2017 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef BOPTools_BoxBndTree_HeaderFile -#define BOPTools_BoxBndTree_HeaderFile - -#include -#include -#include -#include - -typedef NCollection_UBTree BOPTools_BoxBndTree; -typedef BOPTools_BoxSelector BOPTools_BoxBndTreeSelector; - -#endif diff --git a/src/BOPTools/BOPTools_BoxSelector.hxx b/src/BOPTools/BOPTools_BoxSelector.hxx index e8bf2683f4..d779200a37 100644 --- a/src/BOPTools/BOPTools_BoxSelector.hxx +++ b/src/BOPTools/BOPTools_BoxSelector.hxx @@ -15,32 +15,27 @@ #ifndef BOPTools_BoxSelector_HeaderFile #define BOPTools_BoxSelector_HeaderFile -#include -#include +#include +#include + #include +#include -//! Template Selector for the unbalanced binary tree -//! of overlapped bounding boxes. -template class BOPTools_BoxSelector : - public NCollection_UBTree::Selector +//! Template Selector for elements selection from BVH tree. +template +class BOPTools_BoxSelector : + public BVH_Traverse , Standard_Boolean> { public: + typedef typename BVH::VectorType::Type BVH_VecNd; + +public: //! @name Constructor + //! Empty constructor BOPTools_BoxSelector() {}; - //! Checks if the box should be rejected - virtual Standard_Boolean Reject(const BoxType& theOther) const - { - return myBox.IsOut(theOther); - } - - //! Accepts the index - virtual Standard_Boolean Accept(const Standard_Integer& theIndex) - { - myIndices.Append(theIndex); - return Standard_True; - } +public: //! @name public interfaces //! Clears the indices void Clear() @@ -49,7 +44,7 @@ public: } //! Sets the box - void SetBox(const BoxType& theBox) + void SetBox (const BVH_Box & theBox) { myBox = theBox; } @@ -60,11 +55,46 @@ public: return myIndices; } -private: +public: //! @name Rejection/Acceptance rules + + //! Checks if the box should be rejected + virtual Standard_Boolean RejectNode (const BVH_VecNd& theCMin, + const BVH_VecNd& theCMax, + Standard_Boolean& theIsInside) const Standard_OVERRIDE + { + Standard_Boolean hasOverlap; + theIsInside = myBox.Contains (theCMin, theCMax, hasOverlap); + return !hasOverlap; + } + + //! Rejects the element by the index + Standard_Boolean RejectElement (const Standard_Integer theIndex) + { + return myBox.IsOut (this->myBVHSet->Box (theIndex)); + } + + //! Accepts the index + virtual Standard_Boolean AcceptMetric (const Standard_Boolean& theIsInside) const Standard_OVERRIDE + { + return theIsInside; + } + + //! Accepts the index + virtual Standard_Boolean Accept (const Standard_Integer theIndex, + const Standard_Boolean& theIsInside) Standard_OVERRIDE + { + if (theIsInside || !RejectElement (theIndex)) + { + myIndices.Append (this->myBVHSet->Element (theIndex)); + return Standard_True; + } + return Standard_False; + } - BoxType myBox; - TColStd_ListOfInteger myIndices; +protected: //! @name Fields + BVH_Box myBox; //!< Selection box + TColStd_ListOfInteger myIndices; //!< Selected indices }; #endif diff --git a/src/BOPTools/BOPTools_BoxTree.hxx b/src/BOPTools/BOPTools_BoxTree.hxx new file mode 100644 index 0000000000..7477139f3b --- /dev/null +++ b/src/BOPTools/BOPTools_BoxTree.hxx @@ -0,0 +1,47 @@ +// Created by: Eugeny MALTCHIKOV +// Copyright (c) 2017 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef BOPTools_BoxTree_HeaderFile +#define BOPTools_BoxTree_HeaderFile + +#include +#include +#include +#include +#include +#include + +//! Redefines BoxSet to use the Linear builder by default + +template +class BOPTools_BoxSet : public BVH_BoxSet +{ +public: //! @name Constructors + //! Empty constructor for use the default BVH_Builder + BOPTools_BoxSet (const opencascade::handle >& theBuilder = NULL) + : BVH_BoxSet (theBuilder.IsNull() ? new BVH_LinearBuilder() : theBuilder) + {} +}; + +//! 2D definitions +typedef BOPTools_BoxSet BOPTools_Box2dTree; +typedef BOPTools_BoxSelector<2> BOPTools_Box2dTreeSelector; +typedef BOPTools_PairSelector<2> BOPTools_Box2dPairSelector; + +//! 3D definitions +typedef BOPTools_BoxSet BOPTools_BoxTree; +typedef BOPTools_BoxSelector<3> BOPTools_BoxTreeSelector; +typedef BOPTools_PairSelector<3> BOPTools_BoxPairSelector; + +#endif diff --git a/src/BOPTools/BOPTools_PairSelector.hxx b/src/BOPTools/BOPTools_PairSelector.hxx new file mode 100644 index 0000000000..3da7451ed2 --- /dev/null +++ b/src/BOPTools/BOPTools_PairSelector.hxx @@ -0,0 +1,125 @@ +// Created by: Eugeny MALTCHIKOV +// Copyright (c) 2017 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef BOPTools_PairSelector_HeaderFile +#define BOPTools_PairSelector_HeaderFile + +#include +#include + +#include +#include +#include + +//! Template Selector for elements selection from BVH tree. +template +class BOPTools_PairSelector : + public BVH_PairTraverse > +{ +public: //! @name public types + + //! Auxiliary structure to keep the pair of indices + struct PairIDs + { + PairIDs (const Standard_Integer theId1 = -1, + const Standard_Integer theId2 = -1) + : ID1 (theId1), ID2 (theId2) + {} + + Standard_Boolean operator< (const PairIDs& theOther) const + { + return ID1 < theOther.ID1 || + (ID1 == theOther.ID1 && ID2 < theOther.ID2); + } + + Standard_Integer ID1; + Standard_Integer ID2; + }; + + typedef typename BVH::VectorType::Type BVH_VecNd; + +public: //! @name Constructor + + //! Empty constructor + BOPTools_PairSelector() + : mySameBVHs (Standard_False) + {} + +public: //! @name public interfaces + + //! Clears the indices + void Clear() + { + myPairs.Clear(); + } + + //! Sorts the indices + void Sort() + { + std::sort (myPairs.begin(), myPairs.end()); + } + + //! Tells to selector that BVH trees are the same + void SetSame (const Standard_Boolean theIsSame) + { + mySameBVHs = theIsSame; + } + + //! Returns the list of accepted indices + const std::vector& Pairs() const + { + return myPairs; + } + +public: //! @name Rejection/Acceptance rules + + //! Checks if the box should be rejected + virtual Standard_Boolean RejectNode (const BVH_VecNd& theCMin1, + const BVH_VecNd& theCMax1, + const BVH_VecNd& theCMin2, + const BVH_VecNd& theCMax2, + Standard_Real&) const Standard_OVERRIDE + { + return BVH_Box (theCMin1, theCMax1).IsOut (theCMin2, theCMax2); + } + + //! Rejects the element by the index + Standard_Boolean RejectElement (const Standard_Integer theID1, + const Standard_Integer theID2) + { + return (mySameBVHs && theID1 >= theID2) || + this->myBVHSet1->Box (theID1).IsOut( + this->myBVHSet2->Box (theID2)); + } + + //! Accepts the index + virtual Standard_Boolean Accept (const Standard_Integer theID1, + const Standard_Integer theID2) Standard_OVERRIDE + { + if (!RejectElement (theID1, theID2)) + { + myPairs.push_back (PairIDs (this->myBVHSet1->Element (theID1), + this->myBVHSet2->Element (theID2))); + return Standard_True; + } + return Standard_False; + } + +protected: //! @name Fields + + std::vector myPairs; //!< Selected pairs of indices + Standard_Boolean mySameBVHs; //!< Selection is performed from the same BVH trees +}; + +#endif diff --git a/src/BOPTools/FILES b/src/BOPTools/FILES index 26526d0a30..26ade9a944 100755 --- a/src/BOPTools/FILES +++ b/src/BOPTools/FILES @@ -8,13 +8,14 @@ BOPTools_AlgoTools3D.hxx BOPTools_AlgoTools_1.cxx BOPTools_AlgoTools_2.cxx BOPTools_BoxSelector.hxx -BOPTools_BoxBndTree.hxx +BOPTools_BoxTree.hxx BOPTools_ConnexityBlock.hxx BOPTools_CoupleOfShape.hxx BOPTools_IndexedDataMapOfSetShape.hxx BOPTools_ListOfConnexityBlock.hxx BOPTools_ListOfCoupleOfShape.hxx BOPTools_MapOfSet.hxx +BOPTools_PairSelector.hxx BOPTools_Parallel.hxx BOPTools_Set.cxx BOPTools_Set.hxx diff --git a/src/BRepOffset/BRepOffset_Inter3d.cxx b/src/BRepOffset/BRepOffset_Inter3d.cxx index adbaa2dd6a..c7b4d31c77 100644 --- a/src/BRepOffset/BRepOffset_Inter3d.cxx +++ b/src/BRepOffset/BRepOffset_Inter3d.cxx @@ -16,6 +16,7 @@ // Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 +#include #include #include #include @@ -46,8 +47,7 @@ #include // #include -#include -#include +#include // #include @@ -114,8 +114,8 @@ void BRepOffset_Inter3d::CompletInt(const TopTools_ListOfShape& SetOfFaces, //--------------------------------------------------------------- // Prepare tools for sorting the bounding boxes - BOPTools_BoxBndTree aBBTree; - NCollection_UBTreeFiller aTreeFiller(aBBTree); + Handle(BOPTools_BoxTree) aBBTree = new BOPTools_BoxTree(); + aBBTree->SetSize (SetOfFaces.Extent()); // NCollection_IndexedDataMap aMFaces; // Construct bounding boxes for faces and add them to the tree @@ -129,11 +129,11 @@ void BRepOffset_Inter3d::CompletInt(const TopTools_ListOfShape& SetOfFaces, // Standard_Integer i = aMFaces.Add(aF, aBoxF); // - aTreeFiller.Add(i, aBoxF); + aBBTree->Add(i, Bnd_Tools::Bnd2BVH(aBoxF)); } // // shake tree filler - aTreeFiller.Fill(); + aBBTree->Build(); // // get faces with interfering bounding boxes aItL.Initialize(SetOfFaces); @@ -141,9 +141,10 @@ void BRepOffset_Inter3d::CompletInt(const TopTools_ListOfShape& SetOfFaces, const TopoDS_Face& aF1 = TopoDS::Face(aItL.Value()); const Bnd_Box& aBoxF1 = aMFaces.FindFromKey(aF1); // - BOPTools_BoxBndTreeSelector aSelector; - aSelector.SetBox(aBoxF1); - aBBTree.Select(aSelector); + BOPTools_BoxTreeSelector aSelector; + aSelector.SetBox (Bnd_Tools::Bnd2BVH(aBoxF1)); + aSelector.SetBVHSet (aBBTree.get()); + aSelector.Select (); // const TColStd_ListOfInteger& aLI = aSelector.Indices(); TColStd_ListIteratorOfListOfInteger aItLI(aLI);