8046062ce58455a0fbd3887a7769a03bbc96ed03
[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   if (BRep_Tool::IsClosed(W))
274     CheckInside();
275 }
276
277
278 //=======================================================================
279 //function : BRepLib_MakeFace
280 //purpose  : 
281 //=======================================================================
282
283 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Pln& P,
284                                    const TopoDS_Wire& W,
285                                    const Standard_Boolean Inside)
286 {
287   Handle(Geom_Plane) Pl = new Geom_Plane(P);
288   Init(Pl, Standard_False, Precision::Confusion());
289   Add(W);
290   if (Inside && BRep_Tool::IsClosed(W)) CheckInside();
291 }
292
293
294 //=======================================================================
295 //function : BRepLib_MakeFace
296 //purpose  : 
297 //=======================================================================
298
299 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cylinder& C,
300                                    const TopoDS_Wire& W,
301                                    const Standard_Boolean Inside)
302 {
303   Handle(Geom_CylindricalSurface) GC = new Geom_CylindricalSurface(C);
304   Init(GC, Standard_False, Precision::Confusion());
305   Add(W);
306   if (Inside && BRep_Tool::IsClosed(W)) CheckInside();
307 }
308
309
310 //=======================================================================
311 //function : BRepLib_MakeFace
312 //purpose  : 
313 //=======================================================================
314
315 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Cone& C,
316                                    const TopoDS_Wire& W,
317                                    const Standard_Boolean Inside)
318 {
319   Handle(Geom_ConicalSurface) GC = new Geom_ConicalSurface(C);
320   Init(GC, Standard_False, Precision::Confusion());
321   Add(W);
322   if (Inside && BRep_Tool::IsClosed(W)) CheckInside();
323 }
324
325
326 //=======================================================================
327 //function : BRepLib_MakeFace
328 //purpose  : 
329 //=======================================================================
330
331 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Sphere& S,
332                                    const TopoDS_Wire& W,
333                                    const Standard_Boolean Inside)
334 {
335   Handle(Geom_SphericalSurface) GS = new Geom_SphericalSurface(S);
336   Init(GS, Standard_False, Precision::Confusion());
337   Add(W);
338   if (Inside && BRep_Tool::IsClosed(W)) CheckInside();
339 }
340
341
342 //=======================================================================
343 //function : BRepLib_MakeFace
344 //purpose  : 
345 //=======================================================================
346
347 BRepLib_MakeFace::BRepLib_MakeFace(const gp_Torus& T,
348                                    const TopoDS_Wire& W,
349                                    const Standard_Boolean Inside)
350 {
351   Handle(Geom_ToroidalSurface) GT = new Geom_ToroidalSurface(T);
352   Init(GT, Standard_False, Precision::Confusion());
353   Add(W);
354   if (Inside && BRep_Tool::IsClosed(W)) CheckInside();
355 }
356
357
358 //=======================================================================
359 //function : BRepLib_MakeFace
360 //purpose  : 
361 //=======================================================================
362
363 BRepLib_MakeFace::BRepLib_MakeFace(const Handle(Geom_Surface)& S,
364                                    const TopoDS_Wire& W,
365                                    const Standard_Boolean Inside)
366 {
367   Init(S, Standard_False, Precision::Confusion());
368   Add(W);
369   if (Inside && BRep_Tool::IsClosed(W)) CheckInside();
370 }
371
372
373 //=======================================================================
374 //function : BRepLib_MakeFace
375 //purpose  : 
376 //=======================================================================
377
378 BRepLib_MakeFace::BRepLib_MakeFace(const TopoDS_Face& F,
379                                    const TopoDS_Wire& W)
380 {
381   Init(F);
382   Add(W);
383 }
384
385 //=======================================================================
386 //function : Init
387 //purpose  : 
388 //=======================================================================
389
390 void BRepLib_MakeFace::Init(const TopoDS_Face& F)
391 {
392   // copy the face
393   myShape = F.EmptyCopied();
394   myError = BRepLib_FaceDone;
395   
396   BRep_Builder B;
397   TopoDS_Iterator It(F);
398   while (It.More()) {
399     B.Add(myShape,It.Value());
400     It.Next();
401   }
402 }
403
404 //=======================================================================
405 //function : Init
406 //purpose  : 
407 //=======================================================================
408
409 void  BRepLib_MakeFace::Init(const Handle(Geom_Surface)& S,
410                              const Standard_Boolean Bound,
411                              const Standard_Real TolDegen)
412 {
413   myError = BRepLib_FaceDone;
414   if (Bound) {
415     Standard_Real UMin,UMax,VMin,VMax;
416     S->Bounds(UMin,UMax,VMin,VMax);
417     Init(S,UMin,UMax,VMin,VMax,TolDegen);
418   }
419   else {
420     BRep_Builder B;
421     B.MakeFace(TopoDS::Face(myShape),S,Precision::Confusion());
422   }
423   BRep_Builder B;
424   B.NaturalRestriction(TopoDS::Face(myShape),Standard_True);
425 }
426
427
428 //=======================================================================
429 //function : IsDegenerated
430 //purpose  : Checks whether the passed curve is degenerated with the
431 //           passed tolerance value
432 //=======================================================================
433
434 Standard_Boolean BRepLib_MakeFace::IsDegenerated(
435     const Handle(Geom_Curve)& theCurve,
436     const Standard_Real       theMaxTol,
437           Standard_Real&      theActTol)
438 {
439   GeomAdaptor_Curve AC(theCurve);
440   Standard_Real aConfusion = Precision::Confusion();
441   theActTol = aConfusion;
442   GeomAbs_CurveType Type = AC.GetType();
443
444   if (Type == GeomAbs_Circle) {
445     gp_Circ Circ = AC.Circle();
446     if ( Circ.Radius() > theMaxTol )
447       return Standard_False;
448     theActTol = Max(Circ.Radius(), aConfusion);
449     return Standard_True;
450   }
451   else if (Type == GeomAbs_BSplineCurve) {
452     Handle(Geom_BSplineCurve) BS = AC.BSpline();
453     Standard_Integer NbPoles = BS->NbPoles();
454     Standard_Real aMaxPoleDist2 = 0.0, aMaxTol2 = theMaxTol*theMaxTol;
455     gp_Pnt P1,P2;
456     P1 = BS->Pole(1);
457     for (Standard_Integer i = 2; i <= NbPoles; i++) {
458       P2 = BS->Pole(i);
459       Standard_Real aPoleDist2 = P1.SquareDistance(P2);
460       if (aPoleDist2 > aMaxTol2)
461         return Standard_False;
462       if (aPoleDist2 > aMaxPoleDist2)
463         aMaxPoleDist2 = aPoleDist2;
464     }
465     theActTol = Max(1.000001*Sqrt(aMaxPoleDist2), aConfusion);
466     return Standard_True;
467   }
468   else if (Type == GeomAbs_BezierCurve) {
469     Handle(Geom_BezierCurve) BZ = AC.Bezier();
470     Standard_Integer NbPoles = BZ->NbPoles();
471     Standard_Real aMaxPoleDist2 = 0.0, aMaxTol2 = theMaxTol*theMaxTol;;
472     gp_Pnt P1,P2;
473     P1 = BZ->Pole(1);
474     for (Standard_Integer i = 2; i <= NbPoles; i++) {
475       P2 = BZ->Pole(i);
476       Standard_Real aPoleDist2 = P1.SquareDistance(P2);
477       if (aPoleDist2 > aMaxTol2)
478         return Standard_False;
479       if (aPoleDist2 > aMaxPoleDist2)
480         aMaxPoleDist2 = aPoleDist2;
481     }
482     theActTol = Max(1.000001*Sqrt(aMaxPoleDist2), aConfusion);
483     return Standard_True;
484   }
485   
486   return Standard_False;
487 }
488
489 //=======================================================================
490 //function : Init
491 //purpose  : 
492 //=======================================================================
493
494 void  BRepLib_MakeFace::Init(const Handle(Geom_Surface)& SS,
495                              const Standard_Real Um,
496                              const Standard_Real UM,
497                              const Standard_Real Vm,
498                              const Standard_Real VM,
499                              const Standard_Real TolDegen)
500 {
501   myError = BRepLib_FaceDone;
502
503   Standard_Real UMin = Um;
504   Standard_Real UMax = UM;
505   Standard_Real VMin = Vm;
506   Standard_Real VMax = VM;
507
508   Standard_Real umin,umax,vmin,vmax,T;
509
510   Handle(Geom_Surface) S = SS, BS = SS;
511   Handle(Geom_RectangularTrimmedSurface) RS = 
512     Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
513   if (!RS.IsNull())
514     BS = RS->BasisSurface();
515
516   Standard_Boolean OffsetSurface = 
517     (BS->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface));
518      
519   // adjust periodical surface or reordonate
520   // check if the values are in the natural range
521   Standard_Real epsilon = Precision::PConfusion();
522   
523   BS->Bounds(umin,umax,vmin,vmax);
524
525   if (OffsetSurface) {
526     Handle(Geom_OffsetSurface) OS = Handle(Geom_OffsetSurface)::DownCast(BS);
527     Handle(Geom_Surface) Base = OS->BasisSurface();
528
529     if (Base->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
530       if (Precision::IsInfinite(umin) || Precision::IsInfinite(umax))
531         S = new Geom_RectangularTrimmedSurface(OS, UMin, UMax, VMin, VMax);
532       else
533         S = new Geom_RectangularTrimmedSurface(OS, VMin, VMax, Standard_False);
534     }  else if (Base->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution)) {
535       if (Precision::IsInfinite(vmin) || Precision::IsInfinite(vmax))
536         S = new Geom_RectangularTrimmedSurface(OS, VMin, VMax, Standard_False);
537     }
538   }
539
540   if (S->IsUPeriodic()) {
541     ElCLib::AdjustPeriodic(umin,umax,epsilon,UMin,UMax);
542   }
543   else if (UMin > UMax) {
544     T = UMin;
545     UMin = UMax;
546     UMax = T;
547     if ((umin - UMin > epsilon) || (UMax - umax > epsilon)) {
548       myError = BRepLib_ParametersOutOfRange;
549       return;
550     }
551   }
552
553   if (S->IsVPeriodic()) {
554     ElCLib::AdjustPeriodic(vmin,vmax,epsilon,VMin,VMax);
555   }
556   else if (VMin > VMax) {
557     T = VMin;
558     VMin = VMax;
559     VMax = T;
560     if ((vmin - VMin > epsilon) || (VMax - vmax > epsilon)) {
561       myError = BRepLib_ParametersOutOfRange;
562       return;
563     }
564   }
565   
566
567   // compute infinite flags
568   Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
569   Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
570   Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
571   Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
572   
573   // closed flag
574   Standard_Boolean uclosed = 
575     S->IsUClosed() && 
576       Abs(UMin - umin) < epsilon && 
577         Abs(UMax - umax) < epsilon;
578   
579   Standard_Boolean vclosed = 
580     S->IsVClosed() && 
581       Abs(VMin - vmin) < epsilon && 
582         Abs(VMax - vmax) < epsilon;
583   
584   
585   // compute 3d curves and degenerate flag
586   Standard_Real maxTol = TolDegen;
587   Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
588   Standard_Boolean Dumin,Dumax,Dvmin,Dvmax;
589   Dumin = Dumax = Dvmin = Dvmax = Standard_False;
590   Standard_Real uminTol = Precision::Confusion(), 
591                 umaxTol = Precision::Confusion(), 
592                 vminTol = Precision::Confusion(), 
593                 vmaxTol = Precision::Confusion();
594
595   if (!umininf) {
596     Cumin = S->UIso(UMin);
597     Dumin = IsDegenerated(Cumin, maxTol, uminTol);
598   }
599   if (!umaxinf) {
600     Cumax = S->UIso(UMax);
601     Dumax = IsDegenerated(Cumax, maxTol, umaxTol);
602   }
603   if (!vmininf) {
604     Cvmin = S->VIso(VMin);
605     Dvmin = IsDegenerated(Cvmin, maxTol, vminTol);
606   }
607   if (!vmaxinf) {
608     Cvmax = S->VIso(VMax);
609     Dvmax = IsDegenerated(Cvmax, maxTol, vmaxTol);
610   }
611
612   // compute vertices
613   BRep_Builder B;
614   
615   TopoDS_Vertex V00,V10,V11,V01;
616   
617   if (!umininf) {
618     if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin), Max(uminTol, vminTol));
619     if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax), Max(uminTol, vmaxTol));
620   }
621   if (!umaxinf) {
622     if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin), Max(umaxTol, vminTol));
623     if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax), Max(umaxTol, vmaxTol));
624   }
625
626   if (uclosed) {
627     V10 = V00;
628     V11 = V01;
629   }
630
631   if (vclosed) {
632     V01 = V00;
633     V11 = V10;
634   }
635
636   if (Dumin) V00 = V01;
637   if (Dumax) V10 = V11;
638   if (Dvmin) V00 = V10;
639   if (Dvmax) V01 = V11;
640
641   // make the lines
642   Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
643   if (!umininf)
644     Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
645   if (!umaxinf)
646     Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
647   if (!vmininf)
648     Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
649   if (!vmaxinf)
650     Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
651   
652   // make the face
653   TopoDS_Face& F = TopoDS::Face(myShape);
654   B.MakeFace(F,S,Precision::Confusion());
655
656   // make the edges
657   TopoDS_Edge eumin,eumax,evmin,evmax;
658
659   if (!umininf) {
660     if (!Dumin)
661       B.MakeEdge(eumin,Cumin,uminTol);
662     else
663       B.MakeEdge(eumin);
664     if (uclosed) 
665       B.UpdateEdge(eumin,Lumax,Lumin,F,Max(uminTol, umaxTol));
666     else
667       B.UpdateEdge(eumin,Lumin,F,uminTol);
668     B.Degenerated(eumin,Dumin);
669     if (!vmininf) {
670       V00.Orientation(TopAbs_FORWARD);
671       B.Add(eumin,V00);
672     }
673     if (!vmaxinf) {
674       V01.Orientation(TopAbs_REVERSED);
675       B.Add(eumin,V01);
676     }
677     B.Range(eumin,VMin,VMax);
678   }
679
680   if (!umaxinf) {
681     if (uclosed)
682       eumax = eumin;
683     else {
684       if (!Dumax)
685         B.MakeEdge(eumax,Cumax,umaxTol);
686       else
687         B.MakeEdge(eumax);
688       B.UpdateEdge(eumax,Lumax,F,umaxTol);
689       B.Degenerated(eumax,Dumax);
690       if (!vmininf) {
691         V10.Orientation(TopAbs_FORWARD);
692         B.Add(eumax,V10);
693       }
694       if (!vmaxinf) {
695         V11.Orientation(TopAbs_REVERSED);
696         B.Add(eumax,V11);
697       }
698       B.Range(eumax,VMin,VMax);
699     }
700   }
701
702   if (!vmininf) {
703     if (!Dvmin)
704       B.MakeEdge(evmin,Cvmin,vminTol);
705     else
706       B.MakeEdge(evmin);
707     if (vclosed)
708       B.UpdateEdge(evmin,Lvmin,Lvmax,F,Max(vminTol, vmaxTol));
709     else
710       B.UpdateEdge(evmin,Lvmin,F,vminTol);
711     B.Degenerated(evmin,Dvmin);
712     if (!umininf) {
713       V00.Orientation(TopAbs_FORWARD);
714       B.Add(evmin,V00);
715     }
716     if (!umaxinf) {
717       V10.Orientation(TopAbs_REVERSED);
718       B.Add(evmin,V10);
719     }
720     B.Range(evmin,UMin,UMax);
721   }
722
723   if (!vmaxinf) {
724     if (vclosed)
725       evmax = evmin;
726     else {
727       if (!Dvmax)
728         B.MakeEdge(evmax,Cvmax,vmaxTol);
729       else
730         B.MakeEdge(evmax);
731       B.UpdateEdge(evmax,Lvmax,F,vmaxTol);
732       B.Degenerated(evmax,Dvmax);
733       if (!umininf) {
734         V01.Orientation(TopAbs_FORWARD);
735         B.Add(evmax,V01);
736       }
737       if (!umaxinf) {
738         V11.Orientation(TopAbs_REVERSED);
739         B.Add(evmax,V11);
740       }
741       B.Range(evmax,UMin,UMax);
742     }
743   }
744
745   // make the wires and add them to the face
746   eumin.Orientation(TopAbs_REVERSED);
747   evmax.Orientation(TopAbs_REVERSED);
748   
749   TopoDS_Wire W;
750
751   if (!umininf && !umaxinf && vmininf && vmaxinf) {
752     // two wires in u
753     B.MakeWire(W);
754     B.Add(W,eumin);
755     B.Add(F,W);
756     B.MakeWire(W);
757     B.Add(W,eumax);
758     B.Add(F,W);
759     F.Closed(uclosed);
760   }
761     
762   else if (umininf && umaxinf && !vmininf && !vmaxinf) {
763     // two wires in v
764     B.MakeWire(W);
765     B.Add(W,evmin);
766     B.Add(F,W);
767     B.MakeWire(W);
768     B.Add(W,evmax);
769     B.Add(F,W);
770     F.Closed(vclosed);
771   }
772     
773   else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
774     // one wire
775     B.MakeWire(W);
776     if (!umininf) B.Add(W,eumin);
777     if (!vmininf) B.Add(W,evmin);
778     if (!umaxinf) B.Add(W,eumax);
779     if (!vmaxinf) B.Add(W,evmax);
780     B.Add(F,W);
781     W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
782     F.Closed(uclosed && vclosed);
783   }
784
785   if (OffsetSurface) { 
786     // Les Isos sont Approximees a Precision::Approximation()
787     // et on code Precision::Confusion() dans l'arete.
788     // ==> Un petit passage dans SamePrameter pour regler les tolerances.
789     BRepLib::SameParameter(F, Precision::Confusion(), Standard_True);
790   }
791
792   Done();
793 }
794
795
796 //=======================================================================
797 //function : Add
798 //purpose  : 
799 //=======================================================================
800
801 void  BRepLib_MakeFace::Add(const TopoDS_Wire& W)
802 {
803   BRep_Builder B;
804   B.Add(myShape,W);
805   B.NaturalRestriction(TopoDS::Face(myShape),Standard_False);
806   Done();
807 }
808
809
810 //=======================================================================
811 //function : Face
812 //purpose  : 
813 //=======================================================================
814
815 const TopoDS_Face&  BRepLib_MakeFace::Face()const 
816 {
817   return TopoDS::Face(myShape);
818 }
819
820
821
822 //=======================================================================
823 //function : operator
824 //purpose  : 
825 //=======================================================================
826
827 BRepLib_MakeFace::operator TopoDS_Face() const
828 {
829   return Face();
830 }
831
832 //=======================================================================
833 //function : Error
834 //purpose  : 
835 //=======================================================================
836
837 BRepLib_FaceError BRepLib_MakeFace::Error() const
838 {
839   return myError;
840 }
841
842
843 //=======================================================================
844 //function : CheckInside
845 //purpose  : Reverses the current face if not a bounded area
846 //=======================================================================
847
848 void BRepLib_MakeFace::CheckInside()
849 {
850   // compute the area and return the face if the area is negative
851   TopoDS_Face F = TopoDS::Face(myShape);
852   BRepTopAdaptor_FClass2d FClass(F,0.);
853   if ( FClass.PerformInfinitePoint() == TopAbs_IN) {
854     BRep_Builder B;
855     TopoDS_Shape S = myShape.EmptyCopied();
856     TopoDS_Iterator it(myShape);
857     while (it.More()) {
858       B.Add(S,it.Value().Reversed());
859       it.Next();
860     }
861     myShape = S;
862   }
863 }