1 // Created on: 1993-01-21
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Bnd_Box2d.hxx>
19 #include <BndLib_Add2dCurve.hxx>
20 #include <BRep_Builder.hxx>
21 #include <BRep_CurveRepresentation.hxx>
22 #include <BRep_GCurve.hxx>
23 #include <BRep_ListOfCurveRepresentation.hxx>
24 #include <BRep_TEdge.hxx>
25 #include <BRep_Tool.hxx>
26 #include <BRepTools.hxx>
27 #include <BRepTools_MapOfVertexPnt2d.hxx>
28 #include <BRepTools_ShapeSet.hxx>
29 #include <BRepAdaptor_Surface.hxx>
31 #include <Geom2d_Curve.hxx>
32 #include <Geom2dAdaptor_Curve.hxx>
33 #include <Geom_BSplineSurface.hxx>
34 #include <Geom_Curve.hxx>
35 #include <Geom_RectangularTrimmedSurface.hxx>
36 #include <Geom_Surface.hxx>
37 #include <gp_Lin2d.hxx>
38 #include <gp_Vec2d.hxx>
39 #include <Message_ProgressIndicator.hxx>
40 #include <OSD_OpenFile.hxx>
41 #include <Poly_PolygonOnTriangulation.hxx>
42 #include <Poly_Triangulation.hxx>
43 #include <Precision.hxx>
44 #include <Standard_ErrorHandler.hxx>
45 #include <Standard_Failure.hxx>
46 #include <Standard_Stream.hxx>
47 #include <TColGeom2d_SequenceOfCurve.hxx>
48 #include <TColgp_SequenceOfPnt2d.hxx>
49 #include <TColStd_Array1OfReal.hxx>
50 #include <TColStd_HArray1OfInteger.hxx>
51 #include <TColStd_MapOfTransient.hxx>
52 #include <TColStd_SequenceOfReal.hxx>
54 #include <TopExp_Explorer.hxx>
56 #include <TopoDS_Compound.hxx>
57 #include <TopoDS_CompSolid.hxx>
58 #include <TopoDS_Edge.hxx>
59 #include <TopoDS_Face.hxx>
60 #include <TopoDS_Shape.hxx>
61 #include <TopoDS_Shell.hxx>
62 #include <TopoDS_Solid.hxx>
63 #include <TopoDS_Vertex.hxx>
64 #include <TopoDS_Wire.hxx>
65 #include <TopTools_SequenceOfShape.hxx>
66 #include <GeomLib_CheckCurveOnSurface.hxx>
70 //=======================================================================
73 //=======================================================================
74 void BRepTools::UVBounds(const TopoDS_Face& F,
75 Standard_Real& UMin, Standard_Real& UMax,
76 Standard_Real& VMin, Standard_Real& VMax)
82 B.Get(UMin,VMin,UMax,VMax);
86 UMin = UMax = VMin = VMax = 0.0;
90 //=======================================================================
93 //=======================================================================
95 void BRepTools::UVBounds(const TopoDS_Face& F,
97 Standard_Real& UMin, Standard_Real& UMax,
98 Standard_Real& VMin, Standard_Real& VMax)
104 B.Get(UMin,VMin,UMax,VMax);
108 UMin = UMax = VMin = VMax = 0.0;
113 //=======================================================================
114 //function : UVBounds
116 //=======================================================================
118 void BRepTools::UVBounds(const TopoDS_Face& F,
119 const TopoDS_Edge& E,
120 Standard_Real& UMin, Standard_Real& UMax,
121 Standard_Real& VMin, Standard_Real& VMax)
127 B.Get(UMin,VMin,UMax,VMax);
131 UMin = UMax = VMin = VMax = 0.0;
135 //=======================================================================
136 //function : AddUVBounds
138 //=======================================================================
140 void BRepTools::AddUVBounds(const TopoDS_Face& FF, Bnd_Box2d& B)
143 F.Orientation(TopAbs_FORWARD);
144 TopExp_Explorer ex(F,TopAbs_EDGE);
146 // fill box for the given face
148 for (;ex.More();ex.Next()) {
149 BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),aBox);
152 // if the box is empty (face without edges or without pcurves),
153 // get natural bounds
155 Standard_Real UMin,UMax,VMin,VMax;
157 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(F, L);
163 aSurf->Bounds(UMin,UMax,VMin,VMax);
164 aBox.Update(UMin,VMin,UMax,VMax);
167 // add face box to result
172 //=======================================================================
173 //function : AddUVBounds
175 //=======================================================================
176 void BRepTools::AddUVBounds(const TopoDS_Face& F,
177 const TopoDS_Wire& W,
181 for (ex.Init(W,TopAbs_EDGE);ex.More();ex.Next()) {
182 BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),B);
187 //=======================================================================
188 //function : AddUVBounds
190 //=======================================================================
191 void BRepTools::AddUVBounds(const TopoDS_Face& aF,
192 const TopoDS_Edge& aE,
195 Standard_Real aT1, aT2, aXmin = 0.0, aYmin = 0.0, aXmax = 0.0, aYmax = 0.0;
196 Standard_Real aUmin, aUmax, aVmin, aVmax;
197 Bnd_Box2d aBoxC, aBoxS;
198 TopLoc_Location aLoc;
200 const Handle(Geom2d_Curve) aC2D = BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
205 BndLib_Add2dCurve::Add(aC2D, aT1, aT2, 0., aBoxC);
208 aBoxC.Get(aXmin, aYmin, aXmax, aYmax);
211 Handle(Geom_Surface) aS = BRep_Tool::Surface(aF, aLoc);
212 aS->Bounds(aUmin, aUmax, aVmin, aVmax);
214 if(aS->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
216 const Handle(Geom_RectangularTrimmedSurface) aSt =
217 Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
218 aS = aSt->BasisSurface();
222 if(!aS->IsUPeriodic())
224 Standard_Boolean isUPeriodic = Standard_False;
226 // Additional verification for U-periodicity for B-spline surfaces
227 // 1. Verify that the surface is U-closed (if such flag is false). Verification uses 2 points
228 // 2. Verify periodicity of surface inside UV-bounds of the edge. Verification uses 3 or 6 points.
229 if (aS->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface) &&
230 (aXmin < aUmin || aXmax > aUmax))
232 Standard_Real aTol2 = 100 * Precision::Confusion() * Precision::Confusion();
233 isUPeriodic = Standard_True;
235 // 1. Verify that the surface is U-closed
236 if (!aS->IsUClosed())
238 Standard_Real aVStep = aVmax - aVmin;
239 for (Standard_Real aV = aVmin; aV <= aVmax; aV += aVStep)
241 P1 = aS->Value(aUmin, aV);
242 P2 = aS->Value(aUmax, aV);
243 if (P1.SquareDistance(P2) > aTol2)
245 isUPeriodic = Standard_False;
250 // 2. Verify periodicity of surface inside UV-bounds of the edge
251 if (isUPeriodic) // the flag still not changed
253 Standard_Real aV = (aVmin + aVmax) * 0.5;
254 Standard_Real aU[6]; // values of U lying out of surface boundaries
255 Standard_Real aUpp[6]; // corresponding U-values plus/minus period
256 Standard_Integer aNbPnt = 0;
260 aU[1] = (aXmin + aUmin) * 0.5;
262 aUpp[0] = aU[0] + aUmax - aUmin;
263 aUpp[1] = aU[1] + aUmax - aUmin;
264 aUpp[2] = aU[2] + aUmax - aUmin;
270 aU[aNbPnt + 1] = (aXmax + aUmax) * 0.5;
271 aU[aNbPnt + 2] = aXmax;
272 aUpp[aNbPnt] = aU[aNbPnt] - aUmax + aUmin;
273 aUpp[aNbPnt + 1] = aU[aNbPnt + 1] - aUmax + aUmin;
274 aUpp[aNbPnt + 2] = aU[aNbPnt + 2] - aUmax + aUmin;
277 for (Standard_Integer anInd = 0; anInd < aNbPnt; anInd++)
279 P1 = aS->Value(aU[anInd], aV);
280 P2 = aS->Value(aUpp[anInd], aV);
281 if (P1.SquareDistance(P2) > aTol2)
283 isUPeriodic = Standard_False;
292 if((aXmin<aUmin) && (aUmin < aXmax))
296 if((aXmin < aUmax) && (aUmax < aXmax))
303 if(!aS->IsVPeriodic())
305 Standard_Boolean isVPeriodic = Standard_False;
307 // Additional verification for V-periodicity for B-spline surfaces
308 // 1. Verify that the surface is V-closed (if such flag is false). Verification uses 2 points
309 // 2. Verify periodicity of surface inside UV-bounds of the edge. Verification uses 3 or 6 points.
310 if (aS->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface) &&
311 (aYmin < aVmin || aYmax > aVmax))
313 Standard_Real aTol2 = 100 * Precision::Confusion() * Precision::Confusion();
314 isVPeriodic = Standard_True;
316 // 1. Verify that the surface is V-closed
317 if (!aS->IsVClosed())
319 Standard_Real aUStep = aUmax - aUmin;
320 for (Standard_Real aU = aUmin; aU <= aUmax; aU += aUStep)
322 P1 = aS->Value(aU, aVmin);
323 P2 = aS->Value(aU, aVmax);
324 if (P1.SquareDistance(P2) > aTol2)
326 isVPeriodic = Standard_False;
331 // 2. Verify periodicity of surface inside UV-bounds of the edge
332 if (isVPeriodic) // the flag still not changed
334 Standard_Real aU = (aUmin + aUmax) * 0.5;
335 Standard_Real aV[6]; // values of V lying out of surface boundaries
336 Standard_Real aVpp[6]; // corresponding V-values plus/minus period
337 Standard_Integer aNbPnt = 0;
341 aV[1] = (aYmin + aVmin) * 0.5;
343 aVpp[0] = aV[0] + aVmax - aVmin;
344 aVpp[1] = aV[1] + aVmax - aVmin;
345 aVpp[2] = aV[2] + aVmax - aVmin;
351 aV[aNbPnt + 1] = (aYmax + aVmax) * 0.5;
352 aV[aNbPnt + 2] = aYmax;
353 aVpp[aNbPnt] = aV[aNbPnt] - aVmax + aVmin;
354 aVpp[aNbPnt + 1] = aV[aNbPnt + 1] - aVmax + aVmin;
355 aVpp[aNbPnt + 2] = aV[aNbPnt + 2] - aVmax + aVmin;
358 for (Standard_Integer anInd = 0; anInd < aNbPnt; anInd++)
360 P1 = aS->Value(aU, aV[anInd]);
361 P2 = aS->Value(aU, aVpp[anInd]);
362 if (P1.SquareDistance(P2) > aTol2)
364 isVPeriodic = Standard_False;
373 if((aYmin<aVmin) && (aVmin < aYmax))
377 if((aYmin < aVmax) && (aVmax < aYmax))
384 aBoxS.Update(aXmin, aYmin, aXmax, aYmax);
389 //=======================================================================
392 //=======================================================================
394 void BRepTools::Update(const TopoDS_Vertex&)
398 //=======================================================================
401 //=======================================================================
403 void BRepTools::Update(const TopoDS_Edge&)
407 //=======================================================================
410 //=======================================================================
412 void BRepTools::Update(const TopoDS_Wire&)
416 //=======================================================================
419 //=======================================================================
421 void BRepTools::Update(const TopoDS_Face& F)
424 UpdateFaceUVPoints(F);
425 F.TShape()->Checked(Standard_True);
429 //=======================================================================
432 //=======================================================================
434 void BRepTools::Update(const TopoDS_Shell& S)
436 TopExp_Explorer ex(S,TopAbs_FACE);
438 Update(TopoDS::Face(ex.Current()));
443 //=======================================================================
446 //=======================================================================
448 void BRepTools::Update(const TopoDS_Solid& S)
450 TopExp_Explorer ex(S,TopAbs_FACE);
452 Update(TopoDS::Face(ex.Current()));
457 //=======================================================================
460 //=======================================================================
462 void BRepTools::Update(const TopoDS_CompSolid& CS)
464 TopExp_Explorer ex(CS,TopAbs_FACE);
466 Update(TopoDS::Face(ex.Current()));
471 //=======================================================================
474 //=======================================================================
476 void BRepTools::Update(const TopoDS_Compound& C)
478 TopExp_Explorer ex(C,TopAbs_FACE);
480 Update(TopoDS::Face(ex.Current()));
485 //=======================================================================
488 //=======================================================================
490 void BRepTools::Update(const TopoDS_Shape& S)
492 switch (S.ShapeType()) {
495 Update(TopoDS::Vertex(S));
499 Update(TopoDS::Edge(S));
503 Update(TopoDS::Wire(S));
507 Update(TopoDS::Face(S));
511 Update(TopoDS::Shell(S));
515 Update(TopoDS::Solid(S));
518 case TopAbs_COMPSOLID :
519 Update(TopoDS::CompSolid(S));
522 case TopAbs_COMPOUND :
523 Update(TopoDS::Compound(S));
532 //=======================================================================
533 //function : UpdateFaceUVPoints
534 //purpose : Reset the UV points of edges on the Face
535 //=======================================================================
536 void BRepTools::UpdateFaceUVPoints(const TopoDS_Face& theF)
538 // For each edge of the face <F> reset the UV points to the bounding
539 // points of the parametric curve of the edge on the face.
541 // Get surface of the face
542 TopLoc_Location aLoc;
543 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(theF, aLoc);
544 // Iterate on edges and reset UV points
545 TopExp_Explorer anExpE(theF, TopAbs_EDGE);
546 for (; anExpE.More(); anExpE.Next())
548 const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current());
550 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
554 const TopLoc_Location aELoc = aLoc.Predivided(aE.Location());
555 // Edge representations
556 BRep_ListOfCurveRepresentation& aLCR = TE->ChangeCurves();
557 BRep_ListIteratorOfListOfCurveRepresentation itLCR(aLCR);
558 for (; itLCR.More(); itLCR.Next())
560 Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itLCR.Value());
561 if (!GC.IsNull() && GC->IsCurveOnSurface(aSurf, aELoc))
571 //=======================================================================
574 //=======================================================================
576 Standard_Boolean BRepTools::Compare(const TopoDS_Vertex& V1,
577 const TopoDS_Vertex& V2)
579 if (V1.IsSame(V2)) return Standard_True;
580 gp_Pnt p1 = BRep_Tool::Pnt(V1);
581 gp_Pnt p2 = BRep_Tool::Pnt(V2);
582 Standard_Real l = p1.Distance(p2);
583 if (l <= BRep_Tool::Tolerance(V1)) return Standard_True;
584 if (l <= BRep_Tool::Tolerance(V2)) return Standard_True;
585 return Standard_False;
588 //=======================================================================
591 //=======================================================================
593 Standard_Boolean BRepTools::Compare(const TopoDS_Edge& E1,
594 const TopoDS_Edge& E2)
596 if (E1.IsSame(E2)) return Standard_True;
597 return Standard_False;
600 //=======================================================================
601 //function : OuterWire
603 //=======================================================================
605 TopoDS_Wire BRepTools::OuterWire(const TopoDS_Face& F)
608 TopExp_Explorer expw (F,TopAbs_WIRE);
611 Wres = TopoDS::Wire(expw.Current());
614 Standard_Real UMin, UMax, VMin, VMax;
615 Standard_Real umin, umax, vmin, vmax;
616 BRepTools::UVBounds(F,Wres,UMin,UMax,VMin,VMax);
617 while (expw.More()) {
618 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
619 BRepTools::UVBounds(F,W,umin, umax, vmin, vmax);
620 if ((umin <= UMin) &&
637 //=======================================================================
638 //function : Map3DEdges
640 //=======================================================================
642 void BRepTools::Map3DEdges(const TopoDS_Shape& S,
643 TopTools_IndexedMapOfShape& M)
646 for (Ex.Init(S,TopAbs_EDGE); Ex.More(); Ex.Next()) {
647 if (!BRep_Tool::Degenerated(TopoDS::Edge(Ex.Current())))
652 //=======================================================================
655 //=======================================================================
657 void BRepTools::Dump(const TopoDS_Shape& Sh, Standard_OStream& S)
659 BRepTools_ShapeSet SS;
665 //=======================================================================
668 //=======================================================================
670 void BRepTools::Write(const TopoDS_Shape& Sh, Standard_OStream& S,
671 const Handle(Message_ProgressIndicator)& PR)
673 BRepTools_ShapeSet SS;
681 //=======================================================================
684 //=======================================================================
686 void BRepTools::Read(TopoDS_Shape& Sh,
688 const BRep_Builder& B,
689 const Handle(Message_ProgressIndicator)& PR)
691 BRepTools_ShapeSet SS(B);
697 //=======================================================================
700 //=======================================================================
702 Standard_Boolean BRepTools::Write(const TopoDS_Shape& Sh,
703 const Standard_CString File,
704 const Handle(Message_ProgressIndicator)& PR)
707 OSD_OpenStream(os, File, std::ios::out);
708 if (!os.is_open() || !os.good())
709 return Standard_False;
711 Standard_Boolean isGood = (os.good() && !os.eof());
715 BRepTools_ShapeSet SS;
719 os << "DBRep_DrawableShape\n"; // for easy Draw read
729 isGood = os.good() && isGood && !errno;
734 //=======================================================================
737 //=======================================================================
739 Standard_Boolean BRepTools::Read(TopoDS_Shape& Sh,
740 const Standard_CString File,
741 const BRep_Builder& B,
742 const Handle(Message_ProgressIndicator)& PR)
745 std::istream in(&fic);
746 OSD_OpenStream (fic, File, std::ios::in);
747 if(!fic.is_open()) return Standard_False;
749 BRepTools_ShapeSet SS(B);
752 if(!SS.NbShapes()) return Standard_False;
754 return Standard_True;
758 //=======================================================================
761 //=======================================================================
763 void BRepTools::Clean (const TopoDS_Shape& theShape)
765 if (theShape.IsNull())
768 BRep_Builder aBuilder;
769 Handle(Poly_Triangulation) aNullTriangulation;
770 Handle(Poly_PolygonOnTriangulation) aNullPoly;
772 TopTools_MapOfShape aShapeMap;
773 const TopLoc_Location anEmptyLoc;
775 TopExp_Explorer aFaceIt(theShape, TopAbs_FACE);
776 for (; aFaceIt.More(); aFaceIt.Next())
778 TopoDS_Shape aFaceNoLoc = aFaceIt.Value();
779 aFaceNoLoc.Location (anEmptyLoc);
780 if (!aShapeMap.Add (aFaceNoLoc))
782 // the face has already been processed
786 const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current());
787 if (!BRep_Tool::IsGeometric (aFace))
789 // Do not remove triangulation as there is no surface to recompute it.
794 TopLoc_Location aLoc;
795 const Handle(Poly_Triangulation)& aTriangulation =
796 BRep_Tool::Triangulation(aFace, aLoc);
798 if (aTriangulation.IsNull())
802 // Theoretically, the edges on the face (with surface) may have no geometry
803 // (no curve 3d or 2d or both). Such faces should be considered as invalid and
804 // are not supported by current implementation. So, both triangulation of the face
805 // and polygon on triangulation of the edges are removed unconditionally.
806 TopExp_Explorer aEdgeIt(aFace, TopAbs_EDGE);
807 for (; aEdgeIt.More(); aEdgeIt.Next())
809 const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
810 aBuilder.UpdateEdge(aEdge, aNullPoly, aTriangulation, aLoc);
813 aBuilder.UpdateFace(aFace, aNullTriangulation);
816 // Iterate over all edges seeking for 3d polygons
817 Handle (Poly_Polygon3D) aNullPoly3d;
818 TopExp_Explorer aEdgeIt (theShape, TopAbs_EDGE);
819 for (; aEdgeIt.More (); aEdgeIt.Next ())
821 TopoDS_Edge anEdgeNoLoc = TopoDS::Edge (aEdgeIt.Value());
822 anEdgeNoLoc.Location (anEmptyLoc);
824 if (!aShapeMap.Add (anEdgeNoLoc))
826 // the edge has already been processed
830 if (!BRep_Tool::IsGeometric (TopoDS::Edge (anEdgeNoLoc)))
832 // Do not remove polygon 3d as there is no curve to recompute it.
836 TopLoc_Location aLoc;
837 Handle (Poly_Polygon3D) aPoly3d = BRep_Tool::Polygon3D (anEdgeNoLoc, aLoc);
838 if (aPoly3d.IsNull())
841 aBuilder.UpdateEdge (anEdgeNoLoc, aNullPoly3d);
844 //=======================================================================
845 //function : CleanGeometry
847 //=======================================================================
849 void BRepTools::CleanGeometry(const TopoDS_Shape& theShape)
851 if (theShape.IsNull())
854 BRep_Builder aBuilder;
856 for (TopExp_Explorer aFaceIt(theShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
858 TopLoc_Location aLocation;
859 const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
860 const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(aFace, aLocation);
862 for (TopExp_Explorer aEdgeIt(aFace, TopAbs_EDGE); aEdgeIt.More(); aEdgeIt.Next())
864 const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt.Current());
865 aBuilder.UpdateEdge(anEdge, Handle(Geom2d_Curve)(), aSurface,
866 aLocation, BRep_Tool::Tolerance(anEdge));
869 aBuilder.UpdateFace(aFace, Handle(Geom_Surface)(), aFace.Location(), BRep_Tool::Tolerance(aFace));
872 for (TopExp_Explorer aEdgeIt2(theShape, TopAbs_EDGE); aEdgeIt2.More(); aEdgeIt2.Next())
874 const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt2.Current());
876 aBuilder.UpdateEdge(anEdge, Handle(Geom_Curve)(),
877 TopLoc_Location(), BRep_Tool::Tolerance(anEdge));
882 //=======================================================================
883 //function : RemoveUnusedPCurves
885 //=======================================================================
887 void BRepTools::RemoveUnusedPCurves(const TopoDS_Shape& S)
889 TColStd_MapOfTransient UsedSurfaces;
891 TopExp_Explorer Explo(S, TopAbs_FACE);
892 for (; Explo.More(); Explo.Next())
894 TopoDS_Face aFace = TopoDS::Face(Explo.Current());
895 TopLoc_Location aLoc;
896 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
897 UsedSurfaces.Add(aSurf);
900 TopTools_IndexedMapOfShape Emap;
901 TopExp::MapShapes(S, TopAbs_EDGE, Emap);
904 for (i = 1; i <= Emap.Extent(); i++)
906 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Emap(i).TShape());
907 BRep_ListOfCurveRepresentation& lcr = TE -> ChangeCurves();
908 BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr );
911 Standard_Boolean ToRemove = Standard_False;
913 Handle(BRep_CurveRepresentation) CurveRep = itrep.Value();
914 if (CurveRep->IsCurveOnSurface())
916 Handle(Geom_Surface) aSurface = CurveRep->Surface();
917 if (!UsedSurfaces.Contains(aSurface))
918 ToRemove = Standard_True;
920 else if (CurveRep->IsRegularity())
922 Handle(Geom_Surface) Surf1 = CurveRep->Surface();
923 Handle(Geom_Surface) Surf2 = CurveRep->Surface2();
924 ToRemove = (!UsedSurfaces.Contains(Surf1) || !UsedSurfaces.Contains(Surf2));
935 //=======================================================================
936 //function : Triangulation
938 //=======================================================================
940 Standard_Boolean BRepTools::Triangulation(const TopoDS_Shape& theShape,
941 const Standard_Real theLinDefl,
942 const Standard_Boolean theToCheckFreeEdges)
944 TopExp_Explorer anEdgeIter;
945 TopLoc_Location aDummyLoc;
946 for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
948 const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Current());
949 const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation (aFace, aDummyLoc);
951 || aTri->Deflection() > theLinDefl)
953 return Standard_False;
956 for (anEdgeIter.Init (aFace, TopAbs_EDGE); anEdgeIter.More(); anEdgeIter.Next())
958 const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Current());
959 const Handle(Poly_PolygonOnTriangulation)& aPoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTri, aDummyLoc);
962 return Standard_False;
966 if (!theToCheckFreeEdges)
968 return Standard_True;
971 Handle(Poly_Triangulation) anEdgeTri;
972 for (anEdgeIter.Init (theShape, TopAbs_EDGE, TopAbs_FACE); anEdgeIter.More(); anEdgeIter.Next())
974 const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Current());
975 const Handle(Poly_Polygon3D)& aPolygon = BRep_Tool::Polygon3D (anEdge, aDummyLoc);
976 if (!aPolygon.IsNull())
978 if (aPolygon->Deflection() > theLinDefl)
980 return Standard_False;
985 const Handle(Poly_PolygonOnTriangulation)& aPoly = BRep_Tool::PolygonOnTriangulation (anEdge, anEdgeTri, aDummyLoc);
987 || anEdgeTri.IsNull()
988 || anEdgeTri->Deflection() > theLinDefl)
990 return Standard_False;
995 return Standard_True;
999 //=======================================================================
1000 //function : IsReallyClosed
1002 //=======================================================================
1004 Standard_Boolean BRepTools::IsReallyClosed(const TopoDS_Edge& E,
1005 const TopoDS_Face& F)
1007 if (!BRep_Tool::IsClosed(E,F)) {
1008 return Standard_False;
1010 Standard_Integer nbocc = 0;
1011 TopExp_Explorer exp;
1012 for (exp.Init(F,TopAbs_EDGE);exp.More();exp.Next()) {
1013 if (exp.Current().IsSame(E)) {
1020 //=======================================================================
1021 //function : DetectClosedness
1023 //=======================================================================
1025 void BRepTools::DetectClosedness(const TopoDS_Face& theFace,
1026 Standard_Boolean& theUclosed,
1027 Standard_Boolean& theVclosed)
1029 theUclosed = theVclosed = Standard_False;
1031 TopExp_Explorer Explo(theFace, TopAbs_EDGE);
1032 for (; Explo.More(); Explo.Next())
1034 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
1035 if (BRep_Tool::IsClosed(anEdge, theFace) &&
1036 BRepTools::IsReallyClosed(anEdge, theFace))
1038 Standard_Real fpar, lpar;
1039 Handle(Geom2d_Curve) PCurve1 = BRep_Tool::CurveOnSurface(anEdge, theFace, fpar, lpar);
1040 Handle(Geom2d_Curve) PCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(anEdge.Reversed()),
1041 theFace, fpar, lpar);
1042 gp_Pnt2d Point1 = PCurve1->Value(fpar);
1043 gp_Pnt2d Point2 = PCurve2->Value(fpar);
1044 Standard_Boolean IsUiso = (Abs(Point1.X() - Point2.X()) > Abs(Point1.Y() - Point2.Y()));
1046 theUclosed = Standard_True;
1048 theVclosed = Standard_True;
1053 //=======================================================================
1054 //function : EvalAndUpdateTol
1056 //=======================================================================
1058 Standard_Real BRepTools::EvalAndUpdateTol(const TopoDS_Edge& theE,
1059 const Handle(Geom_Curve)& C3d,
1060 const Handle(Geom2d_Curve) C2d,
1061 const Handle(Geom_Surface)& S,
1062 const Standard_Real f,
1063 const Standard_Real l)
1065 Standard_Real newtol = 0.;
1066 Standard_Real first = f, last = l;
1067 //Set first, last to avoid ErrosStatus = 2 because of
1068 //too strong checking of limits in class CheckCurveOnSurface
1070 if(!C3d->IsPeriodic())
1072 first = Max(first, C3d->FirstParameter());
1073 last = Min(last, C3d->LastParameter());
1075 if(!C2d->IsPeriodic())
1077 first = Max(first, C2d->FirstParameter());
1078 last = Min(last, C2d->LastParameter());
1081 GeomLib_CheckCurveOnSurface CT(C3d, S, first, last);
1085 newtol = CT.MaxDistance();
1089 if(CT.ErrorStatus() == 3 || (CT.ErrorStatus() == 2 &&
1090 (C3d->IsPeriodic() || C2d->IsPeriodic())))
1092 //Try to estimate by sample points
1093 Standard_Integer nbint = 22;
1094 Standard_Real dt = (last - first) / nbint;
1095 dt = Max(dt, Precision::Confusion());
1096 Standard_Real d, dmax = 0.;
1099 Standard_Integer cnt = 0;
1100 Standard_Real t = first;
1101 for(; t <= last; t += dt)
1106 S->D0(aP2d.X(), aP2d.Y(), aPS);
1107 d = aPS.SquareDistance(aPC);
1118 S->D0(aP2d.X(), aP2d.Y(), aPS);
1119 d = aPS.SquareDistance(aPC);
1126 newtol = 1.2 * Sqrt(dmax);
1129 Standard_Real Tol = BRep_Tool::Tolerance(theE);
1134 B.UpdateEdge(theE, Tol);
1141 //=======================================================================
1142 //function : OriEdgeInFace
1144 //=======================================================================
1146 TopAbs_Orientation BRepTools::OriEdgeInFace (const TopoDS_Edge& E,
1147 const TopoDS_Face& F )
1150 TopExp_Explorer Exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1152 for (; Exp.More() ;Exp.Next()) {
1153 if (Exp.Current().IsSame(E)) {
1154 return Exp.Current().Orientation();
1157 throw Standard_ConstructionError("BRepTools::OriEdgeInFace");