From 118e720920fbde393f30d811086f9499bf7dcc3e Mon Sep 17 00:00:00 2001 From: emv Date: Wed, 7 Feb 2018 14:31:43 +0300 Subject: [PATCH] 0029488: Regression: boolean operation " general fuse" creates solid containing 5 not connected shells lying on the one level. Boolean Operations - when checking two faces with the same bounds on Same Domain, take into account possible deviation of the edges from the faces surfaces. Test cases for the issue. (cherry picked from commit 8a7476a62292cb359f2459138e8a267d1aa07ce2) --- src/BOPTools/BOPTools_AlgoTools.cxx | 89 +++++++++++++++++------------ tests/bugs/modalg_7/bug29488_1 | 16 ++++++ tests/bugs/modalg_7/bug29488_2 | 19 ++++++ 3 files changed, 87 insertions(+), 37 deletions(-) create mode 100644 tests/bugs/modalg_7/bug29488_1 create mode 100644 tests/bugs/modalg_7/bug29488_2 diff --git a/src/BOPTools/BOPTools_AlgoTools.cxx b/src/BOPTools/BOPTools_AlgoTools.cxx index 795686c093..d799b1e953 100644 --- a/src/BOPTools/BOPTools_AlgoTools.cxx +++ b/src/BOPTools/BOPTools_AlgoTools.cxx @@ -994,46 +994,61 @@ Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain Handle(IntTools_Context)& theContext, const Standard_Real theFuzz) { - Standard_Boolean bFlag; - Standard_Integer iErr; - Standard_Real aTolF1, aTolF2, aTol; - gp_Pnt2d aP2D; - gp_Pnt aP; - TopoDS_Face aF1, aF2; - TopoDS_Edge aE1; - TopExp_Explorer aExp; - Standard_Real aFuzz1 = (theFuzz > Precision::Confusion() ? theFuzz : Precision::Confusion()); - // - bFlag=Standard_False; - // - aF1=theF1; - aF1.Orientation(TopAbs_FORWARD); - aF2=theF2; - aF2.Orientation(TopAbs_FORWARD); - // - aTolF1=BRep_Tool::Tolerance(aF1); - // 1 - aExp.Init(aF1, TopAbs_EDGE); - for (; aExp.More(); aExp.Next()) { - aE1=(*(TopoDS_Edge*)(&aExp.Current())); - if (!BRep_Tool::Degenerated(aE1)) { - Standard_Real aTolE = BRep_Tool::Tolerance(aE1); - if (aTolE > aTolF1) { - aTolF1 = aTolE; + Standard_Boolean bFacesSD = Standard_False; + + // The idea is to find a point inside the first face + // and check its validity for the second face. + // If valid - the faces are same domain. + + gp_Pnt aP1; + gp_Pnt2d aP2D1; + // Find point inside the first face + Standard_Integer iErr = + BOPTools_AlgoTools3D::PointInFace(theF1, aP1, aP2D1, theContext); + + if (iErr != 0) + { + // unable to find the point + return bFacesSD; + } + + // Check validity of the point for second face + + // Compute the tolerance to check the validity - + // sum of tolerance of faces and fuzzy tolerance + + // Compute the tolerance of the faces, taking into account the deviation + // of the edges from the surfaces + Standard_Real aTolF1 = BRep_Tool::Tolerance(theF1), + aTolF2 = BRep_Tool::Tolerance(theF2); + + // Find maximal tolerance of edges. + // The faces should have the same boundaries, thus + // it does not matter which face to explore. + { + Standard_Real aTolEMax = -1.; + TopExp_Explorer anExpE(theF1, TopAbs_EDGE); + for (; anExpE.More(); anExpE.Next()) + { + const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current()); + if (!BRep_Tool::Degenerated(aE)) + { + Standard_Real aTolE = BRep_Tool::Tolerance(aE); + if (aTolE > aTolEMax) + aTolEMax = aTolE; } } + if (aTolEMax > aTolF1) aTolF1 = aTolEMax; + if (aTolEMax > aTolF2) aTolF2 = aTolEMax; } - // 2 - aTolF2=BRep_Tool::Tolerance(aF2); - aTol = aTolF1 + aTolF2 + aFuzz1; - // - iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D, - theContext); - if (!iErr) { - bFlag=theContext->IsValidPointForFace(aP, aF2, aTol); - } - // - return bFlag; + + // Checking criteria + Standard_Real aTol = aTolF1 + aTolF2 + Max(theFuzz, Precision::Confusion()); + + // Project and classify the point on second face + bFacesSD = theContext->IsValidPointForFace(aP1, theF2, aTol); + + return bFacesSD; } //======================================================================= diff --git a/tests/bugs/modalg_7/bug29488_1 b/tests/bugs/modalg_7/bug29488_1 new file mode 100644 index 0000000000..8cf689e7d2 --- /dev/null +++ b/tests/bugs/modalg_7/bug29488_1 @@ -0,0 +1,16 @@ +puts "========" +puts "OCC29488" +puts "========" +puts "" +################################################# +# Regression: boolean operation " general fuse" creates solid containing 5 not connected shells lying on the one level +################################################# + +restore [locate_data_file bug29488_shapes.brep] s +eval mkvolume result [lrange [explode s] 1 end] + +checkshape result +checknbshapes result -wire 77 -face 77 -shell 1 -solid 1 +checkprops result -s 3073.39 -v 10240.8 + +checkview -display result -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_7/bug29488_2 b/tests/bugs/modalg_7/bug29488_2 new file mode 100644 index 0000000000..262b7e7267 --- /dev/null +++ b/tests/bugs/modalg_7/bug29488_2 @@ -0,0 +1,19 @@ +puts "========" +puts "OCC29488" +puts "========" +puts "" +################################################# +# Regression: boolean operation " general fuse" creates solid containing 5 not connected shells lying on the one level +################################################# + +restore [locate_data_file bug29488_shapes.brep] s + +bclearobjects +bcleartools +eval baddobjects [explode s] +bfillds +bbuild result + +checkshape result +checknbshapes result -wire 401 -face 377 -shell 10 -solid 2 +checkprops result -s 77135.9 -v 246693