}
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);
+}
return 0;
}
+//=======================================================================
+// 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 :
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);
}
//=======================================================================