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