From: msv Date: Tue, 22 Mar 2016 12:23:00 +0000 (+0300) Subject: 0027082: UnifySameDomain must add internal edges where appropriate to resolve self... X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=fee8654f24d78765b32c9a4b2ec96eab68f02fd0;p=occt-copy.git 0027082: UnifySameDomain must add internal edges where appropriate to resolve self-intersections The new option AllowInternalEdges has been added in the class ShapeUpgrade_UnifySameDomain. It determines how the algorithm treats the situation when two faces can be merged together but they have connection with another face via the common edge. With this option turned on, merging of such faces is not stopped, but the multiconnected edges are added to the merged face as INTERNAL edges. By default it is false. In this mode such merging is forbidden, so the result shape will not contain any new INTERNAL edges. The behavior of the algorithm has been changed so that it does not merge faces from different shells. 0027309: Result of UnifySameDomain has InvalidMultiConnexity error The update of the set of boundary edges has been added for the case when faces containing milti-connected edges are excluded from merging. --- diff --git a/samples/tcl/snowflake.tcl b/samples/tcl/snowflake.tcl index 7c8e15a791..9f8336941e 100644 --- a/samples/tcl/snowflake.tcl +++ b/samples/tcl/snowflake.tcl @@ -1,6 +1,6 @@ # Creation of 2d drawing -#Category: Modeling +#Category: Modeling #Title: Snowflake - creation of 2d geometry pload MODELING AISV @@ -85,6 +85,10 @@ bfuse w w w2 bfuse w w w3 bfuse w w w4 bfuse w w w5 +shape wsh Sh +foreach f [explode w f] {add $f wsh} +renamevar wsh w +save w w.brep unifysamedom r w # keep only wires in compound @@ -127,4 +131,4 @@ compound snowflake frame text drawing vinit Driver1/Viewer1/View1 w=1024 h=768 vdisplay snowflake lines text vtop -vfit \ No newline at end of file +vfit diff --git a/src/SWDRAW/SWDRAW_ShapeUpgrade.cxx b/src/SWDRAW/SWDRAW_ShapeUpgrade.cxx index fc9074212b..6aef2acdc0 100644 --- a/src/SWDRAW/SWDRAW_ShapeUpgrade.cxx +++ b/src/SWDRAW/SWDRAW_ShapeUpgrade.cxx @@ -1294,7 +1294,12 @@ static Standard_Integer unifysamedom(Draw_Interpretor& , Standard_Integer n, con if (aShape.IsNull()) return 1; + Standard_Boolean isAllowInternal = Standard_False; + if (n > 3) + isAllowInternal = (strncmp(a[3], "+i", 2) == 0); + ShapeUpgrade_UnifySameDomain Unifier(aShape); + Unifier.AllowInternalEdges(isAllowInternal); Unifier.Build(); TopoDS_Shape Result = Unifier.Shape(); diff --git a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cdl b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cdl index 1401680277..b04fbc19d7 100644 --- a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cdl +++ b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cdl @@ -38,7 +38,13 @@ is UnifyEdges: Boolean from Standard = Standard_True; UnifyFaces: Boolean from Standard = Standard_True; ConcatBSplines: Boolean from Standard = Standard_False); - + + AllowInternalEdges(me: mutable; theValue: Boolean from Standard); + ---Purpose: Sets the flag defining whether it is allowed to create + -- internal edges inside merged faces in the case of non-manifold + -- topology. Without this flag merging through multi connected edge + -- is forbidden. Default value is false. + Build( me : mutable ); ---Purpose: Builds the resulting shape @@ -66,6 +72,7 @@ fields myUnifyFaces : Boolean from Standard; myUnifyEdges : Boolean from Standard; myConcatBSplines : Boolean from Standard; + myAllowInternal : Boolean from Standard; myShape : Shape from TopoDS; diff --git a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx index 5d0dceb01e..59fa5c76dc 100644 --- a/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx +++ b/src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx @@ -941,11 +941,11 @@ static void CheckSharedVertices(const TopTools_SequenceOfShape& theSeqEdges, //======================================================================= ShapeUpgrade_UnifySameDomain::ShapeUpgrade_UnifySameDomain() + : myUnifyFaces (Standard_True), + myUnifyEdges (Standard_True), + myConcatBSplines (Standard_False), + myAllowInternal (Standard_False) { - myUnifyEdges = Standard_True; - myUnifyFaces = Standard_True; - myConcatBSplines = Standard_False; - myContext = new ShapeBuild_ReShape; } @@ -958,13 +958,13 @@ ShapeUpgrade_UnifySameDomain::ShapeUpgrade_UnifySameDomain(const TopoDS_Shape& a const Standard_Boolean UnifyEdges, const Standard_Boolean UnifyFaces, const Standard_Boolean ConcatBSplines) + : myInitShape (aShape), + myUnifyFaces (UnifyFaces), + myUnifyEdges (UnifyEdges), + myConcatBSplines (ConcatBSplines), + myAllowInternal (Standard_False), + myShape (aShape) { - myInitShape = aShape; - myShape = aShape; - myUnifyEdges = UnifyEdges; - myUnifyFaces = UnifyFaces; - myConcatBSplines = ConcatBSplines; - myContext = new ShapeBuild_ReShape; } @@ -986,7 +986,16 @@ void ShapeUpgrade_UnifySameDomain::Initialize(const TopoDS_Shape& aShape, myContext->Clear(); myOldShapes.Clear(); - //myGenerated.Clear(); +} + +//======================================================================= +//function : AllowInternalEdges +//purpose : +//======================================================================= + +void ShapeUpgrade_UnifySameDomain::AllowInternalEdges (const Standard_Boolean theValue) +{ + myAllowInternal = theValue; } //======================================================================= @@ -1027,15 +1036,16 @@ static void putIntWires(TopoDS_Shape& theFace, TopTools_SequenceOfShape& theWire void ShapeUpgrade_UnifySameDomain::UnifyFaces() { - //Handle(ShapeBuild_ReShape) myContext = new ShapeBuild_ReShape; - TopoDS_Shape aResShape = myContext->Apply(myShape); + // creating map of edge faces for the whole shape + TopTools_IndexedDataMapOfShapeListOfShape aGMapEdgeFaces; + TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, aGMapEdgeFaces); // processing each shell TopExp_Explorer exps; for (exps.Init(myShape, TopAbs_SHELL); exps.More(); exps.Next()) { TopoDS_Shell aShell = TopoDS::Shell(exps.Current()); - // creating map of edge faces + // creating map of edge faces for the shell TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces; TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces); @@ -1084,6 +1094,13 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces() if (BRep_Tool::Degenerated(edge)) continue; + // get connectivity of the edge in the global shape + const TopTools_ListOfShape& aGList = aGMapEdgeFaces.FindFromKey(edge); + if (!myAllowInternal && aGList.Extent() != 2) { + // non mainfold case is not processed unless myAllowInternal + continue; + } + // process faces connected through the edge in the current shell const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge); TopTools_ListIteratorOfListOfShape anIter(aList); for (; anIter.More(); anIter.Next()) { @@ -1096,11 +1113,6 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces() if (IsSameDomain(aFace,anCheckedFace)) { - if (aList.Extent() != 2) { - // non mainfold case is not processed - continue; - } - // replacing pcurves TopoDS_Face aMockUpFace; BRep_Builder B; @@ -1119,6 +1131,72 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces() } } + if (faces.Length() > 1) { + // fill in the connectivity map for selected faces + TopTools_IndexedDataMapOfShapeListOfShape aMapEF; + for (i = 1; i <= faces.Length(); i++) { + TopExp::MapShapesAndAncestors(faces(i), TopAbs_EDGE, TopAbs_FACE, aMapEF); + } + + // Collect multiconnected edges, i.e. edges that are internal to + // the set of selected faces and have connections to other faces. + TopTools_ListOfShape aMultEdges; + for (i = 1; i <= aMapEF.Extent(); i++) { + const TopTools_ListOfShape& aLF = aMapEF(i); + if (aLF.Extent() == 2) { + const TopoDS_Shape& aE = aMapEF.FindKey(i); + const TopTools_ListOfShape& aGLF = aGMapEdgeFaces.FindFromKey(aE); + if (aGLF.Extent() > 2) { + aMultEdges.Append(aE); + } + } + } + if (!aMultEdges.IsEmpty()) { + if (!myAllowInternal) { + // Remove from the selection the faces containing multiconnected edges + TopTools_MapOfShape anAvoidFaces; + TopTools_ListIteratorOfListOfShape it(aMultEdges); + for (; it.More(); it.Next()) { + const TopoDS_Shape& aE = it.Value(); + const TopTools_ListOfShape& aLF = aMapEF.FindFromKey(aE); + anAvoidFaces.Add(aLF.First()); + anAvoidFaces.Add(aLF.Last()); + } + for (i = 1; i <= faces.Length(); ) { + if (anAvoidFaces.Contains(faces(i))) { + // update the boundaries of merged area, for that + // remove from 'edges' the edges of this face and add to 'edges' + // the edges of this face that were not present in 'edges' before + TopExp_Explorer ex(faces(i), TopAbs_EDGE); + for (; ex.More(); ex.Next()) { + TopoDS_Shape aE = ex.Current(); + Standard_Integer j; + for (j = 1; j <= edges.Length(); j++) { + if (edges(j).IsSame(aE)) + break; + } + if (j <= edges.Length()) + edges.Remove(j); + else + edges.Append(aE); + } + faces.Remove(i); + } + else + i++; + } + } + else { + // add multiconnected edges as internal in new face + TopTools_ListIteratorOfListOfShape it(aMultEdges); + for (; it.More(); it.Next()) { + const TopoDS_Shape& aE = it.Value(); + edges.Append(aE.Oriented(TopAbs_INTERNAL)); + } + } + } + } + // all faces collected in the sequence. Perform union of faces if (faces.Length() > 1) { NbModif++; diff --git a/tests/bugs/modalg_6/bug27082_1 b/tests/bugs/modalg_6/bug27082_1 new file mode 100644 index 0000000000..a58a1a23ac --- /dev/null +++ b/tests/bugs/modalg_6/bug27082_1 @@ -0,0 +1,18 @@ +puts "============" +puts "OCC27082" +puts "============" +puts "" +############################### +## UnifySameDomain must add internal edges where appropriate to resolve self-intersections +############################### + +restore [locate_data_file bug27082_shapes1.brep] a +explode a +bcut r1 a_1 a_3 +bfuse r2 r1 a_2 +unifysamedom result r2 + +don result +smallview; l; fit +bopcheck result +checknbshapes result -m UnifySameDomain -face 22 -edge 40 diff --git a/tests/bugs/modalg_6/bug27082_1i b/tests/bugs/modalg_6/bug27082_1i new file mode 100644 index 0000000000..0a0ff3b888 --- /dev/null +++ b/tests/bugs/modalg_6/bug27082_1i @@ -0,0 +1,18 @@ +puts "============" +puts "OCC27082" +puts "============" +puts "" +############################### +## UnifySameDomain must add internal edges where appropriate to resolve self-intersections +############################### + +restore [locate_data_file bug27082_shapes1.brep] a +explode a +bcut r1 a_1 a_3 +bfuse r2 r1 a_2 +unifysamedom result r2 +i + +don result +smallview; l; fit +bopcheck result +checknbshapes result -m UnifySameDomain -face 14 -edge 28 diff --git a/tests/bugs/modalg_6/bug27082_2 b/tests/bugs/modalg_6/bug27082_2 new file mode 100644 index 0000000000..cbe7bc5d5a --- /dev/null +++ b/tests/bugs/modalg_6/bug27082_2 @@ -0,0 +1,17 @@ +puts "============" +puts "OCC27082" +puts "============" +puts "" +############################### +## UnifySameDomain must add internal edges where appropriate to resolve self-intersections +############################### + +restore [locate_data_file bug27082_shapes2.brep] a +explode a +bfuse r a_1 a_2 +unifysamedom result r + +don result +smallview; l; fit +bopcheck result +checknbshapes result -m UnifySameDomain -face 37 -edge 94 diff --git a/tests/bugs/modalg_6/bug27082_2i b/tests/bugs/modalg_6/bug27082_2i new file mode 100644 index 0000000000..82ee825b22 --- /dev/null +++ b/tests/bugs/modalg_6/bug27082_2i @@ -0,0 +1,17 @@ +puts "============" +puts "OCC27082" +puts "============" +puts "" +############################### +## UnifySameDomain must add internal edges where appropriate to resolve self-intersections +############################### + +restore [locate_data_file bug27082_shapes2.brep] a +explode a +bfuse r a_1 a_2 +unifysamedom result r +i + +don result +smallview; l; fit +bopcheck result +checknbshapes result -m UnifySameDomain -face 33 -edge 86 diff --git a/tests/bugs/modalg_6/bug27082_3 b/tests/bugs/modalg_6/bug27082_3 new file mode 100644 index 0000000000..4728c05a2e --- /dev/null +++ b/tests/bugs/modalg_6/bug27082_3 @@ -0,0 +1,15 @@ +puts "============" +puts "OCC27082" +puts "============" +puts "" +############################### +## UnifySameDomain must add internal edges where appropriate to resolve self-intersections +############################### + +restore [locate_data_file bug27082_shapes3.brep] a +unifysamedom result a + +don result +smallview; l; fit +bopcheck result +checknbshapes result -m UnifySameDomain -face 249 -edge 600 diff --git a/tests/bugs/modalg_6/bug27082_3i b/tests/bugs/modalg_6/bug27082_3i new file mode 100644 index 0000000000..49d91b0e32 --- /dev/null +++ b/tests/bugs/modalg_6/bug27082_3i @@ -0,0 +1,15 @@ +puts "============" +puts "OCC27082" +puts "============" +puts "" +############################### +## UnifySameDomain must add internal edges where appropriate to resolve self-intersections +############################### + +restore [locate_data_file bug27082_shapes3.brep] a +unifysamedom result a +i + +don result +smallview; l; fit +bopcheck result +checknbshapes result -m UnifySameDomain -face 225 -edge 576 diff --git a/tests/bugs/modalg_6/bug27309 b/tests/bugs/modalg_6/bug27309 new file mode 100644 index 0000000000..f482cd1f01 --- /dev/null +++ b/tests/bugs/modalg_6/bug27309 @@ -0,0 +1,15 @@ +puts "============" +puts "OCC27309" +puts "============" +puts "" +############################### +## Result of UnifySameDomain has InvalidMultiConnexity error +############################### + +restore [locate_data_file bug27309_shape.brep] a +unifysamedom result a + +don result +smallview; l; fit +checkshape result +checknbshapes result -m UnifySameDomain -face 28 -edge 66