5299b44dab81fe656955648e0a2cccee85e9874e
[occt.git] / src / BRepLib / BRepLib_MakeFace.cxx
1 // File:        BRepLib_MakeFace.cxx
2 // Created:     Fri Jul 23 15:51:48 1993
3 // Author:      Remi LEQUETTE
4 //              <rle@nonox>
5
6
7 #include <BRepLib_MakeFace.ixx>
8
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>
20
21 #include <Geom2d_Line.hxx>
22
23 #include <BRep_Builder.hxx>
24
25 #include <TopoDS.hxx>
26 #include <TopoDS_Vertex.hxx>
27 #include <TopoDS_Edge.hxx>
28 #include <TopoDS_Iterator.hxx>
29
30 #include <BRepTopAdaptor_FClass2d.hxx>
31 #include <TopAbs_State.hxx>
32
33 #include <ElCLib.hxx>
34 #include <Precision.hxx>
35 #include <BRepLib.hxx>
36
37 #include <BRepLib_FindSurface.hxx>
38 #include <Geom_SurfaceOfLinearExtrusion.hxx>
39 #include <Geom_SurfaceOfRevolution.hxx>
40
41 //=======================================================================
42 //function : BRepLib_MakeFace
43 //purpose  : 
44 //=======================================================================
45
46 BRepLib_MakeFace::BRepLib_MakeFace() :
47        myError(BRepLib_NoFace)
48 {
49 }
50
51
52 //=======================================================================
53 //function : BRepLib_MakeFace
54 //purpose  : 
55 //=======================================================================
56
57 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Face& F)
58 {
59   Init(F);
60 }
61
62
63 //=======================================================================
64 //function : BRepLib_MakeFace
65 //purpose  : 
66 //=======================================================================
67
68 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Pln& P)
69 {
70   Handle(Geom_Plane) GP = new Geom_Plane(P);
71   Init(GP);
72 }
73
74
75 //=======================================================================
76 //function : BRepLib_MakeFace
77 //purpose  : 
78 //=======================================================================
79
80 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cylinder& C)
81 {
82   Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
83   Init(GC);
84 }
85
86
87 //=======================================================================
88 //function : BRepLib_MakeFace
89 //purpose  : 
90 //=======================================================================
91
92 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cone& C)
93 {
94   Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
95   Init(GC);
96 }
97
98
99 //=======================================================================
100 //function : BRepLib_MakeFace
101 //purpose  : 
102 //=======================================================================
103
104 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Sphere& S)
105 {
106   Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
107   Init(GS);
108 }
109
110
111 //=======================================================================
112 //function : BRepLib_MakeFace
113 //purpose  : 
114 //=======================================================================
115
116 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Torus& T)
117 {
118   Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
119   Init(GT);
120 }
121
122
123 //=======================================================================
124 //function : BRepLib_MakeFace
125 //purpose  : 
126 //=======================================================================
127
128 BRepLib_MakeFace::BRepLib_MakeFace(const Handle(Geom_Surface)& S)
129 {
130   Init(S);
131 }
132
133
134 //=======================================================================
135 //function : BRepLib_MakeFace
136 //purpose  : 
137 //=======================================================================
138
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)
144 {
145   Handle(Geom_Plane) GP = new Geom_Plane(P);
146   Init(GP,UMin,UMax,VMin,VMax);
147 }
148
149
150 //=======================================================================
151 //function : BRepLib_MakeFace
152 //purpose  : 
153 //=======================================================================
154
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)
160 {
161   Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
162   Init(GC,UMin,UMax,VMin,VMax);
163 }
164
165
166 //=======================================================================
167 //function : BRepLib_MakeFace
168 //purpose  : 
169 //=======================================================================
170
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)
176 {
177   Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
178   Init(GC,UMin,UMax,VMin,VMax);
179 }
180
181
182 //=======================================================================
183 //function : BRepLib_MakeFace
184 //purpose  : 
185 //=======================================================================
186
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)
192 {
193   Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
194   Init(GS,UMin,UMax,VMin,VMax);
195 }
196
197
198 //=======================================================================
199 //function : BRepLib_MakeFace
200 //purpose  : 
201 //=======================================================================
202
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)
208 {
209   Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
210   Init(GT,UMin,UMax,VMin,VMax);
211 }
212
213
214 //=======================================================================
215 //function : BRepLib_MakeFace
216 //purpose  : 
217 //=======================================================================
218
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)
224 {
225   Init(S,UMin,UMax,VMin,VMax);
226 }
227
228
229 //=======================================================================
230 //function : BRepLib_MakeFace
231 //purpose  : 
232 //=======================================================================
233
234 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Wire& W,
235                                    const Standard_Boolean OnlyPlane)
236
237 {
238   // Find a surface through the wire
239   BRepLib_FindSurface FS(W, -1, OnlyPlane);
240   if (!FS.Found()) {
241     myError = BRepLib_NotPlanar;
242     return;
243   }
244  
245   // build the face and add the wire
246   BRep_Builder B;
247   myError = BRepLib_FaceDone;
248
249   Standard_Real tol = Max(1.2*FS.ToleranceReached(), FS.Tolerance());
250
251   B.MakeFace(TopoDS::Face(myShape),FS.Surface(),FS.Location(),tol);
252   Add(W);
253
254   BRepLib::UpdateTolerances(myShape);
255
256   CheckInside();
257 }
258
259
260 //=======================================================================
261 //function : BRepLib_MakeFace
262 //purpose  : 
263 //=======================================================================
264
265 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Pln& P,
266                                    const TopoDS_Wire& W,
267                                    const Standard_Boolean Inside)
268 {
269   Handle(Geom_Plane) Pl = new Geom_Plane(P);
270   Init(Pl,Standard_False);
271   Add(W);
272   if (Inside) CheckInside();
273 }
274
275
276 //=======================================================================
277 //function : BRepLib_MakeFace
278 //purpose  : 
279 //=======================================================================
280
281 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cylinder& C,
282                                    const TopoDS_Wire& W,
283                                    const Standard_Boolean Inside)
284 {
285   Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
286   Init(GC,Standard_False);
287   Add(W);
288   if (Inside) CheckInside();
289 }
290
291
292 //=======================================================================
293 //function : BRepLib_MakeFace
294 //purpose  : 
295 //=======================================================================
296
297 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cone& C,
298                                    const TopoDS_Wire& W,
299                                    const Standard_Boolean Inside)
300 {
301   Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
302   Init(GC,Standard_False);
303   Add(W);
304   if (Inside) CheckInside();
305 }
306
307
308 //=======================================================================
309 //function : BRepLib_MakeFace
310 //purpose  : 
311 //=======================================================================
312
313 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Sphere& S,
314                                    const TopoDS_Wire& W,
315                                    const Standard_Boolean Inside)
316 {
317   Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
318   Init(GS,Standard_False);
319   Add(W);
320   if (Inside) CheckInside();
321 }
322
323
324 //=======================================================================
325 //function : BRepLib_MakeFace
326 //purpose  : 
327 //=======================================================================
328
329 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Torus& T,
330                                    const TopoDS_Wire& W,
331                                    const Standard_Boolean Inside)
332 {
333   Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
334   Init(GT,Standard_False);
335   Add(W);
336   if (Inside) CheckInside();
337 }
338
339
340 //=======================================================================
341 //function : BRepLib_MakeFace
342 //purpose  : 
343 //=======================================================================
344
345 BRepLib_MakeFace::BRepLib_MakeFace(const Handle(Geom_Surface)& S,
346                                    const TopoDS_Wire& W,
347                                    const Standard_Boolean Inside)
348 {
349   Init(S,Standard_False);
350   Add(W);
351   if (Inside) CheckInside();
352 }
353
354
355 //=======================================================================
356 //function : BRepLib_MakeFace
357 //purpose  : 
358 //=======================================================================
359
360 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Face& F,
361                                    const TopoDS_Wire& W)
362 {
363   Init(F);
364   Add(W);
365 }
366
367 //=======================================================================
368 //function : Init
369 //purpose  : 
370 //=======================================================================
371
372 void BRepLib_MakeFace::Init(const TopoDS_Face& F)
373 {
374   // copy the face
375   myShape = F.EmptyCopied();
376   myError = BRepLib_FaceDone;
377   
378   BRep_Builder B;
379   TopoDS_Iterator It(F);
380   while (It.More()) {
381     B.Add(myShape,It.Value());
382     It.Next();
383   }
384 }
385
386 //=======================================================================
387 //function : Init
388 //purpose  : 
389 //=======================================================================
390
391 void  BRepLib_MakeFace::Init(const Handle(Geom_Surface)& S,
392                              const Standard_Boolean Bound)
393 {
394   myError = BRepLib_FaceDone;
395   if (Bound) {
396     Standard_Real UMin,UMax,VMin,VMax;
397     S->Bounds(UMin,UMax,VMin,VMax);
398     Init(S,UMin,UMax,VMin,VMax);
399   }
400   else {
401     BRep_Builder B;
402     B.MakeFace(TopoDS::Face(myShape),S,Precision::Confusion());
403   }
404   BRep_Builder B;
405   B.NaturalRestriction(TopoDS::Face(myShape),Standard_True);
406 }
407
408
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 //=======================================================================
414
415 static Standard_Boolean IsDegenerated(const Handle(Geom_Curve)& C,
416                                       const Standard_Real       tol)
417 {
418   GeomAdaptor_Curve AC(C);
419   
420   GeomAbs_CurveType Type = AC.GetType();
421   if (Type == GeomAbs_Circle) {
422     gp_Circ Circ = AC.Circle();
423     return (Circ.Radius() < tol);
424   }
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;
429     gp_Pnt P1,P2;
430     P1 = BS->Pole(1);
431     for (Standard_Integer i = 2; i <= NbPoles; i++) {
432       P2 = BS->Pole(i);
433       if (P1.SquareDistance(P2) > tol2) return Standard_False;
434 //      P1 = P2;
435     }
436     return Standard_True;
437   }
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;
442     gp_Pnt P1,P2;
443     P1 = BZ->Pole(1);
444     for (Standard_Integer i = 2; i <= NbPoles; i++) {
445       P2 = BZ->Pole(i);
446       if (P1.SquareDistance(P2) > tol2) return Standard_False;
447 //      P1 = P2;
448     }
449     return Standard_True;
450   }
451   
452   return Standard_False;
453 }
454
455 //=======================================================================
456 //function : Init
457 //purpose  : 
458 //=======================================================================
459
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)
465 {
466   myError = BRepLib_FaceDone;
467
468   Standard_Real UMin = Um;
469   Standard_Real UMax = UM;
470   Standard_Real VMin = Vm;
471   Standard_Real VMax = VM;
472
473   Standard_Real umin,umax,vmin,vmax,T;
474
475   Handle(Geom_Surface) S = SS;
476   Handle(Geom_RectangularTrimmedSurface) RS = 
477     Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
478   if (!RS.IsNull())
479     S = RS->BasisSurface();
480   
481
482   Standard_Boolean OffsetSurface = 
483     (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface));
484
485   // adjust periodical surface or reordonate
486   // check if the values are in the natural range
487   Standard_Real epsilon = Precision::PConfusion();
488   
489   S->Bounds(umin,umax,vmin,vmax);
490
491   if (OffsetSurface) {
492     Handle(Geom_OffsetSurface) OS = Handle(Geom_OffsetSurface)::DownCast(S);
493     Handle(Geom_Surface) Base = OS->BasisSurface();
494
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);
498       else
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);
503     }
504   }
505
506   if (S->IsUPeriodic()) {
507     ElCLib::AdjustPeriodic(umin,umax,epsilon,UMin,UMax);
508   }
509   else if (UMin > UMax) {
510     T = UMin;
511     UMin = UMax;
512     UMax = T;
513     if ((umin - UMin > epsilon) || (UMax - umax > epsilon)) {
514       myError = BRepLib_ParametersOutOfRange;
515       return;
516     }
517   }
518
519   if (S->IsVPeriodic()) {
520     ElCLib::AdjustPeriodic(vmin,vmax,epsilon,VMin,VMax);
521   }
522   else if (VMin > VMax) {
523     T = VMin;
524     VMin = VMax;
525     VMax = T;
526     if ((vmin - VMin > epsilon) || (VMax - vmax > epsilon)) {
527       myError = BRepLib_ParametersOutOfRange;
528       return;
529     }
530   }
531   
532
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);
538   
539   // closed flag
540   Standard_Boolean uclosed = 
541     S->IsUClosed() && 
542       Abs(UMin - umin) < epsilon && 
543         Abs(UMax - umax) < epsilon;
544   
545   Standard_Boolean vclosed = 
546     S->IsVClosed() && 
547       Abs(VMin - vmin) < epsilon && 
548         Abs(VMax - vmax) < epsilon;
549   
550   
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;
556
557   if (!umininf) {
558     Cumin = S->UIso(UMin);
559     Dumin = IsDegenerated(Cumin,tol);
560   }
561   if (!umaxinf) {
562     Cumax = S->UIso(UMax);
563     Dumax = IsDegenerated(Cumax,tol);
564   }
565   if (!vmininf) {
566     Cvmin = S->VIso(VMin);
567     Dvmin = IsDegenerated(Cvmin,tol);
568   }
569   if (!vmaxinf) {
570     Cvmax = S->VIso(VMax);
571     Dvmax = IsDegenerated(Cvmax,tol);
572   }
573
574   // compute vertices
575   BRep_Builder B;
576   
577   TopoDS_Vertex V00,V10,V11,V01;
578   
579   if (!umininf) {
580     if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin),tol);
581     if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax),tol);
582   }
583   if (!umaxinf) {
584     if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin),tol);
585     if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax),tol);
586   }
587
588   if (uclosed) {
589     V10 = V00;
590     V11 = V01;
591   }
592
593   if (vclosed) {
594     V01 = V00;
595     V11 = V10;
596   }
597
598   if (Dumin) V00 = V01;
599   if (Dumax) V10 = V11;
600   if (Dvmin) V00 = V10;
601   if (Dvmax) V01 = V11;
602
603   // make the lines
604   Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
605   if (!umininf)
606     Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
607   if (!umaxinf)
608     Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
609   if (!vmininf)
610     Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
611   if (!vmaxinf)
612     Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
613   
614   // make the face
615   TopoDS_Face& F = TopoDS::Face(myShape);
616   B.MakeFace(F,S,tol);
617
618   // make the edges
619   TopoDS_Edge eumin,eumax,evmin,evmax;
620
621   if (!umininf) {
622     if (!Dumin)
623       B.MakeEdge(eumin,Cumin,tol);
624     else
625       B.MakeEdge(eumin);
626     if (uclosed) 
627       B.UpdateEdge(eumin,Lumax,Lumin,F,tol);
628     else
629       B.UpdateEdge(eumin,Lumin,F,tol);
630     B.Degenerated(eumin,Dumin);
631     if (!vmininf) {
632       V00.Orientation(TopAbs_FORWARD);
633       B.Add(eumin,V00);
634     }
635     if (!vmaxinf) {
636       V01.Orientation(TopAbs_REVERSED);
637       B.Add(eumin,V01);
638     }
639     B.Range(eumin,VMin,VMax);
640   }
641
642   if (!umaxinf) {
643     if (uclosed)
644       eumax = eumin;
645     else {
646       if (!Dumax)
647         B.MakeEdge(eumax,Cumax,tol);
648       else
649         B.MakeEdge(eumax);
650       B.UpdateEdge(eumax,Lumax,F,tol);
651       B.Degenerated(eumax,Dumax);
652       if (!vmininf) {
653         V10.Orientation(TopAbs_FORWARD);
654         B.Add(eumax,V10);
655       }
656       if (!vmaxinf) {
657         V11.Orientation(TopAbs_REVERSED);
658         B.Add(eumax,V11);
659       }
660       B.Range(eumax,VMin,VMax);
661     }
662   }
663
664   if (!vmininf) {
665     if (!Dvmin)
666       B.MakeEdge(evmin,Cvmin,tol);
667     else
668       B.MakeEdge(evmin);
669     if (vclosed)
670       B.UpdateEdge(evmin,Lvmin,Lvmax,F,tol);
671     else
672       B.UpdateEdge(evmin,Lvmin,F,tol);
673     B.Degenerated(evmin,Dvmin);
674     if (!umininf) {
675       V00.Orientation(TopAbs_FORWARD);
676       B.Add(evmin,V00);
677     }
678     if (!umaxinf) {
679       V10.Orientation(TopAbs_REVERSED);
680       B.Add(evmin,V10);
681     }
682     B.Range(evmin,UMin,UMax);
683   }
684
685   if (!vmaxinf) {
686     if (vclosed)
687       evmax = evmin;
688     else {
689       if (!Dvmax)
690         B.MakeEdge(evmax,Cvmax,tol);
691       else
692         B.MakeEdge(evmax);
693       B.UpdateEdge(evmax,Lvmax,F,tol);
694       B.Degenerated(evmax,Dvmax);
695       if (!umininf) {
696         V01.Orientation(TopAbs_FORWARD);
697         B.Add(evmax,V01);
698       }
699       if (!umaxinf) {
700         V11.Orientation(TopAbs_REVERSED);
701         B.Add(evmax,V11);
702       }
703       B.Range(evmax,UMin,UMax);
704     }
705   }
706
707   // make the wires and add them to the face
708   eumin.Orientation(TopAbs_REVERSED);
709   evmax.Orientation(TopAbs_REVERSED);
710   
711   TopoDS_Wire W;
712
713   if (!umininf && !umaxinf && vmininf && vmaxinf) {
714     // two wires in u
715     B.MakeWire(W);
716     B.Add(W,eumin);
717     B.Add(F,W);
718     B.MakeWire(W);
719     B.Add(W,eumax);
720     B.Add(F,W);
721     F.Closed(uclosed);
722   }
723     
724   else if (umininf && umaxinf && !vmininf && !vmaxinf) {
725     // two wires in v
726     B.MakeWire(W);
727     B.Add(W,evmin);
728     B.Add(F,W);
729     B.MakeWire(W);
730     B.Add(W,evmax);
731     B.Add(F,W);
732     F.Closed(vclosed);
733   }
734     
735   else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
736     // one wire
737     B.MakeWire(W);
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);
742     B.Add(F,W);
743     W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
744     F.Closed(uclosed && vclosed);
745   }
746
747   if (OffsetSurface) { 
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);
752   }
753
754   Done();
755 }
756
757
758 //=======================================================================
759 //function : Add
760 //purpose  : 
761 //=======================================================================
762
763 void  BRepLib_MakeFace::Add(const TopoDS_Wire& W)
764 {
765   BRep_Builder B;
766   B.Add(myShape,W);
767   B.NaturalRestriction(TopoDS::Face(myShape),Standard_False);
768   Done();
769 }
770
771
772 //=======================================================================
773 //function : Face
774 //purpose  : 
775 //=======================================================================
776
777 const TopoDS_Face&  BRepLib_MakeFace::Face()const 
778 {
779   return TopoDS::Face(myShape);
780 }
781
782
783
784 //=======================================================================
785 //function : operator
786 //purpose  : 
787 //=======================================================================
788
789 BRepLib_MakeFace::operator TopoDS_Face() const
790 {
791   return Face();
792 }
793
794 //=======================================================================
795 //function : Error
796 //purpose  : 
797 //=======================================================================
798
799 BRepLib_FaceError BRepLib_MakeFace::Error() const
800 {
801   return myError;
802 }
803
804
805 //=======================================================================
806 //function : CheckInside
807 //purpose  : Reverses the current face if not a bounded area
808 //=======================================================================
809
810 void BRepLib_MakeFace::CheckInside()
811 {
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) {
816     BRep_Builder B;
817     TopoDS_Shape S = myShape.EmptyCopied();
818     TopoDS_Iterator it(myShape);
819     while (it.More()) {
820       B.Add(S,it.Value().Reversed());
821       it.Next();
822     }
823     myShape = S;
824   }
825 }