0028002: Invalid result of Boolean Fuse operation
authoremv <emv@opencascade.com>
Wed, 26 Oct 2016 10:00:56 +0000 (13:00 +0300)
committerapn <apn@opencascade.com>
Thu, 27 Oct 2016 14:43:43 +0000 (17:43 +0300)
The SolidClassifier algorithm does not take into account the internal parts of the solid and its faces.
But in some cases the parts which are internal on some shapes can be included in other shapes of
the same solid with FORWARD/REVERSED orientation and therefore should be counted as well.

The fix changes the procedure of the initialization of the tree of bounding boxes of the edges and
vertices of the solid in SolidExplorer algorithm to treat the internal/external parts of the solid correctly.

src/BRepClass3d/BRepClass3d_SolidExplorer.cxx
tests/bugs/modalg_6/bug28002_1 [new file with mode: 0644]
tests/bugs/modalg_6/bug28002_2 [new file with mode: 0644]

index 06802db..6d8d33d 100644 (file)
@@ -870,23 +870,44 @@ void BRepClass3d_SolidExplorer::InitShape(const TopoDS_Shape& S)
   BRepBndLib::Add(myShape,myBox);
 #endif
 
-  // Fill mapEV with vertices and edges from shape.
-  TopExp::MapShapes(myShape, TopAbs_EDGE, myMapEV);
-  TopExp::MapShapes(myShape, TopAbs_VERTEX, myMapEV);  
-
-  NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller (myTree);
-
-  for (Standard_Integer i = 1; i <= myMapEV.Extent(); i++)
-  {
-    Bnd_Box B;
-    const TopoDS_Shape& Sh = myMapEV(i);
-    TopAbs_Orientation ori = Sh.Orientation();
-    if (ori == TopAbs_EXTERNAL || ori == TopAbs_INTERNAL)
-      continue;
-    if (Sh.ShapeType() == TopAbs_EDGE && BRep_Tool::Degenerated(TopoDS::Edge(Sh)))
+  // since the internal/external parts should be avoided in tree filler,
+  // there is no need to add these parts in the EV map as well
+  TopExp_Explorer aExpF(myShape, TopAbs_FACE);
+  for (; aExpF.More(); aExpF.Next()) {
+    const TopoDS_Shape& aF = aExpF.Current();
+    //
+    TopAbs_Orientation anOrF = aF.Orientation();
+    if (anOrF == TopAbs_INTERNAL || anOrF == TopAbs_EXTERNAL) {
       continue;
-    BRepBndLib::Add(Sh,B);
-    aTreeFiller.Add(i, B);
+    }
+    //
+    TopExp_Explorer aExpE(aF, TopAbs_EDGE);
+    for (; aExpE.More(); aExpE.Next()) {
+      const TopoDS_Shape& aE = aExpE.Current();
+      //
+      TopAbs_Orientation anOrE = aE.Orientation();
+      if (anOrE == TopAbs_INTERNAL || anOrE == TopAbs_EXTERNAL) {
+        continue;
+      }
+      //
+      if (BRep_Tool::Degenerated(TopoDS::Edge(aE))) {
+        continue;
+      }
+      //
+      TopExp::MapShapes(aE, myMapEV);
+    }
+  }
+  //
+  // Fill mapEV with vertices and edges from shape
+  NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller (myTree);
+  //
+  Standard_Integer i, aNbEV = myMapEV.Extent();
+  for (i = 1; i <= aNbEV; ++i) {
+    const TopoDS_Shape& aS = myMapEV(i);
+    //
+    Bnd_Box aBox;
+    BRepBndLib::Add(aS, aBox);
+    aTreeFiller.Add(i, aBox);
   }
   aTreeFiller.Fill();
 }
diff --git a/tests/bugs/modalg_6/bug28002_1 b/tests/bugs/modalg_6/bug28002_1
new file mode 100644 (file)
index 0000000..dd340c7
--- /dev/null
@@ -0,0 +1,30 @@
+puts "========"
+puts "OCC28002"
+puts "========"
+puts ""
+#################################################
+# Invalid result of Boolean Fuse operation
+#################################################
+
+binrestore [locate_data_file bug28002_shapes.bin] b
+
+explode b
+
+# perform intersection
+bclearobjects
+bcleartools
+baddobjects b_1
+baddtools b_2 b_3 b_4 b_5 b_6 b_7
+bfillds
+
+# build the result of General Fuse operation
+bbuild rgf
+checkshape rgf
+checknbshapes rgf -solid 82 
+
+# build the result of Boolean Fuse operation
+bbop result 1
+checkshape result
+checknbshapes result -solid 1 -face 404
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
diff --git a/tests/bugs/modalg_6/bug28002_2 b/tests/bugs/modalg_6/bug28002_2
new file mode 100644 (file)
index 0000000..2fbfdf5
--- /dev/null
@@ -0,0 +1,18 @@
+puts "========"
+puts "OCC28002"
+puts "========"
+puts ""
+#################################################
+# Invalid result of Boolean Fuse operation
+#################################################
+
+binrestore [locate_data_file bug28002_solid.bin] solid
+
+point pnt -91.9238815542512 433.456456867354 81.42128884
+
+# perform classification and get the result
+set result [lindex [bclassify solid pnt] 3]
+
+if {$result != "OUT"} {
+  puts "Error: incorrect classification of the point relatively solid"
+}