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