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