diff --git a/dox/dev_guides/upgrade/upgrade.md b/dox/dev_guides/upgrade/upgrade.md index c67248800f..e4c78255c5 100644 --- a/dox/dev_guides/upgrade/upgrade.md +++ b/dox/dev_guides/upgrade/upgrade.md @@ -1751,3 +1751,13 @@ Proxy classes *SelectBasics_SensitiveEntity* and *SelectBasics_EntityOwner* have *env.bat* produced by Visual Studio project generator *genproj.bat* has been modified so that *%CSF_DEFINES%* variable is reset to initial state. Custom building environment relying on old behavior and setting extra macros within *%CSF_DEFINES%* before env.bat should be updated to either modify custom.bat or setup new variable *%CSF_DEFINES_EXTRA%* instead. + +@subsection upgrade_740_BVH_in_BOP Switching Boolean Operations algorithm to use BVH tree instead of UB tree + +Since OCCT 7.4.0 Boolean Operations algorithm uses BVH tree instead of UBTree to find the pairs of entities with interfering bounding boxes. +The following API changes have been made: +* BOPTools_BoxBndTree and BOPTools_BoxBndTreeSelector have been removed. Use the BOPTools_BoxTree and BOPTools_BoxTreeSelector instead. +* BOPTools_BoxSelector::SetBox() method now accepts the BVH_Box instead of Bnd_Box. +* Methods BOPTools_BoxSelector::Reject and BOPTools_BoxSelector::Accept have been removed as unused. +* The RunParallel flag has been removed from the list of parameters of BOPAlgo_Tools::IntersectVertices method. Earlier, it performed selection from the UB tree in parallel mode. Now all interfering pairs are found in one pass, using pair traverse of the same BVH tree. + diff --git a/samples/tcl/ANC101.tcl b/samples/tcl/ANC101.tcl index 818f3eb6c8..42852ebb92 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 d75aad1f11..8fe38f13ff 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,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -448,28 +448,28 @@ void BOPAlgo_BuilderFace::PerformAreas() // Classify holes relatively faces - // Prepare tree filler with the boxes of the hole faces - NCollection_UBTree aBBTree; - NCollection_UBTreeFiller aTreeFiller(aBBTree); - + // Prepare tree with the boxes of the hole faces + BOPTools_Box2dTree aBoxTree; 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); TopTools_ListIteratorOfListOfShape aItLS(aNewFaces); for (; aItLS.More(); aItLS.Next()) @@ -481,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); @@ -590,9 +590,8 @@ void BOPAlgo_BuilderFace::PerformInternalShapes() // No edges left for classification return; - // Prepare tree filler with the boxes of the edges to classify - NCollection_UBTree aBBTree; - NCollection_UBTreeFiller aTreeFiller(aBBTree); + // Prepare tree with the boxes of the edges to classify + BOPTools_Box2dTree aBoxTree; // Map of edges to classify TopTools_IndexedMapOfShape anEdgesMap; @@ -611,13 +610,13 @@ void BOPAlgo_BuilderFace::PerformInternalShapes() BRepTools::AddUVBounds(myFace, aE, aBoxE); // Make sure the index of edge in the map and // of the box in the tree is the same - aTreeFiller.Add(anEdgesMap.Add(aE), aBoxE); + aBoxTree.Add(anEdgesMap.Add(aE), Bnd_Tools::Bnd2BVH (aBoxE)); } } } - // Shake the tree - aTreeFiller.Fill(); + // Build BVH + aBoxTree.Build(); // Fence map TColStd_MapOfInteger aMEDone; @@ -633,9 +632,10 @@ void BOPAlgo_BuilderFace::PerformInternalShapes() BRepTools::AddUVBounds(aF, aBoxF); // Select edges for the classification - BOPTools_BoxSelector aSelector; - aSelector.SetBox(aBoxF); - if (!aBBTree.Select(aSelector)) + BOPTools_Box2dTreeSelector aSelector; + aSelector.SetBVHSet (&aBoxTree); + aSelector.SetBox(Bnd_Tools::Bnd2BVH (aBoxF)); + if (!aSelector.Select()) continue; // Collect edges inside the face diff --git a/src/BOPAlgo/BOPAlgo_BuilderSolid.cxx b/src/BOPAlgo/BOPAlgo_BuilderSolid.cxx index 29cc5a610d..a024a4f2ca 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 @@ -443,24 +443,23 @@ 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); - + // Prepare tree with the boxes of the hole shells + BOPTools_BoxTree aBBTree; 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(); + // Build BVH + 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); + 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 d03fac1ac0..a12e527c4d 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller.cxx @@ -298,7 +298,7 @@ void BOPAlgo_PaveFiller::PerformInternal() // MakeSplitEdges(); if (HasErrors()) { - return; + return; } // UpdatePaveBlocksWithSDVertices(); @@ -361,7 +361,7 @@ void BOPAlgo_PaveFiller::RepeatIntersection() return; // Update iterator of pairs of shapes with interfering boxes - myIterator->PrepareExt(anExtraInterfMap); + myIterator->IntersectExt(anExtraInterfMap); // Perform intersections with vertices PerformVV(); diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx index 4171cc90d7..6994be6fcd 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx @@ -595,7 +595,7 @@ void BOPAlgo_PaveFiller::TreatNewVertices // // Perform intersection TopTools_ListOfListOfShape aChains; - BOPAlgo_Tools::IntersectVertices(aVerts, myRunParallel, myFuzzyValue, aChains); + BOPAlgo_Tools::IntersectVertices(aVerts, myFuzzyValue, aChains); // // Treat the results - make new vertices for each chain TopTools_ListOfListOfShape::Iterator aItC(aChains); diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx index c6b43cfc9a..7248bf994b 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx @@ -17,6 +17,7 @@ #include +#include #include #include #include @@ -31,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -729,8 +729,7 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB return; // Fill the tree with bounding boxes of the pave blocks - NCollection_UBTree aBBTree; - NCollection_UBTreeFiller aTreeFiller(aBBTree); + BOPTools_BoxTree aBBTree; Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator; BOPDS_IndexedMapOfPaveBlock aPBMap(1, anAlloc); @@ -751,11 +750,11 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB Standard_Boolean isSplit; aPB->ShrunkData(f, l, aPBBox, isSplit); - aTreeFiller.Add(aPBMap.Add(aPB), aPBBox); + aBBTree.Add(aPBMap.Add(aPB), Bnd_Tools::Bnd2BVH(aPBBox)); } // Shake the tree - aTreeFiller.Fill(); + aBBTree.Build(); // Find pairs of Face/PaveBlock containing the same vertices // and prepare those pairs for intersection. @@ -774,10 +773,10 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB continue; const Bnd_Box& aBoxF = aSI.Box(); - BOPTools_BoxSelector aSelector; - aSelector.SetBox(aBoxF); - - if (!aBBTree.Select(aSelector)) + BOPTools_BoxTreeSelector aSelector; + aSelector.SetBox(Bnd_Tools::Bnd2BVH(aBoxF)); + aSelector.SetBVHSet (&aBBTree); + if (!aSelector.Select()) continue; const TopoDS_Face& aF = TopoDS::Face(aSI.Shape()); diff --git a/src/BOPAlgo/BOPAlgo_Tools.cxx b/src/BOPAlgo/BOPAlgo_Tools.cxx index fa93d31291..b5b7625e87 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 @@ -954,78 +954,66 @@ Standard_Boolean FindPlane(const TopoDS_Shape& theWire, ///////////////////////////////////////////////////////////////////////// //======================================================================= -//class : BOPAlgo_TNV +//class : BOPAlgo_PairVerticesSelector //purpose : //======================================================================= -class BOPAlgo_TNV; -typedef NCollection_Vector BOPAlgo_VectorOfTNV; +class BOPAlgo_PairVerticesSelector : public BOPTools_BoxPairSelector +{ +public: -//======================================================================= -class BOPAlgo_TNV : public BOPTools_BoxBndTreeSelector{ - public: - BOPAlgo_TNV() - : BOPTools_BoxBndTreeSelector(), - myTol (0.), myFuzzyValue(0.), myTree(NULL), myVecTNV(NULL) { - }; - // - ~BOPAlgo_TNV(){ - }; - // - void SetVertex(const TopoDS_Vertex& aV) { - myV=aV; - myPnt = BRep_Tool::Pnt(myV); + BOPAlgo_PairVerticesSelector() + : myVertices(NULL), + myFuzzyValue(Precision::Confusion()) + {} + + //! Sets the map of vertices with tolerances + void SetMapOfVerticesTolerances (const TopTools_IndexedDataMapOfShapeReal& theVertices) + { + myVertices = &theVertices; } - // - const TopoDS_Vertex& Vertex()const { - return myV; - } - // - void SetTree(BOPTools_BoxBndTree& aTree) { - myTree=&aTree; - } - // - void SetTolerance(const Standard_Real theTol) { - myTol = theTol; - } - // - Standard_Real Tolerance() const { - return myTol; - } - // - const gp_Pnt& Pnt() const { - return myPnt; - } - // - void SetFuzzyValue(const Standard_Real theFuzzyValue) { + + //! Sets the fuzzy value + void SetFuzzyValue (const Standard_Real theFuzzyValue) + { myFuzzyValue = theFuzzyValue; } - // - void SetVectorOfTNV(const BOPAlgo_VectorOfTNV& theVec) { - myVecTNV = &theVec; - } - // - virtual Standard_Boolean Accept(const Standard_Integer& theIndex) + + //! Checks and accepts the pair of elements. + virtual Standard_Boolean Accept (const Standard_Integer theID1, + const Standard_Integer theID2) Standard_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 (!RejectElement (theID1, theID2)) + { + const Standard_Integer anID1 = this->myBVHSet1->Element (theID1); + const TopoDS_Vertex& aV1 = TopoDS::Vertex (myVertices->FindKey (anID1)); + Standard_Real aTolV1 = BRep_Tool::Tolerance (aV1); + if (aTolV1 < myVertices->FindFromIndex (anID1)) + aTolV1 = myVertices->FindFromIndex (anID1); + gp_Pnt aP1 = BRep_Tool::Pnt (aV1); + + const Standard_Integer anID2 = this->myBVHSet1->Element (theID2); + const TopoDS_Vertex& aV2 = TopoDS::Vertex (myVertices->FindKey (anID2)); + Standard_Real aTolV2 = BRep_Tool::Tolerance (aV2); + if (aTolV2 < myVertices->FindFromIndex (anID2)) + aTolV2 = myVertices->FindFromIndex (anID2); + gp_Pnt aP2 = BRep_Tool::Pnt (aV2); + + Standard_Real aTolSum2 = aTolV1 + aTolV2 + myFuzzyValue; + aTolSum2 *= aTolSum2; + + Standard_Real aD2 = aP1.SquareDistance (aP2); + if (aD2 < aTolSum2) + { + myPairs.push_back (PairIDs (anID1, anID2)); + return Standard_True; + } + } return Standard_False; } - // - void Perform() { - myTree->Select(*this); - } - // - protected: - Standard_Real myTol; + +protected: + const TopTools_IndexedDataMapOfShapeReal * myVertices; Standard_Real myFuzzyValue; - gp_Pnt myPnt; - TopoDS_Vertex myV; - BOPTools_BoxBndTree *myTree; - const BOPAlgo_VectorOfTNV *myVecTNV; }; // ///////////////////////////////////////////////////////////////////////// @@ -1035,84 +1023,82 @@ class BOPAlgo_TNV : public BOPTools_BoxBndTreeSelector{ //purpose : Builds the chains of intersecting vertices //======================================================================= void BOPAlgo_Tools::IntersectVertices(const TopTools_IndexedDataMapOfShapeReal& theVertices, - const Standard_Boolean theRunParallel, const Standard_Real theFuzzyValue, TopTools_ListOfListOfShape& theChains) { - Standard_Integer i, j, aNbV = theVertices.Extent(); + Standard_Integer aNbV = theVertices.Extent(); if (aNbV <= 1) { if (aNbV == 1) { theChains.Append(TopTools_ListOfShape()).Append(theVertices.FindKey(1)); } return; } - // - // Use unbalanced binary tree of bounding boxes for sorting of the vertices. - BOPTools_BoxBndTree aBBTree; - NCollection_UBTreeFiller aTreeFiller(aBBTree); - // Perform intersection of the vertices - BOPAlgo_VectorOfTNV aVTNV; - // - // Use additional tolerance for intersection + + // Additional tolerance for intersection Standard_Real aTolAdd = theFuzzyValue / 2.; - // Prepare the tree - for (i = 1; i <= aNbV; ++i) { + + // Use BVH Tree for sorting the vertices + BOPTools_BoxTree aBBTree; + aBBTree.SetSize (aNbV); + + for (Standard_Integer i = 1; i <= aNbV; ++i) + { const TopoDS_Vertex& aV = TopoDS::Vertex(theVertices.FindKey(i)); Standard_Real aTol = BRep_Tool::Tolerance(aV); - if (aTol < theVertices(i)) { + if (aTol < theVertices(i)) aTol = theVertices(i); - } + // Build bnd box for vertex Bnd_Box aBox; aBox.Add(BRep_Tool::Pnt(aV)); aBox.SetGap(aTol + aTolAdd); - // - aTreeFiller.Add(i, aBox); - // - BOPAlgo_TNV& aTNV=aVTNV.Appended(); - aTNV.SetTree(aBBTree); - aTNV.SetBox(aBox); - aTNV.SetVertex(aV); - aTNV.SetTolerance(aTol); - aTNV.SetFuzzyValue(theFuzzyValue); - aTNV.SetVectorOfTNV(aVTNV); + aBBTree.Add(i, Bnd_Tools::Bnd2BVH(aBox)); } - // Shake the tree - aTreeFiller.Fill(); - // - // Perform intersection - BOPTools_Parallel::Perform (theRunParallel, aVTNV); - // - // Fence map - TColStd_MapOfInteger aMFence; - // Build chains of intersecting vertices - for (i = 1; i <= aNbV; ++i) { - if (!aMFence.Add(i)) { - continue; - } - // Start the chain - TColStd_IndexedMapOfInteger aMChain; - aMChain.Add(i); - // - for (j = 1; j <= aMChain.Extent(); ++j) { - BOPAlgo_TNV& aTNV = aVTNV(aMChain(j) - 1); - const TColStd_ListOfInteger& aLI = aTNV.Indices(); - // Add these vertices into the chain - for (TColStd_ListIteratorOfListOfInteger aItLI(aLI); aItLI.More(); aItLI.Next()) { - if (aMFence.Add(aItLI.Value())) { - aMChain.Add(aItLI.Value()); - } - } - } - // - // Put vertices of the chain into the list - TopTools_ListOfShape& aChain = theChains.Append(TopTools_ListOfShape()); - // - Standard_Integer aNbVChain = aMChain.Extent(); - for (j = 1; j <= aNbVChain; ++j) { - const TopoDS_Vertex& aVP = aVTNV(aMChain(j) - 1).Vertex(); - aChain.Append(aVP); + + aBBTree.Build(); + + // Perform selection of the interfering vertices + BOPAlgo_PairVerticesSelector aPairSelector; + aPairSelector.SetBVHSets (&aBBTree, &aBBTree); + aPairSelector.SetSame (Standard_True); + aPairSelector.SetMapOfVerticesTolerances (theVertices); + aPairSelector.SetFuzzyValue (theFuzzyValue); + aPairSelector.Select(); + + // Treat the selected pairs + const std::vector& aPairs = aPairSelector.Pairs(); + const Standard_Integer aNbPairs = static_cast (aPairs.size()); + + // Collect interfering pairs + Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator; + NCollection_IndexedDataMap aMILI (1, anAlloc); + + for (Standard_Integer iPair = 0; iPair < aNbPairs; ++iPair) + { + const BOPTools_BoxPairSelector::PairIDs& aPair = aPairs[iPair]; + BOPAlgo_Tools::FillMap (aPair.ID1, aPair.ID2, aMILI, anAlloc); + } + + NCollection_List aBlocks (anAlloc); + BOPAlgo_Tools::MakeBlocks (aMILI, aBlocks, anAlloc); + + NCollection_List::Iterator itLI (aBlocks); + for (; itLI.More(); itLI.Next()) + { + const TColStd_ListOfInteger& aLI = itLI.Value(); + TopTools_ListOfShape &aChain = theChains.Append (TopTools_ListOfShape()); + + for (TColStd_ListOfInteger::Iterator itI (aLI); itI.More(); itI.Next()) + aChain.Append (theVertices.FindKey (itI.Value())); + } + + // Add not interfered vertices as a chain of 1 element + for (Standard_Integer i = 1; i <= aNbV; ++i) + { + if (!aMILI.Contains (i)) + { + TopTools_ListOfShape &aChain = theChains.Append (TopTools_ListOfShape()); + aChain.Append (theVertices.FindKey(i)); } } } @@ -1236,9 +1222,9 @@ public: }; //! Sets the Bounding Box tree - void SetBBTree(const BOPTools_BoxBndTree& theBBTree) + void SetBBTree(BOPTools_BoxTree* theBBTree) { - myBBTree = (BOPTools_BoxBndTree*)&theBBTree; + myBBTree = theBBTree; }; //! Sets the ShapeBox structure @@ -1288,7 +1274,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 + BOPTools_BoxTree* myBBTree; //! BVH tree of bounding boxes BOPAlgo_VectorOfShapeBox* myVShapeBox; //! ShapeBoxMap TopoDS_Iterator myItF; //! Iterators @@ -1308,10 +1294,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); // - if (!myBBTree->Select(aSelector)) + if (!aSelector.Select()) return; const TColStd_ListOfInteger& aLIFP = aSelector.Indices(); @@ -1559,19 +1546,18 @@ void BOPAlgo_Tools::ClassifyFaces(const TopTools_ListOfShape& theFaces, } } - // Prepare UB tree of bounding boxes of the faces to classify + // Prepare BVH 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); - + BOPTools_BoxTree aBBTree; Standard_Integer aNbF = aVSB.Length(); + aBBTree.SetSize (aNbF); 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; @@ -1605,7 +1591,7 @@ void BOPAlgo_Tools::ClassifyFaces(const TopTools_ListOfShape& theFaces, if (pLIF) aFIP.SetOwnIF(*pLIF); - aFIP.SetBBTree(aBBTree); + aFIP.SetBBTree(&aBBTree); aFIP.SetShapeBoxVector(aVSB); } diff --git a/src/BOPAlgo/BOPAlgo_Tools.hxx b/src/BOPAlgo/BOPAlgo_Tools.hxx index 50492e9b55..9d20dd3b26 100644 --- a/src/BOPAlgo/BOPAlgo_Tools.hxx +++ b/src/BOPAlgo/BOPAlgo_Tools.hxx @@ -162,7 +162,6 @@ public: //! Finds chains of intersecting vertices Standard_EXPORT static void IntersectVertices(const TopTools_IndexedDataMapOfShapeReal& theVertices, - const Standard_Boolean theRunParallel, const Standard_Real theFuzzyValue, TopTools_ListOfListOfShape& theChains); diff --git a/src/BOPDS/BOPDS_Iterator.cxx b/src/BOPDS/BOPDS_Iterator.cxx index 03228384c0..a685c02aee 100644 --- a/src/BOPDS/BOPDS_Iterator.cxx +++ b/src/BOPDS/BOPDS_Iterator.cxx @@ -18,16 +18,16 @@ #include #include +#include #include #include #include #include #include #include -#include +#include #include #include -#include #include #include #include @@ -37,12 +37,12 @@ //class : BOPDS_TreeSelector //purpose : //======================================================================= -class BOPDS_TSR : public BOPTools_BoxBndTreeSelector{ +class BOPDS_TSR : public BOPTools_BoxTreeSelector +{ public: BOPDS_TSR() : - BOPTools_BoxBndTreeSelector(), + BOPTools_BoxTreeSelector(), myHasBRep(Standard_False), - myTree(NULL), myIndex(-1) {} // virtual ~BOPDS_TSR() { @@ -52,23 +52,18 @@ class BOPDS_TSR : public BOPTools_BoxBndTreeSelector{ myHasBRep=bFlag; } // - void SetTree(BOPTools_BoxBndTree& aTree) { - myTree=&aTree; - } - // void SetIndex(const Standard_Integer theIndex) { myIndex = theIndex; } // Standard_Integer Index() const { return myIndex; } // void Perform() { if (myHasBRep) { - myTree->Select(*this); + Select(); } } // protected: Standard_Boolean myHasBRep; - BOPTools_BoxBndTree *myTree; Standard_Integer myIndex; }; // @@ -76,7 +71,6 @@ class BOPDS_TSR : public BOPTools_BoxBndTreeSelector{ typedef NCollection_Vector BOPDS_VectorOfTSR; ///////////////////////////////////////////////////////////////////////// - //======================================================================= //function : //purpose : @@ -289,142 +283,81 @@ 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; - // - myBoxTree.Clear(); - NCollection_UBTreeFiller aTreeFiller(myBoxTree); - // - 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) { - continue; - } - // - const Bnd_Box& aBoxEx=aSI.Box(); - aTSR.SetTree(myBoxTree); - aTSR.SetBox(aBoxEx); - aTSR.SetIndex(i); - // - aTreeFiller.Add(i, aBoxEx); - } - // - aTreeFiller.Fill(); - // - //=========================================== - BOPTools_Parallel::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)) { - continue; - } - // - BOPDS_TSR& aTSRi = aVTSR(i); - const TColStd_ListOfInteger& aLI = aTSRi.Indices(); - Standard_Integer aNbSD = aLI.Extent(); - if (!aNbSD) { - 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); + const Standard_Integer aNb = myDS->NbSourceShapes(); - if (anOBBi.IsOut(anOBBj)) - continue; - } - - 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; iRHasShapeSD(nV, nVSD); - const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nVSD); + const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); + if (!aSI.HasBRep()) + continue; const Bnd_Box& aBox = aSI.Box(); - myBoxTree.Add(nV, aBox); + aBoxTree.Add (i, Bnd_Tools::Bnd2BVH (aBox)); } - // Clear the extra lists - const Standard_Integer aNbExt = BOPDS_Iterator::NbExtInterfs(); - myLength = 0; - for (Standard_Integer i = 0; i < aNbExt; ++i) - myExtLists(i).Clear(); + // Build BVH + aBoxTree.Build(); - IntersectExt(theIndices); + // Select pairs of shapes with interfering bounding boxes + BOPTools_BoxPairSelector aPairSelector; + aPairSelector.SetBVHSets (&aBoxTree, &aBoxTree); + aPairSelector.SetSame (Standard_True); + aPairSelector.Select(); + aPairSelector.Sort(); - myUseExt = Standard_True; + // 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; + + 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 shape with its sub-shapes + if (((iType1 < iType2) && aSI1.HasSubShape (aPair.ID2)) || + ((iType1 > iType2) && aSI2.HasSubShape (aPair.ID1))) + continue; + + if (theCheckOBB) + { + // Check intersection of Oriented bounding boxes of the shapes + const Bnd_OBB& anOBB1 = theCtx->OBB (aSI1.Shape(), theFuzzyValue); + const Bnd_OBB& anOBB2 = theCtx->OBB (aSI2.Shape(), theFuzzyValue); + + if (anOBB1.IsOut (anOBB2)) + continue; + } + + Standard_Integer iX = BOPDS_Tools::TypeToInteger (aType1, aType2); + myLists(iX).Append (BOPDS_Pair (Min (aPair.ID1, aPair.ID2), + Max (aPair.ID1, aPair.ID2))); + } + } } //======================================================================= @@ -433,24 +366,43 @@ void BOPDS_Iterator::PrepareExt(const TColStd_MapOfInteger& theIndices) //======================================================================= void BOPDS_Iterator::IntersectExt(const TColStd_MapOfInteger& theIndices) { - // Prepare vector for parallel selection - BOPDS_VectorOfTSR aVTSR(theIndices.Extent()); + if (!myDS) + return; - TColStd_MapIteratorOfMapOfInteger itM(theIndices); - for (; itM.More(); itM.Next()) + const Standard_Integer aNb = myDS->NbSourceShapes(); + + BOPTools_BoxTree aBoxTree; + aBoxTree.SetSize (aNb); + BOPDS_VectorOfTSR aVTSR(theIndices.Extent()); + // + for (Standard_Integer i = 0; i < aNb; ++i) { - Standard_Integer nV = itM.Value(); - Standard_Integer nVSD = nV; - myDS->HasShapeSD(nV, nVSD); - const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nVSD); - const Bnd_Box& aBox = aSI.Box(); - BOPDS_TSR& aTSR = aVTSR.Appended(); - aTSR.SetHasBRep(Standard_True); - aTSR.SetTree(myBoxTree); - aTSR.SetBox(aBox); - aTSR.SetIndex(nV); + const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); + if (!aSI.IsInterfering() || (aSI.ShapeType() == TopAbs_SOLID)) + continue; + // + if (theIndices.Contains (i)) + { + Standard_Integer nVSD = i; + myDS->HasShapeSD (i, nVSD); + const BOPDS_ShapeInfo& aSISD = myDS->ShapeInfo (nVSD); + const Bnd_Box& aBox = aSISD.Box (); + aBoxTree.Add (i, Bnd_Tools::Bnd2BVH(aBox)); + + BOPDS_TSR& aTSR=aVTSR.Appended(); + aTSR.SetHasBRep(Standard_True); + aTSR.SetBVHSet (&aBoxTree); + aTSR.SetBox (Bnd_Tools::Bnd2BVH (aBox)); + aTSR.SetIndex (i); + } + else + { + aBoxTree.Add (i, Bnd_Tools::Bnd2BVH (aSI.Box ())); + } } + aBoxTree.Build(); + // Perform selection BOPTools_Parallel::Perform (myRunParallel, aVTSR); @@ -459,8 +411,8 @@ void BOPDS_Iterator::IntersectExt(const TColStd_MapOfInteger& theIndices) // Fence map to avoid duplicating pairs BOPDS_MapOfPair aMPFence; - const Standard_Integer aNb = aVTSR.Length(); - for (Standard_Integer k = 0; k < aNb; ++k) + const Standard_Integer aNbV = aVTSR.Length(); + for (Standard_Integer k = 0; k < aNbV; ++k) { BOPDS_TSR& aTSRi = aVTSR(k); const TColStd_ListOfInteger& aLI = aTSRi.Indices(); @@ -485,7 +437,7 @@ void BOPDS_Iterator::IntersectExt(const TColStd_MapOfInteger& theIndices) const TopAbs_ShapeEnum aTJ = aSJ.ShapeType(); const Standard_Integer iTJ = BOPDS_Tools::TypeToInteger(aTJ); - // avoid interfering of the same shapes and shape with its sub-shapes + // avoid interfering of the shape with its sub-shapes if (((iTI < iTJ) && aSI.HasSubShape(j)) || ((iTI > iTJ) && aSJ.HasSubShape(i))) continue; @@ -499,4 +451,6 @@ void BOPDS_Iterator::IntersectExt(const TColStd_MapOfInteger& theIndices) } } } + + myUseExt = Standard_True; } diff --git a/src/BOPDS/BOPDS_Iterator.hxx b/src/BOPDS/BOPDS_Iterator.hxx index 04b339a5af..9faf534c49 100644 --- a/src/BOPDS/BOPDS_Iterator.hxx +++ b/src/BOPDS/BOPDS_Iterator.hxx @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include @@ -88,7 +88,7 @@ public: //! Updates the tree of Bounding Boxes with increased boxes and //! intersects such elements with the tree. - Standard_EXPORT void PrepareExt(const TColStd_MapOfInteger& theIndicies); + Standard_EXPORT void IntersectExt(const TColStd_MapOfInteger& theIndicies); //! Returns the number of intersections founded Standard_EXPORT Standard_Integer ExpectedLength() const; @@ -119,12 +119,6 @@ protected: //! @name Protected methods for bounding boxes intersection const Standard_Boolean theCheckOBB = Standard_False, const Standard_Real theFuzzyValue = Precision::Confusion()); - //! Intersects the bounding boxes of the shapes with given indices in DS - //! with the tree of bounding boxes and saves the interfering pairs in - //! extra lists for further geometrical intersection. - Standard_EXPORT void IntersectExt(const TColStd_MapOfInteger& theIndices); - - protected: //! @name Fields Handle(NCollection_BaseAllocator) myAllocator; //!< Allocator @@ -134,7 +128,6 @@ protected: //! @name Fields BOPDS_VectorOfVectorOfPair myLists; //!< Pairs with interfering bounding boxes BOPDS_VectorOfPair::Iterator myIterator; //!< Iterator on each interfering type Standard_Boolean myRunParallel; //!< Flag for parallel processing - BOPTools_BoxBndTree myBoxTree; //!< Unbalanced tree of bounding boxes BOPDS_VectorOfVectorOfPair myExtLists; //!< Extra pairs of sub-shapes found after //! intersection of increased sub-shapes Standard_Boolean myUseExt; //!< Information flag for using the extra lists diff --git a/src/BOPDS/BOPDS_IteratorSI.cxx b/src/BOPDS/BOPDS_IteratorSI.cxx index 3b824010eb..13f0926ead 100644 --- a/src/BOPDS/BOPDS_IteratorSI.cxx +++ b/src/BOPDS/BOPDS_IteratorSI.cxx @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -21,11 +22,10 @@ #include #include #include -#include +#include #include #include #include -#include #include #include #include @@ -79,83 +79,68 @@ void BOPDS_IteratorSI::UpdateByLevelOfCheck(const Standard_Integer theLevel) // function: Intersect // purpose: //======================================================================= -void BOPDS_IteratorSI::Intersect(const Handle(IntTools_Context)& theCtx, - const Standard_Boolean theCheckOBB, - const Standard_Real theFuzzyValue) +void BOPDS_IteratorSI::Intersect (const Handle(IntTools_Context)& theCtx, + const Standard_Boolean theCheckOBB, + const Standard_Real theFuzzyValue) { - Standard_Integer i, j, iX, aNbS; - Standard_Integer iTi, iTj; - TopAbs_ShapeEnum aTi, aTj; - // - BOPTools_BoxBndTreeSelector aSelector; - BOPTools_BoxBndTree aBBTree; - NCollection_UBTreeFiller aTreeFiller(aBBTree); - // - aNbS = myDS->NbSourceShapes(); - for (i=0; iShapeInfo(i); - if (!aSI.IsInterfering()) { + const Standard_Integer aNbS = myDS->NbSourceShapes(); + + BOPTools_BoxTree aBBTree; + aBBTree.SetSize (aNbS); + + for (Standard_Integer i = 0; i < aNbS; ++i) + { + const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo (i); + if (!aSI.IsInterfering()) continue; - } - // + const Bnd_Box& aBoxEx = aSI.Box(); - aTreeFiller.Add(i, aBoxEx); + aBBTree.Add (i, Bnd_Tools::Bnd2BVH (aBoxEx)); } - // - aTreeFiller.Fill(); - // - BOPDS_MapOfPair aMPFence; - // - for (i = 0; i < aNbS; ++i) { - const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); - if (!aSI.IsInterfering()){ + + aBBTree.Build(); + + // Select pairs of shapes with interfering bounding boxes + BOPTools_BoxPairSelector aPairSelector; + aPairSelector.SetBVHSets (&aBBTree, &aBBTree); + 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()); + + for (Standard_Integer iPair = 0; iPair < aNbPairs; ++iPair) + { + const BOPTools_BoxPairSelector::PairIDs& aPair = aPairs[iPair]; + + 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 shape with its sub-shapes + if (((iType1 < iType2) && aSI1.HasSubShape (aPair.ID2)) || + ((iType1 > iType2) && aSI2.HasSubShape (aPair.ID1))) continue; - } - // - const Bnd_Box& aBoxEx = aSI.Box(); - // - aSelector.Clear(); - aSelector.SetBox(aBoxEx); - // - Standard_Integer aNbSD = aBBTree.Select(aSelector); - if (!aNbSD) { - continue; - } - // - aTi = aSI.ShapeType(); - iTi = BOPDS_Tools::TypeToInteger(aTi); - // - const TColStd_ListOfInteger& aLI = aSelector.Indices(); - TColStd_ListIteratorOfListOfInteger aIt(aLI); - for (; aIt.More(); aIt.Next()) { - j = aIt.Value(); - 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 ((i == j) || ((iTi < iTj) && aSI.HasSubShape(j)) || - ((iTi > iTj) && aSJ.HasSubShape(i))) { + + if (theCheckOBB) + { + // Check intersection of Oriented bounding boxes of the shapes + const Bnd_OBB& anOBB1 = theCtx->OBB (aSI1.Shape (), theFuzzyValue); + const Bnd_OBB& anOBB2 = theCtx->OBB (aSI2.Shape (), theFuzzyValue); + + if (anOBB1.IsOut (anOBB2)) 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; - } - - iX = BOPDS_Tools::TypeToInteger(aTi, aTj); - myLists(iX).Append(aPair); - }// if (aMPKXB.Add(aPKXB)) { - }// for (; aIt.More(); aIt.Next()) { - }//for (i=1; i<=aNbS; ++i) { - // - aMPFence.Clear(); + Standard_Integer iX = BOPDS_Tools::TypeToInteger (aType1, aType2); + myLists(iX).Append (BOPDS_Pair (Min (aPair.ID1, aPair.ID2), + Max (aPair.ID1, aPair.ID2))); + } } 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..5105fa3e9a 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 @@ -115,60 +114,65 @@ void BOPDS_SubIterator::Initialize() // function: Intersect // purpose: //======================================================================= - void BOPDS_SubIterator::Intersect() +void BOPDS_SubIterator::Intersect() { - Standard_Integer i, j, iTi, iTj; - BOPTools_BoxBndTree aBBTree; - NCollection_UBTreeFiller aTreeFiller(aBBTree); - // - TColStd_ListIteratorOfListOfInteger aIt(*mySubSet1); - for (; aIt.More(); aIt.Next()) { - i = aIt.Value(); - // - const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); - const Bnd_Box& aBoxEx = aSI.Box(); - // - aTreeFiller.Add(i, aBoxEx); + if (!mySubSet1->Extent() || !mySubSet2->Extent()) + return; + + // Construct BVH tree for each sub-set + BOPTools_BoxTree aBBTree[2]; + for (Standard_Integer i = 0; i < 2; ++i) + { + const TColStd_ListOfInteger* aSubSet = !i ? mySubSet1 : mySubSet2; + aBBTree[i].SetSize (aSubSet->Extent()); + for (TColStd_ListOfInteger::Iterator it (*aSubSet); it.More(); it.Next()) + { + const Standard_Integer nS = it.Value(); + const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nS); + const Bnd_Box& aBoxEx = aSI.Box(); + aBBTree[i].Add(nS, Bnd_Tools::Bnd2BVH (aBoxEx)); + } + aBBTree[i].Build(); } - // - aTreeFiller.Fill(); - // + + // Perform selection of the interfering pairs + BOPTools_BoxPairSelector aPairSelector; + aPairSelector.SetBVHSets (&aBBTree[0], &aBBTree[1]); + aPairSelector.Select(); + aPairSelector.Sort(); + + // Treat the selected pairs + const std::vector& aPairs = aPairSelector.Pairs(); + const Standard_Integer aNbPairs = static_cast (aPairs.size()); + + // Fence map BOPDS_MapOfPair aMPKFence; - // - aIt.Initialize(*mySubSet2); - for (; aIt.More(); aIt.Next()) { - i = aIt.Value(); - // - 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); - if (!aNbSD) { + + for (Standard_Integer iPair = 0; iPair < aNbPairs; ++iPair) + { + const BOPTools_BoxPairSelector::PairIDs& aPair = aPairs[iPair]; + if (aPair.ID1 == aPair.ID2) continue; - } - // - iTi = BOPDS_Tools::TypeToInteger(aSI.ShapeType()); - // - const TColStd_ListOfInteger& aLI = aSelector.Indices(); - TColStd_ListIteratorOfListOfInteger aItLI(aLI); - for (; aItLI.More(); aItLI.Next()) { - j = aItLI.Value(); - // - const BOPDS_ShapeInfo& aSJ = myDS->ShapeInfo(j); - iTj = BOPDS_Tools::TypeToInteger(aSJ.ShapeType()); - // - // avoid interfering of the same shapes and shape with its sub-shapes - if ((i == j) || ((iTi < iTj) && aSI.HasSubShape(j)) || - ((iTi > iTj) && aSJ.HasSubShape(i))) { - continue; - } - // - BOPDS_Pair aPair(j, i); - if (aMPKFence.Add(aPair)) { - myList.Append(aPair); - } - } + + BOPDS_Pair aDSPair (Min(aPair.ID1, aPair.ID2), + Max(aPair.ID1, aPair.ID2)); + if (!aMPKFence.Add(aDSPair)) + continue; + + 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 shape with its sub-shapes + if (((iType1 < iType2) && aSI1.HasSubShape (aPair.ID2)) || + ((iType1 > iType2) && aSI2.HasSubShape (aPair.ID1))) + continue; + + myList.Append(aDSPair); } } diff --git a/src/BOPTools/BOPTools_BoxBndTree.hxx b/src/BOPTools/BOPTools_BoxBndTree.hxx deleted file mode 100644 index 6ed2ea0963..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_EBTree BOPTools_BoxBndTree; -typedef BOPTools_BoxSelector BOPTools_BoxBndTreeSelector; - -#endif diff --git a/src/BOPTools/BOPTools_BoxSelector.hxx b/src/BOPTools/BOPTools_BoxSelector.hxx index e8bf2683f4..c29012e04d 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 -//! Template Selector for the unbalanced binary tree -//! of overlapped bounding boxes. -template class BOPTools_BoxSelector : - public NCollection_UBTree::Selector +#include +#include + +//! 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 - BoxType myBox; - TColStd_ListOfInteger myIndices; + //! 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; + } + //! Checks if the element should be rejected + Standard_Boolean RejectElement (const Standard_Integer theIndex) + { + return myBox.IsOut (this->myBVHSet->Box (theIndex)); + } + + //! Checks if the metric of the node may be accepted + virtual Standard_Boolean AcceptMetric (const Standard_Boolean& theIsInside) const Standard_OVERRIDE + { + return theIsInside; + } + + //! Accepts the element with the index in BVH tree + 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; + } + +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..19a22740be --- /dev/null +++ b/src/BOPTools/BOPTools_PairSelector.hxx @@ -0,0 +1,131 @@ +// 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 selection of the elements from two BVH trees. +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. + //! If the flag is set to true the resulting vector will contain + //! only unique pairs (mirrored pairs will be rejected, + //! e.g. (1, 2) will be taken, (2, 1) will be rejected) and will + //! not contain pairs in which IDs are the same (pair (1, 1) will be rejected). + //! If it is required to have a full vector of pairs even + //! for the same BVH trees, just keep the false value of this flag. + 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 + + //! Basing on the bounding boxes of the nodes checks if the pair of nodes 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); + } + + //! Checks if the pair of elements should be rejected. + Standard_Boolean RejectElement (const Standard_Integer theID1, + const Standard_Integer theID2) + { + return (mySameBVHs && theID1 >= theID2) || + this->myBVHSet1->Box (theID1).IsOut( + this->myBVHSet2->Box (theID2)); + } + + //! Checks and accepts the pair of elements. + 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..0019a4f013 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); + BOPTools_BoxTree aBBTree; + aBBTree.SetSize (SetOfFaces.Extent()); // NCollection_IndexedDataMap aMFaces; // Construct bounding boxes for faces and add them to the tree @@ -127,37 +127,37 @@ void BRepOffset_Inter3d::CompletInt(const TopTools_ListOfShape& SetOfFaces, Bnd_Box aBoxF; BRepBndLib::Add(aF, aBoxF); // - Standard_Integer i = aMFaces.Add(aF, aBoxF); + Standard_Integer i = aMFaces.Add (aF, aBoxF); // - aTreeFiller.Add(i, aBoxF); + aBBTree.Add(i, Bnd_Tools::Bnd2BVH(aBoxF)); } - // - // shake tree filler - aTreeFiller.Fill(); - // - // get faces with interfering bounding boxes - aItL.Initialize(SetOfFaces); - for (; aItL.More(); aItL.Next()) { - const TopoDS_Face& aF1 = TopoDS::Face(aItL.Value()); - const Bnd_Box& aBoxF1 = aMFaces.FindFromKey(aF1); - // - BOPTools_BoxBndTreeSelector aSelector; - aSelector.SetBox(aBoxF1); - aBBTree.Select(aSelector); - // - const TColStd_ListOfInteger& aLI = aSelector.Indices(); - TColStd_ListIteratorOfListOfInteger aItLI(aLI); - for (; aItLI.More(); aItLI.Next()) { - Standard_Integer i = aItLI.Value(); - const TopoDS_Face& aF2 = TopoDS::Face(aMFaces.FindKey(i)); - // - // intersect faces - FaceInter(aF1, aF2, InitOffsetFace); - } + + // Build BVH + aBBTree.Build(); + + // Perform selection of the pairs + BOPTools_BoxPairSelector aSelector; + aSelector.SetBVHSets (&aBBTree, &aBBTree); + aSelector.SetSame (Standard_True); + aSelector.Select(); + aSelector.Sort(); + + // Treat the selected pairs + const std::vector& aPairs = aSelector.Pairs(); + const Standard_Integer aNbPairs = static_cast (aPairs.size()); + + for (Standard_Integer iPair = 0; iPair < aNbPairs; ++iPair) + { + const BOPTools_BoxPairSelector::PairIDs& aPair = aPairs[iPair]; + + const TopoDS_Face& aF1 = TopoDS::Face (aMFaces.FindKey (Min (aPair.ID1, aPair.ID2))); + const TopoDS_Face& aF2 = TopoDS::Face (aMFaces.FindKey (Max (aPair.ID1, aPair.ID2))); + + // intersect faces + FaceInter(aF1, aF2, InitOffsetFace); } } - //======================================================================= //function : FaceInter //purpose : Performs intersection of the given faces diff --git a/src/IntPolyh/IntPolyh_MaillageAffinage.cxx b/src/IntPolyh/IntPolyh_MaillageAffinage.cxx index a0f7958673..bcc580f34a 100644 --- a/src/IntPolyh/IntPolyh_MaillageAffinage.cxx +++ b/src/IntPolyh/IntPolyh_MaillageAffinage.cxx @@ -27,6 +27,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -42,16 +46,14 @@ #include #include #include -#include -#include #include #include typedef NCollection_Array1 IntPolyh_ArrayOfInteger; typedef NCollection_IndexedDataMap IntPolyh_IndexedDataMapOfIntegerArrayOfInteger; + TColStd_ListOfInteger, + TColStd_MapIntegerHasher> IntPolyh_IndexedDataMapOfIntegerListOfInteger; static Standard_Real MyTolerance=10.0e-7; @@ -133,32 +135,82 @@ static Standard_Integer& aI2); //======================================================================= -//class : IntPolyh_BoxBndTreeSelector -//purpose : Select interfering bounding boxes +//class : IntPolyh_BoxBndTree +//purpose : BVH structure to contain the boxes of triangles //======================================================================= -typedef NCollection_UBTree IntPolyh_BoxBndTree; -class IntPolyh_BoxBndTreeSelector : public IntPolyh_BoxBndTree::Selector { - public: - IntPolyh_BoxBndTreeSelector(const Bnd_Box& theBox) : myBox(theBox) {} - // - virtual Standard_Boolean Reject(const Bnd_Box& theOther) const +typedef BVH_BoxSet IntPolyh_BoxBndTree; + +//======================================================================= +//class : IntPolyh_BoxBndTreeSelector +//purpose : Selector of interfering boxes +//======================================================================= +class IntPolyh_BoxBndTreeSelector : + public BVH_PairTraverse +{ +public: + typedef BVH_Box::BVH_VecNt BVH_Vec3d; + + //! Auxiliary structure to keep the pair of indices + struct PairIDs { - return myBox.IsOut(theOther); - } - // - virtual Standard_Boolean Accept(const Standard_Integer &theInd) + 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; + }; + +public: + + //! Constructor + IntPolyh_BoxBndTreeSelector () + {} + + //! Rejects the node + virtual Standard_Boolean RejectNode (const BVH_Vec3d& theCMin1, + const BVH_Vec3d& theCMax1, + const BVH_Vec3d& theCMin2, + const BVH_Vec3d& theCMax2, + Standard_Real&) const Standard_OVERRIDE { - myIndices.Append(theInd); - return Standard_True; + return BVH_Box (theCMin1, theCMax1).IsOut (theCMin2, theCMax2); } - // - const TColStd_ListOfInteger& Indices() const + + //! Accepts the element + virtual Standard_Boolean Accept (const Standard_Integer theID1, + const Standard_Integer theID2) Standard_OVERRIDE { - return myIndices; + if (!myBVHSet1->Box (theID1).IsOut (myBVHSet2->Box (theID2))) + { + myPairs.push_back (PairIDs (myBVHSet1->Element (theID1), myBVHSet2->Element (theID2))); + return Standard_True; + } + return Standard_False; } - private: - Bnd_Box myBox; - TColStd_ListOfInteger myIndices; + + //! Returns indices + const std::vector& Pairs() const + { + return myPairs; + } + + //! Sorts the resulting indices + void Sort() + { + std::sort (myPairs.begin(), myPairs.end()); + } + +private: + + std::vector myPairs; }; //======================================================================= @@ -170,59 +222,57 @@ static const IntPolyh_ArrayOfPoints& thePoints1, IntPolyh_ArrayOfTriangles& theTriangles2, const IntPolyh_ArrayOfPoints& thePoints2, - IntPolyh_IndexedDataMapOfIntegerArrayOfInteger& theCouples) + IntPolyh_IndexedDataMapOfIntegerListOfInteger& theCouples) { - // To find the triangles with interfering bounding boxes - // use the algorithm of unbalanced binary tree of overlapping bounding boxes - IntPolyh_BoxBndTree aBBTree; - NCollection_UBTreeFiller aTreeFiller(aBBTree); - // 1. Fill the tree with the boxes of the triangles from second surface - Standard_Integer i, aNbT2 = theTriangles2.NbItems(); - Standard_Boolean bAdded = Standard_False; - for (i = 0; i < aNbT2; ++i) { - IntPolyh_Triangle& aT = theTriangles2[i]; - if (!aT.IsIntersectionPossible() || aT.IsDegenerated()) { - continue; - } - // - const Bnd_Box& aBox = aT.BoundingBox(thePoints2); - aTreeFiller.Add(i, aBox); - bAdded = Standard_True; - } - // - if (!bAdded) - // Intersection is not possible for all triangles in theTriangles2 - return; + // Use linear builder for BVH construction + opencascade::handle> aLBuilder = + new BVH_LinearBuilder (10); - // 2. Shake the tree filler - aTreeFiller.Fill(); - // - // 3. Find boxes interfering with the first triangles - Standard_Integer aNbT1 = theTriangles1.NbItems(); - for (i = 0; i < aNbT1; ++i) { - IntPolyh_Triangle& aT = theTriangles1[i]; - if (!aT.IsIntersectionPossible() || aT.IsDegenerated()) { - continue; + // To find the triangles with interfering bounding boxes + // use the BVH structure + IntPolyh_BoxBndTree aBBTree1 (aLBuilder), aBBTree2 (aLBuilder); + + // 1. Fill the trees with the boxes of the surfaces triangles + for (Standard_Integer i = 0; i < 2; ++i) + { + IntPolyh_BoxBndTree &aBBTree = !i ? aBBTree1 : aBBTree2; + IntPolyh_ArrayOfTriangles& aTriangles = !i ? theTriangles1 : theTriangles2; + const IntPolyh_ArrayOfPoints& aPoints = !i ? thePoints1 : thePoints2; + + const Standard_Integer aNbT = aTriangles.NbItems(); + aBBTree.SetSize (aNbT); + for (Standard_Integer j = 0; j < aNbT; ++j) + { + IntPolyh_Triangle& aT = aTriangles[j]; + if (!aT.IsIntersectionPossible() || aT.IsDegenerated()) + continue; + + aBBTree.Add (j, Bnd_Tools::Bnd2BVH (aT.BoundingBox(aPoints))); } - // - const Bnd_Box& aBox = aT.BoundingBox(thePoints1); - // - IntPolyh_BoxBndTreeSelector aSelector(aBox); - if (!aBBTree.Select(aSelector)) { - continue; - } - // - const TColStd_ListOfInteger& aLI = aSelector.Indices(); - // Sort the indices - IntPolyh_ArrayOfInteger anArr(1, aLI.Extent()); - TColStd_ListIteratorOfListOfInteger aItLI(aLI); - for (Standard_Integer j = 1; aItLI.More(); aItLI.Next(), ++j) { - anArr(j) = aItLI.Value(); - } - // - std::sort(anArr.begin(), anArr.end()); - // - theCouples.Add(i, anArr); + + if (!aBBTree.Size()) + return; + } + // 2. Construct BVH trees + aBBTree1.Build(); + aBBTree2.Build(); + + // 3. Perform selection of the interfering triangles + IntPolyh_BoxBndTreeSelector aSelector; + aSelector.SetBVHSets (&aBBTree1, &aBBTree2); + aSelector.Select(); + aSelector.Sort(); + + const std::vector& aPairs = aSelector.Pairs(); + const Standard_Integer aNbPairs = static_cast(aPairs.size()); + + for (Standard_Integer i = 0; i < aNbPairs; ++i) + { + const IntPolyh_BoxBndTreeSelector::PairIDs& aPair = aPairs[i]; + TColStd_ListOfInteger* pTriangles2 = theCouples.ChangeSeek (aPair.ID1); + if (!pTriangles2) + pTriangles2 = &theCouples( theCouples.Add (aPair.ID1, TColStd_ListOfInteger())); + pTriangles2->Append (aPair.ID2); } } @@ -921,7 +971,7 @@ static const Standard_Real theFlecheCritique2) { // Find the intersecting triangles - IntPolyh_IndexedDataMapOfIntegerArrayOfInteger aDMILI; + IntPolyh_IndexedDataMapOfIntegerListOfInteger aDMILI; GetInterferingTriangles(theTriangles1, thePoints1, theTriangles2, thePoints2, aDMILI); // // Interfering triangles of second surface @@ -938,8 +988,8 @@ static continue; } // - const IntPolyh_ArrayOfInteger *pLI = aDMILI.Seek(i_S1); - if (!pLI || !pLI->Length()) { + const TColStd_ListOfInteger *pLI = aDMILI.Seek(i_S1); + if (!pLI || pLI->IsEmpty()) { // Mark non-interfering triangles of S1 to avoid their repeated usage aTriangle1.SetIntersectionPossible(Standard_False); continue; @@ -949,7 +999,7 @@ static aTriangle1.MiddleRefinement(i_S1, theS1, thePoints1, theTriangles1, theEdges1); } // - IntPolyh_ArrayOfInteger::Iterator Iter(*pLI); + TColStd_ListOfInteger::Iterator Iter(*pLI); for (; Iter.More(); Iter.Next()) { Standard_Integer i_S2 = Iter.Value(); if (aMIntS2.Add(i_S2)) { @@ -2295,7 +2345,7 @@ Standard_Integer IntPolyh_MaillageAffinage::TriangleEdgeContact Standard_Integer IntPolyh_MaillageAffinage::TriangleCompare () { // Find couples with interfering bounding boxes - IntPolyh_IndexedDataMapOfIntegerArrayOfInteger aDMILI; + IntPolyh_IndexedDataMapOfIntegerListOfInteger aDMILI; GetInterferingTriangles(TTriangles1, TPoints1, TTriangles2, TPoints2, aDMILI); @@ -2314,8 +2364,8 @@ Standard_Integer IntPolyh_MaillageAffinage::TriangleCompare () const IntPolyh_Point& P2 = TPoints1[Triangle1.SecondPoint()]; const IntPolyh_Point& P3 = TPoints1[Triangle1.ThirdPoint()]; // - const IntPolyh_ArrayOfInteger& aLI2 = aDMILI(i); - IntPolyh_ArrayOfInteger::Iterator aItLI(aLI2); + const TColStd_ListOfInteger& aLI2 = aDMILI(i); + TColStd_ListOfInteger::Iterator aItLI(aLI2); for (; aItLI.More(); aItLI.Next()) { const Standard_Integer i_S2 = aItLI.Value(); IntPolyh_Triangle &Triangle2 = TTriangles2[i_S2];