0022727: Fillet not produces a result
[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
525   Standard_Integer Degmax = 20, Segmax = 100;
526   BRepBlend_AppSurface approx (TheFunc, 
527                                lin->Point(1).Parameter(),
528                                lin->Point(lin->NbPoints()).Parameter(),
529                                tolapp3d, 1.e-5, //tolapp2d, tolerance max
530                                tolappangle, // Contact G1 
531                                myConti, Degmax, Segmax);  
532   if (!approx.IsDone()) {
533 #ifdef DEB
534     cout << "Approximation non faite !!!" << endl;
535 #endif
536     return Standard_False;
537   }
538 #ifdef DEB
539   approx.Dump(cout);
540 #endif
541   return StoreData( Data, approx, lin, S1, S2, Or1, Gd1, Gd2, Gf1, Gf2, Reversed);
542
543
544
545 //=======================================================================
546 //function : CompleteData
547 //purpose  : New overload for functions surf/rst
548 // jlr le 28/07/97 branchement F(t)
549 //=======================================================================
550
551 Standard_Boolean ChFi3d_Builder::CompleteData
552 (Handle(ChFiDS_SurfData)&        Data,
553  Blend_SurfRstFunction&          Func,
554  Handle(BRepBlend_Line)&         lin,
555  const Handle(Adaptor3d_HSurface)& S1,
556  const Handle(Adaptor3d_HSurface)& S2,
557  const TopAbs_Orientation        Or,
558  const Standard_Boolean          Reversed)
559 {
560   Handle(BRepBlend_AppFuncRst) TheFunc 
561     = new (BRepBlend_AppFuncRst)(lin, Func, tolapp3d, 1.e-5);
562   BRepBlend_AppSurface approx (TheFunc, 
563                                lin->Point(1).Parameter(),
564                                lin->Point(lin->NbPoints()).Parameter(),
565                                tolapp3d, 1.e-5, //tolapp2d, tolerance max
566                                tolappangle, // Contact G1 
567                                myConti);  
568  if (!approx.IsDone()) {
569 #ifdef DEB
570     cout << "Approximation is not done!" << endl;
571 #endif  
572     return Standard_False;
573   }
574 #ifdef DEB
575   approx.Dump(cout);
576 #endif
577
578   return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0,Reversed);
579
580
581
582
583 //=======================================================================
584 //function : CompleteData
585 //purpose  : New overload for functions rst/rst
586 // jlr le 28/07/97 branchement F(t)
587 //=======================================================================
588
589 Standard_Boolean ChFi3d_Builder::CompleteData
590 (Handle(ChFiDS_SurfData)&        Data,
591  Blend_RstRstFunction&           Func,
592  Handle(BRepBlend_Line)&         lin,
593  const Handle(Adaptor3d_HSurface)& S1,
594  const Handle(Adaptor3d_HSurface)& S2,
595  const TopAbs_Orientation        Or)
596 {
597   Handle(BRepBlend_AppFuncRstRst) TheFunc 
598     = new (BRepBlend_AppFuncRstRst)(lin, Func, tolapp3d, 1.e-5);
599   BRepBlend_AppSurface approx (TheFunc, 
600                                lin->Point(1).Parameter(),
601                                lin->Point(lin->NbPoints()).Parameter(),
602                                tolapp3d, 1.e-5, //tolapp2d, tolerance max
603                                tolappangle, // Contact G1 
604                                myConti);  
605  if (!approx.IsDone()) {
606 #ifdef DEB
607     cout << "Approximation non faite !!!" << endl;
608 #endif  
609     return Standard_False;
610   }
611 #ifdef DEB
612   approx.Dump(cout);
613 #endif
614
615   return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0);
616
617
618
619
620
621 //=======================================================================
622 //function : StoreData
623 //purpose  : Copy of an approximation result in SurfData.
624 //=======================================================================
625
626 Standard_Boolean ChFi3d_Builder::StoreData(Handle(ChFiDS_SurfData)& Data,
627                                            const AppBlend_Approx& approx,
628                                            const Handle(BRepBlend_Line)& lin,
629                                            const Handle(Adaptor3d_HSurface)& S1,
630                                            const Handle(Adaptor3d_HSurface)& S2,
631                                            const TopAbs_Orientation Or1,
632                                            const Standard_Boolean Gd1,
633                                            const Standard_Boolean Gd2,
634                                            const Standard_Boolean Gf1,
635                                            const Standard_Boolean Gf2,
636                                            const Standard_Boolean Reversed)
637 {
638   // Small control tools.
639   static Handle(GeomAdaptor_HCurve) checkcurve;
640   if(checkcurve.IsNull()) checkcurve = new GeomAdaptor_HCurve();
641   GeomAdaptor_Curve& chc = checkcurve->ChangeCurve();
642   Standard_Real tolget3d, tolget2d, tolaux, tolC1,  tolcheck;
643 #ifndef DEB
644   Standard_Real  tolC2 = 0.;
645 #else
646   Standard_Real  tolC2;
647 #endif
648   approx.TolReached(tolget3d, tolget2d);
649   tolaux = approx.TolCurveOnSurf(1);
650   tolC1 = tolget3d + tolaux;
651   if(!S2.IsNull()) {
652     tolaux = approx.TolCurveOnSurf(2);
653     tolC2 = tolget3d + tolaux;
654   }
655
656   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
657   // By default parametric space is created using a square surface
658   // to be able to parameterize in U by # R*teta // a revoir lbo 29/08/97
659   const TColStd_Array1OfReal& ku = approx.SurfUKnots();
660   const TColStd_Array1OfReal& kv = approx.SurfVKnots();
661   Standard_Real larg = (kv(kv.Upper())-kv(kv.Lower()));
662   TColStd_Array1OfReal& kku = *((TColStd_Array1OfReal*)((void*)&ku));
663   BSplCLib::Reparametrize(0.,larg,kku);
664   Handle(Geom_BSplineSurface) Surf = 
665     new Geom_BSplineSurface(approx.SurfPoles(),approx.SurfWeights(),
666                             kku,kv,
667                             approx.SurfUMults(),approx.SurfVMults(),
668                             approx.UDegree(),approx.VDegree());
669 // extension of the surface 
670
671   Standard_Real length1,length2;
672   length1=Data->FirstExtensionValue();
673   length2=Data->LastExtensionValue();
674   if (length1 > Precision::Confusion())
675     GeomLib::ExtendSurfByLength(Surf,length1,1,Standard_False,Standard_False);
676   if (length2 >  Precision::Confusion())
677     GeomLib::ExtendSurfByLength(Surf,length2,1,Standard_False,Standard_True);
678
679   Data->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(Surf,tolget3d)));
680
681 #ifdef DRAW
682   ChFi3d_SettraceDRAWFIL(Standard_True);
683   if (ChFi3d_GettraceDRAWFIL()) {
684     IndexOfConge++;
685 //    char name[100];
686     char* name=new char[100];
687     sprintf(name,"%s_%d","Surf",IndexOfConge);
688     DrawTrSurf::Set(name,Surf);
689   }
690 #endif
691   Standard_Real UFirst,ULast,VFirst,VLast,pppdeb,pppfin;
692   Surf->Bounds(UFirst,ULast,VFirst,VLast);
693   BRepAdaptor_Curve2d brc;
694   BRepAdaptor_Curve CArc;
695   Handle(BRepAdaptor_HSurface) 
696     BS1 = Handle(BRepAdaptor_HSurface)::DownCast(S1);
697   Handle(BRepAdaptor_HSurface) 
698     BS2 = Handle(BRepAdaptor_HSurface)::DownCast(S2);
699   Geom2dAPI_ProjectPointOnCurve projector;
700
701   Standard_Real Uon1 = UFirst, Uon2 = ULast;
702   Standard_Integer ion1 = 1, ion2 = 2;
703   if(Reversed) { Uon1 = ULast; Uon2 = UFirst; ion1 = 2; ion2 = 1; }
704   
705   // The SurfData is filled in what concerns S1,
706   Handle(Geom_Curve) Crv3d1 = Surf->UIso(Uon1);
707   gp_Pnt2d pori1(Uon1,0.);
708   gp_Lin2d lfil1(pori1,gp::DY2d());
709   Handle(Geom2d_Curve) PCurveOnSurf = new Geom2d_Line(lfil1);
710   Handle(Geom2d_Curve) PCurveOnFace;
711   PCurveOnFace = new 
712     Geom2d_BSplineCurve(approx.Curve2dPoles(ion1),approx.Curves2dKnots(),
713                         approx.Curves2dMults(),approx.Curves2dDegree());
714   
715   
716    Standard_Real par1=PCurveOnFace->FirstParameter();
717    Standard_Real par2= PCurveOnFace->LastParameter();
718    chc.Load(Crv3d1,par1,par2);
719    
720  if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S1,tolC1,tolcheck)){
721 #ifdef DEB
722    cout<<"aaproximate tolerance under-valued : "<<tolC1<<" for "<<tolcheck<<endl;
723 #endif 
724     tolC1 = tolcheck;
725   }
726   Standard_Integer Index1OfCurve = 
727     DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d1,tolC1));
728   
729   Standard_Real uarc,utg;
730   if(Gd1){
731     TopoDS_Face forwfac = BS1->ChangeSurface().Face();
732     forwfac.Orientation(TopAbs_FORWARD);
733     brc.Initialize(Data->VertexFirstOnS1().Arc(),forwfac);
734     ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS1();
735     CArc.Initialize(V.Arc());
736     CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
737     tolcheck = CArc.Value(uarc).Distance(V.Point());
738     V.SetArc(tolC1+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
739     pppdeb = utg;
740   }
741   else pppdeb = VFirst;
742   if(Gf1){
743     TopoDS_Face forwfac = BS1->ChangeSurface().Face();
744     forwfac.Orientation(TopAbs_FORWARD);
745     ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS1();
746     brc.Initialize(V.Arc(),forwfac);
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     pppfin = utg;
752   }
753   else pppfin = VLast;
754   ChFiDS_FaceInterference& Fint1 = Data->ChangeInterferenceOnS1();
755   Fint1.SetFirstParameter(pppdeb);
756   Fint1.SetLastParameter(pppfin);
757   TopAbs_Orientation TraOn1;
758   if(Reversed) TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS2());
759   else TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS1());
760   Fint1.SetInterference(Index1OfCurve,TraOn1,PCurveOnFace,PCurveOnSurf);
761   
762   // SurfData is filled in what concerns S2,
763   Handle(Geom_Curve) Crv3d2 = Surf->UIso(Uon2);
764   gp_Pnt2d pori2(Uon2,0.);
765   gp_Lin2d lfil2(pori2,gp::DY2d());
766   PCurveOnSurf = new Geom2d_Line(lfil2);
767   if(!S2.IsNull()){
768     PCurveOnFace = new Geom2d_BSplineCurve(approx.Curve2dPoles(ion2),
769                                            approx.Curves2dKnots(),
770                                            approx.Curves2dMults(),
771                                            approx.Curves2dDegree());
772     chc.Load(Crv3d2,par1,par2);
773    if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S2,tolC2,tolcheck)){
774 #ifdef DEB
775       cout<<"approximate tolerance under-evaluated : "<<tolC2<<" for "<<tolcheck<<endl;
776 #endif 
777       tolC2 = tolcheck;
778     }
779   }
780   Standard_Integer Index2OfCurve = 
781     DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d2,tolC2));
782   if(Gd2){
783     TopoDS_Face forwfac = BS2->ChangeSurface().Face();
784     forwfac.Orientation(TopAbs_FORWARD);
785     brc.Initialize(Data->VertexFirstOnS2().Arc(),forwfac);
786     ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS2();
787     CArc.Initialize(V.Arc());
788     CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
789     tolcheck = CArc.Value(uarc).Distance(V.Point());
790     V.SetArc(tolC2+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
791     pppdeb = utg;
792   }
793   else pppdeb = VFirst;
794   if(Gf2){
795     TopoDS_Face forwfac = BS2->ChangeSurface().Face();
796     forwfac.Orientation(TopAbs_FORWARD);
797     brc.Initialize(Data->VertexLastOnS2().Arc(),forwfac);
798     ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS2();
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     pppfin = utg;
804   }
805   else pppfin = VLast;
806   ChFiDS_FaceInterference& Fint2 = Data->ChangeInterferenceOnS2();
807   Fint2.SetFirstParameter(pppdeb);
808   Fint2.SetLastParameter(pppfin);
809   if(!S2.IsNull()){
810     TopAbs_Orientation TraOn2;
811     if(Reversed) TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS1());
812     else TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS2());
813     Fint2.SetInterference(Index2OfCurve,TraOn2,PCurveOnFace,PCurveOnSurf);
814   }
815   else {
816     Handle(Geom2d_Curve) bidpc;
817     Fint2.SetInterference
818       (Index2OfCurve,TopAbs_FORWARD,bidpc,PCurveOnSurf);
819   }
820
821   // the orientation of the fillet in relation to the faces is evaluated,
822
823   Handle(Adaptor3d_HSurface) Sref = S1;
824   PCurveOnFace = Fint1.PCurveOnFace();
825   if(Reversed){ Sref = S2; PCurveOnFace = Fint2.PCurveOnFace(); }
826   
827 //  Modified by skv - Wed Jun  9 17:16:26 2004 OCC5898 Begin
828 //   gp_Pnt2d PUV = PCurveOnFace->Value((VFirst+VLast)/2.);
829 //   gp_Pnt P;
830 //   gp_Vec Du1,Du2,Dv1,Dv2;
831 //   Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1);
832 //   Du1.Cross(Dv1);
833 //   if (Or1 == TopAbs_REVERSED) Du1.Reverse();
834 //   Surf->D1(UFirst,(VFirst+VLast)/2.,P,Du2,Dv2);
835 //   Du2.Cross(Dv2);
836 //   if (Du1.Dot(Du2)>0) Data->ChangeOrientation() = TopAbs_FORWARD;
837 //   else Data->ChangeOrientation() = TopAbs_REVERSED;
838
839   Standard_Real    aDelta = VLast - VFirst;
840   Standard_Integer aDenom = 2;
841
842   while (Standard_True) {
843     Standard_Real aDeltav = aDelta/aDenom;
844     Standard_Real aParam  = VFirst + aDeltav;
845     gp_Pnt2d      PUV     = PCurveOnFace->Value(aParam);
846     gp_Pnt        P;
847     gp_Vec        Du1,Du2,Dv1,Dv2;
848
849     Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1);
850     Du1.Cross(Dv1);
851
852     if (Or1 == TopAbs_REVERSED)
853       Du1.Reverse();
854
855     Surf->D1(UFirst, aParam, P, Du2, Dv2);
856     Du2.Cross(Dv2);
857
858     if (Du1.Magnitude() <= tolget3d ||
859         Du2.Magnitude() <= tolget3d) {
860       aDenom++;
861
862       if (Abs(aDeltav) <= tolget2d)
863         return Standard_False;
864
865       continue;
866     }
867
868     if (Du1.Dot(Du2)>0)
869       Data->ChangeOrientation() = TopAbs_FORWARD;
870     else
871       Data->ChangeOrientation() = TopAbs_REVERSED;
872
873     break;
874   }
875 //  Modified by skv - Wed Jun  9 17:16:26 2004 OCC5898 End
876   
877   if(!Gd1 && !S1.IsNull())
878     ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(),
879                           Standard_True, Data->ChangeVertex(1,ion1),tolC1);
880   if(!Gf1 && !S1.IsNull())
881     ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(),
882                           Standard_False,Data->ChangeVertex(0,ion1),tolC1);
883   if(!Gd2 && !S2.IsNull())
884     ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(),
885                           Standard_True, Data->ChangeVertex(1,ion2),tolC2);
886   if(!Gf2 && !S2.IsNull())
887     ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(),
888                           Standard_False, Data->ChangeVertex(0,ion2),tolC2);
889   // Parameters on ElSpine
890   Standard_Integer nbp = lin->NbPoints();
891   Data->FirstSpineParam(lin->Point(1).Parameter());
892   Data->LastSpineParam(lin->Point(nbp).Parameter());
893   return Standard_True;
894 }                        
895
896
897
898 //=======================================================================
899 //function : ComputeData
900 //purpose  : Head of the path edge/face for the bypass of obstacle.
901 //=======================================================================
902
903 Standard_Boolean ChFi3d_Builder::ComputeData
904 (Handle(ChFiDS_SurfData)&         Data,
905  const Handle(ChFiDS_HElSpine)&   HGuide,
906  Handle(BRepBlend_Line)&          Lin,
907  const Handle(Adaptor3d_HSurface)&  S1,
908  const Handle(Adaptor3d_TopolTool)& I1,
909  const Handle(Adaptor3d_HSurface)&  S2,
910  const Handle(Adaptor2d_HCurve2d)&  PC2,
911  const Handle(Adaptor3d_TopolTool)& I2,
912  Standard_Boolean&                Decroch,
913  Blend_SurfRstFunction&           Func,
914  Blend_FuncInv&                   FInv,
915  Blend_SurfPointFuncInv&          FInvP,
916  Blend_SurfCurvFuncInv&           FInvC,
917  const Standard_Real              PFirst,
918  const Standard_Real              MaxStep,
919  const Standard_Real              Fleche,
920  const Standard_Real              TolGuide,
921  Standard_Real&                   First,
922  Standard_Real&                   Last,
923  const math_Vector&               Soldep,
924  const Standard_Boolean           Inside,
925  const Standard_Boolean           Appro,
926  const Standard_Boolean           Forward,
927  const Standard_Boolean           RecP,
928  const Standard_Boolean           RecS,
929  const Standard_Boolean           RecRst)
930 {
931   BRepBlend_SurfRstLineBuilder TheWalk(S1,I1,S2,PC2,I2);
932   
933   Data->FirstExtensionValue(0);
934   Data->LastExtensionValue(0); 
935
936   Standard_Boolean reverse = (!Forward || Inside);
937   Standard_Real SpFirst = HGuide->FirstParameter();
938   Standard_Real SpLast =  HGuide->LastParameter();
939   Standard_Real Target = SpLast;
940   if(reverse) Target = SpFirst;
941   Standard_Real Targetsov = Target;
942   
943   Standard_Real MS = MaxStep;
944   Standard_Integer again = 0;
945   Standard_Integer nbptmin = 3; //jlr
946 #ifndef DEB
947   Standard_Integer Nbpnt = 0;
948 #else
949   Standard_Integer Nbpnt;
950 #endif
951   // the initial solution is reframed if necessary.
952   math_Vector ParSol(1,3);
953   Standard_Real NewFirst = PFirst;
954   if(RecP || RecS || RecRst){
955     if(!TheWalk.PerformFirstSection(Func,FInv,FInvP,FInvC,PFirst,Target,Soldep,
956                                     tolesp,TolGuide,RecRst,RecP,RecS,
957                                     NewFirst,ParSol)){
958 #ifdef DEB
959       cout<<"ChFi3d_Builder::ComputeData : calculation fail first section"<<endl;
960 #endif
961       return Standard_False;
962     }
963   }
964   else {
965     ParSol = Soldep;
966   }
967
968   while (again < 2){
969     TheWalk.Perform (Func,FInv,FInvP,FInvC,NewFirst,Last,
970                      MS,TolGuide,ParSol,tolesp,Fleche,Appro);
971
972     if (!TheWalk.IsDone()) {
973 #ifdef DEB
974       cout << "Path not created" << endl;
975 #endif  
976       return Standard_False;
977     }
978   
979     if (reverse) {
980       if (!TheWalk.Complete(Func,FInv,FInvP,FInvC,SpLast)) {
981 #ifdef DEB
982         cout << "Not completed" << endl;
983 #endif
984       }
985     }  
986   
987
988     Lin = TheWalk.Line();
989     Nbpnt = Lin->NbPoints();
990     if (Nbpnt <= 1 && again == 0)  {
991       again++;
992 #ifdef DEB
993       cout <<"one point of the path MS/50 is attempted."<<endl;
994 #endif  
995       MS = MS/50.; Target = Targetsov;
996     }
997     else if (Nbpnt<=nbptmin && again == 0)  {
998       again++;
999 #ifdef DEB
1000       cout <<"Number of points is too small, the step is reduced"<<endl;
1001 #endif  
1002       Standard_Real u1 = Lin->Point(1).Parameter();
1003       Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1004       MS = (u2-u1)/(nbptmin+1.0);
1005 //      cout << " MS : " << MS << " u1 : " << u1 << " u2 : " << u2 << " nbptmin : " << nbptmin << endl;
1006       Target = Targetsov;
1007     }
1008     else if(Nbpnt<=nbptmin){
1009 #ifdef DEB
1010       cout <<"Number of points is still too small, quit"<<endl;
1011 #endif  
1012       return Standard_False;
1013     }
1014     else {
1015       again = 2;
1016     }
1017   }
1018 #ifdef DRAW
1019   ChFi3d_SettraceDRAWWALK(Standard_True);
1020   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1021 #endif  
1022   if(Forward) Decroch = TheWalk.DecrochEnd();
1023   else Decroch = TheWalk.DecrochStart();
1024   Last = Lin->Point(Nbpnt).Parameter();
1025   First = Lin->Point(1).Parameter();
1026   return Standard_True;
1027 }
1028
1029
1030 //=======================================================================
1031 //function : ComputeData
1032 //purpose  : Heading of the path edge/edge for the bypass of obstacle.
1033 //=======================================================================
1034
1035 Standard_Boolean ChFi3d_Builder::ComputeData
1036 (Handle(ChFiDS_SurfData)&         Data,
1037  const Handle(ChFiDS_HElSpine)&   HGuide,
1038  Handle(BRepBlend_Line)&          Lin,
1039  const Handle(Adaptor3d_HSurface)&  S1,
1040  const Handle(Adaptor2d_HCurve2d)&  PC1,
1041  const Handle(Adaptor3d_TopolTool)& I1,
1042  Standard_Boolean&                Decroch1,
1043  const Handle(Adaptor3d_HSurface)&  S2,
1044  const Handle(Adaptor2d_HCurve2d)&  PC2,
1045  const Handle(Adaptor3d_TopolTool)& I2,
1046  Standard_Boolean&                Decroch2,
1047  Blend_RstRstFunction&            Func,
1048  Blend_SurfCurvFuncInv&           FInv1,
1049  Blend_CurvPointFuncInv&          FInvP1,
1050  Blend_SurfCurvFuncInv&           FInv2,
1051  Blend_CurvPointFuncInv&          FInvP2,
1052  const Standard_Real              PFirst,
1053  const Standard_Real              MaxStep,
1054  const Standard_Real              Fleche,
1055  const Standard_Real              TolGuide,
1056  Standard_Real&                   First,
1057  Standard_Real&                   Last,
1058  const math_Vector&               Soldep,
1059  const Standard_Boolean           Inside,
1060  const Standard_Boolean           Appro,
1061  const Standard_Boolean           Forward,
1062  const Standard_Boolean           RecP1,
1063  const Standard_Boolean           RecRst1,
1064  const Standard_Boolean           RecP2,
1065  const Standard_Boolean           RecRst2)
1066 {
1067   BRepBlend_RstRstLineBuilder TheWalk(S1, PC1, I1, S2, PC2, I2);
1068   
1069   Data->FirstExtensionValue(0);
1070   Data->LastExtensionValue(0); 
1071
1072   Standard_Boolean reverse = (!Forward || Inside);
1073   Standard_Real SpFirst = HGuide->FirstParameter();
1074   Standard_Real SpLast =  HGuide->LastParameter();
1075   Standard_Real Target = SpLast;
1076   if(reverse) Target = SpFirst;
1077   Standard_Real Targetsov = Target;
1078   
1079   Standard_Real MS = MaxStep;
1080   Standard_Integer again = 0;
1081   Standard_Integer nbptmin = 3; //jlr
1082 #ifndef DEB
1083   Standard_Integer Nbpnt = 0;
1084 #else
1085   Standard_Integer Nbpnt;
1086 #endif
1087   // the initial solution is reframed if necessary.
1088   math_Vector ParSol(1,2);
1089   Standard_Real NewFirst = PFirst;
1090   if (RecP1 || RecRst1 || RecP2 || RecRst2) {
1091     if (!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep,
1092                                      tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2,
1093                                      NewFirst, ParSol)){
1094 #ifdef DEB
1095       cout<<"ChFi3d_Builder::ComputeData : fail calculation first section"<<endl;
1096 #endif
1097       return Standard_False;
1098     }
1099   }
1100   else {
1101     ParSol = Soldep;
1102   }
1103
1104   while (again < 2){
1105     TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last,
1106                      MS, TolGuide, ParSol, tolesp, Fleche, Appro);
1107
1108     if (!TheWalk.IsDone()) {
1109 #ifdef DEB
1110       cout << "Path not done" << endl;
1111 #endif  
1112       return Standard_False;
1113     }
1114   
1115     if (reverse) {
1116       if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) {
1117 #ifdef DEB
1118         cout << "Not completed" << endl;
1119 #endif
1120       }
1121     }  
1122   
1123
1124     Lin = TheWalk.Line();
1125     Nbpnt = Lin->NbPoints();
1126     if (Nbpnt <= 1 && again == 0)  {
1127       again++;
1128 #ifdef DEB
1129       cout <<"one point of path MS/50 is attempted."<<endl;
1130 #endif  
1131       MS = MS/50.; Target = Targetsov;
1132     }
1133     else if (Nbpnt<=nbptmin && again == 0)  {
1134       again++;
1135 #ifdef DEB
1136       cout <<"Number of points is too small, the step is reduced"<<endl;
1137 #endif  
1138       Standard_Real u1 = Lin->Point(1).Parameter();
1139       Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1140       MS = (u2-u1)/(nbptmin+1);
1141       Target = Targetsov;
1142     }
1143     else if(Nbpnt<=nbptmin){
1144 #ifdef DEB
1145       cout <<"Number of points is still too small, quit"<<endl;
1146 #endif  
1147       return Standard_False;
1148     }
1149     else {
1150       again = 2;
1151     }
1152   }
1153 #ifdef DRAW
1154   ChFi3d_SettraceDRAWWALK(Standard_True);
1155   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1156 #endif  
1157   if (Forward) {
1158     Decroch1 = TheWalk.Decroch1End();
1159     Decroch2 = TheWalk.Decroch2End();
1160   }
1161   else {
1162     Decroch1 = TheWalk.Decroch1Start();
1163     Decroch2 = TheWalk.Decroch2Start();  
1164   }
1165   Last  = Lin->Point(Nbpnt).Parameter();
1166   First = Lin->Point(1).Parameter();
1167   return Standard_True;
1168 }
1169
1170
1171 //=======================================================================
1172 //function : SimulData
1173 //purpose  : Heading of the path edge/face for the bypass of obstacle in simulation mode.
1174 //=======================================================================
1175
1176 Standard_Boolean ChFi3d_Builder::SimulData
1177 (Handle(ChFiDS_SurfData)&         /*Data*/,
1178  const Handle(ChFiDS_HElSpine)&   HGuide,
1179  Handle(BRepBlend_Line)&          Lin,
1180  const Handle(Adaptor3d_HSurface)&  S1,
1181  const Handle(Adaptor3d_TopolTool)& I1,
1182  const Handle(Adaptor3d_HSurface)&  S2,
1183  const Handle(Adaptor2d_HCurve2d)&  PC2,
1184  const Handle(Adaptor3d_TopolTool)& I2,
1185  Standard_Boolean&                Decroch,
1186  Blend_SurfRstFunction&           Func,
1187  Blend_FuncInv&                   FInv,
1188  Blend_SurfPointFuncInv&          FInvP,
1189  Blend_SurfCurvFuncInv&           FInvC,
1190  const Standard_Real              PFirst,
1191  const Standard_Real              MaxStep,
1192  const Standard_Real              Fleche,
1193  const Standard_Real              TolGuide,
1194  Standard_Real&                   First,
1195  Standard_Real&                   Last,
1196  const math_Vector&               Soldep,
1197  const Standard_Integer           NbSecMin,
1198  const Standard_Boolean           Inside,
1199  const Standard_Boolean           Appro,
1200  const Standard_Boolean           Forward,
1201  const Standard_Boolean           RecP,
1202  const Standard_Boolean           RecS,
1203  const Standard_Boolean           RecRst)
1204 {
1205   BRepBlend_SurfRstLineBuilder TheWalk(S1,I1,S2,PC2,I2);
1206
1207   Standard_Boolean reverse = (!Forward || Inside);
1208   Standard_Real SpFirst = HGuide->FirstParameter();
1209   Standard_Real SpLast =  HGuide->LastParameter();
1210   Standard_Real Target = SpLast;
1211   if(reverse) Target = SpFirst;
1212   Standard_Real Targetsov = Target;
1213   
1214   Standard_Real MS = MaxStep;
1215   Standard_Integer again = 0;
1216 #ifndef DEB
1217   Standard_Integer Nbpnt = 0; 
1218 #else
1219   Standard_Integer Nbpnt; 
1220 #endif
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 #ifndef DEB
1347   Standard_Integer Nbpnt = 0; 
1348 #else
1349   Standard_Integer Nbpnt; 
1350 #endif
1351   // The initial solution is reframed if necessary.
1352   math_Vector ParSol(1,2);
1353   Standard_Real NewFirst = PFirst;
1354   if (RecP1 || RecRst1 || RecP2 || RecRst2) {
1355     if(!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep,
1356                                     tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2,
1357                                     NewFirst,ParSol)){
1358 #ifdef DEB
1359
1360       cout<<"ChFi3d_Builder::SimulData : calculation fail first section"<<endl;
1361 #endif
1362       return Standard_False;
1363     }
1364   }
1365   else {
1366     ParSol = Soldep;
1367   }
1368
1369   while (again < 2){
1370     TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last,
1371                      MS, TolGuide, ParSol, tolesp, Fleche, Appro);
1372     if (!TheWalk.IsDone()) {
1373 #ifdef DEB
1374       cout << "Path not created" << endl;
1375 #endif
1376       return Standard_False;
1377     }
1378     if (reverse) {
1379       if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) {
1380 #ifdef DEB
1381         cout << "Not completed" << endl;
1382 #endif
1383       }
1384     }  
1385     Lin = TheWalk.Line();
1386     Nbpnt = Lin->NbPoints();
1387     if (Nbpnt <= 1 && again == 0)  {
1388       again++;
1389 #ifdef DEB
1390       cout <<"only one point of path MS/50 is attempted."<<endl;
1391 #endif
1392       MS = MS/50.; Target = Targetsov;
1393     }
1394     else if (Nbpnt <= NbSecMin && again == 0)  {
1395       again++;
1396 #ifdef DEB
1397       cout <<"Number of points is too small, the step is reduced"<<endl;
1398 #endif
1399       Standard_Real u1 = Lin->Point(1).Parameter();
1400       Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1401       MS = (u2-u1)/(NbSecMin+1);
1402       Target = Targetsov;
1403     }
1404     else if(Nbpnt<=NbSecMin){
1405 #ifdef DEB
1406       cout <<"Number of points is still too small, quit"<<endl;
1407 #endif
1408       return Standard_False;
1409     }
1410     else {
1411       again = 2;
1412     }
1413   }
1414 #ifdef DRAW
1415   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1416 #endif
1417   if (Forward) {
1418     Decroch1 = TheWalk.Decroch1End();
1419     Decroch2 = TheWalk.Decroch2End();
1420   }
1421   else {
1422     Decroch1 = TheWalk.Decroch1Start();
1423     Decroch2 = TheWalk.Decroch2Start();  
1424   }  
1425
1426   Last = Lin->Point(Nbpnt).Parameter();
1427   First = Lin->Point(1).Parameter();
1428   return Standard_True;
1429 }
1430
1431
1432
1433
1434 //=======================================================================
1435 //function : ComputeData
1436 //purpose  : Construction of elementary fillet by path.
1437 //
1438 //=======================================================================
1439
1440 Standard_Boolean ChFi3d_Builder::ComputeData
1441 (Handle(ChFiDS_SurfData)& Data,
1442  const Handle(ChFiDS_HElSpine)& HGuide,
1443  const Handle(ChFiDS_Spine)& Spine,
1444  Handle(BRepBlend_Line)& Lin,
1445  const Handle(Adaptor3d_HSurface)& S1,
1446  const Handle(Adaptor3d_TopolTool)& I1,
1447  const Handle(Adaptor3d_HSurface)& S2,
1448  const Handle(Adaptor3d_TopolTool)& I2,
1449  Blend_Function& Func,
1450  Blend_FuncInv& FInv,
1451  const Standard_Real PFirst,
1452  const Standard_Real MaxStep,
1453  const Standard_Real Fleche,
1454  const Standard_Real tolguide,
1455  Standard_Real& First,
1456  Standard_Real& Last,
1457  const Standard_Boolean Inside,
1458  const Standard_Boolean Appro,
1459  const Standard_Boolean Forward,
1460  const math_Vector& Soldep,
1461  Standard_Boolean& intf,
1462  Standard_Boolean& intl,
1463  Standard_Boolean& Gd1,
1464  Standard_Boolean& Gd2,
1465  Standard_Boolean& Gf1,
1466  Standard_Boolean& Gf2,
1467  const Standard_Boolean RecOnS1,
1468  const Standard_Boolean RecOnS2)
1469 {
1470   //The extrensions are created in case of output of two domains
1471   //directly and not by path ( too hasardous ).
1472   Data->FirstExtensionValue(0);
1473   Data-> LastExtensionValue(0);
1474
1475   //The eventual faces are restored to test the jump of edge.
1476   TopoDS_Face F1, F2;
1477   Handle(BRepAdaptor_HSurface) HS = Handle(BRepAdaptor_HSurface)::DownCast(S1); 
1478   if(!HS.IsNull()) F1 = HS->ChangeSurface().Face();
1479   HS = Handle(BRepAdaptor_HSurface)::DownCast(S2); 
1480   if(!HS.IsNull()) F2 = HS->ChangeSurface().Face();
1481   
1482   // Path framing variables
1483   Standard_Real TolGuide=tolguide, TolEsp = tolesp;
1484   Standard_Integer nbptmin = 4;
1485
1486   BRepBlend_Walking TheWalk(S1,S2,I1,I2);
1487
1488   //Start of removal, 2D path controls 
1489   //that qui s'accomodent mal des surfaces a parametrages non homogenes
1490   //en u et en v are extinguished.
1491   TheWalk.Check2d(0);
1492   
1493   Standard_Real MS = MaxStep;
1494   Standard_Integer Nbpnt;
1495   Standard_Real SpFirst = HGuide->FirstParameter();
1496   Standard_Real SpLast =  HGuide->LastParameter();
1497
1498   // When the start point is inside, the path goes first to the left  
1499   // to determine the Last for the periodicals.
1500   Standard_Boolean reverse = (!Forward || Inside);
1501   Standard_Real Target;
1502   if(reverse){
1503     Target = SpFirst;
1504     if(!intf) Target = Last;
1505   }
1506   else{
1507     Target = SpLast + Abs(SpLast);
1508     if(!intl) Target = Last;
1509   }
1510
1511   // In case if the singularity is pre-determined,
1512   // the path is indicated.
1513   if (!Spine.IsNull()){
1514     if (Spine->IsTangencyExtremity(Standard_True)) {
1515       TopoDS_Vertex V = Spine->FirstVertex();
1516       TopoDS_Edge E = Spine->Edges(1);
1517       Standard_Real param =  Spine->FirstParameter();
1518       Blend_Point BP;
1519       if (CompBlendPoint(V, E, param, F1, F2, BP)) {
1520         math_Vector vec(1,4);
1521         BP.ParametersOnS1(vec(1),vec(2));
1522         BP.ParametersOnS2(vec(3),vec(4));
1523         Func.Set(param);
1524         if (Func.IsSolution(vec, tolesp)) {
1525           TheWalk.AddSingularPoint(BP);
1526         }
1527       }
1528     }
1529     if (Spine->IsTangencyExtremity(Standard_False)) {
1530       TopoDS_Vertex V = Spine->LastVertex();
1531       TopoDS_Edge E = Spine->Edges( Spine->NbEdges()); 
1532       Standard_Real param =  Spine->LastParameter();
1533       Blend_Point BP;
1534       if (CompBlendPoint(V, E, param, F1, F2, BP)) {
1535         math_Vector vec(1,4);
1536         BP.ParametersOnS1(vec(1),vec(2));
1537         BP.ParametersOnS2(vec(3),vec(4));
1538         Func.Set(param);
1539         if (Func.IsSolution(vec, tolesp)) {
1540           TheWalk.AddSingularPoint(BP);
1541         }
1542       }
1543     }
1544   }
1545
1546   //The starting solution is reframed if necessary.
1547   //**********************************************//
1548   math_Vector ParSol(1,4);
1549   Standard_Real NewFirst = PFirst;
1550   if(RecOnS1 || RecOnS2){
1551     if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep,
1552                                     tolesp,TolGuide,RecOnS1,RecOnS2,
1553                                     NewFirst,ParSol)){
1554 #ifdef DEB
1555       cout<<"ChFi3d_Builder::ComputeData : calculation fail first section"<<endl;
1556 #endif
1557       return Standard_False;
1558     }
1559   }
1560   else {
1561     ParSol = Soldep;
1562   }
1563
1564   //First the valid part is calculate, without caring for the extensions.
1565   //******************************************************************//
1566   Standard_Integer again = 0;
1567   Standard_Boolean tchernobyl = 0;
1568 #ifndef DEB
1569   Standard_Real u1sov = 0., u2sov = 0.;
1570 #else
1571   Standard_Real u1sov, u2sov;
1572 #endif
1573   TopoDS_Face bif;
1574   //Max step is relevant, but too great, the vector is required to detect
1575   //the twists.
1576   if( (Abs(Last-First) <= MS * 5.) &&
1577       (Abs(Last-First) >= 0.01*Abs(NewFirst-Target)) ){ 
1578     MS = Abs(Last-First)*0.2; 
1579   }
1580
1581   while(again < 3){
1582     //Path. 
1583     if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide;
1584     else {
1585       if (5*TolGuide > MS) TolGuide = MS/5;
1586       if (5*TolEsp > MS) TolEsp = MS/5;
1587     }
1588     TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
1589                     ParSol,TolEsp,Fleche,Appro);
1590     if (!TheWalk.IsDone()) {
1591 #ifdef DEB
1592       cout << "Path is not created" << endl;
1593 #endif
1594       return Standard_False;
1595     }
1596     Lin = TheWalk.Line();
1597     if(HGuide->IsPeriodic() && Inside) {
1598       SpFirst = Lin->Point(1).Parameter();
1599       SpLast  = SpFirst + HGuide->Period();
1600       HGuide->ChangeCurve().FirstParameter(SpFirst);
1601       HGuide->ChangeCurve().LastParameter (SpLast );
1602       HGuide->ChangeCurve().SetOrigin(SpFirst);
1603     }
1604     Standard_Boolean complmnt = Standard_True;
1605     if (Inside)  complmnt = TheWalk.Complete(Func,FInv,SpLast);
1606     if(!complmnt){
1607 #ifdef DEB
1608       cout << "Not completed" << endl;
1609 #endif
1610       return Standard_False;
1611     }
1612     
1613     //The result is controlled using two criterions :
1614     //- if there is enough points,
1615     //- if one has gone far enough.
1616     Nbpnt = Lin->NbPoints();
1617     if (Nbpnt == 0){
1618 #ifdef DEB
1619       cout <<"0 point of path, quit."<<endl;
1620 #endif
1621       return Standard_False;
1622     }
1623     Standard_Real fpointpar = Lin->Point(1).Parameter();
1624     Standard_Real lpointpar = Lin->Point(Nbpnt).Parameter();
1625     
1626     Standard_Real factor =  1./(nbptmin + 1);
1627     Standard_Boolean okdeb = (Forward && !Inside);  
1628     Standard_Boolean okfin = (!Forward && !Inside);
1629     if(!okdeb){
1630       Standard_Integer narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1631       Standard_Integer narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1632       okdeb = (narc1 > 0 || narc2 > 0 || (fpointpar-First) < 10*TolGuide); 
1633     }
1634     if(!okfin){
1635       Standard_Integer narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1636       Standard_Integer narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1637       okfin = (narc1 > 0 || narc2 > 0 || (Last-lpointpar) < 10*TolGuide);
1638     }
1639     if(!okdeb || !okfin || Nbpnt == 1){
1640       //It drags, the controls are extended, it is  expected to evaluate a
1641       //satisfactory maximum step. If it already done, quit.
1642       if(tchernobyl){
1643 #ifdef DEB
1644         cout <<"If it drags without control, quit."<<endl;
1645 #endif
1646         return Standard_False;
1647       }
1648       tchernobyl = Standard_True;
1649       TheWalk.Check(0);
1650       if (Nbpnt == 1){
1651 #ifdef DEB
1652         cout <<"only one point of path MS/100 is attempted"<<endl;
1653         cout <<"and the controls are extended."<<endl;
1654 #endif
1655         MS *= 0.01;
1656       }
1657       else{
1658 #ifdef DEB
1659         cout <<"It drags, the controls are extended."<<endl;
1660 #endif
1661         MS = (lpointpar-fpointpar)/Nbpnt; //EvalStep(Lin);
1662       }
1663     }
1664     else if (Nbpnt < nbptmin){
1665       if(again == 0){
1666 #ifdef DEB
1667         cout <<"Number of points is too small, the step is reduced"<<endl;
1668 #endif
1669         u1sov = fpointpar;
1670         u2sov = lpointpar;
1671         MS = (lpointpar - fpointpar) * factor;
1672       }
1673       else if(again == 1){
1674         if(Abs(fpointpar-u1sov)>=TolGuide || 
1675            Abs(lpointpar-u2sov)>=TolGuide){
1676 #ifdef DEB
1677           cout <<"Number of points is still too small, the step is reduced"<<endl;
1678 #endif  
1679           MS = (lpointpar - fpointpar) * factor;
1680         }
1681         else{
1682 #ifdef DEB
1683           cout <<"Number of points is still too small, quit"<<endl;
1684 #endif  
1685           return Standard_False;
1686         }
1687       }
1688       again++;
1689     }
1690     else {
1691       again = 3;
1692     }
1693   }
1694
1695   if(TheWalk.TwistOnS1()){
1696     Data->TwistOnS1(Standard_True);
1697 #ifdef DEB
1698     cout<<"Path completed, but TWIST on S1"<<endl;
1699 #endif
1700   }
1701   if(TheWalk.TwistOnS2()){
1702     Data->TwistOnS2(Standard_True);
1703 #ifdef DEB
1704     cout<<"Parh completed, but TWIST on S2"<<endl;
1705 #endif
1706   }
1707
1708
1709   //Here there is a more or less presentable result 
1710   //however it covers a the minimum zone.
1711   //The extensions are targeted.
1712   //*****************************//
1713
1714   Gd1 = Gd2 = Gf1 = Gf2 = Standard_False;
1715   
1716   Standard_Boolean unseulsuffitdeb = (intf >= 2);
1717   Standard_Boolean unseulsuffitfin = (intl >= 2);
1718   Standard_Boolean noproldeb = (intf >= 3);
1719   Standard_Boolean noprolfin = (intl >= 3);
1720
1721   Standard_Real Rab = 0.03*(SpLast-SpFirst);
1722
1723   Standard_Boolean debarc1 = 0, debarc2 = 0;
1724   Standard_Boolean debcas1 = 0, debcas2 = 0;
1725   Standard_Boolean debobst1 = 0, debobst2 = 0;
1726
1727   Standard_Boolean finarc1 = 0, finarc2 = 0;
1728   Standard_Boolean fincas1 = 0, fincas2 = 0;
1729   Standard_Boolean finobst1 = 0, finobst2 = 0;
1730
1731   Standard_Integer narc1, narc2;
1732
1733   Standard_Boolean backwContinueFailed = Standard_False; // eap
1734   if(reverse && intf) {
1735     narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1736     narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1737     if(narc1 != 0) {
1738       ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(),
1739                             Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1740       debarc1 = Standard_True;
1741       if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){
1742         //It is checked if there is not an obstacle.
1743         debcas1 = Standard_True;
1744         if(!Spine.IsNull()){
1745           if(Spine->IsPeriodic()){
1746             debobst1 = 1;
1747           }
1748           else{
1749             debobst1 = IsObst(Data->VertexFirstOnS1(),
1750                               Spine->FirstVertex(),myVEMap);
1751           }
1752         }
1753       }
1754     }
1755     if(narc2 != 0){
1756       ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(),
1757                             Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1758       debarc2 = Standard_True;
1759       if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){
1760         //It is checked if it is not an obstacle.
1761         debcas2 = Standard_True;
1762         if(!Spine.IsNull()){
1763           if(Spine->IsPeriodic()){
1764             debobst2 = 1;
1765           }
1766           else{
1767             debobst2 = IsObst(Data->VertexFirstOnS2(),
1768                               Spine->FirstVertex(),myVEMap);
1769           }
1770         }
1771       }
1772     }
1773     Standard_Boolean oncontinue = !noproldeb && (narc1 != 0 || narc2 != 0);
1774     if(debobst1 || debobst2) oncontinue = Standard_False;
1775     else if(debcas1 && debcas2) oncontinue = Standard_False;
1776     else if((!debcas1 && debarc1) || (!debcas2 && debarc2)) oncontinue = Standard_False;
1777
1778     if(oncontinue) {
1779       TheWalk.ClassificationOnS1(!debarc1);
1780       TheWalk.ClassificationOnS2(!debarc2);
1781       TheWalk.Check2d(Standard_True); // It should be strict (PMN)
1782       TheWalk.Continu(Func,FInv,Target);
1783       TheWalk.ClassificationOnS1(Standard_True);
1784       TheWalk.ClassificationOnS2(Standard_True);
1785       TheWalk.Check2d(Standard_False);
1786       narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1787       narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1788 //  modified by eap Fri Feb  8 11:43:48 2002 ___BEGIN___
1789       if(!debarc1)
1790         if (narc1 == 0)
1791           backwContinueFailed = Lin->StartPointOnFirst().ParameterOnGuide() > Target;
1792         else {
1793           ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(),
1794                                 Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1795           debarc1 = Standard_True;
1796           if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){
1797             //It is checked if it is not an obstacle.
1798             debcas1 = Standard_True;
1799 //          if(!Spine.IsNull()) {
1800 //            if(Spine->IsPeriodic()){
1801 //              debobst1 = 1;
1802 //            }
1803 //            else{
1804 //              debobst1 = IsObst(Data->VertexFirstOnS1(),
1805 //                                Spine->FirstVertex(),myVEMap);
1806 //            }
1807 //          }
1808           }
1809         }
1810       if(!debarc2)
1811         if (narc2 == 0)
1812           backwContinueFailed = Lin->StartPointOnSecond().ParameterOnGuide() > Target;
1813         else {
1814           ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(),
1815                                 Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1816           debarc2 = Standard_True;
1817           if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){
1818             //It is checked if it is not an obstacle.
1819             debcas2 = Standard_True;
1820 //             if(!Spine.IsNull()){
1821 //               if(Spine->IsPeriodic()){
1822 //                 debobst2 = 1;
1823 //               }
1824 //               else{
1825 //                 debobst2 = IsObst(Data->VertexFirstOnS2(),
1826 //                                   Spine->FirstVertex(),myVEMap);
1827 //               }
1828 //             }
1829           }
1830         }
1831       if (backwContinueFailed) {
1832         // if we leave backwContinueFailed as is, we will stop in this direction
1833         // but we are to continue if there are no more faces on the side with arc
1834         // check this condition
1835         const ChFiDS_CommonPoint& aCP
1836           = debarc1 ? Data->VertexFirstOnS1() : Data->VertexFirstOnS2();
1837         if (aCP.IsOnArc() && bif.IsNull())
1838           backwContinueFailed = Standard_False;
1839       }
1840     }
1841   }
1842   Standard_Boolean forwContinueFailed = Standard_False;
1843 //  modified by eap Fri Feb  8 11:44:11 2002 ___END___
1844   if(Forward && intl) {
1845     Target = SpLast;
1846     narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1847     narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1848     if(narc1 != 0){
1849       ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(),
1850                             Standard_False, Data->ChangeVertexLastOnS1(),tolesp);
1851       finarc1 = Standard_True;
1852       if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){
1853              //It is checked if it is not an obstacle.
1854         fincas1 = Standard_True;
1855         if(!Spine.IsNull()){
1856           finobst1 = IsObst(Data->VertexLastOnS1(),
1857                             Spine->LastVertex(),myVEMap);
1858         }
1859       }
1860     }
1861     if(narc2 != 0){
1862       ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(),
1863                             Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1864       finarc2 = Standard_True;
1865       if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){
1866          //It is checked if it is not an obstacle.
1867         fincas2 = Standard_True;
1868         if(!Spine.IsNull()){
1869           finobst2 = IsObst(Data->VertexLastOnS2(),
1870                             Spine->LastVertex(),myVEMap);
1871         }
1872       }
1873     }
1874     Standard_Boolean oncontinue = !noprolfin && (narc1 != 0 || narc2 != 0);
1875     if(finobst1 || finobst2) oncontinue = Standard_False;
1876     else if(fincas1 && fincas2) oncontinue = Standard_False;
1877     else if((!fincas1 && finarc1) || (!fincas2 && finarc2)) oncontinue = Standard_False;
1878     
1879     if(oncontinue){
1880       TheWalk.ClassificationOnS1(!finarc1);
1881       TheWalk.ClassificationOnS2(!finarc2);
1882       TheWalk.Check2d(Standard_True); // It should be strict (PMN)
1883       TheWalk.Continu(Func,FInv,Target);
1884       TheWalk.ClassificationOnS1(Standard_True);
1885       TheWalk.ClassificationOnS2(Standard_True);
1886       TheWalk.Check2d(Standard_False);
1887       narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1888       narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1889 //  modified by eap Fri Feb  8 11:44:57 2002 ___BEGIN___
1890       if(!finarc1)
1891         if (narc1 == 0) 
1892           forwContinueFailed = Lin->EndPointOnFirst().ParameterOnGuide() < Target;
1893         else {
1894           ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(),
1895                                 Standard_False, Data->ChangeVertexLastOnS1(),tolesp);
1896           finarc1 = Standard_True;
1897           if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){
1898              //It is checked if it is not an obstacle.
1899             fincas1 = Standard_True;
1900 //          if(!Spine.IsNull()){
1901 //            finobst1 = IsObst(Data->VertexLastOnS1(),
1902 //                              Spine->LastVertex(),myVEMap);
1903 //          }
1904           }
1905         }
1906       if(!finarc2)
1907         if (narc2 == 0)
1908           forwContinueFailed = Lin->EndPointOnSecond().ParameterOnGuide() < Target;
1909         else {
1910           ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(),
1911                                 Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1912           finarc2 = Standard_True;
1913           if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){
1914             //On regarde si ce n'est pas un obstacle.
1915             fincas2 = Standard_True;
1916 //          if(!Spine.IsNull()){
1917 //            finobst2 = IsObst(Data->VertexLastOnS2(),
1918 //                              Spine->LastVertex(),myVEMap);
1919 //          }
1920           }
1921         }
1922       if (forwContinueFailed) {
1923         // if we leave forwContinueFailed as is, we will stop in this direction
1924         // but we are to continue if there are no more faces on the side with arc
1925         // check this condition
1926         const ChFiDS_CommonPoint& aCP
1927           = finarc1 ? Data->VertexLastOnS1() : Data->VertexLastOnS2();
1928         if (aCP.IsOnArc() && bif.IsNull())
1929           forwContinueFailed = Standard_False;
1930       }
1931 //  modified by eap Fri Feb  8 11:45:10 2002 ___END___
1932     }
1933   }
1934   Nbpnt = Lin->NbPoints();
1935 #ifdef DRAW
1936   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False);
1937 #endif  
1938   First = Lin->Point(1).Parameter();
1939   Last  = Lin->Point(Nbpnt).Parameter();
1940
1941   // ============= INVALIDATION EVENTUELLE =============
1942   // ------ Preparation des prolongement par plan tangent -----
1943   if(reverse && intf){
1944     Gd1 = debcas1/* && !debobst1*/; // skv(occ67)
1945     Gd2 = debcas2/* && !debobst2*/; // skv(occ67)
1946     if ((debarc1^debarc2) && !unseulsuffitdeb && (First!=SpFirst)) {
1947       // Case of incomplete path, of course this ends badly : 
1948       // the result is truncated instead of exit.
1949       Standard_Real sortie;
1950       Standard_Integer ind;
1951       if (debarc1)  sortie = Data->VertexFirstOnS1().Parameter();
1952       else  sortie = Data->VertexFirstOnS2().Parameter();
1953       if (sortie - First > tolesp) {
1954         ind = SearchIndex(sortie, Lin);
1955         if (Lin->Point(ind).Parameter() == sortie) ind--;
1956         if (ind >= 1) {
1957           Lin->Remove(1, ind);
1958           UpdateLine(Lin, Standard_True);
1959         }
1960         Nbpnt = Lin->NbPoints();
1961         First = Lin->Point(1).Parameter();
1962       }
1963     }
1964     else if ((intf>=5) && !debarc1 && !debarc2 && (First!=SpFirst)) {
1965       Standard_Real sortie = (2*First+Last)/3;
1966       Standard_Integer ind;
1967       if (sortie - First > tolesp) {
1968         ind = SearchIndex(sortie, Lin);
1969         if (Lin->Point(ind).Parameter() == sortie) ind--;
1970         if (Nbpnt-ind < 3) ind = Nbpnt -3;
1971         if (ind >= 1) {
1972           Lin->Remove(1, ind);
1973           UpdateLine(Lin, Standard_True);
1974         }
1975         Nbpnt = Lin->NbPoints();
1976         First = Lin->Point(1).Parameter();
1977       }
1978     }
1979     if(Gd1 && Gd2){
1980       Target = Min((Lin->Point(1).Parameter() - Rab),First);
1981       Target = Max(Target,SpFirst);
1982       Data->FirstExtensionValue(Abs(Lin->Point(1).Parameter()-Target));
1983     }
1984     if (intf && !unseulsuffitdeb) intf = (Gd1 && Gd2)//;
1985       || backwContinueFailed; // eap
1986     else if (intf && unseulsuffitdeb && (intf<5)) {
1987       intf = (Gd1 || Gd2);
1988       // It is checked if there is no new face.
1989       if (intf && 
1990           ((!debcas1 && debarc1) || (!debcas2 && debarc2)) ) intf = 0;  
1991     }
1992     else if (intf < 5) intf = 0;
1993   }
1994
1995   if(Forward && intl){
1996     Gf1 = fincas1/* && !finobst1*/; // skv(occ67)
1997     Gf2 = fincas2/* && !finobst2*/; // skv(occ67)
1998     if ((finarc1 ^finarc2) && !unseulsuffitfin && (Last!=SpLast)) {
1999       // Case of incomplete path, of course, this ends badly : 
2000       // the result is truncated instead of exit.
2001       Standard_Real sortie;
2002       Standard_Integer ind;
2003       if (finarc1)  sortie = Data->VertexLastOnS1().Parameter();
2004       else  sortie = Data->VertexLastOnS2().Parameter();
2005       if (Last - sortie > tolesp) {
2006         ind = SearchIndex(sortie, Lin);
2007         if (Lin->Point(ind).Parameter() == sortie) ind++;
2008         if (ind<= Nbpnt) {
2009           Lin->Remove(ind, Nbpnt);
2010           UpdateLine(Lin, Standard_False);
2011         }
2012         Nbpnt = Lin->NbPoints();
2013         Last = Lin->Point(Nbpnt).Parameter();
2014       }
2015     }
2016     else if ((intl>=5) && !finarc1 && !finarc2 && (Last!=SpLast) ) {
2017       // The same in case when the entire "Lin" is an extension
2018       Standard_Real sortie = (First+2*Last)/3;
2019       Standard_Integer ind;
2020       if (Last - sortie > tolesp) {
2021         ind = SearchIndex(sortie, Lin);
2022         if (Lin->Point(ind).Parameter() == sortie) ind++;
2023         if (ind < 3) ind = 3;
2024         if (ind <= Nbpnt) {
2025           Lin->Remove(ind, Nbpnt);
2026           UpdateLine(Lin, Standard_False);
2027         }
2028         Nbpnt = Lin->NbPoints();
2029         Last = Lin->Point(Nbpnt).Parameter();
2030       }
2031     }
2032     if(Gf1 && Gf2) {
2033       Target = Max((Lin->Point(Nbpnt).Parameter() + Rab),Last);
2034       Target = Min(Target,SpLast);
2035       Data->LastExtensionValue(Abs(Target-Lin->Point(Nbpnt).Parameter()));
2036     }    
2037
2038     if (intl && !unseulsuffitfin) intl = (Gf1 && Gf2)//;
2039       || forwContinueFailed;  // eap
2040     else if (intl && unseulsuffitfin && (intl<5)) {
2041       intl = (Gf1 || Gf2);// It is checked if there is no new face.
2042       if (intl && 
2043           ((!fincas1 && finarc1) || (!fincas2 && finarc2)) ) intl = 0;  
2044     }
2045     else if (intl <5) intl = 0;
2046   }
2047   return Standard_True;
2048 }
2049
2050 //=======================================================================
2051 //function : SimulData
2052 //purpose  : 
2053 //=======================================================================
2054
2055 Standard_Boolean ChFi3d_Builder::SimulData
2056 (Handle(ChFiDS_SurfData)& /*Data*/,
2057  const Handle(ChFiDS_HElSpine)& HGuide,
2058  Handle(BRepBlend_Line)& Lin,
2059  const Handle(Adaptor3d_HSurface)& S1,
2060  const Handle(Adaptor3d_TopolTool)& I1,
2061  const Handle(Adaptor3d_HSurface)& S2,
2062  const Handle(Adaptor3d_TopolTool)& I2,
2063  Blend_Function& Func,
2064  Blend_FuncInv& FInv,
2065  const Standard_Real PFirst,
2066  const Standard_Real MaxStep,
2067  const Standard_Real Fleche,
2068  const Standard_Real tolguide,
2069  Standard_Real& First,
2070  Standard_Real& Last,
2071  const Standard_Boolean Inside,
2072  const Standard_Boolean Appro,
2073  const Standard_Boolean Forward,
2074  const math_Vector& Soldep,
2075  const Standard_Integer NbSecMin,
2076  const Standard_Boolean RecOnS1,
2077  const Standard_Boolean RecOnS2)
2078 {
2079   BRepBlend_Walking TheWalk(S1,S2,I1,I2);
2080   TheWalk.Check2d(Standard_False);
2081   
2082   Standard_Real MS = MaxStep;
2083   Standard_Real TolGuide=tolguide, TolEsp = tolesp;
2084   Standard_Integer Nbpnt;
2085   Standard_Real SpFirst = HGuide->FirstParameter();
2086   Standard_Real SpLast =  HGuide->LastParameter();
2087   Standard_Boolean reverse = (!Forward || Inside);
2088   Standard_Real Target;
2089   if(reverse){
2090     Target = SpFirst;
2091   }
2092   else{
2093     Target = SpLast;
2094   }
2095
2096   Standard_Real Targetsov = Target;
2097 #ifndef DEB
2098   Standard_Real u1sov = 0., u2sov = 0.; 
2099 #else
2100   Standard_Real u1sov, u2sov; 
2101 #endif
2102   // on recadre la solution de depart a la demande.
2103   math_Vector ParSol(1,4);
2104   Standard_Real NewFirst = PFirst;
2105   if(RecOnS1 || RecOnS2){
2106     if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep,
2107                                     tolesp,TolGuide,RecOnS1,RecOnS2,
2108                                     NewFirst,ParSol)){
2109 #ifdef DEB
2110       cout<<"ChFi3d_Builder::SimulData : calculation fail first section"<<endl;
2111 #endif
2112       return Standard_False;
2113     }
2114   }
2115   else {
2116     ParSol = Soldep;
2117   }
2118   Standard_Integer again = 0;
2119   while(again < 3){
2120      // When the start point is inside, the path goes first to the left  
2121      // to determine the Last for the periodicals.
2122     if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide;
2123     else  {
2124       if (5*TolGuide > MS) TolGuide = MS/5;
2125       if (5*TolEsp > MS) TolEsp = MS/5;
2126     }
2127       
2128     TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
2129                     ParSol,TolEsp,Fleche,Appro);
2130     
2131     if (!TheWalk.IsDone()) {
2132 #ifdef DEB
2133       cout << "Path not created" << endl;
2134 #endif
2135       return Standard_False;
2136     }
2137     Lin = TheWalk.Line();
2138     if(reverse){
2139       if(HGuide->IsPeriodic()) {
2140         SpFirst = Lin->Point(1).Parameter();
2141         SpLast  = SpFirst + HGuide->Period();
2142         HGuide->ChangeCurve().FirstParameter(SpFirst);
2143         HGuide->ChangeCurve().LastParameter (SpLast );
2144       }
2145       Standard_Boolean complmnt = Standard_True;
2146       if (Inside)  complmnt = TheWalk.Complete(Func,FInv,SpLast);
2147       if(!complmnt){
2148 #ifdef DEB
2149         cout << "Not completed" << endl;
2150 #endif
2151         return Standard_False;
2152       }
2153     }
2154     Nbpnt = Lin->NbPoints();
2155     Standard_Real factor =  1./(NbSecMin + 1);
2156     if (Nbpnt == 0){
2157 #ifdef DEB
2158       cout <<"0 point of path, quit."<<endl;
2159 #endif
2160       return Standard_False;
2161     }
2162     else if (Nbpnt == 1 && again == 0)  {
2163       again++;
2164 #ifdef DEB
2165       cout <<"only one point of path, MS/100 is attempted."<<endl;
2166 #endif
2167       MS *= 0.01; Target = Targetsov;
2168       u1sov = u2sov = Lin->Point(1).Parameter();
2169     }
2170     else if (Nbpnt< NbSecMin && again == 0)  {
2171       again++;
2172 #ifdef DEB
2173       cout <<"Number of points is too small, the step is reduced"<<endl;
2174 #endif
2175       Standard_Real u1 = u1sov = Lin->Point(1).Parameter();
2176       Standard_Real u2 = u2sov = Lin->Point(Nbpnt).Parameter();
2177       MS = (u2-u1)*factor;
2178       Target = Targetsov;
2179     }
2180     else if (Nbpnt < NbSecMin && again == 1)  {
2181       Standard_Real u1 = Lin->Point(1).Parameter();
2182       Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
2183       if(Abs(u1-u1sov)>=TolGuide || Abs(u2-u2sov)>=TolGuide){
2184         again++;
2185 #ifdef DEB
2186         cout <<"Number of points is still too small, the step is reduced"<<endl;
2187 #endif
2188         MS /= 100;
2189         Target = Targetsov;
2190       }
2191       else{
2192 #ifdef DEB
2193         cout <<"Number of points is still too small, quit"<<endl;
2194 #endif
2195         return Standard_False;
2196       }
2197     }
2198     else if(Nbpnt < NbSecMin){
2199 #ifdef DEB
2200       cout <<"Number of points is still too small, quit"<<endl;
2201 #endif
2202       return Standard_False;
2203     }
2204     else {
2205       again = 3;
2206     }
2207   }
2208 #ifdef DRAW
2209   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False);
2210 #endif  
2211   First = Lin->Point(1).Parameter();
2212   Last  = Lin->Point(Nbpnt).Parameter();
2213   return Standard_True;
2214 }
2215