Warnings on vc14 were eliminated
[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 under
9 // the terms of the GNU Lesser General Public License 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
18 #include <BRep_Builder.hxx>
19 #include <BRepLib.hxx>
20 #include <BRepLib_FindSurface.hxx>
21 #include <BRepLib_MakeFace.hxx>
22 #include <BRepTopAdaptor_FClass2d.hxx>
23 #include <ElCLib.hxx>
24 #include <Geom2d_Line.hxx>
25 #include <Geom_BezierCurve.hxx>
26 #include <Geom_BSplineCurve.hxx>
27 #include <Geom_ConicalSurface.hxx>
28 #include <Geom_Curve.hxx>
29 #include <Geom_CylindricalSurface.hxx>
30 #include <Geom_OffsetSurface.hxx>
31 #include <Geom_Plane.hxx>
32 #include <Geom_RectangularTrimmedSurface.hxx>
33 #include <Geom_SphericalSurface.hxx>
34 #include <Geom_Surface.hxx>
35 #include <Geom_SurfaceOfLinearExtrusion.hxx>
36 #include <Geom_SurfaceOfRevolution.hxx>
37 #include <Geom_ToroidalSurface.hxx>
38 #include <GeomAbs_CurveType.hxx>
39 #include <GeomAdaptor_Curve.hxx>
40 #include <gp_Cone.hxx>
41 #include <gp_Cylinder.hxx>
42 #include <gp_Pln.hxx>
43 #include <gp_Sphere.hxx>
44 #include <gp_Torus.hxx>
45 #include <Precision.hxx>
46 #include <StdFail_NotDone.hxx>
47 #include <TopAbs_State.hxx>
48 #include <TopoDS.hxx>
49 #include <TopoDS_Edge.hxx>
50 #include <TopoDS_Face.hxx>
51 #include <TopoDS_Iterator.hxx>
52 #include <TopoDS_Vertex.hxx>
53 #include <TopoDS_Wire.hxx>
54
55 //=======================================================================
56 //function : BRepLib_MakeFace
57 //purpose  : 
58 //=======================================================================
59 BRepLib_MakeFace::BRepLib_MakeFace() :
60        myError(BRepLib_NoFace)
61 {
62 }
63
64
65 //=======================================================================
66 //function : BRepLib_MakeFace
67 //purpose  : 
68 //=======================================================================
69
70 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Face& F)
71 {
72   Init(F);
73 }
74
75
76 //=======================================================================
77 //function : BRepLib_MakeFace
78 //purpose  : 
79 //=======================================================================
80
81 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Pln& P)
82 {
83   Handle(Geom_Plane) GP = new Geom_Plane(P);
84   Init(GP, Standard_True, Precision::Confusion());
85 }
86
87
88 //=======================================================================
89 //function : BRepLib_MakeFace
90 //purpose  : 
91 //=======================================================================
92
93 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cylinder& C)
94 {
95   Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
96   Init(GC, Standard_True, Precision::Confusion());
97 }
98
99
100 //=======================================================================
101 //function : BRepLib_MakeFace
102 //purpose  : 
103 //=======================================================================
104
105 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cone& C)
106 {
107   Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
108   Init(GC, Standard_True, Precision::Confusion());
109 }
110
111
112 //=======================================================================
113 //function : BRepLib_MakeFace
114 //purpose  : 
115 //=======================================================================
116
117 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Sphere& S)
118 {
119   Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
120   Init(GS, Standard_True, Precision::Confusion());
121 }
122
123
124 //=======================================================================
125 //function : BRepLib_MakeFace
126 //purpose  : 
127 //=======================================================================
128
129 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Torus& T)
130 {
131   Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
132   Init(GT, Standard_True, Precision::Confusion());
133 }
134
135
136 //=======================================================================
137 //function : BRepLib_MakeFace
138 //purpose  : 
139 //=======================================================================
140
141 BRepLib_MakeFace::BRepLib_MakeFace(const Handle(Geom_Surface)& S,
142                                    const Standard_Real TolDegen)
143 {
144   Init(S, Standard_True, TolDegen);
145 }
146
147
148 //=======================================================================
149 //function : BRepLib_MakeFace
150 //purpose  : 
151 //=======================================================================
152
153 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Pln& P,
154                                    const Standard_Real UMin,
155                                    const Standard_Real UMax,
156                                    const Standard_Real VMin,
157                                    const Standard_Real VMax)
158 {
159   Handle(Geom_Plane) GP = new Geom_Plane(P);
160   Init(GP, UMin, UMax, VMin, VMax, Precision::Confusion());
161 }
162
163
164 //=======================================================================
165 //function : BRepLib_MakeFace
166 //purpose  : 
167 //=======================================================================
168
169 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cylinder& C,
170                                    const Standard_Real UMin,
171                                    const Standard_Real UMax,
172                                    const Standard_Real VMin,
173                                    const Standard_Real VMax)
174 {
175   Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
176   Init(GC, UMin, UMax, VMin, VMax, Precision::Confusion());
177 }
178
179
180 //=======================================================================
181 //function : BRepLib_MakeFace
182 //purpose  : 
183 //=======================================================================
184
185 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cone& C,
186                                    const Standard_Real UMin,
187                                    const Standard_Real UMax,
188                                    const Standard_Real VMin,
189                                    const Standard_Real VMax)
190 {
191   Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
192   Init(GC, UMin, UMax, VMin, VMax, Precision::Confusion());
193 }
194
195
196 //=======================================================================
197 //function : BRepLib_MakeFace
198 //purpose  : 
199 //=======================================================================
200
201 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Sphere& S,
202                                    const Standard_Real UMin,
203                                    const Standard_Real UMax,
204                                    const Standard_Real VMin,
205                                    const Standard_Real VMax)
206 {
207   Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
208   Init(GS, UMin, UMax, VMin, VMax, Precision::Confusion());
209 }
210
211
212 //=======================================================================
213 //function : BRepLib_MakeFace
214 //purpose  : 
215 //=======================================================================
216
217 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Torus& T,
218                                    const Standard_Real UMin,
219                                    const Standard_Real UMax,
220                                    const Standard_Real VMin,
221                                    const Standard_Real VMax)
222 {
223   Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
224   Init(GT, UMin, UMax, VMin, VMax, Precision::Confusion());
225 }
226
227
228 //=======================================================================
229 //function : BRepLib_MakeFace
230 //purpose  : 
231 //=======================================================================
232
233 BRepLib_MakeFace::BRepLib_MakeFace(const Handle(Geom_Surface)& S,
234                                    const Standard_Real UMin,
235                                    const Standard_Real UMax,
236                                    const Standard_Real VMin,
237                                    const Standard_Real VMax,
238                                    const Standard_Real TolDegen)
239 {
240   Init(S, UMin, UMax, VMin, VMax, TolDegen);
241 }
242
243
244 //=======================================================================
245 //function : BRepLib_MakeFace
246 //purpose  : 
247 //=======================================================================
248
249 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Wire& W,
250                                    const Standard_Boolean OnlyPlane)
251
252 {
253   // Find a surface through the wire
254   BRepLib_FindSurface FS(W, -1, OnlyPlane, Standard_True);
255   if (!FS.Found()) {
256     myError = BRepLib_NotPlanar;
257     return;
258   }
259  
260   // build the face and add the wire
261   BRep_Builder B;
262   myError = BRepLib_FaceDone;
263
264   Standard_Real tol = Max(1.2*FS.ToleranceReached(), FS.Tolerance());
265
266   B.MakeFace(TopoDS::Face(myShape),FS.Surface(),FS.Location(),tol);
267   Add(W);
268   //
269   BRepLib::UpdateTolerances(myShape);
270   //
271   BRepLib::SameParameter(myShape, tol, Standard_True);
272   //
273   CheckInside();
274 }
275
276
277 //=======================================================================
278 //function : BRepLib_MakeFace
279 //purpose  : 
280 //=======================================================================
281
282 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Pln& P,
283                                    const TopoDS_Wire& W,
284                                    const Standard_Boolean Inside)
285 {
286   Handle(Geom_Plane) Pl = new Geom_Plane(P);
287   Init(Pl, Standard_False, Precision::Confusion());
288   Add(W);
289   if (Inside) CheckInside();
290 }
291
292
293 //=======================================================================
294 //function : BRepLib_MakeFace
295 //purpose  : 
296 //=======================================================================
297
298 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cylinder& C,
299                                    const TopoDS_Wire& W,
300                                    const Standard_Boolean Inside)
301 {
302   Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
303   Init(GC, Standard_False, Precision::Confusion());
304   Add(W);
305   if (Inside) CheckInside();
306 }
307
308
309 //=======================================================================
310 //function : BRepLib_MakeFace
311 //purpose  : 
312 //=======================================================================
313
314 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cone& C,
315                                    const TopoDS_Wire& W,
316                                    const Standard_Boolean Inside)
317 {
318   Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
319   Init(GC, Standard_False, Precision::Confusion());
320   Add(W);
321   if (Inside) CheckInside();
322 }
323
324
325 //=======================================================================
326 //function : BRepLib_MakeFace
327 //purpose  : 
328 //=======================================================================
329
330 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Sphere& S,
331                                    const TopoDS_Wire& W,
332                                    const Standard_Boolean Inside)
333 {
334   Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
335   Init(GS, Standard_False, Precision::Confusion());
336   Add(W);
337   if (Inside) CheckInside();
338 }
339
340
341 //=======================================================================
342 //function : BRepLib_MakeFace
343 //purpose  : 
344 //=======================================================================
345
346 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Torus& T,
347                                    const TopoDS_Wire& W,
348                                    const Standard_Boolean Inside)
349 {
350   Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
351   Init(GT, Standard_False, Precision::Confusion());
352   Add(W);
353   if (Inside) CheckInside();
354 }
355
356
357 //=======================================================================
358 //function : BRepLib_MakeFace
359 //purpose  : 
360 //=======================================================================
361
362 BRepLib_MakeFace::BRepLib_MakeFace(const Handle(Geom_Surface)& S,
363                                    const TopoDS_Wire& W,
364                                    const Standard_Boolean Inside)
365 {
366   Init(S, Standard_False, Precision::Confusion());
367   Add(W);
368   if (Inside) CheckInside();
369 }
370
371
372 //=======================================================================
373 //function : BRepLib_MakeFace
374 //purpose  : 
375 //=======================================================================
376
377 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Face& F,
378                                    const TopoDS_Wire& W)
379 {
380   Init(F);
381   Add(W);
382 }
383
384 //=======================================================================
385 //function : Init
386 //purpose  : 
387 //=======================================================================
388
389 void BRepLib_MakeFace::Init(const TopoDS_Face& F)
390 {
391   // copy the face
392   myShape = F.EmptyCopied();
393   myError = BRepLib_FaceDone;
394   
395   BRep_Builder B;
396   TopoDS_Iterator It(F);
397   while (It.More()) {
398     B.Add(myShape,It.Value());
399     It.Next();
400   }
401 }
402
403 //=======================================================================
404 //function : Init
405 //purpose  : 
406 //=======================================================================
407
408 void  BRepLib_MakeFace::Init(const Handle(Geom_Surface)& S,
409                              const Standard_Boolean Bound,
410                              const Standard_Real TolDegen)
411 {
412   myError = BRepLib_FaceDone;
413   if (Bound) {
414     Standard_Real UMin,UMax,VMin,VMax;
415     S->Bounds(UMin,UMax,VMin,VMax);
416     Init(S,UMin,UMax,VMin,VMax,TolDegen);
417   }
418   else {
419     BRep_Builder B;
420     B.MakeFace(TopoDS::Face(myShape),S,Precision::Confusion());
421   }
422   BRep_Builder B;
423   B.NaturalRestriction(TopoDS::Face(myShape),Standard_True);
424 }
425
426
427 //=======================================================================
428 //function : IsDegenerated
429 //purpose  : Checks whether the passed curve is degenerated with the
430 //           passed tolerance value
431 //=======================================================================
432
433 Standard_Boolean BRepLib_MakeFace::IsDegenerated(
434     const Handle(Geom_Curve)& theCurve,
435     const Standard_Real       theMaxTol,
436           Standard_Real&      theActTol)
437 {
438   GeomAdaptor_Curve AC(theCurve);
439   Standard_Real aConfusion = Precision::Confusion();
440   theActTol = aConfusion;
441   GeomAbs_CurveType Type = AC.GetType();
442
443   if (Type == GeomAbs_Circle) {
444     gp_Circ Circ = AC.Circle();
445     if ( Circ.Radius() > theMaxTol )
446       return Standard_False;
447     theActTol = Max(Circ.Radius(), aConfusion);
448     return Standard_True;
449   }
450   else if (Type == GeomAbs_BSplineCurve) {
451     Handle(Geom_BSplineCurve) BS = AC.BSpline();
452     Standard_Integer NbPoles = BS->NbPoles();
453     Standard_Real aMaxPoleDist2 = 0.0, aMaxTol2 = theMaxTol*theMaxTol;
454     gp_Pnt P1,P2;
455     P1 = BS->Pole(1);
456     for (Standard_Integer i = 2; i <= NbPoles; i++) {
457       P2 = BS->Pole(i);
458       Standard_Real aPoleDist2 = P1.SquareDistance(P2);
459       if (aPoleDist2 > aMaxTol2)
460         return Standard_False;
461       if (aPoleDist2 > aMaxPoleDist2)
462         aMaxPoleDist2 = aPoleDist2;
463     }
464     theActTol = Max(1.000001*Sqrt(aMaxPoleDist2), aConfusion);
465     return Standard_True;
466   }
467   else if (Type == GeomAbs_BezierCurve) {
468     Handle(Geom_BezierCurve) BZ = AC.Bezier();
469     Standard_Integer NbPoles = BZ->NbPoles();
470     Standard_Real aMaxPoleDist2 = 0.0, aMaxTol2 = theMaxTol*theMaxTol;;
471     gp_Pnt P1,P2;
472     P1 = BZ->Pole(1);
473     for (Standard_Integer i = 2; i <= NbPoles; i++) {
474       P2 = BZ->Pole(i);
475       Standard_Real aPoleDist2 = P1.SquareDistance(P2);
476       if (aPoleDist2 > aMaxTol2)
477         return Standard_False;
478       if (aPoleDist2 > aMaxPoleDist2)
479         aMaxPoleDist2 = aPoleDist2;
480     }
481     theActTol = Max(1.000001*Sqrt(aMaxPoleDist2), aConfusion);
482     return Standard_True;
483   }
484   
485   return Standard_False;
486 }
487
488 //=======================================================================
489 //function : Init
490 //purpose  : 
491 //=======================================================================
492
493 void  BRepLib_MakeFace::Init(const Handle(Geom_Surface)& SS,
494                              const Standard_Real Um,
495                              const Standard_Real UM,
496                              const Standard_Real Vm,
497                              const Standard_Real VM,
498                              const Standard_Real TolDegen)
499 {
500   myError = BRepLib_FaceDone;
501
502   Standard_Real UMin = Um;
503   Standard_Real UMax = UM;
504   Standard_Real VMin = Vm;
505   Standard_Real VMax = VM;
506
507   Standard_Real umin,umax,vmin,vmax,T;
508
509   Handle(Geom_Surface) S = SS, BS = SS;
510   Handle(Geom_RectangularTrimmedSurface) RS = 
511     Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
512   if (!RS.IsNull())
513     BS = RS->BasisSurface();
514
515   Standard_Boolean OffsetSurface = 
516     (BS->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface));
517      
518   // adjust periodical surface or reordonate
519   // check if the values are in the natural range
520   Standard_Real epsilon = Precision::PConfusion();
521   
522   BS->Bounds(umin,umax,vmin,vmax);
523
524   if (OffsetSurface) {
525     Handle(Geom_OffsetSurface) OS = Handle(Geom_OffsetSurface)::DownCast(BS);
526     Handle(Geom_Surface) Base = OS->BasisSurface();
527
528     if (Base->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
529       if (Precision::IsInfinite(umin) || Precision::IsInfinite(umax))
530         S = new Geom_RectangularTrimmedSurface(OS, UMin, UMax, VMin, VMax);
531       else
532         S = new Geom_RectangularTrimmedSurface(OS, VMin, VMax, Standard_False);
533     }  else if (Base->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution)) {
534       if (Precision::IsInfinite(vmin) || Precision::IsInfinite(vmax))
535         S = new Geom_RectangularTrimmedSurface(OS, VMin, VMax, Standard_False);
536     }
537   }
538
539   if (S->IsUPeriodic()) {
540     ElCLib::AdjustPeriodic(umin,umax,epsilon,UMin,UMax);
541   }
542   else if (UMin > UMax) {
543     T = UMin;
544     UMin = UMax;
545     UMax = T;
546     if ((umin - UMin > epsilon) || (UMax - umax > epsilon)) {
547       myError = BRepLib_ParametersOutOfRange;
548       return;
549     }
550   }
551
552   if (S->IsVPeriodic()) {
553     ElCLib::AdjustPeriodic(vmin,vmax,epsilon,VMin,VMax);
554   }
555   else if (VMin > VMax) {
556     T = VMin;
557     VMin = VMax;
558     VMax = T;
559     if ((vmin - VMin > epsilon) || (VMax - vmax > epsilon)) {
560       myError = BRepLib_ParametersOutOfRange;
561       return;
562     }
563   }
564   
565
566   // compute infinite flags
567   Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
568   Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
569   Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
570   Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
571   
572   // closed flag
573   Standard_Boolean uclosed = 
574     S->IsUClosed() && 
575       Abs(UMin - umin) < epsilon && 
576         Abs(UMax - umax) < epsilon;
577   
578   Standard_Boolean vclosed = 
579     S->IsVClosed() && 
580       Abs(VMin - vmin) < epsilon && 
581         Abs(VMax - vmax) < epsilon;
582   
583   
584   // compute 3d curves and degenerate flag
585   Standard_Real maxTol = TolDegen;
586   Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
587   Standard_Boolean Dumin,Dumax,Dvmin,Dvmax;
588   Dumin = Dumax = Dvmin = Dvmax = Standard_False;
589   Standard_Real uminTol = Precision::Confusion(), 
590                 umaxTol = Precision::Confusion(), 
591                 vminTol = Precision::Confusion(), 
592                 vmaxTol = Precision::Confusion();
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 }