#include <BndLib_Add2dCurve.hxx>
#include <BRep_Builder.hxx>
#include <BRep_CurveRepresentation.hxx>
-#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
+#include <BRep_GCurve.hxx>
+#include <BRep_ListOfCurveRepresentation.hxx>
#include <BRep_TEdge.hxx>
#include <BRep_Tool.hxx>
#include <BRepTools.hxx>
#include <BRepTools_MapOfVertexPnt2d.hxx>
#include <BRepTools_ShapeSet.hxx>
+#include <BRepAdaptor_Surface.hxx>
#include <ElCLib.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2dAdaptor_Curve.hxx>
#include <TopoDS_CompSolid.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
-#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Solid.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <GeomLib_CheckCurveOnSurface.hxx>
#include <errno.h>
+
+
//=======================================================================
//function : UVBounds
//purpose :
}
}
-
//=======================================================================
//function : UpdateFaceUVPoints
-//purpose : reset the UV points of a Face
+//purpose : Reset the UV points of edges on the Face
//=======================================================================
-
-void BRepTools::UpdateFaceUVPoints(const TopoDS_Face& F)
+void BRepTools::UpdateFaceUVPoints(const TopoDS_Face& theF)
{
- // Recompute for each edge the two UV points in order to have the same
- // UV point on connected edges.
-
- // First edge loop, store the vertices in a Map with their 2d points
-
- BRepTools_MapOfVertexPnt2d theVertices;
- TopoDS_Iterator expE,expV;
- TopoDS_Iterator EdgeIt,VertIt;
- TColStd_SequenceOfReal aFSeq, aLSeq;
- TColGeom2d_SequenceOfCurve aCSeq;
- TopTools_SequenceOfShape aShSeq;
- gp_Pnt2d P;
- Standard_Integer i;
- // a 3d tolerance for UV !!
- Standard_Real tolerance = BRep_Tool::Tolerance(F);
- TColgp_SequenceOfPnt2d emptySequence;
-
- for (expE.Initialize(F); expE.More(); expE.Next()) {
- if(expE.Value().ShapeType() != TopAbs_WIRE)
- continue;
-
- EdgeIt.Initialize(expE.Value());
- for( ; EdgeIt.More(); EdgeIt.Next())
- {
- const TopoDS_Edge& E = TopoDS::Edge(EdgeIt.Value());
- Standard_Real f,l;
- Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,f,l);
-
- aFSeq.Append(f);
- aLSeq.Append(l);
- aCSeq.Append(C);
- aShSeq.Append(E);
-
- if (C.IsNull()) continue;
-
- for (expV.Initialize(E.Oriented(TopAbs_FORWARD));
- expV.More(); expV.Next()) {
-
- const TopoDS_Vertex& V = TopoDS::Vertex(expV.Value());
-
- TopAbs_Orientation Vori = V.Orientation();
- if ( Vori == TopAbs_INTERNAL ) {
- continue;
- }
-
- Standard_Real p = BRep_Tool::Parameter(V,E,F);
- C->D0(p,P);
- if (!theVertices.IsBound(V))
- theVertices.Bind(V,emptySequence);
- TColgp_SequenceOfPnt2d& S = theVertices(V);
- for (i = 1; i <= S.Length(); i++) {
- if (P.Distance(S(i)) < tolerance) break;
- }
- if (i > S.Length())
- S.Append(P);
- }
- }
- }
-
- // second edge loop, update the edges 2d points
- TopoDS_Vertex Vf,Vl;
- gp_Pnt2d Pf,Pl;
+ // For each edge of the face <F> reset the UV points to the bounding
+ // points of the parametric curve of the edge on the face.
- for(Standard_Integer j = 1; j <= aShSeq.Length(); j++)
+ // Get surface of the face
+ TopLoc_Location aLoc;
+ const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(theF, aLoc);
+ // Iterate on edges and reset UV points
+ TopExp_Explorer anExpE(theF, TopAbs_EDGE);
+ for (; anExpE.More(); anExpE.Next())
{
- const TopoDS_Edge& E = TopoDS::Edge(aShSeq.Value(j));
- const Handle(Geom2d_Curve)& C = aCSeq.Value(j);
- if (C.IsNull()) continue;
-
- TopExp::Vertices(E,Vf,Vl);
- if (Vf.IsNull()) {
- Pf.SetCoord(RealLast(),RealLast());
- }
- else {
- if ( Vf.Orientation() == TopAbs_INTERNAL ) {
- continue;
- }
- const TColgp_SequenceOfPnt2d& seqf = theVertices(Vf);
- if (seqf.Length() == 1)
- Pf = seqf(1);
- else {
- C->D0(aFSeq.Value(j),Pf);
- for (i = 1; i <= seqf.Length(); i++) {
- if (Pf.Distance(seqf(i)) <= tolerance) {
- Pf = seqf(i);
- break;
- }
- }
- }
- }
- if (Vl.IsNull()) {
- Pl.SetCoord(RealLast(),RealLast());
- }
- else {
- if ( Vl.Orientation() == TopAbs_INTERNAL ) {
- continue;
- }
- const TColgp_SequenceOfPnt2d& seql = theVertices(Vl);
- if (seql.Length() == 1)
- Pl = seql(1);
- else {
- C->D0(aLSeq.Value(j),Pl);
- for (i = 1; i <= seql.Length(); i++) {
- if (Pl.Distance(seql(i)) <= tolerance) {
- Pl = seql(i);
- break;
- }
- }
+ const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current());
+
+ const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
+ if (TE->Locked())
+ return;
+
+ const TopLoc_Location aELoc = aLoc.Predivided(aE.Location());
+ // Edge representations
+ BRep_ListOfCurveRepresentation& aLCR = TE->ChangeCurves();
+ BRep_ListIteratorOfListOfCurveRepresentation itLCR(aLCR);
+ for (; itLCR.More(); itLCR.Next())
+ {
+ Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itLCR.Value());
+ if (!GC.IsNull() && GC->IsCurveOnSurface(aSurf, aELoc))
+ {
+ // Update UV points
+ GC->Update();
+ break;
}
}
-
- // set the correct points
- BRep_Tool::SetUVPoints(E,F,Pf,Pl);
}
}
-
-
//=======================================================================
//function : Compare
//purpose :
//=======================================================================
void BRepTools::Read(TopoDS_Shape& Sh,
- istream& S,
+ std::istream& S,
const BRep_Builder& B,
const Handle(Message_ProgressIndicator)& PR)
{
const Standard_CString File,
const Handle(Message_ProgressIndicator)& PR)
{
- ofstream os;
- OSD_OpenStream(os, File, ios::out);
- if (!os.rdbuf()->is_open()) return Standard_False;
+ std::ofstream os;
+ OSD_OpenStream(os, File, std::ios::out);
+ if (!os.is_open() || !os.good())
+ return Standard_False;
Standard_Boolean isGood = (os.good() && !os.eof());
if(!isGood)
const BRep_Builder& B,
const Handle(Message_ProgressIndicator)& PR)
{
- filebuf fic;
- istream in(&fic);
- OSD_OpenFileBuf(fic,File,ios::in);
+ std::filebuf fic;
+ std::istream in(&fic);
+ OSD_OpenStream (fic, File, std::ios::in);
if(!fic.is_open()) return Standard_False;
BRepTools_ShapeSet SS(B);
//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.Value();
+ 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 =
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())
{
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.Value());
+ 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 : CleanGeometry
+//purpose :
+//=======================================================================
+
+void BRepTools::CleanGeometry(const TopoDS_Shape& theShape)
+{
+ if (theShape.IsNull())
+ return;
+
+ BRep_Builder aBuilder;
+
+ for (TopExp_Explorer aFaceIt(theShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
+ {
+ TopLoc_Location aLocation;
+ const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
+ const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(aFace, aLocation);
+
+ for (TopExp_Explorer aEdgeIt(aFace, TopAbs_EDGE); aEdgeIt.More(); aEdgeIt.Next())
+ {
+ const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt.Current());
+ aBuilder.UpdateEdge(anEdge, Handle(Geom2d_Curve)(), aSurface,
+ aLocation, BRep_Tool::Tolerance(anEdge));
+ }
+
+ aBuilder.UpdateFace(aFace, Handle(Geom_Surface)(), aFace.Location(), BRep_Tool::Tolerance(aFace));
+ }
+
+ for (TopExp_Explorer aEdgeIt2(theShape, TopAbs_EDGE); aEdgeIt2.More(); aEdgeIt2.Next())
+ {
+ const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt2.Current());
+
+ aBuilder.UpdateEdge(anEdge, Handle(Geom_Curve)(),
+ TopLoc_Location(), BRep_Tool::Tolerance(anEdge));
+ }
}
+
//=======================================================================
//function : RemoveUnusedPCurves
//purpose :
//purpose :
//=======================================================================
-Standard_Boolean BRepTools::Triangulation(const TopoDS_Shape& S,
- const Standard_Real deflec)
+Standard_Boolean BRepTools::Triangulation(const TopoDS_Shape& theShape,
+ const Standard_Real theLinDefl,
+ const Standard_Boolean theToCheckFreeEdges)
{
- TopExp_Explorer exf, exe;
- TopLoc_Location l;
- Handle(Poly_Triangulation) T;
- Handle(Poly_PolygonOnTriangulation) Poly;
-
- for (exf.Init(S, TopAbs_FACE); exf.More(); exf.Next()) {
- const TopoDS_Face& F = TopoDS::Face(exf.Current());
- T = BRep_Tool::Triangulation(F, l);
- if (T.IsNull() || (T->Deflection() > deflec))
+ TopExp_Explorer anEdgeIter;
+ TopLoc_Location aDummyLoc;
+ for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
+ {
+ const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Current());
+ const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation (aFace, aDummyLoc);
+ if (aTri.IsNull()
+ || aTri->Deflection() > theLinDefl)
+ {
return Standard_False;
- for (exe.Init(F, TopAbs_EDGE); exe.More(); exe.Next()) {
- const TopoDS_Edge& E = TopoDS::Edge(exe.Current());
- Poly = BRep_Tool::PolygonOnTriangulation(E, T, l);
- if (Poly.IsNull()) return Standard_False;
+ }
+
+ for (anEdgeIter.Init (aFace, TopAbs_EDGE); anEdgeIter.More(); anEdgeIter.Next())
+ {
+ const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Current());
+ const Handle(Poly_PolygonOnTriangulation)& aPoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTri, aDummyLoc);
+ if (aPoly.IsNull())
+ {
+ return Standard_False;
+ }
+ }
+ }
+ if (!theToCheckFreeEdges)
+ {
+ return Standard_True;
+ }
+
+ Handle(Poly_Triangulation) anEdgeTri;
+ for (anEdgeIter.Init (theShape, TopAbs_EDGE, TopAbs_FACE); anEdgeIter.More(); anEdgeIter.Next())
+ {
+ const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Current());
+ const Handle(Poly_Polygon3D)& aPolygon = BRep_Tool::Polygon3D (anEdge, aDummyLoc);
+ if (!aPolygon.IsNull())
+ {
+ if (aPolygon->Deflection() > theLinDefl)
+ {
+ return Standard_False;
+ }
+ }
+ else
+ {
+ const Handle(Poly_PolygonOnTriangulation)& aPoly = BRep_Tool::PolygonOnTriangulation (anEdge, anEdgeTri, aDummyLoc);
+ if (aPoly.IsNull()
+ || anEdgeTri.IsNull()
+ || anEdgeTri->Deflection() > theLinDefl)
+ {
+ return Standard_False;
+ }
}
}
+
return Standard_True;
}
return nbocc == 2;
}
+//=======================================================================
+//function : DetectClosedness
+//purpose :
+//=======================================================================
+
+void BRepTools::DetectClosedness(const TopoDS_Face& theFace,
+ Standard_Boolean& theUclosed,
+ Standard_Boolean& theVclosed)
+{
+ theUclosed = theVclosed = Standard_False;
+
+ TopExp_Explorer Explo(theFace, TopAbs_EDGE);
+ for (; Explo.More(); Explo.Next())
+ {
+ const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
+ if (BRep_Tool::IsClosed(anEdge, theFace) &&
+ BRepTools::IsReallyClosed(anEdge, theFace))
+ {
+ Standard_Real fpar, lpar;
+ Handle(Geom2d_Curve) PCurve1 = BRep_Tool::CurveOnSurface(anEdge, theFace, fpar, lpar);
+ Handle(Geom2d_Curve) PCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(anEdge.Reversed()),
+ theFace, fpar, lpar);
+ gp_Pnt2d Point1 = PCurve1->Value(fpar);
+ gp_Pnt2d Point2 = PCurve2->Value(fpar);
+ Standard_Boolean IsUiso = (Abs(Point1.X() - Point2.X()) > Abs(Point1.Y() - Point2.Y()));
+ if (IsUiso)
+ theUclosed = Standard_True;
+ else
+ theVclosed = Standard_True;
+ }
+ }
+}
+
//=======================================================================
//function : EvalAndUpdateTol
//purpose :
}
+//=======================================================================
+//function : OriEdgeInFace
+//purpose :
+//=======================================================================
+
+TopAbs_Orientation BRepTools::OriEdgeInFace (const TopoDS_Edge& E,
+ const TopoDS_Face& F )
+
+{
+ TopExp_Explorer Exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
+
+ for (; Exp.More() ;Exp.Next()) {
+ if (Exp.Current().IsSame(E)) {
+ return Exp.Current().Orientation();
+ }
+ }
+ 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);
+}