]> OCCT Git - occt-copy.git/commitdiff
0031662: Modeling Algorithms - Incomplete result of section operation
authoremv <emv@opencascade.com>
Mon, 3 Aug 2020 14:10:08 +0000 (17:10 +0300)
committerkgv <kgv@opencascade.com>
Wed, 23 Sep 2020 17:18:07 +0000 (20:18 +0300)
BOPAlgo_PaveFiller: Add method for forced Edge/Face intersection to look for additional cases of coincidence.
BOPAlgo_BuilderSolid: Avoid creating solids from unclassified faces as such solids will be useless. Just warn user about unclassified faces.

24 files changed:
src/BOPAlgo/BOPAlgo.msg
src/BOPAlgo/BOPAlgo_Alerts.hxx
src/BOPAlgo/BOPAlgo_BuilderSolid.cxx
src/BOPAlgo/BOPAlgo_Builder_3.cxx
src/BOPAlgo/BOPAlgo_PaveFiller.cxx
src/BOPAlgo/BOPAlgo_PaveFiller.hxx
src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx
src/BOPAlgo/BOPAlgo_Tools.cxx
src/BOPAlgo/BOPAlgo_Tools.hxx
tests/boolean/bcut_complex/F2
tests/boolean/bfuse_complex/F5
tests/boolean/bfuse_complex/Q2
tests/boolean/bopfuse_complex/H1
tests/boolean/bsection/R8
tests/bugs/modalg_6/bug26619
tests/bugs/modalg_6/bug26789_1
tests/bugs/modalg_7/bug25983 [deleted file]
tests/bugs/modalg_7/bug25983_1 [new file with mode: 0644]
tests/bugs/modalg_7/bug25983_2 [new file with mode: 0644]
tests/bugs/modalg_7/bug27049
tests/bugs/modalg_7/bug31662 [new file with mode: 0644]
tests/bugs/moddata_1/bug152_2
tests/bugs/moddata_2/bug26_2

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