1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

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.
This commit is contained in:
emv 2018-04-11 12:22:29 +03:00 committed by bugmaster
parent 6822a3bef1
commit 1ccef79a2a
3 changed files with 66 additions and 4 deletions

View File

@ -307,8 +307,8 @@ void BOPAlgo_Builder::BuildSplitFaces()
// No internal parts for the face, so just build the draft face // No internal parts for the face, so just build the draft face
// and keep it to pass directly into result. // and keep it to pass directly into result.
// If the original face has any internal edges, the draft face // If the original face has any internal edges or multi-connected vertices,
// will be null, as the internal edges may split the face on parts // 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"). // (as in the case "bugs modalg_5 bug25245_1").
// The BuilderFace algorithm will be called in this case. // The BuilderFace algorithm will be called in this case.
TopoDS_Face aFD = BuildDraftFace(aF, myImages, myContext); 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 //function : BuildDraftFace
//purpose : Build draft faces, updating the bounding edges, //purpose : Build draft faces, updating the bounding edges,
// according to the information stored into the <theImages> map // according to the information stored into the <theImages> map
@ -826,6 +850,13 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
TopoDS_Face aDraftFace; TopoDS_Face aDraftFace;
aBB.MakeFace(aDraftFace, aS, aLoc, aTol); 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 // Update wires of the original face and add them to draft face
TopoDS_Iterator aItW(theFace.Oriented(TopAbs_FORWARD)); TopoDS_Iterator aItW(theFace.Oriented(TopAbs_FORWARD));
for (; aItW.More(); aItW.Next()) 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. // The internal edges could split the original face on halves.
// Thus, use the BuilderFace algorithm to build the new face. // Thus, use the BuilderFace algorithm to build the new face.
TopoDS_Face aNull; return TopoDS_Face();
return aNull;
} }
// Check for the splits of the edge
const TopTools_ListOfShape* pLEIm = theImages.Seek(aE); const TopTools_ListOfShape* pLEIm = theImages.Seek(aE);
if (!pLEIm) if (!pLEIm)
{ {
// Check if the edge has multi-connected vertices
if (HasMultiConnected(aE, aVerticesCounter))
return TopoDS_Face();
aBB.Add(aNewWire, aE); aBB.Add(aNewWire, aE);
continue; continue;
} }
@ -872,6 +907,10 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
{ {
TopoDS_Edge& aSp = TopoDS::Edge(aItLEIm.Value()); 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); aSp.Orientation(anOriE);
if (bIsDegenerated) if (bIsDegenerated)
{ {

View File

@ -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 "TODO OCC25917 ALL: Error : is WRONG because number of "
puts "========================" puts "========================"
puts " OCC472 " puts " OCC472 "

View File

@ -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