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