1 // Created on: 1993-01-21
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 #include <Standard_Stream.hxx>
24 #include <BRepTools.ixx>
25 #include <BRepTools_ShapeSet.hxx>
26 #include <BRep_Tool.hxx>
28 #include <TopExp_Explorer.hxx>
30 #include <TopoDS_Iterator.hxx>
31 #include <BndLib_Add2dCurve.hxx>
32 #include <Geom2dAdaptor_Curve.hxx>
33 #include <Geom_Surface.hxx>
34 #include <Geom_Curve.hxx>
35 #include <Geom2d_Curve.hxx>
36 #include <BRepTools_MapOfVertexPnt2d.hxx>
37 #include <BRep_CurveRepresentation.hxx>
38 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
39 #include <BRep_TEdge.hxx>
40 #include <TColgp_SequenceOfPnt2d.hxx>
41 #include <TColStd_SequenceOfReal.hxx>
42 #include <TColGeom2d_SequenceOfCurve.hxx>
43 #include <TopTools_SequenceOfShape.hxx>
44 #include <Precision.hxx>
46 #include <Poly_Triangulation.hxx>
47 #include <Poly_PolygonOnTriangulation.hxx>
48 #include <TColStd_HArray1OfInteger.hxx>
49 #include <TColStd_MapOfTransient.hxx>
51 #include <gp_Lin2d.hxx>
53 #include <gp_Vec2d.hxx>
54 #include <Standard_ErrorHandler.hxx>
55 #include <Standard_Failure.hxx>
59 //=======================================================================
62 //=======================================================================
64 void BRepTools::UVBounds(const TopoDS_Face& F,
65 Standard_Real& UMin, Standard_Real& UMax,
66 Standard_Real& VMin, Standard_Real& VMax)
70 B.Get(UMin,VMin,UMax,VMax);
73 //=======================================================================
76 //=======================================================================
78 void BRepTools::UVBounds(const TopoDS_Face& F,
80 Standard_Real& UMin, Standard_Real& UMax,
81 Standard_Real& VMin, Standard_Real& VMax)
85 B.Get(UMin,VMin,UMax,VMax);
89 //=======================================================================
92 //=======================================================================
94 void BRepTools::UVBounds(const TopoDS_Face& F,
96 Standard_Real& UMin, Standard_Real& UMax,
97 Standard_Real& VMin, Standard_Real& VMax)
101 B.Get(UMin,VMin,UMax,VMax);
104 //=======================================================================
105 //function : AddUVBounds
107 //=======================================================================
109 void BRepTools::AddUVBounds(const TopoDS_Face& FF, Bnd_Box2d& B)
112 F.Orientation(TopAbs_FORWARD);
113 TopExp_Explorer ex(F,TopAbs_EDGE);
115 // fill box for the given face
117 for (;ex.More();ex.Next()) {
118 BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),aBox);
121 // if the box is empty (face without edges or without pcurves),
122 // get natural bounds
124 Standard_Real UMin,UMax,VMin,VMax;
126 BRep_Tool::Surface(F,L)->Bounds(UMin,UMax,VMin,VMax);
127 aBox.Update(UMin,VMin,UMax,VMax);
130 // add face box to result
135 //=======================================================================
136 //function : AddUVBounds
138 //=======================================================================
140 void BRepTools::AddUVBounds(const TopoDS_Face& F,
141 const TopoDS_Wire& W,
145 for (ex.Init(W,TopAbs_EDGE);ex.More();ex.Next()) {
146 BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),B);
151 //=======================================================================
152 //function : AddUVBounds
154 //=======================================================================
156 void BRepTools::AddUVBounds(const TopoDS_Face& F,
157 const TopoDS_Edge& E,
162 const Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,pf,pl);
163 if (C.IsNull()) return;
164 if (pl < pf) { // Petit Blindage
166 aux = pf; pf = pl; pl = aux;
168 Geom2dAdaptor_Curve PC(C,pf,pl);
169 if (Precision::IsNegativeInfinite(pf) ||
170 Precision::IsPositiveInfinite(pf)) {
171 Geom2dAdaptor_Curve GC(PC);
172 BndLib_Add2dCurve::Add(GC,0.,B);
176 // just compute points to get a close box.
178 Standard_Real Umin,Umax,Vmin,Vmax;
179 const Handle(Geom_Surface)& Surf=BRep_Tool::Surface(F,L);
180 Surf->Bounds(Umin,Umax,Vmin,Vmax);
184 Standard_Real i, nbp = 20;
185 if (PC.GetType() == GeomAbs_Line) nbp = 2;
186 Standard_Real step = (pl - pf) / nbp;
191 Standard_Real du=0.0;
192 Standard_Real dv=0.0;
195 for (i = 1; i < nbp; i++) {
199 if(i==1) { Pb=Pc; Pc=P; }
201 //-- Calcul de la fleche
203 gp_Vec2d PaPc(Pa,Pc);
204 // gp_Lin2d L2d(Pa,PaPc);
205 // Standard_Real up = ElCLib::Parameter(L2d,Pb);
206 // gp_Pnt2d PProj = ElCLib::Value(up,L2d);
207 gp_Pnt2d PProj(Pa.Coord()+(PaPc.XY()/2.));
208 Standard_Real ddu=Abs(Pb.X()-PProj.X());
209 Standard_Real ddv=Abs(Pb.Y()-PProj.Y());
217 //-- cout<<" du="<<du<<" dv="<<dv<<endl;
218 Standard_Real u0,u1,v0,v1;
219 Baux.Get(u0,v0,u1,v1);
222 u0-=du; v0-=dv; u1+=du; v1+=dv;
223 if(Surf->IsUPeriodic()) { }
225 if(u0<=Umin) { u0=Umin; }
226 if(u1>=Umax) { u1=Umax; }
228 if(Surf->IsVPeriodic()) { }
230 if(v0<=Vmin) { v0=Vmin; }
231 if(v1>=Vmax) { v1=Vmax; }
233 P.SetCoord(u0,v0) ; Baux.Add(P);
234 P.SetCoord(u1,v1) ; Baux.Add(P);
237 Standard_Real aXmin, aYmin, aXmax, aYmax;
238 Baux.Get(aXmin, aYmin, aXmax, aYmax);
239 Standard_Real Tol2d = Precision::PConfusion();
240 if (Abs(aXmin - Umin) <= Tol2d)
242 if (Abs(aYmin - Vmin) <= Tol2d)
244 if (Abs(aXmax - Umax) <= Tol2d)
246 if (Abs(aYmax - Vmax) <= Tol2d)
248 FinalBox.Update(aXmin, aYmin, aXmax, aYmax);
254 //=======================================================================
257 //=======================================================================
259 void BRepTools::Update(const TopoDS_Vertex&)
263 //=======================================================================
266 //=======================================================================
268 void BRepTools::Update(const TopoDS_Edge&)
272 //=======================================================================
275 //=======================================================================
277 void BRepTools::Update(const TopoDS_Wire&)
281 //=======================================================================
284 //=======================================================================
286 void BRepTools::Update(const TopoDS_Face& F)
289 UpdateFaceUVPoints(F);
290 F.TShape()->Checked(Standard_True);
294 //=======================================================================
297 //=======================================================================
299 void BRepTools::Update(const TopoDS_Shell& S)
301 TopExp_Explorer ex(S,TopAbs_FACE);
303 Update(TopoDS::Face(ex.Current()));
308 //=======================================================================
311 //=======================================================================
313 void BRepTools::Update(const TopoDS_Solid& S)
315 TopExp_Explorer ex(S,TopAbs_FACE);
317 Update(TopoDS::Face(ex.Current()));
322 //=======================================================================
325 //=======================================================================
327 void BRepTools::Update(const TopoDS_CompSolid& CS)
329 TopExp_Explorer ex(CS,TopAbs_FACE);
331 Update(TopoDS::Face(ex.Current()));
336 //=======================================================================
339 //=======================================================================
341 void BRepTools::Update(const TopoDS_Compound& C)
343 TopExp_Explorer ex(C,TopAbs_FACE);
345 Update(TopoDS::Face(ex.Current()));
350 //=======================================================================
353 //=======================================================================
355 void BRepTools::Update(const TopoDS_Shape& S)
357 switch (S.ShapeType()) {
360 Update(TopoDS::Vertex(S));
364 Update(TopoDS::Edge(S));
368 Update(TopoDS::Wire(S));
372 Update(TopoDS::Face(S));
376 Update(TopoDS::Shell(S));
380 Update(TopoDS::Solid(S));
383 case TopAbs_COMPSOLID :
384 Update(TopoDS::CompSolid(S));
387 case TopAbs_COMPOUND :
388 Update(TopoDS::Compound(S));
398 //=======================================================================
399 //function : UpdateFaceUVPoints
400 //purpose : reset the UV points of a Face
401 //=======================================================================
403 void BRepTools::UpdateFaceUVPoints(const TopoDS_Face& F)
405 // Recompute for each edge the two UV points in order to have the same
406 // UV point on connected edges.
408 // First edge loop, store the vertices in a Map with their 2d points
410 BRepTools_MapOfVertexPnt2d theVertices;
411 TopoDS_Iterator expE,expV;
412 TopoDS_Iterator EdgeIt,VertIt;
413 TColStd_SequenceOfReal aFSeq, aLSeq;
414 TColGeom2d_SequenceOfCurve aCSeq;
415 TopTools_SequenceOfShape aShSeq;
418 // a 3d tolerance for UV !!
419 Standard_Real tolerance = BRep_Tool::Tolerance(F);
420 TColgp_SequenceOfPnt2d emptySequence;
422 for (expE.Initialize(F); expE.More(); expE.Next()) {
423 if(expE.Value().ShapeType() != TopAbs_WIRE)
426 EdgeIt.Initialize(expE.Value());
427 for( ; EdgeIt.More(); EdgeIt.Next())
429 const TopoDS_Edge& E = TopoDS::Edge(EdgeIt.Value());
431 Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,f,l);
438 if (C.IsNull()) continue;
440 for (expV.Initialize(E.Oriented(TopAbs_FORWARD));
441 expV.More(); expV.Next()) {
443 const TopoDS_Vertex& V = TopoDS::Vertex(expV.Value());
445 TopAbs_Orientation Vori = V.Orientation();
446 if ( Vori == TopAbs_INTERNAL ) {
450 Standard_Real p = BRep_Tool::Parameter(V,E,F);
452 if (!theVertices.IsBound(V))
453 theVertices.Bind(V,emptySequence);
454 TColgp_SequenceOfPnt2d& S = theVertices(V);
455 for (i = 1; i <= S.Length(); i++) {
456 if (P.Distance(S(i)) < tolerance) break;
464 // second edge loop, update the edges 2d points
468 for(Standard_Integer j = 1; j <= aShSeq.Length(); j++)
470 const TopoDS_Edge& E = TopoDS::Edge(aShSeq.Value(j));
471 const Handle(Geom2d_Curve)& C = aCSeq.Value(j);
472 if (C.IsNull()) continue;
474 TopExp::Vertices(E,Vf,Vl);
476 Pf.SetCoord(RealLast(),RealLast());
479 if ( Vf.Orientation() == TopAbs_INTERNAL ) {
482 const TColgp_SequenceOfPnt2d& seqf = theVertices(Vf);
483 if (seqf.Length() == 1)
486 C->D0(aFSeq.Value(j),Pf);
487 for (i = 1; i <= seqf.Length(); i++) {
488 if (Pf.Distance(seqf(i)) <= tolerance) {
496 Pl.SetCoord(RealLast(),RealLast());
499 if ( Vl.Orientation() == TopAbs_INTERNAL ) {
502 const TColgp_SequenceOfPnt2d& seql = theVertices(Vl);
503 if (seql.Length() == 1)
506 C->D0(aLSeq.Value(j),Pl);
507 for (i = 1; i <= seql.Length(); i++) {
508 if (Pl.Distance(seql(i)) <= tolerance) {
516 // set the correct points
517 BRep_Tool::SetUVPoints(E,F,Pf,Pl);
523 //=======================================================================
526 //=======================================================================
528 Standard_Boolean BRepTools::Compare(const TopoDS_Vertex& V1,
529 const TopoDS_Vertex& V2)
531 if (V1.IsSame(V2)) return Standard_True;
532 gp_Pnt p1 = BRep_Tool::Pnt(V1);
533 gp_Pnt p2 = BRep_Tool::Pnt(V2);
534 Standard_Real l = p1.Distance(p2);
535 if (l <= BRep_Tool::Tolerance(V1)) return Standard_True;
536 if (l <= BRep_Tool::Tolerance(V2)) return Standard_True;
537 return Standard_False;
540 //=======================================================================
543 //=======================================================================
545 Standard_Boolean BRepTools::Compare(const TopoDS_Edge& E1,
546 const TopoDS_Edge& E2)
548 if (E1.IsSame(E2)) return Standard_True;
549 return Standard_False;
552 //=======================================================================
553 //function : OuterWire
555 //=======================================================================
557 TopoDS_Wire BRepTools::OuterWire(const TopoDS_Face& F)
560 TopExp_Explorer expw (F,TopAbs_WIRE);
563 Wres = TopoDS::Wire(expw.Current());
566 Standard_Real UMin, UMax, VMin, VMax;
567 Standard_Real umin, umax, vmin, vmax;
568 BRepTools::UVBounds(F,Wres,UMin,UMax,VMin,VMax);
569 while (expw.More()) {
570 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
571 BRepTools::UVBounds(F,W,umin, umax, vmin, vmax);
572 if ((umin <= UMin) &&
589 //=======================================================================
590 //function : Map3DEdges
592 //=======================================================================
594 void BRepTools::Map3DEdges(const TopoDS_Shape& S,
595 TopTools_IndexedMapOfShape& M)
598 for (Ex.Init(S,TopAbs_EDGE); Ex.More(); Ex.Next()) {
599 if (!BRep_Tool::Degenerated(TopoDS::Edge(Ex.Current())))
604 //=======================================================================
607 //=======================================================================
609 void BRepTools::Dump(const TopoDS_Shape& Sh, Standard_OStream& S)
611 BRepTools_ShapeSet SS;
618 //=======================================================================
619 //function : BRepTools_Write
621 //=======================================================================
622 void BRepTools_Write (const TopoDS_Shape& S,
623 const Standard_CString File)
625 BRepTools::Write (S,File);
629 //=======================================================================
632 //=======================================================================
634 void BRepTools::Write(const TopoDS_Shape& Sh, Standard_OStream& S,
635 const Handle(Message_ProgressIndicator)& PR)
637 BRepTools_ShapeSet SS;
645 //=======================================================================
648 //=======================================================================
650 void BRepTools::Read(TopoDS_Shape& Sh,
652 const BRep_Builder& B,
653 const Handle(Message_ProgressIndicator)& PR)
655 BRepTools_ShapeSet SS(B);
661 //=======================================================================
664 //=======================================================================
666 Standard_Boolean BRepTools::Write(const TopoDS_Shape& Sh,
667 const Standard_CString File,
668 const Handle(Message_ProgressIndicator)& PR)
671 // if (!fic.open(File,output)) return Standard_False;
672 os.open(File, ios::out);
673 if (!os.rdbuf()->is_open()) return Standard_False;
675 Standard_Boolean isGood = (os.good() && !os.eof());
679 BRepTools_ShapeSet SS;
683 os << "DBRep_DrawableShape\n"; // for easy Draw read
693 isGood = os.good() && isGood && !errno;
698 //=======================================================================
701 //=======================================================================
703 Standard_Boolean BRepTools::Read(TopoDS_Shape& Sh,
704 const Standard_CString File,
705 const BRep_Builder& B,
706 const Handle(Message_ProgressIndicator)& PR)
710 if (!fic.open(File, ios::in)) return Standard_False;
712 BRepTools_ShapeSet SS(B);
715 if(!SS.NbShapes()) return Standard_False;
717 return Standard_True;
721 //=======================================================================
724 //=======================================================================
726 void BRepTools::Clean(const TopoDS_Shape& S)
730 Handle(Poly_Triangulation) TNULL, T;
731 Handle(Poly_PolygonOnTriangulation) PolyNULL, Poly;
735 for (ex.Init(S,TopAbs_FACE);ex.More();ex.Next()) {
736 const TopoDS_Face& F = TopoDS::Face(ex.Current());
737 B.UpdateFace(F, TNULL);
739 for (ex.Init(S, TopAbs_EDGE); ex.More(); ex.Next()) {
740 const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
741 // agv 21.09.01 : Inefficient management of Locations -> improve performance
743 // BRep_Tool::PolygonOnTriangulation(E, Poly, T, L);
744 // B.UpdateEdge(E, PolyNULL, T, L);
745 // } while(!Poly.IsNull());
747 Handle(BRep_CurveRepresentation) cr;
748 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
749 BRep_ListOfCurveRepresentation& lcr = TE -> ChangeCurves();
750 BRep_ListIteratorOfListOfCurveRepresentation itcr(lcr);
752 // find and remove all representations
753 while (itcr.More()) {
755 if (cr->IsPolygonOnTriangulation())
760 TE->Modified(Standard_True);
766 //=======================================================================
767 //function : RemoveUnusedPCurves
769 //=======================================================================
771 void BRepTools::RemoveUnusedPCurves(const TopoDS_Shape& S)
773 TColStd_MapOfTransient UsedSurfaces;
775 TopExp_Explorer Explo(S, TopAbs_FACE);
776 for (; Explo.More(); Explo.Next())
778 TopoDS_Face aFace = TopoDS::Face(Explo.Current());
779 TopLoc_Location aLoc;
780 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
781 UsedSurfaces.Add(aSurf);
784 TopTools_IndexedMapOfShape Emap;
785 TopExp::MapShapes(S, TopAbs_EDGE, Emap);
788 for (i = 1; i <= Emap.Extent(); i++)
790 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Emap(i).TShape());
791 BRep_ListOfCurveRepresentation& lcr = TE -> ChangeCurves();
792 BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr );
795 Standard_Boolean ToRemove = Standard_False;
797 Handle(BRep_CurveRepresentation) CurveRep = itrep.Value();
798 if (CurveRep->IsCurveOnSurface())
800 Handle(Geom_Surface) aSurface = CurveRep->Surface();
801 if (!UsedSurfaces.Contains(aSurface))
802 ToRemove = Standard_True;
804 else if (CurveRep->IsRegularity())
806 Handle(Geom_Surface) Surf1 = CurveRep->Surface();
807 Handle(Geom_Surface) Surf2 = CurveRep->Surface2();
808 ToRemove = (!UsedSurfaces.Contains(Surf1) || !UsedSurfaces.Contains(Surf2));
819 //=======================================================================
820 //function : Triangulation
822 //=======================================================================
824 Standard_Boolean BRepTools::Triangulation(const TopoDS_Shape& S,
825 const Standard_Real deflec)
827 TopExp_Explorer exf, exe;
829 Handle(Poly_Triangulation) T;
830 Handle(Poly_PolygonOnTriangulation) Poly;
832 for (exf.Init(S, TopAbs_FACE); exf.More(); exf.Next()) {
833 const TopoDS_Face& F = TopoDS::Face(exf.Current());
834 T = BRep_Tool::Triangulation(F, l);
835 if (T.IsNull() || (T->Deflection() > deflec))
836 return Standard_False;
837 for (exe.Init(F, TopAbs_EDGE); exe.More(); exe.Next()) {
838 const TopoDS_Edge& E = TopoDS::Edge(exe.Current());
839 Poly = BRep_Tool::PolygonOnTriangulation(E, T, l);
840 if (Poly.IsNull()) return Standard_False;
843 return Standard_True;
847 //=======================================================================
848 //function : IsReallyClosed
850 //=======================================================================
852 Standard_Boolean BRepTools::IsReallyClosed(const TopoDS_Edge& E,
853 const TopoDS_Face& F)
855 if (!BRep_Tool::IsClosed(E,F)) {
856 return Standard_False;
858 Standard_Integer nbocc = 0;
860 for (exp.Init(F,TopAbs_EDGE);exp.More();exp.Next()) {
861 if (exp.Current().IsSame(E)) {