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