0024861: Extra solid is in the result of General Fuse Operation
authorpkv <pkv@opencascade.com>
Mon, 21 Apr 2014 11:54:03 +0000 (15:54 +0400)
committerabv <abv@opencascade.com>
Thu, 24 Apr 2014 11:43:33 +0000 (15:43 +0400)
I. New features:
No new features.

II. Changes:
II.1. class BOPAlgo_ShellSplitter
   - statc function:
void RefineShell(TopoDS_Shell& theShell);
has been addded.
The function provides splitting connexity block of faces when the block begins with
the face that is intended to be internal.

II.2. class BOPAlgo_ShellSplitter
   - statc function:
Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell);
has been modified to process empty shells.

II.3. class BOPAlgo_ShellSplitter
   - method:
void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB);
has been modified to process connexity blocks of faces when the block
begins with the face that is intended to be internal [ II.1 ].

III. Modified entities:
packages:
BOPAlgo

Test case for issue CR24861

src/BOPAlgo/BOPAlgo_ShellSplitter.cxx
tests/bugs/modalg_2/bug497_1
tests/bugs/modalg_2/bug497_5
tests/bugs/modalg_5/bug24861 [new file with mode: 0644]

index 5850912..78d7078 100644 (file)
 #include <BOPTools.hxx>
 #include <BOPTools_AlgoTools.hxx>
 #include <BOPTools_CoupleOfShape.hxx>
-//
-typedef BOPCol_NCVector<BOPTools_ConnexityBlock> \
-  BOPAlgo_ShellSplitter_VectorOfConnexityBlock;
+
 //
 static
   Standard_Boolean IsClosedShell(const TopoDS_Shell& );
+//
 static
   void MakeShell(const BOPCol_ListOfShape& , 
                  TopoDS_Shell& );
+//
+static
+  void RefineShell(TopoDS_Shell& theShell);
 
 //=======================================================================
+//class    : BOPAlgo_CBK
+//purpose  : 
+//=======================================================================
+class BOPAlgo_CBK {
+ public:
+  BOPAlgo_CBK() : 
+    myPCB (NULL) {
+  }
+  //
+  ~BOPAlgo_CBK() {
+  }
+  //
+  void SetConnexityBlock (const BOPTools_ConnexityBlock& aCB) {
+    myPCB=(BOPTools_ConnexityBlock*)&aCB;
+  }
+  //
+  BOPTools_ConnexityBlock& ConnexityBlock () {
+    return *myPCB;
+  }
+  //
+  void Perform() {
+    BOPAlgo_ShellSplitter::SplitBlock(*myPCB);
+  }
+ protected:
+  BOPTools_ConnexityBlock *myPCB;
+};
+//=======================================================================
+typedef BOPCol_NCVector
+  <BOPAlgo_CBK> BOPAlgo_VectorOfCBK; 
+//
+typedef BOPCol_TBBFunctor 
+  <BOPAlgo_CBK,
+  BOPAlgo_VectorOfCBK> BOPAlgo_CBKFunctor;
+//
+typedef BOPCol_TBBCnt 
+  <BOPAlgo_CBKFunctor,
+  BOPAlgo_VectorOfCBK> BOPAlgo_CBKCnt;
+//
+//=======================================================================
 //function : 
 //purpose  : 
 //=======================================================================
@@ -148,7 +189,8 @@ void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
     if (!aMEP.Contains(aSE)) {
       aMEP.Add(aSE);
       BOPTools::MapShapesAndAncestors(aSE, 
-                                      TopAbs_EDGE, TopAbs_FACE, 
+                                      TopAbs_EDGE, 
+                                      TopAbs_FACE, 
                                       aMEF);
     }
     else {
@@ -236,7 +278,8 @@ void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
       //
       if (bRegular) {
         BOPTools::MapShapesAndAncestors(aFR,
-                                        TopAbs_EDGE, TopAbs_FACE, 
+                                        TopAbs_EDGE, 
+                                        TopAbs_FACE, 
                                         aMEFR);
       }
     }
@@ -288,8 +331,10 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
   aItF.Initialize (myShapes);
   for (; aItF.More(); aItF.Next()) {
     const TopoDS_Shape& aFF = aItF.Value();
-    BOPTools::MapShapesAndAncestors
-      (aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
+    BOPTools::MapShapesAndAncestors (aFF, 
+                                     TopAbs_EDGE, 
+                                     TopAbs_FACE, 
+                                     aEFMap);
   }
   //
   aItF.Initialize (myShapes);
@@ -306,7 +351,8 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
     //
     aMEFP.Clear();
     BOPTools::MapShapesAndAncestors(aFF, 
-                                    TopAbs_EDGE, TopAbs_FACE, 
+                                    TopAbs_EDGE, 
+                                    TopAbs_FACE, 
                                     aMEFP);
     //
     // loop on faces added to Shell; 
@@ -381,88 +427,188 @@ void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
           aSelF=(*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
         }
         else if (aNbOff>1){
-          BOPTools_AlgoTools::GetFaceOff(aE, aF, 
-                                         aLCSOff, aSelF, aContext);
+          BOPTools_AlgoTools::GetFaceOff(aE, 
+                                         aF, 
+                                         aLCSOff, 
+                                         aSelF, 
+                                         aContext);
         }
         //
         if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) { 
           aBB.Add(aShell, aSelF);
           BOPTools::MapShapesAndAncestors(aSelF, 
-                                          TopAbs_EDGE, TopAbs_FACE, 
+                                          TopAbs_EDGE, 
+                                          TopAbs_FACE, 
                                           aMEFP);
         }
-      } // for (; aEdgeExp.More(); aEdgeExp.Next()) { 
-    } //for (; aItAddedF.More(); aItAddedF.Next()) {
+      } // for (; aExp.More(); aExp.Next()) {
+    } // for (; aItS.More(); aItS.Next()) {
     //
     if (IsClosedShell(aShell)) {
       myLoops.Append(aShell);
     }
+    else {
+      RefineShell(aShell);
+      if (IsClosedShell(aShell)) {
+        myLoops.Append(aShell);
+      }
+    }
   } // for (; aItF.More(); aItF.Next()) {
 }
 //=======================================================================
-//class    : ShellSplitterFunctor
-//purpose  : Auxiliary class
+//function : RefineShell
+//purpose  : 
 //=======================================================================
-class BOPAlgo_ShellSplitterFunctor {
- protected:
-  TopoDS_Face myFace;
-  BOPAlgo_ShellSplitter_VectorOfConnexityBlock* myPVCB;
+void RefineShell(TopoDS_Shell& theShell)
+{
+  TopoDS_Iterator aIt;
   //
- public:
-  BOPAlgo_ShellSplitterFunctor
-    (BOPAlgo_ShellSplitter_VectorOfConnexityBlock& aVCB) 
-      : myPVCB(&aVCB) {
+  aIt.Initialize(theShell);
+  if(!aIt.More()) {
+    return;
   }
   //
-  void operator()( const flexible_range<Standard_Size>& aBR ) const{
-    Standard_Size i, iBeg, iEnd;
+  Standard_Integer i, aNbMEF, aNbF;
+  BOPCol_IndexedDataMapOfShapeListOfShape aMEF; 
+  TopoDS_Builder aBB;
+  TopExp_Explorer aExp;
+  BOPCol_MapOfShape aMEStop, aMFB;
+  BOPCol_MapIteratorOfMapOfShape aItM;
+  BOPCol_ListIteratorOfListOfShape aItLF, aItLFP;
+  BOPCol_ListOfShape aLFP, aLFP1;
+  //
+  // Branch points
+  BOPTools::MapShapesAndAncestors (theShell, 
+                                   TopAbs_EDGE, 
+                                   TopAbs_FACE, 
+                                   aMEF);
+  aNbMEF=aMEF.Extent();
+  for (i=1; i<=aNbMEF; ++i) {
+    const TopoDS_Shape& aE=aMEF.FindKey(i);
+    const BOPCol_ListOfShape& aLF=aMEF.FindFromIndex(i);
+    aNbF=aLF.Extent();
+    if (aNbF>2) {
+      aMEStop.Add(aE);
+    }
+  }
+  //
+  if (aMEStop.IsEmpty()) {
+    return;
+  }
+  //
+  // The first Face 
+  const TopoDS_Shape& aF1=aIt.Value();
+  aMFB.Add(aF1);
+  aLFP.Append(aF1);
+  //
+  // Trying to reach the branch point
+  for (;;)  {
+    aItLFP.Initialize(aLFP);
+    for (; aItLFP.More(); aItLFP.Next()) { 
+      const TopoDS_Shape& aFP=aItLFP.Value();
+      //
+      aExp.Init(aFP, TopAbs_EDGE);
+      for (; aExp.More(); aExp.Next()) {
+        const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
+        if (aMEStop.Contains(aE)) {
+          continue;
+        }
+        //
+        if (BRep_Tool::Degenerated(aE)) {
+          continue;
+        }
+        //
+        const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
+        //
+        aItLF.Initialize(aLF);
+        for (; aItLF.More(); aItLF.Next()) { 
+          const TopoDS_Shape& aFP1=aItLF.Value();
+          if (aFP1.IsSame(aFP)) {
+            continue;
+          }
+          if (aMFB.Contains(aFP1)) {
+            continue;
+          }
+          aMFB.Add(aFP1);
+          aLFP1.Append(aFP1);
+        }// for (; aItLF.More(); aItLF.Next()) { 
+      }// for (; aExp.More(); aExp.Next()) {
+    }// for (; aItLFP.More(); aItLFP.Next()) { 
     //
-    BOPAlgo_ShellSplitter_VectorOfConnexityBlock& aVCB=*myPVCB;
     //
-    iBeg=aBR.begin();
-    iEnd=aBR.end();
-    for(i=iBeg; i!=iEnd; ++i) {
-      BOPTools_ConnexityBlock& aCB=aVCB((Standard_Integer)i);
-      //
-      BOPAlgo_ShellSplitter::SplitBlock(aCB);
+    if (aLFP1.IsEmpty()) {
+      break;
+    }
+    //
+    aLFP.Clear();
+    aItLF.Initialize(aLFP1);
+    for (; aItLF.More(); aItLF.Next()) { 
+      const TopoDS_Shape& aFP1=aItLF.Value();
+      aLFP.Append(aFP1);
     }
+    aLFP1.Clear();
+  }// for (;;)  {
+  //
+  // Remove all faces before the branch point
+  aItM.Initialize(aMFB);
+  for (; aItM.More(); aItM.Next()) { 
+    const TopoDS_Shape& aFB=aItM.Value();
+    aBB.Remove(theShell, aFB);
   }
-};
+}
 //=======================================================================
-//class    : BOPAlgo_ShellSplitterCnt
-//purpose  : Auxiliary class
+//function : IsClosedShell
+//purpose  : 
 //=======================================================================
-class BOPAlgo_ShellSplitterCnt {
- public:
-  //-------------------------------
-  // Perform
-  Standard_EXPORT 
-    static void Perform
-      (const Standard_Boolean bRunParallel,
-       BOPAlgo_ShellSplitter_VectorOfConnexityBlock& aVCB) {
-    //
-    BOPAlgo_ShellSplitterFunctor aSSF(aVCB);
-    Standard_Size aNbVCB=aVCB.Extent();
+Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
+{
+  Standard_Integer i, aNbE;
+  Standard_Boolean bRet;
+  TopoDS_Iterator aIt;
+  TopExp_Explorer aExp;
+  BOPCol_MapOfShape aM;
+  // 
+  bRet=Standard_False;
+  //
+  aIt.Initialize(theShell);
+  for(i=0; aIt.More(); aIt.Next(), ++i) {
+    const TopoDS_Shape& aF=aIt.Value();
     //
-    if (bRunParallel) {
-      flexible_for(flexible_range<Standard_Size>(0,aNbVCB), aSSF);
+    aExp.Init(aF, TopAbs_EDGE);
+    for (; aExp.More(); aExp.Next()) {
+      const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
+      if (BRep_Tool::Degenerated(aE)) {
+        continue;
+      }
+      //
+      if (aE.Orientation()==TopAbs_INTERNAL) {
+        continue;
+      }
+      if (!aM.Add(aE)) {
+        aM.Remove(aE);
+      }
     }
-    else {
-      aSSF.operator()(flexible_range<Standard_Size>(0,aNbVCB));
+  }
+  //
+  if(i) {
+    aNbE=aM.Extent();
+    if (!aNbE) {
+      bRet=!bRet; 
     }
   }
-};
+  return bRet;
+}
 //=======================================================================
-//function : MMakeShells
+//function : MakeShells
 //purpose  : 
 //=======================================================================
 void BOPAlgo_ShellSplitter::MakeShells()
 {
   Standard_Boolean bIsRegular;
-  Standard_Integer aNbVCB, k;
+  Standard_Integer aNbVCBK, k;
   BOPTools_ListIteratorOfListOfConnexityBlock aItCB;
   BOPCol_ListIteratorOfListOfShape aIt;
-  BOPAlgo_ShellSplitter_VectorOfConnexityBlock aVCB;
+  BOPAlgo_VectorOfCBK aVCBK;
   //
   myErrorStatus=0;
   myShells.Clear();
@@ -480,16 +626,18 @@ void BOPAlgo_ShellSplitter::MakeShells()
       myShells.Append(aShell);
     }
     else {
-      aVCB.Append(aCB);
+      BOPAlgo_CBK& aCBK=aVCBK.Append1();
+      aCBK.SetConnexityBlock(aCB);
     }
   }
   //
-  aNbVCB=aVCB.Extent();
+  aNbVCBK=aVCBK.Extent();
   //===================================================
-  BOPAlgo_ShellSplitterCnt::Perform(myRunParallel, aVCB);
+  BOPAlgo_CBKCnt::Perform(myRunParallel, aVCBK);
   //===================================================
-  for (k=0; k<aNbVCB; ++k) {
-    const BOPTools_ConnexityBlock& aCB=aVCB(k);
+  for (k=0; k<aNbVCBK; ++k) {
+    BOPAlgo_CBK& aCBK=aVCBK(k);
+    const BOPTools_ConnexityBlock& aCB=aCBK.ConnexityBlock();
     const BOPCol_ListOfShape& aLS=aCB.Loops();
     aIt.Initialize(aLS);
     for (; aIt.More(); aIt.Next()) {
@@ -500,44 +648,6 @@ void BOPAlgo_ShellSplitter::MakeShells()
   }
 }
 //=======================================================================
-//function : IsClosedShell
-//purpose  : 
-//=======================================================================
-Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
-{
-  Standard_Integer aNbE;
-  Standard_Boolean bRet;
-  TopoDS_Iterator aIt;
-  TopExp_Explorer aExp;
-  BOPCol_MapOfShape aM;
-  // 
-  bRet=Standard_False;
-  aIt.Initialize(theShell);
-  for(; aIt.More(); aIt.Next()) {
-    const TopoDS_Face& aF=(*(TopoDS_Face*)(&aIt.Value()));
-    aExp.Init(aF, TopAbs_EDGE);
-    for (; aExp.More(); aExp.Next()) {
-      const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
-      if (BRep_Tool::Degenerated(aE)) {
-        continue;
-      }
-      //
-      if (aE.Orientation()==TopAbs_INTERNAL) {
-        continue;
-      }
-      if (!aM.Add(aE)) {
-        aM.Remove(aE);
-      }
-    }
-  }
-  //
-  aNbE=aM.Extent();
-  if (!aNbE) {
-    bRet=!bRet;
-  }
-  return bRet;
-}
-//=======================================================================
 //function : MakeShell
 //purpose  : 
 //=======================================================================
index ac7f0b6..8b1d5f6 100755 (executable)
@@ -1,5 +1,3 @@
-puts "TODO OCC12345 ALL: Error : The square of result shape is"
-
 puts "========="
 puts " OCC497 "
 puts "(case 1)"
@@ -15,10 +13,14 @@ checkshape a_1
 restore [locate_data_file OCC497b.brep] a_2
 checkshape a_2
 
-if [catch {bcut result a_1 a_2 } catch_result] {
+explode a_2 so
+bop a_2_1 a_2_2
+bopfuse r1
+
+if [catch {bcut result a_1 r1 } catch_result] {
     puts "Faulty OCC497:function CUT works wrongly "
 } else {
     puts "OCC497 : function CUT works without hangs up "
 }
-set square 0
+set square 646.969
 set 2dviewer 0
index e621918..a99929b 100755 (executable)
@@ -1,3 +1,6 @@
+puts "TODO OCC24861 ALL: Faulty shapes in variables faulty_1 to faulty_"
+puts "TODO OCC24861 ALL: Error : The square of result shape is"
+
 puts "========="
 puts " OCC497 "
 puts "(case 5)"
diff --git a/tests/bugs/modalg_5/bug24861 b/tests/bugs/modalg_5/bug24861
new file mode 100644 (file)
index 0000000..6404481
--- /dev/null
@@ -0,0 +1,33 @@
+puts "========="
+puts "OCC24861"
+puts "========="
+puts ""
+###########################################################
+# Extra solid is in the result of General Fuse Operation
+###########################################################
+
+restore [locate_data_file bug24861_b1.brep] b1
+restore [locate_data_file bug24861_b2.brep] b2
+
+explode b2
+
+bclearobjects
+bcleartools
+baddobjects b1 b2_1 b2_2 b2_3 b2_4 b2_5 b2_6 b2_7
+
+bfillds -s
+bbuild result -s
+
+set square 1780.37
+
+set nb_v_good 18
+set nb_e_good 38
+set nb_w_good 32
+set nb_f_good 29
+set nb_sh_good 9
+set nb_sol_good 7
+set nb_compsol_good 0
+set nb_compound_good 1
+set nb_shape_good 134
+
+set 2dviewer 1