0022922: Clean up warnings on uninitialized / unused variables
[occt.git] / src / IntWalk / IntWalk_PWalking_1.gxx
1 //-----------------------------
2 //--  IntWalk_PWalking_1.gxx
3 //-- 
4
5 #include <Precision.hxx>
6 #include <math_FunctionSetRoot.hxx>
7
8 //#define KELARG 20.0
9
10 //==================================================================================
11 // function : IntWalk_PWalking::IntWalk_PWalking
12 // purpose  :
13 // estimation des max pas : Pour eviter des changenets 
14 // trop brusques lors des changements d isos 
15 //==================================================================================
16 void ComputePasInit(Standard_Real *pasuv,
17                     Standard_Real Um1,Standard_Real UM1,
18                     Standard_Real Vm1,Standard_Real VM1,
19                     Standard_Real Um2,Standard_Real UM2,
20                     Standard_Real Vm2,Standard_Real VM2,
21                     Standard_Real _Um1,Standard_Real _UM1,
22                     Standard_Real _Vm1,Standard_Real _VM1,
23                     Standard_Real _Um2,Standard_Real _UM2,
24                     Standard_Real _Vm2,Standard_Real _VM2,
25                     const ThePSurface& ,
26                     const ThePSurface& ,
27                     const Standard_Real Increment) 
28
29   Standard_Real du1=Abs(UM1-Um1);
30   Standard_Real dv1=Abs(VM1-Vm1);
31   Standard_Real du2=Abs(UM2-Um2);
32   Standard_Real dv2=Abs(VM2-Vm2);
33  
34   Standard_Real _du1=Abs(_UM1-_Um1);
35   Standard_Real _dv1=Abs(_VM1-_Vm1);
36   Standard_Real _du2=Abs(_UM2-_Um2);
37   Standard_Real _dv2=Abs(_VM2-_Vm2);
38  
39   //-- On limite la reduction de l estimation de la boite uv a 0.01 la boite naturelle
40   //--  du1 : Sur boite des Inter
41   //-- _du1 : Sur espace parametrique
42   if(_du1<1e50 && du1<0.01*_du1) du1=0.01*_du1;
43   if(_dv1<1e50 && dv1<0.01*_dv1) dv1=0.01*_dv1;
44   if(_du2<1e50 && du2<0.01*_du2) du2=0.01*_du2;
45   if(_dv2<1e50 && dv2<0.01*_dv2) dv2=0.01*_dv2;
46   
47   pasuv[0]=Increment*du1;
48   pasuv[1]=Increment*dv1;
49   pasuv[2]=Increment*du2;
50   pasuv[3]=Increment*dv2;
51 }
52 //==================================================================================
53 // function : IntWalk_PWalking::IntWalk_PWalking
54 // purpose  : 
55 //==================================================================================
56 IntWalk_PWalking::IntWalk_PWalking(const ThePSurface& Caro1,
57                                    const ThePSurface& Caro2,
58                                    const Standard_Real TolTangency,
59                                    const Standard_Real Epsilon,
60                                    const Standard_Real Deflection,
61                                    const Standard_Real Increment ) 
62      :
63        
64        done(Standard_True),
65        close(Standard_False),
66        fleche(Deflection),
67        tolconf(Epsilon),
68        sensCheminement(1),
69        myIntersectionOn2S(Caro1,Caro2,TolTangency)
70 {
71   Standard_Real KELARG=20.;
72   //
73   pasMax=Increment*0.2; //-- le 25 juin 99 suite a des pbs de precision 
74   Um1 = ThePSurfaceTool::FirstUParameter(Caro1);
75   Vm1 = ThePSurfaceTool::FirstVParameter(Caro1);
76   UM1 = ThePSurfaceTool::LastUParameter(Caro1);
77   VM1 = ThePSurfaceTool::LastVParameter(Caro1);
78
79   Um2 = ThePSurfaceTool::FirstUParameter(Caro2);
80   Vm2 = ThePSurfaceTool::FirstVParameter(Caro2);
81   UM2 = ThePSurfaceTool::LastUParameter(Caro2);
82   VM2 = ThePSurfaceTool::LastVParameter(Caro2);
83
84   ResoU1 = ThePSurfaceTool::UResolution(Caro1,Precision::Confusion());
85   ResoV1 = ThePSurfaceTool::VResolution(Caro1,Precision::Confusion());
86
87   ResoU2 = ThePSurfaceTool::UResolution(Caro2,Precision::Confusion());
88   ResoV2 = ThePSurfaceTool::VResolution(Caro2,Precision::Confusion());
89
90   Standard_Real NEWRESO;
91   Standard_Real MAXVAL;
92   Standard_Real MAXVAL2;
93   //
94   MAXVAL  = Abs(Um1);  MAXVAL2 = Abs(UM1);
95   if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
96   NEWRESO = ResoU1 * MAXVAL ;
97   if(NEWRESO > ResoU1 &&NEWRESO<10) {    ResoU1 = NEWRESO;  }
98
99
100   MAXVAL  = Abs(Um2);   MAXVAL2 = Abs(UM2);
101   if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
102   NEWRESO = ResoU2 * MAXVAL ;
103   if(NEWRESO > ResoU2 && NEWRESO<10) {     ResoU2 = NEWRESO;  }
104
105
106   MAXVAL  = Abs(Vm1);  MAXVAL2 = Abs(VM1);
107   if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
108   NEWRESO = ResoV1 * MAXVAL ;
109   if(NEWRESO > ResoV1 && NEWRESO<10) {     ResoV1 = NEWRESO;  }
110
111
112   MAXVAL  = Abs(Vm2);  MAXVAL2 = Abs(VM2);
113   if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
114   NEWRESO = ResoV2 * MAXVAL ;
115   if(NEWRESO > ResoV2 && NEWRESO<10) {     ResoV2 = NEWRESO;  }
116
117   pasuv[0]=pasMax*Abs(UM1-Um1);
118   pasuv[1]=pasMax*Abs(VM1-Vm1);
119   pasuv[2]=pasMax*Abs(UM2-Um2);
120   pasuv[3]=pasMax*Abs(VM2-Vm2);
121
122   if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
123   if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
124   if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
125   if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
126
127
128   if(ThePSurfaceTool::IsUPeriodic(Caro1)==Standard_False) { 
129     UM1+=KELARG*pasuv[0];  Um1-=KELARG*pasuv[0];
130   }
131   else { 
132     Standard_Real t = UM1-Um1; 
133     if(t<ThePSurfaceTool::UPeriod(Caro1)) { 
134       t=0.5*(ThePSurfaceTool::UPeriod(Caro1)-t);
135       t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
136       UM1+=t;  Um1-=t;
137     }
138   }
139       
140   if(ThePSurfaceTool::IsVPeriodic(Caro1)==Standard_False) { 
141     VM1+=KELARG*pasuv[1];  Vm1-=KELARG*pasuv[1];
142   }
143   else { 
144     Standard_Real t = VM1-Vm1; 
145     if(t<ThePSurfaceTool::VPeriod(Caro1)) { 
146       t=0.5*(ThePSurfaceTool::VPeriod(Caro1)-t);
147       t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
148       VM1+=t;  Vm1-=t;
149     }
150   }
151    
152   if(ThePSurfaceTool::IsUPeriodic(Caro2)==Standard_False) { 
153     UM2+=KELARG*pasuv[2];  Um2-=KELARG*pasuv[2];
154   }
155   else { 
156     Standard_Real t = UM2-Um2; 
157     if(t<ThePSurfaceTool::UPeriod(Caro2)) { 
158       t=0.5*(ThePSurfaceTool::UPeriod(Caro2)-t);
159       t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
160       UM2+=t;  Um2-=t;
161     }
162   }
163    
164   if(ThePSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {   
165     VM2+=KELARG*pasuv[3];  Vm2-=KELARG*pasuv[3];
166   }
167   else { 
168     Standard_Real t = VM2-Vm2; 
169     if(t<ThePSurfaceTool::VPeriod(Caro2)) { 
170       t=0.5*(ThePSurfaceTool::VPeriod(Caro2)-t);
171       t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
172       VM2+=t;  Vm2-=t;
173     }
174   }
175
176   //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
177
178   for (Standard_Integer i = 0; i<=3;i++) {
179     if(pasuv[i]>10) 
180       pasuv[i] = 10; 
181     pasInit[i] = pasSav[i] = pasuv[i]; 
182   }
183
184
185 }
186 //==================================================================================
187 // function : IntWalk_PWalking
188 // purpose  : 
189 //==================================================================================
190 IntWalk_PWalking::IntWalk_PWalking(const ThePSurface& Caro1,
191                                    const ThePSurface& Caro2,
192                                    const Standard_Real TolTangency,
193                                    const Standard_Real Epsilon,
194                                    const Standard_Real Deflection,
195                                    const Standard_Real Increment, 
196                                    const Standard_Real U1,
197                                    const Standard_Real V1,
198                                    const Standard_Real U2, 
199                                    const Standard_Real V2)
200      :
201        
202        done(Standard_True),
203        close(Standard_False),
204        fleche(Deflection),
205        tolconf(Epsilon),
206        sensCheminement(1),       
207        myIntersectionOn2S(Caro1,Caro2,TolTangency)
208 {
209   Standard_Real KELARG=20.;
210   //
211   pasMax=Increment*0.2; //-- le 25 juin 99 suite a des pbs de precision 
212   //
213   Um1 = ThePSurfaceTool::FirstUParameter(Caro1);
214   Vm1 = ThePSurfaceTool::FirstVParameter(Caro1);
215   UM1 = ThePSurfaceTool::LastUParameter(Caro1);
216   VM1 = ThePSurfaceTool::LastVParameter(Caro1);
217
218   Um2 = ThePSurfaceTool::FirstUParameter(Caro2);
219   Vm2 = ThePSurfaceTool::FirstVParameter(Caro2);
220   UM2 = ThePSurfaceTool::LastUParameter(Caro2);
221   VM2 = ThePSurfaceTool::LastVParameter(Caro2);
222
223   ResoU1 = ThePSurfaceTool::UResolution(Caro1,Precision::Confusion());
224   ResoV1 = ThePSurfaceTool::VResolution(Caro1,Precision::Confusion());
225
226   ResoU2 = ThePSurfaceTool::UResolution(Caro2,Precision::Confusion());
227   ResoV2 = ThePSurfaceTool::VResolution(Caro2,Precision::Confusion());
228   //
229   Standard_Real NEWRESO, MAXVAL, MAXVAL2;
230   //
231   MAXVAL  = Abs(Um1);  
232   MAXVAL2 = Abs(UM1);
233   if(MAXVAL2 > MAXVAL) {
234     MAXVAL = MAXVAL2;
235   }
236   NEWRESO = ResoU1 * MAXVAL ;
237   if(NEWRESO > ResoU1) {
238     ResoU1 = NEWRESO;  
239   }
240   //
241   MAXVAL  = Abs(Um2);   
242   MAXVAL2 = Abs(UM2);
243   if(MAXVAL2 > MAXVAL){
244     MAXVAL = MAXVAL2;
245   }  
246   NEWRESO = ResoU2 * MAXVAL ;
247   if(NEWRESO > ResoU2) {
248     ResoU2 = NEWRESO;  
249   }
250   //
251   MAXVAL  = Abs(Vm1);  
252   MAXVAL2 = Abs(VM1);
253   if(MAXVAL2 > MAXVAL) {
254     MAXVAL = MAXVAL2;
255   }
256   NEWRESO = ResoV1 * MAXVAL ;
257   if(NEWRESO > ResoV1) {    
258     ResoV1 = NEWRESO; 
259   }
260   //
261   MAXVAL  = Abs(Vm2);  
262   MAXVAL2 = Abs(VM2);
263   if(MAXVAL2 > MAXVAL){
264     MAXVAL = MAXVAL2;
265   }  
266   NEWRESO = ResoV2 * MAXVAL ;
267   if(NEWRESO > ResoV2) {  
268     ResoV2 = NEWRESO;
269   }
270   //
271   pasuv[0]=pasMax*Abs(UM1-Um1);
272   pasuv[1]=pasMax*Abs(VM1-Vm1);
273   pasuv[2]=pasMax*Abs(UM2-Um2);
274   pasuv[3]=pasMax*Abs(VM2-Vm2);
275   //
276   if(ThePSurfaceTool::IsUPeriodic(Caro1)==Standard_False) { 
277     UM1+=KELARG*pasuv[0];  
278     Um1-=KELARG*pasuv[0];
279   }
280   else { 
281     Standard_Real t = UM1-Um1; 
282     if(t<ThePSurfaceTool::UPeriod(Caro1)) { 
283       t=0.5*(ThePSurfaceTool::UPeriod(Caro1)-t);
284       t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
285       UM1+=t;  
286       Um1-=t;
287     }
288   }
289   //
290   if(ThePSurfaceTool::IsVPeriodic(Caro1)==Standard_False) { 
291     VM1+=KELARG*pasuv[1];
292     Vm1-=KELARG*pasuv[1];
293   }
294   else { 
295     Standard_Real t = VM1-Vm1; 
296     if(t<ThePSurfaceTool::VPeriod(Caro1)) { 
297       t=0.5*(ThePSurfaceTool::VPeriod(Caro1)-t);
298       t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
299       VM1+=t;  Vm1-=t;
300     }
301   }
302   //
303   if(ThePSurfaceTool::IsUPeriodic(Caro2)==Standard_False) { 
304     UM2+=KELARG*pasuv[2];  
305     Um2-=KELARG*pasuv[2];
306   }
307   else { 
308     Standard_Real t = UM2-Um2; 
309     if(t<ThePSurfaceTool::UPeriod(Caro2)) { 
310       t=0.5*(ThePSurfaceTool::UPeriod(Caro2)-t);
311       t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
312       UM2+=t;  
313       Um2-=t;
314     }
315   }
316    
317   if(ThePSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {   
318     VM2+=KELARG*pasuv[3];  
319     Vm2-=KELARG*pasuv[3];
320   }
321   else { 
322     Standard_Real t = VM2-Vm2; 
323     if(t<ThePSurfaceTool::UPeriod(Caro2)) { 
324       t=0.5*(ThePSurfaceTool::VPeriod(Caro2)-t);
325       t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
326       VM2+=t;  
327       Vm2-=t;
328     }
329   }
330   //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
331
332   for (Standard_Integer i = 0; i<=3;i++) {
333     pasInit[i] = pasSav[i] = pasuv[i]; 
334   }  
335
336   if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
337   if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
338   if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
339   if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
340   //
341   TColStd_Array1OfReal Par(1,4);
342   Par(1) = U1;
343   Par(2) = V1;
344   Par(3) = U2;
345   Par(4) = V2;
346   Perform(Par);
347 }
348
349 //==================================================================================
350 // function : PerformFirstPoint
351 // purpose  : 
352 //==================================================================================
353 Standard_Boolean IntWalk_PWalking::PerformFirstPoint  (const TColStd_Array1OfReal& ParDep,
354                                                        IntSurf_PntOn2S& FirstPoint)   
355 {
356   sensCheminement = 1;
357   close = Standard_False;
358   //
359   Standard_Integer i;
360   Standard_Real aTmp;
361   TColStd_Array1OfReal Param(1,4);
362   //
363   for (i=1; i<=4; ++i) {
364     aTmp = ParDep(i);
365     Param(i) = ParDep(i);
366   }
367   //-- calcul du premier point solution
368   math_FunctionSetRoot  Rsnld(myIntersectionOn2S.Function());
369   //
370   myIntersectionOn2S.Perform(Param,Rsnld);
371   if (!myIntersectionOn2S.IsDone())  { 
372     return Standard_False;
373   }
374   if (myIntersectionOn2S.IsEmpty()) {
375     return Standard_False;
376   }
377   FirstPoint = myIntersectionOn2S.Point();
378   return Standard_True;
379 }
380 //==================================================================================
381 // function : Perform
382 // purpose  : 
383 //==================================================================================
384 void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep)    
385 {
386   Perform(ParDep,Um1,Vm1,Um2,Vm2,UM1,VM1,UM2,VM2);
387 }
388 //==================================================================================
389 // function : Perform
390 // purpose  : 
391 //==================================================================================
392 void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
393                                const Standard_Real u1min,
394                                const Standard_Real v1min,
395                                const Standard_Real u2min,
396                                const Standard_Real v2min,
397                                const Standard_Real u1max,
398                                const Standard_Real v1max,
399                                const Standard_Real u2max,
400                                const Standard_Real v2max)
401 {
402   //xf
403   Standard_Integer i, NbPasOKConseq;
404   Standard_Real UFirst1, VFirst1, ULast1, VLast1, UFirst2, VFirst2, ULast2, VLast2;
405   Standard_Real pasMaxSV[4], aTmp;
406   TColStd_Array1OfReal Param(1,4);
407   IntImp_ConstIsoparametric ChoixIso;
408   //xt
409   //
410   done = Standard_False;
411   NbPasOKConseq=0;
412   //
413   // Caro1 and Caro2
414   const ThePSurface& Caro1 =myIntersectionOn2S.Function().AuxillarSurface1();
415   const ThePSurface& Caro2 =myIntersectionOn2S.Function().AuxillarSurface2();
416   //
417   UFirst1 = ThePSurfaceTool::FirstUParameter(Caro1);
418   VFirst1 = ThePSurfaceTool::FirstVParameter(Caro1);
419   ULast1  = ThePSurfaceTool::LastUParameter (Caro1);
420   VLast1  = ThePSurfaceTool::LastVParameter (Caro1);
421   //
422   UFirst2 = ThePSurfaceTool::FirstUParameter(Caro2);
423   VFirst2 = ThePSurfaceTool::FirstVParameter(Caro2);
424   ULast2  = ThePSurfaceTool::LastUParameter (Caro2);
425   VLast2  = ThePSurfaceTool::LastVParameter (Caro2);
426   //
427   ComputePasInit(pasuv,u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max,
428                  Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2,pasMax+pasMax);
429   //
430   if(pasuv[0]<100*ResoU1) {
431     pasuv[0]=100*ResoU1; 
432   }
433   if(pasuv[1]<100*ResoV1) {
434     pasuv[1]=100*ResoV1; 
435   }
436   if(pasuv[2]<100*ResoU2) {
437     pasuv[2]=100*ResoU2;
438   }
439   if(pasuv[3]<100*ResoV2) {
440     pasuv[3]=100*ResoV2;
441   }
442   //
443   for (i=0; i<4; ++i) {
444     if(pasuv[i]>10) {
445       pasuv[i] = 10;
446     }
447     pasInit[i] = pasSav[i] = pasuv[i]; 
448   }
449   //
450   line = new IntSurf_LineOn2S ();
451   //
452   for (i=1; i<=4; ++i) {
453     aTmp=ParDep(i);
454     Param(i)=ParDep(i);
455   }
456   //-- reprise des pas uv lies aux surfaces Caro1 et Caro2
457   //-- pasuv[] et pasSav[] sont modifies lors du cheminement
458   for(i = 0; i < 4; ++i) { 
459     pasMaxSV[i] = pasSav[i] = pasuv[i] = pasInit[i]; 
460   }
461
462   //-- calcul du premier point solution
463   math_FunctionSetRoot  Rsnld(myIntersectionOn2S.Function());
464   //
465   ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld);
466   if (!myIntersectionOn2S.IsDone())   {
467     return;
468   }
469   //
470   if (myIntersectionOn2S.IsEmpty()) {
471     return;
472   }
473   //
474   if(myIntersectionOn2S.IsTangent()) {
475     return;
476   }
477   //
478   Standard_Boolean Arrive, DejaReparti;
479   Standard_Integer IncKey, RejectIndex;
480   gp_Pnt pf,pl;
481   //
482   DejaReparti = Standard_False;
483   IncKey = 0;
484   RejectIndex = 0;
485   //
486   previousPoint = myIntersectionOn2S.Point();
487   previoustg = Standard_False;
488   previousd  = myIntersectionOn2S.Direction();
489   previousd1 = myIntersectionOn2S.DirectionOnS1();
490   previousd2 = myIntersectionOn2S.DirectionOnS2();
491   indextg = 1;
492   tgdir   = previousd;
493   firstd1 = previousd1;
494   firstd2 = previousd2;
495   tgfirst = tglast = Standard_False;
496   choixIsoSav  =  ChoixIso;
497   //------------------------------------------------------------
498   //-- On Teste si le premier point de cheminement correspond 
499   //-- a un point sur frontiere. 
500   //-- Dans ce cas, DejaReparti est initialise a True
501   //-- 
502   pf = previousPoint.Value();
503   Standard_Boolean bTestFirstPoint = Standard_True;
504   
505   previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));  
506   AddAPoint(line,previousPoint);
507   //
508   IntWalk_StatusDeflection Status = IntWalk_OK;
509   Standard_Boolean NoTestDeflection = Standard_False;
510   Standard_Real SvParam[4], f;
511   Standard_Integer LevelOfEmptyInmyIntersectionOn2S=0;
512   Standard_Integer LevelOfPointConfondu = 0; 
513   Standard_Integer LevelOfIterWithoutAppend = -1;
514   //
515   Arrive = Standard_False;
516   while(!Arrive) {//010
517     LevelOfIterWithoutAppend++;
518     if(LevelOfIterWithoutAppend>20) { 
519       Arrive = Standard_True; 
520       if(DejaReparti) {
521         break;
522       }
523       RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
524       LevelOfIterWithoutAppend = 0;
525     }
526     //
527     // compute f
528     f = 0.;
529     switch (ChoixIso) { 
530       case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
531       case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
532       case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
533       case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
534       default:break;
535     }
536     //
537     if(f<0.1) {
538       f=0.1;
539     }
540     //
541     previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
542     //
543     //--ofv.begin
544     Standard_Real aIncKey, aEps, dP1, dP2, dP3, dP4;
545     //
546     dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
547     dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
548     dP3 = sensCheminement * pasuv[2] * previousd2.X() /f; 
549     dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
550     //
551     aIncKey=5.*(Standard_Real)IncKey;
552     aEps=1.e-7;
553     if(ChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < aEps) {
554       dP1 *= aIncKey;
555     }
556     if(ChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < aEps) {
557       dP2 *= aIncKey;
558     }
559     if(ChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < aEps) {
560       dP3 *= aIncKey;
561     }
562     if(ChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < aEps) {
563       dP4 *= aIncKey;
564     }
565     //--ofv.end
566     //
567     Param(1) += dP1;
568     Param(2) += dP2;
569     Param(3) += dP3; 
570     Param(4) += dP4;
571     //==========================
572     SvParam[0]=Param(1); 
573     SvParam[1]=Param(2);
574     SvParam[2]=Param(3);
575     SvParam[3]=Param(4);
576     //
577     ChoixIso= myIntersectionOn2S.Perform(Param, Rsnld, ChoixIso);                  
578     //
579     if (!myIntersectionOn2S.IsDone())   {
580       //arret de la ligne,division
581       Arrive = Standard_False;
582       Param(1)=SvParam[0]; 
583       Param(2)=SvParam[1]; 
584       Param(3)=SvParam[2];
585       Param(4)=SvParam[3];
586       RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
587     }
588     else  {//009 
589       //== Le calcul du point exact a partir de Param(.) est possible
590       if (myIntersectionOn2S.IsEmpty()) {
591         Standard_Real u1,v1,u2,v2;
592         previousPoint.Parameters(u1,v1,u2,v2);
593         //
594         Arrive = Standard_False;
595         if(u1<UFirst1 || u1>ULast1) {
596           Arrive=Standard_True;
597         }       
598         if(u2<UFirst2 || u2>ULast2) {
599           Arrive=Standard_True;
600         }
601         if(v1<VFirst1 || v1>VLast1) {
602           Arrive=Standard_True;
603         }
604         if(v2<VFirst2 || v2>VLast2) {
605           Arrive=Standard_True;
606         }       
607         RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
608         LevelOfEmptyInmyIntersectionOn2S++;
609         //
610         if(LevelOfEmptyInmyIntersectionOn2S>10)    {
611           pasuv[0]=pasSav[0]; 
612           pasuv[1]=pasSav[1]; 
613           pasuv[2]=pasSav[2]; 
614           pasuv[3]=pasSav[3];
615         }           
616       }
617       else {//008
618         //============================================================
619         //== Un point a ete trouve :  T E S T   D E F L E C T I O N 
620         //============================================================
621         if(NoTestDeflection) {
622           NoTestDeflection = Standard_False;
623         }                 
624         else { 
625           if(--LevelOfEmptyInmyIntersectionOn2S<=0)     { 
626             LevelOfEmptyInmyIntersectionOn2S=0;
627             if(LevelOfIterWithoutAppend < 10) {
628               Status = TestDeflection();
629             }                   
630             else   { 
631               pasuv[0]*=0.5; 
632               pasuv[1]*=0.5; 
633               pasuv[2]*=0.5; 
634               pasuv[3]*=0.5;
635             }
636           }
637         }
638         //============================================================
639         //==       T r a i t e m e n t   s u r   S t a t u s        ==
640         //============================================================
641         if(LevelOfPointConfondu > 5) { 
642           Status = IntWalk_ArretSurPoint; 
643           LevelOfPointConfondu = 0;  
644         }
645         //
646         if(Status==IntWalk_OK) { 
647           NbPasOKConseq++;
648           if(NbPasOKConseq >= 5) { 
649             NbPasOKConseq=0;
650             Standard_Boolean pastroppetit;
651             Standard_Real t;
652             //
653             do { 
654               pastroppetit=Standard_True;
655               //
656               if(pasuv[0]<pasInit[0])     { 
657                 t = (pasInit[0]-pasuv[0])*0.25;
658                 if(t>0.1*pasInit[0]) {
659                   t=0.1*pasuv[0];
660                 }
661                 pasuv[0]+=t; 
662                 pastroppetit=Standard_False;
663               } 
664               if(pasuv[1]<pasInit[1])   { 
665                 t = (pasInit[1]-pasuv[1])*0.25;
666                 if(t>0.1*pasInit[1]) {
667                   t=0.1*pasuv[1];
668                 }               
669                 pasuv[1]+=t; 
670                 pastroppetit=Standard_False;
671               } 
672               if(pasuv[2]<pasInit[2]){
673                 t = (pasInit[2]-pasuv[2])*0.25;
674                 if(t>0.1*pasInit[2]) {
675                   t=0.1*pasuv[2];
676                 }
677                 pasuv[2]+=t; 
678                 pastroppetit=Standard_False;
679               } 
680               if(pasuv[3]<pasInit[3])   { 
681                 t = (pasInit[3]-pasuv[3])*0.25;
682                 if(t>0.1*pasInit[3]) {
683                   t=0.1*pasuv[3];
684                 }
685                 pasuv[3]+=t; 
686                 pastroppetit=Standard_False;
687               }
688               if(pastroppetit) { 
689                 if(pasMax<0.1){ 
690                   pasMax*=1.1; 
691                   pasInit[0]*=1.1; 
692                   pasInit[1]*=1.1; 
693                   pasInit[2]*=1.1; 
694                   pasInit[3]*=1.1; 
695                 }
696                 else {
697                   pastroppetit=Standard_False;
698                 }
699               }
700             } while(pastroppetit);
701           }
702         }//Status==IntWalk_OK
703         else NbPasOKConseq=0;
704         //
705         switch(Status) {//007 
706           case IntWalk_ArretSurPointPrecedent:  {                     
707             Arrive = Standard_False;                        
708             RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
709             break;
710           }
711           case IntWalk_PasTropGrand:  {
712             Param(1)=SvParam[0]; 
713             Param(2)=SvParam[1]; 
714             Param(3)=SvParam[2]; 
715             Param(4)=SvParam[3];
716             if(LevelOfIterWithoutAppend > 5) { 
717               if(pasSav[0]<pasInit[0]) { 
718                 pasInit[0]-=(pasInit[0]-pasSav[0])*0.25; 
719                 LevelOfIterWithoutAppend=0;
720               }
721               if(pasSav[1]<pasInit[1]) { 
722                 pasInit[1]-=(pasInit[1]-pasSav[1])*0.25;  
723                 LevelOfIterWithoutAppend=0; 
724               }
725               if(pasSav[2]<pasInit[2]) { 
726                 pasInit[2]-=(pasInit[2]-pasSav[2])*0.25;  
727                 LevelOfIterWithoutAppend=0; 
728               }
729               if(pasSav[3]<pasInit[3]) {
730                 pasInit[3]-=(pasInit[3]-pasSav[3])*0.25; 
731                 LevelOfIterWithoutAppend=0; 
732               }
733             }
734             break;
735           }
736           case IntWalk_PointConfondu:   {
737             LevelOfPointConfondu++;
738             if(LevelOfPointConfondu>5)   { 
739               Standard_Boolean pastroppetit;
740               //
741               do { 
742                 pastroppetit=Standard_True;
743                 if(pasuv[0]<pasInit[0]) { 
744                   pasuv[0]+=(pasInit[0]-pasuv[0])*0.25;
745                   pastroppetit=Standard_False; 
746                 } 
747                 if(pasuv[1]<pasInit[1]) { 
748                   pasuv[1]+=(pasInit[1]-pasuv[1])*0.25;
749                   pastroppetit=Standard_False; 
750                 } 
751                 if(pasuv[2]<pasInit[2]) { 
752                   pasuv[2]+=(pasInit[2]-pasuv[2])*0.25;
753                   pastroppetit=Standard_False; 
754                 } 
755                 if(pasuv[3]<pasInit[3]) { 
756                   pasuv[3]+=(pasInit[3]-pasuv[3])*0.25; 
757                   pastroppetit=Standard_False; 
758                 }
759                 if(pastroppetit)  { 
760                   if(pasMax<0.1){ 
761                     pasMax*=1.1; 
762                     pasInit[0]*=1.1; 
763                     pasInit[1]*=1.1; 
764                     pasInit[2]*=1.1; 
765                     pasInit[3]*=1.1; 
766                   }
767                   else{
768                     pastroppetit=Standard_False; 
769                   }             
770                 }
771               } while(pastroppetit);
772             }
773             break;
774           }
775           case IntWalk_OK:
776           case IntWalk_ArretSurPoint:  {//006
777             //=======================================================
778             //== T e s t   A r r e t   :  Cadrage sur Param(.)     ==
779             //=======================================================
780             //xft arrive here
781             Arrive = TestArret(DejaReparti,Param,ChoixIso); 
782             // JMB 30th December 1999. 
783             // Some statement below should not be put in comment because they are useful.
784             // See grid CTO 909 A1 which infinitely loops 
785             if(Arrive==Standard_False && Status==IntWalk_ArretSurPoint) { 
786               Arrive=Standard_True;
787 #ifdef DEB
788               cout << "Compile avec option DEB :Si Pb d intersection : ";
789               cout << "IntWalk_PWalking_1.gxx (lbr le 1erdec98)"<<endl;
790 #endif
791             }
792             if(Arrive) {
793               NbPasOKConseq = -10;
794             }
795             if(!Arrive)  {//005
796               //=====================================================
797               //== Param(.)  est dans les bornes                   ==
798               //==  et ne finit pas une ligne fermee               ==
799               //=====================================================
800               //== Verification sur Le Point Courant de myInters
801               Standard_Boolean pointisvalid = Standard_False;
802               {
803                 Standard_Real u1,v1,u2,v2; 
804                 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2); 
805                 //
806                 if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 && 
807                    v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
808                    v1 >= Vm1  && v2 >= Vm2) {
809                   pointisvalid=Standard_True;
810                 }
811               }
812               //
813               if(pointisvalid) { 
814                 previousPoint = myIntersectionOn2S.Point();
815                 previoustg = myIntersectionOn2S.IsTangent();
816                 if(!previoustg) {
817                   previousd  = myIntersectionOn2S.Direction();
818                   previousd1 = myIntersectionOn2S.DirectionOnS1();
819                   previousd2 = myIntersectionOn2S.DirectionOnS2();
820                 }
821                 //=====================================================
822                 //== Verification sur Previous Point
823                 {
824                   Standard_Real u1,v1,u2,v2; 
825                   previousPoint.Parameters(u1,v1,u2,v2); 
826                   if( u1 <= UM1  && u2 <= UM2 && v1 <= VM1 &&
827                       v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
828                       v1 >= Vm1  && v2 >= Vm2) { 
829                     pl = previousPoint.Value();
830                     if(bTestFirstPoint) {
831                       if(pf.Distance(pl) < 1.e-7){ 
832                         IncKey++; 
833                         if(IncKey == 5000) 
834                           return; 
835                         else 
836                           continue; 
837                       }
838                       else {
839                         bTestFirstPoint = Standard_False;
840                       }
841                     }
842                     //
843                     AddAPoint(line,previousPoint);
844                     RejectIndex++; 
845                     if(RejectIndex >= 250000) {
846                       break; 
847                     };
848                     //
849                     LevelOfIterWithoutAppend = 0;
850                   } 
851                 }
852               }//pointisvalid
853               //====================================================
854               if(Status == IntWalk_ArretSurPoint)  {
855                 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
856               }
857               else{ 
858                 if (line->NbPoints() == 2) {
859                   pasSav[0] = pasuv[0]; 
860                   pasSav[1] = pasuv[1]; 
861                   pasSav[2] = pasuv[2]; 
862                   pasSav[3] = pasuv[3];
863                 }
864               }
865             }//005 if(!Arrive)
866             //
867             else {//004
868               if(close) { 
869                 //================= la ligne est fermee ===============
870                 AddAPoint(line,line->Value(1)); //ligne fermee
871                 LevelOfIterWithoutAppend=0;
872               }
873               else {//$$$
874                 //====================================================
875                 //== Param n etait pas dans les bornes (a ete recadre)
876                 //====================================================
877                 Standard_Boolean bPrevNotTangent = !previoustg || !myIntersectionOn2S.IsTangent();
878                 
879                 IntImp_ConstIsoparametric SauvChoixIso = ChoixIso;
880                 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);    
881                 //
882                 if(!myIntersectionOn2S.IsEmpty()) { //002
883                   // debordement sur le carreau reciproque ou intersection en coin
884                   if(TestArret(Standard_True,Param,ChoixIso))  {
885                     NbPasOKConseq = -10;
886                     ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso); 
887                     if(!myIntersectionOn2S.IsEmpty())     {
888                       previousPoint = myIntersectionOn2S.Point();         
889                       previoustg = myIntersectionOn2S.IsTangent();
890                       if (!previoustg)     {
891                         previousd  = myIntersectionOn2S.Direction();
892                         previousd1 = myIntersectionOn2S.DirectionOnS1();
893                         previousd2 = myIntersectionOn2S.DirectionOnS2();
894                       }
895                       pl = previousPoint.Value();
896                       if(bTestFirstPoint) {
897                         if(pf.Distance(pl) < 1.e-7){ 
898                           IncKey++; 
899                           if(IncKey == 5000) 
900                             return; 
901                           else 
902                             continue; 
903                         }
904                         else {
905                           bTestFirstPoint = Standard_False;
906                         }
907                       }
908                       //
909                       AddAPoint(line,previousPoint);
910                       RejectIndex++;
911                       if(RejectIndex >= 250000) {
912                         break;
913                       };
914                       //
915                       LevelOfIterWithoutAppend=0;
916                       RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
917                     }
918                     else  {
919                       //echec cadrage diviser le pas
920                       Arrive = Standard_False;
921                       RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
922                       NoTestDeflection = Standard_True;
923                       ChoixIso = SauvChoixIso;
924                     }
925                   }//if(TestArret())
926                   else {
927                     // save the last point
928                     // to revert to it if the current point is out of bounds
929                     IntSurf_PntOn2S previousPointSave = previousPoint;
930                     Standard_Boolean previoustgSave   = previoustg;
931                     gp_Dir previousdSave              = previousd;
932                     gp_Dir2d previousd1Save           = previousd1;
933                     gp_Dir2d previousd2Save           = previousd2;
934                     
935                     previousPoint = myIntersectionOn2S.Point();         
936                     previoustg = myIntersectionOn2S.IsTangent();
937                     Arrive = Standard_False; 
938                     if(!previoustg)  {
939                       previousd  = myIntersectionOn2S.Direction();
940                       previousd1 = myIntersectionOn2S.DirectionOnS1();
941                       previousd2 = myIntersectionOn2S.DirectionOnS2();
942                     }
943                     //========================================
944                     //== Verification sur PreviousPoint @@
945                     {
946                       Standard_Real u1,v1,u2,v2; 
947                       previousPoint.Parameters(u1,v1,u2,v2); 
948                       Param(1) = u1; 
949                       Param(2) = v1;    
950                       Param(3) = u2; 
951                       Param(4) = v2;
952                       //
953                       //xf
954                       Standard_Boolean bFlag1, bFlag2;
955                       Standard_Real aTol2D=1.e-11;
956                       //
957                       bFlag1=u1 >= Um1-aTol2D && v1 >= Vm1-aTol2D && u1 <= UM1+aTol2D && v1 <= VM1+aTol2D;
958                       bFlag2=u2 >= Um2-aTol2D && v2 >= Vm2-aTol2D && u2 <= UM2+aTol2D && v2 <= VM2+aTol2D;
959                       if (bFlag1 && bFlag2) {
960                       /*
961                       if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 &&
962                          v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
963                          v1 >= Vm1  && v2 >= Vm2)  {
964                          */                     
965                       //xt
966                         pl = previousPoint.Value();
967                         if(bTestFirstPoint) {
968                           if(pf.Distance(pl) < 1.e-7) {
969                             IncKey++;
970                             if(IncKey == 5000)
971                               return; 
972                             else 
973                               continue;
974                           }
975                           else {
976                             bTestFirstPoint = Standard_False;
977                           }
978                         }
979                         AddAPoint(line,previousPoint);
980                         RejectIndex++;
981                         if(RejectIndex >= 250000) {
982                           break;
983                         }
984                         //
985                         LevelOfIterWithoutAppend=0;
986                         Arrive = Standard_True;
987                       }
988                       else {
989                         // revert to the last correctly calculated point
990                         previousPoint = previousPointSave;
991                         previoustg    = previoustgSave;
992                         previousd     = previousdSave;
993                         previousd1    = previousd1Save;
994                         previousd2    = previousd2Save;
995                       }
996                     }
997                     //
998                     Standard_Boolean wasExtended = Standard_False;
999                     
1000                     if(Arrive && myIntersectionOn2S.IsTangent() && bPrevNotTangent) {
1001                       if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti)) {
1002                         wasExtended = Standard_True;
1003                         Arrive = Standard_False;
1004                         ChoixIso = SauvChoixIso;
1005                       }
1006                     }
1007                     
1008                     RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1009                     if(Arrive && 
1010                        myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() &&
1011                        myIntersectionOn2S.IsTangent() && bPrevNotTangent &&
1012                        !wasExtended) {
1013                       
1014                       if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti)) {
1015                         wasExtended = Standard_True;
1016                         Arrive = Standard_False;
1017                         ChoixIso = SauvChoixIso;
1018                       }
1019                     }
1020                   }//else !TestArret() $
1021                 } //$$ fin succes cadrage sur frontiere (!myIntersectionOn2S.IsEmpty())
1022                 else  {
1023                   //echec cadrage  sur frontiere;division du pas 
1024                   Arrive = Standard_False;
1025                   NoTestDeflection = Standard_True;
1026                   RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1027                 } 
1028               }//$$$ fin cadrage sur frontiere (!close)
1029             } //004 fin TestArret retourne Arrive = True
1030           } // 006case IntWalk_ArretSurPoint:  fin Traitement Status = OK  ou ArretSurPoint 
1031         } //007  switch(Status) 
1032       } //008 fin traitement point en court (TEST DEFLECTION)
1033     } //009 fin traitement ligne (else if myIntersectionOn2S.IsDone())
1034   }  //010 fin si premier point de depart a permis un cheminement while(!Arrive)
1035   done = Standard_True;
1036 }
1037 // ===========================================================================================================
1038 // function: ExtendLineInCommonZone
1039 // purpose:  Extends already computed line inside tangent zone in the direction given by theChoixIso.
1040 //           Returns Standard_True if the line was extended through tangent zone and the last computed point 
1041 //           is outside the tangent zone (but it is not put into the line). Otherwise returns Standard_False.
1042 // ===========================================================================================================
1043 Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso,
1044                                                           const Standard_Boolean          theDirectionFlag) 
1045 {
1046   Standard_Boolean bOutOfTangentZone = Standard_False;
1047   Standard_Boolean bStop = !myIntersectionOn2S.IsTangent();
1048   Standard_Integer dIncKey = 1;
1049   TColStd_Array1OfReal Param(1,4);
1050   IntWalk_StatusDeflection Status = IntWalk_OK;
1051   Standard_Integer nbIterWithoutAppend = 0;
1052   Standard_Integer nbEqualPoints = 0;
1053   Standard_Integer parit = 0;
1054   Standard_Integer uvit = 0;
1055   IntSurf_SequenceOfPntOn2S aSeqOfNewPoint;
1056
1057   while (!bStop) {
1058     nbIterWithoutAppend++;
1059
1060     if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) {
1061 #ifdef DEB
1062       cout<<"Compile with option DEB:";
1063       cout<<"Infinite loop has detected. Stop iterations (IntWalk_PWalking_1.gxx)" << endl;
1064 #endif
1065       bStop = Standard_True;
1066       break;
1067     }
1068     Standard_Real f = 0.;
1069
1070     switch (theChoixIso)
1071       { 
1072       case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
1073       case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
1074       case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
1075       case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
1076       }
1077
1078     if(f<0.1) f=0.1;
1079     
1080     previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
1081
1082     Standard_Real dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
1083     Standard_Real dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
1084     Standard_Real dP3 = sensCheminement * pasuv[2] * previousd2.X() /f; 
1085     Standard_Real dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
1086
1087     if(theChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < 1.e-7) dP1 *= (5. * (Standard_Real)dIncKey);
1088     if(theChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < 1.e-7) dP2 *= (5. * (Standard_Real)dIncKey);
1089     if(theChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < 1.e-7) dP3 *= (5. * (Standard_Real)dIncKey);
1090     if(theChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < 1.e-7) dP4 *= (5. * (Standard_Real)dIncKey);
1091    
1092     Param(1) += dP1;
1093     Param(2) += dP2;
1094     Param(3) += dP3; 
1095     Param(4) += dP4;
1096     Standard_Real SvParam[4];
1097     IntImp_ConstIsoparametric ChoixIso = theChoixIso;
1098
1099     for(parit = 0; parit < 4; parit++) {
1100       SvParam[parit] = Param(parit+1);
1101     }
1102     math_FunctionSetRoot  Rsnld(myIntersectionOn2S.Function());
1103     ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld, theChoixIso);
1104
1105     if (!myIntersectionOn2S.IsDone()) {
1106       return bOutOfTangentZone;
1107     }
1108     else {
1109       if (myIntersectionOn2S.IsEmpty()) {
1110         return bOutOfTangentZone;
1111       }
1112
1113       Status = TestDeflection();
1114
1115       if(Status == IntWalk_OK) {
1116
1117         for(uvit = 0; uvit < 4; uvit++) {
1118           if(pasuv[uvit] < pasInit[uvit]) {
1119             pasuv[uvit] = pasInit[uvit];
1120           }
1121         }
1122       }
1123
1124       switch(Status) {
1125       case  IntWalk_ArretSurPointPrecedent:
1126         {
1127           bStop = Standard_True;
1128           bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1129           break;
1130         }
1131       case IntWalk_PasTropGrand:
1132         {
1133           for(parit = 0; parit < 4; parit++) {
1134             Param(parit+1) = SvParam[parit];
1135           }
1136           Standard_Boolean bDecrease = Standard_False;
1137
1138           for(uvit = 0; uvit < 4; uvit++) {
1139             if(pasSav[uvit] < pasInit[uvit]) { 
1140               pasInit[uvit] -= (pasInit[uvit] - pasSav[uvit]) * 0.1;
1141               bDecrease = Standard_True;
1142             }
1143           }
1144
1145           if(bDecrease) nbIterWithoutAppend--;
1146           break;
1147         }
1148       case IntWalk_PointConfondu:
1149         {
1150           for(uvit = 0; uvit < 4; uvit++) {
1151             if(pasuv[uvit] < pasInit[uvit]) {
1152               pasuv[uvit] += (pasInit[uvit] - pasuv[uvit]) * 0.1;
1153             }
1154           }
1155           break;
1156         }
1157       case IntWalk_OK:
1158       case IntWalk_ArretSurPoint:
1159         {
1160           //
1161           bStop = TestArret(theDirectionFlag, Param, ChoixIso);
1162           //
1163
1164           //
1165           if(!bStop) {
1166             Standard_Real u11,v11,u12,v12; 
1167             myIntersectionOn2S.Point().Parameters(u11,v11,u12,v12); 
1168             Standard_Real u21,v21,u22,v22;
1169             previousPoint.Parameters(u21,v21,u22,v22); 
1170
1171             if(((fabs(u11-u21) < ResoU1) && (fabs(v11-v21) < ResoV1)) ||
1172                ((fabs(u12-u22) < ResoU2) && (fabs(v12-v22) < ResoV2))) {
1173               nbEqualPoints++;
1174             }
1175             else {
1176               nbEqualPoints = 0;
1177             }
1178           }
1179           //
1180
1181           bStop = bStop || !myIntersectionOn2S.IsTangent();
1182           bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1183
1184           if(!bStop) {
1185             Standard_Boolean pointisvalid = Standard_False;
1186             Standard_Real u1,v1,u2,v2; 
1187             myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2); 
1188
1189             if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 && 
1190                v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
1191                v1 >= Vm1  && v2 >= Vm2) 
1192               pointisvalid = Standard_True;
1193
1194             if(pointisvalid) {
1195               previousPoint = myIntersectionOn2S.Point();
1196               previoustg = myIntersectionOn2S.IsTangent();
1197
1198               if(!previoustg) {
1199                 previousd  = myIntersectionOn2S.Direction();
1200                 previousd1 = myIntersectionOn2S.DirectionOnS1();
1201                 previousd2 = myIntersectionOn2S.DirectionOnS2();
1202               }
1203               Standard_Boolean bAddPoint = Standard_True;
1204
1205               if(line->NbPoints() >= 1) {
1206                 gp_Pnt pf = line->Value(1).Value();
1207                 gp_Pnt pl = previousPoint.Value(); 
1208
1209                 if(pf.Distance(pl) < Precision::Confusion()) { 
1210                   dIncKey++; 
1211                   if(dIncKey == 5000) return bOutOfTangentZone; 
1212                   else bAddPoint = Standard_False;
1213                 }
1214               }
1215
1216               if(bAddPoint) {
1217                 aSeqOfNewPoint.Append(previousPoint);
1218                 nbIterWithoutAppend = 0;
1219               }
1220             }
1221
1222             if (line->NbPoints() == 2) {
1223               for(uvit = 0; uvit < 4; uvit++) {
1224                 pasSav[uvit] = pasuv[uvit]; 
1225               }
1226             }
1227
1228             if ( !pointisvalid ) {
1229               // decrease step if out of bounds
1230               // otherwise the same calculations will be 
1231               // repeated several times
1232               if ( ( u1 > UM1 ) || ( u1 < Um1 ) )
1233                 pasuv[0] *= 0.5;
1234
1235               if ( ( v1 > VM1 ) || ( v1 < Vm1 ) ) 
1236                 pasuv[1] *= 0.5;
1237
1238               if ( ( u2 > UM2 ) || ( u2 < Um2 ) )
1239                 pasuv[2] *= 0.5;
1240
1241               if ( ( v2 > VM2 ) || ( v2 < Vm2 ) )
1242                 pasuv[3] *= 0.5;
1243             }
1244           } // end if(!bStop)
1245           else { //if(bStop)
1246             if(close && (line->NbPoints() >= 1)) { 
1247
1248               if(!bOutOfTangentZone) {
1249                 aSeqOfNewPoint.Append(line->Value(1)); // line end
1250               }
1251               nbIterWithoutAppend = 0;
1252             }
1253             else {
1254               ChoixIso = myIntersectionOn2S.Perform(Param, Rsnld, theChoixIso);
1255
1256               if(myIntersectionOn2S.IsEmpty()) { 
1257                 bStop = !myIntersectionOn2S.IsTangent();
1258                 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1259               }
1260               else {
1261                 Standard_Boolean bAddPoint = Standard_True;
1262                 Standard_Boolean pointisvalid = Standard_False;
1263
1264                 previousPoint = myIntersectionOn2S.Point();
1265                 Standard_Real u1,v1,u2,v2; 
1266                 previousPoint.Parameters(u1,v1,u2,v2); 
1267
1268                 if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 && 
1269                    v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
1270                    v1 >= Vm1  && v2 >= Vm2) 
1271                   pointisvalid = Standard_True;
1272
1273                 if(pointisvalid) {
1274
1275                   if(line->NbPoints() >= 1) {
1276                     gp_Pnt pf = line->Value(1).Value();
1277                     gp_Pnt pl = previousPoint.Value(); 
1278
1279                     if(pf.Distance(pl) < Precision::Confusion()) { 
1280                       dIncKey++; 
1281                       if(dIncKey == 5000) return bOutOfTangentZone; 
1282                       else bAddPoint = Standard_False;
1283                     }
1284                   }
1285
1286                   if(bAddPoint && !bOutOfTangentZone) {
1287                     aSeqOfNewPoint.Append(previousPoint);
1288                     nbIterWithoutAppend = 0;
1289                   }
1290                 }
1291               }
1292             }
1293           }
1294           break;
1295         }
1296       default:
1297         {
1298           break;
1299         }
1300       }
1301     }
1302   }
1303   Standard_Boolean bExtendLine = Standard_False;
1304   Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.; 
1305
1306   Standard_Integer pit = 0;
1307
1308   for(pit = 0; !bExtendLine && (pit < 2); pit++) {
1309     if(pit == 0)
1310       previousPoint.Parameters(u1,v1,u2,v2); 
1311     else {
1312       if(aSeqOfNewPoint.Length() > 0)
1313         aSeqOfNewPoint.Value(aSeqOfNewPoint.Length()).Parameters(u1,v1,u2,v2); 
1314       else
1315         break;
1316     }
1317
1318     if(((u1 - Um1) < ResoU1) ||
1319        ((UM1 - u1) < ResoU1) ||
1320        ((u2 - Um2) < ResoU2) ||
1321        ((UM2 - u2) < ResoU2) ||
1322        ((v1 - Vm1) < ResoV1) ||
1323        ((VM1 - v1) < ResoV1) ||
1324        ((v2 - Vm2) < ResoV2) ||
1325        ((VM2 - v2) < ResoV2))
1326       bExtendLine = Standard_True;
1327   }
1328
1329   if(!bExtendLine) {
1330     //    if(Status == IntWalk_OK || Status == IntWalk_ArretSurPoint) {
1331     if(Status == IntWalk_OK) {
1332       bExtendLine = Standard_True;
1333
1334       if(aSeqOfNewPoint.Length() > 1) {
1335         TColStd_Array1OfReal FirstParams(0, 3), LastParams(0, 3), Resolutions(0, 3);
1336         Resolutions(0) = ResoU1; Resolutions(1) = ResoV1; Resolutions(2) = ResoU2; Resolutions(3) = ResoV2;
1337
1338         aSeqOfNewPoint(1).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1339                                      FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1340         aSeqOfNewPoint(aSeqOfNewPoint.Length()).Parameters(LastParams.ChangeValue(0), 
1341                                                            LastParams.ChangeValue(1),
1342                                                            LastParams.ChangeValue(2), 
1343                                                            LastParams.ChangeValue(3)); 
1344         Standard_Integer indexofiso = 0;
1345
1346         if(theChoixIso == IntImp_UIsoparametricOnCaro1) indexofiso = 0;
1347         if(theChoixIso == IntImp_VIsoparametricOnCaro1) indexofiso = 1;
1348         if(theChoixIso == IntImp_UIsoparametricOnCaro2) indexofiso = 2;
1349         if(theChoixIso == IntImp_VIsoparametricOnCaro2) indexofiso = 3;
1350
1351         Standard_Integer afirstindex = (indexofiso < 2) ? 0 : 2;
1352         gp_Vec2d aTangentZoneDir(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)),
1353                                  gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1)));
1354
1355         gp_Dir2d anIsoDir(0, 1);
1356
1357         if((indexofiso == 1) || (indexofiso == 3))
1358           anIsoDir = gp_Dir2d(1, 0);
1359
1360         if(aTangentZoneDir.SquareMagnitude() > gp::Resolution()) {
1361           Standard_Real piquota = M_PI*0.25;
1362
1363           if(fabs(aTangentZoneDir.Angle(anIsoDir)) > piquota) {
1364             Standard_Integer ii = 1, nextii = 2;
1365             gp_Vec2d d1(0, 0);
1366             Standard_Real asqresol = gp::Resolution();
1367             asqresol *= asqresol;
1368
1369             do {
1370               aSeqOfNewPoint(ii).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1371                                             FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1372               aSeqOfNewPoint(ii + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1373                                                   LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1374               d1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1375                                      FirstParams.Value(afirstindex + 1)),
1376                             gp_Pnt2d(LastParams.Value(afirstindex),
1377                                      LastParams.Value(afirstindex + 1)));
1378               ii++;
1379             }
1380             while((d1.SquareMagnitude() < asqresol) &&
1381                   (ii < aSeqOfNewPoint.Length()));
1382
1383             nextii = ii;
1384
1385             while(nextii < aSeqOfNewPoint.Length()) {
1386
1387               gp_Vec2d nextd1(0, 0);
1388               Standard_Integer jj = nextii;
1389
1390               do {
1391                 aSeqOfNewPoint(jj).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1392                                               FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1393                 aSeqOfNewPoint(jj + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1394                                                   LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1395                 nextd1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1396                                            FirstParams.Value(afirstindex + 1)),
1397                                   gp_Pnt2d(LastParams.Value(afirstindex),
1398                                            LastParams.Value(afirstindex + 1)));
1399                 jj++;
1400                 
1401               }
1402               while((nextd1.SquareMagnitude() < asqresol) &&
1403                     (jj < aSeqOfNewPoint.Length()));
1404               nextii = jj;
1405               
1406               if(fabs(d1.Angle(nextd1)) > piquota) {
1407                 bExtendLine = Standard_False;
1408                 break;
1409               }
1410               d1 = nextd1;
1411             }
1412           }
1413           // end if(fabs(aTangentZoneDir.Angle(anIsoDir)
1414         }
1415       }
1416     }
1417   }
1418
1419   if(!bExtendLine) {
1420     return Standard_False;
1421   }
1422   Standard_Integer i = 0;
1423
1424   for(i = 1; i <= aSeqOfNewPoint.Length(); i++) {
1425     AddAPoint(line, aSeqOfNewPoint.Value(i));
1426   }
1427
1428   return bOutOfTangentZone;
1429 }