diff --git a/src/BRep/BRep_Tool.cxx b/src/BRep/BRep_Tool.cxx index d4bade16eb..defb2cdcde 100644 --- a/src/BRep/BRep_Tool.cxx +++ b/src/BRep/BRep_Tool.cxx @@ -206,6 +206,17 @@ Handle(Geom_Curve) BRep_Tool::Curve(const TopoDS_Edge& E, return C; } +//======================================================================= +//function : IsGeometric +//purpose : Returns True if has a surface. +//======================================================================= +Standard_Boolean BRep_Tool::IsGeometric (const TopoDS_Face& F) +{ + const BRep_TFace* TF = static_cast(F.TShape().get()); + const Handle(Geom_Surface)& S = TF->Surface(); + return !S.IsNull(); +} + //======================================================================= //function : IsGeometric //purpose : Returns True if is a 3d curve or a curve on diff --git a/src/BRep/BRep_Tool.hxx b/src/BRep/BRep_Tool.hxx index fa6efbe69d..12c061cde9 100644 --- a/src/BRep/BRep_Tool.hxx +++ b/src/BRep/BRep_Tool.hxx @@ -74,6 +74,9 @@ public: //! Returns the NaturalRestriction flag of the face. Standard_EXPORT static Standard_Boolean NaturalRestriction (const TopoDS_Face& F); + //! Returns True if has a surface, false otherwise. + Standard_EXPORT static Standard_Boolean IsGeometric (const TopoDS_Face& F); + //! Returns True if is a 3d curve or a curve on //! surface. Standard_EXPORT static Standard_Boolean IsGeometric (const TopoDS_Edge& E); diff --git a/src/BRepTools/BRepTools.cxx b/src/BRepTools/BRepTools.cxx index ae2cb9dce4..eb178570de 100644 --- a/src/BRepTools/BRepTools.cxx +++ b/src/BRepTools/BRepTools.cxx @@ -62,6 +62,7 @@ #include #include #include +#include #include #include //======================================================================= @@ -843,19 +844,36 @@ Standard_Boolean BRepTools::Read(TopoDS_Shape& Sh, //purpose : //======================================================================= -void BRepTools::Clean(const TopoDS_Shape& theShape) +void BRepTools::Clean (const TopoDS_Shape& theShape) { + if (theShape.IsNull()) + return; + BRep_Builder aBuilder; Handle(Poly_Triangulation) aNullTriangulation; Handle(Poly_PolygonOnTriangulation) aNullPoly; - if (theShape.IsNull()) - return; + TopTools_MapOfShape aShapeMap; + const TopLoc_Location anEmptyLoc; TopExp_Explorer aFaceIt(theShape, TopAbs_FACE); for (; aFaceIt.More(); aFaceIt.Next()) { - const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current()); + TopoDS_Shape aFaceNoLoc = aFaceIt.Current(); + aFaceNoLoc.Location (anEmptyLoc); + if (!aShapeMap.Add (aFaceNoLoc)) + { + // the face has already been processed + continue; + } + + const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current()); + if (!BRep_Tool::IsGeometric (aFace)) + { + // Do not remove triangulation as there is no surface to recompute it. + continue; + } + TopLoc_Location aLoc; const Handle(Poly_Triangulation)& aTriangulation = @@ -865,6 +883,10 @@ void BRepTools::Clean(const TopoDS_Shape& theShape) continue; // Nullify edges + // Theoretically, the edges on the face (with surface) may have no geometry + // (no curve 3d or 2d or both). Such faces should be considered as invalid and + // are not supported by current implementation. So, both triangulation of the face + // and polygon on triangulation of the edges are removed unconditionally. TopExp_Explorer aEdgeIt(aFace, TopAbs_EDGE); for (; aEdgeIt.More(); aEdgeIt.Next()) { @@ -874,8 +896,34 @@ void BRepTools::Clean(const TopoDS_Shape& theShape) aBuilder.UpdateFace(aFace, aNullTriangulation); } -} + // Iterate over all edges seeking for 3d polygons + Handle (Poly_Polygon3D) aNullPoly3d; + TopExp_Explorer aEdgeIt (theShape, TopAbs_EDGE); + for (; aEdgeIt.More (); aEdgeIt.Next ()) + { + TopoDS_Edge anEdgeNoLoc = TopoDS::Edge (aEdgeIt.Current()); + anEdgeNoLoc.Location (anEmptyLoc); + + if (!aShapeMap.Add (anEdgeNoLoc)) + { + // the edge has already been processed + continue; + } + if (!BRep_Tool::IsGeometric (TopoDS::Edge (anEdgeNoLoc))) + { + // Do not remove polygon 3d as there is no curve to recompute it. + continue; + } + + TopLoc_Location aLoc; + Handle (Poly_Polygon3D) aPoly3d = BRep_Tool::Polygon3D (anEdgeNoLoc, aLoc); + if (aPoly3d.IsNull()) + continue; + + aBuilder.UpdateEdge (anEdgeNoLoc, aNullPoly3d); + } +} //======================================================================= //function : RemoveUnusedPCurves //purpose : diff --git a/src/BRepTools/BRepTools.hxx b/src/BRepTools/BRepTools.hxx index cc49cc1044..74ca6749e2 100644 --- a/src/BRepTools/BRepTools.hxx +++ b/src/BRepTools/BRepTools.hxx @@ -152,9 +152,11 @@ public: //! same point at there common extremity. Standard_EXPORT static void UpdateFaceUVPoints (const TopoDS_Face& F); - //! Removes all the triangulations of the faces of - //! and removes all polygons on triangulations of the - //! edges. + //! Removes all cashed polygonal representation of the shape, + //! i.e. the triangulations of the faces of and polygons on + //! triangulations and polygons 3d of the edges. + //! In case polygonal representation is the only available representation + //! for the shape (shape does not have geometry) it is not removed. Standard_EXPORT static void Clean (const TopoDS_Shape& S); //! Removes all the pcurves of the edges of that