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