diff --git a/src/BOPAlgo/BOPAlgo_Builder_2.cxx b/src/BOPAlgo/BOPAlgo_Builder_2.cxx index 1dfc9cdfbf..210dab9d06 100644 --- a/src/BOPAlgo/BOPAlgo_Builder_2.cxx +++ b/src/BOPAlgo/BOPAlgo_Builder_2.cxx @@ -292,31 +292,52 @@ void BOPAlgo_Builder::BuildSplitFaces() if (!aNbPBIn && !aNbPBSc) { + // If there are any alone vertices to be put in the face, + // the new face has to be created even if the wires of the + // face have not been modified. + + // It is also necessary to check if the face contains any internal edges, + // as such edges may split the face on parts and it is better + // to send the face be treated by the BuilderFace algorithm. + // In case of alone vertices the check for internals will be performed + // in the BuildDraftFace method. + Standard_Boolean hasInternals = Standard_False; if (!aNbAV) { // Check if any wires of the face have been modified. - // If not, there is no need to create the new face. + // If no modified and internal wires present in the face + // there is no need to create the new face. + Standard_Boolean hasModified = Standard_False; + TopoDS_Iterator aItW(aF); for (; aItW.More(); aItW.Next()) { - if (myImages.IsBound(aItW.Value())) + TopoDS_Iterator itE(aItW.Value()); + hasInternals = (itE.More() && (itE.Value().Orientation() == TopAbs_INTERNAL)); + if (hasInternals) break; + + hasModified |= myImages.IsBound(aItW.Value()); } - if (!aItW.More()) + + if (!hasInternals && !hasModified) continue; } - // 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 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, myReport); - if (!aFD.IsNull()) + if (!hasInternals) { - aFacesIm(aFacesIm.Add(i, TopTools_ListOfShape())).Append(aFD); - continue; + // 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 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, myReport); + if (!aFD.IsNull()) + { + aFacesIm(aFacesIm.Add(i, TopTools_ListOfShape())).Append(aFD); + continue; + } } } diff --git a/tests/bugs/modalg_7/bug30281 b/tests/bugs/modalg_7/bug30281 new file mode 100644 index 0000000000..ed060f83c9 --- /dev/null +++ b/tests/bugs/modalg_7/bug30281 @@ -0,0 +1,42 @@ +puts "========" +puts "0030281: Regression to 7.2.0: Modeling Algorithms - Wrong result of CUT operation" +puts "========" +puts "" + +restore [locate_data_file bug30281_shape.brep] s1 +restore [locate_data_file bug30281_tool.brep] s2 + +bclearobjects +bcleartools +baddobjects s1 +baddtools s2 +bfillds + +bbop r0 0 +bbop r1 1 +bbop r2 2 +bbop r3 3 +bbop r4 4 + +foreach r {r0 r1 r2 r3 r4} { + checkshape $r + if {![regexp "OK" [bopcheck $r]]} { + puts "Error: the result of BOP is self-interfering shape" + } +} + +checknbshapes r0 -wire 112 -face 88 -shell 4 -solid 4 +checkprops r0 -s 590506 -v 7.584e+006 + +checknbshapes r1 -wire 58 -face 46 -shell 1 -solid 1 +checkprops r1 -s 976583 -v 2.24e+007 + +checknbshapes r2 -wire 94 -face 82 -shell 1 -solid 1 +checkprops r2 -s 1.00882e+006 -v 1.4816e+007 + +checknbshapes r3 -shell 0 -solid 0 +checkprops r3 -s empty -v empty + +checkprops r4 -l 9614.01 + +checkview -display r2 -2d -path ${imagedir}/${test_image}.png