1 // Created on: 1993-07-23
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 <BRep_Builder.hxx>
19 #include <BRepLib.hxx>
20 #include <BRepLib_FindSurface.hxx>
21 #include <BRepLib_MakeFace.hxx>
22 #include <BRepTopAdaptor_FClass2d.hxx>
24 #include <Geom2d_Line.hxx>
25 #include <Geom_BezierCurve.hxx>
26 #include <Geom_BSplineCurve.hxx>
27 #include <Geom_ConicalSurface.hxx>
28 #include <Geom_Curve.hxx>
29 #include <Geom_CylindricalSurface.hxx>
30 #include <Geom_OffsetSurface.hxx>
31 #include <Geom_Plane.hxx>
32 #include <Geom_RectangularTrimmedSurface.hxx>
33 #include <Geom_SphericalSurface.hxx>
34 #include <Geom_Surface.hxx>
35 #include <Geom_SurfaceOfLinearExtrusion.hxx>
36 #include <Geom_SurfaceOfRevolution.hxx>
37 #include <Geom_ToroidalSurface.hxx>
38 #include <GeomAbs_CurveType.hxx>
39 #include <GeomAdaptor_Curve.hxx>
40 #include <gp_Cone.hxx>
41 #include <gp_Cylinder.hxx>
43 #include <gp_Sphere.hxx>
44 #include <gp_Torus.hxx>
45 #include <Precision.hxx>
46 #include <StdFail_NotDone.hxx>
47 #include <TopAbs_State.hxx>
49 #include <TopoDS_Edge.hxx>
50 #include <TopoDS_Face.hxx>
51 #include <TopoDS_Iterator.hxx>
52 #include <TopoDS_Vertex.hxx>
53 #include <TopoDS_Wire.hxx>
55 //=======================================================================
56 //function : BRepLib_MakeFace
58 //=======================================================================
59 BRepLib_MakeFace::BRepLib_MakeFace() :
60 myError(BRepLib_NoFace)
65 //=======================================================================
66 //function : BRepLib_MakeFace
68 //=======================================================================
70 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Face& F)
76 //=======================================================================
77 //function : BRepLib_MakeFace
79 //=======================================================================
81 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Pln& P)
83 Handle(Geom_Plane) GP = new Geom_Plane(P);
84 Init(GP, Standard_True, Precision::Confusion());
88 //=======================================================================
89 //function : BRepLib_MakeFace
91 //=======================================================================
93 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cylinder& C)
95 Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
96 Init(GC, Standard_True, Precision::Confusion());
100 //=======================================================================
101 //function : BRepLib_MakeFace
103 //=======================================================================
105 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cone& C)
107 Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
108 Init(GC, Standard_True, Precision::Confusion());
112 //=======================================================================
113 //function : BRepLib_MakeFace
115 //=======================================================================
117 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Sphere& S)
119 Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
120 Init(GS, Standard_True, Precision::Confusion());
124 //=======================================================================
125 //function : BRepLib_MakeFace
127 //=======================================================================
129 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Torus& T)
131 Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
132 Init(GT, Standard_True, Precision::Confusion());
136 //=======================================================================
137 //function : BRepLib_MakeFace
139 //=======================================================================
141 BRepLib_MakeFace::BRepLib_MakeFace(const Handle(Geom_Surface)& S,
142 const Standard_Real TolDegen)
144 Init(S, Standard_True, TolDegen);
148 //=======================================================================
149 //function : BRepLib_MakeFace
151 //=======================================================================
153 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Pln& P,
154 const Standard_Real UMin,
155 const Standard_Real UMax,
156 const Standard_Real VMin,
157 const Standard_Real VMax)
159 Handle(Geom_Plane) GP = new Geom_Plane(P);
160 Init(GP, UMin, UMax, VMin, VMax, Precision::Confusion());
164 //=======================================================================
165 //function : BRepLib_MakeFace
167 //=======================================================================
169 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cylinder& C,
170 const Standard_Real UMin,
171 const Standard_Real UMax,
172 const Standard_Real VMin,
173 const Standard_Real VMax)
175 Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
176 Init(GC, UMin, UMax, VMin, VMax, Precision::Confusion());
180 //=======================================================================
181 //function : BRepLib_MakeFace
183 //=======================================================================
185 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cone& C,
186 const Standard_Real UMin,
187 const Standard_Real UMax,
188 const Standard_Real VMin,
189 const Standard_Real VMax)
191 Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
192 Init(GC, UMin, UMax, VMin, VMax, Precision::Confusion());
196 //=======================================================================
197 //function : BRepLib_MakeFace
199 //=======================================================================
201 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Sphere& S,
202 const Standard_Real UMin,
203 const Standard_Real UMax,
204 const Standard_Real VMin,
205 const Standard_Real VMax)
207 Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
208 Init(GS, UMin, UMax, VMin, VMax, Precision::Confusion());
212 //=======================================================================
213 //function : BRepLib_MakeFace
215 //=======================================================================
217 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Torus& T,
218 const Standard_Real UMin,
219 const Standard_Real UMax,
220 const Standard_Real VMin,
221 const Standard_Real VMax)
223 Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
224 Init(GT, UMin, UMax, VMin, VMax, Precision::Confusion());
228 //=======================================================================
229 //function : BRepLib_MakeFace
231 //=======================================================================
233 BRepLib_MakeFace::BRepLib_MakeFace(const Handle(Geom_Surface)& S,
234 const Standard_Real UMin,
235 const Standard_Real UMax,
236 const Standard_Real VMin,
237 const Standard_Real VMax,
238 const Standard_Real TolDegen)
240 Init(S, UMin, UMax, VMin, VMax, TolDegen);
244 //=======================================================================
245 //function : BRepLib_MakeFace
247 //=======================================================================
249 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Wire& W,
250 const Standard_Boolean OnlyPlane)
253 // Find a surface through the wire
254 BRepLib_FindSurface FS(W, -1, OnlyPlane, Standard_True);
256 myError = BRepLib_NotPlanar;
260 // build the face and add the wire
262 myError = BRepLib_FaceDone;
264 Standard_Real tol = Max(1.2*FS.ToleranceReached(), FS.Tolerance());
266 B.MakeFace(TopoDS::Face(myShape),FS.Surface(),FS.Location(),tol);
269 BRepLib::UpdateTolerances(myShape);
271 BRepLib::SameParameter(myShape, tol, Standard_True);
273 if (BRep_Tool::IsClosed(W))
278 //=======================================================================
279 //function : BRepLib_MakeFace
281 //=======================================================================
283 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Pln& P,
284 const TopoDS_Wire& W,
285 const Standard_Boolean Inside)
287 Handle(Geom_Plane) Pl = new Geom_Plane(P);
288 Init(Pl, Standard_False, Precision::Confusion());
290 if (Inside && BRep_Tool::IsClosed(W)) CheckInside();
294 //=======================================================================
295 //function : BRepLib_MakeFace
297 //=======================================================================
299 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cylinder& C,
300 const TopoDS_Wire& W,
301 const Standard_Boolean Inside)
303 Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
304 Init(GC, Standard_False, Precision::Confusion());
306 if (Inside && BRep_Tool::IsClosed(W)) CheckInside();
310 //=======================================================================
311 //function : BRepLib_MakeFace
313 //=======================================================================
315 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cone& C,
316 const TopoDS_Wire& W,
317 const Standard_Boolean Inside)
319 Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
320 Init(GC, Standard_False, Precision::Confusion());
322 if (Inside && BRep_Tool::IsClosed(W)) CheckInside();
326 //=======================================================================
327 //function : BRepLib_MakeFace
329 //=======================================================================
331 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Sphere& S,
332 const TopoDS_Wire& W,
333 const Standard_Boolean Inside)
335 Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
336 Init(GS, Standard_False, Precision::Confusion());
338 if (Inside && BRep_Tool::IsClosed(W)) CheckInside();
342 //=======================================================================
343 //function : BRepLib_MakeFace
345 //=======================================================================
347 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Torus& T,
348 const TopoDS_Wire& W,
349 const Standard_Boolean Inside)
351 Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
352 Init(GT, Standard_False, Precision::Confusion());
354 if (Inside && BRep_Tool::IsClosed(W)) CheckInside();
358 //=======================================================================
359 //function : BRepLib_MakeFace
361 //=======================================================================
363 BRepLib_MakeFace::BRepLib_MakeFace(const Handle(Geom_Surface)& S,
364 const TopoDS_Wire& W,
365 const Standard_Boolean Inside)
367 Init(S, Standard_False, Precision::Confusion());
369 if (Inside && BRep_Tool::IsClosed(W)) CheckInside();
373 //=======================================================================
374 //function : BRepLib_MakeFace
376 //=======================================================================
378 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Face& F,
379 const TopoDS_Wire& W)
385 //=======================================================================
388 //=======================================================================
390 void BRepLib_MakeFace::Init(const TopoDS_Face& F)
393 myShape = F.EmptyCopied();
394 myError = BRepLib_FaceDone;
397 TopoDS_Iterator It(F);
399 B.Add(myShape,It.Value());
404 //=======================================================================
407 //=======================================================================
409 void BRepLib_MakeFace::Init(const Handle(Geom_Surface)& S,
410 const Standard_Boolean Bound,
411 const Standard_Real TolDegen)
413 myError = BRepLib_FaceDone;
415 Standard_Real UMin,UMax,VMin,VMax;
416 S->Bounds(UMin,UMax,VMin,VMax);
417 Init(S,UMin,UMax,VMin,VMax,TolDegen);
421 B.MakeFace(TopoDS::Face(myShape),S,Precision::Confusion());
424 B.NaturalRestriction(TopoDS::Face(myShape),Standard_True);
428 //=======================================================================
429 //function : IsDegenerated
430 //purpose : Checks whether the passed curve is degenerated with the
431 // passed tolerance value
432 //=======================================================================
434 Standard_Boolean BRepLib_MakeFace::IsDegenerated(
435 const Handle(Geom_Curve)& theCurve,
436 const Standard_Real theMaxTol,
437 Standard_Real& theActTol)
439 GeomAdaptor_Curve AC(theCurve);
440 Standard_Real aConfusion = Precision::Confusion();
441 theActTol = aConfusion;
442 GeomAbs_CurveType Type = AC.GetType();
444 if (Type == GeomAbs_Circle) {
445 gp_Circ Circ = AC.Circle();
446 if ( Circ.Radius() > theMaxTol )
447 return Standard_False;
448 theActTol = Max(Circ.Radius(), aConfusion);
449 return Standard_True;
451 else if (Type == GeomAbs_BSplineCurve) {
452 Handle(Geom_BSplineCurve) BS = AC.BSpline();
453 Standard_Integer NbPoles = BS->NbPoles();
454 Standard_Real aMaxPoleDist2 = 0.0, aMaxTol2 = theMaxTol*theMaxTol;
457 for (Standard_Integer i = 2; i <= NbPoles; i++) {
459 Standard_Real aPoleDist2 = P1.SquareDistance(P2);
460 if (aPoleDist2 > aMaxTol2)
461 return Standard_False;
462 if (aPoleDist2 > aMaxPoleDist2)
463 aMaxPoleDist2 = aPoleDist2;
465 theActTol = Max(1.000001*Sqrt(aMaxPoleDist2), aConfusion);
466 return Standard_True;
468 else if (Type == GeomAbs_BezierCurve) {
469 Handle(Geom_BezierCurve) BZ = AC.Bezier();
470 Standard_Integer NbPoles = BZ->NbPoles();
471 Standard_Real aMaxPoleDist2 = 0.0, aMaxTol2 = theMaxTol*theMaxTol;;
474 for (Standard_Integer i = 2; i <= NbPoles; i++) {
476 Standard_Real aPoleDist2 = P1.SquareDistance(P2);
477 if (aPoleDist2 > aMaxTol2)
478 return Standard_False;
479 if (aPoleDist2 > aMaxPoleDist2)
480 aMaxPoleDist2 = aPoleDist2;
482 theActTol = Max(1.000001*Sqrt(aMaxPoleDist2), aConfusion);
483 return Standard_True;
486 return Standard_False;
489 //=======================================================================
492 //=======================================================================
494 void BRepLib_MakeFace::Init(const Handle(Geom_Surface)& SS,
495 const Standard_Real Um,
496 const Standard_Real UM,
497 const Standard_Real Vm,
498 const Standard_Real VM,
499 const Standard_Real TolDegen)
501 myError = BRepLib_FaceDone;
503 Standard_Real UMin = Um;
504 Standard_Real UMax = UM;
505 Standard_Real VMin = Vm;
506 Standard_Real VMax = VM;
508 Standard_Real umin,umax,vmin,vmax,T;
510 Handle(Geom_Surface) S = SS, BS = SS;
511 Handle(Geom_RectangularTrimmedSurface) RS =
512 Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
514 BS = RS->BasisSurface();
516 Standard_Boolean OffsetSurface =
517 (BS->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface));
519 // adjust periodical surface or reordonate
520 // check if the values are in the natural range
521 Standard_Real epsilon = Precision::PConfusion();
523 BS->Bounds(umin,umax,vmin,vmax);
526 Handle(Geom_OffsetSurface) OS = Handle(Geom_OffsetSurface)::DownCast(BS);
527 Handle(Geom_Surface) Base = OS->BasisSurface();
529 if (Base->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
530 if (Precision::IsInfinite(umin) || Precision::IsInfinite(umax))
531 S = new Geom_RectangularTrimmedSurface(OS, UMin, UMax, VMin, VMax);
533 S = new Geom_RectangularTrimmedSurface(OS, VMin, VMax, Standard_False);
534 } else if (Base->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution)) {
535 if (Precision::IsInfinite(vmin) || Precision::IsInfinite(vmax))
536 S = new Geom_RectangularTrimmedSurface(OS, VMin, VMax, Standard_False);
540 if (S->IsUPeriodic()) {
541 ElCLib::AdjustPeriodic(umin,umax,epsilon,UMin,UMax);
543 else if (UMin > UMax) {
547 if ((umin - UMin > epsilon) || (UMax - umax > epsilon)) {
548 myError = BRepLib_ParametersOutOfRange;
553 if (S->IsVPeriodic()) {
554 ElCLib::AdjustPeriodic(vmin,vmax,epsilon,VMin,VMax);
556 else if (VMin > VMax) {
560 if ((vmin - VMin > epsilon) || (VMax - vmax > epsilon)) {
561 myError = BRepLib_ParametersOutOfRange;
567 // compute infinite flags
568 Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
569 Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
570 Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
571 Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
574 Standard_Boolean uclosed =
576 Abs(UMin - umin) < epsilon &&
577 Abs(UMax - umax) < epsilon;
579 Standard_Boolean vclosed =
581 Abs(VMin - vmin) < epsilon &&
582 Abs(VMax - vmax) < epsilon;
585 // compute 3d curves and degenerate flag
586 Standard_Real maxTol = TolDegen;
587 Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
588 Standard_Boolean Dumin,Dumax,Dvmin,Dvmax;
589 Dumin = Dumax = Dvmin = Dvmax = Standard_False;
590 Standard_Real uminTol = Precision::Confusion(),
591 umaxTol = Precision::Confusion(),
592 vminTol = Precision::Confusion(),
593 vmaxTol = Precision::Confusion();
596 Cumin = S->UIso(UMin);
597 Dumin = IsDegenerated(Cumin, maxTol, uminTol);
600 Cumax = S->UIso(UMax);
601 Dumax = IsDegenerated(Cumax, maxTol, umaxTol);
604 Cvmin = S->VIso(VMin);
605 Dvmin = IsDegenerated(Cvmin, maxTol, vminTol);
608 Cvmax = S->VIso(VMax);
609 Dvmax = IsDegenerated(Cvmax, maxTol, vmaxTol);
615 TopoDS_Vertex V00,V10,V11,V01;
618 if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin), Max(uminTol, vminTol));
619 if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax), Max(uminTol, vmaxTol));
622 if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin), Max(umaxTol, vminTol));
623 if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax), Max(umaxTol, vmaxTol));
636 if (Dumin) V00 = V01;
637 if (Dumax) V10 = V11;
638 if (Dvmin) V00 = V10;
639 if (Dvmax) V01 = V11;
642 Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
644 Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
646 Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
648 Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
650 Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
653 TopoDS_Face& F = TopoDS::Face(myShape);
654 B.MakeFace(F,S,Precision::Confusion());
657 TopoDS_Edge eumin,eumax,evmin,evmax;
661 B.MakeEdge(eumin,Cumin,uminTol);
665 B.UpdateEdge(eumin,Lumax,Lumin,F,Max(uminTol, umaxTol));
667 B.UpdateEdge(eumin,Lumin,F,uminTol);
668 B.Degenerated(eumin,Dumin);
670 V00.Orientation(TopAbs_FORWARD);
674 V01.Orientation(TopAbs_REVERSED);
677 B.Range(eumin,VMin,VMax);
685 B.MakeEdge(eumax,Cumax,umaxTol);
688 B.UpdateEdge(eumax,Lumax,F,umaxTol);
689 B.Degenerated(eumax,Dumax);
691 V10.Orientation(TopAbs_FORWARD);
695 V11.Orientation(TopAbs_REVERSED);
698 B.Range(eumax,VMin,VMax);
704 B.MakeEdge(evmin,Cvmin,vminTol);
708 B.UpdateEdge(evmin,Lvmin,Lvmax,F,Max(vminTol, vmaxTol));
710 B.UpdateEdge(evmin,Lvmin,F,vminTol);
711 B.Degenerated(evmin,Dvmin);
713 V00.Orientation(TopAbs_FORWARD);
717 V10.Orientation(TopAbs_REVERSED);
720 B.Range(evmin,UMin,UMax);
728 B.MakeEdge(evmax,Cvmax,vmaxTol);
731 B.UpdateEdge(evmax,Lvmax,F,vmaxTol);
732 B.Degenerated(evmax,Dvmax);
734 V01.Orientation(TopAbs_FORWARD);
738 V11.Orientation(TopAbs_REVERSED);
741 B.Range(evmax,UMin,UMax);
745 // make the wires and add them to the face
746 eumin.Orientation(TopAbs_REVERSED);
747 evmax.Orientation(TopAbs_REVERSED);
751 if (!umininf && !umaxinf && vmininf && vmaxinf) {
762 else if (umininf && umaxinf && !vmininf && !vmaxinf) {
773 else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
776 if (!umininf) B.Add(W,eumin);
777 if (!vmininf) B.Add(W,evmin);
778 if (!umaxinf) B.Add(W,eumax);
779 if (!vmaxinf) B.Add(W,evmax);
781 W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
782 F.Closed(uclosed && vclosed);
786 // Les Isos sont Approximees a Precision::Approximation()
787 // et on code Precision::Confusion() dans l'arete.
788 // ==> Un petit passage dans SamePrameter pour regler les tolerances.
789 BRepLib::SameParameter(F, Precision::Confusion(), Standard_True);
796 //=======================================================================
799 //=======================================================================
801 void BRepLib_MakeFace::Add(const TopoDS_Wire& W)
805 B.NaturalRestriction(TopoDS::Face(myShape),Standard_False);
810 //=======================================================================
813 //=======================================================================
815 const TopoDS_Face& BRepLib_MakeFace::Face()const
817 return TopoDS::Face(myShape);
822 //=======================================================================
823 //function : operator
825 //=======================================================================
827 BRepLib_MakeFace::operator TopoDS_Face() const
832 //=======================================================================
835 //=======================================================================
837 BRepLib_FaceError BRepLib_MakeFace::Error() const
843 //=======================================================================
844 //function : CheckInside
845 //purpose : Reverses the current face if not a bounded area
846 //=======================================================================
848 void BRepLib_MakeFace::CheckInside()
850 // compute the area and return the face if the area is negative
851 TopoDS_Face F = TopoDS::Face(myShape);
852 BRepTopAdaptor_FClass2d FClass(F,0.);
853 if ( FClass.PerformInfinitePoint() == TopAbs_IN) {
855 TopoDS_Shape S = myShape.EmptyCopied();
856 TopoDS_Iterator it(myShape);
858 B.Add(S,it.Value().Reversed());