From 8a7476a62292cb359f2459138e8a267d1aa07ce2 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. --- 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 b971decf90..b4f474ba38 100644 --- a/src/BOPTools/BOPTools_AlgoTools.cxx +++ b/src/BOPTools/BOPTools_AlgoTools.cxx @@ -1094,46 +1094,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 -- 2.20.1