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