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.
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 <TColStd_Array1OfReal.hxx>
38 #include <TColGeom2d_SequenceOfCurve.hxx>
39 #include <TopTools_SequenceOfShape.hxx>
40 #include <Precision.hxx>
42 #include <Poly_Triangulation.hxx>
43 #include <Poly_PolygonOnTriangulation.hxx>
44 #include <TColStd_HArray1OfInteger.hxx>
45 #include <TColStd_MapOfTransient.hxx>
47 #include <gp_Lin2d.hxx>
49 #include <gp_Vec2d.hxx>
50 #include <Standard_ErrorHandler.hxx>
51 #include <Standard_Failure.hxx>
52 #include <Geom_RectangularTrimmedSurface.hxx>
53 #include <OSD_OpenFile.hxx>
57 //=======================================================================
60 //=======================================================================
62 void BRepTools::UVBounds(const TopoDS_Face& F,
63 Standard_Real& UMin, Standard_Real& UMax,
64 Standard_Real& VMin, Standard_Real& VMax)
68 B.Get(UMin,VMin,UMax,VMax);
71 //=======================================================================
74 //=======================================================================
76 void BRepTools::UVBounds(const TopoDS_Face& F,
78 Standard_Real& UMin, Standard_Real& UMax,
79 Standard_Real& VMin, Standard_Real& VMax)
83 B.Get(UMin,VMin,UMax,VMax);
87 //=======================================================================
90 //=======================================================================
92 void BRepTools::UVBounds(const TopoDS_Face& F,
94 Standard_Real& UMin, Standard_Real& UMax,
95 Standard_Real& VMin, Standard_Real& VMax)
99 B.Get(UMin,VMin,UMax,VMax);
102 //=======================================================================
103 //function : AddUVBounds
105 //=======================================================================
107 void BRepTools::AddUVBounds(const TopoDS_Face& FF, Bnd_Box2d& B)
110 F.Orientation(TopAbs_FORWARD);
111 TopExp_Explorer ex(F,TopAbs_EDGE);
113 // fill box for the given face
115 for (;ex.More();ex.Next()) {
116 BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),aBox);
119 // if the box is empty (face without edges or without pcurves),
120 // get natural bounds
122 Standard_Real UMin,UMax,VMin,VMax;
124 BRep_Tool::Surface(F,L)->Bounds(UMin,UMax,VMin,VMax);
125 aBox.Update(UMin,VMin,UMax,VMax);
128 // add face box to result
133 //=======================================================================
134 //function : AddUVBounds
136 //=======================================================================
137 void BRepTools::AddUVBounds(const TopoDS_Face& F,
138 const TopoDS_Wire& W,
142 for (ex.Init(W,TopAbs_EDGE);ex.More();ex.Next()) {
143 BRepTools::AddUVBounds(F,TopoDS::Edge(ex.Current()),B);
148 //=======================================================================
149 //function : AddUVBounds
151 //=======================================================================
152 void BRepTools::AddUVBounds(const TopoDS_Face& aF,
153 const TopoDS_Edge& aE,
156 Standard_Real aT1, aT2, aXmin, aYmin, aXmax, aYmax;
157 Standard_Real aUmin, aUmax, aVmin, aVmax;
158 Bnd_Box2d aBoxC, aBoxS;
159 TopLoc_Location aLoc;
161 const Handle(Geom2d_Curve) aC2D = BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
166 BndLib_Add2dCurve::Add(aC2D, aT1, aT2, 0., aBoxC);
167 aBoxC.Get(aXmin, aYmin, aXmax, aYmax);
169 Handle(Geom_Surface) aS = BRep_Tool::Surface(aF, aLoc);
170 aS->Bounds(aUmin, aUmax, aVmin, aVmax);
172 if(aS->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
174 const Handle(Geom_RectangularTrimmedSurface) aSt =
175 Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
176 aS = aSt->BasisSurface();
180 if(!aS->IsUPeriodic())
182 if((aXmin<aUmin) && (aUmin < aXmax))
186 if((aXmin < aUmax) && (aUmax < aXmax))
192 if(!aS->IsVPeriodic())
194 if((aYmin<aVmin) && (aVmin < aYmax))
199 if((aYmin < aVmax) && (aVmax < aYmax))
205 aBoxS.Update(aXmin, aYmin, aXmax, aYmax);
210 //=======================================================================
213 //=======================================================================
215 void BRepTools::Update(const TopoDS_Vertex&)
219 //=======================================================================
222 //=======================================================================
224 void BRepTools::Update(const TopoDS_Edge&)
228 //=======================================================================
231 //=======================================================================
233 void BRepTools::Update(const TopoDS_Wire&)
237 //=======================================================================
240 //=======================================================================
242 void BRepTools::Update(const TopoDS_Face& F)
245 UpdateFaceUVPoints(F);
246 F.TShape()->Checked(Standard_True);
250 //=======================================================================
253 //=======================================================================
255 void BRepTools::Update(const TopoDS_Shell& S)
257 TopExp_Explorer ex(S,TopAbs_FACE);
259 Update(TopoDS::Face(ex.Current()));
264 //=======================================================================
267 //=======================================================================
269 void BRepTools::Update(const TopoDS_Solid& S)
271 TopExp_Explorer ex(S,TopAbs_FACE);
273 Update(TopoDS::Face(ex.Current()));
278 //=======================================================================
281 //=======================================================================
283 void BRepTools::Update(const TopoDS_CompSolid& CS)
285 TopExp_Explorer ex(CS,TopAbs_FACE);
287 Update(TopoDS::Face(ex.Current()));
292 //=======================================================================
295 //=======================================================================
297 void BRepTools::Update(const TopoDS_Compound& C)
299 TopExp_Explorer ex(C,TopAbs_FACE);
301 Update(TopoDS::Face(ex.Current()));
306 //=======================================================================
309 //=======================================================================
311 void BRepTools::Update(const TopoDS_Shape& S)
313 switch (S.ShapeType()) {
316 Update(TopoDS::Vertex(S));
320 Update(TopoDS::Edge(S));
324 Update(TopoDS::Wire(S));
328 Update(TopoDS::Face(S));
332 Update(TopoDS::Shell(S));
336 Update(TopoDS::Solid(S));
339 case TopAbs_COMPSOLID :
340 Update(TopoDS::CompSolid(S));
343 case TopAbs_COMPOUND :
344 Update(TopoDS::Compound(S));
354 //=======================================================================
355 //function : UpdateFaceUVPoints
356 //purpose : reset the UV points of a Face
357 //=======================================================================
359 void BRepTools::UpdateFaceUVPoints(const TopoDS_Face& F)
361 // Recompute for each edge the two UV points in order to have the same
362 // UV point on connected edges.
364 // First edge loop, store the vertices in a Map with their 2d points
366 BRepTools_MapOfVertexPnt2d theVertices;
367 TopoDS_Iterator expE,expV;
368 TopoDS_Iterator EdgeIt,VertIt;
369 TColStd_SequenceOfReal aFSeq, aLSeq;
370 TColGeom2d_SequenceOfCurve aCSeq;
371 TopTools_SequenceOfShape aShSeq;
374 // a 3d tolerance for UV !!
375 Standard_Real tolerance = BRep_Tool::Tolerance(F);
376 TColgp_SequenceOfPnt2d emptySequence;
378 for (expE.Initialize(F); expE.More(); expE.Next()) {
379 if(expE.Value().ShapeType() != TopAbs_WIRE)
382 EdgeIt.Initialize(expE.Value());
383 for( ; EdgeIt.More(); EdgeIt.Next())
385 const TopoDS_Edge& E = TopoDS::Edge(EdgeIt.Value());
387 Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,f,l);
394 if (C.IsNull()) continue;
396 for (expV.Initialize(E.Oriented(TopAbs_FORWARD));
397 expV.More(); expV.Next()) {
399 const TopoDS_Vertex& V = TopoDS::Vertex(expV.Value());
401 TopAbs_Orientation Vori = V.Orientation();
402 if ( Vori == TopAbs_INTERNAL ) {
406 Standard_Real p = BRep_Tool::Parameter(V,E,F);
408 if (!theVertices.IsBound(V))
409 theVertices.Bind(V,emptySequence);
410 TColgp_SequenceOfPnt2d& S = theVertices(V);
411 for (i = 1; i <= S.Length(); i++) {
412 if (P.Distance(S(i)) < tolerance) break;
420 // second edge loop, update the edges 2d points
424 for(Standard_Integer j = 1; j <= aShSeq.Length(); j++)
426 const TopoDS_Edge& E = TopoDS::Edge(aShSeq.Value(j));
427 const Handle(Geom2d_Curve)& C = aCSeq.Value(j);
428 if (C.IsNull()) continue;
430 TopExp::Vertices(E,Vf,Vl);
432 Pf.SetCoord(RealLast(),RealLast());
435 if ( Vf.Orientation() == TopAbs_INTERNAL ) {
438 const TColgp_SequenceOfPnt2d& seqf = theVertices(Vf);
439 if (seqf.Length() == 1)
442 C->D0(aFSeq.Value(j),Pf);
443 for (i = 1; i <= seqf.Length(); i++) {
444 if (Pf.Distance(seqf(i)) <= tolerance) {
452 Pl.SetCoord(RealLast(),RealLast());
455 if ( Vl.Orientation() == TopAbs_INTERNAL ) {
458 const TColgp_SequenceOfPnt2d& seql = theVertices(Vl);
459 if (seql.Length() == 1)
462 C->D0(aLSeq.Value(j),Pl);
463 for (i = 1; i <= seql.Length(); i++) {
464 if (Pl.Distance(seql(i)) <= tolerance) {
472 // set the correct points
473 BRep_Tool::SetUVPoints(E,F,Pf,Pl);
479 //=======================================================================
482 //=======================================================================
484 Standard_Boolean BRepTools::Compare(const TopoDS_Vertex& V1,
485 const TopoDS_Vertex& V2)
487 if (V1.IsSame(V2)) return Standard_True;
488 gp_Pnt p1 = BRep_Tool::Pnt(V1);
489 gp_Pnt p2 = BRep_Tool::Pnt(V2);
490 Standard_Real l = p1.Distance(p2);
491 if (l <= BRep_Tool::Tolerance(V1)) return Standard_True;
492 if (l <= BRep_Tool::Tolerance(V2)) return Standard_True;
493 return Standard_False;
496 //=======================================================================
499 //=======================================================================
501 Standard_Boolean BRepTools::Compare(const TopoDS_Edge& E1,
502 const TopoDS_Edge& E2)
504 if (E1.IsSame(E2)) return Standard_True;
505 return Standard_False;
508 //=======================================================================
509 //function : OuterWire
511 //=======================================================================
513 TopoDS_Wire BRepTools::OuterWire(const TopoDS_Face& F)
516 TopExp_Explorer expw (F,TopAbs_WIRE);
519 Wres = TopoDS::Wire(expw.Current());
522 Standard_Real UMin, UMax, VMin, VMax;
523 Standard_Real umin, umax, vmin, vmax;
524 BRepTools::UVBounds(F,Wres,UMin,UMax,VMin,VMax);
525 while (expw.More()) {
526 const TopoDS_Wire& W = TopoDS::Wire(expw.Current());
527 BRepTools::UVBounds(F,W,umin, umax, vmin, vmax);
528 if ((umin <= UMin) &&
545 //=======================================================================
546 //function : Map3DEdges
548 //=======================================================================
550 void BRepTools::Map3DEdges(const TopoDS_Shape& S,
551 TopTools_IndexedMapOfShape& M)
554 for (Ex.Init(S,TopAbs_EDGE); Ex.More(); Ex.Next()) {
555 if (!BRep_Tool::Degenerated(TopoDS::Edge(Ex.Current())))
560 //=======================================================================
563 //=======================================================================
565 void BRepTools::Dump(const TopoDS_Shape& Sh, Standard_OStream& S)
567 BRepTools_ShapeSet SS;
573 //=======================================================================
576 //=======================================================================
578 void BRepTools::Write(const TopoDS_Shape& Sh, Standard_OStream& S,
579 const Handle(Message_ProgressIndicator)& PR)
581 BRepTools_ShapeSet SS;
589 //=======================================================================
592 //=======================================================================
594 void BRepTools::Read(TopoDS_Shape& Sh,
596 const BRep_Builder& B,
597 const Handle(Message_ProgressIndicator)& PR)
599 BRepTools_ShapeSet SS(B);
605 //=======================================================================
608 //=======================================================================
610 Standard_Boolean BRepTools::Write(const TopoDS_Shape& Sh,
611 const Standard_CString File,
612 const Handle(Message_ProgressIndicator)& PR)
615 OSD_OpenStream(os, File, ios::out);
616 if (!os.rdbuf()->is_open()) return Standard_False;
618 Standard_Boolean isGood = (os.good() && !os.eof());
622 BRepTools_ShapeSet SS;
626 os << "DBRep_DrawableShape\n"; // for easy Draw read
636 isGood = os.good() && isGood && !errno;
641 //=======================================================================
644 //=======================================================================
646 Standard_Boolean BRepTools::Read(TopoDS_Shape& Sh,
647 const Standard_CString File,
648 const BRep_Builder& B,
649 const Handle(Message_ProgressIndicator)& PR)
653 OSD_OpenFileBuf(fic,File,ios::in);
654 if(!fic.is_open()) return Standard_False;
656 BRepTools_ShapeSet SS(B);
659 if(!SS.NbShapes()) return Standard_False;
661 return Standard_True;
665 //=======================================================================
668 //=======================================================================
670 void BRepTools::Clean(const TopoDS_Shape& theShape)
672 BRep_Builder aBuilder;
673 Handle(Poly_Triangulation) aNullTriangulation;
674 Handle(Poly_PolygonOnTriangulation) aNullPoly;
676 if (theShape.IsNull())
679 TopExp_Explorer aFaceIt(theShape, TopAbs_FACE);
680 for (; aFaceIt.More(); aFaceIt.Next())
682 const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
684 TopLoc_Location aLoc;
685 const Handle(Poly_Triangulation)& aTriangulation =
686 BRep_Tool::Triangulation(aFace, aLoc);
688 if (aTriangulation.IsNull())
692 TopExp_Explorer aEdgeIt(aFace, TopAbs_EDGE);
693 for (; aEdgeIt.More(); aEdgeIt.Next())
695 const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
696 aBuilder.UpdateEdge(aEdge, aNullPoly, aTriangulation, aLoc);
699 aBuilder.UpdateFace(aFace, aNullTriangulation);
703 //=======================================================================
704 //function : RemoveUnusedPCurves
706 //=======================================================================
708 void BRepTools::RemoveUnusedPCurves(const TopoDS_Shape& S)
710 TColStd_MapOfTransient UsedSurfaces;
712 TopExp_Explorer Explo(S, TopAbs_FACE);
713 for (; Explo.More(); Explo.Next())
715 TopoDS_Face aFace = TopoDS::Face(Explo.Current());
716 TopLoc_Location aLoc;
717 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
718 UsedSurfaces.Add(aSurf);
721 TopTools_IndexedMapOfShape Emap;
722 TopExp::MapShapes(S, TopAbs_EDGE, Emap);
725 for (i = 1; i <= Emap.Extent(); i++)
727 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Emap(i).TShape());
728 BRep_ListOfCurveRepresentation& lcr = TE -> ChangeCurves();
729 BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr );
732 Standard_Boolean ToRemove = Standard_False;
734 Handle(BRep_CurveRepresentation) CurveRep = itrep.Value();
735 if (CurveRep->IsCurveOnSurface())
737 Handle(Geom_Surface) aSurface = CurveRep->Surface();
738 if (!UsedSurfaces.Contains(aSurface))
739 ToRemove = Standard_True;
741 else if (CurveRep->IsRegularity())
743 Handle(Geom_Surface) Surf1 = CurveRep->Surface();
744 Handle(Geom_Surface) Surf2 = CurveRep->Surface2();
745 ToRemove = (!UsedSurfaces.Contains(Surf1) || !UsedSurfaces.Contains(Surf2));
756 //=======================================================================
757 //function : Triangulation
759 //=======================================================================
761 Standard_Boolean BRepTools::Triangulation(const TopoDS_Shape& S,
762 const Standard_Real deflec)
764 TopExp_Explorer exf, exe;
766 Handle(Poly_Triangulation) T;
767 Handle(Poly_PolygonOnTriangulation) Poly;
769 for (exf.Init(S, TopAbs_FACE); exf.More(); exf.Next()) {
770 const TopoDS_Face& F = TopoDS::Face(exf.Current());
771 T = BRep_Tool::Triangulation(F, l);
772 if (T.IsNull() || (T->Deflection() > deflec))
773 return Standard_False;
774 for (exe.Init(F, TopAbs_EDGE); exe.More(); exe.Next()) {
775 const TopoDS_Edge& E = TopoDS::Edge(exe.Current());
776 Poly = BRep_Tool::PolygonOnTriangulation(E, T, l);
777 if (Poly.IsNull()) return Standard_False;
780 return Standard_True;
784 //=======================================================================
785 //function : IsReallyClosed
787 //=======================================================================
789 Standard_Boolean BRepTools::IsReallyClosed(const TopoDS_Edge& E,
790 const TopoDS_Face& F)
792 if (!BRep_Tool::IsClosed(E,F)) {
793 return Standard_False;
795 Standard_Integer nbocc = 0;
797 for (exp.Init(F,TopAbs_EDGE);exp.More();exp.Next()) {
798 if (exp.Current().IsSame(E)) {