From b8781394613481000901216936008f01ee96b8fd Mon Sep 17 00:00:00 2001 From: emv Date: Fri, 10 Sep 2021 16:06:50 +0300 Subject: [PATCH] 0032566: Modeling Algorithms - Incorrect result of offset operation in mode "Complete" join type "Intersection" Before removal of the part make sure that it was not filled due to overlapping of opposite parts. Improve procedure of checking for inverted edges by taking into account that the original edges may not be connected. Correct test case offset/shape_type_i_c/YL5, as it was working incorrectly - some parts were missing. --- src/BRepOffset/BRepOffset_MakeOffset_1.cxx | 74 ++++++++++------------ tests/offset/shape_type_i_c/XY8 | 44 +++++++++++++ tests/offset/shape_type_i_c/YL5 | 8 ++- 3 files changed, 84 insertions(+), 42 deletions(-) create mode 100644 tests/offset/shape_type_i_c/XY8 diff --git a/src/BRepOffset/BRepOffset_MakeOffset_1.cxx b/src/BRepOffset/BRepOffset_MakeOffset_1.cxx index 170eed611f..b4c9f12243 100644 --- a/src/BRepOffset/BRepOffset_MakeOffset_1.cxx +++ b/src/BRepOffset/BRepOffset_MakeOffset_1.cxx @@ -1384,10 +1384,9 @@ void BRepOffset_BuildOffsetFaces::BuildSplitsOfFaces (const Message_ProgressRang // show inverted edges TopoDS_Compound aCEInverted; BRep_Builder().MakeCompound (aCEInverted); - TopTools_MapIteratorOfMapOfShape aItM (myInvertedEdges); - for (; aItM.More(); aItM.Next()) + for (i = 1; i <= myInvertedEdges.Extent(); ++i) { - BRep_Builder().Add (aCEInverted, aItM.Value()); + BRep_Builder().Add (aCEInverted, myInvertedEdges(i)); } #endif @@ -2131,7 +2130,9 @@ void BRepOffset_BuildOffsetFaces::FindInvalidEdges (const TopoDS_Face& theF, { Standard_Boolean bSkip = Standard_True; - // Allow the edge to be analyzed if it is: + // It seems the edge originated from not connected edges and cannot be + // considered as correctly classified as it may fill some undesired parts. + // Still, allow the edge to be accounted for local analysis if it is: // * originated from more than two faces // * unanimously considered valid or invalid // * not a boundary edge in the splits @@ -2544,7 +2545,7 @@ void BRepOffset_BuildOffsetFaces::FindInvalidFaces (TopTools_ListOfShape& theLFI // 1. Some of the edges are valid for this face. Standard_Boolean bHasValid, bAllValid, bAllInvalid, bHasReallyInvalid, bAllInvNeutral; Standard_Boolean bValid, bValidLoc, bInvalid, bInvalidLoc, bNeutral, bInverted; - Standard_Boolean bIsInvalidByInverted; + Standard_Boolean bIsInvalidByInverted, bHasInverted; Standard_Integer aNbChecked; // Standard_Boolean bTreatInvertedAsInvalid = (theLFImages.Extent() == 1); @@ -2579,6 +2580,7 @@ void BRepOffset_BuildOffsetFaces::FindInvalidFaces (TopTools_ListOfShape& theLFI bHasReallyInvalid = Standard_False; bAllInvNeutral = Standard_True; bIsInvalidByInverted = Standard_True; + bHasInverted = Standard_False; aNbChecked = 0; // const TopoDS_Wire& aWIm = BRepTools::OuterWire (aFIm); @@ -2628,6 +2630,7 @@ void BRepOffset_BuildOffsetFaces::FindInvalidFaces (TopTools_ListOfShape& theLFI bAllInvalid &= (bInvalid || bInvalidLoc); bAllInvNeutral &= (bAllInvalid && bNeutral); bIsInvalidByInverted &= (bInvalidLoc || bInverted); + bHasInverted |= bInverted; } // if (!aNbChecked) @@ -2638,6 +2641,13 @@ void BRepOffset_BuildOffsetFaces::FindInvalidFaces (TopTools_ListOfShape& theLFI // if (!bHasReallyInvalid && (bAllInvNeutral && !bHasValid) && (aNbChecked > 1)) { + if (bHasInverted) + { + // The part seems to be filled due to overlapping of parts rather than + // due to multi-connection of faces. No need to remove the part. + aItLF.Next(); + continue; + } // remove edges from neutral TopExp::MapShapes (aFIm, TopAbs_EDGE, aMENRem); // remove face @@ -3084,49 +3094,35 @@ Standard_Boolean BRepOffset_BuildOffsetFaces::CheckInverted (const TopoDS_Edge& return Standard_False; } // - // find vertices common for all edges in the lists + // find vertices common for the max number of edges in the lists for (i = 0; i < 2; ++i) { const TopTools_ListOfShape& aLOE = !i ? aLOE1 : aLOE2; TopoDS_Vertex& aVO = !i ? aVO1 : aVO2; - // - const TopoDS_Shape& aEO = aLOE.First(); - TopExp_Explorer aExpV (aEO, TopAbs_VERTEX); - for (; aExpV.More(); aExpV.Next()) + + TopTools_IndexedDataMapOfShapeListOfShape aDMVELoc; + for (TopTools_ListOfShape::Iterator itLOE (aLOE); itLOE.More(); itLOE.Next()) { - const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aExpV.Current(); - // - Standard_Boolean bVertValid = Standard_True; - TopTools_ListIteratorOfListOfShape aItLOE (aLOE); - for (aItLOE.Next(); aItLOE.More(); aItLOE.Next()) - { - const TopoDS_Shape& aEOx = aItLOE.Value(); - TopExp_Explorer aExpVx (aEOx, TopAbs_VERTEX); - for (; aExpVx.More(); aExpVx.Next()) - { - const TopoDS_Shape& aVx = aExpVx.Current(); - if (aVx.IsSame (aV)) - { - break; - } - } - // - if (!aExpVx.More()) - { - bVertValid = Standard_False; - break; - } - } - // - if (bVertValid) + TopExp::MapShapesAndAncestors (itLOE.Value(), TopAbs_VERTEX, TopAbs_EDGE, aDMVELoc); + } + + Standard_Integer aNbEMax = 0; + for (Standard_Integer j = 1; j <= aDMVELoc.Extent(); ++j) + { + Standard_Integer aNbE = aDMVELoc (j).Extent(); + if (aNbE > 1 && aNbE > aNbEMax) { - aVO = aV; - break; + aVO = TopoDS::Vertex (aDMVELoc.FindKey (j)); + aNbEMax = aNbE; } } + if (aVO.IsNull()) + { + return Standard_False; + } } - // - if (aVO1.IsNull() || aVO2.IsNull() || aVO1.IsSame (aVO2)) + + if (aVO1.IsSame (aVO2)) { return Standard_False; } diff --git a/tests/offset/shape_type_i_c/XY8 b/tests/offset/shape_type_i_c/XY8 new file mode 100644 index 0000000000..a6736ae090 --- /dev/null +++ b/tests/offset/shape_type_i_c/XY8 @@ -0,0 +1,44 @@ +puts "=============================================================================================" +puts "0032566: Modeling Algorithms - Incorrect result of offset operation in mode \"Complete\" join type \"Intersection\"" +puts "=============================================================================================" +puts "" + +restore [locate_data_file bug32566.brep] s + +set ref_values { { 3.94658e+06 9.49773e+07 58 58 } \ + { 4.15709e+06 1.15236e+08 58 58 } \ + { 4.36881e+06 1.3655e+08 58 58 } \ + { 2.91882e+06 1.54418e+08 16 16 } \ + { 3.04675e+06 1.69332e+08 16 16 } \ + { 3.17587e+06 1.84888e+08 16 16 } \ + { 3.30619e+06 2.01092e+08 16 16 } \ + { 3.43772e+06 2.17952e+08 16 16 } \ + { 3.57044e+06 2.35471e+08 16 16 } \ + { 3.70436e+06 2.53658e+08 16 16 } \ + { 3.83949e+06 2.72517e+08 16 16 } \ + { 3.97581e+06 2.92055e+08 16 16 } \ + { 4.11334e+06 3.12277e+08 16 16 } \ + { 4.2523e+06 3.3319e+08 17 17 } \ + { 4.39391e+06 3.54805e+08 17 17 } \ + { 4.53673e+06 3.77131e+08 17 17 } \ + { 4.68075e+06 4.00175e+08 17 17 } \ + { 4.82596e+06 4.23941e+08 17 17 } \ + { 4.97238e+06 4.48436e+08 17 17 } \ + { 5.12e+06 4.73667e+08 17 17 } \ + { 5.26881e+06 4.99638e+08 17 17 } \ + { 5.41883e+06 5.26357e+08 17 17 } \ + { 5.57005e+06 5.53829e+08 17 17 } \ + { 5.72247e+06 5.82059e+08 17 17 } \ + { 5.87608e+06 6.11055e+08 17 17 } \ + { 6.0309e+06 6.40822e+08 17 17 } \ + { 6.18692e+06 6.71366e+08 17 17 } \ + { 6.34413e+06 7.02693e+08 17 17 } \ + { 6.50255e+06 7.3481e+08 17 17 } \ + { 6.66217e+06 7.67721e+08 17 17 } } + +perform_offset_increasing s 5 150 5 $ref_values + +copy r90 result +copy r90_unif result_unif + +checkview -display result_unif -2d -path ${imagedir}/${test_image}.png diff --git a/tests/offset/shape_type_i_c/YL5 b/tests/offset/shape_type_i_c/YL5 index c86e2a4eda..447966a4df 100644 --- a/tests/offset/shape_type_i_c/YL5 +++ b/tests/offset/shape_type_i_c/YL5 @@ -1,10 +1,12 @@ restore [locate_data_file bug28501_input.r2.brep] s -OFFSETSHAPE 10 {} $calcul $type +offsetparameter 1e-7 c i r +offsetload s 10 +offsetperform result -checkprops result -v 2.48594e+007 -s 1.07443e+006 +checkprops result -s 1.06886e+06 -v 2.48884e+07 unifysamedom result_unif result -checknbshapes result_unif -face 313 -shell 1 +checknbshapes result_unif -wire 324 -face 289 -shell 1 -solid 1 checkview -display result_unif -2d -path ${imagedir}/${test_image}.png -- 2.39.5