1 // File: BRepLib_MakeFace.cxx
2 // Created: Fri Jul 23 15:51:48 1993
3 // Author: Remi LEQUETTE
7 #include <BRepLib_MakeFace.ixx>
9 #include <Geom_Plane.hxx>
10 #include <Geom_CylindricalSurface.hxx>
11 #include <Geom_ConicalSurface.hxx>
12 #include <Geom_SphericalSurface.hxx>
13 #include <Geom_ToroidalSurface.hxx>
14 #include <Geom_RectangularTrimmedSurface.hxx>
15 #include <Geom_OffsetSurface.hxx>
16 #include <Geom_BSplineCurve.hxx>
17 #include <Geom_BezierCurve.hxx>
18 #include <GeomAdaptor_Curve.hxx>
19 #include <GeomAbs_CurveType.hxx>
21 #include <Geom2d_Line.hxx>
23 #include <BRep_Builder.hxx>
26 #include <TopoDS_Vertex.hxx>
27 #include <TopoDS_Edge.hxx>
28 #include <TopoDS_Iterator.hxx>
30 #include <BRepTopAdaptor_FClass2d.hxx>
31 #include <TopAbs_State.hxx>
34 #include <Precision.hxx>
35 #include <BRepLib.hxx>
37 #include <BRepLib_FindSurface.hxx>
38 #include <Geom_SurfaceOfLinearExtrusion.hxx>
39 #include <Geom_SurfaceOfRevolution.hxx>
41 //=======================================================================
42 //function : BRepLib_MakeFace
44 //=======================================================================
46 BRepLib_MakeFace::BRepLib_MakeFace() :
47 myError(BRepLib_NoFace)
52 //=======================================================================
53 //function : BRepLib_MakeFace
55 //=======================================================================
57 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Face& F)
63 //=======================================================================
64 //function : BRepLib_MakeFace
66 //=======================================================================
68 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Pln& P)
70 Handle(Geom_Plane) GP = new Geom_Plane(P);
75 //=======================================================================
76 //function : BRepLib_MakeFace
78 //=======================================================================
80 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cylinder& C)
82 Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
87 //=======================================================================
88 //function : BRepLib_MakeFace
90 //=======================================================================
92 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cone& C)
94 Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
99 //=======================================================================
100 //function : BRepLib_MakeFace
102 //=======================================================================
104 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Sphere& S)
106 Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
111 //=======================================================================
112 //function : BRepLib_MakeFace
114 //=======================================================================
116 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Torus& T)
118 Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
123 //=======================================================================
124 //function : BRepLib_MakeFace
126 //=======================================================================
128 BRepLib_MakeFace::BRepLib_MakeFace(const Handle(Geom_Surface)& S)
134 //=======================================================================
135 //function : BRepLib_MakeFace
137 //=======================================================================
139 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Pln& P,
140 const Standard_Real UMin,
141 const Standard_Real UMax,
142 const Standard_Real VMin,
143 const Standard_Real VMax)
145 Handle(Geom_Plane) GP = new Geom_Plane(P);
146 Init(GP,UMin,UMax,VMin,VMax);
150 //=======================================================================
151 //function : BRepLib_MakeFace
153 //=======================================================================
155 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cylinder& C,
156 const Standard_Real UMin,
157 const Standard_Real UMax,
158 const Standard_Real VMin,
159 const Standard_Real VMax)
161 Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
162 Init(GC,UMin,UMax,VMin,VMax);
166 //=======================================================================
167 //function : BRepLib_MakeFace
169 //=======================================================================
171 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cone& C,
172 const Standard_Real UMin,
173 const Standard_Real UMax,
174 const Standard_Real VMin,
175 const Standard_Real VMax)
177 Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
178 Init(GC,UMin,UMax,VMin,VMax);
182 //=======================================================================
183 //function : BRepLib_MakeFace
185 //=======================================================================
187 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Sphere& S,
188 const Standard_Real UMin,
189 const Standard_Real UMax,
190 const Standard_Real VMin,
191 const Standard_Real VMax)
193 Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
194 Init(GS,UMin,UMax,VMin,VMax);
198 //=======================================================================
199 //function : BRepLib_MakeFace
201 //=======================================================================
203 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Torus& T,
204 const Standard_Real UMin,
205 const Standard_Real UMax,
206 const Standard_Real VMin,
207 const Standard_Real VMax)
209 Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
210 Init(GT,UMin,UMax,VMin,VMax);
214 //=======================================================================
215 //function : BRepLib_MakeFace
217 //=======================================================================
219 BRepLib_MakeFace::BRepLib_MakeFace(const Handle(Geom_Surface)& S,
220 const Standard_Real UMin,
221 const Standard_Real UMax,
222 const Standard_Real VMin,
223 const Standard_Real VMax)
225 Init(S,UMin,UMax,VMin,VMax);
229 //=======================================================================
230 //function : BRepLib_MakeFace
232 //=======================================================================
234 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Wire& W,
235 const Standard_Boolean OnlyPlane)
238 // Find a surface through the wire
239 BRepLib_FindSurface FS(W, -1, OnlyPlane);
241 myError = BRepLib_NotPlanar;
245 // build the face and add the wire
247 myError = BRepLib_FaceDone;
249 Standard_Real tol = Max(1.2*FS.ToleranceReached(), FS.Tolerance());
251 B.MakeFace(TopoDS::Face(myShape),FS.Surface(),FS.Location(),tol);
254 BRepLib::UpdateTolerances(myShape);
260 //=======================================================================
261 //function : BRepLib_MakeFace
263 //=======================================================================
265 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Pln& P,
266 const TopoDS_Wire& W,
267 const Standard_Boolean Inside)
269 Handle(Geom_Plane) Pl = new Geom_Plane(P);
270 Init(Pl,Standard_False);
272 if (Inside) CheckInside();
276 //=======================================================================
277 //function : BRepLib_MakeFace
279 //=======================================================================
281 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cylinder& C,
282 const TopoDS_Wire& W,
283 const Standard_Boolean Inside)
285 Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
286 Init(GC,Standard_False);
288 if (Inside) CheckInside();
292 //=======================================================================
293 //function : BRepLib_MakeFace
295 //=======================================================================
297 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cone& C,
298 const TopoDS_Wire& W,
299 const Standard_Boolean Inside)
301 Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
302 Init(GC,Standard_False);
304 if (Inside) CheckInside();
308 //=======================================================================
309 //function : BRepLib_MakeFace
311 //=======================================================================
313 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Sphere& S,
314 const TopoDS_Wire& W,
315 const Standard_Boolean Inside)
317 Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
318 Init(GS,Standard_False);
320 if (Inside) CheckInside();
324 //=======================================================================
325 //function : BRepLib_MakeFace
327 //=======================================================================
329 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Torus& T,
330 const TopoDS_Wire& W,
331 const Standard_Boolean Inside)
333 Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
334 Init(GT,Standard_False);
336 if (Inside) CheckInside();
340 //=======================================================================
341 //function : BRepLib_MakeFace
343 //=======================================================================
345 BRepLib_MakeFace::BRepLib_MakeFace(const Handle(Geom_Surface)& S,
346 const TopoDS_Wire& W,
347 const Standard_Boolean Inside)
349 Init(S,Standard_False);
351 if (Inside) CheckInside();
355 //=======================================================================
356 //function : BRepLib_MakeFace
358 //=======================================================================
360 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Face& F,
361 const TopoDS_Wire& W)
367 //=======================================================================
370 //=======================================================================
372 void BRepLib_MakeFace::Init(const TopoDS_Face& F)
375 myShape = F.EmptyCopied();
376 myError = BRepLib_FaceDone;
379 TopoDS_Iterator It(F);
381 B.Add(myShape,It.Value());
386 //=======================================================================
389 //=======================================================================
391 void BRepLib_MakeFace::Init(const Handle(Geom_Surface)& S,
392 const Standard_Boolean Bound)
394 myError = BRepLib_FaceDone;
396 Standard_Real UMin,UMax,VMin,VMax;
397 S->Bounds(UMin,UMax,VMin,VMax);
398 Init(S,UMin,UMax,VMin,VMax);
402 B.MakeFace(TopoDS::Face(myShape),S,Precision::Confusion());
405 B.NaturalRestriction(TopoDS::Face(myShape),Standard_True);
409 //=======================================================================
410 //function : IsDegenerated
411 //purpose : fonction statique qui verifie qu'une courbe n'est pas reduite
412 // a un point, pour ainsi coder l'edge Degenere.
413 //=======================================================================
415 static Standard_Boolean IsDegenerated(const Handle(Geom_Curve)& C,
416 const Standard_Real tol)
418 GeomAdaptor_Curve AC(C);
420 GeomAbs_CurveType Type = AC.GetType();
421 if (Type == GeomAbs_Circle) {
422 gp_Circ Circ = AC.Circle();
423 return (Circ.Radius() < tol);
425 else if (Type == GeomAbs_BSplineCurve) {
426 Handle(Geom_BSplineCurve) BS = AC.BSpline();
427 Standard_Integer NbPoles = BS->NbPoles();
428 Standard_Real tol2 = tol*tol;
431 for (Standard_Integer i = 2; i <= NbPoles; i++) {
433 if (P1.SquareDistance(P2) > tol2) return Standard_False;
436 return Standard_True;
438 else if (Type == GeomAbs_BezierCurve) {
439 Handle(Geom_BezierCurve) BZ = AC.Bezier();
440 Standard_Integer NbPoles = BZ->NbPoles();
441 Standard_Real tol2 = tol*tol;
444 for (Standard_Integer i = 2; i <= NbPoles; i++) {
446 if (P1.SquareDistance(P2) > tol2) return Standard_False;
449 return Standard_True;
452 return Standard_False;
455 //=======================================================================
458 //=======================================================================
460 void BRepLib_MakeFace::Init(const Handle(Geom_Surface)& SS,
461 const Standard_Real Um,
462 const Standard_Real UM,
463 const Standard_Real Vm,
464 const Standard_Real VM)
466 myError = BRepLib_FaceDone;
468 Standard_Real UMin = Um;
469 Standard_Real UMax = UM;
470 Standard_Real VMin = Vm;
471 Standard_Real VMax = VM;
473 Standard_Real umin,umax,vmin,vmax,T;
475 Handle(Geom_Surface) S = SS;
476 Handle(Geom_RectangularTrimmedSurface) RS =
477 Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
479 S = RS->BasisSurface();
482 Standard_Boolean OffsetSurface =
483 (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface));
485 // adjust periodical surface or reordonate
486 // check if the values are in the natural range
487 Standard_Real epsilon = Precision::PConfusion();
489 S->Bounds(umin,umax,vmin,vmax);
492 Handle(Geom_OffsetSurface) OS = Handle(Geom_OffsetSurface)::DownCast(S);
493 Handle(Geom_Surface) Base = OS->BasisSurface();
495 if (Base->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
496 if (Precision::IsInfinite(umin) || Precision::IsInfinite(umax))
497 S = new Geom_RectangularTrimmedSurface(OS, UMin, UMax, VMin, VMax);
499 S = new Geom_RectangularTrimmedSurface(OS, VMin, VMax, Standard_False);
500 } else if (Base->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution)) {
501 if (Precision::IsInfinite(vmin) || Precision::IsInfinite(vmax))
502 S = new Geom_RectangularTrimmedSurface(OS, VMin, VMax, Standard_False);
506 if (S->IsUPeriodic()) {
507 ElCLib::AdjustPeriodic(umin,umax,epsilon,UMin,UMax);
509 else if (UMin > UMax) {
513 if ((umin - UMin > epsilon) || (UMax - umax > epsilon)) {
514 myError = BRepLib_ParametersOutOfRange;
519 if (S->IsVPeriodic()) {
520 ElCLib::AdjustPeriodic(vmin,vmax,epsilon,VMin,VMax);
522 else if (VMin > VMax) {
526 if ((vmin - VMin > epsilon) || (VMax - vmax > epsilon)) {
527 myError = BRepLib_ParametersOutOfRange;
533 // compute infinite flags
534 Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
535 Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
536 Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
537 Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
540 Standard_Boolean uclosed =
542 Abs(UMin - umin) < epsilon &&
543 Abs(UMax - umax) < epsilon;
545 Standard_Boolean vclosed =
547 Abs(VMin - vmin) < epsilon &&
548 Abs(VMax - vmax) < epsilon;
551 // compute 3d curves and degenerate flag
552 Standard_Real tol = Precision::Confusion();
553 Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
554 Standard_Boolean Dumin,Dumax,Dvmin,Dvmax;
555 Dumin = Dumax = Dvmin = Dvmax = Standard_False;
558 Cumin = S->UIso(UMin);
559 Dumin = IsDegenerated(Cumin,tol);
562 Cumax = S->UIso(UMax);
563 Dumax = IsDegenerated(Cumax,tol);
566 Cvmin = S->VIso(VMin);
567 Dvmin = IsDegenerated(Cvmin,tol);
570 Cvmax = S->VIso(VMax);
571 Dvmax = IsDegenerated(Cvmax,tol);
577 TopoDS_Vertex V00,V10,V11,V01;
580 if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin),tol);
581 if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax),tol);
584 if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin),tol);
585 if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax),tol);
598 if (Dumin) V00 = V01;
599 if (Dumax) V10 = V11;
600 if (Dvmin) V00 = V10;
601 if (Dvmax) V01 = V11;
604 Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
606 Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
608 Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
610 Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
612 Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
615 TopoDS_Face& F = TopoDS::Face(myShape);
619 TopoDS_Edge eumin,eumax,evmin,evmax;
623 B.MakeEdge(eumin,Cumin,tol);
627 B.UpdateEdge(eumin,Lumax,Lumin,F,tol);
629 B.UpdateEdge(eumin,Lumin,F,tol);
630 B.Degenerated(eumin,Dumin);
632 V00.Orientation(TopAbs_FORWARD);
636 V01.Orientation(TopAbs_REVERSED);
639 B.Range(eumin,VMin,VMax);
647 B.MakeEdge(eumax,Cumax,tol);
650 B.UpdateEdge(eumax,Lumax,F,tol);
651 B.Degenerated(eumax,Dumax);
653 V10.Orientation(TopAbs_FORWARD);
657 V11.Orientation(TopAbs_REVERSED);
660 B.Range(eumax,VMin,VMax);
666 B.MakeEdge(evmin,Cvmin,tol);
670 B.UpdateEdge(evmin,Lvmin,Lvmax,F,tol);
672 B.UpdateEdge(evmin,Lvmin,F,tol);
673 B.Degenerated(evmin,Dvmin);
675 V00.Orientation(TopAbs_FORWARD);
679 V10.Orientation(TopAbs_REVERSED);
682 B.Range(evmin,UMin,UMax);
690 B.MakeEdge(evmax,Cvmax,tol);
693 B.UpdateEdge(evmax,Lvmax,F,tol);
694 B.Degenerated(evmax,Dvmax);
696 V01.Orientation(TopAbs_FORWARD);
700 V11.Orientation(TopAbs_REVERSED);
703 B.Range(evmax,UMin,UMax);
707 // make the wires and add them to the face
708 eumin.Orientation(TopAbs_REVERSED);
709 evmax.Orientation(TopAbs_REVERSED);
713 if (!umininf && !umaxinf && vmininf && vmaxinf) {
724 else if (umininf && umaxinf && !vmininf && !vmaxinf) {
735 else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
738 if (!umininf) B.Add(W,eumin);
739 if (!vmininf) B.Add(W,evmin);
740 if (!umaxinf) B.Add(W,eumax);
741 if (!vmaxinf) B.Add(W,evmax);
743 W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
744 F.Closed(uclosed && vclosed);
748 // Les Isos sont Approximees a Precision::Approximation()
749 // et on code Precision::Confusion() dans l'arete.
750 // ==> Un petit passage dans SamePrameter pour regler les tolerances.
751 BRepLib::SameParameter( F, tol, Standard_True);
758 //=======================================================================
761 //=======================================================================
763 void BRepLib_MakeFace::Add(const TopoDS_Wire& W)
767 B.NaturalRestriction(TopoDS::Face(myShape),Standard_False);
772 //=======================================================================
775 //=======================================================================
777 const TopoDS_Face& BRepLib_MakeFace::Face()const
779 return TopoDS::Face(myShape);
784 //=======================================================================
785 //function : operator
787 //=======================================================================
789 BRepLib_MakeFace::operator TopoDS_Face() const
794 //=======================================================================
797 //=======================================================================
799 BRepLib_FaceError BRepLib_MakeFace::Error() const
805 //=======================================================================
806 //function : CheckInside
807 //purpose : Reverses the current face if not a bounded area
808 //=======================================================================
810 void BRepLib_MakeFace::CheckInside()
812 // compute the area and return the face if the area is negative
813 TopoDS_Face F = TopoDS::Face(myShape);
814 BRepTopAdaptor_FClass2d FClass(F,0.);
815 if ( FClass.PerformInfinitePoint() == TopAbs_IN) {
817 TopoDS_Shape S = myShape.EmptyCopied();
818 TopoDS_Iterator it(myShape);
820 B.Add(S,it.Value().Reversed());