0029688: Regression vs 7.2.0: Wrong result of CUT operation
authoremv <emv@opencascade.com>
Wed, 11 Apr 2018 09:22:29 +0000 (12:22 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 12 Apr 2018 09:40:07 +0000 (12:40 +0300)
Boolean Operations - when splitting the face by the intersections with other arguments check if the face (e.g. really thin one) can be split by a vertex. In this case avoid simple face reconstruction and use the BuilderFace algorithm to split the face.
Test case for the issue.

src/BOPAlgo/BOPAlgo_Builder_2.cxx
tests/bugs/modalg_2/bug472_3
tests/bugs/modalg_7/bug29688 [new file with mode: 0644]

index e7dd973..15b1b3c 100644 (file)
@@ -307,8 +307,8 @@ void BOPAlgo_Builder::BuildSplitFaces()
 
       // No internal parts for the face, so just build the draft face
       // and keep it to pass directly into result.
-      // If the original face has any internal edges, the draft face
-      // will be null, as the internal edges may split the face on parts
+      // If the original face has any internal edges or multi-connected vertices,
+      // the draft face will be null, as such sub-shapes may split the face on parts
       // (as in the case "bugs modalg_5 bug25245_1").
       // The BuilderFace algorithm will be called in this case.
       TopoDS_Face aFD = BuildDraftFace(aF, myImages, myContext);
@@ -809,6 +809,30 @@ void BOPAlgo_Builder::FillInternalVertices()
   }
 }
 //=======================================================================
+//function : HasMultiConnected
+//purpose  : Checks if the edge has multi-connected vertices.
+//=======================================================================
+static Standard_Boolean HasMultiConnected(const TopoDS_Edge& theEdge,
+                                          TopTools_DataMapOfShapeInteger& theMap)
+{
+  TopoDS_Iterator itV(theEdge);
+  for (; itV.More(); itV.Next())
+  {
+    const TopoDS_Shape& aV = itV.Value();
+    Standard_Integer *pCounter = theMap.ChangeSeek(aV);
+    if (!pCounter)
+      pCounter = theMap.Bound(aV, 1);
+    else
+    {
+      if (*pCounter == 2)
+        return Standard_True;
+
+      ++(*pCounter);
+    }
+  }
+  return Standard_False;
+}
+//=======================================================================
 //function : BuildDraftFace
 //purpose  : Build draft faces, updating the bounding edges,
 //           according to the information stored into the <theImages> map
@@ -826,6 +850,13 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
   TopoDS_Face aDraftFace;
   aBB.MakeFace(aDraftFace, aS, aLoc, aTol);
 
+  // Check if the thin face can be split by a vertex - in this case
+  // this vertex will be contained in more than two edges. Thus, count
+  // the vertices appearance, and if the multi-connexity is met return
+  // the null face to use the BuilderFace algorithm for checking the
+  // possibility of split.
+  TopTools_DataMapOfShapeInteger aVerticesCounter;
+
   // Update wires of the original face and add them to draft face
   TopoDS_Iterator aItW(theFace.Oriented(TopAbs_FORWARD));
   for (; aItW.More(); aItW.Next())
@@ -851,13 +882,17 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
       {
         // The internal edges could split the original face on halves.
         // Thus, use the BuilderFace algorithm to build the new face.
-        TopoDS_Face aNull;
-        return aNull;
+        return TopoDS_Face();
       }
 
+      // Check for the splits of the edge
       const TopTools_ListOfShape* pLEIm = theImages.Seek(aE);
       if (!pLEIm)
       {
+        // Check if the edge has multi-connected vertices
+        if (HasMultiConnected(aE, aVerticesCounter))
+          return TopoDS_Face();
+
         aBB.Add(aNewWire, aE);
         continue;
       }
@@ -872,6 +907,10 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
       {
         TopoDS_Edge& aSp = TopoDS::Edge(aItLEIm.Value());
 
+        // Check if the split has multi-connected vertices
+        if (HasMultiConnected(aSp, aVerticesCounter))
+          return TopoDS_Face();
+
         aSp.Orientation(anOriE);
         if (bIsDegenerated)
         {
index f67cacf..55fef09 100755 (executable)
@@ -1,3 +1,4 @@
+puts "TODO OCC25917 ALL: Faulty shapes in variables faulty_1 to faulty_"
 puts "TODO OCC25917 ALL: Error :  is WRONG because number of "
 puts "========================"
 puts " OCC472 "
diff --git a/tests/bugs/modalg_7/bug29688 b/tests/bugs/modalg_7/bug29688
new file mode 100644 (file)
index 0000000..6e882c7
--- /dev/null
@@ -0,0 +1,22 @@
+puts "========"
+puts "OCC29688"
+puts "========"
+puts ""
+#################################################
+# Regression vs 7.2.0: Wrong result of CUT operation
+#################################################
+
+brestore [locate_data_file bug29688_shape.brep] s1
+brestore [locate_data_file bug29688_tool.brep] s2
+
+bfuzzyvalue 2.1e-5
+
+bcut result s1 s2
+
+bfuzzyvalue 0.0
+
+checkshape result
+checknbshapes result -wire 19 -face 19 -shell 1 -solid 1
+checkprops result -s 64946 -v 253467
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png