0023957: Provide CMakeLists.txt file in root folder of OCCT
[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;
512   Handle(Geom_RectangularTrimmedSurface) RS = 
513     Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
514   if (!RS.IsNull())
515     S = RS->BasisSurface();
516   
517
518   Standard_Boolean OffsetSurface = 
519     (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface));
520
521   // adjust periodical surface or reordonate
522   // check if the values are in the natural range
523   Standard_Real epsilon = Precision::PConfusion();
524   
525   S->Bounds(umin,umax,vmin,vmax);
526
527   if (OffsetSurface) {
528     Handle(Geom_OffsetSurface) OS = Handle(Geom_OffsetSurface)::DownCast(S);
529     Handle(Geom_Surface) Base = OS->BasisSurface();
530
531     if (Base->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
532       if (Precision::IsInfinite(umin) || Precision::IsInfinite(umax))
533         S = new Geom_RectangularTrimmedSurface(OS, UMin, UMax, VMin, VMax);
534       else
535         S = new Geom_RectangularTrimmedSurface(OS, VMin, VMax, Standard_False);
536     }  else if (Base->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution)) {
537       if (Precision::IsInfinite(vmin) || Precision::IsInfinite(vmax))
538         S = new Geom_RectangularTrimmedSurface(OS, VMin, VMax, Standard_False);
539     }
540   }
541
542   if (S->IsUPeriodic()) {
543     ElCLib::AdjustPeriodic(umin,umax,epsilon,UMin,UMax);
544   }
545   else if (UMin > UMax) {
546     T = UMin;
547     UMin = UMax;
548     UMax = T;
549     if ((umin - UMin > epsilon) || (UMax - umax > epsilon)) {
550       myError = BRepLib_ParametersOutOfRange;
551       return;
552     }
553   }
554
555   if (S->IsVPeriodic()) {
556     ElCLib::AdjustPeriodic(vmin,vmax,epsilon,VMin,VMax);
557   }
558   else if (VMin > VMax) {
559     T = VMin;
560     VMin = VMax;
561     VMax = T;
562     if ((vmin - VMin > epsilon) || (VMax - vmax > epsilon)) {
563       myError = BRepLib_ParametersOutOfRange;
564       return;
565     }
566   }
567   
568
569   // compute infinite flags
570   Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
571   Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
572   Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
573   Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
574   
575   // closed flag
576   Standard_Boolean uclosed = 
577     S->IsUClosed() && 
578       Abs(UMin - umin) < epsilon && 
579         Abs(UMax - umax) < epsilon;
580   
581   Standard_Boolean vclosed = 
582     S->IsVClosed() && 
583       Abs(VMin - vmin) < epsilon && 
584         Abs(VMax - vmax) < epsilon;
585   
586   
587   // compute 3d curves and degenerate flag
588   Standard_Real maxTol = TolDegen;
589   Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
590   Standard_Boolean Dumin,Dumax,Dvmin,Dvmax;
591   Dumin = Dumax = Dvmin = Dvmax = Standard_False;
592   Standard_Real uminTol, umaxTol, vminTol, vmaxTol;
593
594   if (!umininf) {
595     Cumin = S->UIso(UMin);
596     Dumin = IsDegenerated(Cumin, maxTol, uminTol);
597   }
598   if (!umaxinf) {
599     Cumax = S->UIso(UMax);
600     Dumax = IsDegenerated(Cumax, maxTol, umaxTol);
601   }
602   if (!vmininf) {
603     Cvmin = S->VIso(VMin);
604     Dvmin = IsDegenerated(Cvmin, maxTol, vminTol);
605   }
606   if (!vmaxinf) {
607     Cvmax = S->VIso(VMax);
608     Dvmax = IsDegenerated(Cvmax, maxTol, vmaxTol);
609   }
610
611   // compute vertices
612   BRep_Builder B;
613   
614   TopoDS_Vertex V00,V10,V11,V01;
615   
616   if (!umininf) {
617     if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin), Max(uminTol, vminTol));
618     if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax), Max(uminTol, vmaxTol));
619   }
620   if (!umaxinf) {
621     if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin), Max(umaxTol, vminTol));
622     if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax), Max(umaxTol, vmaxTol));
623   }
624
625   if (uclosed) {
626     V10 = V00;
627     V11 = V01;
628   }
629
630   if (vclosed) {
631     V01 = V00;
632     V11 = V10;
633   }
634
635   if (Dumin) V00 = V01;
636   if (Dumax) V10 = V11;
637   if (Dvmin) V00 = V10;
638   if (Dvmax) V01 = V11;
639
640   // make the lines
641   Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
642   if (!umininf)
643     Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
644   if (!umaxinf)
645     Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
646   if (!vmininf)
647     Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
648   if (!vmaxinf)
649     Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
650   
651   // make the face
652   TopoDS_Face& F = TopoDS::Face(myShape);
653   B.MakeFace(F,S,Precision::Confusion());
654
655   // make the edges
656   TopoDS_Edge eumin,eumax,evmin,evmax;
657
658   if (!umininf) {
659     if (!Dumin)
660       B.MakeEdge(eumin,Cumin,uminTol);
661     else
662       B.MakeEdge(eumin);
663     if (uclosed) 
664       B.UpdateEdge(eumin,Lumax,Lumin,F,Max(uminTol, umaxTol));
665     else
666       B.UpdateEdge(eumin,Lumin,F,uminTol);
667     B.Degenerated(eumin,Dumin);
668     if (!vmininf) {
669       V00.Orientation(TopAbs_FORWARD);
670       B.Add(eumin,V00);
671     }
672     if (!vmaxinf) {
673       V01.Orientation(TopAbs_REVERSED);
674       B.Add(eumin,V01);
675     }
676     B.Range(eumin,VMin,VMax);
677   }
678
679   if (!umaxinf) {
680     if (uclosed)
681       eumax = eumin;
682     else {
683       if (!Dumax)
684         B.MakeEdge(eumax,Cumax,umaxTol);
685       else
686         B.MakeEdge(eumax);
687       B.UpdateEdge(eumax,Lumax,F,umaxTol);
688       B.Degenerated(eumax,Dumax);
689       if (!vmininf) {
690         V10.Orientation(TopAbs_FORWARD);
691         B.Add(eumax,V10);
692       }
693       if (!vmaxinf) {
694         V11.Orientation(TopAbs_REVERSED);
695         B.Add(eumax,V11);
696       }
697       B.Range(eumax,VMin,VMax);
698     }
699   }
700
701   if (!vmininf) {
702     if (!Dvmin)
703       B.MakeEdge(evmin,Cvmin,vminTol);
704     else
705       B.MakeEdge(evmin);
706     if (vclosed)
707       B.UpdateEdge(evmin,Lvmin,Lvmax,F,Max(vminTol, vmaxTol));
708     else
709       B.UpdateEdge(evmin,Lvmin,F,vminTol);
710     B.Degenerated(evmin,Dvmin);
711     if (!umininf) {
712       V00.Orientation(TopAbs_FORWARD);
713       B.Add(evmin,V00);
714     }
715     if (!umaxinf) {
716       V10.Orientation(TopAbs_REVERSED);
717       B.Add(evmin,V10);
718     }
719     B.Range(evmin,UMin,UMax);
720   }
721
722   if (!vmaxinf) {
723     if (vclosed)
724       evmax = evmin;
725     else {
726       if (!Dvmax)
727         B.MakeEdge(evmax,Cvmax,vmaxTol);
728       else
729         B.MakeEdge(evmax);
730       B.UpdateEdge(evmax,Lvmax,F,vmaxTol);
731       B.Degenerated(evmax,Dvmax);
732       if (!umininf) {
733         V01.Orientation(TopAbs_FORWARD);
734         B.Add(evmax,V01);
735       }
736       if (!umaxinf) {
737         V11.Orientation(TopAbs_REVERSED);
738         B.Add(evmax,V11);
739       }
740       B.Range(evmax,UMin,UMax);
741     }
742   }
743
744   // make the wires and add them to the face
745   eumin.Orientation(TopAbs_REVERSED);
746   evmax.Orientation(TopAbs_REVERSED);
747   
748   TopoDS_Wire W;
749
750   if (!umininf && !umaxinf && vmininf && vmaxinf) {
751     // two wires in u
752     B.MakeWire(W);
753     B.Add(W,eumin);
754     B.Add(F,W);
755     B.MakeWire(W);
756     B.Add(W,eumax);
757     B.Add(F,W);
758     F.Closed(uclosed);
759   }
760     
761   else if (umininf && umaxinf && !vmininf && !vmaxinf) {
762     // two wires in v
763     B.MakeWire(W);
764     B.Add(W,evmin);
765     B.Add(F,W);
766     B.MakeWire(W);
767     B.Add(W,evmax);
768     B.Add(F,W);
769     F.Closed(vclosed);
770   }
771     
772   else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
773     // one wire
774     B.MakeWire(W);
775     if (!umininf) B.Add(W,eumin);
776     if (!vmininf) B.Add(W,evmin);
777     if (!umaxinf) B.Add(W,eumax);
778     if (!vmaxinf) B.Add(W,evmax);
779     B.Add(F,W);
780     W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
781     F.Closed(uclosed && vclosed);
782   }
783
784   if (OffsetSurface) { 
785     // Les Isos sont Approximees a Precision::Approximation()
786     // et on code Precision::Confusion() dans l'arete.
787     // ==> Un petit passage dans SamePrameter pour regler les tolerances.
788     BRepLib::SameParameter(F, Precision::Confusion(), Standard_True);
789   }
790
791   Done();
792 }
793
794
795 //=======================================================================
796 //function : Add
797 //purpose  : 
798 //=======================================================================
799
800 void  BRepLib_MakeFace::Add(const TopoDS_Wire& W)
801 {
802   BRep_Builder B;
803   B.Add(myShape,W);
804   B.NaturalRestriction(TopoDS::Face(myShape),Standard_False);
805   Done();
806 }
807
808
809 //=======================================================================
810 //function : Face
811 //purpose  : 
812 //=======================================================================
813
814 const TopoDS_Face&  BRepLib_MakeFace::Face()const 
815 {
816   return TopoDS::Face(myShape);
817 }
818
819
820
821 //=======================================================================
822 //function : operator
823 //purpose  : 
824 //=======================================================================
825
826 BRepLib_MakeFace::operator TopoDS_Face() const
827 {
828   return Face();
829 }
830
831 //=======================================================================
832 //function : Error
833 //purpose  : 
834 //=======================================================================
835
836 BRepLib_FaceError BRepLib_MakeFace::Error() const
837 {
838   return myError;
839 }
840
841
842 //=======================================================================
843 //function : CheckInside
844 //purpose  : Reverses the current face if not a bounded area
845 //=======================================================================
846
847 void BRepLib_MakeFace::CheckInside()
848 {
849   // compute the area and return the face if the area is negative
850   TopoDS_Face F = TopoDS::Face(myShape);
851   BRepTopAdaptor_FClass2d FClass(F,0.);
852   if ( FClass.PerformInfinitePoint() == TopAbs_IN) {
853     BRep_Builder B;
854     TopoDS_Shape S = myShape.EmptyCopied();
855     TopoDS_Iterator it(myShape);
856     while (it.More()) {
857       B.Add(S,it.Value().Reversed());
858       it.Next();
859     }
860     myShape = S;
861   }
862 }