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