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
9 // under the terms of the GNU Lesser General Public 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.
17 #include <Standard_Stream.hxx>
19 #include <BRepTools.ixx>
20 #include <BRepTools_ShapeSet.hxx>
21 #include <BRep_Tool.hxx>
23 #include <TopExp_Explorer.hxx>
25 #include <TopoDS_Iterator.hxx>
26 #include <BndLib_Add2dCurve.hxx>
27 #include <Geom2dAdaptor_Curve.hxx>
28 #include <Geom_Surface.hxx>
29 #include <Geom_Curve.hxx>
30 #include <Geom2d_Curve.hxx>
31 #include <BRepTools_MapOfVertexPnt2d.hxx>
32 #include <BRep_CurveRepresentation.hxx>
33 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
34 #include <BRep_TEdge.hxx>
35 #include <TColgp_SequenceOfPnt2d.hxx>
36 #include <TColStd_SequenceOfReal.hxx>
37 #include <TColGeom2d_SequenceOfCurve.hxx>
38 #include <TopTools_SequenceOfShape.hxx>
39 #include <Precision.hxx>
41 #include <Poly_Triangulation.hxx>
42 #include <Poly_PolygonOnTriangulation.hxx>
43 #include <TColStd_HArray1OfInteger.hxx>
44 #include <TColStd_MapOfTransient.hxx>
46 #include <gp_Lin2d.hxx>
48 #include <gp_Vec2d.hxx>
49 #include <Standard_ErrorHandler.hxx>
50 #include <Standard_Failure.hxx>
54 //=======================================================================
57 //=======================================================================
59 void BRepTools::UVBounds(const TopoDS_Face& F,
60 Standard_Real& UMin, Standard_Real& UMax,
61 Standard_Real& VMin, Standard_Real& VMax)
65 B.Get(UMin,VMin,UMax,VMax);
68 //=======================================================================
71 //=======================================================================
73 void BRepTools::UVBounds(const TopoDS_Face& F,
75 Standard_Real& UMin, Standard_Real& UMax,
76 Standard_Real& VMin, Standard_Real& VMax)
80 B.Get(UMin,VMin,UMax,VMax);
84 //=======================================================================
87 //=======================================================================
89 void BRepTools::UVBounds(const TopoDS_Face& F,
91 Standard_Real& UMin, Standard_Real& UMax,
92 Standard_Real& VMin, Standard_Real& VMax)
96 B.Get(UMin,VMin,UMax,VMax);
99 //=======================================================================
100 //function : AddUVBounds
102 //=======================================================================
104 void BRepTools::AddUVBounds(const TopoDS_Face& FF, Bnd_Box2d& B)
107 F.Orientation(TopAbs_FORWARD);
108 TopExp_Explorer ex(F,TopAbs_EDGE);
110 // fill box for the given face
112 for (;ex.More();ex.Next()) {
113 BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),aBox);
116 // if the box is empty (face without edges or without pcurves),
117 // get natural bounds
119 Standard_Real UMin,UMax,VMin,VMax;
121 BRep_Tool::Surface(F,L)->Bounds(UMin,UMax,VMin,VMax);
122 aBox.Update(UMin,VMin,UMax,VMax);
125 // add face box to result
130 //=======================================================================
131 //function : AddUVBounds
133 //=======================================================================
135 void BRepTools::AddUVBounds(const TopoDS_Face& F,
136 const TopoDS_Wire& W,
140 for (ex.Init(W,TopAbs_EDGE);ex.More();ex.Next()) {
141 BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),B);
146 //=======================================================================
147 //function : AddUVBounds
149 //=======================================================================
151 void BRepTools::AddUVBounds(const TopoDS_Face& F,
152 const TopoDS_Edge& E,
157 const Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,pf,pl);
158 if (C.IsNull()) return;
159 if (pl < pf) { // Petit Blindage
161 aux = pf; pf = pl; pl = aux;
163 Geom2dAdaptor_Curve PC(C,pf,pl);
164 if (Precision::IsNegativeInfinite(pf) ||
165 Precision::IsPositiveInfinite(pf)) {
166 Geom2dAdaptor_Curve GC(PC);
167 BndLib_Add2dCurve::Add(GC,0.,B);
171 // just compute points to get a close box.
173 Standard_Real Umin,Umax,Vmin,Vmax;
174 const Handle(Geom_Surface)& Surf=BRep_Tool::Surface(F,L);
175 Surf->Bounds(Umin,Umax,Vmin,Vmax);
179 Standard_Real i, nbp = 20;
180 if (PC.GetType() == GeomAbs_Line) nbp = 2;
181 Standard_Real step = (pl - pf) / nbp;
186 Standard_Real du=0.0;
187 Standard_Real dv=0.0;
190 for (i = 1; i < nbp; i++) {
194 if(i==1) { Pb=Pc; Pc=P; }
196 //-- Calcul de la fleche
198 gp_Vec2d PaPc(Pa,Pc);
199 // gp_Lin2d L2d(Pa,PaPc);
200 // Standard_Real up = ElCLib::Parameter(L2d,Pb);
201 // gp_Pnt2d PProj = ElCLib::Value(up,L2d);
202 gp_Pnt2d PProj(Pa.Coord()+(PaPc.XY()/2.));
203 Standard_Real ddu=Abs(Pb.X()-PProj.X());
204 Standard_Real ddv=Abs(Pb.Y()-PProj.Y());
212 //-- cout<<" du="<<du<<" dv="<<dv<<endl;
213 Standard_Real u0,u1,v0,v1;
214 Baux.Get(u0,v0,u1,v1);
217 u0-=du; v0-=dv; u1+=du; v1+=dv;
218 if(Surf->IsUPeriodic()) { }
220 if(u0<=Umin) { u0=Umin; }
221 if(u1>=Umax) { u1=Umax; }
223 if(Surf->IsVPeriodic()) { }
225 if(v0<=Vmin) { v0=Vmin; }
226 if(v1>=Vmax) { v1=Vmax; }
228 P.SetCoord(u0,v0) ; Baux.Add(P);
229 P.SetCoord(u1,v1) ; Baux.Add(P);
232 Standard_Real aXmin, aYmin, aXmax, aYmax;
233 Baux.Get(aXmin, aYmin, aXmax, aYmax);
234 Standard_Real Tol2d = Precision::PConfusion();
235 if (Abs(aXmin - Umin) <= Tol2d)
237 if (Abs(aYmin - Vmin) <= Tol2d)
239 if (Abs(aXmax - Umax) <= Tol2d)
241 if (Abs(aYmax - Vmax) <= Tol2d)
243 FinalBox.Update(aXmin, aYmin, aXmax, aYmax);
249 //=======================================================================
252 //=======================================================================
254 void BRepTools::Update(const TopoDS_Vertex&)
258 //=======================================================================
261 //=======================================================================
263 void BRepTools::Update(const TopoDS_Edge&)
267 //=======================================================================
270 //=======================================================================
272 void BRepTools::Update(const TopoDS_Wire&)
276 //=======================================================================
279 //=======================================================================
281 void BRepTools::Update(const TopoDS_Face& F)
284 UpdateFaceUVPoints(F);
285 F.TShape()->Checked(Standard_True);
289 //=======================================================================
292 //=======================================================================
294 void BRepTools::Update(const TopoDS_Shell& S)
296 TopExp_Explorer ex(S,TopAbs_FACE);
298 Update(TopoDS::Face(ex.Current()));
303 //=======================================================================
306 //=======================================================================
308 void BRepTools::Update(const TopoDS_Solid& S)
310 TopExp_Explorer ex(S,TopAbs_FACE);
312 Update(TopoDS::Face(ex.Current()));
317 //=======================================================================
320 //=======================================================================
322 void BRepTools::Update(const TopoDS_CompSolid& CS)
324 TopExp_Explorer ex(CS,TopAbs_FACE);
326 Update(TopoDS::Face(ex.Current()));
331 //=======================================================================
334 //=======================================================================
336 void BRepTools::Update(const TopoDS_Compound& C)
338 TopExp_Explorer ex(C,TopAbs_FACE);
340 Update(TopoDS::Face(ex.Current()));
345 //=======================================================================
348 //=======================================================================
350 void BRepTools::Update(const TopoDS_Shape& S)
352 switch (S.ShapeType()) {
355 Update(TopoDS::Vertex(S));
359 Update(TopoDS::Edge(S));
363 Update(TopoDS::Wire(S));
367 Update(TopoDS::Face(S));
371 Update(TopoDS::Shell(S));
375 Update(TopoDS::Solid(S));
378 case TopAbs_COMPSOLID :
379 Update(TopoDS::CompSolid(S));
382 case TopAbs_COMPOUND :
383 Update(TopoDS::Compound(S));
393 //=======================================================================
394 //function : UpdateFaceUVPoints
395 //purpose : reset the UV points of a Face
396 //=======================================================================
398 void BRepTools::UpdateFaceUVPoints(const TopoDS_Face& F)
400 // Recompute for each edge the two UV points in order to have the same
401 // UV point on connected edges.
403 // First edge loop, store the vertices in a Map with their 2d points
405 BRepTools_MapOfVertexPnt2d theVertices;
406 TopoDS_Iterator expE,expV;
407 TopoDS_Iterator EdgeIt,VertIt;
408 TColStd_SequenceOfReal aFSeq, aLSeq;
409 TColGeom2d_SequenceOfCurve aCSeq;
410 TopTools_SequenceOfShape aShSeq;
413 // a 3d tolerance for UV !!
414 Standard_Real tolerance = BRep_Tool::Tolerance(F);
415 TColgp_SequenceOfPnt2d emptySequence;
417 for (expE.Initialize(F); expE.More(); expE.Next()) {
418 if(expE.Value().ShapeType() != TopAbs_WIRE)
421 EdgeIt.Initialize(expE.Value());
422 for( ; EdgeIt.More(); EdgeIt.Next())
424 const TopoDS_Edge& E = TopoDS::Edge(EdgeIt.Value());
426 Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,f,l);
433 if (C.IsNull()) continue;
435 for (expV.Initialize(E.Oriented(TopAbs_FORWARD));
436 expV.More(); expV.Next()) {
438 const TopoDS_Vertex& V = TopoDS::Vertex(expV.Value());
440 TopAbs_Orientation Vori = V.Orientation();
441 if ( Vori == TopAbs_INTERNAL ) {
445 Standard_Real p = BRep_Tool::Parameter(V,E,F);
447 if (!theVertices.IsBound(V))
448 theVertices.Bind(V,emptySequence);
449 TColgp_SequenceOfPnt2d& S = theVertices(V);
450 for (i = 1; i <= S.Length(); i++) {
451 if (P.Distance(S(i)) < tolerance) break;
459 // second edge loop, update the edges 2d points
463 for(Standard_Integer j = 1; j <= aShSeq.Length(); j++)
465 const TopoDS_Edge& E = TopoDS::Edge(aShSeq.Value(j));
466 const Handle(Geom2d_Curve)& C = aCSeq.Value(j);
467 if (C.IsNull()) continue;
469 TopExp::Vertices(E,Vf,Vl);
471 Pf.SetCoord(RealLast(),RealLast());
474 if ( Vf.Orientation() == TopAbs_INTERNAL ) {
477 const TColgp_SequenceOfPnt2d& seqf = theVertices(Vf);
478 if (seqf.Length() == 1)
481 C->D0(aFSeq.Value(j),Pf);
482 for (i = 1; i <= seqf.Length(); i++) {
483 if (Pf.Distance(seqf(i)) <= tolerance) {
491 Pl.SetCoord(RealLast(),RealLast());
494 if ( Vl.Orientation() == TopAbs_INTERNAL ) {
497 const TColgp_SequenceOfPnt2d& seql = theVertices(Vl);
498 if (seql.Length() == 1)
501 C->D0(aLSeq.Value(j),Pl);
502 for (i = 1; i <= seql.Length(); i++) {
503 if (Pl.Distance(seql(i)) <= tolerance) {
511 // set the correct points
512 BRep_Tool::SetUVPoints(E,F,Pf,Pl);
518 //=======================================================================
521 //=======================================================================
523 Standard_Boolean BRepTools::Compare(const TopoDS_Vertex& V1,
524 const TopoDS_Vertex& V2)
526 if (V1.IsSame(V2)) return Standard_True;
527 gp_Pnt p1 = BRep_Tool::Pnt(V1);
528 gp_Pnt p2 = BRep_Tool::Pnt(V2);
529 Standard_Real l = p1.Distance(p2);
530 if (l <= BRep_Tool::Tolerance(V1)) return Standard_True;
531 if (l <= BRep_Tool::Tolerance(V2)) return Standard_True;
532 return Standard_False;
535 //=======================================================================
538 //=======================================================================
540 Standard_Boolean BRepTools::Compare(const TopoDS_Edge& E1,
541 const TopoDS_Edge& E2)
543 if (E1.IsSame(E2)) return Standard_True;
544 return Standard_False;
547 //=======================================================================
548 //function : OuterWire
550 //=======================================================================
552 TopoDS_Wire BRepTools::OuterWire(const TopoDS_Face& F)
555 TopExp_Explorer expw (F,TopAbs_WIRE);
558 Wres = TopoDS::Wire(expw.Current());
561 Standard_Real UMin, UMax, VMin, VMax;
562 Standard_Real umin, umax, vmin, vmax;
563 BRepTools::UVBounds(F,Wres,UMin,UMax,VMin,VMax);
564 while (expw.More()) {
565 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
566 BRepTools::UVBounds(F,W,umin, umax, vmin, vmax);
567 if ((umin <= UMin) &&
584 //=======================================================================
585 //function : Map3DEdges
587 //=======================================================================
589 void BRepTools::Map3DEdges(const TopoDS_Shape& S,
590 TopTools_IndexedMapOfShape& M)
593 for (Ex.Init(S,TopAbs_EDGE); Ex.More(); Ex.Next()) {
594 if (!BRep_Tool::Degenerated(TopoDS::Edge(Ex.Current())))
599 //=======================================================================
602 //=======================================================================
604 void BRepTools::Dump(const TopoDS_Shape& Sh, Standard_OStream& S)
606 BRepTools_ShapeSet SS;
613 //=======================================================================
614 //function : BRepTools_Write
616 //=======================================================================
617 void BRepTools_Write (const TopoDS_Shape& S,
618 const Standard_CString File)
620 BRepTools::Write (S,File);
624 //=======================================================================
627 //=======================================================================
629 void BRepTools::Write(const TopoDS_Shape& Sh, Standard_OStream& S,
630 const Handle(Message_ProgressIndicator)& PR)
632 BRepTools_ShapeSet SS;
640 //=======================================================================
643 //=======================================================================
645 void BRepTools::Read(TopoDS_Shape& Sh,
647 const BRep_Builder& B,
648 const Handle(Message_ProgressIndicator)& PR)
650 BRepTools_ShapeSet SS(B);
656 //=======================================================================
659 //=======================================================================
661 Standard_Boolean BRepTools::Write(const TopoDS_Shape& Sh,
662 const Standard_CString File,
663 const Handle(Message_ProgressIndicator)& PR)
666 // if (!fic.open(File,output)) return Standard_False;
667 os.open(File, ios::out);
668 if (!os.rdbuf()->is_open()) return Standard_False;
670 Standard_Boolean isGood = (os.good() && !os.eof());
674 BRepTools_ShapeSet SS;
678 os << "DBRep_DrawableShape\n"; // for easy Draw read
688 isGood = os.good() && isGood && !errno;
693 //=======================================================================
696 //=======================================================================
698 Standard_Boolean BRepTools::Read(TopoDS_Shape& Sh,
699 const Standard_CString File,
700 const BRep_Builder& B,
701 const Handle(Message_ProgressIndicator)& PR)
705 if (!fic.open(File, ios::in)) return Standard_False;
707 BRepTools_ShapeSet SS(B);
710 if(!SS.NbShapes()) return Standard_False;
712 return Standard_True;
716 //=======================================================================
719 //=======================================================================
721 void BRepTools::Clean(const TopoDS_Shape& S)
725 Handle(Poly_Triangulation) TNULL, T;
726 Handle(Poly_PolygonOnTriangulation) PolyNULL, Poly;
730 for (ex.Init(S,TopAbs_FACE);ex.More();ex.Next()) {
731 const TopoDS_Face& F = TopoDS::Face(ex.Current());
732 B.UpdateFace(F, TNULL);
734 for (ex.Init(S, TopAbs_EDGE); ex.More(); ex.Next()) {
735 const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
736 // agv 21.09.01 : Inefficient management of Locations -> improve performance
738 // BRep_Tool::PolygonOnTriangulation(E, Poly, T, L);
739 // B.UpdateEdge(E, PolyNULL, T, L);
740 // } while(!Poly.IsNull());
742 Handle(BRep_CurveRepresentation) cr;
743 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
744 BRep_ListOfCurveRepresentation& lcr = TE -> ChangeCurves();
745 BRep_ListIteratorOfListOfCurveRepresentation itcr(lcr);
747 // find and remove all representations
748 while (itcr.More()) {
750 if (cr->IsPolygonOnTriangulation())
755 TE->Modified(Standard_True);
761 //=======================================================================
762 //function : RemoveUnusedPCurves
764 //=======================================================================
766 void BRepTools::RemoveUnusedPCurves(const TopoDS_Shape& S)
768 TColStd_MapOfTransient UsedSurfaces;
770 TopExp_Explorer Explo(S, TopAbs_FACE);
771 for (; Explo.More(); Explo.Next())
773 TopoDS_Face aFace = TopoDS::Face(Explo.Current());
774 TopLoc_Location aLoc;
775 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
776 UsedSurfaces.Add(aSurf);
779 TopTools_IndexedMapOfShape Emap;
780 TopExp::MapShapes(S, TopAbs_EDGE, Emap);
783 for (i = 1; i <= Emap.Extent(); i++)
785 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Emap(i).TShape());
786 BRep_ListOfCurveRepresentation& lcr = TE -> ChangeCurves();
787 BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr );
790 Standard_Boolean ToRemove = Standard_False;
792 Handle(BRep_CurveRepresentation) CurveRep = itrep.Value();
793 if (CurveRep->IsCurveOnSurface())
795 Handle(Geom_Surface) aSurface = CurveRep->Surface();
796 if (!UsedSurfaces.Contains(aSurface))
797 ToRemove = Standard_True;
799 else if (CurveRep->IsRegularity())
801 Handle(Geom_Surface) Surf1 = CurveRep->Surface();
802 Handle(Geom_Surface) Surf2 = CurveRep->Surface2();
803 ToRemove = (!UsedSurfaces.Contains(Surf1) || !UsedSurfaces.Contains(Surf2));
814 //=======================================================================
815 //function : Triangulation
817 //=======================================================================
819 Standard_Boolean BRepTools::Triangulation(const TopoDS_Shape& S,
820 const Standard_Real deflec)
822 TopExp_Explorer exf, exe;
824 Handle(Poly_Triangulation) T;
825 Handle(Poly_PolygonOnTriangulation) Poly;
827 for (exf.Init(S, TopAbs_FACE); exf.More(); exf.Next()) {
828 const TopoDS_Face& F = TopoDS::Face(exf.Current());
829 T = BRep_Tool::Triangulation(F, l);
830 if (T.IsNull() || (T->Deflection() > deflec))
831 return Standard_False;
832 for (exe.Init(F, TopAbs_EDGE); exe.More(); exe.Next()) {
833 const TopoDS_Edge& E = TopoDS::Edge(exe.Current());
834 Poly = BRep_Tool::PolygonOnTriangulation(E, T, l);
835 if (Poly.IsNull()) return Standard_False;
838 return Standard_True;
842 //=======================================================================
843 //function : IsReallyClosed
845 //=======================================================================
847 Standard_Boolean BRepTools::IsReallyClosed(const TopoDS_Edge& E,
848 const TopoDS_Face& F)
850 if (!BRep_Tool::IsClosed(E,F)) {
851 return Standard_False;
853 Standard_Integer nbocc = 0;
855 for (exp.Init(F,TopAbs_EDGE);exp.More();exp.Next()) {
856 if (exp.Current().IsSame(E)) {