0031587: Modeling Data - add BRepTools::RemoveInternals() removing internal sub-shape...
authoremv <emv@opencascade.com>
Tue, 2 Jun 2020 09:06:42 +0000 (12:06 +0300)
committerbugmaster <bugmaster@opencascade.com>
Tue, 9 Jun 2020 17:01:06 +0000 (20:01 +0300)
src/BRepTools/BRepTools.cxx
src/BRepTools/BRepTools.hxx
src/DBRep/DBRep.cxx
tests/bugs/moddata_3/bug31587_1 [new file with mode: 0644]
tests/bugs/moddata_3/bug31587_2 [new file with mode: 0644]
tests/bugs/moddata_3/bug31587_3 [new file with mode: 0644]
tests/bugs/moddata_3/bug31587_4 [new file with mode: 0644]
tests/bugs/moddata_3/bug31587_5 [new file with mode: 0644]
tests/bugs/moddata_3/bug31587_6 [new file with mode: 0644]
tests/bugs/moddata_3/bug31587_7 [new file with mode: 0644]
tests/bugs/moddata_3/bug31587_8 [new file with mode: 0644]

index cc38b3a..2af4d61 100644 (file)
@@ -1156,3 +1156,112 @@ TopAbs_Orientation BRepTools::OriEdgeInFace (const TopoDS_Edge& E,
   }
   throw Standard_ConstructionError("BRepTools::OriEdgeInFace");
 }
+
+
+namespace
+{
+  //=======================================================================
+  //function : findInternalsToKeep
+  //purpose  : Looks for internal sub-shapes which has to be kept to preserve
+  //           topological connectivity.
+  //=======================================================================
+  static void findInternalsToKeep (const TopoDS_Shape& theS,
+                                   TopTools_MapOfShape& theAllNonInternals,
+                                   TopTools_MapOfShape& theAllInternals,
+                                   TopTools_MapOfShape& theShapesToKeep)
+  {
+    for (TopoDS_Iterator it (theS, Standard_True); it.More(); it.Next())
+    {
+      const TopoDS_Shape& aSS = it.Value();
+      findInternalsToKeep (aSS, theAllNonInternals, theAllInternals, theShapesToKeep);
+
+      if (aSS.Orientation() == TopAbs_INTERNAL)
+        theAllInternals.Add (aSS);
+      else
+        theAllNonInternals.Add (aSS);
+
+      if (theAllNonInternals.Contains(aSS) && theAllInternals.Contains (aSS))
+        theShapesToKeep.Add (aSS);
+    }
+  }
+
+  //=======================================================================
+  //function : removeShapes
+  //purpose  : Removes sub-shapes from the shape
+  //=======================================================================
+  static void removeShapes (TopoDS_Shape& theS,
+                            const TopTools_ListOfShape& theLS)
+  {
+    BRep_Builder aBB;
+    Standard_Boolean isFree = theS.Free();
+    theS.Free (Standard_True);
+
+    for (TopTools_ListOfShape::Iterator it (theLS); it.More(); it.Next())
+    {
+      aBB.Remove (theS, it.Value());
+    }
+    theS.Free (isFree);
+  }
+
+  //=======================================================================
+  //function : removeInternals
+  //purpose  : Removes recursively all internal sub-shapes from the given shape.
+  //           Returns true if all sub-shapes have been removed from the shape.
+  //=======================================================================
+  static Standard_Boolean removeInternals (TopoDS_Shape& theS,
+                                           const TopTools_MapOfShape* theShapesToKeep)
+  {
+    TopTools_ListOfShape aLRemove;
+    for (TopoDS_Iterator it (theS, Standard_True); it.More(); it.Next())
+    {
+      const TopoDS_Shape& aSS = it.Value();
+      if (aSS.Orientation() == TopAbs_INTERNAL)
+      {
+        if (!theShapesToKeep || !theShapesToKeep->Contains (aSS))
+          aLRemove.Append (aSS);
+      }
+      else
+      {
+        if (removeInternals (*(TopoDS_Shape*)&aSS, theShapesToKeep))
+          aLRemove.Append (aSS);
+      }
+    }
+
+    Standard_Integer aNbSToRemove = aLRemove.Extent();
+    if (aNbSToRemove)
+    {
+      removeShapes (theS, aLRemove);
+      return (theS.NbChildren() == 0);
+    }
+    return Standard_False;
+  }
+
+}
+
+//=======================================================================
+//function : RemoveInternals
+//purpose  : 
+//=======================================================================
+void BRepTools::RemoveInternals (TopoDS_Shape& theS,
+                                 const Standard_Boolean theForce)
+{
+  TopTools_MapOfShape *pMKeep = NULL, aMKeep;
+  if (!theForce)
+  {
+    // Find all internal sub-shapes which has to be kept to preserve topological connectivity.
+    // Note that if the multi-connected shape is not directly contained in some shape,
+    // but as a part of bigger sub-shape which will be removed, the multi-connected
+    // shape is going to be removed also, breaking topological connectivity.
+    // For instance, <theS> is a compound of the face and edge, which does not
+    // belong to the face. The face contains internal wire and the edge shares
+    // the vertex with one of the vertices of that wire. The vertex is not directly
+    // contained in the face, thus will be removed as part of internal wire, and topological
+    // connectivity between edge and face will be lost.
+    TopTools_MapOfShape anAllNonInternals, anAllInternals;
+    findInternalsToKeep (theS, anAllNonInternals, anAllInternals, aMKeep);
+    if (aMKeep.Extent())
+      pMKeep = &aMKeep;
+  }
+
+  removeInternals (theS, pMKeep);
+}
index 1e1b916..cbc23eb 100644 (file)
@@ -238,6 +238,16 @@ public:
   Standard_EXPORT static TopAbs_Orientation OriEdgeInFace(const TopoDS_Edge& theEdge, 
                                                           const TopoDS_Face& theFace);
 
+  //! Removes internal sub-shapes from the shape.
+  //! The check on internal status is based on orientation of sub-shapes,
+  //! classification is not performed.
+  //! Before removal of internal sub-shapes the algorithm checks if such
+  //! removal is not going to break topological connectivity between sub-shapes.
+  //! The flag <theForce> if set to true disables the connectivity check and clears
+  //! the given shape from all sub-shapes with internal orientation.
+  Standard_EXPORT static void RemoveInternals (TopoDS_Shape& theS,
+                                               const Standard_Boolean theForce = Standard_False);
+
 
 protected:
 
index f5d8ad9..214ba8b 100644 (file)
@@ -1417,6 +1417,39 @@ static Standard_Integer binrestore(Draw_Interpretor& di, Standard_Integer n, con
 }
 
 //=======================================================================
+// removeinternals
+//=======================================================================
+static Standard_Integer removeInternals (Draw_Interpretor& di,
+                                         Standard_Integer n,
+                                         const char** a)
+{
+  if (n < 2)
+  {
+    di.PrintHelp (a[0]);
+    return 1;
+  }
+
+  TopoDS_Shape aShape = DBRep::Get (a[1]);
+  if (aShape.IsNull())
+  {
+    di << a[1] << "is a null shape\n";
+    return 1;
+  }
+
+  Standard_Boolean isForce = Standard_False;
+  if (n > 2)
+  {
+    isForce = (Draw::Atoi (a[2]) != 0);
+  }
+
+  BRepTools::RemoveInternals (aShape, isForce);
+
+  DBRep::Set (a[1], aShape);
+
+  return 0;
+}
+
+//=======================================================================
 //function : BasicCommands
 //purpose  : 
 //=======================================================================
@@ -1487,6 +1520,12 @@ void  DBRep::BasicCommands(Draw_Interpretor& theCommands)
   theCommands.Add("binrestore", "binrestore filename shape\n"
                   "\t\trestore the shape from the binary format file",
                   __FILE__, binrestore, g);
+
+  theCommands.Add ("removeinternals", "removeinternals shape [force flag {0/1}]"
+                   "\n\t\t             Removes sub-shapes with internal orientation from the shape.\n"
+                   "\n\t\t             Force flag disables the check on topological connectivity and"
+                                       "removes all internal sub-shapes\n",
+                  __FILE__, removeInternals, g);
 }
 
 //=======================================================================
diff --git a/tests/bugs/moddata_3/bug31587_1 b/tests/bugs/moddata_3/bug31587_1
new file mode 100644 (file)
index 0000000..b811bc4
--- /dev/null
@@ -0,0 +1,21 @@
+puts "================"
+puts "0031587: Modeling Data - Remove internal sub-shapes from the shape"
+puts "================"
+puts ""
+
+box b 10 10 10
+box b1 2 2 2 3 2 1
+explode b1 f
+
+bclearobjects
+bcleartools
+baddobjects b
+baddtools b1_1
+eval baddtools [explode b1_2 e]
+bfillds
+bsplit r
+
+removeinternals r
+
+checkshape r
+checknbshapes r -vertex 8 -edge 12 -wire 6 -face 6 -shell 1 -solid 1
diff --git a/tests/bugs/moddata_3/bug31587_2 b/tests/bugs/moddata_3/bug31587_2
new file mode 100644 (file)
index 0000000..671f613
--- /dev/null
@@ -0,0 +1,22 @@
+puts "================"
+puts "0031587: Modeling Data - Remove internal sub-shapes from the shape"
+puts "================"
+puts ""
+
+box b 10 10 10
+box b1 2 2 0 3 2 1
+explode b1 f
+
+bclearobjects
+bcleartools
+baddobjects b
+baddtools b1_1
+eval baddtools [explode b1_2 e]
+eval baddtools [explode b1_3 v]
+bfillds
+bsplit r
+
+removeinternals r
+
+checkshape r
+checknbshapes r -vertex 8 -edge 12 -wire 6 -face 6 -shell 1 -solid 1
diff --git a/tests/bugs/moddata_3/bug31587_3 b/tests/bugs/moddata_3/bug31587_3
new file mode 100644 (file)
index 0000000..96c5194
--- /dev/null
@@ -0,0 +1,34 @@
+puts "================"
+puts "0031587: Modeling Data - Remove internal sub-shapes from the shape"
+puts "================"
+puts ""
+
+box b 10 10 10
+box b1 2 2 -1 3 2 2
+explode b1 f
+
+bclearobjects
+bcleartools
+baddobjects b
+baddtools b1_1 b1_2
+bfillds
+bsplit r
+
+removeinternals r
+
+checkshape r
+checknbshapes r -vertex 8 -edge 12 -wire 6 -face 6 -shell 1 -solid 1
+
+bbuild r
+bbuild r1
+removeinternals r1 0
+
+checkshape r1
+checknbshapes r1 -ref [nbshapes r]
+
+removeinternals r1 1
+checkshape r1
+checknbshapes r1 -vertex 20 -edge 26 -wire 10 -face 10 -shell 1 -solid 1
+
+explode r1 so
+checknbshapes r1_1 -vertex 8 -edge 12 -wire 6 -face 6 -shell 1 -solid 1
diff --git a/tests/bugs/moddata_3/bug31587_4 b/tests/bugs/moddata_3/bug31587_4
new file mode 100644 (file)
index 0000000..9bc0826
--- /dev/null
@@ -0,0 +1,20 @@
+puts "================"
+puts "0031587: Modeling Data - Remove internal sub-shapes from the shape"
+puts "================"
+puts ""
+
+box b 10 10 10
+box b1 2 2 0 5 5 5
+explode b1 f
+bclearobjects
+bcleartools
+baddobjects b
+baddtools b1_2 b1_3
+eval baddtools [explode b1_1 w]
+bfillds
+bsplit r
+
+removeinternals r
+
+checkshape r
+checknbshapes r -vertex 8 -edge 12 -wire 6 -face 6 -shell 1 -solid 1
diff --git a/tests/bugs/moddata_3/bug31587_5 b/tests/bugs/moddata_3/bug31587_5
new file mode 100644 (file)
index 0000000..e06e4a9
--- /dev/null
@@ -0,0 +1,23 @@
+puts "================"
+puts "0031587: Modeling Data - Remove internal sub-shapes from the shape"
+puts "================"
+puts ""
+
+box b 10 10 10
+box b1 2 2 0 5 5 5
+box b2 3 2 2 4 5 2
+explode b1 f
+explode b2 f
+bclearobjects
+bcleartools
+baddobjects b
+baddtools b1_2 b1_3
+eval baddtools [explode b1_1 w]
+baddtools b2_5 b2_6
+bfillds
+bsplit r
+
+removeinternals r
+
+checkshape r
+checknbshapes r -vertex 8 -edge 12 -wire 6 -face 6 -shell 1 -solid 1
diff --git a/tests/bugs/moddata_3/bug31587_6 b/tests/bugs/moddata_3/bug31587_6
new file mode 100644 (file)
index 0000000..58a631e
--- /dev/null
@@ -0,0 +1,23 @@
+puts "================"
+puts "0031587: Modeling Data - Remove internal sub-shapes from the shape"
+puts "================"
+puts ""
+
+box b 10 10 10
+polyline e1 2 2 0 8 2 0
+polyline e2 3 2 -5 3 2 0
+
+bclearobjects
+bcleartools
+baddobjects b
+baddtools e1 e2
+bfillds
+bsplit r
+
+compound r e2 c
+
+# topological connectivity is broken without force flag set to true
+removeinternals c
+
+checkshape c
+checknbshapes c -vertex 10 -edge 13 -wire 7 -face 6 -shell 1 -solid 1
diff --git a/tests/bugs/moddata_3/bug31587_7 b/tests/bugs/moddata_3/bug31587_7
new file mode 100644 (file)
index 0000000..0d12f2b
--- /dev/null
@@ -0,0 +1,11 @@
+puts "================"
+puts "0031587: Modeling Data - Remove internal sub-shapes from the shape"
+puts "================"
+puts ""
+
+restore [locate_data_file bug31587_wall1.brep] s
+removeinternals s
+
+checkshape s
+checknbshapes s -vertex 6 -edge 6 -wire 1 -face 1
+
diff --git a/tests/bugs/moddata_3/bug31587_8 b/tests/bugs/moddata_3/bug31587_8
new file mode 100644 (file)
index 0000000..35b056e
--- /dev/null
@@ -0,0 +1,10 @@
+puts "================"
+puts "0031587: Modeling Data - Remove internal sub-shapes from the shape"
+puts "================"
+puts ""
+
+restore [locate_data_file bug31587_wall12.brep] s
+removeinternals s
+
+checkshape s
+checknbshapes s -vertex 16 -edge 16 -wire 3 -face 3