From 1ccef79a2aaa086ee7f1be45d7d7b9e240a5c2dd Mon Sep 17 00:00:00 2001 From: emv Date: Wed, 11 Apr 2018 12:22:29 +0300 Subject: [PATCH] 0029688: Regression vs 7.2.0: Wrong result of CUT operation 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 | 47 ++++++++++++++++++++++++++++--- tests/bugs/modalg_2/bug472_3 | 1 + tests/bugs/modalg_7/bug29688 | 22 +++++++++++++++ 3 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 tests/bugs/modalg_7/bug29688 diff --git a/src/BOPAlgo/BOPAlgo_Builder_2.cxx b/src/BOPAlgo/BOPAlgo_Builder_2.cxx index e7dd973031..15b1b3cf38 100644 --- a/src/BOPAlgo/BOPAlgo_Builder_2.cxx +++ b/src/BOPAlgo/BOPAlgo_Builder_2.cxx @@ -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 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) { diff --git a/tests/bugs/modalg_2/bug472_3 b/tests/bugs/modalg_2/bug472_3 index f67cacf4be..55fef09fac 100755 --- a/tests/bugs/modalg_2/bug472_3 +++ b/tests/bugs/modalg_2/bug472_3 @@ -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 index 0000000000..6e882c75e1 --- /dev/null +++ b/tests/bugs/modalg_7/bug29688 @@ -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