1 // Created on: 1993-07-23
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.
23 #include <BRepLib_MakeFace.ixx>
25 #include <Geom_Plane.hxx>
26 #include <Geom_CylindricalSurface.hxx>
27 #include <Geom_ConicalSurface.hxx>
28 #include <Geom_SphericalSurface.hxx>
29 #include <Geom_ToroidalSurface.hxx>
30 #include <Geom_RectangularTrimmedSurface.hxx>
31 #include <Geom_OffsetSurface.hxx>
32 #include <Geom_BSplineCurve.hxx>
33 #include <Geom_BezierCurve.hxx>
34 #include <GeomAdaptor_Curve.hxx>
35 #include <GeomAbs_CurveType.hxx>
37 #include <Geom2d_Line.hxx>
39 #include <BRep_Builder.hxx>
42 #include <TopoDS_Vertex.hxx>
43 #include <TopoDS_Edge.hxx>
44 #include <TopoDS_Iterator.hxx>
46 #include <BRepTopAdaptor_FClass2d.hxx>
47 #include <TopAbs_State.hxx>
50 #include <Precision.hxx>
51 #include <BRepLib.hxx>
53 #include <BRepLib_FindSurface.hxx>
54 #include <Geom_SurfaceOfLinearExtrusion.hxx>
55 #include <Geom_SurfaceOfRevolution.hxx>
57 //=======================================================================
58 //function : BRepLib_MakeFace
60 //=======================================================================
62 BRepLib_MakeFace::BRepLib_MakeFace() :
63 myError(BRepLib_NoFace)
68 //=======================================================================
69 //function : BRepLib_MakeFace
71 //=======================================================================
73 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Face& F)
79 //=======================================================================
80 //function : BRepLib_MakeFace
82 //=======================================================================
84 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Pln& P)
86 Handle(Geom_Plane) GP = new Geom_Plane(P);
87 Init(GP, Standard_True, Precision::Confusion());
91 //=======================================================================
92 //function : BRepLib_MakeFace
94 //=======================================================================
96 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cylinder& C)
98 Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
99 Init(GC, Standard_True, Precision::Confusion());
103 //=======================================================================
104 //function : BRepLib_MakeFace
106 //=======================================================================
108 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cone& C)
110 Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
111 Init(GC, Standard_True, Precision::Confusion());
115 //=======================================================================
116 //function : BRepLib_MakeFace
118 //=======================================================================
120 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Sphere& S)
122 Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
123 Init(GS, Standard_True, Precision::Confusion());
127 //=======================================================================
128 //function : BRepLib_MakeFace
130 //=======================================================================
132 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Torus& T)
134 Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
135 Init(GT, Standard_True, Precision::Confusion());
139 //=======================================================================
140 //function : BRepLib_MakeFace
142 //=======================================================================
144 BRepLib_MakeFace::BRepLib_MakeFace(const Handle(Geom_Surface)& S,
145 const Standard_Real TolDegen)
147 Init(S, Standard_True, TolDegen);
151 //=======================================================================
152 //function : BRepLib_MakeFace
154 //=======================================================================
156 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Pln& P,
157 const Standard_Real UMin,
158 const Standard_Real UMax,
159 const Standard_Real VMin,
160 const Standard_Real VMax)
162 Handle(Geom_Plane) GP = new Geom_Plane(P);
163 Init(GP, UMin, UMax, VMin, VMax, Precision::Confusion());
167 //=======================================================================
168 //function : BRepLib_MakeFace
170 //=======================================================================
172 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cylinder& C,
173 const Standard_Real UMin,
174 const Standard_Real UMax,
175 const Standard_Real VMin,
176 const Standard_Real VMax)
178 Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
179 Init(GC, UMin, UMax, VMin, VMax, Precision::Confusion());
183 //=======================================================================
184 //function : BRepLib_MakeFace
186 //=======================================================================
188 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cone& C,
189 const Standard_Real UMin,
190 const Standard_Real UMax,
191 const Standard_Real VMin,
192 const Standard_Real VMax)
194 Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
195 Init(GC, UMin, UMax, VMin, VMax, Precision::Confusion());
199 //=======================================================================
200 //function : BRepLib_MakeFace
202 //=======================================================================
204 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Sphere& S,
205 const Standard_Real UMin,
206 const Standard_Real UMax,
207 const Standard_Real VMin,
208 const Standard_Real VMax)
210 Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
211 Init(GS, UMin, UMax, VMin, VMax, Precision::Confusion());
215 //=======================================================================
216 //function : BRepLib_MakeFace
218 //=======================================================================
220 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Torus& T,
221 const Standard_Real UMin,
222 const Standard_Real UMax,
223 const Standard_Real VMin,
224 const Standard_Real VMax)
226 Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
227 Init(GT, UMin, UMax, VMin, VMax, Precision::Confusion());
231 //=======================================================================
232 //function : BRepLib_MakeFace
234 //=======================================================================
236 BRepLib_MakeFace::BRepLib_MakeFace(const Handle(Geom_Surface)& S,
237 const Standard_Real UMin,
238 const Standard_Real UMax,
239 const Standard_Real VMin,
240 const Standard_Real VMax,
241 const Standard_Real TolDegen)
243 Init(S, UMin, UMax, VMin, VMax, TolDegen);
247 //=======================================================================
248 //function : BRepLib_MakeFace
250 //=======================================================================
252 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Wire& W,
253 const Standard_Boolean OnlyPlane)
256 // Find a surface through the wire
257 BRepLib_FindSurface FS(W, -1, OnlyPlane, Standard_True);
259 myError = BRepLib_NotPlanar;
263 // build the face and add the wire
265 myError = BRepLib_FaceDone;
267 Standard_Real tol = Max(1.2*FS.ToleranceReached(), FS.Tolerance());
269 B.MakeFace(TopoDS::Face(myShape),FS.Surface(),FS.Location(),tol);
272 BRepLib::UpdateTolerances(myShape);
274 BRepLib::SameParameter(myShape, tol, Standard_True);
280 //=======================================================================
281 //function : BRepLib_MakeFace
283 //=======================================================================
285 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Pln& P,
286 const TopoDS_Wire& W,
287 const Standard_Boolean Inside)
289 Handle(Geom_Plane) Pl = new Geom_Plane(P);
290 Init(Pl, Standard_False, Precision::Confusion());
292 if (Inside) CheckInside();
296 //=======================================================================
297 //function : BRepLib_MakeFace
299 //=======================================================================
301 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cylinder& C,
302 const TopoDS_Wire& W,
303 const Standard_Boolean Inside)
305 Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
306 Init(GC, Standard_False, Precision::Confusion());
308 if (Inside) CheckInside();
312 //=======================================================================
313 //function : BRepLib_MakeFace
315 //=======================================================================
317 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cone& C,
318 const TopoDS_Wire& W,
319 const Standard_Boolean Inside)
321 Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
322 Init(GC, Standard_False, Precision::Confusion());
324 if (Inside) CheckInside();
328 //=======================================================================
329 //function : BRepLib_MakeFace
331 //=======================================================================
333 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Sphere& S,
334 const TopoDS_Wire& W,
335 const Standard_Boolean Inside)
337 Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
338 Init(GS, Standard_False, Precision::Confusion());
340 if (Inside) CheckInside();
344 //=======================================================================
345 //function : BRepLib_MakeFace
347 //=======================================================================
349 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Torus& T,
350 const TopoDS_Wire& W,
351 const Standard_Boolean Inside)
353 Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
354 Init(GT, Standard_False, Precision::Confusion());
356 if (Inside) CheckInside();
360 //=======================================================================
361 //function : BRepLib_MakeFace
363 //=======================================================================
365 BRepLib_MakeFace::BRepLib_MakeFace(const Handle(Geom_Surface)& S,
366 const TopoDS_Wire& W,
367 const Standard_Boolean Inside)
369 Init(S, Standard_False, Precision::Confusion());
371 if (Inside) CheckInside();
375 //=======================================================================
376 //function : BRepLib_MakeFace
378 //=======================================================================
380 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Face& F,
381 const TopoDS_Wire& W)
387 //=======================================================================
390 //=======================================================================
392 void BRepLib_MakeFace::Init(const TopoDS_Face& F)
395 myShape = F.EmptyCopied();
396 myError = BRepLib_FaceDone;
399 TopoDS_Iterator It(F);
401 B.Add(myShape,It.Value());
406 //=======================================================================
409 //=======================================================================
411 void BRepLib_MakeFace::Init(const Handle(Geom_Surface)& S,
412 const Standard_Boolean Bound,
413 const Standard_Real TolDegen)
415 myError = BRepLib_FaceDone;
417 Standard_Real UMin,UMax,VMin,VMax;
418 S->Bounds(UMin,UMax,VMin,VMax);
419 Init(S,UMin,UMax,VMin,VMax,TolDegen);
423 B.MakeFace(TopoDS::Face(myShape),S,Precision::Confusion());
426 B.NaturalRestriction(TopoDS::Face(myShape),Standard_True);
430 //=======================================================================
431 //function : IsDegenerated
432 //purpose : Checks whether the passed curve is degenerated with the
433 // passed tolerance value
434 //=======================================================================
436 static Standard_Boolean IsDegenerated(const Handle(Geom_Curve)& theCurve,
437 const Standard_Real theMaxTol,
438 Standard_Real& theActTol)
440 GeomAdaptor_Curve AC(theCurve);
441 Standard_Real aConfusion = Precision::Confusion();
442 theActTol = aConfusion;
443 GeomAbs_CurveType Type = AC.GetType();
445 if (Type == GeomAbs_Circle) {
446 gp_Circ Circ = AC.Circle();
447 if ( Circ.Radius() > theMaxTol )
448 return Standard_False;
449 theActTol = Max(Circ.Radius(), aConfusion);
450 return Standard_True;
452 else if (Type == GeomAbs_BSplineCurve) {
453 Handle(Geom_BSplineCurve) BS = AC.BSpline();
454 Standard_Integer NbPoles = BS->NbPoles();
455 Standard_Real aMaxPoleDist2 = 0.0, aMaxTol2 = theMaxTol*theMaxTol;
458 for (Standard_Integer i = 2; i <= NbPoles; i++) {
460 Standard_Real aPoleDist2 = P1.SquareDistance(P2);
461 if (aPoleDist2 > aMaxTol2)
462 return Standard_False;
463 if (aPoleDist2 > aMaxPoleDist2)
464 aMaxPoleDist2 = aPoleDist2;
466 theActTol = Max(1.000001*Sqrt(aMaxPoleDist2), aConfusion);
467 return Standard_True;
469 else if (Type == GeomAbs_BezierCurve) {
470 Handle(Geom_BezierCurve) BZ = AC.Bezier();
471 Standard_Integer NbPoles = BZ->NbPoles();
472 Standard_Real aMaxPoleDist2 = 0.0, aMaxTol2 = theMaxTol*theMaxTol;;
475 for (Standard_Integer i = 2; i <= NbPoles; i++) {
477 Standard_Real aPoleDist2 = P1.SquareDistance(P2);
478 if (aPoleDist2 > aMaxTol2)
479 return Standard_False;
480 if (aPoleDist2 > aMaxPoleDist2)
481 aMaxPoleDist2 = aPoleDist2;
483 theActTol = Max(1.000001*Sqrt(aMaxPoleDist2), aConfusion);
484 return Standard_True;
487 return Standard_False;
490 //=======================================================================
493 //=======================================================================
495 void BRepLib_MakeFace::Init(const Handle(Geom_Surface)& SS,
496 const Standard_Real Um,
497 const Standard_Real UM,
498 const Standard_Real Vm,
499 const Standard_Real VM,
500 const Standard_Real TolDegen)
502 myError = BRepLib_FaceDone;
504 Standard_Real UMin = Um;
505 Standard_Real UMax = UM;
506 Standard_Real VMin = Vm;
507 Standard_Real VMax = VM;
509 Standard_Real umin,umax,vmin,vmax,T;
511 Handle(Geom_Surface) S = SS, BS = SS;
512 Handle(Geom_RectangularTrimmedSurface) RS =
513 Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
515 BS = RS->BasisSurface();
517 Standard_Boolean OffsetSurface =
518 (BS->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface));
520 // adjust periodical surface or reordonate
521 // check if the values are in the natural range
522 Standard_Real epsilon = Precision::PConfusion();
524 BS->Bounds(umin,umax,vmin,vmax);
527 Handle(Geom_OffsetSurface) OS = Handle(Geom_OffsetSurface)::DownCast(BS);
528 Handle(Geom_Surface) Base = OS->BasisSurface();
530 if (Base->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
531 if (Precision::IsInfinite(umin) || Precision::IsInfinite(umax))
532 S = new Geom_RectangularTrimmedSurface(OS, UMin, UMax, VMin, VMax);
534 S = new Geom_RectangularTrimmedSurface(OS, VMin, VMax, Standard_False);
535 } else if (Base->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution)) {
536 if (Precision::IsInfinite(vmin) || Precision::IsInfinite(vmax))
537 S = new Geom_RectangularTrimmedSurface(OS, VMin, VMax, Standard_False);
541 if (S->IsUPeriodic()) {
542 ElCLib::AdjustPeriodic(umin,umax,epsilon,UMin,UMax);
544 else if (UMin > UMax) {
548 if ((umin - UMin > epsilon) || (UMax - umax > epsilon)) {
549 myError = BRepLib_ParametersOutOfRange;
554 if (S->IsVPeriodic()) {
555 ElCLib::AdjustPeriodic(vmin,vmax,epsilon,VMin,VMax);
557 else if (VMin > VMax) {
561 if ((vmin - VMin > epsilon) || (VMax - vmax > epsilon)) {
562 myError = BRepLib_ParametersOutOfRange;
568 // compute infinite flags
569 Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
570 Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
571 Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
572 Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
575 Standard_Boolean uclosed =
577 Abs(UMin - umin) < epsilon &&
578 Abs(UMax - umax) < epsilon;
580 Standard_Boolean vclosed =
582 Abs(VMin - vmin) < epsilon &&
583 Abs(VMax - vmax) < epsilon;
586 // compute 3d curves and degenerate flag
587 Standard_Real maxTol = TolDegen;
588 Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
589 Standard_Boolean Dumin,Dumax,Dvmin,Dvmax;
590 Dumin = Dumax = Dvmin = Dvmax = Standard_False;
591 Standard_Real uminTol, umaxTol, vminTol, vmaxTol;
594 Cumin = S->UIso(UMin);
595 Dumin = IsDegenerated(Cumin, maxTol, uminTol);
598 Cumax = S->UIso(UMax);
599 Dumax = IsDegenerated(Cumax, maxTol, umaxTol);
602 Cvmin = S->VIso(VMin);
603 Dvmin = IsDegenerated(Cvmin, maxTol, vminTol);
606 Cvmax = S->VIso(VMax);
607 Dvmax = IsDegenerated(Cvmax, maxTol, vmaxTol);
613 TopoDS_Vertex V00,V10,V11,V01;
616 if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin), Max(uminTol, vminTol));
617 if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax), Max(uminTol, vmaxTol));
620 if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin), Max(umaxTol, vminTol));
621 if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax), Max(umaxTol, vmaxTol));
634 if (Dumin) V00 = V01;
635 if (Dumax) V10 = V11;
636 if (Dvmin) V00 = V10;
637 if (Dvmax) V01 = V11;
640 Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
642 Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
644 Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
646 Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
648 Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
651 TopoDS_Face& F = TopoDS::Face(myShape);
652 B.MakeFace(F,S,Precision::Confusion());
655 TopoDS_Edge eumin,eumax,evmin,evmax;
659 B.MakeEdge(eumin,Cumin,uminTol);
663 B.UpdateEdge(eumin,Lumax,Lumin,F,Max(uminTol, umaxTol));
665 B.UpdateEdge(eumin,Lumin,F,uminTol);
666 B.Degenerated(eumin,Dumin);
668 V00.Orientation(TopAbs_FORWARD);
672 V01.Orientation(TopAbs_REVERSED);
675 B.Range(eumin,VMin,VMax);
683 B.MakeEdge(eumax,Cumax,umaxTol);
686 B.UpdateEdge(eumax,Lumax,F,umaxTol);
687 B.Degenerated(eumax,Dumax);
689 V10.Orientation(TopAbs_FORWARD);
693 V11.Orientation(TopAbs_REVERSED);
696 B.Range(eumax,VMin,VMax);
702 B.MakeEdge(evmin,Cvmin,vminTol);
706 B.UpdateEdge(evmin,Lvmin,Lvmax,F,Max(vminTol, vmaxTol));
708 B.UpdateEdge(evmin,Lvmin,F,vminTol);
709 B.Degenerated(evmin,Dvmin);
711 V00.Orientation(TopAbs_FORWARD);
715 V10.Orientation(TopAbs_REVERSED);
718 B.Range(evmin,UMin,UMax);
726 B.MakeEdge(evmax,Cvmax,vmaxTol);
729 B.UpdateEdge(evmax,Lvmax,F,vmaxTol);
730 B.Degenerated(evmax,Dvmax);
732 V01.Orientation(TopAbs_FORWARD);
736 V11.Orientation(TopAbs_REVERSED);
739 B.Range(evmax,UMin,UMax);
743 // make the wires and add them to the face
744 eumin.Orientation(TopAbs_REVERSED);
745 evmax.Orientation(TopAbs_REVERSED);
749 if (!umininf && !umaxinf && vmininf && vmaxinf) {
760 else if (umininf && umaxinf && !vmininf && !vmaxinf) {
771 else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
774 if (!umininf) B.Add(W,eumin);
775 if (!vmininf) B.Add(W,evmin);
776 if (!umaxinf) B.Add(W,eumax);
777 if (!vmaxinf) B.Add(W,evmax);
779 W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
780 F.Closed(uclosed && vclosed);
784 // Les Isos sont Approximees a Precision::Approximation()
785 // et on code Precision::Confusion() dans l'arete.
786 // ==> Un petit passage dans SamePrameter pour regler les tolerances.
787 BRepLib::SameParameter(F, Precision::Confusion(), Standard_True);
794 //=======================================================================
797 //=======================================================================
799 void BRepLib_MakeFace::Add(const TopoDS_Wire& W)
803 B.NaturalRestriction(TopoDS::Face(myShape),Standard_False);
808 //=======================================================================
811 //=======================================================================
813 const TopoDS_Face& BRepLib_MakeFace::Face()const
815 return TopoDS::Face(myShape);
820 //=======================================================================
821 //function : operator
823 //=======================================================================
825 BRepLib_MakeFace::operator TopoDS_Face() const
830 //=======================================================================
833 //=======================================================================
835 BRepLib_FaceError BRepLib_MakeFace::Error() const
841 //=======================================================================
842 //function : CheckInside
843 //purpose : Reverses the current face if not a bounded area
844 //=======================================================================
846 void BRepLib_MakeFace::CheckInside()
848 // compute the area and return the face if the area is negative
849 TopoDS_Face F = TopoDS::Face(myShape);
850 BRepTopAdaptor_FClass2d FClass(F,0.);
851 if ( FClass.PerformInfinitePoint() == TopAbs_IN) {
853 TopoDS_Shape S = myShape.EmptyCopied();
854 TopoDS_Iterator it(myShape);
856 B.Add(S,it.Value().Reversed());