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