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