0025788: Parallelization of the BOP Builder algorithm on second level
authorpkv <pkv@opencascade.com>
Thu, 12 Feb 2015 08:57:15 +0000 (11:57 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 12 Feb 2015 08:58:02 +0000 (11:58 +0300)
Changes:
class BOPAlgo_Builder
method:
  void BOPAlgo_Builder::FillIn3DParts
  (BOPCol_DataMapOfShapeListOfShape&,
   BOPCol_DataMapOfShapeShape&,
   const BOPCol_BaseAllocator& )
has been optimized and
modified to provide parallel treatment.

Correction of compilation errors

Test cases for issue CR25788

src/BOPAlgo/BOPAlgo_BuilderSolid.cxx
src/BOPAlgo/BOPAlgo_Builder_3.cxx
src/BOPAlgo/BOPAlgo_ShellSplitter.cxx
src/BOPTools/BOPTools.cxx
tests/bugs/modalg_5/bug25788 [new file with mode: 0644]

index fbeb55f..89bb2be 100644 (file)
@@ -20,6 +20,7 @@
 #include <NCollection_List.hxx>
 #include <NCollection_DataMap.hxx>
 #include <NCollection_UBTreeFiller.hxx>
+#include <NCollection_IncAllocator.hxx>
 //
 #include <gp_Pnt2d.hxx>
 #include <gp_Pln.hxx>
@@ -73,6 +74,7 @@
 //
 #include <BOPAlgo_ShellSplitter.hxx>
 
+
 static
   Standard_Boolean IsGrowthShell(const TopoDS_Shape& ,
                                  const BOPCol_IndexedMapOfShape& );
@@ -450,11 +452,14 @@ void BOPAlgo_BuilderSolid::PerformLoops()
   BOPCol_ListIteratorOfListOfShape aIt;
   TopoDS_Iterator aItS;
   BOPCol_MapIteratorOfMapOfOrientedShape aItM;
-  BOPAlgo_ShellSplitter aSSp;
+  Handle(NCollection_BaseAllocator) aAlr;
   // 
   myErrorStatus=0;
   myLoops.Clear();
   //
+  aAlr=new NCollection_IncAllocator();
+  BOPAlgo_ShellSplitter aSSp(aAlr);
+  //
   // 1. Shells Usual
   aIt.Initialize (myShapes);
   for (; aIt.More(); aIt.Next()) {
@@ -535,17 +540,18 @@ void BOPAlgo_BuilderSolid::PerformLoops()
     }
     //
     // make a new shell
+    TopExp_Explorer aExp;
     TopoDS_Shell aShell;
     aBB.MakeShell(aShell);
     aBB.Add(aShell, aFF);
     //
-    TopoDS_Iterator aItAddedF (aShell);
-    for (; aItAddedF.More(); aItAddedF.Next()) {
-      const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value()));
+    aItS.Initialize(aShell);
+    for (; aItS.More(); aItS.Next()) {
+      const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItS.Value()));
       //
-      TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
-      for (; aEdgeExp.More(); aEdgeExp.Next()) {
-        const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
+      aExp.Init(aF, TopAbs_EDGE);
+      for (; aExp.More(); aExp.Next()) {
+        const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current()));
         const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
         aIt.Initialize(aLF);
         for (; aIt.More(); aIt.Next()) { 
index 6b2605e..6bd36a4 100644 (file)
@@ -68,6 +68,7 @@
 #include <NCollection_Array1.hxx>
 
 #include <algorithm>
+#include <BOPAlgo_Algo.hxx>
 
 static
   void OwnInternalShapes(const TopoDS_Shape& ,
@@ -93,6 +94,9 @@ typedef BOPCol_Cnt
   BOPAlgo_VectorOfBuilderSolid> BOPAlgo_BuilderSolidCnt;
 //
 //=======================================================================
+// class:  BOPAlgo_ShapeBox
+//
+//=======================================================================
 //class     : BOPAlgo_ShapeBox
 //purpose   : Auxiliary class
 //=======================================================================
@@ -125,15 +129,371 @@ class BOPAlgo_ShapeBox {
   Bnd_Box myBox;
 };
 //
-typedef NCollection_DataMap
-  <Standard_Integer,
-  BOPAlgo_ShapeBox, 
-  TColStd_MapIntegerHasher> BOPAlgo_DataMapOfIntegerShapeBox; 
+typedef BOPCol_NCVector<BOPAlgo_ShapeBox> BOPAlgo_VectorOfShapeBox;
+//
+//=======================================================================
+// class:  BOPAlgo_FillIn3DParts
 //
-typedef BOPAlgo_DataMapOfIntegerShapeBox::Iterator 
-  BOPAlgo_DataMapIteratorOfDataMapOfIntegerShapeBox; 
-// 
+//=======================================================================
+//class : BOPAlgo_FillIn3DParts
+//purpose  : 
+//=======================================================================
+class BOPAlgo_FillIn3DParts : public BOPAlgo_Algo  {
+ public:
+  DEFINE_STANDARD_ALLOC
+  
+  BOPAlgo_FillIn3DParts(){
+    myHasImage=Standard_False;
+    myBBTree=NULL;
+    myVSB=NULL;
+  };
+  //
+  virtual ~BOPAlgo_FillIn3DParts(){
+  };
+  //
+  void SetSolid(const TopoDS_Solid& aS) {
+    mySolid=aS;
+  };
+  //
+  const TopoDS_Solid& Solid()const {
+    return mySolid;
+  };
+  //
+  void SetDraftSolid(const TopoDS_Solid& aS) {
+    myDraftSolid=aS;
+  };
+  //
+  const TopoDS_Solid& DraftSolid()const {
+    return myDraftSolid;
+  };
+  //
+  void SetHasImage(const Standard_Boolean bFlag) {
+    myHasImage=bFlag;
+  };
+  //
+  Standard_Boolean HasImage()const {
+    return myHasImage;
+  };
+  //
+  void SetBoxS(const Bnd_Box& aBox) {
+    myBoxS=aBox;
+  };
+  //
+  const Bnd_Box& BoxS()const {
+    return myBoxS;
+  };
+  //
+  void SetLIF(const BOPCol_ListOfShape& aLIF) {
+    myLIF=aLIF;
+  };
+  //
+  const BOPCol_ListOfShape& LIF()const {
+    return myLIF;
+  };
+  //
+  void SetBBTree(const BOPCol_BoxBndTree& aBBTree) {
+    myBBTree=(BOPCol_BoxBndTree*)&aBBTree;
+  };
+  //
+  void SetVSB(const BOPAlgo_VectorOfShapeBox& aVSB) {
+    myVSB=(BOPAlgo_VectorOfShapeBox*)&aVSB;
+  };
+  //
+  //
+  void SetContext(const Handle(IntTools_Context)& aContext) {
+    myContext=aContext;
+  }
+  //
+  const Handle(IntTools_Context)& Context()const {
+    return myContext;
+  }
+  //
+  virtual void Perform();
+  //
+  
+  //
+  const BOPCol_ListOfShape& LFIN()const {
+    return myLFIN;
+  };
+  
+ protected:
+  void MapEdgesAndFaces
+    (const TopoDS_Shape& ,
+     BOPCol_IndexedDataMapOfShapeListOfShape& ,
+     const Handle(NCollection_BaseAllocator)& );
+  
+  void MakeConnexityBlock 
+    (const BOPCol_ListOfShape& ,
+     const BOPCol_IndexedMapOfShape& ,
+     const BOPCol_MapOfShape& , 
+     const BOPCol_IndexedDataMapOfShapeListOfShape& ,
+     BOPCol_ListOfShape& ,
+     const Handle(NCollection_BaseAllocator)& );
+  //
+ protected:
+  TopoDS_Solid mySolid;
+  TopoDS_Solid myDraftSolid;
+  Standard_Boolean myHasImage;
+  Bnd_Box myBoxS;
+  BOPCol_ListOfShape myLIF;
+  BOPCol_ListOfShape myLFIN;
+  //
+  BOPCol_BoxBndTree* myBBTree;
+  BOPAlgo_VectorOfShapeBox* myVSB;
+  //
+  TopoDS_Iterator myItF;
+  TopoDS_Iterator myItW;
+  
+  Handle(IntTools_Context) myContext;
+};
 
+//=======================================================================
+//function : BOPAlgo_FillIn3DParts::Perform
+//purpose  : 
+//=======================================================================
+void BOPAlgo_FillIn3DParts::Perform() 
+{
+  Handle(NCollection_IncAllocator) aAlr1;
+  BOPAlgo_Algo::UserBreak();
+  //  
+  Standard_Integer aNbFP, k, nFP, iIsIN;
+  Standard_Real aTolPC;
+  BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1;
+  BOPCol_ListIteratorOfListOfShape aItLS;
+  BOPCol_BoxBndTreeSelector aSelector; 
+  //
+  aAlr1=new NCollection_IncAllocator();
+  //
+  BOPCol_ListOfShape aLFP(aAlr1);
+  BOPCol_ListOfShape aLCBF(aAlr1);
+  BOPCol_MapOfShape aMFDone(100, aAlr1);
+  BOPCol_IndexedMapOfShape aME(100, aAlr1);
+  BOPCol_IndexedMapOfShape aMF(100, aAlr1);
+  BOPCol_IndexedDataMapOfShapeListOfShape aMEFP(100, aAlr1);
+  BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, aAlr1);
+  //
+  aTolPC=Precision::Confusion();
+  myLFIN.Clear();
+  BOPAlgo_VectorOfShapeBox& aVSB=*myVSB;
+  //
+  // 1. aMEF - EF map for myDraftSolid
+  BOPTools::MapShapesAndAncestors(myDraftSolid, 
+                                  TopAbs_EDGE, 
+                                  TopAbs_FACE, 
+                                  aMEF); 
+  
+  //
+  // 2. Faces from myDraftSolid and its own internal faces => aMF 
+  BOPTools::MapShapes(myDraftSolid, TopAbs_FACE, aMF);
+  aItLS.Initialize(myLIF);
+  for (; aItLS.More(); aItLS.Next()) {
+    const TopoDS_Shape& aFI=aItLS.Value();
+    aMF.Add(aFI);
+  }
+  // aME - Edges from DraftSolid [i.e. edges to stop]
+  BOPTools::MapShapes(myDraftSolid, TopAbs_EDGE, aME);
+  //
+  // 3. Select boxes of faces that are not out of aBoxS
+  aSelector.Clear();
+  aSelector.SetBox(myBoxS);
+  //
+  aNbFP=myBBTree->Select(aSelector);
+  const BOPCol_ListOfInteger& aLIFPx=aSelector.Indices();
+  //
+  // 4. aIVec, aLIFP -  faces to process
+  BOPCol_ListOfInteger aLIFP(aAlr1); 
+  BOPCol_NCVector<Standard_Integer> aIVec(256, aAlr1);
+  //
+  k=0;
+  aItLI.Initialize(aLIFPx);
+  for (; aItLI.More(); aItLI.Next()) {
+    nFP=aItLI.Value();
+    const TopoDS_Shape& aFP=aVSB(nFP).Shape();
+    if (!aMF.Contains(aFP)) {
+      MapEdgesAndFaces(aFP, aMEFP, aAlr1);
+      aLIFP.Append(nFP);
+      aIVec.Append1()=nFP;
+      ++k;
+    }
+  }
+  aNbFP=k;
+  //
+  // sort indices
+  std::sort(aIVec.begin(), aIVec.end());
+  //
+  // 5. Collect faces that are IN mySolid [ myLFIN ]
+  for (k=0; k<aNbFP; ++k) {
+    nFP = aIVec(k);
+    const BOPAlgo_ShapeBox& aSBF=aVSB(nFP);
+    const TopoDS_Face& aFP=(*(TopoDS_Face*)&aSBF.Shape());
+    //
+    if (!aMFDone.Add(aFP)) {
+      continue;
+    }
+    //
+    iIsIN=BOPTools_AlgoTools::IsInternalFace
+      (aFP, myDraftSolid, aMEF, aTolPC, myContext);
+    //
+    aLFP.Clear();
+    aLFP.Append(aFP);
+    //
+    aItLI1.Initialize(aLIFP);
+    for (; aItLI1.More(); aItLI1.Next()) {
+      const TopoDS_Shape& aFx=aVSB(aItLI1.Value()).Shape();
+      if (!aMFDone.Contains(aFx)) {
+        aLFP.Append(aFx);
+      }
+    }
+    //
+    aLCBF.Clear();
+    //
+    MakeConnexityBlock(aLFP, aME, aMFDone, aMEFP, aLCBF, aAlr1);
+    //
+    aItLS.Initialize(aLCBF);
+    for (; aItLS.More(); aItLS.Next()) {
+      const TopoDS_Shape& aFx=aItLS.Value();
+      aMFDone.Add(aFx);
+      if (iIsIN) {
+        myLFIN.Append(aFx);
+      }
+    }
+  } // for (k=0; k<aNbFP; ++k) {
+};
+//=======================================================================
+// function: MapEdgesAndFaces
+// purpose: 
+//=======================================================================
+void BOPAlgo_FillIn3DParts::MapEdgesAndFaces
+  (const TopoDS_Shape& aF,
+   BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
+   const Handle(NCollection_BaseAllocator)& theAllocator)
+{
+  myItF.Initialize(aF);
+  for (; myItF.More(); myItF.Next()) {
+    const TopoDS_Shape& aW=myItF.Value();
+    if (aW.ShapeType()!=TopAbs_WIRE) {
+      continue;
+    }
+    //
+    myItW.Initialize(aW);
+    for (; myItW.More(); myItW.Next()) {
+      const TopoDS_Shape& aE=myItW.Value();
+      //
+      if (aMEF.Contains(aE)) {
+        BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
+        aLF.Append(aF);
+      }
+      else {
+        BOPCol_ListOfShape aLS(theAllocator);
+        //
+        aLS.Append(aF);
+        aMEF.Add(aE, aLS);
+      } 
+    }
+  }
+}
+//=======================================================================
+// function: MakeConnexityBlock
+// purpose: 
+//=======================================================================
+void BOPAlgo_FillIn3DParts::MakeConnexityBlock 
+  (const BOPCol_ListOfShape& theLFIn,
+   const BOPCol_IndexedMapOfShape& theMEAvoid,
+   const BOPCol_MapOfShape& aMFDone, 
+   const BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
+   BOPCol_ListOfShape& theLCB,
+   const Handle(NCollection_BaseAllocator)& theAlr)
+{
+  Standard_Integer  aNbF, aNbAdd1, aNbAdd, i;
+  BOPCol_ListIteratorOfListOfShape aIt;
+  //
+  BOPCol_IndexedMapOfShape aMCB(100, theAlr);
+  BOPCol_IndexedMapOfShape aMAdd(100, theAlr);
+  BOPCol_IndexedMapOfShape aMAdd1(100, theAlr);
+  //
+  aNbF=theLFIn.Extent();
+  //
+  // 2. aMCB
+  const TopoDS_Shape& aF1=theLFIn.First();
+  aMAdd.Add(aF1);
+  //
+  for(;;) {
+    aMAdd1.Clear();
+    aNbAdd = aMAdd.Extent();
+    for (i=1; i<=aNbAdd; ++i) {
+      const TopoDS_Shape& aF=aMAdd(i);
+      //
+      myItF.Initialize(aF);
+      for (; myItF.More(); myItF.Next()) {
+        const TopoDS_Shape& aW=myItF.Value();
+        if (aW.ShapeType()!=TopAbs_WIRE) {
+          continue;
+        }
+        //
+        myItW.Initialize(aW);
+        for (; myItW.More(); myItW.Next()) {
+          const TopoDS_Shape& aE=myItW.Value();
+          if (theMEAvoid.Contains(aE)){
+            continue;
+          }
+          //
+          const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
+          aIt.Initialize(aLF);
+          for (; aIt.More(); aIt.Next()) {
+            const TopoDS_Shape& aFx=aIt.Value();
+            if (aFx.IsSame(aF)) {
+              continue;
+            }
+            if (aMCB.Contains(aFx)) {
+              continue;
+            }
+            if (aMFDone.Contains(aFx)) {
+              continue;
+            }
+            aMAdd1.Add(aFx);
+          }
+        }// for (; myItW.More(); myItW.Next()) {
+      }// for (; myItF.More(); myItF.Next()) {
+      aMCB.Add(aF);
+    }// for (i=1; i<=aNbAdd; ++i) {
+    //
+    aNbAdd1=aMAdd1.Extent();
+    if (!aNbAdd1) {
+      break;
+    }
+    //
+    aMAdd.Clear();
+    for (i=1; i<=aNbAdd1; ++i) {
+      const TopoDS_Shape& aFAdd=aMAdd1(i);
+      aMAdd.Add(aFAdd);
+    }
+    //
+  }//while(1) {
+  //
+  aNbF=aMCB.Extent();
+  for (i=1; i<=aNbF; ++i) {
+    const TopoDS_Shape& aF=aMCB(i);
+    theLCB.Append(aF);
+  }
+}
+//
+typedef BOPCol_NCVector<BOPAlgo_FillIn3DParts> \
+  BOPAlgo_VectorOfFillIn3DParts;
+//
+typedef BOPCol_ContextFunctor 
+  <BOPAlgo_FillIn3DParts,
+  BOPAlgo_VectorOfFillIn3DParts,
+  Handle(IntTools_Context), 
+  IntTools_Context> BOPCol_FillIn3DPartsFunctor;
+//
+typedef BOPCol_ContextCnt 
+  <BOPCol_FillIn3DPartsFunctor,
+  BOPAlgo_VectorOfFillIn3DParts,
+  Handle(IntTools_Context)> BOPAlgo_FillIn3DPartsCnt;
+//
+//=======================================================================
+// class:  BOPAlgo_Builder
+//
 //=======================================================================
 //function : FillImagesSolids
 //purpose  : 
@@ -182,24 +542,24 @@ void BOPAlgo_Builder::FillIn3DParts
    const BOPCol_BaseAllocator& )
 {
   Standard_Boolean bHasImage;
-  Standard_Integer i, k, aNbS, aNbLIF, nFP, aNbFP, aNbFIN, iIsIN;
+  Standard_Integer i, k, aNbS, aNbLIF, aNbFIN, aNbVSB, aNbVFIP;
+  Handle(NCollection_IncAllocator) aAlr0;
   TopoDS_Solid aSD;
   TopoDS_Iterator aIt;
   BRep_Builder aBB; 
+  //
   BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1;
   BOPCol_ListIteratorOfListOfShape aItLS;
-  BOPAlgo_ShapeBox aSB;
-  Handle(NCollection_IncAllocator) aAlr0;
   //
   aAlr0=new NCollection_IncAllocator();
-  BOPAlgo_DataMapOfIntegerShapeBox aDMISB(100, aAlr0);
-  BOPAlgo_DataMapIteratorOfDataMapOfIntegerShapeBox aItDMISB;
+  //
+  BOPCol_MapOfShape aMFence(100, aAlr0);
+  BOPAlgo_VectorOfShapeBox aVSB(256, aAlr0);
   //
   myErrorStatus=0;
   theDraftSolids.Clear();
   //
-  // 1. aDMISB map Index/FaceBox 
-  k=0;
+  // 1. aVSB vector Index/FaceBox 
   aNbS=myDS->NbSourceShapes();
   for (i=0; i<aNbS; ++i) {
     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
@@ -214,36 +574,35 @@ void BOPAlgo_Builder::FillIn3DParts
       aItLS.Initialize(aLS);
       for (; aItLS.More(); aItLS.Next()) {
         const TopoDS_Shape& aSx=aItLS.Value();
-        //
+        if (!aMFence.Add(aSx)) {
+          continue;
+        }
         Bnd_Box aBox;
         BRepBndLib::Add(aSx, aBox);
         //
+        BOPAlgo_ShapeBox& aSB=aVSB.Append1();
         aSB.SetShape(aSx);
         aSB.SetBox(aBox);
-        //
-        aDMISB.Bind(k, aSB);
-        ++k;
       }
     }
     else {
       const Bnd_Box& aBox=aSI.Box();
       //
+      BOPAlgo_ShapeBox& aSB=aVSB.Append1();
       aSB.SetShape(aS);
       aSB.SetBox(aBox);
-      //
-      aDMISB.Bind(k, aSB);
-      ++k;
     }
   }//for (i=0; i<aNbS; ++i) {
+  aMFence.Clear();
   //
   // 1.2. Prepare TreeFiller
   BOPCol_BoxBndTree aBBTree;
-  NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
+  NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> 
+    aTreeFiller(aBBTree);
   //
-  aItDMISB.Initialize(aDMISB);
-  for (; aItDMISB.More(); aItDMISB.Next()) {
-    k=aItDMISB.Key();
-    const BOPAlgo_ShapeBox& aSBk=aItDMISB.Value();
+  aNbVSB=aVSB.Extent();
+  for (k=0; k<aNbVSB; ++k) {
+    const BOPAlgo_ShapeBox& aSBk=aVSB(k);
     const Bnd_Box& aBk=aSBk.Box();
     //
     aTreeFiller.Add(k, aBk);
@@ -254,24 +613,13 @@ void BOPAlgo_Builder::FillIn3DParts
   //
   //---------------------------------------------
   // 2. Solids
+  BOPAlgo_VectorOfFillIn3DParts aVFIP;
+  //
   for (i=0; i<aNbS; ++i) {
     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
     if (aSI.ShapeType()!=TopAbs_SOLID) {
       continue;
     }
-    // 
-    UserBreak();
-    //---------------------------------------------
-    Handle(NCollection_IncAllocator) aAlr1;
-    //
-    aAlr1=new NCollection_IncAllocator();
-    //
-    BOPCol_ListOfShape aLFIN(aAlr1);
-    BOPCol_ListOfShape aLIF(aAlr1);
-    BOPCol_IndexedMapOfShape aMF(100, aAlr1);
-    BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, aAlr1);
-    BOPCol_BoxBndTreeSelector aSelector;
-    Bnd_Box aBoxS;
     //
     const TopoDS_Shape& aS=aSI.Shape();
     const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
@@ -288,113 +636,62 @@ void BOPAlgo_Builder::FillIn3DParts
     }
     //
     // 2.1 Bounding box for the solid aS  [ aBoxS ]
+    Bnd_Box aBoxS;
     aBoxS=aSI.Box();
-    //-----
     //
     // 2.2 Build Draft Solid [aSD]
-    aBB.MakeSolid(aSD);
+    BOPCol_ListOfShape aLIF;
     //
+    aBB.MakeSolid(aSD);
     BuildDraftSolid(aSolid, aSD, aLIF);
-    aNbLIF=aLIF.Extent();
-    //
-    BOPTools::MapShapesAndAncestors(aSD, TopAbs_EDGE, TopAbs_FACE, aMEF);
-    //
-    // 2.3 Faces from aSD and own internal faces => aMF 
-    BOPTools::MapShapes(aSD, TopAbs_FACE, aMF);
     //
-    aItLS.Initialize(aLIF);
-    for (; aItLS.More(); aItLS.Next()) {
-      const TopoDS_Shape& aFI=aItLS.Value();
-      aMF.Add(aFI);
-    }
-    //
-    // 2.4. Select boxes of faces that are not out of aBoxS
-    aSelector.Clear();
-    aSelector.SetBox(aBoxS);
-    //
-    aNbFP=aBBTree.Select(aSelector);
-    //
-    const BOPCol_ListOfInteger& aLIFP=aSelector.Indices();
-    //sort indices
-    NCollection_Array1<Standard_Integer> aIVec(1, aNbFP);
-    aItLI.Initialize(aLIFP);
-    for (k = 1; aItLI.More(); aItLI.Next(), ++k) {
-      nFP=aItLI.Value();
-      aIVec(k) = nFP;
-    }
-    std::sort(aIVec.begin(), aIVec.end());
+    BOPAlgo_FillIn3DParts& aFIP=aVFIP.Append1();
     //
-    // 2.5. Collect faces that are IN aSolid [ aLFIN ]
-    BOPCol_ListOfShape aLFP(aAlr1);
-    BOPCol_ListOfShape aLCBF(aAlr1);
-    BOPCol_MapOfShape aMFDone(100, aAlr1);
-    BOPCol_IndexedMapOfShape aME(100, aAlr1);
+    aFIP.SetSolid(aSolid);
+    aFIP.SetDraftSolid(aSD);
+    aFIP.SetHasImage(bHasImage);
+    aFIP.SetBoxS(aBoxS);
+    aFIP.SetLIF(aLIF);
+    aFIP.SetBBTree(aBBTree);
+    aFIP.SetVSB(aVSB);
+  }//for (i=0; i<aNbS; ++i) {
+  //
+  aNbVFIP=aVFIP.Extent();
+  //================================================================
+  BOPAlgo_FillIn3DPartsCnt::Perform(myRunParallel, aVFIP, myContext);
+  //================================================================
+  for (k=0; k<aNbVFIP; ++k) {
+    BOPAlgo_FillIn3DParts& aFIP=aVFIP(k);
+    bHasImage=aFIP.HasImage();
+    const TopoDS_Solid& aSolid=aFIP.Solid();
+    const TopoDS_Solid& aSD=aFIP.DraftSolid();
+    const BOPCol_ListOfShape& aLFIN=aFIP.LFIN();
+    const BOPCol_ListOfShape& aLIF=aFIP.LIF();
     //
-    BOPTools::MapShapes(aSD, TopAbs_EDGE, aME);
+    aNbLIF=aLIF.Extent();
     //
-    for (k = 1; k <= aNbFP; ++k) {
-      nFP = aIVec(k);
-      const BOPAlgo_ShapeBox& aSBF=aDMISB.Find(nFP);
-      const TopoDS_Face& aFP=(*(TopoDS_Face*)&aSBF.Shape());
-      if (aMF.Contains(aFP)) {
-        continue;
-      }
-      if (aMFDone.Contains(aFP)) {
-        continue;
-      }
-      //
-      aMFDone.Add(aFP);
-      //
-      iIsIN=BOPTools_AlgoTools::IsInternalFace(aFP, aSD, aMEF,
-                                               Precision::Confusion(),
-                                               myContext);
-      //
-      aLFP.Clear();
-      aLFP.Append(aFP);
-      //
-      aItLI1.Initialize(aLIFP);
-      for (; aItLI1.More(); aItLI1.Next()) {
-        const TopoDS_Shape& aFx=aDMISB.Find(aItLI1.Value()).Shape();
-        if (!aMFDone.Contains(aFx)) {
-          aLFP.Append(aFx);
-        }
-      }
-      //
-      aLCBF.Clear();
-      //---------------------------------------- 
-      {
-        Handle(NCollection_IncAllocator) aAlr2;
-        aAlr2=new NCollection_IncAllocator();
-        //
-        BOPTools_AlgoTools::MakeConnexityBlock(aLFP, aME, aLCBF, aAlr2);
-      }
-      //----------------------------------------
-      aItLS.Initialize(aLCBF);
-      for (; aItLS.More(); aItLS.Next()) {
-        const TopoDS_Shape& aFx=aItLS.Value();
-        aMFDone.Add(aFx);
-        if (iIsIN) {
-          aLFIN.Append(aFx);
-        }
-      }
-    }// for (; aItLI.More(); aItLI.Next()) {
+    // Store the results in theInParts, theDraftSolids
+    BOPCol_ListOfShape aLFINx;
     //
-    // 2.6. Store the results in theInParts, theDraftSolids
     aNbFIN=aLFIN.Extent();
     if (aNbFIN || aNbLIF) {
+      aItLS.Initialize(aLFIN);
+      for (; aItLS.More(); aItLS.Next()) {
+        const TopoDS_Shape& aFI=aItLS.Value();
+        aLFINx.Append(aFI);
+      }
       aItLS.Initialize(aLIF);
       for (; aItLS.More(); aItLS.Next()) {
         const TopoDS_Shape& aFI=aItLS.Value();
-        aLFIN.Append(aFI);
+        aLFINx.Append(aFI);
       }
-      theInParts.Bind(aSolid, aLFIN);
+      theInParts.Bind(aSolid, aLFINx);
     }
     //
     if (aNbFIN || bHasImage) {
       theDraftSolids.Bind(aSolid, aSD);
     }
-    //---------------------------------------------
-  }// for (i=0; i<aNbS; ++i) {
+  }
 }
 //=======================================================================
 //function : BuildDraftSolid
@@ -798,7 +1095,8 @@ void BOPAlgo_Builder::FillInternalShapes()
       TopoDS_Shape aSI=aItM.Key();
       aSI.Orientation(TopAbs_INTERNAL);
       //
-      aState=BOPTools_AlgoTools::ComputeStateByOnePoint(aSI, aSd, 1.e-11, myContext);
+      aState=BOPTools_AlgoTools::ComputeStateByOnePoint
+        (aSI, aSd, 1.e-11, myContext);
       if (aState==TopAbs_IN) {
         //
         if(aMSOr.Contains(aSd)) {
@@ -888,8 +1186,7 @@ void TreatCompound(const TopoDS_Shape& theS,
     TreatCompound(aS, aMFence, theLS);
   }
 }
-
 //
 // ErrorStatus
 // 30 - SolidBuilder failed
-// A
+
index 5c78dec..9b35a30 100644 (file)
@@ -14,7 +14,6 @@
 
 // File: BOPAlgo_ShellSplitter.cxx
 // Created: Thu Jan 16 08:33:50 2014
-// <pkv@PETREX>
 
 #include <BOPAlgo_ShellSplitter.ixx>
 //
@@ -45,6 +44,12 @@ static
 //
 static
   void RefineShell(TopoDS_Shell& theShell);
+//
+static
+  void MapEdgesAndFaces
+  (const TopoDS_Shape& aF,
+   BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
+   const Handle(NCollection_BaseAllocator)& theAllocator);
 
 //=======================================================================
 //class    : BOPAlgo_CBK
@@ -165,7 +170,7 @@ void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
   Standard_Boolean bRegular;
   Standard_Integer i, j, aNbE, aNbES, aNbEP, k, aNbCB;
   TopoDS_Shape aFR;
-  TopExp_Explorer aExpF;
+  TopoDS_Iterator aItF, aItW;
   BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, myAllocator);
   BOPCol_IndexedMapOfShape aMEP(100, myAllocator);
   BOPCol_IndexedMapOfShape aMFC(100, myAllocator);
@@ -185,10 +190,7 @@ void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
     const TopoDS_Shape& aSE=aIt.Value();
     if (!aMEP.Contains(aSE)) {
       aMEP.Add(aSE);
-      BOPTools::MapShapesAndAncestors(aSE, 
-                                      TopAbs_EDGE, 
-                                      TopAbs_FACE, 
-                                      aMEF);
+      MapEdgesAndFaces(aSE, aMEF, myAllocator);
     }
     else {
       aMER.Add(aSE);
@@ -226,12 +228,26 @@ void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
         for (; aIt.More(); aIt.Next()) {
           const TopoDS_Shape& aF=aIt.Value();
           if (aMFC.Add(aF)) {
-            aExpF.Init(aF, TopAbs_EDGE);
-            for (; aExpF.More(); aExpF.Next()) {
-              const TopoDS_Shape& aEF=aExpF.Current();
-              if (aMES.Add(aEF)) {
-                aMEAdd.Add(aEF);
+            aItF.Initialize(aF);
+            while (aItF.More()) {
+              const TopoDS_Shape& aW=aItF.Value();  
+              if (aW.ShapeType()!=TopAbs_WIRE) {
+                aItF.Next();
+                continue;
+              }
+              //
+              aItW.Initialize(aW);
+              while (aItW.More()) {
+                const TopoDS_Shape& aEF=aItW.Value();  
+                //
+                if (aMES.Add(aEF)) {
+                  aMEAdd.Add(aEF);
+                }
+                //
+                aItW.Next();
               }
+              //
+              aItF.Next();
             }
           }
         }
@@ -274,10 +290,7 @@ void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
       }
       //
       if (bRegular) {
-        BOPTools::MapShapesAndAncestors(aFR,
-                                        TopAbs_EDGE, 
-                                        TopAbs_FACE, 
-                                        aMEFR);
+        MapEdgesAndFaces(aFR, aMEFR, myAllocator);
       }
     }
     //
@@ -555,7 +568,6 @@ void RefineShell(TopoDS_Shell& theShell)
     aBB.Remove(theShell, aFB);
   }
 }
-
 //=======================================================================
 //function : MakeShells
 //purpose  : 
@@ -623,3 +635,43 @@ void MakeShell(const BOPCol_ListOfShape& aLS,
     aBB.Add(aShell, aF);
   }
 }
+//=======================================================================
+// function: MapEdgesAndFaces
+// purpose: 
+//=======================================================================
+void MapEdgesAndFaces
+  (const TopoDS_Shape& aF,
+   BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
+   const Handle(NCollection_BaseAllocator)& theAllocator)
+{
+  TopoDS_Iterator aItF, aItW;
+  //
+  aItF.Initialize(aF);
+  while (aItF.More()) {
+    const TopoDS_Shape& aW=aItF.Value();  
+    if (aW.ShapeType()!=TopAbs_WIRE) {
+      aItF.Next();
+      continue;
+    }
+    //
+    aItW.Initialize(aW);
+    while (aItW.More()) {
+      const TopoDS_Shape& aE=aItW.Value();  
+      //
+      if (aMEF.Contains(aE)) {
+        BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
+        aLF.Append(aF);
+      }
+      else {
+        BOPCol_ListOfShape aLS(theAllocator);
+        //
+        aLS.Append(aF);
+        aMEF.Add(aE, aLS);
+      }
+      //
+      aItW.Next();
+    }
+    //
+    aItF.Next();
+  }
+}
index bea05ef..333cea1 100644 (file)
@@ -20,8 +20,8 @@
 //function : MapShapes
 //purpose  : 
 //=======================================================================
-  void BOPTools::MapShapes(const TopoDS_Shape& S,
-                           BOPCol_MapOfShape& M)
+void BOPTools::MapShapes(const TopoDS_Shape& S,
+                         BOPCol_MapOfShape& M)
 {
   M.Add(S);
   TopoDS_Iterator It(S);
@@ -36,8 +36,8 @@
 //function : MapShapes
 //purpose  : 
 //=======================================================================
-  void BOPTools::MapShapes(const TopoDS_Shape& S,
-                           BOPCol_IndexedMapOfShape& M)
+void BOPTools::MapShapes(const TopoDS_Shape& S,
+                         BOPCol_IndexedMapOfShape& M)
 {
   M.Add(S);
   TopoDS_Iterator It(S);
@@ -51,9 +51,9 @@
 //function : MapShapes
 //purpose  : 
 //=======================================================================
-  void BOPTools::MapShapes(const TopoDS_Shape& S,
-                           const TopAbs_ShapeEnum T,
-                           BOPCol_IndexedMapOfShape& M)
+void BOPTools::MapShapes(const TopoDS_Shape& S,
+                         const TopAbs_ShapeEnum T,
+                         BOPCol_IndexedMapOfShape& M)
 {
   TopExp_Explorer Ex(S,T);
   while (Ex.More()) {
     Ex.Next();
   }
 }
-
-
-
 //=======================================================================
 //function : MapShapesAndAncestors
 //purpose  : 
 //=======================================================================
-  void BOPTools::MapShapesAndAncestors(const TopoDS_Shape& S, 
-                                       const TopAbs_ShapeEnum TS, 
-                                       const TopAbs_ShapeEnum TA, 
-                                       BOPCol_IndexedDataMapOfShapeListOfShape& M)
+void BOPTools::MapShapesAndAncestors
+  (const TopoDS_Shape& S, 
+   const TopAbs_ShapeEnum TS, 
+   const TopAbs_ShapeEnum TA, 
+   BOPCol_IndexedDataMapOfShapeListOfShape& aMEF)
 {
-  BOPCol_ListOfShape empty;
-  
+  TopExp_Explorer aExS, aExA;
+  //
   // visit ancestors
-  TopExp_Explorer exa(S,TA);
-  while (exa.More()) {
+  aExA.Init(S, TA);
+  while (aExA.More()) {
     // visit shapes
-    const TopoDS_Shape& anc = exa.Current();
-    TopExp_Explorer exs(anc,TS);
-    while (exs.More()) {
-      Standard_Integer index = M.FindIndex(exs.Current());
-      if (index == 0) index = M.Add(exs.Current(),empty);
-      M(index).Append(anc);
-      exs.Next();
+    const TopoDS_Shape& aF = aExA.Current();
+    //
+    aExS.Init(aF, TS);
+    while (aExS.More()) {
+      const TopoDS_Shape& aE= aExS.Current();
+      if (aMEF.Contains(aE)) {
+        aMEF.ChangeFromKey(aE).Append(aF);
+      }
+      else {
+        BOPCol_ListOfShape aLS;
+        aLS.Append(aF);
+        aMEF.Add(aE, aLS);
+      }
+      aExS.Next();
     }
-    exa.Next();
+    aExA.Next();
   }
-  
+  //
   // visit shapes not under ancestors
-  TopExp_Explorer ex(S,TS,TA);
-  while (ex.More()) {
-    Standard_Integer index = M.FindIndex(ex.Current());
-    if (index == 0) index = M.Add(ex.Current(),empty);
-    ex.Next();
+  aExS.Init(S, TS, TA);
+  while (aExS.More()) {
+    const TopoDS_Shape& aE=aExS.Current();
+    BOPCol_ListOfShape aLS;
+    aMEF.Add(aE, aLS);
+    aExS.Next();
   }
 }
diff --git a/tests/bugs/modalg_5/bug25788 b/tests/bugs/modalg_5/bug25788
new file mode 100644 (file)
index 0000000..465299e
--- /dev/null
@@ -0,0 +1,61 @@
+puts "========="
+puts "OCC25788"
+puts "========="
+puts ""
+###############################################
+# Parallelization of the BOP Builder algorithm on second level
+###############################################
+
+# box plate to cut the holes from
+box b1 100 100 1
+
+# N defines number of holes along each of X and Y, thus total N^2 holes
+# will be drilled; note that the algorithm iself is likely to be quadratic
+# for number of shapes, i.e. CPU 
+set N 40
+set holes {}
+for {set i 1} {$i < $N} {incr i} {
+ for {set j 1} {$j < $N} {incr j} {
+   pcylinder p_${i}_$j 0.5 1
+   ttranslate p_${i}_$j [expr $i * 100. / $N]  [expr $j * 100. / $N]  0.
+   lappend holes p_${i}_$j
+ }
+}
+
+eval compound $holes b2
+
+bclearobjects
+bcleartools
+baddobjects b1
+baddtools b2
+
+brunparallel 1
+
+dchrono cpu reset
+dchrono cpu start
+bcut r b1 b2 
+dchrono cpu stop
+set chrono_info [dchrono cpu show]
+
+if { [regexp {Debug mode} [dversion]] } {
+  if { [regexp {Windows} [dversion]] } {
+    set max_time 200
+  } else {
+    set max_time 200
+  }
+} else {
+  if { [regexp {Windows} [dversion]] } {
+    set max_time 50
+  } else {
+    set max_time 50
+  }
+}
+
+regexp {CPU user time: ([-0-9.+eE]+) seconds} ${chrono_info} full z
+puts "$z"
+
+if { $z > ${max_time} } {                                         
+    puts "Elapsed time is more than ${max_time} seconds - Faulty"
+} else {
+    puts "Elapsed time is less than ${max_time} seconds - OK"
+}