From f9481b4f217a0a89e33a4450d76d7d8f75dfe8df Mon Sep 17 00:00:00 2001 From: jgv Date: Fri, 15 Oct 2021 07:53:48 +0300 Subject: [PATCH] 0032619: [Regression] Modelling Algorithms - UnifySameDomain ignores shared face Correct method ShapeUpgrade_UnifySameDomain::UnifyFaces: exclude free boundary edges from unification. --- .../ShapeUpgrade_UnifySameDomain.cxx | 32 ++++++++++++++++--- .../ShapeUpgrade_UnifySameDomain.hxx | 3 +- tests/bugs/heal/bug32619 | 20 ++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 tests/bugs/heal/bug32619 diff --git a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx index d4a7345d9b..14166e9d52 100644 --- a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx +++ b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx @@ -2618,11 +2618,29 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces() TopExp::MapShapes (myShape, TopAbs_FACE, aFaceMap); for (Standard_Integer i = 1; i <= aFaceMap.Extent(); i++) TopExp::MapShapesAndAncestors (aFaceMap(i), TopAbs_EDGE, TopAbs_FACE, aGMapEdgeFaces); + + // creating map of free boundaries + TopTools_MapOfShape aFreeBoundMap; + // look at only shells not belonging to solids + TopExp_Explorer anExplo (myShape, TopAbs_SHELL, TopAbs_SOLID); + for (; anExplo.More(); anExplo.Next()) + { + const TopoDS_Shape& aShell = anExplo.Current(); + TopTools_IndexedDataMapOfShapeListOfShape aEFmap; + TopExp::MapShapesAndAncestors (aShell, TopAbs_EDGE, TopAbs_FACE, aEFmap); + for (Standard_Integer ii = 1; ii <= aEFmap.Extent(); ii++) + { + const TopoDS_Edge& anEdge = TopoDS::Edge (aEFmap.FindKey(ii)); + const TopTools_ListOfShape& aFaceList = aEFmap(ii); + if (!BRep_Tool::Degenerated (anEdge) && aFaceList.Extent() == 1) + aFreeBoundMap.Add (anEdge); + } + } // unify faces in each shell separately TopExp_Explorer exps; for (exps.Init(myShape, TopAbs_SHELL); exps.More(); exps.Next()) - IntUnifyFaces(exps.Current(), aGMapEdgeFaces); + IntUnifyFaces(exps.Current(), aGMapEdgeFaces, aFreeBoundMap); // gather all faces out of shells in one compound and unify them at once BRep_Builder aBB; @@ -2633,7 +2651,7 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces() aBB.Add(aCmp, exps.Current()); if (nbf > 0) - IntUnifyFaces(aCmp, aGMapEdgeFaces); + IntUnifyFaces(aCmp, aGMapEdgeFaces, aFreeBoundMap); myShape = myContext->Apply(myShape); } @@ -2662,7 +2680,8 @@ static void SetFixWireModes(ShapeFix_Face& theSff) //======================================================================= void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape, - TopTools_IndexedDataMapOfShapeListOfShape& theGMapEdgeFaces) + TopTools_IndexedDataMapOfShapeListOfShape& theGMapEdgeFaces, + const TopTools_MapOfShape& theFreeBoundMap) { // creating map of edge faces for the shape TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces; @@ -2719,7 +2738,9 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape // get connectivity of the edge in the global shape const TopTools_ListOfShape& aGList = theGMapEdgeFaces.FindFromKey(edge); - if (!myAllowInternal && (aGList.Extent() != 2 || myKeepShapes.Contains(edge))) { + if (!myAllowInternal && + (aGList.Extent() != 2 || myKeepShapes.Contains(edge) || theFreeBoundMap.Contains(edge))) + { // non manifold case is not processed unless myAllowInternal continue; } @@ -2807,7 +2828,8 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape if (aLF.Extent() == 2) { const TopoDS_Shape& aE = aMapEF.FindKey(i); const TopTools_ListOfShape& aGLF = theGMapEdgeFaces.FindFromKey(aE); - if (aGLF.Extent() > 2 || myKeepShapes.Contains(aE)) { + if (aGLF.Extent() > 2 || myKeepShapes.Contains(aE) || theFreeBoundMap.Contains(aE)) + { aKeepEdges.Append(aE); } } diff --git a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx index b1558d111f..c144ae0abf 100644 --- a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx +++ b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.hxx @@ -172,7 +172,8 @@ protected: Standard_EXPORT void UnifyEdges(); void IntUnifyFaces(const TopoDS_Shape& theInpShape, - TopTools_IndexedDataMapOfShapeListOfShape& theGMapEdgeFaces); + TopTools_IndexedDataMapOfShapeListOfShape& theGMapEdgeFaces, + const TopTools_MapOfShape& theFreeBoundMap); //! Splits the sequence of edges into the sequence of chains Standard_Boolean MergeEdges(TopTools_SequenceOfShape& SeqEdges, diff --git a/tests/bugs/heal/bug32619 b/tests/bugs/heal/bug32619 new file mode 100644 index 0000000000..3e4677e1bc --- /dev/null +++ b/tests/bugs/heal/bug32619 @@ -0,0 +1,20 @@ +puts "=============================================" +puts "OCC32619: UnifySameDomain ignores shared face" +puts "=============================================" +puts "" + +restore [locate_data_file bug32619.brep] a + +unifysamedom result a + +checkshape result + +checknbshapes result -t -shell 2 -face 3 -wire 3 -edge 12 -vertex 10 + +set tolres [checkmaxtol result] + +if { ${tolres} > 2.e-7} { + puts "Error: bad tolerance of result" +} + +checkview -display result -2d -path ${imagedir}/${test_image}.png \ No newline at end of file