Integration of OCCT 6.5.0 from SVN
[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 // Pour les mesures.
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) On verifie si les paramtres fournies sont bon
255   //    cas ou les pcurves sont paramtres comme la 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) On intersecte
265 #ifdef DEB
266     cout<< "CompParam : mauvais parametres on intersecte"<<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 d intersection sur les 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) On projette...
302 #ifdef DEB
303     cout<<"CompParam : echec intersection PC, on projette."<<endl;
304 #endif
305     parc = prefarc;
306     Geom2dAPI_ProjectPointOnCurve projector(point,Ctg);
307
308     if(projector.NbPoints() == 0){
309       // Cela arrive parfois dans les cas singuliers ou l'on sort 
310       // en bout de spine sur vertex...
311       ptg = preftg; 
312 #ifdef DEB
313       cout<<"CompParam :  echec proj p2d/c2d, on prend l'extremite!" <<endl;
314 #endif
315     }
316     else  {
317       // On controle que l'on n'as pas calculer n'importe quoi (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  : fabrique le BlendPoint correspondant a une tangence sur Vertex
328 // pmn : 15/10/1997 : renvoi false, si l'on n' a pas de 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  : Met a jour les extremites apres une invalidation partiel   
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  : Calcule les courbes et les CommonPoints a partir des donnees
402 //           calculees par remplissage.
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   //calcul des courbes cote 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   //calcul des courbes cote 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  : Calcule la surface les courbes et eventuellement les
503 //           CommonPoints a partir des donnees calculees dans 
504 //           ComputeData.
505 //
506 //  11/08/1996 : Utilisation de F(t)
507 //
508 //=======================================================================
509
510 Standard_Boolean ChFi3d_Builder::CompleteData
511 (Handle(ChFiDS_SurfData)& Data,
512  Blend_Function& Func,
513  Handle(BRepBlend_Line)& lin,
514  const Handle(Adaptor3d_HSurface)& S1,
515  const Handle(Adaptor3d_HSurface)& S2,
516  const TopAbs_Orientation Or1,
517  const Standard_Boolean Gd1,
518  const Standard_Boolean Gd2,
519  const Standard_Boolean Gf1,
520  const Standard_Boolean Gf2,
521  const Standard_Boolean Reversed)
522 {
523   Handle(BRepBlend_AppFunc) TheFunc 
524     = new (BRepBlend_AppFunc)(lin, Func, tolapp3d, 1.e-5);
525   BRepBlend_AppSurface approx (TheFunc, 
526                                lin->Point(1).Parameter(),
527                                lin->Point(lin->NbPoints()).Parameter(),
528                                tolapp3d, 1.e-5, //tolapp2d, tolerance max
529                                tolappangle, // Contact G1 
530                                myConti);  
531   if (!approx.IsDone()) {
532 #ifdef DEB
533     cout << "Approximation non faite !!!" << endl;
534 #endif
535     return Standard_False;
536   }
537 #ifdef DEB
538   approx.Dump(cout);
539 #endif
540   return StoreData( Data, approx, lin, S1, S2, Or1, Gd1, Gd2, Gf1, Gf2, Reversed);
541
542
543
544 //=======================================================================
545 //function : CompleteData
546 //purpose  : Nouvelle surcharge pour les fonctions surf/rst
547 // jlr le 28/07/97 branchement F(t)
548 //=======================================================================
549
550 Standard_Boolean ChFi3d_Builder::CompleteData
551 (Handle(ChFiDS_SurfData)&        Data,
552  Blend_SurfRstFunction&          Func,
553  Handle(BRepBlend_Line)&         lin,
554  const Handle(Adaptor3d_HSurface)& S1,
555  const Handle(Adaptor3d_HSurface)& S2,
556  const TopAbs_Orientation        Or,
557  const Standard_Boolean          Reversed)
558 {
559   Handle(BRepBlend_AppFuncRst) TheFunc 
560     = new (BRepBlend_AppFuncRst)(lin, Func, tolapp3d, 1.e-5);
561   BRepBlend_AppSurface approx (TheFunc, 
562                                lin->Point(1).Parameter(),
563                                lin->Point(lin->NbPoints()).Parameter(),
564                                tolapp3d, 1.e-5, //tolapp2d, tolerance max
565                                tolappangle, // Contact G1 
566                                myConti);  
567  if (!approx.IsDone()) {
568 #ifdef DEB
569     cout << "Approximation non faite !!!" << endl;
570 #endif  
571     return Standard_False;
572   }
573 #ifdef DEB
574   approx.Dump(cout);
575 #endif
576
577   return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0,Reversed);
578
579
580
581
582 //=======================================================================
583 //function : CompleteData
584 //purpose  : Nouvelle surcharge pour les fonctions rst/rst
585 // jlr le 28/07/97 branchement F(t)
586 //=======================================================================
587
588 Standard_Boolean ChFi3d_Builder::CompleteData
589 (Handle(ChFiDS_SurfData)&        Data,
590  Blend_RstRstFunction&           Func,
591  Handle(BRepBlend_Line)&         lin,
592  const Handle(Adaptor3d_HSurface)& S1,
593  const Handle(Adaptor3d_HSurface)& S2,
594  const TopAbs_Orientation        Or)
595 {
596   Handle(BRepBlend_AppFuncRstRst) TheFunc 
597     = new (BRepBlend_AppFuncRstRst)(lin, Func, tolapp3d, 1.e-5);
598   BRepBlend_AppSurface approx (TheFunc, 
599                                lin->Point(1).Parameter(),
600                                lin->Point(lin->NbPoints()).Parameter(),
601                                tolapp3d, 1.e-5, //tolapp2d, tolerance max
602                                tolappangle, // Contact G1 
603                                myConti);  
604  if (!approx.IsDone()) {
605 #ifdef DEB
606     cout << "Approximation non faite !!!" << endl;
607 #endif  
608     return Standard_False;
609   }
610 #ifdef DEB
611   approx.Dump(cout);
612 #endif
613
614   return StoreData(Data,approx,lin,S1,S2,Or,0,0,0,0);
615
616
617
618
619
620 //=======================================================================
621 //function : StoreData
622 //purpose  : Recopie d un resultat d approx dans une SurfData.
623 //=======================================================================
624
625 Standard_Boolean ChFi3d_Builder::StoreData(Handle(ChFiDS_SurfData)& Data,
626                                            const AppBlend_Approx& approx,
627                                            const Handle(BRepBlend_Line)& lin,
628                                            const Handle(Adaptor3d_HSurface)& S1,
629                                            const Handle(Adaptor3d_HSurface)& S2,
630                                            const TopAbs_Orientation Or1,
631                                            const Standard_Boolean Gd1,
632                                            const Standard_Boolean Gd2,
633                                            const Standard_Boolean Gf1,
634                                            const Standard_Boolean Gf2,
635                                            const Standard_Boolean Reversed)
636 {
637   // Petits outils pour les controles.
638   static Handle(GeomAdaptor_HCurve) checkcurve;
639   if(checkcurve.IsNull()) checkcurve = new GeomAdaptor_HCurve();
640   GeomAdaptor_Curve& chc = checkcurve->ChangeCurve();
641   Standard_Real tolget3d, tolget2d, tolaux, tolC1,  tolcheck;
642 #ifndef DEB
643   Standard_Real  tolC2 = 0.;
644 #else
645   Standard_Real  tolC2;
646 #endif
647   approx.TolReached(tolget3d, tolget2d);
648   tolaux = approx.TolCurveOnSurf(1);
649   tolC1 = tolget3d + tolaux;
650   if(!S2.IsNull()) {
651     tolaux = approx.TolCurveOnSurf(2);
652     tolC2 = tolget3d + tolaux;
653   }
654
655   TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS();
656   // On rend l espace parametric de la surface carre a defaut de pouvoir
657   // parametrer en U par # R*teta // a revoir lbo 29/08/97
658   const TColStd_Array1OfReal& ku = approx.SurfUKnots();
659   const TColStd_Array1OfReal& kv = approx.SurfVKnots();
660   Standard_Real larg = (kv(kv.Upper())-kv(kv.Lower()));
661   TColStd_Array1OfReal& kku = *((TColStd_Array1OfReal*)((void*)&ku));
662   BSplCLib::Reparametrize(0.,larg,kku);
663   Handle(Geom_BSplineSurface) Surf = 
664     new Geom_BSplineSurface(approx.SurfPoles(),approx.SurfWeights(),
665                             kku,kv,
666                             approx.SurfUMults(),approx.SurfVMults(),
667                             approx.UDegree(),approx.VDegree());
668 // prolongement de la surface 
669
670   Standard_Real length1,length2;
671   length1=Data->FirstExtensionValue();
672   length2=Data->LastExtensionValue();
673   if (length1 > Precision::Confusion())
674     GeomLib::ExtendSurfByLength(Surf,length1,1,Standard_False,Standard_False);
675   if (length2 >  Precision::Confusion())
676     GeomLib::ExtendSurfByLength(Surf,length2,1,Standard_False,Standard_True);
677
678   Data->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(Surf,tolget3d)));
679
680 #ifdef DRAW
681   ChFi3d_SettraceDRAWFIL(Standard_True);
682   if (ChFi3d_GettraceDRAWFIL()) {
683     IndexOfConge++;
684 //    char name[100];
685     char* name=new char[100];
686     sprintf(name,"%s_%d","Surf",IndexOfConge);
687     DrawTrSurf::Set(name,Surf);
688   }
689 #endif
690   Standard_Real UFirst,ULast,VFirst,VLast,pppdeb,pppfin;
691   Surf->Bounds(UFirst,ULast,VFirst,VLast);
692   BRepAdaptor_Curve2d brc;
693   BRepAdaptor_Curve CArc;
694   Handle(BRepAdaptor_HSurface) 
695     BS1 = Handle(BRepAdaptor_HSurface)::DownCast(S1);
696   Handle(BRepAdaptor_HSurface) 
697     BS2 = Handle(BRepAdaptor_HSurface)::DownCast(S2);
698   Geom2dAPI_ProjectPointOnCurve projector;
699
700   Standard_Real Uon1 = UFirst, Uon2 = ULast;
701   Standard_Integer ion1 = 1, ion2 = 2;
702   if(Reversed) { Uon1 = ULast; Uon2 = UFirst; ion1 = 2; ion2 = 1; }
703   
704   // On remplit la SurfData pour ce qui concerne S1,
705   Handle(Geom_Curve) Crv3d1 = Surf->UIso(Uon1);
706   gp_Pnt2d pori1(Uon1,0.);
707   gp_Lin2d lfil1(pori1,gp::DY2d());
708   Handle(Geom2d_Curve) PCurveOnSurf = new Geom2d_Line(lfil1);
709   Handle(Geom2d_Curve) PCurveOnFace;
710   PCurveOnFace = new 
711     Geom2d_BSplineCurve(approx.Curve2dPoles(ion1),approx.Curves2dKnots(),
712                         approx.Curves2dMults(),approx.Curves2dDegree());
713   
714   
715    Standard_Real par1=PCurveOnFace->FirstParameter();
716    Standard_Real par2= PCurveOnFace->LastParameter();
717    chc.Load(Crv3d1,par1,par2);
718    
719  if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S1,tolC1,tolcheck)){
720 #ifdef DEB
721    cout<<"tol approx sous evaluee : "<<tolC1<<" pour "<<tolcheck<<endl;
722 #endif 
723     tolC1 = tolcheck;
724   }
725   Standard_Integer Index1OfCurve = 
726     DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d1,tolC1));
727   
728   Standard_Real uarc,utg;
729   if(Gd1){
730     TopoDS_Face forwfac = BS1->ChangeSurface().Face();
731     forwfac.Orientation(TopAbs_FORWARD);
732     brc.Initialize(Data->VertexFirstOnS1().Arc(),forwfac);
733     ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS1();
734     CArc.Initialize(V.Arc());
735     CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
736     tolcheck = CArc.Value(uarc).Distance(V.Point());
737     V.SetArc(tolC1+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
738     pppdeb = utg;
739   }
740   else pppdeb = VFirst;
741   if(Gf1){
742     TopoDS_Face forwfac = BS1->ChangeSurface().Face();
743     forwfac.Orientation(TopAbs_FORWARD);
744     ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS1();
745     brc.Initialize(V.Arc(),forwfac);
746     CArc.Initialize(V.Arc());
747     CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
748     tolcheck = CArc.Value(uarc).Distance(V.Point());
749     V.SetArc(tolC1+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
750     pppfin = utg;
751   }
752   else pppfin = VLast;
753   ChFiDS_FaceInterference& Fint1 = Data->ChangeInterferenceOnS1();
754   Fint1.SetFirstParameter(pppdeb);
755   Fint1.SetLastParameter(pppfin);
756   TopAbs_Orientation TraOn1;
757   if(Reversed) TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS2());
758   else TraOn1 = ChFi3d_TrsfTrans(lin->TransitionOnS1());
759   Fint1.SetInterference(Index1OfCurve,TraOn1,PCurveOnFace,PCurveOnSurf);
760   
761   // on remplit la SurfData pour ce qui concerne S2,
762   Handle(Geom_Curve) Crv3d2 = Surf->UIso(Uon2);
763   gp_Pnt2d pori2(Uon2,0.);
764   gp_Lin2d lfil2(pori2,gp::DY2d());
765   PCurveOnSurf = new Geom2d_Line(lfil2);
766   if(!S2.IsNull()){
767     PCurveOnFace = new Geom2d_BSplineCurve(approx.Curve2dPoles(ion2),
768                                            approx.Curves2dKnots(),
769                                            approx.Curves2dMults(),
770                                            approx.Curves2dDegree());
771     chc.Load(Crv3d2,par1,par2);
772    if(!ChFi3d_CheckSameParameter(checkcurve,PCurveOnFace,S2,tolC2,tolcheck)){
773 #ifdef DEB
774       cout<<"tol approx sous evaluee : "<<tolC2<<" pour "<<tolcheck<<endl;
775 #endif 
776       tolC2 = tolcheck;
777     }
778   }
779   Standard_Integer Index2OfCurve = 
780     DStr.AddCurve(TopOpeBRepDS_Curve(Crv3d2,tolC2));
781   if(Gd2){
782     TopoDS_Face forwfac = BS2->ChangeSurface().Face();
783     forwfac.Orientation(TopAbs_FORWARD);
784     brc.Initialize(Data->VertexFirstOnS2().Arc(),forwfac);
785     ChFiDS_CommonPoint& V = Data->ChangeVertexFirstOnS2();
786     CArc.Initialize(V.Arc());
787     CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
788     tolcheck = CArc.Value(uarc).Distance(V.Point());
789     V.SetArc(tolC2+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
790     pppdeb = utg;
791   }
792   else pppdeb = VFirst;
793   if(Gf2){
794     TopoDS_Face forwfac = BS2->ChangeSurface().Face();
795     forwfac.Orientation(TopAbs_FORWARD);
796     brc.Initialize(Data->VertexLastOnS2().Arc(),forwfac);
797     ChFiDS_CommonPoint& V = Data->ChangeVertexLastOnS2();
798     CArc.Initialize(V.Arc());
799     CompParam(brc,PCurveOnFace,uarc,utg, V.ParameterOnArc(), V.Parameter());
800     tolcheck = CArc.Value(uarc).Distance(V.Point());
801     V.SetArc(tolC2+tolcheck,V.Arc(),uarc,V.TransitionOnArc());
802     pppfin = utg;
803   }
804   else pppfin = VLast;
805   ChFiDS_FaceInterference& Fint2 = Data->ChangeInterferenceOnS2();
806   Fint2.SetFirstParameter(pppdeb);
807   Fint2.SetLastParameter(pppfin);
808   if(!S2.IsNull()){
809     TopAbs_Orientation TraOn2;
810     if(Reversed) TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS1());
811     else TraOn2 = ChFi3d_TrsfTrans(lin->TransitionOnS2());
812     Fint2.SetInterference(Index2OfCurve,TraOn2,PCurveOnFace,PCurveOnSurf);
813   }
814   else {
815     Handle(Geom2d_Curve) bidpc;
816     Fint2.SetInterference
817       (Index2OfCurve,TopAbs_FORWARD,bidpc,PCurveOnSurf);
818   }
819
820   // on calcule l orientation du conge par rapport aux faces,
821
822   Handle(Adaptor3d_HSurface) Sref = S1;
823   PCurveOnFace = Fint1.PCurveOnFace();
824   if(Reversed){ Sref = S2; PCurveOnFace = Fint2.PCurveOnFace(); }
825   
826 //  Modified by skv - Wed Jun  9 17:16:26 2004 OCC5898 Begin
827 //   gp_Pnt2d PUV = PCurveOnFace->Value((VFirst+VLast)/2.);
828 //   gp_Pnt P;
829 //   gp_Vec Du1,Du2,Dv1,Dv2;
830 //   Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1);
831 //   Du1.Cross(Dv1);
832 //   if (Or1 == TopAbs_REVERSED) Du1.Reverse();
833 //   Surf->D1(UFirst,(VFirst+VLast)/2.,P,Du2,Dv2);
834 //   Du2.Cross(Dv2);
835 //   if (Du1.Dot(Du2)>0) Data->ChangeOrientation() = TopAbs_FORWARD;
836 //   else Data->ChangeOrientation() = TopAbs_REVERSED;
837
838   Standard_Real    aDelta = VLast - VFirst;
839   Standard_Integer aDenom = 2;
840
841   while (Standard_True) {
842     Standard_Real aDeltav = aDelta/aDenom;
843     Standard_Real aParam  = VFirst + aDeltav;
844     gp_Pnt2d      PUV     = PCurveOnFace->Value(aParam);
845     gp_Pnt        P;
846     gp_Vec        Du1,Du2,Dv1,Dv2;
847
848     Sref->D1(PUV.X(),PUV.Y(),P,Du1,Dv1);
849     Du1.Cross(Dv1);
850
851     if (Or1 == TopAbs_REVERSED)
852       Du1.Reverse();
853
854     Surf->D1(UFirst, aParam, P, Du2, Dv2);
855     Du2.Cross(Dv2);
856
857     if (Du1.Magnitude() <= tolget3d ||
858         Du2.Magnitude() <= tolget3d) {
859       aDenom++;
860
861       if (Abs(aDeltav) <= tolget2d)
862         return Standard_False;
863
864       continue;
865     }
866
867     if (Du1.Dot(Du2)>0)
868       Data->ChangeOrientation() = TopAbs_FORWARD;
869     else
870       Data->ChangeOrientation() = TopAbs_REVERSED;
871
872     break;
873   }
874 //  Modified by skv - Wed Jun  9 17:16:26 2004 OCC5898 End
875   
876   if(!Gd1 && !S1.IsNull())
877     ChFi3d_FilCommonPoint(lin->StartPointOnFirst(),lin->TransitionOnS1(),
878                           Standard_True, Data->ChangeVertex(1,ion1),tolC1);
879   if(!Gf1 && !S1.IsNull())
880     ChFi3d_FilCommonPoint(lin->EndPointOnFirst(),lin->TransitionOnS1(),
881                           Standard_False,Data->ChangeVertex(0,ion1),tolC1);
882   if(!Gd2 && !S2.IsNull())
883     ChFi3d_FilCommonPoint(lin->StartPointOnSecond(),lin->TransitionOnS2(),
884                           Standard_True, Data->ChangeVertex(1,ion2),tolC2);
885   if(!Gf2 && !S2.IsNull())
886     ChFi3d_FilCommonPoint(lin->EndPointOnSecond(),lin->TransitionOnS2(),
887                           Standard_False, Data->ChangeVertex(0,ion2),tolC2);
888   // Les parametres sur l ElSpine
889   Standard_Integer nbp = lin->NbPoints();
890   Data->FirstSpineParam(lin->Point(1).Parameter());
891   Data->LastSpineParam(lin->Point(nbp).Parameter());
892   return Standard_True;
893 }                        
894
895
896
897 //=======================================================================
898 //function : ComputeData
899 //purpose  : Chapeau du cheminement edge/face pour le contournement
900 //           d 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   // on recadre la solution de depart a la demande.
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 : echec calcul 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 << "Cheminement non fait" << 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 << "Complement non fait" << 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 <<"1 seul point de cheminement on essaye MS/50."<<endl;
994 #endif  
995       MS = MS/50.; Target = Targetsov;
996     }
997     else if (Nbpnt<=nbptmin && again == 0)  {
998       again++;
999 #ifdef DEB
1000       cout <<"Nombre de points insuffisant on reduit le pas"<<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 <<"Nombre de points toujours insuffisant on sort"<<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  : Chapeau du cheminement edge/edge pour le contournement
1033 //           d obstacle.
1034 //=======================================================================
1035
1036 Standard_Boolean ChFi3d_Builder::ComputeData
1037 (Handle(ChFiDS_SurfData)&         Data,
1038  const Handle(ChFiDS_HElSpine)&   HGuide,
1039  Handle(BRepBlend_Line)&          Lin,
1040  const Handle(Adaptor3d_HSurface)&  S1,
1041  const Handle(Adaptor2d_HCurve2d)&  PC1,
1042  const Handle(Adaptor3d_TopolTool)& I1,
1043  Standard_Boolean&                Decroch1,
1044  const Handle(Adaptor3d_HSurface)&  S2,
1045  const Handle(Adaptor2d_HCurve2d)&  PC2,
1046  const Handle(Adaptor3d_TopolTool)& I2,
1047  Standard_Boolean&                Decroch2,
1048  Blend_RstRstFunction&            Func,
1049  Blend_SurfCurvFuncInv&           FInv1,
1050  Blend_CurvPointFuncInv&          FInvP1,
1051  Blend_SurfCurvFuncInv&           FInv2,
1052  Blend_CurvPointFuncInv&          FInvP2,
1053  const Standard_Real              PFirst,
1054  const Standard_Real              MaxStep,
1055  const Standard_Real              Fleche,
1056  const Standard_Real              TolGuide,
1057  Standard_Real&                   First,
1058  Standard_Real&                   Last,
1059  const math_Vector&               Soldep,
1060  const Standard_Boolean           Inside,
1061  const Standard_Boolean           Appro,
1062  const Standard_Boolean           Forward,
1063  const Standard_Boolean           RecP1,
1064  const Standard_Boolean           RecRst1,
1065  const Standard_Boolean           RecP2,
1066  const Standard_Boolean           RecRst2)
1067 {
1068   BRepBlend_RstRstLineBuilder TheWalk(S1, PC1, I1, S2, PC2, I2);
1069   
1070   Data->FirstExtensionValue(0);
1071   Data->LastExtensionValue(0); 
1072
1073   Standard_Boolean reverse = (!Forward || Inside);
1074   Standard_Real SpFirst = HGuide->FirstParameter();
1075   Standard_Real SpLast =  HGuide->LastParameter();
1076   Standard_Real Target = SpLast;
1077   if(reverse) Target = SpFirst;
1078   Standard_Real Targetsov = Target;
1079   
1080   Standard_Real MS = MaxStep;
1081   Standard_Integer again = 0;
1082   Standard_Integer nbptmin = 3; //jlr
1083 #ifndef DEB
1084   Standard_Integer Nbpnt = 0;
1085 #else
1086   Standard_Integer Nbpnt;
1087 #endif
1088   // on recadre la solution de depart a la demande.
1089   math_Vector ParSol(1,2);
1090   Standard_Real NewFirst = PFirst;
1091   if (RecP1 || RecRst1 || RecP2 || RecRst2) {
1092     if (!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep,
1093                                      tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2,
1094                                      NewFirst, ParSol)){
1095 #ifdef DEB
1096       cout<<"ChFi3d_Builder::ComputeData : echec calcul first section"<<endl;
1097 #endif
1098       return Standard_False;
1099     }
1100   }
1101   else {
1102     ParSol = Soldep;
1103   }
1104
1105   while (again < 2){
1106     TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last,
1107                      MS, TolGuide, ParSol, tolesp, Fleche, Appro);
1108
1109     if (!TheWalk.IsDone()) {
1110 #ifdef DEB
1111       cout << "Cheminement non fait" << endl;
1112 #endif  
1113       return Standard_False;
1114     }
1115   
1116     if (reverse) {
1117       if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) {
1118 #ifdef DEB
1119         cout << "Complement non fait" << endl;
1120 #endif
1121       }
1122     }  
1123   
1124
1125     Lin = TheWalk.Line();
1126     Nbpnt = Lin->NbPoints();
1127     if (Nbpnt <= 1 && again == 0)  {
1128       again++;
1129 #ifdef DEB
1130       cout <<"1 seul point de cheminement on essaye MS/50."<<endl;
1131 #endif  
1132       MS = MS/50.; Target = Targetsov;
1133     }
1134     else if (Nbpnt<=nbptmin && again == 0)  {
1135       again++;
1136 #ifdef DEB
1137       cout <<"Nombre de points insuffisant on reduit le pas"<<endl;
1138 #endif  
1139       Standard_Real u1 = Lin->Point(1).Parameter();
1140       Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1141       MS = (u2-u1)/(nbptmin+1);
1142       Target = Targetsov;
1143     }
1144     else if(Nbpnt<=nbptmin){
1145 #ifdef DEB
1146       cout <<"Nombre de points toujours insuffisant on sort"<<endl;
1147 #endif  
1148       return Standard_False;
1149     }
1150     else {
1151       again = 2;
1152     }
1153   }
1154 #ifdef DRAW
1155   ChFi3d_SettraceDRAWWALK(Standard_True);
1156   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1157 #endif  
1158   if (Forward) {
1159     Decroch1 = TheWalk.Decroch1End();
1160     Decroch2 = TheWalk.Decroch2End();
1161   }
1162   else {
1163     Decroch1 = TheWalk.Decroch1Start();
1164     Decroch2 = TheWalk.Decroch2Start();  
1165   }
1166   Last  = Lin->Point(Nbpnt).Parameter();
1167   First = Lin->Point(1).Parameter();
1168   return Standard_True;
1169 }
1170
1171
1172 //=======================================================================
1173 //function : SimulData
1174 //purpose  : Chapeau du cheminement edge/face pour le contournement
1175 //           d obstacle en mode simulation.
1176 //=======================================================================
1177
1178 Standard_Boolean ChFi3d_Builder::SimulData
1179 (Handle(ChFiDS_SurfData)&         /*Data*/,
1180  const Handle(ChFiDS_HElSpine)&   HGuide,
1181  Handle(BRepBlend_Line)&          Lin,
1182  const Handle(Adaptor3d_HSurface)&  S1,
1183  const Handle(Adaptor3d_TopolTool)& I1,
1184  const Handle(Adaptor3d_HSurface)&  S2,
1185  const Handle(Adaptor2d_HCurve2d)&  PC2,
1186  const Handle(Adaptor3d_TopolTool)& I2,
1187  Standard_Boolean&                Decroch,
1188  Blend_SurfRstFunction&           Func,
1189  Blend_FuncInv&                   FInv,
1190  Blend_SurfPointFuncInv&          FInvP,
1191  Blend_SurfCurvFuncInv&           FInvC,
1192  const Standard_Real              PFirst,
1193  const Standard_Real              MaxStep,
1194  const Standard_Real              Fleche,
1195  const Standard_Real              TolGuide,
1196  Standard_Real&                   First,
1197  Standard_Real&                   Last,
1198  const math_Vector&               Soldep,
1199  const Standard_Integer           NbSecMin,
1200  const Standard_Boolean           Inside,
1201  const Standard_Boolean           Appro,
1202  const Standard_Boolean           Forward,
1203  const Standard_Boolean           RecP,
1204  const Standard_Boolean           RecS,
1205  const Standard_Boolean           RecRst)
1206 {
1207   BRepBlend_SurfRstLineBuilder TheWalk(S1,I1,S2,PC2,I2);
1208
1209   Standard_Boolean reverse = (!Forward || Inside);
1210   Standard_Real SpFirst = HGuide->FirstParameter();
1211   Standard_Real SpLast =  HGuide->LastParameter();
1212   Standard_Real Target = SpLast;
1213   if(reverse) Target = SpFirst;
1214   Standard_Real Targetsov = Target;
1215   
1216   Standard_Real MS = MaxStep;
1217   Standard_Integer again = 0;
1218 #ifndef DEB
1219   Standard_Integer Nbpnt = 0; 
1220 #else
1221   Standard_Integer Nbpnt; 
1222 #endif
1223   // on recadre la solution de depart a la demande.
1224   math_Vector ParSol(1,3);
1225   Standard_Real NewFirst = PFirst;
1226   if(RecP || RecS || RecRst){
1227     if(!TheWalk.PerformFirstSection(Func,FInv,FInvP,FInvC,PFirst,Target,Soldep,
1228                                     tolesp,TolGuide,RecRst,RecP,RecS,
1229                                     NewFirst,ParSol)){
1230 #ifdef DEB
1231
1232       cout<<"ChFi3d_Builder::SimulData : echec calcul first section"<<endl;
1233 #endif
1234       return Standard_False;
1235     }
1236   }
1237   else {
1238     ParSol = Soldep;
1239   }
1240
1241   while (again < 2){
1242     TheWalk.Perform (Func,FInv,FInvP,FInvC,NewFirst,Last,
1243                      MS,TolGuide,ParSol,tolesp,Fleche,Appro);
1244     if (!TheWalk.IsDone()) {
1245 #ifdef DEB
1246       cout << "Cheminement non fait" << endl;
1247 #endif
1248       return Standard_False;
1249     }
1250     if (reverse) {
1251       if (!TheWalk.Complete(Func,FInv,FInvP,FInvC,SpLast)) {
1252 #ifdef DEB
1253         cout << "Complement non fait" << endl;
1254 #endif
1255       }
1256     }  
1257     Lin = TheWalk.Line();
1258     Nbpnt = Lin->NbPoints();
1259     if (Nbpnt <= 1 && again == 0)  {
1260       again++;
1261 #ifdef DEB
1262       cout <<"1 seul point de cheminement on essaye MS/50."<<endl;
1263 #endif
1264       MS = MS/50.; Target = Targetsov;
1265     }
1266     else if (Nbpnt <= NbSecMin && again == 0)  {
1267       again++;
1268 #ifdef DEB
1269       cout <<"Nombre de points insuffisant on reduit le pas"<<endl;
1270 #endif
1271       Standard_Real u1 = Lin->Point(1).Parameter();
1272       Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1273       MS = (u2-u1)/(NbSecMin+1);
1274       Target = Targetsov;
1275     }
1276     else if(Nbpnt<=NbSecMin){
1277 #ifdef DEB
1278       cout <<"Nombre de points toujours insuffisant on sort"<<endl;
1279 #endif
1280       return Standard_False;
1281     }
1282     else {
1283       again = 2;
1284     }
1285   }
1286 #ifdef DRAW
1287   ChFi3d_SettraceDRAWWALK(Standard_True);
1288   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1289 #endif  
1290   if(Forward) Decroch = TheWalk.DecrochEnd();
1291   else Decroch = TheWalk.DecrochStart();
1292   Last = Lin->Point(Nbpnt).Parameter();
1293   First = Lin->Point(1).Parameter();
1294   return Standard_True;
1295 }
1296
1297
1298 //=======================================================================
1299 //function : SimulData
1300 //purpose  : Chapeau du cheminement edge/edge pour le contournement
1301 //           d obstacle en mode simulation.
1302 //=======================================================================
1303
1304 Standard_Boolean ChFi3d_Builder::SimulData
1305 (Handle(ChFiDS_SurfData)&         /*Data*/,
1306  const Handle(ChFiDS_HElSpine)&   HGuide,
1307  Handle(BRepBlend_Line)&          Lin,
1308  const Handle(Adaptor3d_HSurface)&  S1,
1309  const Handle(Adaptor2d_HCurve2d)&  PC1,
1310  const Handle(Adaptor3d_TopolTool)& I1,
1311  Standard_Boolean&                Decroch1,
1312  const Handle(Adaptor3d_HSurface)&  S2,
1313  const Handle(Adaptor2d_HCurve2d)&  PC2,
1314  const Handle(Adaptor3d_TopolTool)& I2,
1315  Standard_Boolean&                Decroch2,
1316  Blend_RstRstFunction&            Func,
1317  Blend_SurfCurvFuncInv&           FInv1,
1318  Blend_CurvPointFuncInv&          FInvP1,
1319  Blend_SurfCurvFuncInv&           FInv2,
1320  Blend_CurvPointFuncInv&          FInvP2,
1321  const Standard_Real              PFirst,
1322  const Standard_Real              MaxStep,
1323  const Standard_Real              Fleche,
1324  const Standard_Real              TolGuide,
1325  Standard_Real&                   First,
1326  Standard_Real&                   Last,
1327  const math_Vector&               Soldep,
1328  const Standard_Integer           NbSecMin,
1329  const Standard_Boolean           Inside,
1330  const Standard_Boolean           Appro,
1331  const Standard_Boolean           Forward,
1332  const Standard_Boolean           RecP1,
1333  const Standard_Boolean           RecRst1,
1334  const Standard_Boolean           RecP2,
1335  const Standard_Boolean           RecRst2)
1336 {
1337   BRepBlend_RstRstLineBuilder TheWalk(S1, PC1, I1, S2, PC2, I2);
1338
1339   Standard_Boolean reverse = (!Forward || Inside);
1340   Standard_Real SpFirst = HGuide->FirstParameter();
1341   Standard_Real SpLast =  HGuide->LastParameter();
1342   Standard_Real Target = SpLast;
1343   if(reverse) Target = SpFirst;
1344   Standard_Real Targetsov = Target;
1345   
1346   Standard_Real MS = MaxStep;
1347   Standard_Integer again = 0;
1348 #ifndef DEB
1349   Standard_Integer Nbpnt = 0; 
1350 #else
1351   Standard_Integer Nbpnt; 
1352 #endif
1353   // on recadre la solution de depart a la demande.
1354   math_Vector ParSol(1,2);
1355   Standard_Real NewFirst = PFirst;
1356   if (RecP1 || RecRst1 || RecP2 || RecRst2) {
1357     if(!TheWalk.PerformFirstSection(Func, FInv1, FInvP1, FInv2, FInvP2, PFirst, Target, Soldep,
1358                                     tolesp, TolGuide, RecRst1, RecP1, RecRst2, RecP2,
1359                                     NewFirst,ParSol)){
1360 #ifdef DEB
1361
1362       cout<<"ChFi3d_Builder::SimulData : echec calcul first section"<<endl;
1363 #endif
1364       return Standard_False;
1365     }
1366   }
1367   else {
1368     ParSol = Soldep;
1369   }
1370
1371   while (again < 2){
1372     TheWalk.Perform (Func, FInv1, FInvP1, FInv2, FInvP2, NewFirst, Last,
1373                      MS, TolGuide, ParSol, tolesp, Fleche, Appro);
1374     if (!TheWalk.IsDone()) {
1375 #ifdef DEB
1376       cout << "Cheminement non fait" << endl;
1377 #endif
1378       return Standard_False;
1379     }
1380     if (reverse) {
1381       if (!TheWalk.Complete(Func, FInv1, FInvP1, FInv2, FInvP2, SpLast)) {
1382 #ifdef DEB
1383         cout << "Complement non fait" << endl;
1384 #endif
1385       }
1386     }  
1387     Lin = TheWalk.Line();
1388     Nbpnt = Lin->NbPoints();
1389     if (Nbpnt <= 1 && again == 0)  {
1390       again++;
1391 #ifdef DEB
1392       cout <<"1 seul point de cheminement on essaye MS/50."<<endl;
1393 #endif
1394       MS = MS/50.; Target = Targetsov;
1395     }
1396     else if (Nbpnt <= NbSecMin && again == 0)  {
1397       again++;
1398 #ifdef DEB
1399       cout <<"Nombre de points insuffisant on reduit le pas"<<endl;
1400 #endif
1401       Standard_Real u1 = Lin->Point(1).Parameter();
1402       Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
1403       MS = (u2-u1)/(NbSecMin+1);
1404       Target = Targetsov;
1405     }
1406     else if(Nbpnt<=NbSecMin){
1407 #ifdef DEB
1408       cout <<"Nombre de points toujours insuffisant on sort"<<endl;
1409 #endif
1410       return Standard_False;
1411     }
1412     else {
1413       again = 2;
1414     }
1415   }
1416 #ifdef DRAW
1417   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_True);
1418 #endif
1419   if (Forward) {
1420     Decroch1 = TheWalk.Decroch1End();
1421     Decroch2 = TheWalk.Decroch2End();
1422   }
1423   else {
1424     Decroch1 = TheWalk.Decroch1Start();
1425     Decroch2 = TheWalk.Decroch2Start();  
1426   }  
1427
1428   Last = Lin->Point(Nbpnt).Parameter();
1429   First = Lin->Point(1).Parameter();
1430   return Standard_True;
1431 }
1432
1433
1434
1435
1436 //=======================================================================
1437 //function : ComputeData
1438 //purpose  : Construction d un conge elementaire par cheminement.
1439 //
1440 //=======================================================================
1441
1442 Standard_Boolean ChFi3d_Builder::ComputeData
1443 (Handle(ChFiDS_SurfData)& Data,
1444  const Handle(ChFiDS_HElSpine)& HGuide,
1445  const Handle(ChFiDS_Spine)& Spine,
1446  Handle(BRepBlend_Line)& Lin,
1447  const Handle(Adaptor3d_HSurface)& S1,
1448  const Handle(Adaptor3d_TopolTool)& I1,
1449  const Handle(Adaptor3d_HSurface)& S2,
1450  const Handle(Adaptor3d_TopolTool)& I2,
1451  Blend_Function& Func,
1452  Blend_FuncInv& FInv,
1453  const Standard_Real PFirst,
1454  const Standard_Real MaxStep,
1455  const Standard_Real Fleche,
1456  const Standard_Real tolguide,
1457  Standard_Real& First,
1458  Standard_Real& Last,
1459  const Standard_Boolean Inside,
1460  const Standard_Boolean Appro,
1461  const Standard_Boolean Forward,
1462  const math_Vector& Soldep,
1463  Standard_Boolean& intf,
1464  Standard_Boolean& intl,
1465  Standard_Boolean& Gd1,
1466  Standard_Boolean& Gd2,
1467  Standard_Boolean& Gf1,
1468  Standard_Boolean& Gf2,
1469  const Standard_Boolean RecOnS1,
1470  const Standard_Boolean RecOnS2)
1471 {
1472   //Les prolongements en cas de sortie des deux domaines sont faits
1473   //de facon directe et non plus par cheminement ( trop hasardeux ).
1474   Data->FirstExtensionValue(0);
1475   Data-> LastExtensionValue(0);
1476
1477   //On recupere les faces eventuelles pour les tests de saut d edge.
1478   TopoDS_Face F1, F2;
1479   Handle(BRepAdaptor_HSurface) HS = Handle(BRepAdaptor_HSurface)::DownCast(S1); 
1480   if(!HS.IsNull()) F1 = HS->ChangeSurface().Face();
1481   HS = Handle(BRepAdaptor_HSurface)::DownCast(S2); 
1482   if(!HS.IsNull()) F2 = HS->ChangeSurface().Face();
1483   
1484   // Variables d'encadrement du cheminement
1485   Standard_Real TolGuide=tolguide, TolEsp = tolesp;
1486   Standard_Integer nbptmin = 4;
1487
1488   BRepBlend_Walking TheWalk(S1,S2,I1,I2);
1489
1490   //Debut du carnage, on eteint les controles 2d du cheminement
1491   //qui s'accomodent mal des surfaces a parametrages non homogenes
1492   //en u et en v.
1493   TheWalk.Check2d(0);
1494   
1495   Standard_Real MS = MaxStep;
1496   Standard_Integer Nbpnt;
1497   Standard_Real SpFirst = HGuide->FirstParameter();
1498   Standard_Real SpLast =  HGuide->LastParameter();
1499
1500   // Lorsque le point de depart est interne, on chemine 
1501   // d abord a gauche afin de determiner le Last pour les
1502   // periodiques.
1503   Standard_Boolean reverse = (!Forward || Inside);
1504   Standard_Real Target;
1505   if(reverse){
1506     Target = SpFirst;
1507     if(!intf) Target = Last;
1508   }
1509   else{
1510     Target = SpLast + Abs(SpLast);
1511     if(!intl) Target = Last;
1512   }
1513
1514   // Dans le cas de singularite pre-determinee,
1515   // on en informe le cheminement
1516   if (!Spine.IsNull()){
1517     if (Spine->IsTangencyExtremity(Standard_True)) {
1518       TopoDS_Vertex V = Spine->FirstVertex();
1519       TopoDS_Edge E = Spine->Edges(1);
1520       Standard_Real param =  Spine->FirstParameter();
1521       Blend_Point BP;
1522       if (CompBlendPoint(V, E, param, F1, F2, BP)) {
1523         math_Vector vec(1,4);
1524         BP.ParametersOnS1(vec(1),vec(2));
1525         BP.ParametersOnS2(vec(3),vec(4));
1526         Func.Set(param);
1527         if (Func.IsSolution(vec, tolesp)) {
1528           TheWalk.AddSingularPoint(BP);
1529         }
1530       }
1531     }
1532     if (Spine->IsTangencyExtremity(Standard_False)) {
1533       TopoDS_Vertex V = Spine->LastVertex();
1534       TopoDS_Edge E = Spine->Edges( Spine->NbEdges()); 
1535       Standard_Real param =  Spine->LastParameter();
1536       Blend_Point BP;
1537       if (CompBlendPoint(V, E, param, F1, F2, BP)) {
1538         math_Vector vec(1,4);
1539         BP.ParametersOnS1(vec(1),vec(2));
1540         BP.ParametersOnS2(vec(3),vec(4));
1541         Func.Set(param);
1542         if (Func.IsSolution(vec, tolesp)) {
1543           TheWalk.AddSingularPoint(BP);
1544         }
1545       }
1546     }
1547   }
1548
1549   //On recadre la solution de depart a la demande.
1550   //**********************************************//
1551   math_Vector ParSol(1,4);
1552   Standard_Real NewFirst = PFirst;
1553   if(RecOnS1 || RecOnS2){
1554     if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep,
1555                                     tolesp,TolGuide,RecOnS1,RecOnS2,
1556                                     NewFirst,ParSol)){
1557 #ifdef DEB
1558       cout<<"ChFi3d_Builder::ComputeData : echec calcul first section"<<endl;
1559 #endif
1560       return Standard_False;
1561     }
1562   }
1563   else {
1564     ParSol = Soldep;
1565   }
1566
1567   //On calcule d abord la partie valide, sans souci des prolongements.
1568   //******************************************************************//
1569   Standard_Integer again = 0;
1570   Standard_Boolean tchernobyl = 0;
1571 #ifndef DEB
1572   Standard_Real u1sov = 0., u2sov = 0.;
1573 #else
1574   Standard_Real u1sov, u2sov;
1575 #endif
1576   TopoDS_Face bif;
1577   //Un pas max coherent, mais grand, on compte sur la fleche pour detecter
1578   //les vrillages.
1579   if( (Abs(Last-First) <= MS * 5.) &&
1580       (Abs(Last-First) >= 0.01*Abs(NewFirst-Target)) ){ 
1581     MS = Abs(Last-First)*0.2; 
1582   }
1583
1584   while(again < 3){
1585     //On chemine. 
1586     if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide;
1587     else {
1588       if (5*TolGuide > MS) TolGuide = MS/5;
1589       if (5*TolEsp > MS) TolEsp = MS/5;
1590     }
1591     TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
1592                     ParSol,TolEsp,Fleche,Appro);
1593     if (!TheWalk.IsDone()) {
1594 #ifdef DEB
1595       cout << "Cheminement non fait" << endl;
1596 #endif
1597       return Standard_False;
1598     }
1599     Lin = TheWalk.Line();
1600     if(HGuide->IsPeriodic() && Inside) {
1601       SpFirst = Lin->Point(1).Parameter();
1602       SpLast  = SpFirst + HGuide->Period();
1603       HGuide->ChangeCurve().FirstParameter(SpFirst);
1604       HGuide->ChangeCurve().LastParameter (SpLast );
1605       HGuide->ChangeCurve().SetOrigin(SpFirst);
1606     }
1607     Standard_Boolean complmnt = Standard_True;
1608     if (Inside)  complmnt = TheWalk.Complete(Func,FInv,SpLast);
1609     if(!complmnt){
1610 #ifdef DEB
1611       cout << "Complement non fait" << endl;
1612 #endif
1613       return Standard_False;
1614     }
1615     
1616     //On controle le resultat avec deux criteres :
1617     //- y a-t-il assez de points,
1618     //- est-on alle assez loin.
1619     Nbpnt = Lin->NbPoints();
1620     if (Nbpnt == 0){
1621 #ifdef DEB
1622       cout <<"0 point de cheminement on sort."<<endl;
1623 #endif
1624       return Standard_False;
1625     }
1626     Standard_Real fpointpar = Lin->Point(1).Parameter();
1627     Standard_Real lpointpar = Lin->Point(Nbpnt).Parameter();
1628     
1629     Standard_Real factor =  1./(nbptmin + 1);
1630     Standard_Boolean okdeb = (Forward && !Inside);  
1631     Standard_Boolean okfin = (!Forward && !Inside);
1632     if(!okdeb){
1633       Standard_Integer narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1634       Standard_Integer narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1635       okdeb = (narc1 > 0 || narc2 > 0 || (fpointpar-First) < 10*TolGuide); 
1636     }
1637     if(!okfin){
1638       Standard_Integer narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1639       Standard_Integer narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1640       okfin = (narc1 > 0 || narc2 > 0 || (Last-lpointpar) < 10*TolGuide);
1641     }
1642     if(!okdeb || !okfin || Nbpnt == 1){
1643       //Ca frotte, on eteint les controles on espere evaluer un pas max
1644       //satisfaisant, et on serre les fesses!!!. Si c est deja fait on
1645       //sort.
1646       if(tchernobyl){
1647 #ifdef DEB
1648         cout <<"Ca frotte meme sans controle, on sort."<<endl;
1649 #endif
1650         return Standard_False;
1651       }
1652       tchernobyl = Standard_True;
1653       TheWalk.Check(0);
1654       if (Nbpnt == 1){
1655 #ifdef DEB
1656         cout <<"1 seul point de cheminement on essaye MS/100"<<endl;
1657         cout <<"et on eteint les controles."<<endl;
1658 #endif
1659         MS *= 0.01;
1660       }
1661       else{
1662 #ifdef DEB
1663         cout <<"Ca frotte on eteint les controles."<<endl;
1664 #endif
1665         MS = (lpointpar-fpointpar)/Nbpnt; //EvalStep(Lin);
1666       }
1667     }
1668     else if (Nbpnt < nbptmin){
1669       if(again == 0){
1670 #ifdef DEB
1671         cout <<"Nombre de points insuffisant on reduit le pas"<<endl;
1672 #endif
1673         u1sov = fpointpar;
1674         u2sov = lpointpar;
1675         MS = (lpointpar - fpointpar) * factor;
1676       }
1677       else if(again == 1){
1678         if(Abs(fpointpar-u1sov)>=TolGuide || 
1679            Abs(lpointpar-u2sov)>=TolGuide){
1680 #ifdef DEB
1681           cout <<"Nombre de points encore insuffisant on reduit le pas"<<endl;
1682 #endif  
1683           MS = (lpointpar - fpointpar) * factor;
1684         }
1685         else{
1686 #ifdef DEB
1687           cout <<"Nombre de points toujours insuffisant on sort"<<endl;
1688 #endif  
1689           return Standard_False;
1690         }
1691       }
1692       again++;
1693     }
1694     else {
1695       again = 3;
1696     }
1697   }
1698
1699   if(TheWalk.TwistOnS1()){
1700     Data->TwistOnS1(Standard_True);
1701 #ifdef DEB
1702     cout<<"Cheminement complet mais VRILLE sur S1"<<endl;
1703 #endif
1704   }
1705   if(TheWalk.TwistOnS2()){
1706     Data->TwistOnS2(Standard_True);
1707 #ifdef DEB
1708     cout<<"Cheminement complet mais VRILLE sur S2"<<endl;
1709 #endif
1710   }
1711
1712
1713   //Ici on a un resultat plus ou moins presentable mais qui recouvre 
1714   //la zone minimum visee.
1715   //On attaque les prolongements.
1716   //*****************************//
1717
1718   Gd1 = Gd2 = Gf1 = Gf2 = Standard_False;
1719   
1720   Standard_Boolean unseulsuffitdeb = (intf >= 2);
1721   Standard_Boolean unseulsuffitfin = (intl >= 2);
1722   Standard_Boolean noproldeb = (intf >= 3);
1723   Standard_Boolean noprolfin = (intl >= 3);
1724
1725   Standard_Real Rab = 0.03*(SpLast-SpFirst);
1726
1727   Standard_Boolean debarc1 = 0, debarc2 = 0;
1728   Standard_Boolean debcas1 = 0, debcas2 = 0;
1729   Standard_Boolean debobst1 = 0, debobst2 = 0;
1730
1731   Standard_Boolean finarc1 = 0, finarc2 = 0;
1732   Standard_Boolean fincas1 = 0, fincas2 = 0;
1733   Standard_Boolean finobst1 = 0, finobst2 = 0;
1734
1735   Standard_Integer narc1, narc2;
1736
1737   Standard_Boolean backwContinueFailed = Standard_False; // eap
1738   if(reverse && intf) {
1739     narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1740     narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1741     if(narc1 != 0) {
1742       ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(),
1743                             Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1744       debarc1 = Standard_True;
1745       if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){
1746         //On regarde si ce n'est pas un obstacle.
1747         debcas1 = Standard_True;
1748         if(!Spine.IsNull()){
1749           if(Spine->IsPeriodic()){
1750             debobst1 = 1;
1751           }
1752           else{
1753             debobst1 = IsObst(Data->VertexFirstOnS1(),
1754                               Spine->FirstVertex(),myVEMap);
1755           }
1756         }
1757       }
1758     }
1759     if(narc2 != 0){
1760       ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(),
1761                             Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1762       debarc2 = Standard_True;
1763       if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){
1764         //On regarde si ce n'est pas un obstacle.
1765         debcas2 = Standard_True;
1766         if(!Spine.IsNull()){
1767           if(Spine->IsPeriodic()){
1768             debobst2 = 1;
1769           }
1770           else{
1771             debobst2 = IsObst(Data->VertexFirstOnS2(),
1772                               Spine->FirstVertex(),myVEMap);
1773           }
1774         }
1775       }
1776     }
1777     Standard_Boolean oncontinue = !noproldeb && (narc1 != 0 || narc2 != 0);
1778     if(debobst1 || debobst2) oncontinue = Standard_False;
1779     else if(debcas1 && debcas2) oncontinue = Standard_False;
1780     else if((!debcas1 && debarc1) || (!debcas2 && debarc2)) oncontinue = Standard_False;
1781
1782     if(oncontinue) {
1783       TheWalk.ClassificationOnS1(!debarc1);
1784       TheWalk.ClassificationOnS2(!debarc2);
1785       TheWalk.Check2d(Standard_True); // Il faut etre severe (PMN)
1786       TheWalk.Continu(Func,FInv,Target);
1787       TheWalk.ClassificationOnS1(Standard_True);
1788       TheWalk.ClassificationOnS2(Standard_True);
1789       TheWalk.Check2d(Standard_False);
1790       narc1 = Lin->StartPointOnFirst().NbPointOnRst();
1791       narc2 = Lin->StartPointOnSecond().NbPointOnRst();
1792 //  modified by eap Fri Feb  8 11:43:48 2002 ___BEGIN___
1793       if(!debarc1)
1794         if (narc1 == 0)
1795           backwContinueFailed = Lin->StartPointOnFirst().ParameterOnGuide() > Target;
1796         else {
1797           ChFi3d_FilCommonPoint(Lin->StartPointOnFirst(),Lin->TransitionOnS1(),
1798                                 Standard_True, Data->ChangeVertexFirstOnS1(),tolesp);
1799           debarc1 = Standard_True;
1800           if(!SearchFace(Spine,Data->VertexFirstOnS1(),F1,bif)){
1801             //On regarde si ce n'est pas un obstacle.
1802             debcas1 = Standard_True;
1803 //          if(!Spine.IsNull()) {
1804 //            if(Spine->IsPeriodic()){
1805 //              debobst1 = 1;
1806 //            }
1807 //            else{
1808 //              debobst1 = IsObst(Data->VertexFirstOnS1(),
1809 //                                Spine->FirstVertex(),myVEMap);
1810 //            }
1811 //          }
1812           }
1813         }
1814       if(!debarc2)
1815         if (narc2 == 0)
1816           backwContinueFailed = Lin->StartPointOnSecond().ParameterOnGuide() > Target;
1817         else {
1818           ChFi3d_FilCommonPoint(Lin->StartPointOnSecond(),Lin->TransitionOnS2(),
1819                                 Standard_True, Data->ChangeVertexFirstOnS2(),tolesp);
1820           debarc2 = Standard_True;
1821           if(!SearchFace(Spine,Data->VertexFirstOnS2(),F2,bif)){
1822             //On regarde si ce n'est pas un obstacle.
1823             debcas2 = Standard_True;
1824 //             if(!Spine.IsNull()){
1825 //               if(Spine->IsPeriodic()){
1826 //                 debobst2 = 1;
1827 //               }
1828 //               else{
1829 //                 debobst2 = IsObst(Data->VertexFirstOnS2(),
1830 //                                   Spine->FirstVertex(),myVEMap);
1831 //               }
1832 //             }
1833           }
1834         }
1835       if (backwContinueFailed) {
1836         // if we leave backwContinueFailed as is, we will stop in this direction
1837         // but we are to continue if there are no more faces on the side with arc
1838         // check this condition
1839         const ChFiDS_CommonPoint& aCP
1840           = debarc1 ? Data->VertexFirstOnS1() : Data->VertexFirstOnS2();
1841         if (aCP.IsOnArc() && bif.IsNull())
1842           backwContinueFailed = Standard_False;
1843       }
1844     }
1845   }
1846   Standard_Boolean forwContinueFailed = Standard_False;
1847 //  modified by eap Fri Feb  8 11:44:11 2002 ___END___
1848   if(Forward && intl) {
1849     Target = SpLast;
1850     narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1851     narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1852     if(narc1 != 0){
1853       ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(),
1854                             Standard_False, Data->ChangeVertexLastOnS1(),tolesp);
1855       finarc1 = Standard_True;
1856       if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){
1857         //On regarde si ce n'est pas un obstacle.
1858         fincas1 = Standard_True;
1859         if(!Spine.IsNull()){
1860           finobst1 = IsObst(Data->VertexLastOnS1(),
1861                             Spine->LastVertex(),myVEMap);
1862         }
1863       }
1864     }
1865     if(narc2 != 0){
1866       ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(),
1867                             Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1868       finarc2 = Standard_True;
1869       if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){
1870         //On regarde si ce n'est pas un obstacle.
1871         fincas2 = Standard_True;
1872         if(!Spine.IsNull()){
1873           finobst2 = IsObst(Data->VertexLastOnS2(),
1874                             Spine->LastVertex(),myVEMap);
1875         }
1876       }
1877     }
1878     Standard_Boolean oncontinue = !noprolfin && (narc1 != 0 || narc2 != 0);
1879     if(finobst1 || finobst2) oncontinue = Standard_False;
1880     else if(fincas1 && fincas2) oncontinue = Standard_False;
1881     else if((!fincas1 && finarc1) || (!fincas2 && finarc2)) oncontinue = Standard_False;
1882     
1883     if(oncontinue){
1884       TheWalk.ClassificationOnS1(!finarc1);
1885       TheWalk.ClassificationOnS2(!finarc2);
1886       TheWalk.Check2d(Standard_True); // Il faut etre severe (PMN)
1887       TheWalk.Continu(Func,FInv,Target);
1888       TheWalk.ClassificationOnS1(Standard_True);
1889       TheWalk.ClassificationOnS2(Standard_True);
1890       TheWalk.Check2d(Standard_False);
1891       narc1 = Lin->EndPointOnFirst().NbPointOnRst();
1892       narc2 = Lin->EndPointOnSecond().NbPointOnRst();
1893 //  modified by eap Fri Feb  8 11:44:57 2002 ___BEGIN___
1894       if(!finarc1)
1895         if (narc1 == 0) 
1896           forwContinueFailed = Lin->EndPointOnFirst().ParameterOnGuide() < Target;
1897         else {
1898           ChFi3d_FilCommonPoint(Lin->EndPointOnFirst(),Lin->TransitionOnS1(),
1899                                 Standard_False, Data->ChangeVertexLastOnS1(),tolesp);
1900           finarc1 = Standard_True;
1901           if(!SearchFace(Spine,Data->VertexLastOnS1(),F1,bif)){
1902             //On regarde si ce n'est pas un obstacle.
1903             fincas1 = Standard_True;
1904 //          if(!Spine.IsNull()){
1905 //            finobst1 = IsObst(Data->VertexLastOnS1(),
1906 //                              Spine->LastVertex(),myVEMap);
1907 //          }
1908           }
1909         }
1910       if(!finarc2)
1911         if (narc2 == 0)
1912           forwContinueFailed = Lin->EndPointOnSecond().ParameterOnGuide() < Target;
1913         else {
1914           ChFi3d_FilCommonPoint(Lin->EndPointOnSecond(),Lin->TransitionOnS2(),
1915                                 Standard_False, Data->ChangeVertexLastOnS2(),tolesp);
1916           finarc2 = Standard_True;
1917           if(!SearchFace(Spine,Data->VertexLastOnS2(),F2,bif)){
1918             //On regarde si ce n'est pas un obstacle.
1919             fincas2 = Standard_True;
1920 //          if(!Spine.IsNull()){
1921 //            finobst2 = IsObst(Data->VertexLastOnS2(),
1922 //                              Spine->LastVertex(),myVEMap);
1923 //          }
1924           }
1925         }
1926       if (forwContinueFailed) {
1927         // if we leave forwContinueFailed as is, we will stop in this direction
1928         // but we are to continue if there are no more faces on the side with arc
1929         // check this condition
1930         const ChFiDS_CommonPoint& aCP
1931           = finarc1 ? Data->VertexLastOnS1() : Data->VertexLastOnS2();
1932         if (aCP.IsOnArc() && bif.IsNull())
1933           forwContinueFailed = Standard_False;
1934       }
1935 //  modified by eap Fri Feb  8 11:45:10 2002 ___END___
1936     }
1937   }
1938   Nbpnt = Lin->NbPoints();
1939 #ifdef DRAW
1940   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False);
1941 #endif  
1942   First = Lin->Point(1).Parameter();
1943   Last  = Lin->Point(Nbpnt).Parameter();
1944
1945   // ============= INVALIDATION EVENTUELLE =============
1946   // ------ Preparation des prolongement par plan tangent -----
1947   if(reverse && intf){
1948     Gd1 = debcas1/* && !debobst1*/; // skv(occ67)
1949     Gd2 = debcas2/* && !debobst2*/; // skv(occ67)
1950     if ((debarc1^debarc2) && !unseulsuffitdeb && (First!=SpFirst)) {
1951       // Cas de cheminement incomplet, cela finit surement mal : 
1952       // on tronque le resultat au lieu de sortie.
1953       Standard_Real sortie;
1954       Standard_Integer ind;
1955       if (debarc1)  sortie = Data->VertexFirstOnS1().Parameter();
1956       else  sortie = Data->VertexFirstOnS2().Parameter();
1957       if (sortie - First > tolesp) {
1958         ind = SearchIndex(sortie, Lin);
1959         if (Lin->Point(ind).Parameter() == sortie) ind--;
1960         if (ind >= 1) {
1961           Lin->Remove(1, ind);
1962           UpdateLine(Lin, Standard_True);
1963         }
1964         Nbpnt = Lin->NbPoints();
1965         First = Lin->Point(1).Parameter();
1966       }
1967     }
1968     else if ((intf>=5) && !debarc1 && !debarc2 && (First!=SpFirst)) {
1969       Standard_Real sortie = (2*First+Last)/3;
1970       Standard_Integer ind;
1971       if (sortie - First > tolesp) {
1972         ind = SearchIndex(sortie, Lin);
1973         if (Lin->Point(ind).Parameter() == sortie) ind--;
1974         if (Nbpnt-ind < 3) ind = Nbpnt -3;
1975         if (ind >= 1) {
1976           Lin->Remove(1, ind);
1977           UpdateLine(Lin, Standard_True);
1978         }
1979         Nbpnt = Lin->NbPoints();
1980         First = Lin->Point(1).Parameter();
1981       }
1982     }
1983     if(Gd1 && Gd2){
1984       Target = Min((Lin->Point(1).Parameter() - Rab),First);
1985       Target = Max(Target,SpFirst);
1986       Data->FirstExtensionValue(Abs(Lin->Point(1).Parameter()-Target));
1987     }
1988     if (intf && !unseulsuffitdeb) intf = (Gd1 && Gd2)//;
1989       || backwContinueFailed; // eap
1990     else if (intf && unseulsuffitdeb && (intf<5)) {
1991       intf = (Gd1 || Gd2);
1992       // On controle qu'il n'y pas de nouvelle face.
1993       if (intf && 
1994           ((!debcas1 && debarc1) || (!debcas2 && debarc2)) ) intf = 0;  
1995     }
1996     else if (intf < 5) intf = 0;
1997   }
1998
1999   if(Forward && intl){
2000     Gf1 = fincas1/* && !finobst1*/; // skv(occ67)
2001     Gf2 = fincas2/* && !finobst2*/; // skv(occ67)
2002     if ((finarc1 ^finarc2) && !unseulsuffitfin && (Last!=SpLast)) {
2003       // Cas de cheminement incomplet, cela finit surement mal : 
2004       // on tronque le resultat au lieu de sortie.
2005       Standard_Real sortie;
2006       Standard_Integer ind;
2007       if (finarc1)  sortie = Data->VertexLastOnS1().Parameter();
2008       else  sortie = Data->VertexLastOnS2().Parameter();
2009       if (Last - sortie > tolesp) {
2010         ind = SearchIndex(sortie, Lin);
2011         if (Lin->Point(ind).Parameter() == sortie) ind++;
2012         if (ind<= Nbpnt) {
2013           Lin->Remove(ind, Nbpnt);
2014           UpdateLine(Lin, Standard_False);
2015         }
2016         Nbpnt = Lin->NbPoints();
2017         Last = Lin->Point(Nbpnt).Parameter();
2018       }
2019     }
2020     else if ((intl>=5) && !finarc1 && !finarc2 && (Last!=SpLast) ) {
2021       // Idem dans le cas ou toute la "Lin" constitue un prolongement
2022       Standard_Real sortie = (First+2*Last)/3;
2023       Standard_Integer ind;
2024       if (Last - sortie > tolesp) {
2025         ind = SearchIndex(sortie, Lin);
2026         if (Lin->Point(ind).Parameter() == sortie) ind++;
2027         if (ind < 3) ind = 3;
2028         if (ind <= Nbpnt) {
2029           Lin->Remove(ind, Nbpnt);
2030           UpdateLine(Lin, Standard_False);
2031         }
2032         Nbpnt = Lin->NbPoints();
2033         Last = Lin->Point(Nbpnt).Parameter();
2034       }
2035     }
2036     if(Gf1 && Gf2) {
2037       Target = Max((Lin->Point(Nbpnt).Parameter() + Rab),Last);
2038       Target = Min(Target,SpLast);
2039       Data->LastExtensionValue(Abs(Target-Lin->Point(Nbpnt).Parameter()));
2040     }    
2041
2042     if (intl && !unseulsuffitfin) intl = (Gf1 && Gf2)//;
2043       || forwContinueFailed;  // eap
2044     else if (intl && unseulsuffitfin && (intl<5)) {
2045       intl = (Gf1 || Gf2);// On controle qu'il n'y pas de nouvelle face.
2046       if (intl && 
2047           ((!fincas1 && finarc1) || (!fincas2 && finarc2)) ) intl = 0;  
2048     }
2049     else if (intl <5) intl = 0;
2050   }
2051   return Standard_True;
2052 }
2053
2054 //=======================================================================
2055 //function : SimulData
2056 //purpose  : 
2057 //=======================================================================
2058
2059 Standard_Boolean ChFi3d_Builder::SimulData
2060 (Handle(ChFiDS_SurfData)& /*Data*/,
2061  const Handle(ChFiDS_HElSpine)& HGuide,
2062  Handle(BRepBlend_Line)& Lin,
2063  const Handle(Adaptor3d_HSurface)& S1,
2064  const Handle(Adaptor3d_TopolTool)& I1,
2065  const Handle(Adaptor3d_HSurface)& S2,
2066  const Handle(Adaptor3d_TopolTool)& I2,
2067  Blend_Function& Func,
2068  Blend_FuncInv& FInv,
2069  const Standard_Real PFirst,
2070  const Standard_Real MaxStep,
2071  const Standard_Real Fleche,
2072  const Standard_Real tolguide,
2073  Standard_Real& First,
2074  Standard_Real& Last,
2075  const Standard_Boolean Inside,
2076  const Standard_Boolean Appro,
2077  const Standard_Boolean Forward,
2078  const math_Vector& Soldep,
2079  const Standard_Integer NbSecMin,
2080  const Standard_Boolean RecOnS1,
2081  const Standard_Boolean RecOnS2)
2082 {
2083   BRepBlend_Walking TheWalk(S1,S2,I1,I2);
2084   TheWalk.Check2d(Standard_False);
2085   
2086   Standard_Real MS = MaxStep;
2087   Standard_Real TolGuide=tolguide, TolEsp = tolesp;
2088   Standard_Integer Nbpnt;
2089   Standard_Real SpFirst = HGuide->FirstParameter();
2090   Standard_Real SpLast =  HGuide->LastParameter();
2091   Standard_Boolean reverse = (!Forward || Inside);
2092   Standard_Real Target;
2093   if(reverse){
2094     Target = SpFirst;
2095   }
2096   else{
2097     Target = SpLast;
2098   }
2099
2100   Standard_Real Targetsov = Target;
2101 #ifndef DEB
2102   Standard_Real u1sov = 0., u2sov = 0.; 
2103 #else
2104   Standard_Real u1sov, u2sov; 
2105 #endif
2106   // on recadre la solution de depart a la demande.
2107   math_Vector ParSol(1,4);
2108   Standard_Real NewFirst = PFirst;
2109   if(RecOnS1 || RecOnS2){
2110     if(!TheWalk.PerformFirstSection(Func,FInv,PFirst,Target,Soldep,
2111                                     tolesp,TolGuide,RecOnS1,RecOnS2,
2112                                     NewFirst,ParSol)){
2113 #ifdef DEB
2114       cout<<"ChFi3d_Builder::SimulData : echec calcul first section"<<endl;
2115 #endif
2116       return Standard_False;
2117     }
2118   }
2119   else {
2120     ParSol = Soldep;
2121   }
2122   Standard_Integer again = 0;
2123   while(again < 3){
2124     // Lorsque le point de depart est interne, on chemine 
2125     // d abord a gauche afin de determiner le Last pour les
2126     // periodiques.
2127     if(!again && (MS < 5*TolGuide)) MS = 5*TolGuide;
2128     else  {
2129       if (5*TolGuide > MS) TolGuide = MS/5;
2130       if (5*TolEsp > MS) TolEsp = MS/5;
2131     }
2132       
2133     TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
2134                     ParSol,TolEsp,Fleche,Appro);
2135     
2136     if (!TheWalk.IsDone()) {
2137 #ifdef DEB
2138       cout << "Cheminement non fait" << endl;
2139 #endif
2140       return Standard_False;
2141     }
2142     Lin = TheWalk.Line();
2143     if(reverse){
2144       if(HGuide->IsPeriodic()) {
2145         SpFirst = Lin->Point(1).Parameter();
2146         SpLast  = SpFirst + HGuide->Period();
2147         HGuide->ChangeCurve().FirstParameter(SpFirst);
2148         HGuide->ChangeCurve().LastParameter (SpLast );
2149       }
2150       Standard_Boolean complmnt = Standard_True;
2151       if (Inside)  complmnt = TheWalk.Complete(Func,FInv,SpLast);
2152       if(!complmnt){
2153 #ifdef DEB
2154         cout << "Complement non fait" << endl;
2155 #endif
2156         return Standard_False;
2157       }
2158     }
2159     Nbpnt = Lin->NbPoints();
2160     Standard_Real factor =  1./(NbSecMin + 1);
2161     if (Nbpnt == 0){
2162 #ifdef DEB
2163       cout <<"0 point de cheminement on sort."<<endl;
2164 #endif
2165       return Standard_False;
2166     }
2167     else if (Nbpnt == 1 && again == 0)  {
2168       again++;
2169 #ifdef DEB
2170       cout <<"1 seul point de cheminement on essaye MS/100."<<endl;
2171 #endif
2172       MS *= 0.01; Target = Targetsov;
2173       u1sov = u2sov = Lin->Point(1).Parameter();
2174     }
2175     else if (Nbpnt< NbSecMin && again == 0)  {
2176       again++;
2177 #ifdef DEB
2178       cout <<"Nombre de points insuffisant on reduit le pas"<<endl;
2179 #endif
2180       Standard_Real u1 = u1sov = Lin->Point(1).Parameter();
2181       Standard_Real u2 = u2sov = Lin->Point(Nbpnt).Parameter();
2182       MS = (u2-u1)*factor;
2183       Target = Targetsov;
2184     }
2185     else if (Nbpnt < NbSecMin && again == 1)  {
2186       Standard_Real u1 = Lin->Point(1).Parameter();
2187       Standard_Real u2 = Lin->Point(Nbpnt).Parameter();
2188       if(Abs(u1-u1sov)>=TolGuide || Abs(u2-u2sov)>=TolGuide){
2189         again++;
2190 #ifdef DEB
2191         cout <<"Nombre de points encore insuffisant on reduit le pas"<<endl;
2192 #endif
2193         MS /= 100;
2194         Target = Targetsov;
2195       }
2196       else{
2197 #ifdef DEB
2198         cout <<"Nombre de points toujours insuffisant on sort"<<endl;
2199 #endif
2200         return Standard_False;
2201       }
2202     }
2203     else if(Nbpnt < NbSecMin){
2204 #ifdef DEB
2205       cout <<"Nombre de points toujours insuffisant on sort"<<endl;
2206 #endif
2207       return Standard_False;
2208     }
2209     else {
2210       again = 3;
2211     }
2212   }
2213 #ifdef DRAW
2214   if(ChFi3d_GettraceDRAWWALK()) drawline(Lin,Standard_False);
2215 #endif  
2216   First = Lin->Point(1).Parameter();
2217   Last  = Lin->Point(Nbpnt).Parameter();
2218   return Standard_True;
2219 }
2220