]> OCCT Git - occt-copy.git/commitdiff
0027082: UnifySameDomain must add internal edges where appropriate to resolve self...
authormsv <msv@opencascade.com>
Tue, 22 Mar 2016 12:23:00 +0000 (15:23 +0300)
committermsv <msv@opencascade.com>
Fri, 22 Apr 2016 12:48:15 +0000 (15:48 +0300)
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.

samples/tcl/snowflake.tcl
src/SWDRAW/SWDRAW_ShapeUpgrade.cxx
src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cdl
src/ShapeUpgrade/ShapeUpgrade_UnifySameDomain.cxx
tests/bugs/modalg_6/bug27082_1 [new file with mode: 0644]
tests/bugs/modalg_6/bug27082_1i [new file with mode: 0644]
tests/bugs/modalg_6/bug27082_2 [new file with mode: 0644]
tests/bugs/modalg_6/bug27082_2i [new file with mode: 0644]
tests/bugs/modalg_6/bug27082_3 [new file with mode: 0644]
tests/bugs/modalg_6/bug27082_3i [new file with mode: 0644]
tests/bugs/modalg_6/bug27309 [new file with mode: 0644]

index 7c8e15a79122627897eb6d3b66bbe536cbd15567..9f8336941eca6f475b5e3f73d89638adc09f900d 100644 (file)
@@ -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
index fc9074212b4bedca7f2a914513651d47f19fa53e..6aef2acdc0c24b45ac7429aa6475f77b4a447b07 100644 (file)
@@ -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();
 
index 14016802771d07f78e4275d395bee0c44e54bbce..b04fbc19d7b28e2133e36d779f5ee8c673b550be 100644 (file)
@@ -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;
     
index 5d0dceb01e1176c2332d59c5bbc245ee000f4ecf..59fa5c76dca644a80a07a19459614b9aabd5d4fe 100644 (file)
@@ -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 (file)
index 0000000..a58a1a2
--- /dev/null
@@ -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 (file)
index 0000000..0a0ff3b
--- /dev/null
@@ -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 (file)
index 0000000..cbe7bc5
--- /dev/null
@@ -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 (file)
index 0000000..82ee825
--- /dev/null
@@ -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 (file)
index 0000000..4728c05
--- /dev/null
@@ -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 (file)
index 0000000..49d91b0
--- /dev/null
@@ -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 (file)
index 0000000..f482cd1
--- /dev/null
@@ -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