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