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