Replacing french comments by english one
[occt.git] / src / ChFi3d / ChFi3d_Builder_6.cxx
1 // File:        ChFi3d_Builder_6.cxx
2 // Created:     Tue Oct 25 17:54:52 1994
3 // Author:      Laurent BOURESCHE
4 //              <lbo@phylox>
5 // modif : jlr branchement F(t) pour Edge/Face
6
7 //  Modified by skv - Wed Jun  9 17:16:26 2004 OCC5898
8 //  modified by Edward AGAPOV (eap) Fri Feb  8 2002 (bug occ67 == BUC61052)
9 //  ComputeData(), case where BRepBlend_Walking::Continu() can't get up to Target
10
11 #include <stdio.h>
12
13 #include <ChFi3d_Builder.jxx>
14 #include <ChFi3d_Builder_0.hxx>
15
16 #include <Precision.hxx>
17 #include <math_Vector.hxx>
18 #include <BSplCLib.hxx>
19
20 #include <gp_Pnt.hxx>
21 #include <gp_Vec.hxx>
22 #include <gp_Pnt2d.hxx>
23 #include <gp_Dir2d.hxx>
24 #include <gp_Vec2d.hxx>
25
26 #include <Geom2d_TrimmedCurve.hxx>
27 #include <Geom2d_BSplineCurve.hxx>
28 #include <Geom2d_Curve.hxx>
29 #include <Geom2d_Line.hxx>
30 #include <Geom_Curve.hxx>
31 #include <Geom_BSplineSurface.hxx>
32 #include <GeomLib.hxx>
33
34 #include <Adaptor3d_HSurface.hxx>
35 #include <Adaptor3d_TopolTool.hxx>
36 #include <GeomAdaptor_HCurve.hxx>
37 #include <GeomAdaptor_HSurface.hxx>
38 #include <BRepAdaptor_Surface.hxx>
39 #include <BRepAdaptor_Curve2d.hxx>
40 #include <BRepAdaptor_Curve.hxx>
41 #include <BRepAdaptor_HCurve2d.hxx>
42 #include <BRepTopAdaptor_TopolTool.hxx>
43 #include <BRepTopAdaptor_HVertex.hxx>
44 #include <BRep_Tool.hxx>
45
46 #include <Approx_SweepFunction.hxx>
47 #include <Blend_Point.hxx>
48 #include <BRepBlend_Extremity.hxx>
49 #include <BRepBlend_PointOnRst.hxx>
50 #include <BRepBlend_Line.hxx>
51 #include <BRepBlend_AppSurf.hxx>
52 #include <BRepBlend_AppSurface.hxx>
53 #include <BRepBlend_AppFunc.hxx>
54 #include <BRepBlend_AppFuncRst.hxx>
55 #include <BRepBlend_AppFuncRstRst.hxx>
56 #include <BRepBlend_CSWalking.hxx>
57 #include <BRepBlend_Walking.hxx>
58 #include <BRepBlend_SurfRstLineBuilder.hxx>
59 #include <BRepBlend_RstRstLineBuilder.hxx>
60 #include <BRepBlend_ConstRad.hxx>
61 #include <BRepBlend_ConstRadInv.hxx>
62
63 #include <TopOpeBRepDS_DataStructure.hxx>
64 #include <TopOpeBRepDS_Curve.hxx>
65 #include <TopOpeBRepDS_Surface.hxx>
66
67 #include <IntRes2d_IntersectionPoint.hxx>
68 #include <Geom2dInt_GInter.hxx>
69 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
70
71 #include <ChFiDS_SurfData.hxx>
72 #include <ChFiDS_FaceInterference.hxx>
73 #include <ChFiDS_CommonPoint.hxx>
74
75 #include <TopExp.hxx>
76 #include <TopTools_ListOfShape.hxx>
77 #include <TopTools_ListIteratorOfListOfShape.hxx>
78
79 #ifdef DEB
80 // For measurements.
81 #include <OSD_Chronometer.hxx>
82 //static OSD_Chronometer appclock;
83 #endif
84
85 //#define DRAW 
86
87 #ifdef DRAW 
88 #include <Draw_Appli.hxx>
89 #include <Draw_Segment2D.hxx>
90 #include <Draw_Marker2D.hxx>
91 #include <Draw_Segment3D.hxx>
92 #include <Draw_Marker3D.hxx>
93 #include <Draw.hxx>
94 #include <DrawTrSurf.hxx>
95 static Standard_Integer IndexOfConge = 0;
96 #endif
97
98 #ifdef DEB
99 extern Standard_Boolean ChFi3d_GettraceDRAWFIL(); 
100 extern Standard_Boolean ChFi3d_GettraceDRAWWALK(); 
101 extern Standard_Boolean ChFi3d_GetcontextNOOPT();
102 extern void ChFi3d_SettraceDRAWFIL(const Standard_Boolean b); 
103 extern void ChFi3d_SettraceDRAWWALK(const Standard_Boolean b); 
104 extern void ChFi3d_SetcontextNOOPT(const Standard_Boolean b);
105 #endif
106
107 #ifdef DRAW 
108 static void drawline(const Handle(BRepBlend_Line)& lin,
109                      const Standard_Boolean iscs)
110 {
111   Handle(Draw_Marker3D) p3d;
112   Handle(Draw_Marker2D) p2d;
113   Handle(Draw_Segment3D) tg3d;
114   Handle(Draw_Segment2D) tg2d;
115   
116   for(Standard_Integer i = 1; i <= lin->NbPoints(); i++){
117     const Blend_Point& pt = lin->Point(i);
118     gp_Pnt point = pt.PointOnS1();
119     gp_Pnt extr = point.Translated(pt.TangentOnS1());
120     p3d = new Draw_Marker3D(point,Draw_Square,Draw_rouge);
121     dout<<p3d;
122     tg3d = new Draw_Segment3D(point,extr,Draw_rouge);
123     dout<<tg3d;
124     point = pt.PointOnS2();
125     extr = point.Translated(pt.TangentOnS2());
126     p3d = new Draw_Marker3D(point,Draw_Plus,Draw_jaune);
127     dout<<p3d;
128     tg3d = new Draw_Segment3D(point,extr,Draw_jaune);
129     dout<<tg3d;
130
131     Standard_Real u,v;
132     pt.ParametersOnS1(u,v);
133     gp_Pnt2d point2d(u,v);
134     gp_Pnt2d extr2d = point2d.Translated(pt.Tangent2dOnS1());
135     p2d = new Draw_Marker2D(point2d,Draw_Square,Draw_rouge);
136     dout<<p2d;
137     tg2d = new Draw_Segment2D(point2d,extr2d,Draw_rouge);
138     dout<<tg2d;
139     pt.ParametersOnS2(u,v);
140     point2d.SetCoord(u,v);
141     extr2d = point2d.Translated(pt.Tangent2dOnS2());
142     p2d = new Draw_Marker2D(point2d,Draw_Plus,Draw_jaune);
143     dout<<p2d;
144     tg2d = new Draw_Segment2D(point2d,extr2d,Draw_jaune);
145     dout<<tg2d;
146     dout.Flush();
147   }
148 }
149 #endif
150 //=======================================================================
151 //function : SearchIndex
152 //purpose  : 
153 //           
154 //=======================================================================
155 static Standard_Integer SearchIndex(const Standard_Real Value,
156                                     Handle(BRepBlend_Line)& Lin)
157 {
158   Standard_Integer NbPnt =  Lin->NbPoints(), Ind;
159
160   for (Ind = 1;  
161        (Ind < NbPnt) && (Lin->Point(Ind).Parameter() < Value); )
162     Ind++;
163   return Ind;
164 }
165
166
167 //=======================================================================
168 //function : IsObst
169 //purpose  : 
170 //           
171 //=======================================================================
172 static Standard_Integer nbedconnex(const TopTools_ListOfShape& L)
173 {
174   Standard_Integer nb = 0, i = 0;
175   TopTools_ListIteratorOfListOfShape It1(L);
176   for(;It1.More();It1.Next(),i++){
177     const TopoDS_Shape& curs = It1.Value();
178     Standard_Boolean dejavu = 0;
179     TopTools_ListIteratorOfListOfShape It2(L);
180     for(Standard_Integer j = 0; j < i && It2.More(); j++, It2.Next()){
181       if(curs.IsSame(It2.Value())){
182         dejavu = 1;
183         break;
184       }
185     }
186     if(!dejavu) nb++;
187   }
188   return nb;
189 }
190
191 static Standard_Boolean IsVois(const TopoDS_Edge&     E,
192                                const TopoDS_Vertex&   Vref,
193                                const ChFiDS_Map&      VEMap,
194                                TopTools_MapOfShape&   DONE,
195                                const Standard_Integer prof,
196                                const Standard_Integer profmax)
197 {
198   if(prof > profmax) return Standard_False;
199   if(DONE.Contains(E)) return Standard_False;
200   TopoDS_Vertex V1,V2;
201   TopExp::Vertices(E,V1,V2);
202   if(Vref.IsSame(V1) || Vref.IsSame(V2)) return Standard_True;
203   DONE.Add(E);
204   const TopTools_ListOfShape& L1 = VEMap(V1);
205   Standard_Integer i1 = nbedconnex(L1);
206   TopTools_ListIteratorOfListOfShape It1(L1);
207   for(;It1.More();It1.Next()){
208     const TopoDS_Edge& curE = TopoDS::Edge(It1.Value());
209     if(i1 <= 2){
210       if(IsVois(curE,Vref,VEMap,DONE,prof,profmax)) return Standard_True;
211     }
212     else if(IsVois(curE,Vref,VEMap,DONE,prof+1,profmax)) return Standard_True;
213   }
214   const TopTools_ListOfShape& L2 = VEMap(V2);
215 #ifdef DEB
216 //  Standard_Integer i2 = nbedconnex(L2);
217 #endif
218   TopTools_ListIteratorOfListOfShape It2(L2);
219   for(;It2.More();It2.Next()){
220     const TopoDS_Edge& curE = TopoDS::Edge(It2.Value());
221     if(i1 <= 2){
222       if(IsVois(curE,Vref,VEMap,DONE,prof,profmax)) return Standard_True;
223     }
224     else if(IsVois(curE,Vref,VEMap,DONE,prof+1,profmax)) return Standard_True;
225   }
226   return Standard_False;
227 }
228
229 static Standard_Boolean IsObst(const ChFiDS_CommonPoint& CP,
230                                const TopoDS_Vertex&      Vref,
231                                const ChFiDS_Map&         VEMap)
232 {
233   if(!CP.IsOnArc()) return Standard_False;
234   const TopoDS_Edge& E = CP.Arc();
235   TopTools_MapOfShape DONE;
236   Standard_Integer prof = 4;
237   return !IsVois(E,Vref,VEMap,DONE,0,prof);
238 }
239
240 //=======================================================================
241 //function : CompParam
242 //purpose  : 
243 //           
244 //=======================================================================
245
246 static void CompParam(Geom2dAdaptor_Curve  Carc,
247                       Handle(Geom2d_Curve) Ctg,
248                       Standard_Real&       parc,
249                       Standard_Real&       ptg,
250                       const Standard_Real  prefarc,
251                       const Standard_Real  preftg)
252 {
253   Standard_Boolean found = 0;
254   //(1) It is checked if the provided parameters are good 
255   //    if pcurves have the same parameters as the spine.
256   gp_Pnt2d point = Carc.Value(prefarc);
257   Standard_Real distini = point.Distance(Ctg->Value(preftg));
258   if (distini <= Precision::PConfusion()) {
259     parc =  prefarc;
260     ptg = preftg;
261     found = Standard_True;
262   }
263   else {
264     //(2) Intersection
265 #ifdef DEB
266     cout<< "CompParam : bad intersection parameters"<<endl; 
267 #endif
268     IntRes2d_IntersectionPoint int2d;
269     Geom2dInt_GInter Intersection;
270     Standard_Integer nbpt,nbseg;
271     Intersection.Perform(Geom2dAdaptor_Curve(Ctg),Carc,
272                          Precision::PIntersection(),
273                          Precision::PIntersection());
274
275     Standard_Real dist = Precision::Infinite(), p1, p2;
276     if (Intersection.IsDone()){
277       if (!Intersection.IsEmpty()){
278         nbseg = Intersection.NbSegments();
279         if ( nbseg > 0 ){ 
280 #ifdef DEB
281           cout<< "segments of intersection on the restrictions"<<endl; 
282 #endif  
283         }
284         nbpt = Intersection.NbPoints();
285         for (Standard_Integer i = 1; i <= nbpt; i++) {
286           int2d = Intersection.Point(i);
287           p1 = int2d.ParamOnFirst();
288           p2 = int2d.ParamOnSecond();
289           if(Abs(prefarc - p2) < dist){
290             ptg  = p1;
291             parc = p2;
292             dist = Abs(prefarc - p2);
293             found = 1;
294           }
295         }
296       }
297     }
298   }
299   
300   if(!found){
301     // (3) Projection...
302 #ifdef DEB
303     cout<<"CompParam : failed intersection PC, projection is created."<<endl;
304 #endif
305     parc = prefarc;
306     Geom2dAPI_ProjectPointOnCurve projector(point,Ctg);
307
308     if(projector.NbPoints() == 0){
309       // This happens in some cases when there is a vertex 
310       // at the end of spine...
311       ptg = preftg; 
312 #ifdef DEB
313       cout<<"CompParam : failed proj p2d/c2d, the extremity is taken!" <<endl;
314 #endif
315     }
316     else  {
317       // It is checked if everything was calculated correctly (EDC402 C2)
318       if  (projector.LowerDistance() < distini) 
319         ptg = projector.LowerDistanceParameter();
320       else  ptg = preftg;
321     }
322   }
323 }
324
325 //=======================================================================
326 //function : CompBlendPoint
327 //purpose  : create BlendPoint corresponding to a tangency on Vertex
328 // pmn : 15/10/1997 : returns false, if there is no pcurve    
329 //=======================================================================
330
331 static Standard_Boolean CompBlendPoint(const TopoDS_Vertex& V,
332                                        const TopoDS_Edge& E,
333                                        const Standard_Real W,
334                                        const TopoDS_Face F1,
335                                        const TopoDS_Face F2,
336                                        Blend_Point& BP)
337 {    
338   gp_Pnt2d P1, P2;
339   gp_Pnt P3d;
340   Standard_Real param, f, l;
341   Handle(Geom2d_Curve) pc;
342   
343   P3d = BRep_Tool::Pnt(V);
344   param = BRep_Tool::Parameter(V,E,F1);
345   pc = BRep_Tool::CurveOnSurface(E,F1,f,l);
346   if (pc.IsNull()) return Standard_False;
347   P1 =  pc->Value(param); 
348   param = BRep_Tool::Parameter(V,E,F2);
349   pc = BRep_Tool::CurveOnSurface(E,F2,f,l);
350   if (pc.IsNull()) return Standard_False;
351   P2 =  pc->Value(param);
352   BP.SetValue(P3d, P3d, W, P1.X(), P1.Y(),  P2.X(), P2.Y());
353   return  Standard_True;
354 }
355
356 //=======================================================================
357 //function :  UpdateLine
358 //purpose  : Updates extremities after a partial invalidation   
359 //=======================================================================
360
361 static void UpdateLine(Handle(BRepBlend_Line)& Line, 
362                        const Standard_Boolean isfirst)
363 {
364   Standard_Real tguide, U, V;
365   if (isfirst) {
366    const Blend_Point& BP = Line->Point(1);
367    tguide = BP.Parameter();
368    if (Line->StartPointOnFirst().ParameterOnGuide() < tguide) {
369      BRepBlend_Extremity BE;
370      BP.ParametersOnS1(U, V);
371      BE.SetValue(BP.PointOnS1(), U, V, Precision::Confusion());
372      Line->SetStartPoints(BE, Line->StartPointOnSecond());
373    }
374    if (Line->StartPointOnSecond().ParameterOnGuide() < tguide) {
375      BRepBlend_Extremity BE;
376      BP.ParametersOnS2(U, V);
377      BE.SetValue(BP.PointOnS2(), U, V, Precision::Confusion());
378      Line->SetStartPoints(Line->StartPointOnFirst(), BE);
379    }
380  }
381   else {
382    const Blend_Point& BP = Line->Point(Line->NbPoints());
383    tguide = BP.Parameter();
384    if (Line->EndPointOnFirst().ParameterOnGuide() > tguide) {
385      BRepBlend_Extremity BE;
386      BP.ParametersOnS1(U, V);
387      BE.SetValue(BP.PointOnS1(), U, V, Precision::Confusion());
388      Line->SetEndPoints(BE, Line->EndPointOnSecond());
389    }
390    if (Line->EndPointOnSecond().ParameterOnGuide() > tguide) {
391      BRepBlend_Extremity BE;
392      BP.ParametersOnS2(U, V);
393      BE.SetValue(BP.PointOnS2(), U, V, Precision::Confusion());
394      Line->SetEndPoints(Line->EndPointOnFirst(), BE);
395    }
396   }
397 }
398
399 //=======================================================================
400 //function : CompleteData
401 //purpose  : Calculates curves and CommonPoints from the data
402 //           calculated by filling.
403 //=======================================================================
404
405 Standard_Boolean ChFi3d_Builder::CompleteData
406 (Handle(ChFiDS_SurfData)&        Data,
407  const Handle(Geom_Surface)&     Surfcoin,
408  const Handle(Adaptor3d_HSurface)& S1,
409  const Handle(Geom2d_Curve)&     PC1,
410  const Handle(Adaptor3d_HSurface)& S2,
411  const Handle(Geom2d_Curve)&     PC2,
412  const TopAbs_Orientation        Or,
413  const Standard_Boolean          On1,
414  const Standard_Boolean          Gd1,
415  const Standard_Boolean          Gd2,
416  const Standard_Boolean          Gf1,
417  const Standard_Boolean          Gf2)
418 {
419   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
420   Data->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(Surfcoin,tolesp)));
421 #ifdef DRAW
422   ChFi3d_SettraceDRAWFIL(Standard_True);
423   if (ChFi3d_GettraceDRAWFIL()) {
424     IndexOfConge++;
425 //    char name[100];
426     char* name = new char[100];
427     sprintf(name,"%s_%d","Surf",IndexOfConge);
428     DrawTrSurf::Set(name,Surfcoin);
429   }
430 #endif
431     
432   Standard_Real UFirst,ULast,VFirst,VLast;
433   Surfcoin->Bounds(UFirst,ULast,VFirst,VLast);
434   if(!Gd1) Data->ChangeVertexFirstOnS1().SetPoint(Surfcoin->Value(UFirst,VFirst));
435   if(!Gd2) Data->ChangeVertexFirstOnS2().SetPoint(Surfcoin->Value(UFirst,VLast));
436   if(!Gf1) Data->ChangeVertexLastOnS1().SetPoint(Surfcoin->Value(ULast,VFirst));
437   if(!Gf2) Data->ChangeVertexLastOnS2().SetPoint(Surfcoin->Value(ULast,VLast));
438
439   //calculate curves side S1
440   Handle(Geom_Curve) Crv3d1;
441   if(!PC1.IsNull()) Crv3d1= Surfcoin->VIso(VFirst);
442   gp_Pnt2d pd1(UFirst,VFirst), pf1(ULast,VFirst);
443   gp_Lin2d lfil1(pd1,gp_Dir2d(gp_Vec2d(pd1,pf1)));
444   Handle(Geom2d_Curve) PCurveOnSurf = new Geom2d_Line(lfil1);
445   TopAbs_Orientation tra1 = TopAbs_FORWARD, orsurf = Or;
446   Standard_Real x,y,w = 0.5*(UFirst+ULast);
447   gp_Pnt p;
448   gp_Vec du,dv;
449   Handle(Geom2d_Curve) c2dtrim;
450   Standard_Real tolreached;
451   if(!PC1.IsNull()){
452     Handle(GeomAdaptor_HCurve) hcS1 = new GeomAdaptor_HCurve(Crv3d1);
453     c2dtrim = new Geom2d_TrimmedCurve(PC1,UFirst,ULast);
454     ChFi3d_SameParameter(hcS1,c2dtrim,S1,tolapp3d,tolreached);
455     c2dtrim->Value(w).Coord(x,y);
456     S1->D1(x,y,p,du,dv);
457     gp_Vec nf = du.Crossed(dv);
458     Surfcoin->D1(w,VFirst,p,du,dv);
459     gp_Vec ns = du.Crossed(dv);
460     if(nf.Dot(ns) > 0.)  tra1 = TopAbs_REVERSED;
461     else if(On1) orsurf = TopAbs::Reverse(orsurf);
462   }
463   Standard_Integer Index1OfCurve = 
464     DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d1,tolreached));
465   ChFiDS_FaceInterference& Fint1 = Data->ChangeInterferenceOnS1();
466   Fint1.SetFirstParameter(UFirst);
467   Fint1.SetLastParameter(ULast);
468   Fint1.SetInterference(Index1OfCurve,tra1,c2dtrim,PCurveOnSurf);
469   //calculate curves side S2
470   Handle(Geom_Curve) Crv3d2;
471   if(!PC2.IsNull()) Crv3d2 = Surfcoin->VIso(VLast);
472   gp_Pnt2d pd2(UFirst,VLast), pf2(ULast,VLast);
473   gp_Lin2d lfil2(pd2,gp_Dir2d(gp_Vec2d(pd2,pf2)));
474   PCurveOnSurf = new Geom2d_Line(lfil2);
475   TopAbs_Orientation tra2 = TopAbs_FORWARD;
476   if(!PC2.IsNull()){
477     Handle(GeomAdaptor_HCurve) hcS2 = new GeomAdaptor_HCurve(Crv3d2);
478     c2dtrim = new Geom2d_TrimmedCurve(PC2,UFirst,ULast);
479     ChFi3d_SameParameter(hcS2,c2dtrim,S2,tolapp3d,tolreached);
480     c2dtrim->Value(w).Coord(x,y);
481     S2->D1(x,y,p,du,dv);
482     gp_Vec np = du.Crossed(dv);
483     Surfcoin->D1(w,VLast,p,du,dv);
484     gp_Vec ns = du.Crossed(dv);
485     if(np.Dot(ns) < 0.) {
486       tra2 = TopAbs_REVERSED;
487       if(!On1) orsurf = TopAbs::Reverse(orsurf);
488     }
489   }
490   Standard_Integer Index2OfCurve = 
491     DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d2,tolreached));
492   ChFiDS_FaceInterference& Fint2 = Data->ChangeInterferenceOnS2();
493   Fint2.SetFirstParameter(UFirst);
494   Fint2.SetLastParameter(ULast);
495   Fint2.SetInterference(Index2OfCurve,tra2,c2dtrim,PCurveOnSurf);
496   Data->ChangeOrientation() = orsurf;
497   return Standard_True;
498 }
499
500 //=======================================================================
501 //function : CompleteData
502 //purpose  : Calculates the surface of curves and eventually 
503 //           CommonPoints from the data calculated in ComputeData.
504 //
505 //  11/08/1996 : Use of F(t)
506 //
507 //=======================================================================
508
509 Standard_Boolean ChFi3d_Builder::CompleteData
510 (Handle(ChFiDS_SurfData)& Data,
511  Blend_Function& Func,
512  Handle(BRepBlend_Line)& lin,
513  const Handle(Adaptor3d_HSurface)& S1,
514  const Handle(Adaptor3d_HSurface)& S2,
515  const TopAbs_Orientation Or1,
516  const Standard_Boolean Gd1,
517  const Standard_Boolean Gd2,
518  const Standard_Boolean Gf1,
519  const Standard_Boolean Gf2,
520  const Standard_Boolean Reversed)
521 {
522   Handle(BRepBlend_AppFunc) TheFunc 
523     = new (BRepBlend_AppFunc)(lin, Func, tolapp3d, 1.e-5);
524   BRepBlend_AppSurface approx (TheFunc, 
525                                lin->Point(1).Parameter(),
526                                lin->Point(lin->NbPoints()).Parameter(),
527                                tolapp3d, 1.e-5, //tolapp2d, tolerance max
528                                tolappangle, // Contact G1 
529                                myConti);  
530   if (!approx.IsDone()) {
531 #ifdef DEB
532     cout << "Approximation non faite !!!" << endl;
533 #endif
534     return Standard_False;
535   }
536 #ifdef DEB
537   approx.Dump(cout);
538 #endif
539   return StoreData( Data, approx, lin, S1, S2, Or1, Gd1, Gd2, Gf1, Gf2, Reversed);
540
541
542
543 //=======================================================================
544 //function : CompleteData
545 //purpose  : New overload for functions surf/rst
546 // jlr le 28/07/97 branchement F(t)
547 //=======================================================================
548
549 Standard_Boolean ChFi3d_Builder::CompleteData
550 (Handle(ChFiDS_SurfData)&        Data,
551  Blend_SurfRstFunction&          Func,
552  Handle(BRepBlend_Line)&         lin,
553  const Handle(Adaptor3d_HSurface)& S1,
554  const Handle(Adaptor3d_HSurface)& S2,
555  const TopAbs_Orientation        Or,
556  const Standard_Boolean          Reversed)
557 {
558   Handle(BRepBlend_AppFuncRst) TheFunc 
559     = new (BRepBlend_AppFuncRst)(lin, Func, tolapp3d, 1.e-5);
560   BRepBlend_AppSurface approx (TheFunc, 
561                                lin->Point(1).Parameter(),
562                                lin->Point(lin->NbPoints()).Parameter(),
563                                tolapp3d, 1.e-5, //tolapp2d, tolerance max
564                                tolappangle, // Contact G1 
565                                myConti);  
566  if (!approx.IsDone()) {
567 #ifdef DEB
568     cout << "Approximation is not done!" << endl;
569 #endif  
570     return Standard_False;
571   }
572 #ifdef DEB
573   approx.Dump(cout);
574 #endif
575
576   return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0,Reversed);
577
578
579
580
581 //=======================================================================
582 //function : CompleteData
583 //purpose  : New overload for functions rst/rst
584 // jlr le 28/07/97 branchement F(t)
585 //=======================================================================
586
587 Standard_Boolean ChFi3d_Builder::CompleteData
588 (Handle(ChFiDS_SurfData)&        Data,
589  Blend_RstRstFunction&           Func,
590  Handle(BRepBlend_Line)&         lin,
591  const Handle(Adaptor3d_HSurface)& S1,
592  const Handle(Adaptor3d_HSurface)& S2,
593  const TopAbs_Orientation        Or)
594 {
595   Handle(BRepBlend_AppFuncRstRst) TheFunc 
596     = new (BRepBlend_AppFuncRstRst)(lin, Func, tolapp3d, 1.e-5);
597   BRepBlend_AppSurface approx (TheFunc, 
598                                lin->Point(1).Parameter(),
599                                lin->Point(lin->NbPoints()).Parameter(),
600                                tolapp3d, 1.e-5, //tolapp2d, tolerance max
601                                tolappangle, // Contact G1 
602                                myConti);  
603  if (!approx.IsDone()) {
604 #ifdef DEB
605     cout << "Approximation non faite !!!" << endl;
606 #endif  
607     return Standard_False;
608   }
609 #ifdef DEB
610   approx.Dump(cout);
611 #endif
612
613   return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0);
614
615
616
617
618
619 //=======================================================================
620 //function : StoreData
621 //purpose  : Copy of an approximation result in SurfData.
622 //=======================================================================
623
624 Standard_Boolean ChFi3d_Builder::StoreData(Handle(ChFiDS_SurfData)& Data,
625                                            const AppBlend_Approx& approx,
626                                            const Handle(BRepBlend_Line)& lin,
627                                            const Handle(Adaptor3d_HSurface)& S1,
628                                            const Handle(Adaptor3d_HSurface)& S2,
629                                            const TopAbs_Orientation Or1,
630                                            const Standard_Boolean Gd1,
631                                            const Standard_Boolean Gd2,
632                                            const Standard_Boolean Gf1,
633                                            const Standard_Boolean Gf2,
634                                            const Standard_Boolean Reversed)
635 {
636   // Small control tools.
637   static Handle(GeomAdaptor_HCurve) checkcurve;
638   if(checkcurve.IsNull()) checkcurve = new GeomAdaptor_HCurve();
639   GeomAdaptor_Curve& chc = checkcurve->ChangeCurve();
640   Standard_Real tolget3d, tolget2d, tolaux, tolC1,  tolcheck;
641 #ifndef DEB
642   Standard_Real  tolC2 = 0.;
643 #else
644   Standard_Real  tolC2;
645 #endif
646   approx.TolReached(tolget3d, tolget2d);
647   tolaux = approx.TolCurveOnSurf(1);
648   tolC1 = tolget3d + tolaux;
649   if(!S2.IsNull()) {
650     tolaux = approx.TolCurveOnSurf(2);
651     tolC2 = tolget3d + tolaux;
652   }
653
654   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
655   // By default parametric space is created using a square surface
656   // to be able to parameterize in U by # R*teta // a revoir lbo 29/08/97
657   const TColStd_Array1OfReal& ku = approx.SurfUKnots();
658   const TColStd_Array1OfReal& kv = approx.SurfVKnots();
659   Standard_Real larg = (kv(kv.Upper())-kv(kv.Lower()));
660   TColStd_Array1OfReal& kku = *((TColStd_Array1OfReal*)((void*)&ku));
661   BSplCLib::Reparametrize(0.,larg,kku);
662   Handle(Geom_BSplineSurface) Surf = 
663     new Geom_BSplineSurface(approx.SurfPoles(),approx.SurfWeights(),
664                             kku,kv,
665                             approx.SurfUMults(),approx.SurfVMults(),
666                             approx.UDegree(),approx.VDegree());
667 // extension of the surface 
668
669   Standard_Real length1,length2;
670   length1=Data->FirstExtensionValue();
671   length2=Data->LastExtensionValue();
672   if (length1 > Precision::Confusion())
673     GeomLib::ExtendSurfByLength(Surf,length1,1,Standard_False,Standard_False);
674   if (length2 >  Precision::Confusion())
675     GeomLib::ExtendSurfByLength(Surf,length2,1,Standard_False,Standard_True);
676
677   Data->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(Surf,tolget3d)));
678
679 #ifdef DRAW
680   ChFi3d_SettraceDRAWFIL(Standard_True);
681   if (ChFi3d_GettraceDRAWFIL()) {
682     IndexOfConge++;
683 //    char name[100];
684     char* name=new char[100];
685     sprintf(name,"%s_%d","Surf",IndexOfConge);
686     DrawTrSurf::Set(name,Surf);
687   }
688 #endif
689   Standard_Real UFirst,ULast,VFirst,VLast,pppdeb,pppfin;
690   Surf->Bounds(UFirst,ULast,VFirst,VLast);
691   BRepAdaptor_Curve2d brc;
692   BRepAdaptor_Curve CArc;
693   Handle(BRepAdaptor_HSurface) 
694     BS1 = Handle(BRepAdaptor_HSurface)::DownCast(S1);
695   Handle(BRepAdaptor_HSurface) 
696     BS2 = Handle(BRepAdaptor_HSurface)::DownCast(S2);
697   Geom2dAPI_ProjectPointOnCurve projector;
698
699   Standard_Real Uon1 = UFirst, Uon2 = ULast;
700   Standard_Integer ion1 = 1, ion2 = 2;
701   if(Reversed) { Uon1 = ULast; Uon2 = UFirst; ion1 = 2; ion2 = 1; }
702   
703   // The SurfData is filled in what concerns S1,
704   Handle(Geom_Curve) Crv3d1 = Surf->UIso(Uon1);
705   gp_Pnt2d pori1(Uon1,0.);
706   gp_Lin2d lfil1(pori1,gp::DY2d());
707   Handle(Geom2d_Curve) PCurveOnSurf = new Geom2d_Line(lfil1);
708   Handle(Geom2d_Curve) PCurveOnFace;
709   PCurveOnFace = new 
710     Geom2d_BSplineCurve(approx.Curve2dPoles(ion1),approx.Curves2dKnots(),
711                         approx.Curves2dMults(),approx.Curves2dDegree());
712   
713   
714    Standard_Real par1=PCurveOnFace->FirstParameter();
715    Standard_Real par2= PCurveOnFace->LastParameter();
716    chc.Load(Crv3d1,par1,par2);
717    
718  if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S1,tolC1,tolcheck)){
719 #ifdef DEB
720    cout<<"aaproximate tolerance under-valued : "<<tolC1<<" for "<<tolcheck<<endl;
721 #endif 
722     tolC1 = tolcheck;
723   }
724   Standard_Integer Index1OfCurve = 
725     DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d1,tolC1));
726   
727   Standard_Real uarc,utg;
728   if(Gd1){
729     TopoDS_Face forwfac = BS1->ChangeSurface().Face();
730     forwfac.Orientation(TopAbs_FORWARD);
731     brc.Initialize(Data->VertexFirstOnS1().Arc(),forwfac);
732     ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS1();
733     CArc.Initialize(V.Arc());
734     CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
735     tolcheck = CArc.Value(uarc).Distance(V.Point());
736     V.SetArc(tolC1+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
737     pppdeb = utg;
738   }
739   else pppdeb = VFirst;
740   if(Gf1){
741     TopoDS_Face forwfac = BS1->ChangeSurface().Face();
742     forwfac.Orientation(TopAbs_FORWARD);
743     ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS1();
744     brc.Initialize(V.Arc(),forwfac);
745     CArc.Initialize(V.Arc());
746     CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
747     tolcheck = CArc.Value(uarc).Distance(V.Point());
748     V.SetArc(tolC1+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
749     pppfin = utg;
750   }
751   else pppfin = VLast;
752   ChFiDS_FaceInterference& Fint1 = Data->ChangeInterferenceOnS1();
753   Fint1.SetFirstParameter(pppdeb);
754   Fint1.SetLastParameter(pppfin);
755   TopAbs_Orientation TraOn1;
756   if(Reversed) TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS2());
757   else TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS1());
758   Fint1.SetInterference(Index1OfCurve,TraOn1,PCurveOnFace,PCurveOnSurf);
759   
760   // SurfData is filled in what concerns S2,
761   Handle(Geom_Curve) Crv3d2 = Surf->UIso(Uon2);
762   gp_Pnt2d pori2(Uon2,0.);
763   gp_Lin2d lfil2(pori2,gp::DY2d());
764   PCurveOnSurf = new Geom2d_Line(lfil2);
765   if(!S2.IsNull()){
766     PCurveOnFace = new Geom2d_BSplineCurve(approx.Curve2dPoles(ion2),
767                                            approx.Curves2dKnots(),
768                                            approx.Curves2dMults(),
769                                            approx.Curves2dDegree());
770     chc.Load(Crv3d2,par1,par2);
771    if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S2,tolC2,tolcheck)){
772 #ifdef DEB
773       cout<<"approximate tolerance under-evaluated : "<<tolC2<<" for "<<tolcheck<<endl;
774 #endif 
775       tolC2 = tolcheck;
776     }
777   }
778   Standard_Integer Index2OfCurve = 
779     DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d2,tolC2));
780   if(Gd2){
781     TopoDS_Face forwfac = BS2->ChangeSurface().Face();
782     forwfac.Orientation(TopAbs_FORWARD);
783     brc.Initialize(Data->VertexFirstOnS2().Arc(),forwfac);
784     ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS2();
785     CArc.Initialize(V.Arc());
786     CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
787     tolcheck = CArc.Value(uarc).Distance(V.Point());
788     V.SetArc(tolC2+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
789     pppdeb = utg;
790   }
791   else pppdeb = VFirst;
792   if(Gf2){
793     TopoDS_Face forwfac = BS2->ChangeSurface().Face();
794     forwfac.Orientation(TopAbs_FORWARD);
795     brc.Initialize(Data->VertexLastOnS2().Arc(),forwfac);
796     ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS2();
797     CArc.Initialize(V.Arc());
798     CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
799     tolcheck = CArc.Value(uarc).Distance(V.Point());
800     V.SetArc(tolC2+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
801     pppfin = utg;
802   }
803   else pppfin = VLast;
804   ChFiDS_FaceInterference& Fint2 = Data->ChangeInterferenceOnS2();
805   Fint2.SetFirstParameter(pppdeb);
806   Fint2.SetLastParameter(pppfin);
807   if(!S2.IsNull()){
808     TopAbs_Orientation TraOn2;
809     if(Reversed) TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS1());
810     else TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS2());
811     Fint2.SetInterference(Index2OfCurve,TraOn2,PCurveOnFace,PCurveOnSurf);
812   }
813   else {
814     Handle(Geom2d_Curve) bidpc;
815     Fint2.SetInterference
816       (Index2OfCurve,TopAbs_FORWARD,bidpc,PCurveOnSurf);
817   }
818
819   // the orientation of the fillet in relation to the faces is evaluated,
820
821   Handle(Adaptor3d_HSurface) Sref = S1;
822   PCurveOnFace = Fint1.PCurveOnFace();
823   if(Reversed){ Sref = S2; PCurveOnFace = Fint2.PCurveOnFace(); }
824   
825 //  Modified by skv - Wed Jun  9 17:16:26 2004 OCC5898 Begin
826 //   gp_Pnt2d PUV = PCurveOnFace->Value((VFirst+VLast)/2.);
827 //   gp_Pnt P;
828 //   gp_Vec Du1,Du2,Dv1,Dv2;
829 //   Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1);
830 //   Du1.Cross(Dv1);
831 //   if (Or1 == TopAbs_REVERSED) Du1.Reverse();
832 //   Surf->D1(UFirst,(VFirst+VLast)/2.,P,Du2,Dv2);
833 //   Du2.Cross(Dv2);
834 //   if (Du1.Dot(Du2)>0) Data->ChangeOrientation() = TopAbs_FORWARD;
835 //   else Data->ChangeOrientation() = TopAbs_REVERSED;
836
837   Standard_Real    aDelta = VLast - VFirst;
838   Standard_Integer aDenom = 2;
839
840   while (Standard_True) {
841     Standard_Real aDeltav = aDelta/aDenom;
842     Standard_Real aParam  = VFirst + aDeltav;
843     gp_Pnt2d      PUV     = PCurveOnFace->Value(aParam);
844     gp_Pnt        P;
845     gp_Vec        Du1,Du2,Dv1,Dv2;
846
847     Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1);
848     Du1.Cross(Dv1);
849
850     if (Or1 == TopAbs_REVERSED)
851       Du1.Reverse();
852
853     Surf->D1(UFirst, aParam, P, Du2, Dv2);
854     Du2.Cross(Dv2);
855
856     if (Du1.Magnitude() <= tolget3d ||
857         Du2.Magnitude() <= tolget3d) {
858       aDenom++;
859
860       if (Abs(aDeltav) <= tolget2d)
861         return Standard_False;
862
863       continue;
864     }
865
866     if (Du1.Dot(Du2)>0)
867       Data->ChangeOrientation() = TopAbs_FORWARD;
868     else
869       Data->ChangeOrientation() = TopAbs_REVERSED;
870
871     break;
872   }
873 //  Modified by skv - Wed Jun  9 17:16:26 2004 OCC5898 End
874   
875   if(!Gd1 && !S1.IsNull())
876     ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(),
877                           Standard_True, Data->ChangeVertex(1,ion1),tolC1);
878   if(!Gf1 && !S1.IsNull())
879     ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(),
880                           Standard_False,Data->ChangeVertex(0,ion1),tolC1);
881   if(!Gd2 && !S2.IsNull())
882     ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(),
883                           Standard_True, Data->ChangeVertex(1,ion2),tolC2);
884   if(!Gf2 && !S2.IsNull())
885     ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(),
886                           Standard_False, Data->ChangeVertex(0,ion2),tolC2);
887   // Parameters on ElSpine
888   Standard_Integer nbp = lin->NbPoints();
889   Data->FirstSpineParam(lin->Point(1).Parameter());
890   Data->LastSpineParam(lin->Point(nbp).Parameter());
891   return Standard_True;
892 }                        
893
894
895
896 //=======================================================================
897 //function : ComputeData
898 //purpose  : Head of the path edge/face for the bypass of obstacle.
899 //=======================================================================
900
901 Standard_Boolean ChFi3d_Builder::ComputeData
902 (Handle(ChFiDS_SurfData)&         Data,
903  const Handle(ChFiDS_HElSpine)&   HGuide,
904  Handle(BRepBlend_Line)&          Lin,
905  const Handle(Adaptor3d_HSurface)&  S1,
906  const Handle(Adaptor3d_TopolTool)& I1,
907  const Handle(Adaptor3d_HSurface)&  S2,
908  const Handle(Adaptor2d_HCurve2d)&  PC2,
909  const Handle(Adaptor3d_TopolTool)& I2,
910  Standard_Boolean&                Decroch,
911  Blend_SurfRstFunction&           Func,
912  Blend_FuncInv&                   FInv,
913  Blend_SurfPointFuncInv&          FInvP,
914  Blend_SurfCurvFuncInv&           FInvC,
915  const Standard_Real              PFirst,
916  const Standard_Real              MaxStep,
917  const Standard_Real              Fleche,
918  const Standard_Real              TolGuide,
919  Standard_Real&                   First,
920  Standard_Real&                   Last,
921  const math_Vector&               Soldep,
922  const Standard_Boolean           Inside,
923  const Standard_Boolean           Appro,
924  const Standard_Boolean           Forward,
925  const Standard_Boolean           RecP,
926  const Standard_Boolean           RecS,
927  const Standard_Boolean           RecRst)
928 {
929   BRepBlend_SurfRstLineBuilder TheWalk(S1,I1,S2,PC2,I2);
930   
931   Data->FirstExtensionValue(0);
932   Data->LastExtensionValue(0); 
933
934   Standard_Boolean reverse = (!Forward || Inside);
935   Standard_Real SpFirst = HGuide->FirstParameter();
936   Standard_Real SpLast =  HGuide->LastParameter();
937   Standard_Real Target = SpLast;
938   if(reverse) Target = SpFirst;
939   Standard_Real Targetsov = Target;
940   
941   Standard_Real MS = MaxStep;
942   Standard_Integer again = 0;
943   Standard_Integer nbptmin = 3; //jlr
944 #ifndef DEB
945   Standard_Integer Nbpnt = 0;
946 #else
947   Standard_Integer Nbpnt;
948 #endif
949   // the initial solution is reframed if necessary.
950   math_Vector ParSol(1,3);
951   Standard_Real NewFirst = PFirst;
952   if(RecP || RecS || RecRst){
953     if(!TheWalk.PerformFirstSection(Func,FInv,FInvP,FInvC,PFirst,Target,Soldep,
954                                     tolesp,TolGuide,RecRst,RecP,RecS,
955                                     NewFirst,ParSol)){
956 #ifdef DEB
957       cout<<"ChFi3d_Builder::ComputeData : calculation fail first section"<<endl;
958 #endif
959       return Standard_False;
960     }
961   }
962   else {
963     ParSol = Soldep;
964   }
965
966   while (again < 2){
967     TheWalk.Perform (Func,FInv,FInvP,FInvC,NewFirst,Last,
968                      MS,TolGuide,ParSol,tolesp,Fleche,Appro);
969
970     if (!TheWalk.IsDone()) {
971 #ifdef DEB
972       cout << "Path not created" << endl;
973 #endif  
974       return Standard_False;
975     }
976   
977     if (reverse) {
978       if (!TheWalk.Complete(Func,FInv,FInvP,FInvC,SpLast)) {
979 #ifdef DEB
980         cout << "Not completed" << endl;
981 #endif
982       }
983     }  
984   
985
986     Lin = TheWalk.Line();
987     Nbpnt = Lin->NbPoints();
988     if (Nbpnt <= 1 && again == 0)  {
989       again++;
990 #ifdef DEB
991       cout <<"one point of the path MS/50 is attempted."<<endl;
992 #endif  
993       MS = MS/50.; Target = Targetsov;
994     }
995     else if (Nbpnt<=nbptmin && again == 0)  {
996       again++;
997 #ifdef DEB
998       cout <<"Number of points is too small, the step is reduced"<<endl;
999 #endif  
1000       Standard_Real u1 = Lin->Point(1).Parameter();
1001       Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1002       MS = (u2-u1)/(nbptmin+1.0);
1003 //      cout << " MS : " << MS << " u1 : " << u1 << " u2 : " << u2 << " nbptmin : " << nbptmin << endl;
1004       Target = Targetsov;
1005     }
1006     else if(Nbpnt<=nbptmin){
1007 #ifdef DEB
1008       cout <<"Number of points is still too small, quit"<<endl;
1009 #endif  
1010       return Standard_False;
1011     }
1012     else {
1013       again = 2;
1014     }
1015   }
1016 #ifdef DRAW
1017   ChFi3d_SettraceDRAWWALK(Standard_True);
1018   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1019 #endif  
1020   if(Forward) Decroch = TheWalk.DecrochEnd();
1021   else Decroch = TheWalk.DecrochStart();
1022   Last = Lin->Point(Nbpnt).Parameter();
1023   First = Lin->Point(1).Parameter();
1024   return Standard_True;
1025 }
1026
1027
1028 //=======================================================================
1029 //function : ComputeData
1030 //purpose  : Heading of the path edge/edge for the bypass of obstacle.
1031 //=======================================================================
1032
1033 Standard_Boolean ChFi3d_Builder::ComputeData
1034 (Handle(ChFiDS_SurfData)&         Data,
1035  const Handle(ChFiDS_HElSpine)&   HGuide,
1036  Handle(BRepBlend_Line)&          Lin,
1037  const Handle(Adaptor3d_HSurface)&  S1,
1038  const Handle(Adaptor2d_HCurve2d)&  PC1,
1039  const Handle(Adaptor3d_TopolTool)& I1,
1040  Standard_Boolean&                Decroch1,
1041  const Handle(Adaptor3d_HSurface)&  S2,
1042  const Handle(Adaptor2d_HCurve2d)&  PC2,
1043  const Handle(Adaptor3d_TopolTool)& I2,
1044  Standard_Boolean&                Decroch2,
1045  Blend_RstRstFunction&            Func,
1046  Blend_SurfCurvFuncInv&           FInv1,
1047  Blend_CurvPointFuncInv&          FInvP1,
1048  Blend_SurfCurvFuncInv&           FInv2,
1049  Blend_CurvPointFuncInv&          FInvP2,
1050  const Standard_Real              PFirst,
1051  const Standard_Real              MaxStep,
1052  const Standard_Real              Fleche,
1053  const Standard_Real              TolGuide,
1054  Standard_Real&                   First,
1055  Standard_Real&                   Last,
1056  const math_Vector&               Soldep,
1057  const Standard_Boolean           Inside,
1058  const Standard_Boolean           Appro,
1059  const Standard_Boolean           Forward,
1060  const Standard_Boolean           RecP1,
1061  const Standard_Boolean           RecRst1,
1062  const Standard_Boolean           RecP2,
1063  const Standard_Boolean           RecRst2)
1064 {
1065   BRepBlend_RstRstLineBuilder TheWalk(S1, PC1, I1, S2, PC2, I2);
1066   
1067   Data->FirstExtensionValue(0);
1068   Data->LastExtensionValue(0); 
1069
1070   Standard_Boolean reverse = (!Forward || Inside);
1071   Standard_Real SpFirst = HGuide->FirstParameter();
1072   Standard_Real SpLast =  HGuide->LastParameter();
1073   Standard_Real Target = SpLast;
1074   if(reverse) Target = SpFirst;
1075   Standard_Real Targetsov = Target;
1076   
1077   Standard_Real MS = MaxStep;
1078   Standard_Integer again = 0;
1079   Standard_Integer nbptmin = 3; //jlr
1080 #ifndef DEB
1081   Standard_Integer Nbpnt = 0;
1082 #else
1083   Standard_Integer Nbpnt;
1084 #endif
1085   // the initial solution is reframed if necessary.
1086   math_Vector ParSol(1,2);
1087   Standard_Real NewFirst = PFirst;
1088   if (RecP1 || RecRst1 || RecP2 || RecRst2) {
1089     if (!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep,
1090                                      tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2,
1091                                      NewFirst, ParSol)){
1092 #ifdef DEB
1093       cout<<"ChFi3d_Builder::ComputeData : fail calculation first section"<<endl;
1094 #endif
1095       return Standard_False;
1096     }
1097   }
1098   else {
1099     ParSol = Soldep;
1100   }
1101
1102   while (again < 2){
1103     TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last,
1104                      MS, TolGuide, ParSol, tolesp, Fleche, Appro);
1105
1106     if (!TheWalk.IsDone()) {
1107 #ifdef DEB
1108       cout << "Path not done" << endl;
1109 #endif  
1110       return Standard_False;
1111     }
1112   
1113     if (reverse) {
1114       if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) {
1115 #ifdef DEB
1116         cout << "Not completed" << endl;
1117 #endif
1118       }
1119     }  
1120   
1121
1122     Lin = TheWalk.Line();
1123     Nbpnt = Lin->NbPoints();
1124     if (Nbpnt <= 1 && again == 0)  {
1125       again++;
1126 #ifdef DEB
1127       cout <<"one point of path MS/50 is attempted."<<endl;
1128 #endif  
1129       MS = MS/50.; Target = Targetsov;
1130     }
1131     else if (Nbpnt<=nbptmin && again == 0)  {
1132       again++;
1133 #ifdef DEB
1134       cout <<"Number of points is too small, the step is reduced"<<endl;
1135 #endif  
1136       Standard_Real u1 = Lin->Point(1).Parameter();
1137       Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1138       MS = (u2-u1)/(nbptmin+1);
1139       Target = Targetsov;
1140     }
1141     else if(Nbpnt<=nbptmin){
1142 #ifdef DEB
1143       cout <<"Number of points is still too small, quit"<<endl;
1144 #endif  
1145       return Standard_False;
1146     }
1147     else {
1148       again = 2;
1149     }
1150   }
1151 #ifdef DRAW
1152   ChFi3d_SettraceDRAWWALK(Standard_True);
1153   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1154 #endif  
1155   if (Forward) {
1156     Decroch1 = TheWalk.Decroch1End();
1157     Decroch2 = TheWalk.Decroch2End();
1158   }
1159   else {
1160     Decroch1 = TheWalk.Decroch1Start();
1161     Decroch2 = TheWalk.Decroch2Start();  
1162   }
1163   Last  = Lin->Point(Nbpnt).Parameter();
1164   First = Lin->Point(1).Parameter();
1165   return Standard_True;
1166 }
1167
1168
1169 //=======================================================================
1170 //function : SimulData
1171 //purpose  : Heading of the path edge/face for the bypass of obstacle in simulation mode.
1172 //=======================================================================
1173
1174 Standard_Boolean ChFi3d_Builder::SimulData
1175 (Handle(ChFiDS_SurfData)&         /*Data*/,
1176  const Handle(ChFiDS_HElSpine)&   HGuide,
1177  Handle(BRepBlend_Line)&          Lin,
1178  const Handle(Adaptor3d_HSurface)&  S1,
1179  const Handle(Adaptor3d_TopolTool)& I1,
1180  const Handle(Adaptor3d_HSurface)&  S2,
1181  const Handle(Adaptor2d_HCurve2d)&  PC2,
1182  const Handle(Adaptor3d_TopolTool)& I2,
1183  Standard_Boolean&                Decroch,
1184  Blend_SurfRstFunction&           Func,
1185  Blend_FuncInv&                   FInv,
1186  Blend_SurfPointFuncInv&          FInvP,
1187  Blend_SurfCurvFuncInv&           FInvC,
1188  const Standard_Real              PFirst,
1189  const Standard_Real              MaxStep,
1190  const Standard_Real              Fleche,
1191  const Standard_Real              TolGuide,
1192  Standard_Real&                   First,
1193  Standard_Real&                   Last,
1194  const math_Vector&               Soldep,
1195  const Standard_Integer           NbSecMin,
1196  const Standard_Boolean           Inside,
1197  const Standard_Boolean           Appro,
1198  const Standard_Boolean           Forward,
1199  const Standard_Boolean           RecP,
1200  const Standard_Boolean           RecS,
1201  const Standard_Boolean           RecRst)
1202 {
1203   BRepBlend_SurfRstLineBuilder TheWalk(S1,I1,S2,PC2,I2);
1204
1205   Standard_Boolean reverse = (!Forward || Inside);
1206   Standard_Real SpFirst = HGuide->FirstParameter();
1207   Standard_Real SpLast =  HGuide->LastParameter();
1208   Standard_Real Target = SpLast;
1209   if(reverse) Target = SpFirst;
1210   Standard_Real Targetsov = Target;
1211   
1212   Standard_Real MS = MaxStep;
1213   Standard_Integer again = 0;
1214 #ifndef DEB
1215   Standard_Integer Nbpnt = 0; 
1216 #else
1217   Standard_Integer Nbpnt; 
1218 #endif
1219   // the starting solution is reframed if needed.
1220   math_Vector ParSol(1,3);
1221   Standard_Real NewFirst = PFirst;
1222   if(RecP || RecS || RecRst){
1223     if(!TheWalk.PerformFirstSection(Func,FInv,FInvP,FInvC,PFirst,Target,Soldep,
1224                                     tolesp,TolGuide,RecRst,RecP,RecS,
1225                                     NewFirst,ParSol)){
1226 #ifdef DEB
1227
1228       cout<<"ChFi3d_Builder::SimulData : fail calculate first section"<<endl;
1229 #endif
1230       return Standard_False;
1231     }
1232   }
1233   else {
1234     ParSol = Soldep;
1235   }
1236
1237   while (again < 2){
1238     TheWalk.Perform (Func,FInv,FInvP,FInvC,NewFirst,Last,
1239                      MS,TolGuide,ParSol,tolesp,Fleche,Appro);
1240     if (!TheWalk.IsDone()) {
1241 #ifdef DEB
1242       cout << "Path not done" << endl;
1243 #endif
1244       return Standard_False;
1245     }
1246     if (reverse) {
1247       if (!TheWalk.Complete(Func,FInv,FInvP,FInvC,SpLast)) {
1248 #ifdef DEB
1249         cout << "Not completed" << endl;
1250 #endif
1251       }
1252     }  
1253     Lin = TheWalk.Line();
1254     Nbpnt = Lin->NbPoints();
1255     if (Nbpnt <= 1 && again == 0)  {
1256       again++;
1257 #ifdef DEB
1258       cout <<"one point of path MS/50 is attempted."<<endl;
1259 #endif
1260       MS = MS/50.; Target = Targetsov;
1261     }
1262     else if (Nbpnt <= NbSecMin && again == 0)  {
1263       again++;
1264 #ifdef DEB
1265       cout <<"Number of points is too small, the step is reduced"<<endl;
1266 #endif
1267       Standard_Real u1 = Lin->Point(1).Parameter();
1268       Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1269       MS = (u2-u1)/(NbSecMin+1);
1270       Target = Targetsov;
1271     }
1272     else if(Nbpnt<=NbSecMin){
1273 #ifdef DEB
1274       cout <<"Number of points is still too small, quit"<<endl;
1275 #endif
1276       return Standard_False;
1277     }
1278     else {
1279       again = 2;
1280     }
1281   }
1282 #ifdef DRAW
1283   ChFi3d_SettraceDRAWWALK(Standard_True);
1284   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1285 #endif  
1286   if(Forward) Decroch = TheWalk.DecrochEnd();
1287   else Decroch = TheWalk.DecrochStart();
1288   Last = Lin->Point(Nbpnt).Parameter();
1289   First = Lin->Point(1).Parameter();
1290   return Standard_True;
1291 }
1292
1293
1294 //=======================================================================
1295 //function : SimulData
1296 //purpose  : Heading of path edge/edge for the bypass
1297 //           of obstacle in simulation mode.
1298 //=======================================================================
1299
1300 Standard_Boolean ChFi3d_Builder::SimulData
1301 (Handle(ChFiDS_SurfData)&         /*Data*/,
1302  const Handle(ChFiDS_HElSpine)&   HGuide,
1303  Handle(BRepBlend_Line)&          Lin,
1304  const Handle(Adaptor3d_HSurface)&  S1,
1305  const Handle(Adaptor2d_HCurve2d)&  PC1,
1306  const Handle(Adaptor3d_TopolTool)& I1,
1307  Standard_Boolean&                Decroch1,
1308  const Handle(Adaptor3d_HSurface)&  S2,
1309  const Handle(Adaptor2d_HCurve2d)&  PC2,
1310  const Handle(Adaptor3d_TopolTool)& I2,
1311  Standard_Boolean&                Decroch2,
1312  Blend_RstRstFunction&            Func,
1313  Blend_SurfCurvFuncInv&           FInv1,
1314  Blend_CurvPointFuncInv&          FInvP1,
1315  Blend_SurfCurvFuncInv&           FInv2,
1316  Blend_CurvPointFuncInv&          FInvP2,
1317  const Standard_Real              PFirst,
1318  const Standard_Real              MaxStep,
1319  const Standard_Real              Fleche,
1320  const Standard_Real              TolGuide,
1321  Standard_Real&                   First,
1322  Standard_Real&                   Last,
1323  const math_Vector&               Soldep,
1324  const Standard_Integer           NbSecMin,
1325  const Standard_Boolean           Inside,
1326  const Standard_Boolean           Appro,
1327  const Standard_Boolean           Forward,
1328  const Standard_Boolean           RecP1,
1329  const Standard_Boolean           RecRst1,
1330  const Standard_Boolean           RecP2,
1331  const Standard_Boolean           RecRst2)
1332 {
1333   BRepBlend_RstRstLineBuilder TheWalk(S1, PC1, I1, S2, PC2, I2);
1334
1335   Standard_Boolean reverse = (!Forward || Inside);
1336   Standard_Real SpFirst = HGuide->FirstParameter();
1337   Standard_Real SpLast =  HGuide->LastParameter();
1338   Standard_Real Target = SpLast;
1339   if(reverse) Target = SpFirst;
1340   Standard_Real Targetsov = Target;
1341   
1342   Standard_Real MS = MaxStep;
1343   Standard_Integer again = 0;
1344 #ifndef DEB
1345   Standard_Integer Nbpnt = 0; 
1346 #else
1347   Standard_Integer Nbpnt; 
1348 #endif
1349   // The initial solution is reframed if necessary.
1350   math_Vector ParSol(1,2);
1351   Standard_Real NewFirst = PFirst;
1352   if (RecP1 || RecRst1 || RecP2 || RecRst2) {
1353     if(!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep,
1354                                     tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2,
1355                                     NewFirst,ParSol)){
1356 #ifdef DEB
1357
1358       cout<<"ChFi3d_Builder::SimulData : calculation fail first section"<<endl;
1359 #endif
1360       return Standard_False;
1361     }
1362   }
1363   else {
1364     ParSol = Soldep;
1365   }
1366
1367   while (again < 2){
1368     TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last,
1369                      MS, TolGuide, ParSol, tolesp, Fleche, Appro);
1370     if (!TheWalk.IsDone()) {
1371 #ifdef DEB
1372       cout << "Path not created" << endl;
1373 #endif
1374       return Standard_False;
1375     }
1376     if (reverse) {
1377       if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) {
1378 #ifdef DEB
1379         cout << "Not completed" << endl;
1380 #endif
1381       }
1382     }  
1383     Lin = TheWalk.Line();
1384     Nbpnt = Lin->NbPoints();
1385     if (Nbpnt <= 1 && again == 0)  {
1386       again++;
1387 #ifdef DEB
1388       cout <<"only one point of path MS/50 is attempted."<<endl;
1389 #endif
1390       MS = MS/50.; Target = Targetsov;
1391     }
1392     else if (Nbpnt <= NbSecMin && again == 0)  {
1393       again++;
1394 #ifdef DEB
1395       cout <<"Number of points is too small, the step is reduced"<<endl;
1396 #endif
1397       Standard_Real u1 = Lin->Point(1).Parameter();
1398       Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1399       MS = (u2-u1)/(NbSecMin+1);
1400       Target = Targetsov;
1401     }
1402     else if(Nbpnt<=NbSecMin){
1403 #ifdef DEB
1404       cout <<"Number of points is still too small, quit"<<endl;
1405 #endif
1406       return Standard_False;
1407     }
1408     else {
1409       again = 2;
1410     }
1411   }
1412 #ifdef DRAW
1413   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1414 #endif
1415   if (Forward) {
1416     Decroch1 = TheWalk.Decroch1End();
1417     Decroch2 = TheWalk.Decroch2End();
1418   }
1419   else {
1420     Decroch1 = TheWalk.Decroch1Start();
1421     Decroch2 = TheWalk.Decroch2Start();  
1422   }  
1423
1424   Last = Lin->Point(Nbpnt).Parameter();
1425   First = Lin->Point(1).Parameter();
1426   return Standard_True;
1427 }
1428
1429
1430
1431
1432 //=======================================================================
1433 //function : ComputeData
1434 //purpose  : Construction of elementary fillet by path.
1435 //
1436 //=======================================================================
1437
1438 Standard_Boolean ChFi3d_Builder::ComputeData
1439 (Handle(ChFiDS_SurfData)& Data,
1440  const Handle(ChFiDS_HElSpine)& HGuide,
1441  const Handle(ChFiDS_Spine)& Spine,
1442  Handle(BRepBlend_Line)& Lin,
1443  const Handle(Adaptor3d_HSurface)& S1,
1444  const Handle(Adaptor3d_TopolTool)& I1,
1445  const Handle(Adaptor3d_HSurface)& S2,
1446  const Handle(Adaptor3d_TopolTool)& I2,
1447  Blend_Function& Func,
1448  Blend_FuncInv& FInv,
1449  const Standard_Real PFirst,
1450  const Standard_Real MaxStep,
1451  const Standard_Real Fleche,
1452  const Standard_Real tolguide,
1453  Standard_Real& First,
1454  Standard_Real& Last,
1455  const Standard_Boolean Inside,
1456  const Standard_Boolean Appro,
1457  const Standard_Boolean Forward,
1458  const math_Vector& Soldep,
1459  Standard_Boolean& intf,
1460  Standard_Boolean& intl,
1461  Standard_Boolean& Gd1,
1462  Standard_Boolean& Gd2,
1463  Standard_Boolean& Gf1,
1464  Standard_Boolean& Gf2,
1465  const Standard_Boolean RecOnS1,
1466  const Standard_Boolean RecOnS2)
1467 {
1468   //The extrensions are created in case of output of two domains
1469   //directly and not by path ( too hasardous ).
1470   Data->FirstExtensionValue(0);
1471   Data-> LastExtensionValue(0);
1472
1473   //The eventual faces are restored to test the jump of edge.
1474   TopoDS_Face F1, F2;
1475   Handle(BRepAdaptor_HSurface) HS = Handle(BRepAdaptor_HSurface)::DownCast(S1); 
1476   if(!HS.IsNull()) F1 = HS->ChangeSurface().Face();
1477   HS = Handle(BRepAdaptor_HSurface)::DownCast(S2); 
1478   if(!HS.IsNull()) F2 = HS->ChangeSurface().Face();
1479   
1480   // Path framing variables
1481   Standard_Real TolGuide=tolguide, TolEsp = tolesp;
1482   Standard_Integer nbptmin = 4;
1483
1484   BRepBlend_Walking TheWalk(S1,S2,I1,I2);
1485
1486   //Start of removal, 2D path controls 
1487   //that qui s'accomodent mal des surfaces a parametrages non homogenes
1488   //en u et en v are extinguished.
1489   TheWalk.Check2d(0);
1490   
1491   Standard_Real MS = MaxStep;
1492   Standard_Integer Nbpnt;
1493   Standard_Real SpFirst = HGuide->FirstParameter();
1494   Standard_Real SpLast =  HGuide->LastParameter();
1495
1496   // When the start point is inside, the path goes first to the left  
1497   // to determine the Last for the periodicals.
1498   Standard_Boolean reverse = (!Forward || Inside);
1499   Standard_Real Target;
1500   if(reverse){
1501     Target = SpFirst;
1502     if(!intf) Target = Last;
1503   }
1504   else{
1505     Target = SpLast + Abs(SpLast);
1506     if(!intl) Target = Last;
1507   }
1508
1509   // In case if the singularity is pre-determined,
1510   // the path is indicated.
1511   if (!Spine.IsNull()){
1512     if (Spine->IsTangencyExtremity(Standard_True)) {
1513       TopoDS_Vertex V = Spine->FirstVertex();
1514       TopoDS_Edge E = Spine->Edges(1);
1515       Standard_Real param =  Spine->FirstParameter();
1516       Blend_Point BP;
1517       if (CompBlendPoint(V, E, param, F1, F2, BP)) {
1518         math_Vector vec(1,4);
1519         BP.ParametersOnS1(vec(1),vec(2));
1520         BP.ParametersOnS2(vec(3),vec(4));
1521         Func.Set(param);
1522         if (Func.IsSolution(vec, tolesp)) {
1523           TheWalk.AddSingularPoint(BP);
1524         }
1525       }
1526     }
1527     if (Spine->IsTangencyExtremity(Standard_False)) {
1528       TopoDS_Vertex V = Spine->LastVertex();
1529       TopoDS_Edge E = Spine->Edges( Spine->NbEdges()); 
1530       Standard_Real param =  Spine->LastParameter();
1531       Blend_Point BP;
1532       if (CompBlendPoint(V, E, param, F1, F2, BP)) {
1533         math_Vector vec(1,4);
1534         BP.ParametersOnS1(vec(1),vec(2));
1535         BP.ParametersOnS2(vec(3),vec(4));
1536         Func.Set(param);
1537         if (Func.IsSolution(vec, tolesp)) {
1538           TheWalk.AddSingularPoint(BP);
1539         }
1540       }
1541     }
1542   }
1543
1544   //The starting solution is reframed if necessary.
1545   //**********************************************//
1546   math_Vector ParSol(1,4);
1547   Standard_Real NewFirst = PFirst;
1548   if(RecOnS1 || RecOnS2){
1549     if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep,
1550                                     tolesp,TolGuide,RecOnS1,RecOnS2,
1551                                     NewFirst,ParSol)){
1552 #ifdef DEB
1553       cout<<"ChFi3d_Builder::ComputeData : calculation fail first section"<<endl;
1554 #endif
1555       return Standard_False;
1556     }
1557   }
1558   else {
1559     ParSol = Soldep;
1560   }
1561
1562   //First the valid part is calculate, without caring for the extensions.
1563   //******************************************************************//
1564   Standard_Integer again = 0;
1565   Standard_Boolean tchernobyl = 0;
1566 #ifndef DEB
1567   Standard_Real u1sov = 0., u2sov = 0.;
1568 #else
1569   Standard_Real u1sov, u2sov;
1570 #endif
1571   TopoDS_Face bif;
1572   //Max step is relevant, but too great, the vector is required to detect
1573   //the twists.
1574   if( (Abs(Last-First) <= MS * 5.) &&
1575       (Abs(Last-First) >= 0.01*Abs(NewFirst-Target)) ){ 
1576     MS = Abs(Last-First)*0.2; 
1577   }
1578
1579   while(again < 3){
1580     //Path. 
1581     if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide;
1582     else {
1583       if (5*TolGuide > MS) TolGuide = MS/5;
1584       if (5*TolEsp > MS) TolEsp = MS/5;
1585     }
1586     TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
1587                     ParSol,TolEsp,Fleche,Appro);
1588     if (!TheWalk.IsDone()) {
1589 #ifdef DEB
1590       cout << "Path is not created" << endl;
1591 #endif
1592       return Standard_False;
1593     }
1594     Lin = TheWalk.Line();
1595     if(HGuide->IsPeriodic() && Inside) {
1596       SpFirst = Lin->Point(1).Parameter();
1597       SpLast  = SpFirst + HGuide->Period();
1598       HGuide->ChangeCurve().FirstParameter(SpFirst);
1599       HGuide->ChangeCurve().LastParameter (SpLast );
1600       HGuide->ChangeCurve().SetOrigin(SpFirst);
1601     }
1602     Standard_Boolean complmnt = Standard_True;
1603     if (Inside)  complmnt = TheWalk.Complete(Func,FInv,SpLast);
1604     if(!complmnt){
1605 #ifdef DEB
1606       cout << "Not completed" << endl;
1607 #endif
1608       return Standard_False;
1609     }
1610     
1611     //The result is controlled using two criterions :
1612     //- if there is enough points,
1613     //- if one has gone far enough.
1614     Nbpnt = Lin->NbPoints();
1615     if (Nbpnt == 0){
1616 #ifdef DEB
1617       cout <<"0 point of path, quit."<<endl;
1618 #endif
1619       return Standard_False;
1620     }
1621     Standard_Real fpointpar = Lin->Point(1).Parameter();
1622     Standard_Real lpointpar = Lin->Point(Nbpnt).Parameter();
1623     
1624     Standard_Real factor =  1./(nbptmin + 1);
1625     Standard_Boolean okdeb = (Forward && !Inside);  
1626     Standard_Boolean okfin = (!Forward && !Inside);
1627     if(!okdeb){
1628       Standard_Integer narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1629       Standard_Integer narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1630       okdeb = (narc1 > 0 || narc2 > 0 || (fpointpar-First) < 10*TolGuide); 
1631     }
1632     if(!okfin){
1633       Standard_Integer narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1634       Standard_Integer narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1635       okfin = (narc1 > 0 || narc2 > 0 || (Last-lpointpar) < 10*TolGuide);
1636     }
1637     if(!okdeb || !okfin || Nbpnt == 1){
1638       //It drags, the controls are extended, it is  expected to evaluate a
1639       //satisfactory maximum step. If it already done, quit.
1640       if(tchernobyl){
1641 #ifdef DEB
1642         cout <<"If it drags without control, quit."<<endl;
1643 #endif
1644         return Standard_False;
1645       }
1646       tchernobyl = Standard_True;
1647       TheWalk.Check(0);
1648       if (Nbpnt == 1){
1649 #ifdef DEB
1650         cout <<"only one point of path MS/100 is attempted"<<endl;
1651         cout <<"and the controls are extended."<<endl;
1652 #endif
1653         MS *= 0.01;
1654       }
1655       else{
1656 #ifdef DEB
1657         cout <<"It drags, the controls are extended."<<endl;
1658 #endif
1659         MS = (lpointpar-fpointpar)/Nbpnt; //EvalStep(Lin);
1660       }
1661     }
1662     else if (Nbpnt < nbptmin){
1663       if(again == 0){
1664 #ifdef DEB
1665         cout <<"Number of points is too small, the step is reduced"<<endl;
1666 #endif
1667         u1sov = fpointpar;
1668         u2sov = lpointpar;
1669         MS = (lpointpar - fpointpar) * factor;
1670       }
1671       else if(again == 1){
1672         if(Abs(fpointpar-u1sov)>=TolGuide || 
1673            Abs(lpointpar-u2sov)>=TolGuide){
1674 #ifdef DEB
1675           cout <<"Number of points is still too small, the step is reduced"<<endl;
1676 #endif  
1677           MS = (lpointpar - fpointpar) * factor;
1678         }
1679         else{
1680 #ifdef DEB
1681           cout <<"Number of points is still too small, quit"<<endl;
1682 #endif  
1683           return Standard_False;
1684         }
1685       }
1686       again++;
1687     }
1688     else {
1689       again = 3;
1690     }
1691   }
1692
1693   if(TheWalk.TwistOnS1()){
1694     Data->TwistOnS1(Standard_True);
1695 #ifdef DEB
1696     cout<<"Path completed, but TWIST on S1"<<endl;
1697 #endif
1698   }
1699   if(TheWalk.TwistOnS2()){
1700     Data->TwistOnS2(Standard_True);
1701 #ifdef DEB
1702     cout<<"Parh completed, but TWIST on S2"<<endl;
1703 #endif
1704   }
1705
1706
1707   //Here there is a more or less presentable result 
1708   //however it covers a the minimum zone.
1709   //The extensions are targeted.
1710   //*****************************//
1711
1712   Gd1 = Gd2 = Gf1 = Gf2 = Standard_False;
1713   
1714   Standard_Boolean unseulsuffitdeb = (intf >= 2);
1715   Standard_Boolean unseulsuffitfin = (intl >= 2);
1716   Standard_Boolean noproldeb = (intf >= 3);
1717   Standard_Boolean noprolfin = (intl >= 3);
1718
1719   Standard_Real Rab = 0.03*(SpLast-SpFirst);
1720
1721   Standard_Boolean debarc1 = 0, debarc2 = 0;
1722   Standard_Boolean debcas1 = 0, debcas2 = 0;
1723   Standard_Boolean debobst1 = 0, debobst2 = 0;
1724
1725   Standard_Boolean finarc1 = 0, finarc2 = 0;
1726   Standard_Boolean fincas1 = 0, fincas2 = 0;
1727   Standard_Boolean finobst1 = 0, finobst2 = 0;
1728
1729   Standard_Integer narc1, narc2;
1730
1731   Standard_Boolean backwContinueFailed = Standard_False; // eap
1732   if(reverse && intf) {
1733     narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1734     narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1735     if(narc1 != 0) {
1736       ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(),
1737                             Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1738       debarc1 = Standard_True;
1739       if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){
1740         //It is checked if there is not an obstacle.
1741         debcas1 = Standard_True;
1742         if(!Spine.IsNull()){
1743           if(Spine->IsPeriodic()){
1744             debobst1 = 1;
1745           }
1746           else{
1747             debobst1 = IsObst(Data->VertexFirstOnS1(),
1748                               Spine->FirstVertex(),myVEMap);
1749           }
1750         }
1751       }
1752     }
1753     if(narc2 != 0){
1754       ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(),
1755                             Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1756       debarc2 = Standard_True;
1757       if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){
1758         //It is checked if it is not an obstacle.
1759         debcas2 = Standard_True;
1760         if(!Spine.IsNull()){
1761           if(Spine->IsPeriodic()){
1762             debobst2 = 1;
1763           }
1764           else{
1765             debobst2 = IsObst(Data->VertexFirstOnS2(),
1766                               Spine->FirstVertex(),myVEMap);
1767           }
1768         }
1769       }
1770     }
1771     Standard_Boolean oncontinue = !noproldeb && (narc1 != 0 || narc2 != 0);
1772     if(debobst1 || debobst2) oncontinue = Standard_False;
1773     else if(debcas1 && debcas2) oncontinue = Standard_False;
1774     else if((!debcas1 && debarc1) || (!debcas2 && debarc2)) oncontinue = Standard_False;
1775
1776     if(oncontinue) {
1777       TheWalk.ClassificationOnS1(!debarc1);
1778       TheWalk.ClassificationOnS2(!debarc2);
1779       TheWalk.Check2d(Standard_True); // It should be strict (PMN)
1780       TheWalk.Continu(Func,FInv,Target);
1781       TheWalk.ClassificationOnS1(Standard_True);
1782       TheWalk.ClassificationOnS2(Standard_True);
1783       TheWalk.Check2d(Standard_False);
1784       narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1785       narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1786 //  modified by eap Fri Feb  8 11:43:48 2002 ___BEGIN___
1787       if(!debarc1)
1788         if (narc1 == 0)
1789           backwContinueFailed = Lin->StartPointOnFirst().ParameterOnGuide() > Target;
1790         else {
1791           ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(),
1792                                 Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1793           debarc1 = Standard_True;
1794           if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){
1795             //It is checked if it is not an obstacle.
1796             debcas1 = Standard_True;
1797 //          if(!Spine.IsNull()) {
1798 //            if(Spine->IsPeriodic()){
1799 //              debobst1 = 1;
1800 //            }
1801 //            else{
1802 //              debobst1 = IsObst(Data->VertexFirstOnS1(),
1803 //                                Spine->FirstVertex(),myVEMap);
1804 //            }
1805 //          }
1806           }
1807         }
1808       if(!debarc2)
1809         if (narc2 == 0)
1810           backwContinueFailed = Lin->StartPointOnSecond().ParameterOnGuide() > Target;
1811         else {
1812           ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(),
1813                                 Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1814           debarc2 = Standard_True;
1815           if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){
1816             //It is checked if it is not an obstacle.
1817             debcas2 = Standard_True;
1818 //             if(!Spine.IsNull()){
1819 //               if(Spine->IsPeriodic()){
1820 //                 debobst2 = 1;
1821 //               }
1822 //               else{
1823 //                 debobst2 = IsObst(Data->VertexFirstOnS2(),
1824 //                                   Spine->FirstVertex(),myVEMap);
1825 //               }
1826 //             }
1827           }
1828         }
1829       if (backwContinueFailed) {
1830         // if we leave backwContinueFailed as is, we will stop in this direction
1831         // but we are to continue if there are no more faces on the side with arc
1832         // check this condition
1833         const ChFiDS_CommonPoint& aCP
1834           = debarc1 ? Data->VertexFirstOnS1() : Data->VertexFirstOnS2();
1835         if (aCP.IsOnArc() && bif.IsNull())
1836           backwContinueFailed = Standard_False;
1837       }
1838     }
1839   }
1840   Standard_Boolean forwContinueFailed = Standard_False;
1841 //  modified by eap Fri Feb  8 11:44:11 2002 ___END___
1842   if(Forward && intl) {
1843     Target = SpLast;
1844     narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1845     narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1846     if(narc1 != 0){
1847       ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(),
1848                             Standard_False, Data->ChangeVertexLastOnS1(),tolesp);
1849       finarc1 = Standard_True;
1850       if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){
1851              //It is checked if it is not an obstacle.
1852         fincas1 = Standard_True;
1853         if(!Spine.IsNull()){
1854           finobst1 = IsObst(Data->VertexLastOnS1(),
1855                             Spine->LastVertex(),myVEMap);
1856         }
1857       }
1858     }
1859     if(narc2 != 0){
1860       ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(),
1861                             Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1862       finarc2 = Standard_True;
1863       if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){
1864          //It is checked if it is not an obstacle.
1865         fincas2 = Standard_True;
1866         if(!Spine.IsNull()){
1867           finobst2 = IsObst(Data->VertexLastOnS2(),
1868                             Spine->LastVertex(),myVEMap);
1869         }
1870       }
1871     }
1872     Standard_Boolean oncontinue = !noprolfin && (narc1 != 0 || narc2 != 0);
1873     if(finobst1 || finobst2) oncontinue = Standard_False;
1874     else if(fincas1 && fincas2) oncontinue = Standard_False;
1875     else if((!fincas1 && finarc1) || (!fincas2 && finarc2)) oncontinue = Standard_False;
1876     
1877     if(oncontinue){
1878       TheWalk.ClassificationOnS1(!finarc1);
1879       TheWalk.ClassificationOnS2(!finarc2);
1880       TheWalk.Check2d(Standard_True); // It should be strict (PMN)
1881       TheWalk.Continu(Func,FInv,Target);
1882       TheWalk.ClassificationOnS1(Standard_True);
1883       TheWalk.ClassificationOnS2(Standard_True);
1884       TheWalk.Check2d(Standard_False);
1885       narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1886       narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1887 //  modified by eap Fri Feb  8 11:44:57 2002 ___BEGIN___
1888       if(!finarc1)
1889         if (narc1 == 0) 
1890           forwContinueFailed = Lin->EndPointOnFirst().ParameterOnGuide() < Target;
1891         else {
1892           ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(),
1893                                 Standard_False, Data->ChangeVertexLastOnS1(),tolesp);
1894           finarc1 = Standard_True;
1895           if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){
1896              //It is checked if it is not an obstacle.
1897             fincas1 = Standard_True;
1898 //          if(!Spine.IsNull()){
1899 //            finobst1 = IsObst(Data->VertexLastOnS1(),
1900 //                              Spine->LastVertex(),myVEMap);
1901 //          }
1902           }
1903         }
1904       if(!finarc2)
1905         if (narc2 == 0)
1906           forwContinueFailed = Lin->EndPointOnSecond().ParameterOnGuide() < Target;
1907         else {
1908           ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(),
1909                                 Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1910           finarc2 = Standard_True;
1911           if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){
1912             //On regarde si ce n'est pas un obstacle.
1913             fincas2 = Standard_True;
1914 //          if(!Spine.IsNull()){
1915 //            finobst2 = IsObst(Data->VertexLastOnS2(),
1916 //                              Spine->LastVertex(),myVEMap);
1917 //          }
1918           }
1919         }
1920       if (forwContinueFailed) {
1921         // if we leave forwContinueFailed as is, we will stop in this direction
1922         // but we are to continue if there are no more faces on the side with arc
1923         // check this condition
1924         const ChFiDS_CommonPoint& aCP
1925           = finarc1 ? Data->VertexLastOnS1() : Data->VertexLastOnS2();
1926         if (aCP.IsOnArc() && bif.IsNull())
1927           forwContinueFailed = Standard_False;
1928       }
1929 //  modified by eap Fri Feb  8 11:45:10 2002 ___END___
1930     }
1931   }
1932   Nbpnt = Lin->NbPoints();
1933 #ifdef DRAW
1934   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False);
1935 #endif  
1936   First = Lin->Point(1).Parameter();
1937   Last  = Lin->Point(Nbpnt).Parameter();
1938
1939   // ============= INVALIDATION EVENTUELLE =============
1940   // ------ Preparation des prolongement par plan tangent -----
1941   if(reverse && intf){
1942     Gd1 = debcas1/* && !debobst1*/; // skv(occ67)
1943     Gd2 = debcas2/* && !debobst2*/; // skv(occ67)
1944     if ((debarc1^debarc2) && !unseulsuffitdeb && (First!=SpFirst)) {
1945       // Case of incomplete path, of course this ends badly : 
1946       // the result is truncated instead of exit.
1947       Standard_Real sortie;
1948       Standard_Integer ind;
1949       if (debarc1)  sortie = Data->VertexFirstOnS1().Parameter();
1950       else  sortie = Data->VertexFirstOnS2().Parameter();
1951       if (sortie - First > tolesp) {
1952         ind = SearchIndex(sortie, Lin);
1953         if (Lin->Point(ind).Parameter() == sortie) ind--;
1954         if (ind >= 1) {
1955           Lin->Remove(1, ind);
1956           UpdateLine(Lin, Standard_True);
1957         }
1958         Nbpnt = Lin->NbPoints();
1959         First = Lin->Point(1).Parameter();
1960       }
1961     }
1962     else if ((intf>=5) && !debarc1 && !debarc2 && (First!=SpFirst)) {
1963       Standard_Real sortie = (2*First+Last)/3;
1964       Standard_Integer ind;
1965       if (sortie - First > tolesp) {
1966         ind = SearchIndex(sortie, Lin);
1967         if (Lin->Point(ind).Parameter() == sortie) ind--;
1968         if (Nbpnt-ind < 3) ind = Nbpnt -3;
1969         if (ind >= 1) {
1970           Lin->Remove(1, ind);
1971           UpdateLine(Lin, Standard_True);
1972         }
1973         Nbpnt = Lin->NbPoints();
1974         First = Lin->Point(1).Parameter();
1975       }
1976     }
1977     if(Gd1 && Gd2){
1978       Target = Min((Lin->Point(1).Parameter() - Rab),First);
1979       Target = Max(Target,SpFirst);
1980       Data->FirstExtensionValue(Abs(Lin->Point(1).Parameter()-Target));
1981     }
1982     if (intf && !unseulsuffitdeb) intf = (Gd1 && Gd2)//;
1983       || backwContinueFailed; // eap
1984     else if (intf && unseulsuffitdeb && (intf<5)) {
1985       intf = (Gd1 || Gd2);
1986       // It is checked if there is no new face.
1987       if (intf && 
1988           ((!debcas1 && debarc1) || (!debcas2 && debarc2)) ) intf = 0;  
1989     }
1990     else if (intf < 5) intf = 0;
1991   }
1992
1993   if(Forward && intl){
1994     Gf1 = fincas1/* && !finobst1*/; // skv(occ67)
1995     Gf2 = fincas2/* && !finobst2*/; // skv(occ67)
1996     if ((finarc1 ^finarc2) && !unseulsuffitfin && (Last!=SpLast)) {
1997       // Case of incomplete path, of course, this ends badly : 
1998       // the result is truncated instead of exit.
1999       Standard_Real sortie;
2000       Standard_Integer ind;
2001       if (finarc1)  sortie = Data->VertexLastOnS1().Parameter();
2002       else  sortie = Data->VertexLastOnS2().Parameter();
2003       if (Last - sortie > tolesp) {
2004         ind = SearchIndex(sortie, Lin);
2005         if (Lin->Point(ind).Parameter() == sortie) ind++;
2006         if (ind<= Nbpnt) {
2007           Lin->Remove(ind, Nbpnt);
2008           UpdateLine(Lin, Standard_False);
2009         }
2010         Nbpnt = Lin->NbPoints();
2011         Last = Lin->Point(Nbpnt).Parameter();
2012       }
2013     }
2014     else if ((intl>=5) && !finarc1 && !finarc2 && (Last!=SpLast) ) {
2015       // The same in case when the entire "Lin" is an extension
2016       Standard_Real sortie = (First+2*Last)/3;
2017       Standard_Integer ind;
2018       if (Last - sortie > tolesp) {
2019         ind = SearchIndex(sortie, Lin);
2020         if (Lin->Point(ind).Parameter() == sortie) ind++;
2021         if (ind < 3) ind = 3;
2022         if (ind <= Nbpnt) {
2023           Lin->Remove(ind, Nbpnt);
2024           UpdateLine(Lin, Standard_False);
2025         }
2026         Nbpnt = Lin->NbPoints();
2027         Last = Lin->Point(Nbpnt).Parameter();
2028       }
2029     }
2030     if(Gf1 && Gf2) {
2031       Target = Max((Lin->Point(Nbpnt).Parameter() + Rab),Last);
2032       Target = Min(Target,SpLast);
2033       Data->LastExtensionValue(Abs(Target-Lin->Point(Nbpnt).Parameter()));
2034     }    
2035
2036     if (intl && !unseulsuffitfin) intl = (Gf1 && Gf2)//;
2037       || forwContinueFailed;  // eap
2038     else if (intl && unseulsuffitfin && (intl<5)) {
2039       intl = (Gf1 || Gf2);// It is checked if there is no new face.
2040       if (intl && 
2041           ((!fincas1 && finarc1) || (!fincas2 && finarc2)) ) intl = 0;  
2042     }
2043     else if (intl <5) intl = 0;
2044   }
2045   return Standard_True;
2046 }
2047
2048 //=======================================================================
2049 //function : SimulData
2050 //purpose  : 
2051 //=======================================================================
2052
2053 Standard_Boolean ChFi3d_Builder::SimulData
2054 (Handle(ChFiDS_SurfData)& /*Data*/,
2055  const Handle(ChFiDS_HElSpine)& HGuide,
2056  Handle(BRepBlend_Line)& Lin,
2057  const Handle(Adaptor3d_HSurface)& S1,
2058  const Handle(Adaptor3d_TopolTool)& I1,
2059  const Handle(Adaptor3d_HSurface)& S2,
2060  const Handle(Adaptor3d_TopolTool)& I2,
2061  Blend_Function& Func,
2062  Blend_FuncInv& FInv,
2063  const Standard_Real PFirst,
2064  const Standard_Real MaxStep,
2065  const Standard_Real Fleche,
2066  const Standard_Real tolguide,
2067  Standard_Real& First,
2068  Standard_Real& Last,
2069  const Standard_Boolean Inside,
2070  const Standard_Boolean Appro,
2071  const Standard_Boolean Forward,
2072  const math_Vector& Soldep,
2073  const Standard_Integer NbSecMin,
2074  const Standard_Boolean RecOnS1,
2075  const Standard_Boolean RecOnS2)
2076 {
2077   BRepBlend_Walking TheWalk(S1,S2,I1,I2);
2078   TheWalk.Check2d(Standard_False);
2079   
2080   Standard_Real MS = MaxStep;
2081   Standard_Real TolGuide=tolguide, TolEsp = tolesp;
2082   Standard_Integer Nbpnt;
2083   Standard_Real SpFirst = HGuide->FirstParameter();
2084   Standard_Real SpLast =  HGuide->LastParameter();
2085   Standard_Boolean reverse = (!Forward || Inside);
2086   Standard_Real Target;
2087   if(reverse){
2088     Target = SpFirst;
2089   }
2090   else{
2091     Target = SpLast;
2092   }
2093
2094   Standard_Real Targetsov = Target;
2095 #ifndef DEB
2096   Standard_Real u1sov = 0., u2sov = 0.; 
2097 #else
2098   Standard_Real u1sov, u2sov; 
2099 #endif
2100   // on recadre la solution de depart a la demande.
2101   math_Vector ParSol(1,4);
2102   Standard_Real NewFirst = PFirst;
2103   if(RecOnS1 || RecOnS2){
2104     if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep,
2105                                     tolesp,TolGuide,RecOnS1,RecOnS2,
2106                                     NewFirst,ParSol)){
2107 #ifdef DEB
2108       cout<<"ChFi3d_Builder::SimulData : calculation fail first section"<<endl;
2109 #endif
2110       return Standard_False;
2111     }
2112   }
2113   else {
2114     ParSol = Soldep;
2115   }
2116   Standard_Integer again = 0;
2117   while(again < 3){
2118      // When the start point is inside, the path goes first to the left  
2119      // to determine the Last for the periodicals.
2120     if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide;
2121     else  {
2122       if (5*TolGuide > MS) TolGuide = MS/5;
2123       if (5*TolEsp > MS) TolEsp = MS/5;
2124     }
2125       
2126     TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
2127                     ParSol,TolEsp,Fleche,Appro);
2128     
2129     if (!TheWalk.IsDone()) {
2130 #ifdef DEB
2131       cout << "Path not created" << endl;
2132 #endif
2133       return Standard_False;
2134     }
2135     Lin = TheWalk.Line();
2136     if(reverse){
2137       if(HGuide->IsPeriodic()) {
2138         SpFirst = Lin->Point(1).Parameter();
2139         SpLast  = SpFirst + HGuide->Period();
2140         HGuide->ChangeCurve().FirstParameter(SpFirst);
2141         HGuide->ChangeCurve().LastParameter (SpLast );
2142       }
2143       Standard_Boolean complmnt = Standard_True;
2144       if (Inside)  complmnt = TheWalk.Complete(Func,FInv,SpLast);
2145       if(!complmnt){
2146 #ifdef DEB
2147         cout << "Not completed" << endl;
2148 #endif
2149         return Standard_False;
2150       }
2151     }
2152     Nbpnt = Lin->NbPoints();
2153     Standard_Real factor =  1./(NbSecMin + 1);
2154     if (Nbpnt == 0){
2155 #ifdef DEB
2156       cout <<"0 point of path, quit."<<endl;
2157 #endif
2158       return Standard_False;
2159     }
2160     else if (Nbpnt == 1 && again == 0)  {
2161       again++;
2162 #ifdef DEB
2163       cout <<"only one point of path, MS/100 is attempted."<<endl;
2164 #endif
2165       MS *= 0.01; Target = Targetsov;
2166       u1sov = u2sov = Lin->Point(1).Parameter();
2167     }
2168     else if (Nbpnt< NbSecMin && again == 0)  {
2169       again++;
2170 #ifdef DEB
2171       cout <<"Number of points is too small, the step is reduced"<<endl;
2172 #endif
2173       Standard_Real u1 = u1sov = Lin->Point(1).Parameter();
2174       Standard_Real u2 = u2sov = Lin->Point(Nbpnt).Parameter();
2175       MS = (u2-u1)*factor;
2176       Target = Targetsov;
2177     }
2178     else if (Nbpnt < NbSecMin && again == 1)  {
2179       Standard_Real u1 = Lin->Point(1).Parameter();
2180       Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
2181       if(Abs(u1-u1sov)>=TolGuide || Abs(u2-u2sov)>=TolGuide){
2182         again++;
2183 #ifdef DEB
2184         cout <<"Number of points is still too small, the step is reduced"<<endl;
2185 #endif
2186         MS /= 100;
2187         Target = Targetsov;
2188       }
2189       else{
2190 #ifdef DEB
2191         cout <<"Number of points is still too small, quit"<<endl;
2192 #endif
2193         return Standard_False;
2194       }
2195     }
2196     else if(Nbpnt < NbSecMin){
2197 #ifdef DEB
2198       cout <<"Number of points is still too small, quit"<<endl;
2199 #endif
2200       return Standard_False;
2201     }
2202     else {
2203       again = 3;
2204     }
2205   }
2206 #ifdef DRAW
2207   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False);
2208 #endif  
2209   First = Lin->Point(1).Parameter();
2210   Last  = Lin->Point(Nbpnt).Parameter();
2211   return Standard_True;
2212 }
2213