0024023: Revamp the OCCT Handle -- ambiguity
[occt.git] / src / BRepFill / BRepFill_Sweep.cxx
1 // Created on: 1998-01-07
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1998-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 #include <stdio.h>
18
19 #include <BRepFill_Sweep.ixx>
20
21 #include <BRepFill_SectionLaw.hxx>
22 //#include <BRepFill_TrimCorner.hxx>
23 #include <BRepFill_CurveConstraint.hxx>
24
25 #include <GeomFill_SectionLaw.hxx>
26 #include <GeomFill_LocationLaw.hxx>
27 #include <GeomFill_Sweep.hxx>
28
29 // modified by NIZHNY-MKK  Wed Oct 22 12:25:45 2003
30 #include <BRepFill_TrimShellCorner.hxx>
31
32 //#include <GeomPlate_BuildPlateSurface.hxx>
33 //#include <GeomPlate_Surface.hxx>
34 //#include <GeomPlate_PointConstraint.hxx>
35
36 #include <gp_Pnt2d.hxx>
37 #include <gp_Vec2d.hxx>
38 #include <Bnd_Box.hxx>
39
40 #include <Geom_Surface.hxx>
41 #include <Geom_SurfaceOfRevolution.hxx>
42 #include <Geom_RectangularTrimmedSurface.hxx>
43 #include <Geom_Plane.hxx>
44 #include <Geom_Curve.hxx>
45 #include <Geom_BezierCurve.hxx>
46 #include <Geom_BSplineCurve.hxx>
47 #include <Geom2d_Line.hxx>
48 #include <Geom2d_BSplineCurve.hxx>
49 #include <Geom2d_TrimmedCurve.hxx>
50 #include <GeomLib.hxx>
51 #include <GeomLib_IsPlanarSurface.hxx>
52 #include <BRepLib_FindSurface.hxx>
53 #include <GeomConvert_ApproxSurface.hxx>
54
55 #include <BRepAdaptor_HCurve.hxx>
56 #include <BRepAdaptor_HCurve2d.hxx>
57 #include <BRepAdaptor_HSurface.hxx>
58 #include <Adaptor3d_HCurveOnSurface.hxx>
59 #include <GeomAdaptor_HSurface.hxx>
60 #include <GeomAdaptor_HCurve.hxx>
61 #include <Geom2dAdaptor_HCurve.hxx>
62 #include <Approx_CurveOnSurface.hxx>
63 #include <Approx_SameParameter.hxx>
64 #include <GCPnts_AbscissaPoint.hxx>
65
66 #include <BRep_Builder.hxx>
67 #include <BRep_Tool.hxx>
68 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
69 #include <BRep_TEdge.hxx>
70 #include <BRep_TVertex.hxx>
71 #include <BRep_CurveRepresentation.hxx>
72 #include <BRep_GCurve.hxx>
73
74 #include <BRepLib.hxx>
75 #include <BRepLib_MakeEdge.hxx>
76 #include <BRepLib_MakeFace.hxx>
77 #include <BRepLib_FaceError.hxx>
78
79 #include <TopoDS.hxx>
80 #include <TopoDS_Edge.hxx>
81 #include <TopoDS_Face.hxx>
82 #include <TopoDS_Compound.hxx>
83 #include <TopoDS_Shell.hxx>
84 #include <TopExp.hxx>
85 #include <TopExp_Explorer.hxx>
86 #include <TopAbs_Orientation.hxx>
87
88 #include <TColStd_HArray1OfInteger.hxx>
89 #include <TColStd_Array2OfInteger.hxx>
90 #include <TColStd_Array1OfReal.hxx>
91 #include <TColStd_Array2OfReal.hxx>
92 #include <TColGeom_Array2OfSurface.hxx>
93 #include <TColgp_Array1OfPnt.hxx>
94 #include <TColStd_Array1OfBoolean.hxx>
95
96 #include <TopTools_Array1OfShape.hxx>
97 #include <TopTools_Array2OfShape.hxx>
98 #include <TopTools_HArray2OfShape.hxx>
99 #include <TopTools_HArray1OfShape.hxx>
100 #include <TopTools_ListIteratorOfListOfShape.hxx> 
101 #include <TopTools_ListOfShape.hxx> 
102 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
103 #include <TopTools_SequenceOfShape.hxx> 
104 #include <BRepTools_WireExplorer.hxx>
105
106 #include <Standard_ConstructionError.hxx>
107 #include <Precision.hxx>
108 #include <BRepBuilderAPI_MakeWire.hxx>
109
110 #include <BRepTools_Substitution.hxx>
111 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
112 #include <TopoDS_Iterator.hxx>
113
114 //OCC500(apo)
115 #include <BRepCheck_Edge.hxx>  
116
117 #ifdef DRAW
118 #include <Draw.hxx>
119 #include <DrawTrSurf.hxx>
120 #include <DBRep.hxx>
121 #include <Geom_BoundedSurface.hxx>
122 static Standard_Boolean Affich = 0;
123 #endif
124
125 //=======================================================================
126 //function : NumberOfPoles
127 //purpose  : 
128 //=======================================================================
129 static Standard_Integer NumberOfPoles(const TopoDS_Wire& W)
130 {
131   Standard_Integer NbPoints = 0;
132
133   TopoDS_Iterator iter(W);
134   for (; iter.More(); iter.Next()) 
135   {
136     BRepAdaptor_Curve c(TopoDS::Edge(iter.Value()));
137
138     Standard_Real dfUf = c.FirstParameter();
139     Standard_Real dfUl = c.LastParameter();
140     if (IsEqual(dfUf,dfUl))
141       // Degenerate
142       continue;
143
144     switch (c.GetType()) 
145     {
146     case GeomAbs_BezierCurve:
147       {
148         // Put all poles for bezier
149         Handle(Geom_BezierCurve) GC = c.Bezier();
150         Standard_Integer iNbPol = GC->NbPoles();
151         if ( iNbPol >= 2)
152           NbPoints += iNbPol;
153         break;
154       }
155     case GeomAbs_BSplineCurve:
156       {
157         // Put all poles for bspline
158         Handle(Geom_BSplineCurve) GC = c.BSpline();
159         Standard_Integer iNbPol = GC->NbPoles();
160         if ( iNbPol >= 2)
161           NbPoints += iNbPol;
162         break;
163       }
164     case GeomAbs_Line:
165       {
166         NbPoints += 2;
167         break;
168       }
169     case GeomAbs_Circle:
170     case GeomAbs_Ellipse:
171     case GeomAbs_Hyperbola:
172     case GeomAbs_Parabola:
173       {
174         NbPoints += 4;
175         break;
176       }
177     default:
178       NbPoints += 15 + c.NbIntervals(GeomAbs_C3);
179     } // switch (c.GetType()) ...
180   } // for (; iter.More(); iter.Next())
181
182   return NbPoints;
183 }
184
185 //=======================================================================
186 //function : HasPCurves
187 //purpose  : 
188 //=======================================================================
189 static Standard_Boolean HasPCurves(const TopoDS_Edge& E)
190 {
191   Standard_Boolean haspcurves = Standard_False;
192
193   BRep_ListIteratorOfListOfCurveRepresentation itcr
194     ((*((Handle(BRep_TEdge)*)&E.TShape()))->Curves());
195   for (; itcr.More(); itcr.Next())
196     {
197       const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
198       if (cr->IsCurveOnSurface())
199         {
200           haspcurves = Standard_True;
201           break;
202         }
203     }
204   return haspcurves;
205 }
206
207 //=======================================================================
208 //function : Translate
209 //purpose  : Copy a column from one table to another. 
210 //=======================================================================
211 static void Translate(const Handle(TopTools_HArray2OfShape)& ArrayIn,
212                       const Standard_Integer In,
213                       Handle(TopTools_HArray2OfShape)& ArrayOut,
214                       const Standard_Integer Out)
215 {
216   Standard_Integer ii, Nb;
217   Nb =  ArrayOut->ColLength();
218   for (ii=1; ii<=Nb; ii++) {
219      ArrayOut->SetValue(ii, Out,  ArrayIn->Value(ii, In));
220   } 
221 }
222
223
224 //=======================================================================
225 //function : Box
226 //purpose  : Bounding box of a section.
227 //=======================================================================
228 static void Box(Handle(GeomFill_SectionLaw)& Sec,
229                 const Standard_Real U,
230                 Bnd_Box& Box)
231
232 {
233   Standard_Integer NbPoles, bid;
234   Box.SetVoid();
235   Sec->SectionShape(NbPoles, bid, bid);
236   TColgp_Array1OfPnt Poles(1, NbPoles);
237   TColStd_Array1OfReal W(1, NbPoles);
238   Sec->D0(U, Poles, W);
239   for (Standard_Integer ii=1; ii<=NbPoles; ii++) {
240       Box.Add(Poles(ii));
241     }  
242 }
243
244 //=======================================================================
245 //function : Couture
246 //purpose  : Check if E is an edge of sewing on S
247 //           and make the representation HadHoc
248 //=======================================================================
249 static Handle(Geom2d_Curve) Couture(const TopoDS_Edge& E, 
250                                     const Handle(Geom_Surface)& S,
251                                     const TopLoc_Location& L)
252 {
253   TopLoc_Location l = L.Predivided(E.Location());
254   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
255
256   // find the representation
257   BRep_ListIteratorOfListOfCurveRepresentation itcr
258     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
259
260   while (itcr.More()) {
261     Handle(BRep_CurveRepresentation)& cr = itcr.Value();
262     if (cr->IsCurveOnSurface(S,l)) {
263       Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
264       if (GC->IsCurveOnClosedSurface() && Eisreversed) 
265         return  GC->PCurve2();
266       else
267         return GC->PCurve();
268     }
269     itcr.Next();
270   }
271   Handle(Geom2d_Curve) pc;
272   pc.Nullify();
273   return pc;
274 }
275
276 //=======================================================================
277 //function : CheckSameParameter
278 //purpose  : Check a posteriori that sameparameter has worked correctly
279 //=======================================================================
280
281 static Standard_Boolean CheckSameParameter 
282 (const Handle(Adaptor3d_HCurve)&   C3d,
283  const Handle(Geom2d_Curve)&           Pcurv,
284  const Handle(Adaptor3d_HSurface)& S,
285  const Standard_Real             tol3d,
286  Standard_Real&                  tolreached)
287 {
288   tolreached = 0.;
289   Standard_Real f = C3d->FirstParameter();
290   Standard_Real l = C3d->LastParameter();
291   Standard_Integer nbp = 45;
292   Standard_Real step = 1./(nbp -1);
293   for(Standard_Integer i = 0; i < nbp; i++){
294     Standard_Real t,u,v;
295     t = step * i;
296     t = (1-t) * f + t * l;
297     Pcurv->Value(t).Coord(u,v);
298     gp_Pnt pS = S->Value(u,v);
299     gp_Pnt pC = C3d->Value(t);
300     Standard_Real d2 = pS.SquareDistance(pC);
301     tolreached = Max(tolreached,d2);
302   }
303   tolreached = sqrt(tolreached);
304   if(tolreached > tol3d){
305     tolreached *= 2.;
306     return Standard_False;
307   }
308   tolreached *= 2.;
309   tolreached = Max(tolreached,Precision::Confusion());
310   return Standard_True;
311 }
312
313 //=======================================================================
314 //function : SameParameter
315 //purpose  : Encapsulation of Sameparameter
316 // Boolean informs if the pcurve was computed or not...
317 // The tolerance is always OK.
318 //=======================================================================
319
320 static Standard_Boolean SameParameter(TopoDS_Edge&    E,
321                                       Handle(Geom2d_Curve)&        Pcurv,
322                                       const Handle(Geom_Surface)&  Surf,
323                                       const Standard_Real          tol3d,
324                                       Standard_Real&               tolreached)
325 {
326   //Handle(BRepAdaptor_HCurve) C3d = new (BRepAdaptor_HCurve)(E);
327   Standard_Real f, l;
328   Handle(Geom_Curve) C3d = BRep_Tool::Curve( E, f, l );
329   GeomAdaptor_Curve GAC3d( C3d, f, l );
330   Handle(GeomAdaptor_HCurve) HC3d = new GeomAdaptor_HCurve( GAC3d );
331
332   Handle(GeomAdaptor_HSurface) S = new (GeomAdaptor_HSurface)(Surf);
333   Standard_Real ResTol;
334
335   if(CheckSameParameter( HC3d, Pcurv, S, tol3d, tolreached )) 
336     return Standard_True;
337
338   if (!HasPCurves(E))
339     {
340       Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( Pcurv );
341       Approx_CurveOnSurface AppCurve(HC2d, S, HC2d->FirstParameter(), HC2d->LastParameter(),
342                                      Precision::Confusion(), GeomAbs_C1, 10, 10, Standard_True);
343       if (AppCurve.IsDone() && AppCurve.HasResult())
344         {
345           C3d = AppCurve.Curve3d();
346           tolreached = AppCurve.MaxError3d();
347           BRep_Builder B;
348           B.UpdateEdge( E, C3d, tolreached );
349           return Standard_True;
350         }
351     }
352
353   const Handle(Adaptor3d_HCurve)& aHCurve = HC3d; // to avoid ambiguity
354   Approx_SameParameter sp (aHCurve, Pcurv, S, tol3d );
355   if(sp.IsDone() && !sp.IsSameParameter()) Pcurv = sp.Curve2d();
356   else if(!sp.IsDone() && !sp.IsSameParameter()){
357 #ifdef OCCT_DEBUG
358     cout<<"echec SameParameter"<<endl;
359 #endif  
360     return Standard_False;
361   }
362
363   ResTol = sp.TolReached();
364   if(ResTol > tolreached ){
365 #ifdef OCCT_DEBUG
366     cout<<"SameParameter : Tolerance not reached!"<<endl;
367     cout<<"tol visee : "<<tol3d<<" tol obtained : "<<ResTol<<endl;
368 #endif  
369     return Standard_False;
370   }
371   else {
372     tolreached = 1.1*ResTol;
373     if(sp.IsDone() && !sp.IsSameParameter()) Pcurv = sp.Curve2d();
374   }
375   return Standard_True;
376 }
377
378 //=======================================================================
379 //Objet : Orientate an edge of natural restriction 
380 //      : General
381 //=======================================================================
382 static void Oriente(const Handle(Geom_Surface)& S,
383                     TopoDS_Edge& E)
384 {
385   gp_Pnt2d P;
386   gp_Vec2d D, URef(1, 0), VRef(0, 1);
387   Standard_Boolean isuiso, isfirst, isopposite;
388   Standard_Real UFirst, ULast, VFirst, VLast, f, l;
389   S->Bounds(UFirst, ULast, VFirst, VLast);
390   Handle(Geom2d_Curve) C;
391   TopLoc_Location bid;
392
393   C = BRep_Tool::CurveOnSurface(E, S, bid, f, l);
394   C->D1((f+l)/2, P, D);
395
396   isuiso = D.IsParallel(VRef, 0.1);
397   
398   if ( isuiso ) {
399     isfirst = (Abs (P.X()-UFirst) < Precision::Confusion());
400     isopposite = D.IsOpposite(VRef, 0.1);
401     E.Orientation(TopAbs_REVERSED);
402   }
403   else {
404     isfirst = (Abs (P.Y()-VFirst) < Precision::Confusion());
405     isopposite = D.IsOpposite(URef, 0.1);
406     E.Orientation(TopAbs_FORWARD);
407   }
408
409   if (!isfirst)   E.Reverse();
410   if (isopposite) E.Reverse();
411 }
412 //OCC500(apo)->
413 static void UpdateEdgeOnPlane(const TopoDS_Face& F, const TopoDS_Edge& E,
414                               const BRep_Builder& BB)
415 {
416   Standard_Real f, l;
417   Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f,l);
418   Handle(Geom_Surface) S = BRep_Tool::Surface(F);
419   TopLoc_Location Loc;
420   Standard_Real Tol = BRep_Tool::Tolerance(E);
421   BB.UpdateEdge(E, C2d, S, Loc, Tol);
422   BRepCheck_Edge Check(E);
423   Tol = Max(Tol,Check.Tolerance());
424   BB.UpdateEdge(E, Tol);
425   TopoDS_Vertex V; 
426   Tol *= 1.01;
427   V = TopExp::FirstVertex(E);
428   if(BRep_Tool::Tolerance(V) < Tol) BB.UpdateVertex(V, Tol);
429   V = TopExp::LastVertex(E);
430   if(BRep_Tool::Tolerance(V) < Tol) BB.UpdateVertex(V, Tol);
431 }
432 //<-OCC500(apo)
433 //=======================================================================
434 //Function : BuildFace
435 //Objet : Construct a Face via a surface and 4 Edges (natural borders)
436 //      : Only one Hypothesis : isos u and v are switched :
437 //        Edge1/3 are iso u (recp v)
438 //        Edge2/4 are iso v (recp u)
439 //=======================================================================
440 static void BuildFace(const Handle(Geom_Surface)& S,
441                       const TopoDS_Edge& E1,
442                       const TopoDS_Edge& E2,
443                       const TopoDS_Edge& E3,
444                       const TopoDS_Edge& E4,
445                       TopTools_DataMapOfShapeShape& EEmap,
446                       const Standard_Boolean ExchUV,
447                       const Standard_Boolean UReverse,
448                       TopoDS_Face& F)
449 {
450   Standard_Real Tol;
451 // Class BRep_Tool without fields and without Constructor :
452 //  BRep_Tool BT;
453   TopoDS_Edge e1, e2, E;
454   TopoDS_Wire WW;
455   BRep_Builder BB;
456   BRepBuilderAPI_MakeWire B;
457   TopoDS_Iterator Iter;
458   //gp_Pnt2d P;
459
460   //Is the surface planar ?
461   Standard_Real Tol1, Tol2, Tol3, Tol4;
462   Tol1 = BRep_Tool::Tolerance( E1 );
463   Tol2 = BRep_Tool::Tolerance( E2 );
464   Tol3 = BRep_Tool::Tolerance( E3 );
465   Tol4 = BRep_Tool::Tolerance( E4 );
466 //  Tol = Min( BT.Tolerance(E1), BT.Tolerance(E2));
467   Tol = Min( Tol1, Tol2 );
468 //  Tol = Min(Tol, Min(BT.Tolerance(E3),BT.Tolerance(E4)));
469   Tol = Min( Tol, Min( Tol3, Tol4 ) );
470   Standard_Boolean IsPlan = Standard_False;
471   Handle(Geom_Plane) thePlane;
472
473   if (!E1.IsSame(E3) && !E2.IsSame(E4)) //exclude cases with seam edges: they are not planar
474     {
475       GeomLib_IsPlanarSurface IsP(S, Tol);
476       if (IsP.IsPlanar())
477         {
478           IsPlan = Standard_True;
479           thePlane = new Geom_Plane( IsP.Plan() );
480         }
481       else
482         {
483           Handle(BRep_TEdge)& TE1 = *((Handle(BRep_TEdge)*)&E1.TShape());
484           Handle(BRep_TEdge)& TE2 = *((Handle(BRep_TEdge)*)&E2.TShape());
485           Handle(BRep_TEdge)& TE3 = *((Handle(BRep_TEdge)*)&E3.TShape());
486           Handle(BRep_TEdge)& TE4 = *((Handle(BRep_TEdge)*)&E4.TShape());
487           TE1->Tolerance( Precision::Confusion() );
488           TE2->Tolerance( Precision::Confusion() );
489           TE3->Tolerance( Precision::Confusion() );
490           TE4->Tolerance( Precision::Confusion() );
491           
492           TopoDS_Wire theWire = BRepLib_MakeWire( E1, E2, E3, E4 );
493           Standard_Integer NbPoints = NumberOfPoles( theWire );
494           if (NbPoints <= 100) //limitation for CPU
495             {
496               BRepLib_FindSurface FS( theWire, -1, Standard_True );
497               if (FS.Found())
498                 {
499                   IsPlan = Standard_True;
500                   thePlane = Handle(Geom_Plane)::DownCast(FS.Surface());
501                 }
502             }
503           BB.UpdateEdge( E1, Tol1 );
504           BB.UpdateEdge( E2, Tol2 );
505           BB.UpdateEdge( E3, Tol3 );
506           BB.UpdateEdge( E4, Tol4 );
507         }
508     }
509
510   // Construction of the wire
511 //  B.MakeWire(WW);
512   e1 = E1;
513   Oriente(S, e1);
514 //  if (!IsPlan || !BT.Degenerated(e1)) 
515   if (!IsPlan || !BRep_Tool::Degenerated(e1)) 
516     B.Add(e1);
517
518   e2 = E2;
519   Oriente(S, e2);  
520 //  if (!IsPlan || !BT.Degenerated(e2)) 
521   if (!IsPlan || !BRep_Tool::Degenerated(e2))
522     {
523       B.Add(e2);
524       if (!BRep_Tool::Degenerated(e2))
525         {
526           WW = B.Wire();
527           TopoDS_Shape NewEdge;
528           //take the last edge added to WW
529           for (Iter.Initialize( WW ); Iter.More(); Iter.Next())
530             NewEdge = Iter.Value();
531           if (! e2.IsSame(NewEdge))
532             EEmap.Bind( e2, NewEdge );
533         }
534     }
535
536   if (E3.IsSame(E1)) {
537     E = e1;
538     E.Reverse();
539   }
540   else {
541     E = E3;
542     Oriente(S, E);
543   }
544 //  if (!IsPlan || !BT.Degenerated(E))   
545   if (!IsPlan || !BRep_Tool::Degenerated(E))
546     {
547       B.Add(E);
548       if (!BRep_Tool::Degenerated(E))
549         {
550           WW = B.Wire();
551           TopoDS_Shape NewEdge;
552           //take the last edge added to WW
553           for (Iter.Initialize( WW ); Iter.More(); Iter.Next())
554             NewEdge = Iter.Value();
555           if (! E.IsSame(NewEdge))
556             EEmap.Bind( E, NewEdge );
557         }
558     }
559
560   if (E4.IsSame(E2)) {
561     E = e2;
562     E.Reverse();
563   }
564   else {
565     E = E4;
566     Oriente(S, E);
567   }
568 //  if (!IsPlan || !BT.Degenerated(E))  
569   if (!IsPlan || !BRep_Tool::Degenerated(E)) 
570     {
571       B.Add(E);
572       if (!BRep_Tool::Degenerated(E))
573         {
574           WW = B.Wire();
575           TopoDS_Shape NewEdge;
576           //take the last edge added to WW
577           for (Iter.Initialize( WW ); Iter.More(); Iter.Next())
578             NewEdge = Iter.Value();
579           if (! E.IsSame(NewEdge))
580             EEmap.Bind( E, NewEdge );
581         }
582     }
583
584   WW = B.Wire();
585 #if DRAW
586   if (Affich)
587     DBRep::Set("wire-on-face", WW);
588 #endif
589   
590 // Construction of the face.
591   if (IsPlan) { // Suspend representation 2d 
592     // and construct face Plane
593
594     //BRepLib_MakeFace MkF(IsP.Plan(), WW);
595     gp_Pnt aPnt;
596     gp_Vec DU, DV, NS, NP;
597     Standard_Real Ufirst, Ulast, Vfirst, Vlast;
598     S->Bounds( Ufirst, Ulast, Vfirst, Vlast );
599     S->D1( (Ufirst+Ulast)/2., (Vfirst+Vlast)/2., aPnt, DU, DV );
600     NS = DU ^ DV;
601     NP = thePlane->Pln().Axis().Direction();
602     if (NS.Dot(NP) < 0.)
603       thePlane->UReverse();
604     BRepLib_MakeFace MkF( thePlane, WW );
605     if (MkF.Error() != BRepLib_FaceDone) {
606 #ifdef OCCT_DEBUG
607       BRepLib_FaceError Err = MkF.Error();
608       cout << "Planar Face Error :" <<   Err << endl;
609 #endif
610     }
611     else {
612       Handle(Geom2d_Curve) NullC2d;
613       TopLoc_Location Loc;
614       BB.UpdateEdge( E1, NullC2d, S, Loc, Tol1 );
615       BB.UpdateEdge( E2, NullC2d, S, Loc, Tol2 );
616       BB.UpdateEdge( E3, NullC2d, S, Loc, Tol3 );
617       BB.UpdateEdge( E4, NullC2d, S, Loc, Tol4 );
618
619       F =  MkF.Face();
620       UpdateEdgeOnPlane(F,E1,BB);
621       UpdateEdgeOnPlane(F,E2,BB);
622       UpdateEdgeOnPlane(F,E3,BB);
623       UpdateEdgeOnPlane(F,E4,BB);
624 /*OCC500(apo)->
625       TopLoc_Location Loc;
626       Handle(Geom2d_Curve) NC;
627       NC.Nullify();
628 //      B.UpdateEdge(E1, NC, S, Loc, BT.Tolerance(E1));
629       BB.UpdateEdge(E1, NC, S, Loc, BRep_Tool::Tolerance(E1));
630 //      B.UpdateEdge(E2, NC, S, Loc, BT.Tolerance(E2));
631       BB.UpdateEdge(E2, NC, S, Loc, BRep_Tool::Tolerance(E2));
632 //      B.UpdateEdge(E3, NC, S, Loc, BT.Tolerance(E3));
633       BB.UpdateEdge(E3, NC, S, Loc, BRep_Tool::Tolerance(E3));
634 //      B.UpdateEdge(E4, NC, S, Loc, BT.Tolerance(E4));
635       BB.UpdateEdge(E4, NC, S, Loc, BRep_Tool::Tolerance(E4));
636 <-OCC500(apo)*/
637     }  
638   }
639
640   if (!IsPlan) {// Cas Standard : Ajout
641     BB.MakeFace(F, S, Precision::Confusion());
642     BB.Add(F, WW);
643   }
644
645   // Reorientation
646   if (ExchUV) F.Reverse();
647   if (UReverse) F.Reverse();
648 }
649
650
651 //=======================================================================
652 //Fonction : BuildEdge
653 //Objet : Construct non-closed Edge 
654 //=======================================================================
655 static TopoDS_Edge BuildEdge(Handle(Geom_Curve)& C3d,
656                              Handle(Geom2d_Curve)& C2d,
657                              Handle(Geom_Surface)& S,
658                              const TopoDS_Vertex& VF,
659                              const TopoDS_Vertex& VL,
660                              const Standard_Real f, 
661                              const Standard_Real l,
662                              const Standard_Real Tol3d)
663 {
664   gp_Pnt P1, P2, P;
665   Standard_Real Tol1, Tol2, Tol, d;
666 // Class BRep_Tool without fields and without Constructor :
667 //  BRep_Tool BT;
668   BRep_Builder B;
669   TopoDS_Edge E;
670
671 //  P1  = BT.Pnt(VF);
672   P1  = BRep_Tool::Pnt(VF);
673 //  Tol1 = BT.Tolerance(VF);
674   Tol1 = BRep_Tool::Tolerance(VF);
675 //  P2  = BT.Pnt(VL);
676   P2  = BRep_Tool::Pnt(VL);
677 //  Tol2 = BT.Tolerance(VF);
678   Tol2 = BRep_Tool::Tolerance(VF);
679   Tol = Max(Tol1, Tol2);
680
681   if (VF.IsSame(VL) || 
682       (P1.Distance(P2) < Tol ) ) { 
683     // Degenerated case
684     gp_Pnt2d P2d;
685     C2d->D0(f, P2d);
686     S->D0(P2d.X(), P2d.Y(), P);
687     d = P1.Distance(P);
688     if (d > Tol) Tol = d;
689     C2d->D0(l, P2d);
690     S->D0(P2d.X(), P2d.Y(), P);
691     d = P2.Distance(P);
692     if (d > Tol) Tol = d;
693
694     B.UpdateVertex(VF, Tol);
695     B.UpdateVertex(VL, Tol);
696
697     B.MakeEdge(E);
698     B.UpdateEdge(E,C2d,S,TopLoc_Location(), Tol);
699     B.Add(E,VF);
700     B.Add(E,VL);
701     B.Range(E,f,l);
702     B.Degenerated(E, Standard_True);
703
704     return E;
705   }
706
707   C3d->D0(f, P);
708   d = P1.Distance(P);
709   if (d > Tol1)
710       B.UpdateVertex(VF, d);
711
712 //  P1 = BT.Pnt(VL);
713   P1 = BRep_Tool::Pnt(VL);
714   C3d->D0(l, P);
715   d = P2.Distance(P);
716   if (d > Tol2)
717       B.UpdateVertex(VL, d); 
718
719   BRepLib_MakeEdge MkE (C3d, VF, VL, f, l);
720   if (!MkE.IsDone()) { // Error of construction !!     
721 #ifdef DRAW    
722     char name[100];
723     sprintf(name,"firstvertex_error");
724     DBRep::Set(name, VF);
725     sprintf(name,"lastvertex_error");
726     DBRep::Set(name, VL);
727     sprintf(name,"curve3d_error");
728     char* Temp = name ;
729     DrawTrSurf::Set(Temp, C3d);
730 //    DrawTrSurf::Set(name, C3d);
731     Standard_ConstructionError::Raise("BRepFill_Sweep::BuildEdge");
732 #endif
733   }
734
735   E = MkE.Edge();
736   TopLoc_Location Loc;
737   B.UpdateEdge(E, C2d, S, Loc, Tol3d);
738
739   return E;
740 }
741
742         
743 //=======================================================================
744 //Fonction : Filling
745 //Objet : Construct the faces of filling
746 //=======================================================================
747 static Standard_Boolean Filling(const TopoDS_Shape& EF,
748                                 const TopoDS_Shape& F1,
749                                 const TopoDS_Shape& EL,
750                                 const TopoDS_Shape& F2,
751                                 TopTools_DataMapOfShapeShape& EEmap,
752                                 const Standard_Real Tol,
753                                 const  gp_Ax2& Axe,
754                                 const  gp_Vec& TangentOnPart1,
755                                 TopoDS_Edge& Aux1,
756                                 TopoDS_Edge& Aux2,
757                                 TopoDS_Face& Result)
758 {
759   BRep_Builder B;
760 // Class BRep_Tool without fields and without Constructor :
761 //  BRep_Tool BT;
762 //  Standard_Integer NbInt =0;
763 //  Standard_Real Tol3d = Tol;
764   Standard_Boolean WithE3, WithE4;
765
766 // Return constraints
767   TopoDS_Vertex V1, V2, Vf, Vl;
768   TopoDS_Edge E1, E2, E3, E4;
769   E1 = TopoDS::Edge(EF);
770   E2 = TopoDS::Edge(EL);
771   
772   TopExp::Vertices(E1, Vf, Vl);
773   Vf.Orientation(TopAbs_FORWARD);
774   Vl.Orientation(TopAbs_FORWARD);
775
776   TopExp::Vertices(E2, V1, V2);
777   V1.Orientation(TopAbs_REVERSED);
778   V2.Orientation(TopAbs_REVERSED);  
779   
780   B.MakeEdge(E3);
781   B.MakeEdge(E4);
782
783   WithE3 = WithE4 = Standard_False;
784
785   if ((!Aux1.IsNull()) && (!Vf.IsSame(V1))) {
786     E3 = Aux1;
787 //    E3 = TopoDS::Edge(Aux1);
788     WithE3 = Standard_True;
789   }
790
791   if (Vf.IsSame(Vl)) {
792     E4 = E3;
793     E4.Reverse();
794     WithE4 = WithE3;
795   }
796   else if (!Aux2.IsNull() && (!Vl.IsSame(V2))) {
797     E4 = Aux2;
798 //    E4 = TopoDS::Edge(Aux2);
799     WithE4 = Standard_True;
800   }
801
802 #if DRAW
803   if (Affich) {
804     DBRep::Set("Fill_Edge1", E1);
805     DBRep::Set("Fill_Edge2", E2);
806     if (!E3.IsNull())
807       DBRep::Set("Fill_Edge3", E3);
808     if (!E4.IsNull())
809       DBRep::Set("Fill_Edge4", E4);
810   }
811 #endif
812
813 // Construction of a surface of revolution
814   Handle(Geom_Curve) Prof1, Prof2;
815   //Standard_Integer ii, jj;//, Nb;
816   Standard_Real f1, f2, l1, l2,/*d1, d2,*/ Angle;//, Eps = 1.e-9;
817 //  Prof1 = BT.Curve(E1, f1, l1);
818   Prof1 = BRep_Tool::Curve(E1, f1, l1);
819 //  Prof2 = BT.Curve(E2, f2, l2);
820   Prof2 = BRep_Tool::Curve(E2, f2, l2);
821   gp_Pnt P1, P2, P;
822   gp_Pnt2d p1, p2;
823   gp_Trsf Tf;
824   Tf.SetTransformation(Axe);
825
826 // Choose the angle of opening
827   P1 = Prof1->Value((f1+l1)/2);
828   P2 = Prof2->Value((f2+l2)/2);
829   P1.Transform(Tf);
830   P2.Transform(Tf);
831   p1.SetCoord(P1.Z(), P1.X());
832   p2.SetCoord(P2.Z(), P2.X());
833   gp_Vec2d v1(gp::Origin2d(), p1);
834   gp_Vec2d v2(gp::Origin2d(), p2);
835   if (v1.Magnitude() <= gp::Resolution() ||
836       v2.Magnitude() <= gp::Resolution())
837     return Standard_False;
838   Angle = v1.Angle(v2);
839
840   gp_Ax1 axe(Axe.Location(), Axe.YDirection());
841
842   if (Angle < 0) {
843     Angle = -Angle;
844     axe.Reverse();
845   }
846
847   Handle(Geom_SurfaceOfRevolution) Rev = 
848     new (Geom_SurfaceOfRevolution) (Prof1, axe);
849   
850   Handle(Geom_Surface) Surf = 
851     new (Geom_RectangularTrimmedSurface) (Rev, 0, Angle, f1, l1);
852
853   // Control the direction of the rotation
854   Standard_Boolean ToReverseResult = Standard_False;
855   gp_Vec d1u;
856   d1u = Surf->DN(0, (f1+l1)/2, 1, 0);
857   if (d1u.Angle(TangentOnPart1) > M_PI/2) { //Invert everything
858     ToReverseResult = Standard_True;
859     /*
860     axe.Reverse();
861     Angle = 2*M_PI - Angle;
862     Rev = new (Geom_SurfaceOfRevolution) (Prof1, axe);
863     Surf = new (Geom_RectangularTrimmedSurface) 
864            (Rev, 0, Angle, f1, l1);
865     */
866   }
867
868 #if DRAW
869   if (Affich) { 
870       char* Temp = "Surf_Init" ;
871       DrawTrSurf::Set(Temp, Surf);
872     }
873 #endif
874
875   Handle(Geom2d_Curve) C1, C2, C3, C4;
876 /*
877 // Deform the surface of revolution.
878   GeomPlate_BuildPlateSurface BPS;
879
880   Handle(BRepAdaptor_HSurface) AS;
881   Handle(BRepAdaptor_HCurve2d) AC2d;
882   Handle(Adaptor3d_HCurveOnSurface) HConS;
883 */
884   Handle(Geom2d_Line) L;
885   gp_Pnt2d P2d(0.,0.);
886
887   L = new (Geom2d_Line) (P2d, gp::DY2d());
888   C1 = new (Geom2d_TrimmedCurve) (L, f1, l1);
889
890   P2d.SetCoord(Angle,0.);
891   L = new (Geom2d_Line) (P2d, gp::DY2d());
892   C2 = new (Geom2d_TrimmedCurve) (L, f1, l1);
893  
894   // It is required to control the direction and the range.
895   C2->D0(f1, P2d);
896   Surf->D0(P2d.X(), P2d.Y(), P1);
897   C2->D0(l1, P2d);
898   Surf->D0(P2d.X(), P2d.Y(), P2);
899 //  P = BT.Pnt(V1);
900   P = BRep_Tool::Pnt(V1);
901   if (P.Distance(P2)+Tol < P.Distance(P1)) {
902     // E2 is parsed in the direction opposite to E1
903     C2->Reverse();
904     TopoDS_Vertex aux;
905     aux = V2;
906     V2 = V1;
907     V1 = aux;
908   }
909   GeomLib::SameRange(Precision::PConfusion(), C2, 
910                      C2->FirstParameter(),
911                      C2->LastParameter(),
912                      f2, l2, C3);
913   C2 = C3;
914
915 //  P1 = BT.Pnt(Vf);
916   P1 = BRep_Tool::Pnt(Vf);
917 //  P2 = BT.Pnt(V1);
918   P2 = BRep_Tool::Pnt(V1);
919 //  pointu_f = Vf.IsSame(V1) || (P1.Distance(P2) < BT.Tolerance(Vf));
920 //  P1 = BT.Pnt(Vl);
921   P1 = BRep_Tool::Pnt(Vl);
922 //  P2 = BT.Pnt(V2);
923   P2 = BRep_Tool::Pnt(V2);
924 //  pointu_l = Vl.IsSame(V2) || (P1.Distance(P2) < BT.Tolerance(Vl));
925
926   P2d.SetCoord(0.,f1);
927   L = new (Geom2d_Line) (P2d, gp::DX2d());
928   C3 = new (Geom2d_TrimmedCurve) (L, 0, Angle);
929
930
931   P2d.SetCoord(0.,l1);
932   L = new (Geom2d_Line) (P2d, gp::DX2d());   
933   C4 = new (Geom2d_TrimmedCurve) (L, 0, Angle);
934 /*
935   // Determine the constraints and  
936   // their parametric localisation.
937   if (!E1.IsNull()) {
938      AS = new BRepAdaptor_HSurface(TopoDS::Face(F1));
939      AC2d = new BRepAdaptor_HCurve2d();
940      AC2d->ChangeCurve2d().Initialize(E1,TopoDS::Face(F1));
941      HConS = new (Adaptor3d_HCurveOnSurface)();
942      HConS->ChangeCurve().Load(AC2d);
943      HConS->ChangeCurve().Load(AS);
944
945      Handle(BRepFill_CurveConstraint) Cont
946       = new BRepFill_CurveConstraint(HConS, 1, 15);
947      Cont->SetCurve2dOnSurf(C1);
948
949      BPS.Add(Cont);
950      NbInt = HConS->NbIntervals(GeomAbs_CN);
951    }
952
953   if (!E2.IsNull()) {
954     AS = new BRepAdaptor_HSurface(TopoDS::Face(F2));
955     AC2d = new BRepAdaptor_HCurve2d();
956     AC2d->ChangeCurve2d().Initialize(E2,TopoDS::Face(F2));
957     HConS = new (Adaptor3d_HCurveOnSurface);
958
959     HConS->ChangeCurve().Load(AC2d);
960     HConS->ChangeCurve().Load(AS);
961
962     Handle(BRepFill_CurveConstraint) Cont
963       = new BRepFill_CurveConstraint(HConS, 1, 15);
964     Cont->SetCurve2dOnSurf(C2);
965     BPS.Add(Cont);
966   }
967
968   if (WithE3) {
969     Handle(BRepAdaptor_HCurve) AC = new (BRepAdaptor_HCurve) (E3);
970     Handle(BRepFill_CurveConstraint) Cont
971       = new BRepFill_CurveConstraint(AC, 0);
972     Cont->SetCurve2dOnSurf(C3);
973     BPS.Add(Cont);
974   } 
975   else if (pointu_f) {
976     Standard_Real delta = Angle / 11;
977 //    P = BT.Pnt(Vf);
978     P = BRep_Tool::Pnt(Vf);
979     Handle(GeomPlate_PointConstraint) PC;
980     for (ii=1; ii<=10; ii++) {
981       C3->D0(ii*delta, P2d);
982       PC = new (GeomPlate_PointConstraint) (P, 0); 
983       PC->SetPnt2dOnSurf(P2d);
984       BPS.Add(PC);
985     }
986   }
987
988
989   if (WithE4) {
990     Handle(BRepAdaptor_HCurve) AC = new (BRepAdaptor_HCurve) (E4);
991     Handle(BRepFill_CurveConstraint) Cont
992       = new BRepFill_CurveConstraint(AC, 0);
993     Cont->SetCurve2dOnSurf(C4);
994     BPS.Add(Cont);
995   }
996   else if (pointu_l) {
997     Standard_Real delta = Angle / 11;
998 //    P = BT.Pnt(Vl);
999     P = BRep_Tool::Pnt(Vl);
1000     Handle(GeomPlate_PointConstraint) PC;
1001     for (ii=1; ii<=10; ii++) {
1002       C4->D0(ii*delta, P2d);
1003       PC = new (GeomPlate_PointConstraint) (P, 0); 
1004       PC->SetPnt2dOnSurf(P2d);
1005       BPS.Add(PC);
1006     }
1007   }
1008
1009   BPS.LoadInitSurface(Surf);
1010   BPS.Perform();
1011
1012   // Controle s'il y a une deformation effective
1013   Handle(GeomPlate_Surface) plate;
1014   plate = BPS.Surface();
1015   plate->SetBounds(0, Angle, f1, l1);
1016   Standard_Boolean Ok=Standard_True;
1017   Standard_Real u, v;
1018   d1 = (l1-f1)/5;
1019   d2 = Angle/5;
1020   for (ii=0; ii<=5 && Ok; ii++) {
1021     u = f1 + ii*d1;
1022     for (jj=0; jj<=5 && Ok; jj++) {
1023       v = jj*d2;
1024       plate->D0(u, v, P1);
1025       Surf->D0(u, v, P2);
1026       Ok = (P2.IsEqual(P1, Tol)); 
1027     }
1028   }
1029
1030
1031   if (!Ok) {
1032     // Approx de la plate surface
1033     // Bords naturelles => pas besoin de criteres.
1034     GeomConvert_ApproxSurface App(BPS.Surface(), 
1035                                   Tol3d,
1036                                   GeomAbs_C1, GeomAbs_C1,
1037                                   8, 8, 2*NbInt, 0);
1038     if (!App.HasResult()) {
1039 #ifdef OCCT_DEBUG
1040       cout << "Filling_Approx : Pas de resultat" << endl;
1041 #endif      
1042       return Standard_False;
1043     }
1044 #ifdef OCCT_DEBUG
1045     cout <<  "Filling_Approx Error 3d = " << 
1046       App.MaxError() << endl;
1047 #endif
1048     Surf = App.Surface();
1049     Tol3d = App.MaxError();  
1050   }
1051 */
1052
1053 // Update des Edges
1054   TopLoc_Location Loc;
1055   Handle(Geom_Curve) C3d;
1056   B.UpdateEdge(E1, C1, Surf, Loc, /*Tol3d*/Precision::Confusion());
1057   B.UpdateEdge(E2, C2, Surf, Loc, /*Tol3d*/Precision::Confusion());
1058  
1059   if (E3.IsSame(E4)) {
1060     if (!WithE3)
1061       {
1062         C3d = Surf->VIso(f1);
1063         E3 = BuildEdge(C3d, C3, Surf, Vf, V1, 0, Angle, /*Tol3d*/Precision::Confusion());
1064       }
1065     else
1066       {
1067         BRepAdaptor_Curve aCurve(E3);
1068         Standard_Real AngleOld = aCurve.LastParameter();
1069         if (Angle > AngleOld)
1070           {
1071             B.Range( E3, 0, Angle );
1072             TopoDS_Vertex V (TopExp::LastVertex(E3));
1073             Handle(BRep_TVertex)& TVlast = *((Handle(BRep_TVertex)*) &V.TShape());
1074             TVlast->Tolerance( Precision::Confusion() );
1075           }
1076       }
1077
1078     B.UpdateEdge(E3, C3, C4, Surf, Loc, /*Tol3d*/Precision::Confusion());
1079     E4 = E3;
1080     E4.Reverse();
1081   }
1082   else {
1083     if (!WithE3)
1084       {
1085         C3d = Surf->VIso(f1);
1086         E3 = BuildEdge(C3d, C3, Surf, Vf, V1, 0, Angle, /*Tol3d*/Precision::Confusion());
1087       }
1088     else
1089       {
1090         BRepAdaptor_Curve aCurve(E3);
1091         Standard_Real AngleOld = aCurve.LastParameter();
1092         if (Angle > AngleOld)
1093           {
1094             B.Range( E3, 0, Angle );
1095             TopoDS_Vertex V(TopExp::LastVertex(E3));
1096             Handle(BRep_TVertex)& TVlast = *((Handle(BRep_TVertex)*) &V.TShape());
1097             TVlast->Tolerance( Precision::Confusion() );
1098           }
1099
1100         B.UpdateEdge(E3, C3, Surf, Loc, /*Tol3d*/Precision::Confusion());
1101       }
1102     
1103     if (!WithE4)
1104       {
1105         C3d = Surf->VIso(l1);
1106         E4 = BuildEdge(C3d, C4, Surf, Vl, V2, 0, Angle, /*Tol3d*/Precision::Confusion());
1107       }
1108     else
1109       {
1110         BRepAdaptor_Curve aCurve(E4);
1111         Standard_Real AngleOld = aCurve.LastParameter();
1112         if (Angle > AngleOld)
1113           {
1114             B.Range( E4, 0, Angle );
1115             TopoDS_Vertex V (TopExp::LastVertex(E4));
1116             Handle(BRep_TVertex)& TVlast = *((Handle(BRep_TVertex)*)&V.TShape());
1117             TVlast->Tolerance( Precision::Confusion() );
1118           }
1119
1120         B.UpdateEdge(E4, C4, Surf, Loc, /*Tol3d*/Precision::Confusion());
1121       }
1122   }
1123
1124 //Construct face
1125   BuildFace(Surf,E1, E3, E2, E4, EEmap,
1126             Standard_False, Standard_False, 
1127             Result);
1128
1129 // Set the continuities.
1130   B.Continuity(E1, TopoDS::Face(F1), Result, GeomAbs_G1);
1131   B.Continuity(E2, TopoDS::Face(F2), Result, GeomAbs_G1);
1132
1133 // Render the calculated borders.
1134 //  if (!BT.Degenerated(E3))
1135   if (!BRep_Tool::Degenerated(E3))
1136     Aux1 = E3;
1137   else
1138     B.MakeEdge(Aux1); //Nullify
1139
1140 //  if (!BT.Degenerated(E4))
1141   if (!BRep_Tool::Degenerated(E4))
1142     Aux2 = E4;
1143   else
1144     B.MakeEdge(Aux2);
1145
1146   // Set the orientation
1147   gp_Vec D1U, D1V, N1, N2;
1148   C1->D0( (f1+l1)/2, P2d);
1149   Surf->D1(P2d.X(), P2d.Y(), P, D1U, D1V);
1150   N1 = D1U^D1V;
1151   
1152 //  C1 = BT.CurveOnSurface(E1, TopoDS::Face(F1), f2, l2);
1153   C1 = BRep_Tool::CurveOnSurface(E1, TopoDS::Face(F1), f2, l2);
1154   C1->D0( (f1+l1)/2, P2d);
1155   Handle(BRepAdaptor_HSurface) AS = new BRepAdaptor_HSurface(TopoDS::Face(F1));
1156   AS->D1(P2d.X(), P2d.Y(), P, D1U, D1V);
1157   N2 = D1U^D1V;
1158   
1159   if ( (F1.Orientation() == TopAbs_REVERSED) ^ (N1.Angle(N2)>M_PI/2) )
1160     Result.Orientation(TopAbs_REVERSED);
1161   else  Result.Orientation(TopAbs_FORWARD);
1162
1163   if (ToReverseResult)
1164     Result.Reverse();
1165
1166 #if DRAW
1167   if (Affich) DBRep::Set("BoucheTrou", Result);
1168 #endif
1169
1170   return Standard_True;
1171 }
1172
1173 //=======================================================================
1174 //function : Substitute
1175 //purpose  :
1176 //=======================================================================
1177 static void Substitute(BRepTools_Substitution& aSubstitute,
1178                        const TopoDS_Edge& Old,
1179                        const TopoDS_Edge& New) 
1180 {
1181   TopTools_ListOfShape listShape;
1182
1183   TopoDS_Vertex OldV1, OldV2, NewV1, NewV2;
1184   TopExp::Vertices( Old, OldV1, OldV2 );
1185   TopExp::Vertices( New, NewV1, NewV2 );
1186
1187   if (!aSubstitute.IsCopied( OldV1 ))
1188     {
1189       listShape.Append( NewV1.Oriented(TopAbs_FORWARD) );
1190       aSubstitute.Substitute( OldV1, listShape );
1191       listShape.Clear();
1192     }
1193   if (!aSubstitute.IsCopied( OldV2 ))
1194     {
1195       listShape.Append( NewV2.Oriented(TopAbs_FORWARD) );
1196       aSubstitute.Substitute( OldV2, listShape );
1197       listShape.Clear();
1198     }
1199   if (!aSubstitute.IsCopied( Old ))
1200     {
1201       listShape.Append( New.Oriented(TopAbs_FORWARD) );
1202       aSubstitute.Substitute( Old, listShape );
1203     }
1204 }
1205
1206 //=======================================================================
1207 //Function : SetCommonEdgeInFace
1208 //Purpose  : Replace an edge of the face by the corresponding edge from
1209 //           myUEdges
1210 //=======================================================================
1211 /*
1212 static void SetCommonEdgeInFace(BRepTools_Substitution& aSubstitute,
1213                                 const TopoDS_Shape& Face,
1214                                 const TopoDS_Shape& Edge)
1215 {
1216   if (Edge.IsNull())
1217     return;
1218
1219   Standard_Boolean done = Standard_False;
1220 // Class BRep_Tool without fields and without Constructor :
1221 //  BRep_Tool BT;
1222   Standard_Real f, l;
1223   TopExp_Explorer Exp(Face, TopAbs_EDGE);
1224   Handle(Geom_Curve) Cref, C;
1225   TopLoc_Location Lref, L;
1226 //  Cref = BT.Curve(TopoDS::Edge(Edge), Lref, f, l); 
1227   const TopoDS_Edge& NewEdge = TopoDS::Edge(Edge);
1228   Cref = BRep_Tool::Curve( NewEdge, Lref, f, l ); 
1229
1230   for ( ; Exp.More() && !done; Exp.Next()) {
1231 //    C = BT.Curve(TopoDS::Edge(Exp.Current()), L, f, l);
1232     const TopoDS_Edge& OldEdge = TopoDS::Edge(Exp.Current());
1233     C = BRep_Tool::Curve(OldEdge, L, f, l);
1234     if ((Cref==C) && (Lref == L)) {
1235       done = Standard_True;
1236       Substitute( aSubstitute, OldEdge, NewEdge );
1237     }
1238   }
1239 #ifdef OCCT_DEBUG
1240   if (!done) cout << "Substitution of Edge failed" << endl;
1241 #endif  
1242 }
1243 */
1244
1245 //=======================================================================
1246 //Fonction : KeepEdge
1247 //Objet : Find edges of the face supported by the same Curve.
1248 //=======================================================================
1249 static void KeepEdge(const TopoDS_Shape& Face,
1250                      const TopoDS_Shape& Edge,
1251                      TopTools_ListOfShape& List)
1252 {
1253   List.Clear();
1254 // Class BRep_Tool without fields and without Constructor :
1255 //  BRep_Tool BT;
1256   Standard_Real f, l;
1257   TopExp_Explorer Exp(Face, TopAbs_EDGE);
1258   Handle(Geom_Curve) Cref, C;
1259   TopLoc_Location Lref, L;
1260 //  Cref = BT.Curve(TopoDS::Edge(Edge), Lref, f, l); 
1261   Cref = BRep_Tool::Curve(TopoDS::Edge(Edge), Lref, f, l); 
1262
1263   for ( ; Exp.More(); Exp.Next()) {
1264 //    C = BT.Curve(TopoDS::Edge(Exp.Current()), L, f, l);
1265     C = BRep_Tool::Curve(TopoDS::Edge(Exp.Current()), L, f, l);
1266     if ((Cref==C) && (Lref == L)) { 
1267       List.Append(Exp.Current());
1268     }
1269   }
1270 }
1271
1272 //=======================================================================
1273 //Function : 
1274 //Objet : Construct a vertex via an iso
1275 //=======================================================================
1276 static void BuildVertex(const Handle(Geom_Curve)& Iso,
1277                         const Standard_Boolean isfirst,
1278                         const Standard_Real First,
1279                         const Standard_Real Last,
1280                         TopoDS_Shape& Vertex)
1281 {
1282   BRep_Builder B;
1283   Standard_Real val;
1284
1285   if (isfirst) val = First;
1286   else val = Last;
1287   B.MakeVertex(TopoDS::Vertex(Vertex),
1288                Iso->Value(val),
1289                Precision::Confusion());
1290 }
1291
1292 //=======================================================================
1293 //Function : 
1294 //Objet : Construct an empty edge
1295 //=======================================================================
1296 static TopoDS_Edge NullEdge(TopoDS_Shape& Vertex)
1297 {
1298   TopoDS_Edge E;
1299   BRep_Builder B;
1300   B.MakeEdge(E);
1301   Vertex.Orientation(TopAbs_FORWARD);
1302   B.Add(E, Vertex);
1303   B.Add(E, Vertex.Reversed());
1304   B.Degenerated(E, Standard_True);
1305   return E;
1306
1307 }
1308         
1309 //=======================================================================
1310 //Function : 
1311 //Objet : Construct an edge via an iso
1312 //=======================================================================
1313 static TopoDS_Edge BuildEdge(const Handle(Geom_Surface)& S,
1314                              const Standard_Boolean isUiso,
1315                              const Standard_Real ValIso,
1316                              const TopoDS_Shape&  VFirst,
1317                              const TopoDS_Shape&  VLast,
1318                              const Standard_Real  Tol)
1319 {
1320   TopoDS_Edge E;
1321   BRep_Builder B;
1322   Handle(Geom_Curve) Iso;
1323   Standard_Boolean sing = Standard_False;
1324   if (isUiso) {
1325     Iso = S->UIso(ValIso);
1326   }
1327   else {      
1328     Iso = S->VIso(ValIso);
1329   }
1330
1331   if (VFirst.IsSame(VLast)) { // Singular case ?
1332     gp_Pnt P; 
1333 // Class BRep_Tool without fields and without Constructor :
1334 //    BRep_Tool BT;
1335     const TopoDS_Vertex& V = TopoDS::Vertex(VFirst);
1336 //    Standard_Real tol = BT.Tolerance(V);
1337     Standard_Real tol = BRep_Tool::Tolerance(V);
1338     if (Tol > tol) tol = Tol; 
1339     Iso->D0((Iso->FirstParameter()+Iso->LastParameter())/2, P);
1340 //    if (P.Distance(BT.Pnt(V)) < tol) {
1341     if (P.Distance(BRep_Tool::Pnt(V)) < tol) {
1342       GeomAdaptor_Curve AC(Iso);
1343       sing = GCPnts_AbscissaPoint::Length(AC, tol/4) < tol;
1344     }
1345   }
1346
1347
1348   if (sing) { // Singular case
1349     TopoDS_Shape V;
1350     V = VFirst;
1351     E = NullEdge(V);
1352 //    Iso.Nullify();
1353 //    B.UpdateEdge(E, Iso, Precision::Confusion());
1354     B.Degenerated(E, Standard_True);
1355   }
1356   
1357   else {
1358     // Construction Via 3d
1359 //    if (isUiso) {
1360 //      Iso = S->UIso(ValIso);
1361     gp_Pnt P1,P2;
1362     Standard_Real p1, p2, p11, p12, p21, p22;
1363     Standard_Boolean fwd = Standard_False;
1364     p1 = Iso->FirstParameter();
1365     p2 = Iso->LastParameter();
1366     P1 = Iso->Value(p1);
1367     P2 = Iso->Value(p2);
1368
1369     Standard_Real t1 = BRep_Tool::Tolerance(TopoDS::Vertex(VFirst));
1370     Standard_Real t2 = BRep_Tool::Tolerance(TopoDS::Vertex(VLast));
1371
1372     BRep_Builder BB;
1373
1374     p11 = P1.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VFirst)));
1375     p22 = P2.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VLast)));
1376     p12 = P1.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VLast)));
1377     p21 = P2.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VFirst)));
1378     
1379     if(p11 < p12 && p22 < p21) fwd = Standard_True;
1380
1381     if(fwd) { //OCC500(apo)
1382       if (p11 >= t1) BB.UpdateVertex(TopoDS::Vertex(VFirst), 1.01*p11);
1383       if (p22 >= t2) BB.UpdateVertex(TopoDS::Vertex(VLast), 1.01*p22);
1384     }
1385     else {      
1386 //      Iso = S->VIso(ValIso);
1387       if (p12 >= t2) BB.UpdateVertex(TopoDS::Vertex(VLast), 1.01*p12);
1388       if (p21 >= t1) BB.UpdateVertex(TopoDS::Vertex(VFirst), 1.01*p21);
1389     }
1390
1391     BRepLib_MakeEdge MkE;
1392
1393 //    MkE.Init(Iso, 
1394 //           TopoDS::Vertex(VFirst), 
1395 //           TopoDS::Vertex(VLast), 
1396 //           Iso->FirstParameter(),
1397 //           Iso->LastParameter());
1398     if(fwd)
1399       MkE.Init(Iso, 
1400                TopoDS::Vertex(VFirst), 
1401                TopoDS::Vertex(VLast), 
1402                Iso->FirstParameter(),
1403                Iso->LastParameter());
1404     else
1405       MkE.Init(Iso,
1406                TopoDS::Vertex(VLast),
1407                TopoDS::Vertex(VFirst), 
1408                Iso->FirstParameter(),
1409                Iso->LastParameter());
1410
1411 //    if (!MkE.IsDone()) { // Il faut peut etre permuter les Vertex
1412 //      MkE.Init(Iso,
1413 //             TopoDS::Vertex(VLast),
1414 //             TopoDS::Vertex(VFirst), 
1415 //             Iso->FirstParameter(),
1416 //             Iso->LastParameter());
1417 //    }
1418
1419     if (!MkE.IsDone()) { // Erreur de construction !!     
1420 #ifdef DRAW
1421       char name[100];
1422       sprintf(name,"firstvertex_error");
1423       DBRep::Set(name, VFirst);
1424       sprintf(name,"lastvertex_error");
1425       DBRep::Set(name, VLast);
1426       sprintf(name,"curve3d_error");
1427       char* Temp = name ;
1428       DrawTrSurf::Set(Temp,Iso);
1429 //      DrawTrSurf::Set(name,Iso);
1430 #endif
1431       Standard_ConstructionError::Raise("BRepFill_Sweep::BuildEdge");
1432     }
1433
1434     E = MkE.Edge();
1435   }
1436
1437   // Associate 2d
1438   Handle(Geom2d_Line) L;
1439   TopLoc_Location Loc;
1440   Standard_Real Umin, Umax, Vmin, Vmax;
1441   S->Bounds(Umin, Umax, Vmin, Vmax);
1442   if (isUiso) {
1443     //gp_Pnt2d P(ValIso, 0);
1444     gp_Pnt2d P( ValIso, Vmin - Iso->FirstParameter() );
1445     gp_Vec2d V(0., 1.);
1446     L = new (Geom2d_Line) (P, V);
1447   }
1448   else {
1449     //gp_Pnt2d P(0., ValIso);
1450     gp_Pnt2d P( Umin -Iso->FirstParameter() , ValIso );
1451     gp_Vec2d V(1., 0.);
1452     L = new (Geom2d_Line) (P, V);
1453   }
1454
1455   B.UpdateEdge(E, L, S, Loc, Precision::Confusion());
1456   if (sing) B.Range(E, S, Loc, 
1457                     Iso->FirstParameter(), 
1458                     Iso->LastParameter());
1459
1460   Standard_Real MaxTol = 1.e-4;
1461   Standard_Real theTol;
1462   GeomAdaptor_Curve GAiso(Iso);
1463   Handle(GeomAdaptor_HCurve) GAHiso = new GeomAdaptor_HCurve(GAiso);
1464   GeomAdaptor_Surface GAsurf(S);
1465   Handle(GeomAdaptor_HSurface) GAHsurf = new GeomAdaptor_HSurface(GAsurf);
1466   CheckSameParameter( GAHiso, L, GAHsurf, MaxTol, theTol);
1467   B.UpdateEdge(E, theTol);
1468
1469   return E;
1470 }
1471
1472 //=======================================================================
1473 //Function : 
1474 //Objet : Complete an edge via an iso
1475 //=======================================================================
1476 static void UpdateEdge(TopoDS_Edge& E,
1477                        const Handle(Geom_Surface)& S,
1478                        const Standard_Boolean isUiso,
1479                        const Standard_Real ValIso)
1480 {
1481   BRep_Builder B;
1482   Handle(Geom2d_Line) L;
1483   Handle(Geom2d_Curve) PCurve, CL;
1484   TopLoc_Location Loc;
1485   Standard_Real UFirst, ULast, VFirst, VLast, F2d, L2d;
1486   S->Bounds( UFirst, ULast, VFirst, VLast);
1487
1488   Standard_Boolean sing = Standard_False;
1489   Handle(Geom_Curve) Iso;
1490   if (isUiso) {
1491     Iso = S->UIso(ValIso);
1492   }
1493   else {      
1494     Iso = S->VIso(ValIso);
1495   }
1496
1497   TopoDS_Vertex Vf, Vl;
1498   TopExp::Vertices(E, Vf, Vl);
1499   if (Vf.IsSame(Vl)) { // Singular case ?
1500     gp_Pnt Pmid; 
1501     Standard_Real tol = BRep_Tool::Tolerance(Vf);
1502     Iso->D0((Iso->FirstParameter()+Iso->LastParameter())/2, Pmid);
1503     if (Pmid.Distance(BRep_Tool::Pnt(Vf)) < tol) {
1504       GeomAdaptor_Curve AC(Iso);
1505       sing = GCPnts_AbscissaPoint::Length(AC, tol/4) < tol;
1506     }
1507   }
1508
1509   if (isUiso) {
1510     gp_Pnt2d P(ValIso, 0);
1511     gp_Vec2d V(0., 1.);
1512     L = new (Geom2d_Line) (P, V);
1513     F2d = VFirst;
1514     L2d = VLast;
1515   }
1516   else {
1517     gp_Pnt2d P(0., ValIso);
1518     gp_Vec2d V(1., 0.);
1519     L = new (Geom2d_Line) (P, V);
1520     F2d = UFirst;
1521     L2d = ULast;
1522   }
1523   CL = new (Geom2d_TrimmedCurve) (L, F2d, L2d);
1524
1525   // Control direction & Range
1526   Standard_Real R, First, Last, Tol=1.e-4;
1527   Standard_Boolean reverse = Standard_False;;
1528   
1529
1530 // Class BRep_Tool without fields and without Constructor :
1531 //  BRep_Tool BT;
1532   gp_Pnt POnS;
1533   gp_Pnt2d P2d;
1534 //  BT.Range(E, First, Last);
1535   BRep_Tool::Range(E, First, Last);
1536
1537   if (!Vf.IsSame(Vl)) {
1538     // Test distances between "FirstPoint" and "Vertex"
1539     P2d = CL->Value(F2d);
1540     POnS = S->Value(P2d.X(), P2d.Y());
1541 //    reverse = POnS.Distance(BT.Pnt(Vl)) < POnS.Distance(BT.Pnt(Vf));
1542     reverse = POnS.Distance(BRep_Tool::Pnt(Vl)) < POnS.Distance(BRep_Tool::Pnt(Vf));
1543   }
1544   else if (!sing) {
1545     // Test angle between "First Tangente"
1546     gp_Vec2d V2d;
1547     gp_Vec V3d, du, dv, dC3d;
1548     BRepAdaptor_Curve C3d(E);
1549
1550     C3d.D1(First, POnS,  dC3d);
1551     CL->D1(F2d, P2d, V2d);
1552     S->D1(P2d.X(), P2d.Y(), POnS, du, dv);
1553     V3d.SetLinearForm(V2d.X(), du, V2d.Y(), dv);
1554     reverse = ( dC3d.Angle(V3d) > Tol);
1555   }
1556   if (reverse ) { // Return curve 2d
1557     CL = new (Geom2d_TrimmedCurve)(L, F2d, L2d);
1558     CL->Reverse();  
1559     F2d = CL->FirstParameter();
1560     L2d = CL->LastParameter();
1561   }
1562
1563   if (sing)
1564     {
1565       Handle(Geom_Curve) NullCurve;
1566       B.UpdateEdge(E, NullCurve, 0.);
1567       B.Degenerated(E, Standard_True);
1568       B.Range(E, F2d, L2d);
1569       First = F2d;
1570       Last  = L2d;
1571     }
1572
1573   if (First != F2d || Last != L2d) {
1574     Handle(Geom2d_Curve) C2d;
1575     GeomLib::SameRange(Precision::PConfusion(), CL, 
1576                        F2d, L2d, First, Last,
1577                        C2d);
1578     CL = new (Geom2d_TrimmedCurve)(C2d, First, Last);
1579   }
1580
1581   // Update des Vertex
1582
1583   TopoDS_Vertex V;
1584
1585   P2d = CL->Value(First);
1586   POnS = S->Value(P2d.X(), P2d.Y());
1587   V = TopExp::FirstVertex(E); 
1588 //  R = POnS.Distance(BT.Pnt(V));
1589   R = POnS.Distance(BRep_Tool::Pnt(V));
1590   B.UpdateVertex(V, R);
1591
1592   P2d = CL->Value(Last);
1593   POnS = S->Value(P2d.X(), P2d.Y());
1594   V = TopExp::LastVertex(E);
1595 //  R = POnS.Distance(BT.Pnt(V));
1596   R = POnS.Distance(BRep_Tool::Pnt(V));
1597   B.UpdateVertex(V, R);
1598
1599   // Update Edge
1600   if (!sing && SameParameter(E, CL, S, Tol, R)) {
1601     B.UpdateEdge(E, R);
1602   }
1603
1604   PCurve = Couture(E, S, Loc);
1605   if (PCurve.IsNull())
1606     B.UpdateEdge(E, CL, S, Loc, Precision::Confusion());
1607   else { // Sewing edge
1608     TopoDS_Edge e = E;
1609     Oriente(S, e);
1610     if (e.Orientation() == TopAbs_REVERSED)
1611       B.UpdateEdge(E, CL, PCurve, S, Loc, Precision::Confusion());
1612     else         
1613       B.UpdateEdge(E, PCurve, CL, S, Loc, Precision::Confusion());
1614   }
1615
1616   // Attention to case not SameRange on its shapes (PRO13551)
1617 //  if (!BT.SameRange(E)) B.Range(E, S, Loc, First, Last);
1618   if (!BRep_Tool::SameRange(E)) B.Range(E, S, Loc, First, Last);
1619 }
1620
1621 //=======================================================================
1622 // Object : Check if a surface is degenerated
1623 //=======================================================================
1624 static Standard_Boolean IsDegen(const Handle(Geom_Surface)& S,
1625                                 const Standard_Real Tol)
1626 {
1627   Standard_Integer Nb = 5;
1628   Standard_Boolean B = Standard_True;
1629   Standard_Real Umax, Umin, Vmax, Vmin, t, dt, l;
1630   Standard_Integer ii;
1631   Handle(Geom_Curve) Iso;
1632   gp_Pnt P1,P2,P3;
1633   GCPnts_AbscissaPoint GC;
1634
1635   S->Bounds(Umin, Umax, Vmin, Vmax);
1636
1637   // Check the length of Iso-U
1638   t = (Umin + Umax)/2;
1639   S->D0(t, Vmin, P1);
1640   S->D0(t, (Vmin+Vmax)/2, P2);
1641   S->D0(t, Vmax, P3);
1642   B = ((P1.Distance(P2) + P2.Distance(P3)) < Tol);
1643   
1644   for (ii=1, dt = (Umax-Umin)/(Nb+1); B && (ii<=Nb); ii++) {
1645     t =  Umin + ii*dt;
1646     Iso = S->UIso(t);
1647     GeomAdaptor_Curve AC(Iso);
1648     l = GC.Length(AC, Tol/4);
1649     B = (l <= Tol);
1650   }
1651  
1652   if (B) return Standard_True;
1653
1654   // Check the length of Iso-V
1655   t = (Vmin + Vmax)/2;
1656   S->D0(Umin, t, P1);
1657   S->D0((Umin+Umax)/2, t, P2);
1658   S->D0(Umax, t, P3);
1659   B = ((P1.Distance(P2) + P2.Distance(P3)) < Tol); 
1660  
1661  
1662   for (ii=1, dt = (Vmax-Vmin)/(Nb+1); B && (ii<=Nb); ii++) {
1663     t =  Vmin + ii*dt;
1664     Iso = S->VIso(t);
1665     GeomAdaptor_Curve AC(Iso);
1666     l = GC.Length(AC, Tol/4);
1667     B = (l <= Tol);
1668   }  
1669     
1670   return B;
1671 }
1672
1673 //=======================================================================
1674 //function : Constructeur
1675 //purpose  : 
1676 //======================================================================
1677 BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
1678                                const Handle(BRepFill_LocationLaw)& Location,
1679                                const Standard_Boolean WithKPart) : 
1680                                isDone(Standard_False),
1681                                KPart(WithKPart)
1682
1683
1684 {
1685  mySec = Section;
1686  myLoc = Location;
1687  
1688  SetTolerance(1.e-4);
1689  SetAngularControl();
1690  myAuxShape.Clear();
1691
1692  myApproxStyle = GeomFill_Location;
1693  myContinuity  = GeomAbs_C2;
1694  myDegmax      = 11;
1695  mySegmax      = 30;
1696  myForceApproxC1 = Standard_False;
1697 }
1698
1699 //=======================================================================
1700 //function : SetBounds
1701 //purpose  : Define start and end shapes
1702 //======================================================================
1703  void BRepFill_Sweep::SetBounds(const TopoDS_Wire& First,
1704                                 const TopoDS_Wire& Last)
1705
1706   FirstShape = First;
1707   LastShape  = Last; 
1708
1709   // It is necessary to check the SameRange on its (PRO13551)
1710 #ifdef OCCT_DEBUG
1711   Standard_Boolean issame = Standard_True;
1712 #endif
1713   BRep_Builder B;
1714   BRepTools_WireExplorer wexp;
1715   if (!FirstShape.IsNull()) {
1716     for (wexp.Init(FirstShape); wexp.More(); wexp.Next()) {
1717       if (!BRepLib::CheckSameRange(wexp.Current())) {
1718         B.SameRange(wexp.Current(), Standard_False);
1719         B.SameParameter(wexp.Current(), Standard_False);
1720 #ifdef OCCT_DEBUG
1721         issame = Standard_False;
1722 #endif
1723       }
1724     }
1725   }
1726   
1727   if (!LastShape.IsNull()) {
1728     for (wexp.Init(LastShape); wexp.More(); wexp.Next()) {
1729       if (!BRepLib::CheckSameRange(wexp.Current())) {
1730         B.SameRange(wexp.Current(), Standard_False); 
1731         B.SameParameter(wexp.Current(), Standard_False);
1732 #ifdef OCCT_DEBUG
1733         issame = Standard_False;
1734 #endif
1735       }
1736     }
1737   }
1738
1739 #ifdef OCCT_DEBUG
1740   if (!issame) 
1741     cout<<"Sweep Warning : Edge not SameRange in the limits"<<endl;
1742 #endif
1743 }
1744
1745 //=======================================================================
1746 //function : SetTolerance
1747 //purpose  :
1748 //======================================================================
1749  void BRepFill_Sweep::SetTolerance(const Standard_Real Tol3d,
1750                                    const Standard_Real BoundTol,
1751                                    const Standard_Real Tol2d, 
1752                                    const Standard_Real TolAngular) 
1753 {
1754   myTol3d = Tol3d;
1755   myBoundTol = BoundTol;
1756   myTol2d =Tol2d;
1757   myTolAngular = TolAngular;
1758 }
1759 //=======================================================================
1760 //function : SetAngularControl
1761 //purpose  :
1762 //======================================================================
1763  void BRepFill_Sweep::SetAngularControl(const Standard_Real MinAngle,
1764                                    const Standard_Real MaxAngle)
1765 {
1766   myAngMin = Max (MinAngle, Precision::Angular());
1767   myAngMax = Min (MaxAngle, 6.28);
1768 }
1769
1770 //=======================================================================
1771 //function : SetForceApproxC1
1772 //purpose  : Set the flag that indicates attempt to approximate
1773 //           a C1-continuous surface if a swept surface proved
1774 //           to be C0.
1775 //=======================================================================
1776  void BRepFill_Sweep::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
1777 {
1778   myForceApproxC1 = ForceApproxC1;
1779 }
1780
1781 ///=======================================================================
1782 //function : CorrectApproxParameters
1783 //purpose  : 
1784 //=======================================================================
1785  Standard_Boolean BRepFill_Sweep::CorrectApproxParameters()
1786 {
1787   TopoDS_Wire thePath = myLoc->Wire();
1788   GeomAbs_Shape    NewCont   = myContinuity;
1789   Standard_Integer NewSegmax = mySegmax;
1790
1791   TopoDS_Iterator iter(thePath);
1792   for (; iter.More(); iter.Next())
1793     {
1794       TopoDS_Edge anEdge = TopoDS::Edge(iter.Value());
1795       BRepAdaptor_Curve aBAcurve(anEdge);
1796       GeomAbs_Shape aContinuity = aBAcurve.Continuity();
1797       Standard_Integer aNbInterv = aBAcurve.NbIntervals(GeomAbs_CN);
1798       if (aContinuity < NewCont)
1799         NewCont = aContinuity;
1800       if (aNbInterv > NewSegmax)
1801         NewSegmax = aNbInterv;
1802     }
1803
1804   Standard_Boolean Corrected = Standard_False;
1805   if (NewCont != myContinuity || NewSegmax != mySegmax)
1806     Corrected = Standard_True;
1807   myContinuity = NewCont;
1808   mySegmax     = NewSegmax;
1809   return Corrected;
1810 }
1811
1812 //=======================================================================
1813 //function : BuildWire
1814 //purpose  : Construit a wire by sweeping
1815 //======================================================================
1816  Standard_Boolean BRepFill_Sweep::
1817  BuildWire(const BRepFill_TransitionStyle /*Transition*/)
1818 {
1819   Standard_Integer ipath, isec = 1;
1820   gp_Pnt P1;//, P2;
1821
1822   BRep_Builder B;
1823 // Class BRep_Tool without fields and without Constructor :
1824 //  BRep_Tool BT;
1825   Standard_Integer NbPath = myLoc->NbLaw();
1826   Standard_Boolean vclose;
1827   vclose = (myLoc->IsClosed() && (myLoc->IsG1(0, myTol3d)>= 0));
1828   Error = 0.;
1829   Handle(Geom_Surface) S;
1830   Handle(Geom_Curve) Iso;
1831   Standard_Real val, bid, First, Last, Tol;
1832
1833  TopoDS_Wire wire;
1834  TopoDS_Edge E;
1835  B.MakeWire(wire);
1836
1837  // (1) Construction of all curves
1838
1839  // (1.1) Construction of Tables
1840  myFaces = new (TopTools_HArray2OfShape) (1, 1, 1, NbPath);
1841  myUEdges = new (TopTools_HArray2OfShape) (1, 2, 1, NbPath);
1842  myVEdges = new (TopTools_HArray2OfShape) (1, 1, 1, NbPath+1);
1843
1844  // (1.2) Calculate curves / vertex / edge
1845   for (ipath=1; ipath <=NbPath; ipath++) { 
1846     // Curve by iso value
1847     GeomFill_Sweep Sweep(myLoc->Law(ipath), KPart);
1848     Sweep.SetTolerance(myTol3d, myBoundTol, myTol2d, myTolAngular);
1849     Sweep.SetForceApproxC1(myForceApproxC1);
1850     Sweep.Build(mySec->Law(isec), myApproxStyle, myContinuity, myDegmax, mySegmax);
1851     if (!Sweep.IsDone())  
1852       return Standard_False;
1853     S = Sweep.Surface();
1854     if (Sweep.ExchangeUV()) {
1855       if  (Sweep.UReversed()) S->Bounds(First, Last, bid, val);
1856       else S->Bounds(First, Last, val, bid);
1857       Iso = S->VIso(val); 
1858     }
1859     else {
1860       if (Sweep.UReversed()) S->Bounds(bid,  val, First, Last);
1861       else  S->Bounds(val, bid, First, Last);
1862       Iso = S->UIso(val); 
1863     }
1864     // Vertex by position
1865     if (ipath < NbPath) 
1866       BuildVertex(Iso, Standard_False, First, Last, 
1867                   myVEdges->ChangeValue(1, ipath+1));
1868     else {
1869       if (vclose) { 
1870         TopoDS_Vertex& V = TopoDS::Vertex(myVEdges->ChangeValue(1, 1));
1871         myVEdges->SetValue(1, ipath+1, V);
1872         Iso->D0(Last, P1);
1873 //      Tol = P1.Distance(BT.Pnt(V));
1874         Tol = P1.Distance(BRep_Tool::Pnt(V));
1875         B.UpdateVertex(V, Tol);
1876       }
1877       else {
1878         if (!LastShape.IsNull()) myVEdges->SetValue(1, NbPath, FirstShape);
1879         else BuildVertex(Iso, Standard_False, First, Last, 
1880                          myVEdges->ChangeValue(1, NbPath+1));
1881       }
1882     }
1883   
1884     if (ipath > 1) {
1885       Iso->D0(First, P1);
1886       TopoDS_Vertex& V = TopoDS::Vertex(myVEdges->ChangeValue(1, ipath));
1887 //      Tol = P1.Distance(BT.Pnt(V));
1888       Tol = P1.Distance(BRep_Tool::Pnt(V));
1889       B.UpdateVertex(V, Tol);
1890     }
1891     if (ipath == 1) {
1892       if (!FirstShape.IsNull()) myVEdges->SetValue(1,1, FirstShape);
1893       else BuildVertex(Iso, Standard_True, First, Last, 
1894                        myVEdges->ChangeValue(1, 1));
1895     }
1896
1897     // Construction of the edge
1898     BRepLib_MakeEdge MkE;
1899     MkE.Init(Iso, 
1900              TopoDS::Vertex(myVEdges->Value(1, ipath)), 
1901              TopoDS::Vertex(myVEdges->Value(1, ipath+1)), 
1902              Iso->FirstParameter(),
1903              Iso->LastParameter());
1904     if (!MkE.IsDone()) { // Error of construction !!     
1905 #ifdef DRAW
1906       char name[100];
1907       sprintf(name,"firstvertex_error");
1908       DBRep::Set(name, myVEdges->Value(1, ipath));
1909       sprintf(name,"lastvertex_error");
1910       DBRep::Set(name, myVEdges->Value(1, ipath+1));
1911       sprintf(name,"curve3d_error");
1912       char* Temp = name ;
1913       DrawTrSurf::Set(Temp,Iso);
1914 //       DrawTrSurf::Set(name,Iso);
1915       Standard_ConstructionError::Raise("BRepFill_Sweep::BuildEdge");
1916 #endif
1917        return Standard_False;  
1918      }
1919     E = MkE.Edge();
1920 #if DRAW
1921     if (Affich) {
1922       sprintf(name,"Surf_%d", ipath);
1923       char* Temp = name;
1924       DrawTrSurf::Set(Temp, S);
1925 //      DrawTrSurf::Set(name, S);
1926       sprintf(name,"Edge_%d", ipath);
1927       DBRep::Set(name, E);
1928     }
1929 #endif
1930     B.UpdateEdge(E, Sweep.ErrorOnSurface());
1931     B.Add(wire, E);
1932     myFaces->SetValue(1, ipath, E);
1933   }  
1934   myShape = wire;
1935   return Standard_True;
1936 }
1937
1938 //=======================================================================
1939 //function : BuildShell
1940 //purpose  : Construct a Shell by sweeping
1941 //======================================================================
1942  Standard_Boolean BRepFill_Sweep::
1943  BuildShell(const BRepFill_TransitionStyle /*Transition*/,
1944             const Standard_Integer IFirst,
1945             const Standard_Integer ILast,
1946             TopTools_MapOfShape& ReversedEdges,
1947             BRepFill_DataMapOfShapeHArray2OfShape& Tapes,
1948             BRepFill_DataMapOfShapeHArray2OfShape& Rails,
1949             const Standard_Real ExtendFirst,
1950             const Standard_Real ExtendLast) 
1951 {
1952   Standard_Integer ipath, isec, IPath;
1953 #ifdef DRAW
1954   char name[100];
1955 #endif
1956   BRep_Builder B;
1957   Standard_Integer NbPath = ILast - IFirst;
1958   Standard_Integer NbLaw =  mySec->NbLaw();
1959   Standard_Boolean uclose, vclose,  constSection, hasdegen = Standard_False;
1960   constSection = mySec->IsConstant();
1961   uclose = mySec->IsUClosed();
1962   vclose = (mySec->IsVClosed() && myLoc->IsClosed()) && 
1963            (NbPath == myLoc->NbLaw()) && (myLoc->IsG1(0, myTol3d)>= 0);
1964   Error = 0.;
1965
1966   // (1) Construction of all surfaces
1967
1968   // (1.1) Construction of Tables
1969
1970   TColStd_Array2OfInteger ExchUV(1, NbLaw, 1, NbPath);
1971   TColStd_Array2OfInteger UReverse(1, NbLaw, 1, NbPath);
1972   TColStd_Array2OfInteger Degenerated(1, NbLaw, 1, NbPath);
1973   Degenerated.Init(0);
1974   // No VReverse for the moment...
1975   TColStd_Array2OfReal TabErr(1, NbLaw   , 1, NbPath);
1976   TColGeom_Array2OfSurface TabS(1, NbLaw , 1, NbPath);
1977   
1978   TopTools_Array2OfShape UEdge(1, NbLaw+1, 1, NbPath);
1979   TopTools_Array2OfShape VEdge(1, NbLaw  , 1, NbPath+1);
1980   TopTools_Array2OfShape Vertex(1,NbLaw+1, 1, NbPath+1);
1981
1982   TopoDS_Vertex VNULL;
1983   VNULL.Nullify();
1984   Vertex.Init(VNULL);
1985
1986   TopTools_Array1OfShape SecVertex(1, NbLaw+1);
1987   TColStd_Array1OfReal VError(1, NbLaw+1);
1988   TColStd_Array1OfReal Vi(1, NbPath+1);
1989
1990 //Initialization of management of parametric intervals 
1991 //(Case of evolutionary sections)
1992   Standard_Real Length, SecDom, SecDeb;
1993   myLoc->CurvilinearBounds(myLoc->NbLaw(), SecDom, Length);
1994   mySec->Law(1)->GetDomain(SecDeb, SecDom);
1995   SecDom -= SecDeb;
1996   if (IFirst > 1) {
1997     Standard_Real Lf, Ll;
1998     myLoc->CurvilinearBounds(IFirst-1, Lf, Ll);
1999     Vi(1) = SecDeb + (Ll/Length)*SecDom;
2000   }
2001   else 
2002     Vi(1) = SecDeb;
2003
2004   // Error a priori on vertices
2005   if (constSection) {
2006     for (isec=1; isec<=NbLaw+1; isec++) {
2007       VError(isec) = mySec->VertexTol(isec-1, 0.);
2008       SecVertex(isec) = mySec->Vertex(isec, 0.);
2009     }
2010   }
2011  
2012
2013   // (1.2) Calculate surfaces
2014   for (ipath=1, IPath=IFirst; ipath <=NbPath; ipath++, IPath++) {
2015
2016     GeomFill_Sweep Sweep(myLoc->Law(IPath), KPart);
2017     Sweep.SetTolerance(myTol3d, myBoundTol, myTol2d, myTolAngular);
2018     Sweep.SetForceApproxC1(myForceApproxC1);
2019
2020     // Case of evolutionary section, definition of parametric correspondence
2021     if (!constSection) {
2022       Standard_Real lf, ll, Lf, Ll;
2023       myLoc->Law(IPath)->GetDomain(lf, ll);
2024       myLoc->CurvilinearBounds(IPath, Lf, Ll);
2025       Vi(ipath+1) = SecDeb + (Ll/Length)*SecDom;
2026       Sweep.SetDomain(lf, ll, Vi(ipath), Vi(ipath+1));
2027     }
2028     else //section is constant
2029       {
2030         Standard_Real lf, ll, Lf, Ll;
2031         myLoc->Law(IPath)->GetDomain(lf, ll);
2032         myLoc->CurvilinearBounds(IPath, Lf, Ll);
2033         Vi(ipath+1) = SecDeb + (Ll/Length)*SecDom;
2034       }
2035     
2036     for(isec=1; isec<=NbLaw; isec++) {
2037       Sweep.Build(mySec->Law(isec), myApproxStyle, myContinuity, myDegmax, mySegmax);
2038       if (!Sweep.IsDone()) 
2039         return Standard_False;
2040       TabS(isec,ipath) = Sweep.Surface();
2041       TabErr(isec,ipath) = Sweep.ErrorOnSurface();
2042       ExchUV(isec, ipath) =  Sweep.ExchangeUV();
2043       UReverse(isec, ipath) =  Sweep.UReversed();
2044       if (Sweep.ErrorOnSurface()>Error) Error = Sweep.ErrorOnSurface();
2045
2046       if ((ipath==1)&&(ExtendFirst>0)) {
2047         Handle(Geom_BoundedSurface) BndS;
2048         BndS = Handle(Geom_BoundedSurface)::DownCast(TabS(isec,ipath));
2049         GeomLib::ExtendSurfByLength(BndS, ExtendFirst, 1, 
2050                                     Sweep.ExchangeUV(), Standard_False);
2051         TabS(isec,ipath) = BndS;
2052       }
2053       if ((ipath==NbPath)&&(ExtendLast>0)){
2054         Handle(Geom_BoundedSurface) BndS;
2055         BndS = Handle(Geom_BoundedSurface)::DownCast(TabS(isec,ipath));
2056         GeomLib::ExtendSurfByLength(BndS, ExtendLast, 1, 
2057                                     Sweep.ExchangeUV(), Standard_True);
2058         TabS(isec,ipath) = BndS;
2059       }
2060
2061 #ifdef DRAW
2062       if (Affich) {
2063         sprintf(name,"Surf_%d_%d", isec, IPath);
2064         char* Temp = name ;
2065         DrawTrSurf::Set(Temp, TabS(isec,ipath));
2066       }
2067 #endif
2068     }
2069   }
2070
2071   // (2) Construction of Edges
2072   Standard_Real UFirst, ULast, VFirst, VLast;
2073   Standard_Boolean exuv, singu, singv;
2074   Handle(Geom_Surface) S;
2075
2076   // (2.0) return preexisting Edges and vertices
2077   TopoDS_Edge E;
2078   TColStd_Array1OfBoolean IsBuilt(1, NbLaw);
2079   IsBuilt.Init(Standard_False);
2080   TopTools_Array1OfShape StartEdges(1, NbLaw);
2081   if (! FirstShape.IsNull() && (IFirst==1)) {
2082     mySec->Init(FirstShape);
2083     for (isec=1; isec<=NbLaw; isec++) {
2084       E = mySec->CurrentEdge();
2085       TopoDS_Vertex Vfirst, Vlast;
2086       TopExp::Vertices(E, Vfirst, Vlast);
2087       VEdge(isec, 1) = E;
2088       if (E.Orientation() == TopAbs_REVERSED)
2089         Vertex(isec+1, 1) = Vfirst; //TopExp::FirstVertex(E);
2090       else 
2091         Vertex(isec+1, 1) = Vlast; //TopExp::LastVertex(E);
2092       UpdateVertex(IFirst-1, isec+1, 
2093                    TabErr(isec, 1), Vi(1),  Vertex(isec+1, 1));
2094
2095       StartEdges(isec) = E;
2096       if (Tapes.IsBound(E))
2097       {
2098         IsBuilt(isec) = Standard_True;
2099         
2100         //Initialize VEdge, UEdge, Vertex and myFaces
2101         Standard_Integer j;
2102         for (j = 1; j <= NbPath+1; j++)
2103         {
2104           VEdge(isec, j) = Tapes(E)->Value(1, j);
2105           VEdge(isec, j).Reverse(); //direction of round is reversed
2106         }
2107         Standard_Integer ifirst = isec+1, ilast = isec; //direction of round is reversed
2108         for (j = 1; j <= NbPath; j++)
2109           UEdge(ifirst, j) = Tapes(E)->Value(2, j);
2110         for (j = 1; j <= NbPath; j++)
2111           UEdge(ilast, j) = Tapes(E)->Value(3, j);
2112         for (j = 1; j <= NbPath+1; j++)
2113           Vertex(ifirst, j) = Tapes(E)->Value(4, j);
2114         for (j = 1; j <= NbPath+1; j++)
2115           Vertex(ilast, j) = Tapes(E)->Value(5, j);
2116         for (j = 1; j <= NbPath; j++)
2117           myFaces->SetValue(isec, j, Tapes(E)->Value(6, j));
2118
2119         if (uclose && isec == 1)
2120         {
2121           for (j = 1; j <= NbPath; j++)
2122             UEdge(NbLaw+1, j) = UEdge(1, j);
2123           for (j = 1; j <= NbPath+1; j++)
2124             Vertex(NbLaw+1, j) = Vertex(1, j);
2125         }
2126         if (uclose && isec == NbLaw)
2127         {
2128           for (j = 1; j <= NbPath; j++)
2129             UEdge(1, j) = UEdge(NbLaw+1, j);
2130           for (j = 1; j <= NbPath+1; j++)
2131             Vertex(1, j) = Vertex(NbLaw+1, j);
2132         }
2133       }
2134       else
2135       {
2136         Handle(TopTools_HArray2OfShape) EmptyArray = new TopTools_HArray2OfShape(1, 6, 1, NbPath+1);
2137         Tapes.Bind(E, EmptyArray);
2138         Standard_Integer j;
2139         if (Rails.IsBound(Vfirst))
2140         {
2141           Standard_Integer ind = (E.Orientation() == TopAbs_REVERSED)? isec+1 : isec;
2142           for (j = 1; j <= NbPath; j++)
2143             UEdge(ind, j) = Rails(Vfirst)->Value(1, j);
2144           for (j = 1; j <= NbPath+1; j++)
2145             Vertex(ind, j) = Rails(Vfirst)->Value(2, j);
2146         }
2147         if (Rails.IsBound(Vlast))
2148         {
2149           Standard_Integer ind = (E.Orientation() == TopAbs_FORWARD)? isec+1 : isec;
2150           for (j = 1; j <= NbPath; j++)
2151             UEdge(ind, j) = Rails(Vlast)->Value(1, j);
2152           for (j = 1; j <= NbPath+1; j++)
2153             Vertex(ind, j) = Rails(Vlast)->Value(2, j);
2154         }
2155       }
2156     }
2157     
2158     if (VEdge(1, 1).Orientation() == TopAbs_REVERSED)
2159       Vertex(1, 1) =  TopExp::LastVertex(TopoDS::Edge(VEdge(1, 1)));
2160     else
2161       Vertex(1, 1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(1, 1)));
2162     UpdateVertex(IFirst-1, 1, 
2163                  TabErr(1, 1), Vi(1),  Vertex(1, 1));
2164   }
2165   
2166   Standard_Real u, v, aux;
2167   Standard_Boolean ureverse;
2168   for (isec=1; isec<=NbLaw+1; isec++) {
2169     // Return data
2170     if (isec >NbLaw) {
2171       S = TabS(NbLaw, 1);
2172       ureverse = UReverse(NbLaw, 1);
2173       exuv = ExchUV(NbLaw, 1);
2174     }
2175     else {
2176       S = TabS(isec, 1);
2177       ureverse = UReverse(isec, 1);
2178       exuv = ExchUV(isec, 1);
2179     }
2180     S->Bounds(UFirst, ULast, VFirst, VLast);
2181     
2182     // Choice of parameters
2183     if (ureverse) {
2184       if (exuv) {
2185         aux = VFirst; VFirst = VLast; VLast = aux;        
2186       }
2187       else {
2188         aux = UFirst; UFirst = ULast; ULast = aux;
2189       }
2190     }
2191     if (isec!= NbLaw+1) {
2192       u = UFirst;
2193       v = VFirst;
2194     }
2195     else {
2196       if (exuv) {
2197         u = UFirst;
2198         v = VLast;
2199       }
2200       else {
2201         u = ULast;
2202         v = VFirst;
2203       }
2204     }
2205     
2206     // construction of vertices
2207     if (Vertex(isec, 1).IsNull())
2208       B.MakeVertex(TopoDS::Vertex(Vertex(isec, 1)), 
2209                    S->Value(u,v), 
2210                    mySec->VertexTol(isec-1,Vi(1)));
2211     else
2212     {
2213       TopLoc_Location Identity;
2214       Vertex(isec, 1).Location(Identity);
2215       B.UpdateVertex(TopoDS::Vertex(Vertex(isec, 1)),
2216                      S->Value(u,v), 
2217                        mySec->VertexTol(isec-1,Vi(1)));
2218     }
2219   } //end of for (isec=1; isec<=NbLaw+1; isec++)
2220   
2221   if (! LastShape.IsNull() && (ILast==myLoc->NbLaw()+1) ) {
2222     mySec->Init(LastShape);
2223     for (isec=1; isec<=NbLaw; isec++) {
2224       E = mySec->CurrentEdge();
2225       if (VEdge(isec, NbPath+1).IsNull())
2226         VEdge(isec, NbPath+1) = E;
2227
2228       if (Vertex(isec+1, NbPath+1).IsNull())
2229       {
2230         if (VEdge(isec, NbPath+1).Orientation() == TopAbs_REVERSED)
2231           Vertex(isec+1, NbPath+1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(isec, NbPath+1)));
2232         else 
2233           Vertex(isec+1, NbPath+1) = TopExp::LastVertex(TopoDS::Edge(VEdge(isec, NbPath+1)));
2234       }
2235       UpdateVertex(ILast-1, isec+1, TabErr(isec, NbPath), 
2236                    Vi(NbPath+1),  Vertex(isec+1, NbPath+1));
2237     }
2238
2239     if (Vertex(1,  NbPath+1).IsNull())
2240     {
2241       if (VEdge(1,  NbPath+1).Orientation() == TopAbs_REVERSED)
2242         Vertex(1,  NbPath+1) = TopExp::LastVertex(TopoDS::Edge(VEdge(1,  NbPath+1)));
2243       else
2244         Vertex(1,  NbPath+1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(1, NbPath+1)));
2245     }
2246     UpdateVertex(ILast-1, 1, 
2247                  TabErr(1, NbPath), Vi(NbPath+1),  Vertex(1, NbPath+1 ));
2248   }
2249   
2250   for (isec=1; isec<=NbLaw+1; isec++) {
2251     // Return data
2252     if (isec >NbLaw) {
2253         S = TabS(NbLaw, NbPath);
2254         ureverse = UReverse(NbLaw, NbPath);
2255         exuv = ExchUV(NbLaw, NbPath);
2256     }
2257     else {
2258       S = TabS(isec, NbPath);
2259       ureverse = UReverse(isec, NbPath);
2260       exuv = ExchUV(isec, NbPath);
2261     }
2262     S->Bounds(UFirst, ULast, VFirst, VLast);
2263     
2264     // Choice of parametres
2265     if (ureverse) {
2266       if (exuv) {
2267         aux = VFirst; VFirst = VLast; VLast = aux;        
2268       }
2269       else {
2270         aux = UFirst; UFirst = ULast; ULast = aux;
2271       }
2272     }
2273     if (isec == NbLaw+1) {
2274       u = ULast;
2275       v = VLast;
2276     }
2277     else {
2278       if (exuv) {
2279         u = ULast;
2280         v = VFirst;
2281       }
2282       else {
2283         u = UFirst;
2284         v = VLast;
2285       }
2286     }
2287     
2288     // construction of vertex
2289     if (Vertex(isec, NbPath+1).IsNull())
2290       B.MakeVertex(TopoDS::Vertex(Vertex(isec, NbPath+1)), 
2291                    S->Value(u,v), 
2292                    mySec->VertexTol(isec-1, Vi(NbPath+1)));
2293       else
2294       {
2295         TopLoc_Location Identity;
2296         Vertex(isec, NbPath+1).Location(Identity);
2297         B.UpdateVertex(TopoDS::Vertex(Vertex(isec, NbPath+1)), 
2298                        S->Value(u,v), 
2299                        mySec->VertexTol(isec-1, Vi(NbPath+1)));
2300       }
2301   } //end of for (isec=1; isec<=NbLaw+1; isec++)
2302
2303  
2304   // ---------- Creation of Vertex and edge ------------
2305   ReversedEdges.Clear();
2306   for (ipath=1, IPath=IFirst; ipath<=NbPath; 
2307        ipath++, IPath++) {
2308     for (isec=1; isec <=NbLaw; isec++) {
2309       if (IsBuilt(isec))
2310         continue;
2311       
2312       S = TabS(isec, ipath);
2313       exuv = ExchUV(isec, ipath);
2314       S->Bounds(UFirst, ULast, VFirst, VLast);
2315       if (UReverse(isec, ipath)) {
2316         Standard_Real aux;
2317         if (exuv) {
2318           aux = VFirst; VFirst = VLast; VLast = aux;      
2319         }
2320         else {
2321           aux = UFirst; UFirst = ULast; ULast = aux;
2322         }
2323       }
2324
2325       // (2.1) Construction of new vertices
2326       if (isec == 1) {
2327         if (ipath == 1 && Vertex(1, 1).IsNull()) {
2328           // All first
2329           if (constSection)
2330             myLoc->PerformVertex(IPath-1, 
2331                                  TopoDS::Vertex(SecVertex(1)), 
2332                                  VError(1),
2333                                  TopoDS::Vertex(Vertex(1, 1)));
2334           else
2335             myLoc->PerformVertex(IPath-1, 
2336                                  mySec->Vertex(1,Vi(1)), 
2337                                  mySec->VertexTol(0,Vi(1)),
2338                                  TopoDS::Vertex(Vertex(1, 1)));
2339         }
2340         // the first and the next column
2341         if (vclose &&(ipath == NbPath) ) {
2342           Vertex(1, ipath+1) =  Vertex(1, 1);
2343         }
2344         else if (Vertex(1, ipath+1).IsNull()) {
2345           if (constSection)
2346             myLoc->PerformVertex(IPath, 
2347                                  TopoDS::Vertex(SecVertex(1)),
2348                                  TabErr(1,ipath)+VError(1),
2349                                  TopoDS::Vertex(Vertex(1, ipath+1)) );
2350           else
2351             myLoc->PerformVertex(IPath, 
2352                                  mySec->Vertex(1,Vi(ipath+1)), 
2353                                  TabErr(1,ipath) +
2354                                  mySec->VertexTol(0,Vi(ipath+1)),
2355                                  TopoDS::Vertex(Vertex(1, ipath+1)));
2356
2357           if (MergeVertex(Vertex(1,ipath), Vertex(1,ipath+1))) {
2358             UEdge(1, ipath) = NullEdge(Vertex(1,ipath));
2359           }
2360          }
2361        }
2362
2363       if (ipath == 1) {
2364         if (uclose && (isec == NbLaw)) {
2365           Vertex(isec+1, 1) =  Vertex(1, 1);
2366         }  
2367         else if (Vertex(isec+1, 1).IsNull()) {
2368           if (constSection)
2369             myLoc->PerformVertex(IPath-1, 
2370                TopoDS::Vertex(SecVertex(isec+1)),
2371                TabErr(isec,1)+VError(isec+1),
2372                TopoDS::Vertex(Vertex(isec+1, 1)) );
2373           else
2374             myLoc->PerformVertex(IPath-1, 
2375                mySec->Vertex(isec+1,Vi(1)), 
2376                TabErr(isec,1) +
2377                mySec->VertexTol(isec,Vi(1)),
2378                TopoDS::Vertex(Vertex(isec+1, 1)) );
2379                                             
2380           if (MergeVertex(Vertex(isec,1), Vertex(isec+1,1))) {
2381             VEdge(isec, 1) = NullEdge(Vertex(isec, 1)); 
2382           }
2383         }
2384       }
2385
2386       if (uclose && (isec == NbLaw)) {
2387         Vertex(isec+1, ipath+1) = Vertex(1, ipath+1);
2388       }
2389       else if (vclose && (ipath == NbPath)) {
2390         Vertex(isec+1, ipath+1) =  Vertex(isec+1, 1);
2391       }
2392       else if (Vertex(isec+1, ipath+1).IsNull()) {
2393         if (constSection)
2394           myLoc->PerformVertex(IPath, 
2395                                TopoDS::Vertex(SecVertex(isec+1)),
2396                                TabErr(isec, ipath)+ VError(isec+1),
2397                                TopoDS::Vertex(Vertex(isec+1, ipath+1)) );
2398         else
2399          myLoc->PerformVertex(IPath, 
2400                               mySec->Vertex(isec+1,Vi(ipath+1)),
2401                               TabErr(isec, ipath) + 
2402                               mySec->VertexTol(isec, Vi(ipath+1)),
2403                               TopoDS::Vertex(Vertex(isec+1, ipath+1)) ); 
2404       }
2405
2406       // Singular cases
2407       singv = MergeVertex(Vertex(isec,ipath+1), Vertex(isec+1,ipath+1));
2408       singu = MergeVertex(Vertex(isec+1,ipath), Vertex(isec+1,ipath+1));
2409
2410       
2411
2412       if (singu || singv) {
2413         Degenerated(isec, ipath) = IsDegen(TabS(isec,ipath), 
2414                                            Max(myTol3d, TabErr(isec,ipath)));
2415       }
2416       if (Degenerated(isec, ipath)) { 
2417 #ifdef OCCT_DEBUG
2418         cout << "Sweep : Degenerated case" << endl;
2419 #endif
2420         hasdegen = Standard_True;
2421         // Particular construction of edges
2422         if (UEdge(isec+1, ipath).IsNull()) {
2423           if (singu) {
2424             // Degenerated edge
2425             UEdge(isec+1, ipath) = NullEdge(Vertex(isec+1,ipath));
2426           }
2427           else { // Copy the previous edge
2428             UEdge(isec+1, ipath) = UEdge(isec, ipath);
2429           }
2430         }
2431         if (VEdge(isec, ipath+1).IsNull()) {
2432           if (singv) {
2433             // Degenerated Edge
2434             VEdge(isec, ipath+1) = NullEdge(Vertex(isec,ipath+1));
2435           }
2436           else { // Copy the previous edge
2437             VEdge(isec, ipath+1) = VEdge(isec, ipath);
2438           }
2439         }
2440       }
2441       else { // Construction of edges by isos
2442         if (exuv) {
2443           Standard_Real UV;
2444           UV = UFirst; UFirst = VFirst; VFirst = UV;
2445           UV = ULast ; ULast = VLast  ; VLast = UV;
2446         }
2447   
2448         // (2.2) Iso-u
2449         if (isec == 1 && UEdge(1, ipath).IsNull()) {
2450           if (!Vertex(1,ipath).IsSame(Vertex(1,ipath+1))) {
2451             gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(Vertex(1,ipath)));
2452             gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(Vertex(1,ipath+1)));
2453             if (P1.Distance(P2) <= myTol3d)
2454               Vertex(1,ipath+1) = Vertex(1,ipath);
2455           }
2456           UEdge(1, ipath) = BuildEdge(S, !exuv, UFirst, 
2457                                       Vertex(1,ipath), 
2458                                       Vertex(1,ipath+1),
2459                                       myTol3d);
2460         }
2461         else
2462         {
2463           if (UEdge(isec, ipath).IsNull()) //sweep failed
2464             return Standard_False;
2465           UpdateEdge(TopoDS::Edge(UEdge(isec, ipath)), 
2466                      S, !exuv, UFirst);
2467         }
2468      
2469         if (uclose && (isec==NbLaw)) {
2470           if (UEdge(1, ipath).IsNull()) //degenerated case
2471           {
2472             UEdge(isec+1, ipath) = BuildEdge(S, !exuv, ULast, 
2473                                              Vertex(isec+1, ipath), 
2474                                              Vertex(isec+1, ipath+1),
2475                                              myTol3d);
2476           }
2477           else {
2478             UpdateEdge(TopoDS::Edge(UEdge(1, ipath)), 
2479                        S, !exuv, ULast);
2480             UEdge(isec+1, ipath) = UEdge(1, ipath);
2481           }
2482         }
2483         else {
2484           if (UEdge(isec+1, ipath).IsNull())
2485             UEdge(isec+1, ipath) = BuildEdge(S, !exuv, ULast, 
2486                                              Vertex(isec+1, ipath), 
2487                                              Vertex(isec+1, ipath+1),
2488                                              myTol3d);
2489           else
2490             UpdateEdge(TopoDS::Edge(UEdge(isec+1, ipath)), S, !exuv, ULast);
2491         }
2492
2493         // (2.3) Iso-v 
2494         if (ipath == 1)
2495         {
2496           TopoDS_Edge aNewFirstEdge = BuildEdge(S, exuv, VFirst, 
2497                                                 Vertex(isec  , 1), 
2498                                                 Vertex(isec+1, 1),
2499                                                 myTol3d);
2500           if (VEdge(isec, ipath).IsNull())
2501             VEdge(isec, ipath) = aNewFirstEdge;
2502           else //rebuild first edge
2503           {
2504             RebuildTopOrBottomEdge(aNewFirstEdge,
2505                                    TopoDS::Edge(VEdge(isec, ipath)),
2506                                    ReversedEdges);
2507             if (ReversedEdges.Contains(VEdge(isec, ipath)))
2508               StartEdges(isec).Reverse();
2509           }
2510         }
2511         
2512         else UpdateEdge(TopoDS::Edge(VEdge(isec, ipath)), 
2513                         S, exuv, VFirst);
2514         
2515         if (vclose && (ipath == NbPath)) {
2516           if (VEdge(isec, 1).IsNull()) //degenerated case
2517           {
2518             VEdge(isec, ipath+1) = BuildEdge(S, exuv, VLast, 
2519                                              Vertex(isec  , ipath+1), 
2520                                              Vertex(isec+1, ipath+1),
2521                                              myTol3d);
2522           }
2523           else {
2524             UpdateEdge(TopoDS::Edge(VEdge(isec, 1)), 
2525                        S, exuv, VLast);
2526             VEdge(isec, ipath+1) = VEdge(isec, 1);
2527           }
2528         }
2529         else if (VEdge(isec, ipath+1).IsNull())
2530           VEdge(isec, ipath+1) = BuildEdge(S, exuv, VLast, 
2531                                            Vertex(isec  , ipath+1), 
2532                                            Vertex(isec+1, ipath+1),
2533                                            myTol3d);
2534         else
2535         {
2536           if (ipath != NbPath || vclose)
2537             UpdateEdge(TopoDS::Edge(VEdge(isec, ipath+1)), 
2538                        S, exuv, VLast);
2539           else //ipath == NbPath && !vclose => rebuild last edge
2540           {
2541             TopoDS_Edge aNewLastEdge = BuildEdge(S, exuv, VLast, 
2542                                                  Vertex(isec  , ipath+1), 
2543                                                  Vertex(isec+1, ipath+1),
2544                                                  myTol3d);
2545             RebuildTopOrBottomEdge(aNewLastEdge,
2546                                    TopoDS::Edge(VEdge(isec, ipath+1)),
2547                                    ReversedEdges);
2548           }
2549         }
2550       }
2551     }// End of construction of edges
2552   }
2553
2554   // (3) Construction of Faces
2555   TopoDS_Face face;
2556
2557 #ifdef DRAW
2558   if (Affich) {
2559     for (ipath=1, IPath=IFirst; ipath<=NbPath; ipath++, IPath++) {
2560       for (isec=1; isec <=NbLaw+1; isec++){
2561         sprintf(name,"uedge_%d_%d", isec, IPath);
2562         DBRep::Set(name,UEdge(isec, ipath));
2563       }
2564     }
2565
2566     for (ipath=1, IPath=IFirst; ipath<=NbPath+1; ipath++, IPath++) {
2567       for (isec=1; isec <=NbLaw; isec++){
2568         sprintf(name,"vedge_%d_%d", isec, IPath);
2569         DBRep::Set(name,VEdge(isec, ipath));
2570       }
2571
2572       for (isec=1; isec <=NbLaw+1; isec++){
2573         sprintf(name,"vertex_%d_%d", isec, IPath);
2574         DBRep::Set(name,Vertex(isec, ipath));
2575       }
2576     }
2577   }
2578 #endif 
2579
2580   for (ipath=1, IPath=IFirst; ipath<=NbPath; ipath++, IPath++) {
2581     for (isec=1; isec <=NbLaw; isec++) {
2582       if (Degenerated(isec, ipath)) {
2583         if (UEdge(isec, ipath).IsSame(UEdge(isec+1, ipath))) 
2584           myFaces->SetValue(isec, IPath, UEdge(isec, ipath));
2585         else  
2586           myFaces->SetValue(isec, IPath, VEdge(isec, ipath));
2587       }
2588       else if (myFaces->Value(isec, IPath).IsNull()) {
2589         BuildFace(TabS(isec,ipath), 
2590                   TopoDS::Edge(UEdge(isec, ipath)),
2591                   TopoDS::Edge(VEdge(isec, ipath)),
2592                   TopoDS::Edge(UEdge(isec+1, ipath)),
2593                   TopoDS::Edge(VEdge(isec, ipath+1)),
2594                   myVEdgesModified,
2595                   ExchUV(isec, ipath),
2596                   UReverse(isec, ipath),
2597                   face);
2598         myFaces->SetValue(isec, IPath, face);
2599       }
2600     }
2601   }
2602
2603   // (3.1) Reverse the faces that have been built ealier
2604   for (ipath = 1; ipath <= NbPath; ipath++)
2605     for (isec = 1; isec <= NbLaw; isec++)
2606       if (IsBuilt(isec))
2607         myFaces->ChangeValue(isec, ipath).Reverse();
2608   
2609
2610   // (4) History and Continuity 
2611
2612   if (hasdegen) {
2613   //(4.1) // Degenerated case => Sledgehammer
2614     TopoDS_Compound Comp;
2615     B.MakeCompound(Comp);
2616     for (isec=1; isec <=  NbLaw+1; isec++) 
2617       for (ipath=1, IPath=IFirst; ipath<=  NbPath+1; ipath++, IPath++) {
2618       if (ipath <= NbPath) myUEdges->SetValue(isec, IPath, UEdge(isec, ipath));
2619       if (isec <= NbLaw) myVEdges->SetValue(isec, IPath, VEdge(isec, ipath)); 
2620       if ((ipath <= NbPath) && (isec <= NbLaw) && 
2621           (myFaces->Value(isec, IPath).ShapeType() == TopAbs_FACE))
2622         B.Add(Comp, myFaces->Value(isec, IPath));
2623     }
2624     BRepLib::EncodeRegularity(Comp, myTolAngular);
2625   }
2626   else {
2627     //(4.2) // General case => Tweezers 
2628     Standard_Boolean isG1;
2629     TopoDS_Face FF;
2630     TopoDS_Edge E;
2631  
2632     for (isec=1; isec <=  NbLaw+1; isec++) {
2633       if (isec>1) isG1 = 
2634         (mySec->Continuity(isec-1, myTolAngular) >= GeomAbs_G1);
2635       else isG1 = Standard_False;
2636       for (ipath=1, IPath=IFirst; ipath<=  NbPath; ipath++, IPath++) {
2637         myUEdges->SetValue(isec, IPath, UEdge(isec, ipath));
2638         if (isG1) {
2639           if (isec == NbLaw+1) FF = TopoDS::Face(myFaces->Value(1, IPath));
2640           else  FF = TopoDS::Face(myFaces->Value(isec, IPath));
2641           B.Continuity(TopoDS::Edge(myUEdges->Value(isec, IPath)),
2642                        TopoDS::Face(myFaces->Value(isec-1, IPath)), 
2643                        FF, GeomAbs_G1);
2644         }
2645       }
2646     }
2647
2648     Standard_Integer nbpath = NbPath;
2649     if (vclose) nbpath++; //Another test G1 
2650     for (ipath=1, IPath=IFirst; ipath<=  NbPath+1; ipath++, IPath++) {
2651       if ((ipath > 1) && (ipath <=nbpath)) 
2652         isG1 = (myLoc->IsG1(IPath-1, myTol3d, myTolAngular) >= 0);
2653       else isG1 = Standard_False;
2654       for (isec=1; isec <=  NbLaw; isec++) {
2655         myVEdges->SetValue(isec, IPath, VEdge(isec, ipath));
2656         if (isG1) { 
2657           if (ipath==NbPath+1) FF = TopoDS::Face(myFaces->Value(isec, 1));
2658           else  FF = TopoDS::Face(myFaces->Value(isec, IPath));
2659           E = TopoDS::Edge(myVEdges->Value(isec, IPath));
2660           BRepLib::EncodeRegularity(E, FF,
2661                                     TopoDS::Face(myFaces->Value(isec, IPath-1)),
2662                                     myTolAngular);
2663         }
2664       } 
2665     }
2666   }
2667
2668   // (5) Update Tapes and Rails
2669   Standard_Integer j;
2670   if (IFirst == 1 && !Tapes.IsEmpty()) //works only in case of single shell
2671   {
2672     for (isec = 1; isec <= NbLaw; isec++)
2673     {
2674       for (j = 1; j <= NbPath+1; j++)
2675         Tapes(StartEdges(isec))->SetValue(1, j, myVEdges->Value(isec, j));
2676       for (j = 1; j <= NbPath; j++)
2677         Tapes(StartEdges(isec))->SetValue(2, j, myUEdges->Value(isec, j));
2678       for (j = 1; j <= NbPath; j++)
2679         Tapes(StartEdges(isec))->SetValue(3, j, myUEdges->Value(isec+1, j));
2680       for (j = 1; j <= NbPath+1; j++)
2681         Tapes(StartEdges(isec))->SetValue(4, j, Vertex(isec, j));
2682       for (j = 1; j <= NbPath+1; j++)
2683         Tapes(StartEdges(isec))->SetValue(5, j, Vertex(isec+1, j));
2684       for (j = 1; j <= NbPath; j++)
2685         Tapes(StartEdges(isec))->SetValue(6, j, myFaces->Value(isec, j));
2686       TopoDS_Vertex Vfirst, Vlast;
2687       TopExp::Vertices(TopoDS::Edge(StartEdges(isec)), Vfirst, Vlast, Standard_True); //with orientation
2688       if (!Rails.IsBound(Vfirst))
2689       {
2690         Handle(TopTools_HArray2OfShape) anArray = new TopTools_HArray2OfShape(1, 2, 1, NbPath+1);
2691         for (j = 1; j <= NbPath; j++)
2692           anArray->SetValue(1, j, myUEdges->Value(isec, j));
2693         for (j = 1; j <= NbPath+1; j++)
2694           anArray->SetValue(2, j, Vertex(isec, j));
2695         Rails.Bind(Vfirst, anArray);
2696       }
2697       if (!Rails.IsBound(Vlast))
2698       {
2699         Handle(TopTools_HArray2OfShape) anArray = new TopTools_HArray2OfShape(1, 2, 1, NbPath+1);
2700         for (j = 1; j <= NbPath; j++)
2701           anArray->SetValue(1, j, myUEdges->Value(isec+1, j));
2702         for (j = 1; j <= NbPath+1; j++)
2703           anArray->SetValue(2, j, Vertex(isec+1, j));
2704         Rails.Bind(Vlast, anArray);
2705       }
2706     }
2707   }
2708   
2709   return Standard_True;
2710 }
2711
2712 //=======================================================================
2713 //function : Build
2714 //purpose  : Construt the result of sweeping
2715 //======================================================================
2716 void BRepFill_Sweep::Build(TopTools_MapOfShape& ReversedEdges,
2717                            BRepFill_DataMapOfShapeHArray2OfShape& Tapes,
2718                            BRepFill_DataMapOfShapeHArray2OfShape& Rails,
2719                            const BRepFill_TransitionStyle Transition,
2720                            const GeomAbs_Shape Continuity,
2721                            const GeomFill_ApproxStyle Approx,
2722                            const Standard_Integer Degmax,
2723                            const Standard_Integer Segmax) 
2724 {
2725   myContinuity  = Continuity;
2726   myApproxStyle = Approx;
2727   myDegmax = Degmax;
2728   mySegmax = Segmax;
2729
2730   CorrectApproxParameters();
2731
2732   // Wire
2733   if (mySec->IsVertex()) isDone = BuildWire(Transition);
2734
2735   else { // Shell   
2736     Standard_Integer NbTrous = myLoc->NbHoles(myTol3d),
2737                      NbPath   = myLoc->NbLaw(),
2738                      NbLaw    = mySec->NbLaw(), ii, jj, NbPart=1;
2739     Standard_Integer ipath, isec;
2740     BRep_Builder B;
2741     myUEdges = new (TopTools_HArray2OfShape) (1, NbLaw+1, 1, NbPath);
2742     myVEdges = new (TopTools_HArray2OfShape) (1, NbLaw, 1, NbPath+1); 
2743     myFaces = new (TopTools_HArray2OfShape) (1, NbLaw, 1, NbPath);
2744     Handle (TopTools_HArray2OfShape) Bounds =  
2745       new (TopTools_HArray2OfShape) (1, NbLaw, 1, 2);
2746  
2747     Handle(TColStd_HArray1OfInteger) Trous;
2748  
2749     if (NbTrous>0) { // How many sub-parts ?
2750       Trous = new (TColStd_HArray1OfInteger) (1, NbTrous);
2751       myLoc->Holes(Trous->ChangeArray1());
2752       NbPart += NbTrous;
2753       if (Trous->Value(NbTrous) == NbPath+1) NbPart--;  
2754     }
2755     if (NbPart == 1)  { // This is done at once
2756       Standard_Real Extend = 0.0;
2757       if (NbTrous==1)  Extend = EvalExtrapol(1, Transition);
2758       isDone = BuildShell(Transition, 
2759                           1, NbPath+1,
2760                           ReversedEdges,
2761                           Tapes, Rails,
2762                           Extend, Extend);
2763     }
2764     else { //  This is done piece by piece
2765       Standard_Integer IFirst = 1, ILast;
2766       for (ii=1, isDone=Standard_True; 
2767            ii<=NbPart && isDone; ii++) {
2768         if (ii > NbTrous) ILast =  NbPath+1;
2769         else ILast = Trous->Value(ii);
2770         isDone = BuildShell(Transition, 
2771                             IFirst, ILast,
2772                             ReversedEdges,
2773                             Tapes, Rails,
2774                             EvalExtrapol(IFirst, Transition),
2775                             EvalExtrapol(ILast,  Transition));
2776         if (IFirst>1) {
2777           Translate(myVEdges, IFirst, Bounds, 2);
2778           PerformCorner(IFirst, 
2779                         Transition, Bounds);
2780         }
2781         IFirst = ILast;
2782         Translate(myVEdges, IFirst, Bounds, 1);
2783       }
2784     }
2785     // Management of looping ends
2786     if ( (NbTrous>0) && (myLoc->IsClosed()) &&
2787          (Trous->Value(NbTrous) == NbPath+1) ) {
2788       Translate(myVEdges,  NbPath+1, Bounds, 1);
2789       Translate(myVEdges,  1, Bounds, 2);
2790       PerformCorner(1, Transition, Bounds); 
2791     }
2792
2793     // Construction of the shell
2794     TopoDS_Shell shell;
2795     B.MakeShell(shell);
2796     for (ipath=1; ipath<=NbPath; ipath++) 
2797       for (isec=1; isec <=NbLaw; isec++) {
2798       const TopoDS_Shape& face = myFaces->Value(isec, ipath);
2799         if (!face.IsNull() && 
2800             (face.ShapeType() == TopAbs_FACE) ) B.Add(shell, face);
2801       }
2802
2803     TopTools_ListIteratorOfListOfShape It(myAuxShape);
2804     for (; It.More(); It.Next()) {
2805        const TopoDS_Shape& face = It.Value();
2806        if (!face.IsNull() && 
2807             (face.ShapeType() == TopAbs_FACE) ) B.Add(shell, face);
2808     }
2809     //Set common Uedges to faces
2810     BRepTools_Substitution aSubstitute;
2811     /*
2812     for (ii = 1; ii <= NbLaw; ii++)
2813       for (jj = 1; jj <= NbPath; jj++)
2814         {
2815           SetCommonEdgeInFace(aSubstitute,
2816                               myFaces->Value(ii, jj),
2817                               myUEdges->Value(ii, jj));
2818           SetCommonEdgeInFace(aSubstitute,
2819                               myFaces->Value(ii, jj),
2820                               myUEdges->Value(ii+1, jj));
2821         }
2822     if (mySec->IsUClosed())
2823       for (jj = 1; jj <= NbPath; jj++)
2824         SetCommonEdgeInFace(aSubstitute,
2825                             myFaces->Value( 1, jj ),
2826                             myUEdges->Value( NbLaw+1, jj));
2827     */
2828     TopTools_DataMapIteratorOfDataMapOfShapeShape mapit( myVEdgesModified );
2829     for (; mapit.More(); mapit.Next())
2830       {
2831         const TopoDS_Edge& OldEdge = TopoDS::Edge(mapit.Key());
2832         const TopoDS_Edge& NewEdge = TopoDS::Edge(mapit.Value());
2833         Substitute( aSubstitute, OldEdge, NewEdge );
2834       }
2835     aSubstitute.Build( shell );
2836     if (aSubstitute.IsCopied( shell )) {
2837       const TopTools_ListOfShape& listSh = aSubstitute.Copy( shell );
2838       shell = TopoDS::Shell( listSh.First() );
2839     }
2840
2841     for (ii = myFaces->LowerRow(); ii <= myFaces->UpperRow(); ii++) {
2842       for (jj = myFaces->LowerCol(); jj <= myFaces->UpperCol(); jj++) {
2843         const TopoDS_Shape& aLocalShape = myFaces->Value(ii, jj);
2844
2845         if(!aLocalShape.IsNull() && aSubstitute.IsCopied(aLocalShape)) {
2846           const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
2847
2848           if(!aList.IsEmpty())
2849             myFaces->ChangeValue(ii, jj) = aList.First();
2850         }
2851       }
2852     }
2853
2854     for (ii = myVEdges->LowerRow(); ii <= myVEdges->UpperRow(); ii++) {
2855       for (jj = myVEdges->LowerCol(); jj <= myVEdges->UpperCol(); jj++) {
2856         const TopoDS_Shape& aLocalShape = myVEdges->Value(ii, jj);
2857
2858         if(!aLocalShape.IsNull() && aSubstitute.IsCopied(aLocalShape)) {
2859           const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
2860
2861           if(!aList.IsEmpty())
2862             myVEdges->ChangeValue(ii, jj) = aList.First();
2863         }
2864       }
2865     }
2866
2867     for (ii = myUEdges->LowerRow(); ii <= myUEdges->UpperRow(); ii++) {
2868       for (jj = myUEdges->LowerCol(); jj <= myUEdges->UpperCol(); jj++) {
2869         const TopoDS_Shape& aLocalShape = myUEdges->Value(ii, jj);
2870
2871         if(!aLocalShape.IsNull() && aSubstitute.IsCopied(aLocalShape)) {
2872           const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
2873
2874           if(!aList.IsEmpty())
2875             myUEdges->ChangeValue(ii, jj) = aList.First();
2876         }
2877       }
2878     }
2879
2880     // Is it Closed ?
2881     if (myLoc->IsClosed() && mySec->IsUClosed()) {
2882       //Check
2883       Standard_Boolean closed = Standard_True;
2884       Standard_Integer iedge;
2885       TopTools_IndexedDataMapOfShapeListOfShape EFmap;
2886       TopExp::MapShapesAndAncestors(shell, TopAbs_EDGE, 
2887                                     TopAbs_FACE, EFmap);
2888       
2889       for (iedge = 1; iedge <=EFmap.Extent() && closed; iedge++) {
2890         const TopoDS_Edge& theEdge = TopoDS::Edge(EFmap.FindKey(iedge));
2891         if (BRep_Tool::Degenerated(theEdge)) continue;
2892         closed = (  EFmap(iedge).Extent() > 1);
2893       }
2894       shell.Closed(closed);
2895     }
2896     myShape = shell;
2897   }
2898 }
2899
2900
2901 //=======================================================================
2902 //function : IsDone
2903 //purpose  : 
2904 //=======================================================================
2905  Standard_Boolean BRepFill_Sweep::IsDone() const
2906 {
2907   return isDone;
2908 }
2909
2910 //=======================================================================
2911 //function : Shape
2912 //purpose  : 
2913 //=======================================================================
2914  TopoDS_Shape BRepFill_Sweep::Shape() const
2915 {
2916   return myShape;
2917 }
2918
2919 //=======================================================================
2920 //function : ErrorOnSurface
2921 //purpose  : 
2922 //=======================================================================
2923  Standard_Real BRepFill_Sweep::ErrorOnSurface() const
2924 {
2925   return Error;
2926 }
2927
2928 //=======================================================================
2929 //function : SubShape
2930 //purpose  : Faces obtained by sweeping
2931 //=======================================================================
2932  Handle(TopTools_HArray2OfShape) BRepFill_Sweep::SubShape() const
2933 {
2934   return myFaces;
2935 }
2936
2937 //=======================================================================
2938 //function : InterFaces
2939 //purpose  : Edges obtained by sweeping
2940 //=======================================================================
2941  Handle(TopTools_HArray2OfShape) BRepFill_Sweep::InterFaces() const
2942 {
2943   return myUEdges;
2944 }
2945
2946 //=======================================================================
2947 //function : Sections
2948 //purpose  : Edges or Face (or compound of 2) Transition between 2 sweepings
2949 //=======================================================================
2950  Handle(TopTools_HArray2OfShape) BRepFill_Sweep::Sections() const
2951 {
2952   return myVEdges;
2953 }
2954
2955 //=======================================================================
2956 //function : PerformCorner
2957 //purpose  : Trim and/or loop a corner
2958 //======================================================================
2959  void  BRepFill_Sweep::PerformCorner(const Standard_Integer Index,
2960                                      const BRepFill_TransitionStyle Transition,
2961                                      const Handle(TopTools_HArray2OfShape)& Bounds)
2962 {
2963
2964   if (Transition == BRepFill_Modified) return; // Do nothing.
2965
2966   BRepFill_TransitionStyle TheTransition = Transition;
2967   Standard_Boolean isTangent=Standard_False;
2968   Standard_Real F, L;
2969   Standard_Integer I1, I2, ii; //, jj;
2970   gp_Pnt P1,P2;
2971   gp_Vec T1, T2, Tang, Sortant;
2972 //  gp_Mat M;
2973   //Handle(TopTools_HArray1OfShape) TheShape = 
2974     //new TopTools_HArray1OfShape( 1, mySec->NbLaw() );
2975 //  TopTools_ListIteratorOfListOfShape Iterator;
2976
2977   if (Index > 1) { 
2978     I1 = Index-1;
2979     I2 = Index;
2980   }
2981   else {
2982     I1 = myLoc->NbLaw();
2983     I2 = 1;
2984   }
2985
2986   // Construct an axis supported by the bissectrice
2987   myLoc->Law(I1)->GetDomain(F, L);
2988   myLoc->Law(I1)->GetCurve()->D1(L, P1, T1);
2989   T1.Normalize();
2990
2991   myLoc->Law(I2)->GetDomain(F, L);  
2992   myLoc->Law(I2)->GetCurve()->D1(F, P2, T2);
2993   T2.Normalize();
2994
2995   if (T1.Angle(T2) <  myAngMin) {
2996     isTangent = Standard_True;
2997     gp_Vec t1, t2, V;
2998     gp_Mat M;
2999     myLoc->Law(I1)->GetDomain(F, L);
3000     myLoc->Law(I1)->D0(L, M, V);
3001     t1 = M.Column(3);
3002     myLoc->Law(I2)->GetDomain(F, L);
3003     myLoc->Law(I2)->D0(L, M, V);
3004     t2 = M.Column(3);
3005
3006     if (t1.Angle(t2) < myAngMin) {
3007 #ifdef OCCT_DEBUG
3008       cout << "BRepFill_Sweep::PerformCorner : This is not a corner !" << endl;
3009 #endif
3010       return;
3011     }
3012     Sortant = t2 - t1;
3013   }
3014
3015   if ((TheTransition == BRepFill_Right) 
3016       && (T1.Angle(T2) >  myAngMax) ) {
3017     TheTransition =  BRepFill_Round;
3018   }
3019
3020   Tang = T1 + T2; //Average direction
3021   gp_Dir NormalOfBisPlane = Tang;
3022
3023   if (isTangent) {
3024     Sortant -= Tang.Dot(Tang)*Tang;
3025   }
3026   else {
3027     Sortant = T2-T1; //Direction input 
3028     Sortant *= -1; //   "   "   output
3029     Tang -= (Tang.Dot(T2))*T2;
3030   }
3031
3032   P1.BaryCenter(0.5, P2, 0.5);
3033   gp_Dir N(Sortant);
3034   gp_Dir Dx(Tang);
3035     
3036   gp_Ax2 Axe (P1, N, Dx);
3037   gp_Ax2 AxeOfBisPlane( P1, NormalOfBisPlane );
3038
3039   // Construct 2 intersecting Shells
3040   Handle (TopTools_HArray2OfShape) UEdges =
3041     new TopTools_HArray2OfShape( 1, mySec->NbLaw()+1, 1, myLoc->NbLaw() );
3042   UEdges->ChangeArray2() = myUEdges->Array2();
3043
3044 // modified by NIZHNY-MKK  Wed Oct 29 18:31:47 2003.BEGIN
3045   Handle (TopTools_HArray2OfShape) aFaces =
3046     new TopTools_HArray2OfShape(myFaces->LowerRow(), myFaces->UpperRow(), 1, 2);
3047   Translate(myFaces, I1, aFaces, 1);
3048   Translate(myFaces, I2, aFaces, 2);
3049
3050   Handle (TopTools_HArray2OfShape) aUEdges =
3051     new TopTools_HArray2OfShape(myUEdges->LowerRow(), myUEdges->UpperRow(), 1, 2);
3052   Translate(myUEdges, I1, aUEdges, 1);
3053   Translate(myUEdges, I2, aUEdges, 2);
3054
3055   gp_Vec aNormal = T2 + T1;
3056   TopoDS_Face aPlaneF;
3057
3058   if(aNormal.Magnitude() > gp::Resolution()) {
3059     gp_Pln pl(P1, gp_Dir(aNormal));
3060     BRepLib_MakeFace aFMaker(pl);
3061
3062     if(aFMaker.Error() == BRepLib_FaceDone) {
3063       aPlaneF = aFMaker.Face();
3064       BRep_Builder aBB;
3065       aBB.UpdateFace(aPlaneF, Precision::Confusion() * 10.);
3066     }
3067   }
3068
3069   BRepFill_TrimShellCorner aTrim(aFaces, AxeOfBisPlane, aPlaneF);
3070   aTrim.AddBounds(Bounds);
3071   aTrim.AddUEdges(aUEdges);
3072   aTrim.Perform();
3073
3074   if (aTrim.IsDone()) {
3075     TopTools_ListOfShape listmodif;
3076     Standard_Integer iit = 0;
3077
3078     for(iit = 0; iit < 2; iit++) {
3079       Standard_Integer II = (iit == 0) ? I1 : I2;
3080
3081       for (ii = 1; ii <= mySec->NbLaw(); ii++) {
3082         aTrim.Modified(myFaces->Value(ii, II), listmodif);
3083
3084         if(!listmodif.IsEmpty()) {
3085           myFaces->SetValue(ii, II, listmodif.First());
3086         }
3087       }
3088
3089       for (ii = myUEdges->LowerRow(); ii <= myUEdges->UpperRow(); ii++) {
3090         aTrim.Modified(myUEdges->Value(ii, II), listmodif);
3091
3092         if(!listmodif.IsEmpty()) {
3093           myUEdges->SetValue(ii, II, listmodif.First());
3094         }
3095       }
3096     }
3097   }
3098   else if ((TheTransition == BRepFill_Right) ||
3099            aTrim.HasSection() ) { 
3100 #ifdef OCCT_DEBUG
3101     cout << "Fail of TrimCorner" << endl;
3102 #endif
3103     return; // Nothing is touched
3104   }
3105
3106   if (mySec->IsUClosed())
3107     {
3108       myUEdges->SetValue( 1, I1, myUEdges->Value(mySec->NbLaw()+1, I1) );
3109       myUEdges->SetValue( 1, I2, myUEdges->Value(mySec->NbLaw()+1, I2) );
3110     }
3111
3112   if (TheTransition == BRepFill_Round) {
3113   // Filling
3114     TopTools_ListOfShape list1, list2;
3115     TopoDS_Edge Bord1, Bord2, BordFirst;
3116     BordFirst.Nullify();
3117     Bord1.Nullify();
3118     Bord2.Nullify();
3119     Standard_Boolean HasFilling = Standard_False;
3120     TopoDS_Face FF;
3121     for (ii=1; ii<=mySec->NbLaw(); ii++) {
3122       KeepEdge(myFaces->Value(ii, I1), Bounds->Value(ii, 1), list1);
3123       KeepEdge(myFaces->Value(ii, I2), Bounds->Value(ii, 2), list2);
3124       if (list1.Extent() == list2.Extent()) {
3125         TopTools_ListIteratorOfListOfShape It1(list1);
3126         TopTools_ListIteratorOfListOfShape It2(list2);
3127         Standard_Boolean B;
3128         for (; It1.More(); It1.Next(), It2.Next()) {
3129           if (HasFilling) { // Transversal choice of constraints
3130             TopoDS_Vertex VF, VL, VC;
3131             TopoDS_Edge E = TopoDS::Edge(It1.Value());
3132             TopoDS_Edge E1, E2;
3133             E1.Nullify();
3134             E2.Nullify();
3135             TopExp::Vertices(E, VF, VL);
3136             if (!Bord1.IsNull() && 
3137                 TopExp::CommonVertex(E, Bord1, VC)) {
3138               if (VC.IsSame(VF)) E1 = Bord1;
3139               else               E2 = Bord1;
3140             }
3141             if (!Bord2.IsNull() && 
3142                 TopExp::CommonVertex(E, Bord2, VC)) {
3143               if (VC.IsSame(VF)) E1 = Bord2;
3144               else               E2 = Bord2;
3145             }
3146             if (!BordFirst.IsNull() && 
3147                 TopExp::CommonVertex(E, BordFirst, VC)) {
3148               if (VC.IsSame(VF)) E1 = BordFirst;
3149               else               E2 = BordFirst;
3150             }
3151             Bord1 = E1;
3152             Bord2 = E2;
3153           }
3154           
3155           // Filling
3156           B = Filling(It1.Value(), myFaces->Value(ii, I1),
3157                       It2.Value(), myFaces->Value(ii, I2),
3158                       myVEdgesModified, myTol3d, Axe, T1, Bord1, Bord2, FF);
3159           
3160           if (B) {
3161             myAuxShape.Append(FF);
3162             myVEdges->ChangeValue(ii, I2) = FF;
3163             HasFilling = Standard_True;
3164           }
3165           if (ii==1) BordFirst = Bord1;
3166         }
3167       }
3168 #ifdef OCCT_DEBUG
3169       else cout << "PerformCorner : Unsymmetry of free border" << endl;
3170 #endif
3171     }
3172   }
3173
3174 /*  
3175 #if DRAW
3176   if (Affich) {
3177     Standard_Integer jj;
3178     char name[100];
3179     DBRep::Set("TrimmedShell", TheShape);
3180     for (jj=1; jj <=myFaces->ColLength(); jj++){
3181       sprintf(name,"Tfaces_%d_%d", jj, I1);
3182       DBRep::Set(name, myFaces->Value(jj, I1));
3183       sprintf(name,"Tfaces_%d_%d", jj, I2);
3184       DBRep::Set(name, myFaces->Value(jj, I2));
3185     }
3186   }
3187 #endif
3188 */
3189 }
3190
3191 //=======================================================================
3192 //function : EvalExtrapol
3193 //purpose  : 
3194 //======================================================================
3195 Standard_Real BRepFill_Sweep::
3196   EvalExtrapol(const Standard_Integer Index,
3197                const BRepFill_TransitionStyle Transition) const
3198 {
3199   Standard_Real Extrap = 0.0;
3200   if (Transition == BRepFill_Right) {
3201     Standard_Integer I1, I2;
3202     if ((Index == 1) || (Index ==myLoc->NbLaw()+1) ) {
3203       if (!myLoc->IsClosed() || !mySec->IsVClosed()) return Extrap;
3204       I1 = myLoc->NbLaw();
3205       I2 = 1;
3206     }
3207     else {
3208       I1 = Index-1;
3209       I2 = Index;
3210     }
3211
3212     gp_Vec V1, V2, T1, T2;
3213     gp_Mat M1, M2;
3214     Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax, R, f, l;
3215
3216     myLoc->Law(I1)->GetDomain(f, l);
3217     myLoc->Law(I1)->D0(l, M1, V1);
3218     T1.SetXYZ(M1.Column(3));
3219     myLoc->Law(I2)->GetDomain(f, l);
3220     myLoc->Law(I2)->D0(f, M2, V2);
3221     T2.SetXYZ(M2.Column(3));
3222      
3223     Standard_Real alpha = T1.Angle(T2);
3224     if ((alpha >  myAngMax) || (alpha <  myAngMin)) {
3225       //Angle too great => No "straight" connection
3226       //Angle too small => No connection
3227       return Extrap; // = 0.0
3228     }   
3229
3230     Handle(GeomFill_SectionLaw) Sec;
3231     Sec = mySec->ConcatenedLaw();
3232
3233     //Calculating parameter U
3234     Standard_Real U, Length, SecFirst, SecLen, Lf, Ll;
3235     myLoc->CurvilinearBounds( myLoc->NbLaw(), Lf, Length );
3236     mySec->Law(1)->GetDomain( SecFirst, SecLen );
3237     SecLen -= SecFirst;
3238     myLoc->CurvilinearBounds( I1, Lf, Ll );
3239     U = SecFirst + (Ll/Length)*SecLen;
3240
3241     Bnd_Box box;
3242     //Box(Sec, 0., box);
3243     Box(Sec, U, box);
3244     box.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
3245     
3246     R =  Max(Max(Abs(Xmin), Abs(Xmax)),Max(Abs(Ymin), Abs(Ymax)));
3247     //R *= 1.1;
3248     // modified by NIZHNY-MKK  Fri Oct 31 18:57:51 2003
3249     //     Standard_Real coef = 1.2;
3250     Standard_Real coef = 2.;
3251     R *= coef;
3252     Extrap = Max(Abs(Zmin), Abs(Zmax)) + 100*myTol3d; 
3253     Extrap += R*Tan(alpha/2);
3254   }
3255   return Extrap;
3256 }
3257
3258 //=======================================================================
3259 //function : MergeVertex
3260 //purpose  : Make V2 = V1 if V2 is too close to V1
3261 //======================================================================
3262 Standard_Boolean BRepFill_Sweep::MergeVertex(const TopoDS_Shape& V1,
3263                                                    TopoDS_Shape& V2) const
3264 {
3265 // Class BRep_Tool without fields and without Constructor :
3266 //  BRep_Tool BT;
3267   const TopoDS_Vertex& v1 = TopoDS::Vertex(V1);
3268   const TopoDS_Vertex& v2 = TopoDS::Vertex(V2);  
3269   Standard_Real tol;
3270 //  tol = Max(BT.Tolerance(v1), BT.Tolerance(v2));
3271   tol = Max(BRep_Tool::Tolerance(v1), BRep_Tool::Tolerance(v2));
3272   if (tol < myTol3d) tol = myTol3d;
3273 //  if (BT.Pnt(v1).Distance(BT.Pnt(v2)) <= tol ){
3274   if (BRep_Tool::Pnt(v1).Distance(BRep_Tool::Pnt(v2)) <= tol ){
3275     V2 = V1;
3276     return Standard_True;
3277   }                              
3278   return Standard_False;
3279 }
3280
3281         
3282 //=======================================================================
3283 //function : UpdateVertex
3284 //purpose  : Update the Tolerance of Vertices depending on Laws.
3285 //======================================================================
3286 void BRepFill_Sweep::UpdateVertex(const Standard_Integer ipath,
3287                                   const Standard_Integer isec,
3288                                   const Standard_Real ErrApp,
3289                                   const Standard_Real Param,
3290                                   TopoDS_Shape& V) const
3291 {
3292   TopoDS_Vertex vv, TheV;
3293   TheV = TopoDS::Vertex(V);
3294   myLoc->PerformVertex(ipath, 
3295                        mySec->Vertex(isec, Param), 
3296                        ErrApp+mySec->VertexTol(isec-1, Param),
3297                        vv);
3298 // Class BRep_Tool without fields and without Constructor :
3299 //  BRep_Tool BT;
3300   gp_Pnt P1, P2;
3301 //  P1 = BT.Pnt(vv);
3302   P1 = BRep_Tool::Pnt(vv);
3303 //  P2 = BT.Pnt(TheV);
3304   P2 = BRep_Tool::Pnt(TheV);
3305
3306 //  Standard_Real Tol = BT.Tolerance(vv);
3307   Standard_Real Tol = BRep_Tool::Tolerance(vv);
3308   Tol += P1.Distance(P2);
3309   
3310 //  if (Tol >  BT.Tolerance(TheV)) {
3311   if (Tol >  BRep_Tool::Tolerance(TheV)) {
3312     BRep_Builder B;
3313     B.UpdateVertex(TheV, Tol);
3314   }
3315 }
3316
3317 //=======================================================================
3318 //function : RebuildTopOrBottomEdge
3319 //purpose  : Rebuild v-iso edge of top or bottom section
3320 //           inserting new 3d and 2d curves taken from swept surfaces
3321 //======================================================================
3322 void BRepFill_Sweep::RebuildTopOrBottomEdge(const TopoDS_Edge& aNewEdge,
3323                                             TopoDS_Edge& anEdge,
3324                                             TopTools_MapOfShape& ReversedEdges) const
3325 {
3326   Standard_Real fpar, lpar;
3327   Handle(Geom_Curve) aNewCurve = BRep_Tool::Curve(aNewEdge, fpar, lpar);
3328   TopLoc_Location Identity;
3329   
3330   Standard_Boolean ToReverse = Standard_False;
3331   Standard_Boolean IsDegen = BRep_Tool::Degenerated(aNewEdge);
3332   if (IsDegen)
3333     BRep_Tool::Range(aNewEdge, fpar, lpar);
3334   else
3335   {
3336     TopoDS_Vertex V1, V2, NewV1, NewV2;
3337     TopExp::Vertices(anEdge, V1, V2);
3338     if (!V1.IsSame(V2))
3339     {
3340       TopExp::Vertices(aNewEdge, NewV1, NewV2);
3341       V1.Location(Identity);
3342       if (!V1.IsSame(NewV1))
3343       {
3344         if (V1.IsSame(NewV2))
3345           ToReverse = Standard_True;
3346         else
3347         {
3348           gp_Pnt Pnt1 = BRep_Tool::Pnt(V1);
3349           gp_Pnt NewPnt1 = BRep_Tool::Pnt(NewV1);
3350           Standard_Real TolSum = BRep_Tool::Tolerance(V1) + BRep_Tool::Tolerance(NewV1);
3351           if (!Pnt1.IsEqual(NewPnt1, TolSum))
3352             ToReverse = Standard_True;
3353         }
3354       }
3355     }
3356     else
3357     {
3358       Standard_Real OldFirst, OldLast;
3359       Handle(Geom_Curve) OldCurve = BRep_Tool::Curve(anEdge, OldFirst, OldLast);
3360       gp_Vec OldD1, NewD1;
3361       gp_Pnt MidPnt;
3362       OldCurve->D1(0.5*(OldFirst + OldLast), MidPnt, OldD1);
3363       aNewCurve->D1(0.5*(fpar + lpar), MidPnt, NewD1);
3364       if (OldD1 * NewD1 < 0.)
3365         ToReverse = Standard_True;
3366     }
3367   }
3368   
3369   anEdge.Location(Identity);
3370   const Handle(BRep_TEdge)& TEdge = *((Handle(BRep_TEdge)*) &anEdge.TShape());
3371   TEdge->Tolerance(BRep_Tool::Tolerance(aNewEdge));
3372   BRep_Builder BB;
3373   BB.Range(anEdge, fpar, lpar);
3374   BB.UpdateEdge(anEdge, aNewCurve, Precision::Confusion());
3375   const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &aNewEdge.TShape());
3376   const BRep_ListOfCurveRepresentation& lcr = TE->Curves();
3377   BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr);
3378   for (; itrep.More(); itrep.Next())
3379   {
3380     const Handle(BRep_CurveRepresentation)& CurveRep = itrep.Value();
3381     if (CurveRep->IsCurveOnSurface())
3382     {
3383       Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (CurveRep));
3384       Handle(Geom2d_Curve) aPCurve = GC->PCurve();
3385       Handle(Geom_Surface) aSurf = GC->Surface();
3386       TopLoc_Location aLoc = aNewEdge.Location() * GC->Location();
3387       BB.UpdateEdge(anEdge, aPCurve, aSurf, aLoc, Precision::Confusion());
3388     }
3389   }
3390   
3391   anEdge.Free(Standard_True);
3392   TopoDS_Vertex V1, V2;
3393   TopExp::Vertices(anEdge, V1, V2);
3394
3395   TopoDS_Shape anEdgeFORWARD = anEdge.Oriented(TopAbs_FORWARD);
3396   
3397   BB.Remove(anEdgeFORWARD, V1);
3398   BB.Remove(anEdgeFORWARD, V2);
3399  
3400   V1.Location(Identity);
3401   V2.Location(Identity);
3402   if (ToReverse)
3403   {
3404     V2.Orientation(TopAbs_FORWARD);
3405     V1.Orientation(TopAbs_REVERSED);
3406   }
3407   BB.Add(anEdgeFORWARD, V1);
3408   BB.Add(anEdgeFORWARD, V2);
3409   
3410   if (ToReverse)
3411   {
3412     anEdge.Reverse();
3413     ReversedEdges.Add(anEdge);
3414   }
3415
3416   BB.Degenerated(anEdge, IsDegen);
3417 }