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