0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[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 iCnt=0;
404   Standard_Integer i, NbPasOKConseq;
405   Standard_Real UFirst1, VFirst1, ULast1, VLast1, UFirst2, VFirst2, ULast2, VLast2;
406   Standard_Real pasMaxSV[4], aTmp;
407   TColStd_Array1OfReal Param(1,4);
408   IntImp_ConstIsoparametric ChoixIso;
409   //xt
410   //
411   done = Standard_False;
412   NbPasOKConseq=0;
413   //
414   // Caro1 and Caro2
415   const ThePSurface& Caro1 =myIntersectionOn2S.Function().AuxillarSurface1();
416   const ThePSurface& Caro2 =myIntersectionOn2S.Function().AuxillarSurface2();
417   //
418   UFirst1 = ThePSurfaceTool::FirstUParameter(Caro1);
419   VFirst1 = ThePSurfaceTool::FirstVParameter(Caro1);
420   ULast1  = ThePSurfaceTool::LastUParameter (Caro1);
421   VLast1  = ThePSurfaceTool::LastVParameter (Caro1);
422   //
423   UFirst2 = ThePSurfaceTool::FirstUParameter(Caro2);
424   VFirst2 = ThePSurfaceTool::FirstVParameter(Caro2);
425   ULast2  = ThePSurfaceTool::LastUParameter (Caro2);
426   VLast2  = ThePSurfaceTool::LastVParameter (Caro2);
427   //
428   ComputePasInit(pasuv,u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max,
429                  Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2,pasMax+pasMax);
430   //
431   if(pasuv[0]<100*ResoU1) {
432     pasuv[0]=100*ResoU1; 
433   }
434   if(pasuv[1]<100*ResoV1) {
435     pasuv[1]=100*ResoV1; 
436   }
437   if(pasuv[2]<100*ResoU2) {
438     pasuv[2]=100*ResoU2;
439   }
440   if(pasuv[3]<100*ResoV2) {
441     pasuv[3]=100*ResoV2;
442   }
443   //
444   for (i=0; i<4; ++i) {
445     if(pasuv[i]>10) {
446       pasuv[i] = 10;
447     }
448     pasInit[i] = pasSav[i] = pasuv[i]; 
449   }
450   //
451   line = new IntSurf_LineOn2S ();
452   //
453   for (i=1; i<=4; ++i) {
454     aTmp=ParDep(i);
455     Param(i)=ParDep(i);
456   }
457   //-- reprise des pas uv lies aux surfaces Caro1 et Caro2
458   //-- pasuv[] et pasSav[] sont modifies lors du cheminement
459   for(i = 0; i < 4; ++i) { 
460     pasMaxSV[i] = pasSav[i] = pasuv[i] = pasInit[i]; 
461   }
462
463   //-- calcul du premier point solution
464   math_FunctionSetRoot  Rsnld(myIntersectionOn2S.Function());
465   //
466   ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld);
467   if (!myIntersectionOn2S.IsDone())   {
468     return;
469   }
470   //
471   if (myIntersectionOn2S.IsEmpty()) {
472     return;
473   }
474   //
475   if(myIntersectionOn2S.IsTangent()) {
476     return;
477   }
478   //
479   Standard_Boolean Arrive, DejaReparti;
480   Standard_Integer IncKey, RejectIndex;
481   gp_Pnt pf,pl;
482   //
483   DejaReparti = Standard_False;
484   IncKey = 0;
485   RejectIndex = 0;
486   //
487   previousPoint = myIntersectionOn2S.Point();
488   previoustg = Standard_False;
489   previousd  = myIntersectionOn2S.Direction();
490   previousd1 = myIntersectionOn2S.DirectionOnS1();
491   previousd2 = myIntersectionOn2S.DirectionOnS2();
492   indextg = 1;
493   tgdir   = previousd;
494   firstd1 = previousd1;
495   firstd2 = previousd2;
496   tgfirst = tglast = Standard_False;
497   choixIsoSav  =  ChoixIso;
498   //------------------------------------------------------------
499   //-- On Teste si le premier point de cheminement correspond 
500   //-- a un point sur frontiere. 
501   //-- Dans ce cas, DejaReparti est initialise a True
502   //-- 
503   pf = previousPoint.Value();
504   Standard_Boolean bTestFirstPoint = Standard_True;
505   
506   previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));  
507   AddAPoint(line,previousPoint);
508   //
509   IntWalk_StatusDeflection Status = IntWalk_OK;
510   Standard_Boolean NoTestDeflection = Standard_False;
511   Standard_Real SvParam[4], f;
512   Standard_Integer LevelOfEmptyInmyIntersectionOn2S=0;
513   Standard_Integer LevelOfPointConfondu = 0; 
514   Standard_Integer LevelOfIterWithoutAppend = -1;
515   //
516   Arrive = Standard_False;
517   while(!Arrive) {//010
518     LevelOfIterWithoutAppend++;
519     if(LevelOfIterWithoutAppend>20) { 
520       Arrive = Standard_True; 
521       if(DejaReparti) {
522         break;
523       }
524       RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
525       LevelOfIterWithoutAppend = 0;
526     }
527     //
528     // compute f
529     f = 0.;
530     switch (ChoixIso) { 
531       case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
532       case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
533       case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
534       case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
535       default:break;
536     }
537     //
538     if(f<0.1) {
539       f=0.1;
540     }
541     //
542     previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
543     //
544     //--ofv.begin
545     Standard_Real aIncKey, aEps, dP1, dP2, dP3, dP4;
546     //
547     dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
548     dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
549     dP3 = sensCheminement * pasuv[2] * previousd2.X() /f; 
550     dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
551     //
552     aIncKey=5.*(Standard_Real)IncKey;
553     aEps=1.e-7;
554     if(ChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < aEps) {
555       dP1 *= aIncKey;
556     }
557     if(ChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < aEps) {
558       dP2 *= aIncKey;
559     }
560     if(ChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < aEps) {
561       dP3 *= aIncKey;
562     }
563     if(ChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < aEps) {
564       dP4 *= aIncKey;
565     }
566     //--ofv.end
567     //
568     Param(1) += dP1;
569     Param(2) += dP2;
570     Param(3) += dP3; 
571     Param(4) += dP4;
572     //==========================
573     SvParam[0]=Param(1); 
574     SvParam[1]=Param(2);
575     SvParam[2]=Param(3);
576     SvParam[3]=Param(4);
577     //
578     ChoixIso= myIntersectionOn2S.Perform(Param, Rsnld, ChoixIso);                  
579     //
580     if (!myIntersectionOn2S.IsDone())   {
581       //arret de la ligne,division
582       Arrive = Standard_False;
583       Param(1)=SvParam[0]; 
584       Param(2)=SvParam[1]; 
585       Param(3)=SvParam[2];
586       Param(4)=SvParam[3];
587       RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
588     }
589     else  {//009 
590       //== Le calcul du point exact a partir de Param(.) est possible
591       if (myIntersectionOn2S.IsEmpty()) {
592         Standard_Real u1,v1,u2,v2;
593         previousPoint.Parameters(u1,v1,u2,v2);
594         //
595         Arrive = Standard_False;
596         if(u1<UFirst1 || u1>ULast1) {
597           Arrive=Standard_True;
598         }       
599         if(u2<UFirst2 || u2>ULast2) {
600           Arrive=Standard_True;
601         }
602         if(v1<VFirst1 || v1>VLast1) {
603           Arrive=Standard_True;
604         }
605         if(v2<VFirst2 || v2>VLast2) {
606           Arrive=Standard_True;
607         }       
608         RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
609         LevelOfEmptyInmyIntersectionOn2S++;
610         //
611         if(LevelOfEmptyInmyIntersectionOn2S>10)    {
612           pasuv[0]=pasSav[0]; 
613           pasuv[1]=pasSav[1]; 
614           pasuv[2]=pasSav[2]; 
615           pasuv[3]=pasSav[3];
616         }           
617       }
618       else {//008
619         //============================================================
620         //== Un point a ete trouve :  T E S T   D E F L E C T I O N 
621         //============================================================
622         if(NoTestDeflection) {
623           NoTestDeflection = Standard_False;
624         }                 
625         else { 
626           if(--LevelOfEmptyInmyIntersectionOn2S<=0)     { 
627             LevelOfEmptyInmyIntersectionOn2S=0;
628             if(LevelOfIterWithoutAppend < 10) {
629               Status = TestDeflection();
630             }                   
631             else   { 
632               pasuv[0]*=0.5; 
633               pasuv[1]*=0.5; 
634               pasuv[2]*=0.5; 
635               pasuv[3]*=0.5;
636             }
637           }
638         }
639         //============================================================
640         //==       T r a i t e m e n t   s u r   S t a t u s        ==
641         //============================================================
642         if(LevelOfPointConfondu > 5) { 
643           Status = IntWalk_ArretSurPoint; 
644           LevelOfPointConfondu = 0;  
645         }
646         //
647         if(Status==IntWalk_OK) { 
648           NbPasOKConseq++;
649           if(NbPasOKConseq >= 5) { 
650             NbPasOKConseq=0;
651             Standard_Boolean pastroppetit;
652             Standard_Real t;
653             //
654             do { 
655               pastroppetit=Standard_True;
656               //
657               if(pasuv[0]<pasInit[0])     { 
658                 t = (pasInit[0]-pasuv[0])*0.25;
659                 if(t>0.1*pasInit[0]) {
660                   t=0.1*pasuv[0];
661                 }
662                 pasuv[0]+=t; 
663                 pastroppetit=Standard_False;
664               } 
665               if(pasuv[1]<pasInit[1])   { 
666                 t = (pasInit[1]-pasuv[1])*0.25;
667                 if(t>0.1*pasInit[1]) {
668                   t=0.1*pasuv[1];
669                 }               
670                 pasuv[1]+=t; 
671                 pastroppetit=Standard_False;
672               } 
673               if(pasuv[2]<pasInit[2]){
674                 t = (pasInit[2]-pasuv[2])*0.25;
675                 if(t>0.1*pasInit[2]) {
676                   t=0.1*pasuv[2];
677                 }
678                 pasuv[2]+=t; 
679                 pastroppetit=Standard_False;
680               } 
681               if(pasuv[3]<pasInit[3])   { 
682                 t = (pasInit[3]-pasuv[3])*0.25;
683                 if(t>0.1*pasInit[3]) {
684                   t=0.1*pasuv[3];
685                 }
686                 pasuv[3]+=t; 
687                 pastroppetit=Standard_False;
688               }
689               if(pastroppetit) { 
690                 if(pasMax<0.1){ 
691                   pasMax*=1.1; 
692                   pasInit[0]*=1.1; 
693                   pasInit[1]*=1.1; 
694                   pasInit[2]*=1.1; 
695                   pasInit[3]*=1.1; 
696                 }
697                 else {
698                   pastroppetit=Standard_False;
699                 }
700               }
701             } while(pastroppetit);
702           }
703         }//Status==IntWalk_OK
704         else NbPasOKConseq=0;
705         //
706         switch(Status) {//007 
707           case IntWalk_ArretSurPointPrecedent:  {                     
708             Arrive = Standard_False;                        
709             RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
710             break;
711           }
712           case IntWalk_PasTropGrand:  {
713             Param(1)=SvParam[0]; 
714             Param(2)=SvParam[1]; 
715             Param(3)=SvParam[2]; 
716             Param(4)=SvParam[3];
717             if(LevelOfIterWithoutAppend > 5) { 
718               if(pasSav[0]<pasInit[0]) { 
719                 pasInit[0]-=(pasInit[0]-pasSav[0])*0.25; 
720                 LevelOfIterWithoutAppend=0;
721               }
722               if(pasSav[1]<pasInit[1]) { 
723                 pasInit[1]-=(pasInit[1]-pasSav[1])*0.25;  
724                 LevelOfIterWithoutAppend=0; 
725               }
726               if(pasSav[2]<pasInit[2]) { 
727                 pasInit[2]-=(pasInit[2]-pasSav[2])*0.25;  
728                 LevelOfIterWithoutAppend=0; 
729               }
730               if(pasSav[3]<pasInit[3]) {
731                 pasInit[3]-=(pasInit[3]-pasSav[3])*0.25; 
732                 LevelOfIterWithoutAppend=0; 
733               }
734             }
735             break;
736           }
737           case IntWalk_PointConfondu:   {
738             LevelOfPointConfondu++;
739             if(LevelOfPointConfondu>5)   { 
740               Standard_Boolean pastroppetit;
741               //
742               do { 
743                 pastroppetit=Standard_True;
744                 if(pasuv[0]<pasInit[0]) { 
745                   pasuv[0]+=(pasInit[0]-pasuv[0])*0.25;
746                   pastroppetit=Standard_False; 
747                 } 
748                 if(pasuv[1]<pasInit[1]) { 
749                   pasuv[1]+=(pasInit[1]-pasuv[1])*0.25;
750                   pastroppetit=Standard_False; 
751                 } 
752                 if(pasuv[2]<pasInit[2]) { 
753                   pasuv[2]+=(pasInit[2]-pasuv[2])*0.25;
754                   pastroppetit=Standard_False; 
755                 } 
756                 if(pasuv[3]<pasInit[3]) { 
757                   pasuv[3]+=(pasInit[3]-pasuv[3])*0.25; 
758                   pastroppetit=Standard_False; 
759                 }
760                 if(pastroppetit)  { 
761                   if(pasMax<0.1){ 
762                     pasMax*=1.1; 
763                     pasInit[0]*=1.1; 
764                     pasInit[1]*=1.1; 
765                     pasInit[2]*=1.1; 
766                     pasInit[3]*=1.1; 
767                   }
768                   else{
769                     pastroppetit=Standard_False; 
770                   }             
771                 }
772               } while(pastroppetit);
773             }
774             break;
775           }
776           case IntWalk_OK:
777           case IntWalk_ArretSurPoint:  {//006
778             //=======================================================
779             //== T e s t   A r r e t   :  Cadrage sur Param(.)     ==
780             //=======================================================
781             //xft arrive here
782             Arrive = TestArret(DejaReparti,Param,ChoixIso); 
783             // JMB 30th December 1999. 
784             // Some statement below should not be put in comment because they are useful.
785             // See grid CTO 909 A1 which infinitely loops 
786             if(Arrive==Standard_False && Status==IntWalk_ArretSurPoint) { 
787               Arrive=Standard_True;
788 #ifdef DEB
789               cout << "Compile avec option DEB :Si Pb d intersection : ";
790               cout << "IntWalk_PWalking_1.gxx (lbr le 1erdec98)"<<endl;
791 #endif
792             }
793             if(Arrive) {
794               NbPasOKConseq = -10;
795             }
796             if(!Arrive)  {//005
797               //=====================================================
798               //== Param(.)  est dans les bornes                   ==
799               //==  et ne finit pas une ligne fermee               ==
800               //=====================================================
801               //== Verification sur Le Point Courant de myInters
802               Standard_Boolean pointisvalid = Standard_False;
803               {
804                 Standard_Real u1,v1,u2,v2; 
805                 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2); 
806                 //
807                 if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 && 
808                    v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
809                    v1 >= Vm1  && v2 >= Vm2) {
810                   pointisvalid=Standard_True;
811                 }
812               }
813               //
814               if(pointisvalid) { 
815                 previousPoint = myIntersectionOn2S.Point();
816                 previoustg = myIntersectionOn2S.IsTangent();
817                 if(!previoustg) {
818                   previousd  = myIntersectionOn2S.Direction();
819                   previousd1 = myIntersectionOn2S.DirectionOnS1();
820                   previousd2 = myIntersectionOn2S.DirectionOnS2();
821                 }
822                 //=====================================================
823                 //== Verification sur Previous Point
824                 {
825                   Standard_Real u1,v1,u2,v2; 
826                   previousPoint.Parameters(u1,v1,u2,v2); 
827                   if( u1 <= UM1  && u2 <= UM2 && v1 <= VM1 &&
828                       v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
829                       v1 >= Vm1  && v2 >= Vm2) { 
830                     pl = previousPoint.Value();
831                     if(bTestFirstPoint) {
832                       if(pf.Distance(pl) < 1.e-7){ 
833                         IncKey++; 
834                         if(IncKey == 5000) 
835                           return; 
836                         else 
837                           continue; 
838                       }
839                       else {
840                         bTestFirstPoint = Standard_False;
841                       }
842                     }
843                     //
844                     AddAPoint(line,previousPoint);
845                     RejectIndex++; 
846                     if(RejectIndex >= 250000) {
847                       break; 
848                     };
849                     //
850                     LevelOfIterWithoutAppend = 0;
851                   } 
852                 }
853               }//pointisvalid
854               //====================================================
855               if(Status == IntWalk_ArretSurPoint)  {
856                 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
857               }
858               else{ 
859                 if (line->NbPoints() == 2) {
860                   pasSav[0] = pasuv[0]; 
861                   pasSav[1] = pasuv[1]; 
862                   pasSav[2] = pasuv[2]; 
863                   pasSav[3] = pasuv[3];
864                 }
865               }
866             }//005 if(!Arrive)
867             //
868             else {//004
869               if(close) { 
870                 //================= la ligne est fermee ===============
871                 AddAPoint(line,line->Value(1)); //ligne fermee
872                 LevelOfIterWithoutAppend=0;
873               }
874               else {//$$$
875                 //====================================================
876                 //== Param n etait pas dans les bornes (a ete recadre)
877                 //====================================================
878                 Standard_Boolean bPrevNotTangent = !previoustg || !myIntersectionOn2S.IsTangent();
879                 
880                 IntImp_ConstIsoparametric SauvChoixIso = ChoixIso;
881                 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);    
882                 //
883                 if(!myIntersectionOn2S.IsEmpty()) { //002
884                   // debordement sur le carreau reciproque ou intersection en coin
885                   if(TestArret(Standard_True,Param,ChoixIso))  {
886                     NbPasOKConseq = -10;
887                     ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso); 
888                     if(!myIntersectionOn2S.IsEmpty())     {
889                       previousPoint = myIntersectionOn2S.Point();         
890                       previoustg = myIntersectionOn2S.IsTangent();
891                       if (!previoustg)     {
892                         previousd  = myIntersectionOn2S.Direction();
893                         previousd1 = myIntersectionOn2S.DirectionOnS1();
894                         previousd2 = myIntersectionOn2S.DirectionOnS2();
895                       }
896                       pl = previousPoint.Value();
897                       if(bTestFirstPoint) {
898                         if(pf.Distance(pl) < 1.e-7){ 
899                           IncKey++; 
900                           if(IncKey == 5000) 
901                             return; 
902                           else 
903                             continue; 
904                         }
905                         else {
906                           bTestFirstPoint = Standard_False;
907                         }
908                       }
909                       //
910                       AddAPoint(line,previousPoint);
911                       RejectIndex++;
912                       if(RejectIndex >= 250000) {
913                         break;
914                       };
915                       //
916                       LevelOfIterWithoutAppend=0;
917                       RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
918                     }
919                     else  {
920                       //echec cadrage diviser le pas
921                       Arrive = Standard_False;
922                       RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
923                       NoTestDeflection = Standard_True;
924                       ChoixIso = SauvChoixIso;
925                     }
926                   }//if(TestArret())
927                   else {
928                     // save the last point
929                     // to revert to it if the current point is out of bounds
930                     IntSurf_PntOn2S previousPointSave = previousPoint;
931                     Standard_Boolean previoustgSave   = previoustg;
932                     gp_Dir previousdSave              = previousd;
933                     gp_Dir2d previousd1Save           = previousd1;
934                     gp_Dir2d previousd2Save           = previousd2;
935                     
936                     previousPoint = myIntersectionOn2S.Point();         
937                     previoustg = myIntersectionOn2S.IsTangent();
938                     Arrive = Standard_False; 
939                     if(!previoustg)  {
940                       previousd  = myIntersectionOn2S.Direction();
941                       previousd1 = myIntersectionOn2S.DirectionOnS1();
942                       previousd2 = myIntersectionOn2S.DirectionOnS2();
943                     }
944                     //========================================
945                     //== Verification sur PreviousPoint @@
946                     {
947                       Standard_Real u1,v1,u2,v2; 
948                       previousPoint.Parameters(u1,v1,u2,v2); 
949                       Param(1) = u1; 
950                       Param(2) = v1;    
951                       Param(3) = u2; 
952                       Param(4) = v2;
953                       //
954                       //xf
955                       Standard_Boolean bFlag1, bFlag2;
956                       Standard_Real aTol2D=1.e-11;
957                       //
958                       bFlag1=u1 >= Um1-aTol2D && v1 >= Vm1-aTol2D && u1 <= UM1+aTol2D && v1 <= VM1+aTol2D;
959                       bFlag2=u2 >= Um2-aTol2D && v2 >= Vm2-aTol2D && u2 <= UM2+aTol2D && v2 <= VM2+aTol2D;
960                       if (bFlag1 && bFlag2) {
961                       /*
962                       if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 &&
963                          v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
964                          v1 >= Vm1  && v2 >= Vm2)  {
965                          */                     
966                       //xt
967                         pl = previousPoint.Value();
968                         if(bTestFirstPoint) {
969                           if(pf.Distance(pl) < 1.e-7) {
970                             IncKey++;
971                             if(IncKey == 5000)
972                               return; 
973                             else 
974                               continue;
975                           }
976                           else {
977                             bTestFirstPoint = Standard_False;
978                           }
979                         }
980                         AddAPoint(line,previousPoint);
981                         RejectIndex++;
982                         if(RejectIndex >= 250000) {
983                           break;
984                         }
985                         //
986                         LevelOfIterWithoutAppend=0;
987                         Arrive = Standard_True;
988                       }
989                       else {
990                         // revert to the last correctly calculated point
991                         previousPoint = previousPointSave;
992                         previoustg    = previoustgSave;
993                         previousd     = previousdSave;
994                         previousd1    = previousd1Save;
995                         previousd2    = previousd2Save;
996                       }
997                     }
998                     //
999                     Standard_Boolean wasExtended = Standard_False;
1000                     
1001                     if(Arrive && myIntersectionOn2S.IsTangent() && bPrevNotTangent) {
1002                       if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti)) {
1003                         wasExtended = Standard_True;
1004                         Arrive = Standard_False;
1005                         ChoixIso = SauvChoixIso;
1006                       }
1007                     }
1008                     
1009                     RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1010                     if(Arrive && 
1011                        myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() &&
1012                        myIntersectionOn2S.IsTangent() && bPrevNotTangent &&
1013                        !wasExtended) {
1014                       
1015                       if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti)) {
1016                         wasExtended = Standard_True;
1017                         Arrive = Standard_False;
1018                         ChoixIso = SauvChoixIso;
1019                       }
1020                     }
1021                   }//else !TestArret() $
1022                 } //$$ fin succes cadrage sur frontiere (!myIntersectionOn2S.IsEmpty())
1023                 else  {
1024                   //echec cadrage  sur frontiere;division du pas 
1025                   Arrive = Standard_False;
1026                   NoTestDeflection = Standard_True;
1027                   RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1028                 } 
1029               }//$$$ fin cadrage sur frontiere (!close)
1030             } //004 fin TestArret retourne Arrive = True
1031           } // 006case IntWalk_ArretSurPoint:  fin Traitement Status = OK  ou ArretSurPoint 
1032         } //007  switch(Status) 
1033       } //008 fin traitement point en court (TEST DEFLECTION)
1034     } //009 fin traitement ligne (else if myIntersectionOn2S.IsDone())
1035   }  //010 fin si premier point de depart a permis un cheminement while(!Arrive)
1036   done = Standard_True;
1037 }
1038 // ===========================================================================================================
1039 // function: ExtendLineInCommonZone
1040 // purpose:  Extends already computed line inside tangent zone in the direction given by theChoixIso.
1041 //           Returns Standard_True if the line was extended through tangent zone and the last computed point 
1042 //           is outside the tangent zone (but it is not put into the line). Otherwise returns Standard_False.
1043 // ===========================================================================================================
1044 Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso,
1045                                                           const Standard_Boolean          theDirectionFlag) 
1046 {
1047   Standard_Boolean bOutOfTangentZone = Standard_False;
1048   Standard_Boolean bStop = !myIntersectionOn2S.IsTangent();
1049   Standard_Integer dIncKey = 1;
1050   TColStd_Array1OfReal Param(1,4);
1051   IntWalk_StatusDeflection Status = IntWalk_OK;
1052   Standard_Integer nbIterWithoutAppend = 0;
1053   Standard_Integer nbEqualPoints = 0;
1054   Standard_Integer parit = 0;
1055   Standard_Integer uvit = 0;
1056   IntSurf_SequenceOfPntOn2S aSeqOfNewPoint;
1057
1058   while (!bStop) {
1059     nbIterWithoutAppend++;
1060
1061     if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) {
1062 #ifdef DEB
1063       cout<<"Compile with option DEB:";
1064       cout<<"Infinite loop has detected. Stop iterations (IntWalk_PWalking_1.gxx)" << endl;
1065 #endif
1066       bStop = Standard_True;
1067       break;
1068     }
1069     Standard_Real f = 0.;
1070
1071     switch (theChoixIso)
1072       { 
1073       case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
1074       case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
1075       case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
1076       case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
1077       }
1078
1079     if(f<0.1) f=0.1;
1080     
1081     previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
1082
1083     Standard_Real dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
1084     Standard_Real dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
1085     Standard_Real dP3 = sensCheminement * pasuv[2] * previousd2.X() /f; 
1086     Standard_Real dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
1087
1088     if(theChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < 1.e-7) dP1 *= (5. * (Standard_Real)dIncKey);
1089     if(theChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < 1.e-7) dP2 *= (5. * (Standard_Real)dIncKey);
1090     if(theChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < 1.e-7) dP3 *= (5. * (Standard_Real)dIncKey);
1091     if(theChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < 1.e-7) dP4 *= (5. * (Standard_Real)dIncKey);
1092    
1093     Param(1) += dP1;
1094     Param(2) += dP2;
1095     Param(3) += dP3; 
1096     Param(4) += dP4;
1097     Standard_Real SvParam[4];
1098     IntImp_ConstIsoparametric ChoixIso = theChoixIso;
1099
1100     for(parit = 0; parit < 4; parit++) {
1101       SvParam[parit] = Param(parit+1);
1102     }
1103     math_FunctionSetRoot  Rsnld(myIntersectionOn2S.Function());
1104     ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld, theChoixIso);
1105
1106     if (!myIntersectionOn2S.IsDone()) {
1107       return bOutOfTangentZone;
1108     }
1109     else {
1110       if (myIntersectionOn2S.IsEmpty()) {
1111         return bOutOfTangentZone;
1112       }
1113
1114       Status = TestDeflection();
1115
1116       if(Status == IntWalk_OK) {
1117
1118         for(uvit = 0; uvit < 4; uvit++) {
1119           if(pasuv[uvit] < pasInit[uvit]) {
1120             pasuv[uvit] = pasInit[uvit];
1121           }
1122         }
1123       }
1124
1125       switch(Status) {
1126       case  IntWalk_ArretSurPointPrecedent:
1127         {
1128           bStop = Standard_True;
1129           bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1130           break;
1131         }
1132       case IntWalk_PasTropGrand:
1133         {
1134           for(parit = 0; parit < 4; parit++) {
1135             Param(parit+1) = SvParam[parit];
1136           }
1137           Standard_Boolean bDecrease = Standard_False;
1138
1139           for(uvit = 0; uvit < 4; uvit++) {
1140             if(pasSav[uvit] < pasInit[uvit]) { 
1141               pasInit[uvit] -= (pasInit[uvit] - pasSav[uvit]) * 0.1;
1142               bDecrease = Standard_True;
1143             }
1144           }
1145
1146           if(bDecrease) nbIterWithoutAppend--;
1147           break;
1148         }
1149       case IntWalk_PointConfondu:
1150         {
1151           for(uvit = 0; uvit < 4; uvit++) {
1152             if(pasuv[uvit] < pasInit[uvit]) {
1153               pasuv[uvit] += (pasInit[uvit] - pasuv[uvit]) * 0.1;
1154             }
1155           }
1156           break;
1157         }
1158       case IntWalk_OK:
1159       case IntWalk_ArretSurPoint:
1160         {
1161           //
1162           bStop = TestArret(theDirectionFlag, Param, ChoixIso);
1163           //
1164
1165           //
1166           if(!bStop) {
1167             Standard_Real u11,v11,u12,v12; 
1168             myIntersectionOn2S.Point().Parameters(u11,v11,u12,v12); 
1169             Standard_Real u21,v21,u22,v22;
1170             previousPoint.Parameters(u21,v21,u22,v22); 
1171
1172             if(((fabs(u11-u21) < ResoU1) && (fabs(v11-v21) < ResoV1)) ||
1173                ((fabs(u12-u22) < ResoU2) && (fabs(v12-v22) < ResoV2))) {
1174               nbEqualPoints++;
1175             }
1176             else {
1177               nbEqualPoints = 0;
1178             }
1179           }
1180           //
1181
1182           bStop = bStop || !myIntersectionOn2S.IsTangent();
1183           bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1184
1185           if(!bStop) {
1186             Standard_Boolean pointisvalid = Standard_False;
1187             Standard_Real u1,v1,u2,v2; 
1188             myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2); 
1189
1190             if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 && 
1191                v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
1192                v1 >= Vm1  && v2 >= Vm2) 
1193               pointisvalid = Standard_True;
1194
1195             if(pointisvalid) {
1196               previousPoint = myIntersectionOn2S.Point();
1197               previoustg = myIntersectionOn2S.IsTangent();
1198
1199               if(!previoustg) {
1200                 previousd  = myIntersectionOn2S.Direction();
1201                 previousd1 = myIntersectionOn2S.DirectionOnS1();
1202                 previousd2 = myIntersectionOn2S.DirectionOnS2();
1203               }
1204               Standard_Boolean bAddPoint = Standard_True;
1205
1206               if(line->NbPoints() >= 1) {
1207                 gp_Pnt pf = line->Value(1).Value();
1208                 gp_Pnt pl = previousPoint.Value(); 
1209
1210                 if(pf.Distance(pl) < Precision::Confusion()) { 
1211                   dIncKey++; 
1212                   if(dIncKey == 5000) return bOutOfTangentZone; 
1213                   else bAddPoint = Standard_False;
1214                 }
1215               }
1216
1217               if(bAddPoint) {
1218                 aSeqOfNewPoint.Append(previousPoint);
1219                 nbIterWithoutAppend = 0;
1220               }
1221             }
1222
1223             if (line->NbPoints() == 2) {
1224               for(uvit = 0; uvit < 4; uvit++) {
1225                 pasSav[uvit] = pasuv[uvit]; 
1226               }
1227             }
1228
1229             if ( !pointisvalid ) {
1230               // decrease step if out of bounds
1231               // otherwise the same calculations will be 
1232               // repeated several times
1233               if ( ( u1 > UM1 ) || ( u1 < Um1 ) )
1234                 pasuv[0] *= 0.5;
1235
1236               if ( ( v1 > VM1 ) || ( v1 < Vm1 ) ) 
1237                 pasuv[1] *= 0.5;
1238
1239               if ( ( u2 > UM2 ) || ( u2 < Um2 ) )
1240                 pasuv[2] *= 0.5;
1241
1242               if ( ( v2 > VM2 ) || ( v2 < Vm2 ) )
1243                 pasuv[3] *= 0.5;
1244             }
1245           } // end if(!bStop)
1246           else { //if(bStop)
1247             if(close && (line->NbPoints() >= 1)) { 
1248
1249               if(!bOutOfTangentZone) {
1250                 aSeqOfNewPoint.Append(line->Value(1)); // line end
1251               }
1252               nbIterWithoutAppend = 0;
1253             }
1254             else {
1255               ChoixIso = myIntersectionOn2S.Perform(Param, Rsnld, theChoixIso);
1256
1257               if(myIntersectionOn2S.IsEmpty()) { 
1258                 bStop = !myIntersectionOn2S.IsTangent();
1259                 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1260               }
1261               else {
1262                 Standard_Boolean bAddPoint = Standard_True;
1263                 Standard_Boolean pointisvalid = Standard_False;
1264
1265                 previousPoint = myIntersectionOn2S.Point();
1266                 Standard_Real u1,v1,u2,v2; 
1267                 previousPoint.Parameters(u1,v1,u2,v2); 
1268
1269                 if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 && 
1270                    v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
1271                    v1 >= Vm1  && v2 >= Vm2) 
1272                   pointisvalid = Standard_True;
1273
1274                 if(pointisvalid) {
1275
1276                   if(line->NbPoints() >= 1) {
1277                     gp_Pnt pf = line->Value(1).Value();
1278                     gp_Pnt pl = previousPoint.Value(); 
1279
1280                     if(pf.Distance(pl) < Precision::Confusion()) { 
1281                       dIncKey++; 
1282                       if(dIncKey == 5000) return bOutOfTangentZone; 
1283                       else bAddPoint = Standard_False;
1284                     }
1285                   }
1286
1287                   if(bAddPoint && !bOutOfTangentZone) {
1288                     aSeqOfNewPoint.Append(previousPoint);
1289                     nbIterWithoutAppend = 0;
1290                   }
1291                 }
1292               }
1293             }
1294           }
1295           break;
1296         }
1297       default:
1298         {
1299           break;
1300         }
1301       }
1302     }
1303   }
1304   Standard_Boolean bExtendLine = Standard_False;
1305   Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.; 
1306
1307   Standard_Integer pit = 0;
1308
1309   for(pit = 0; !bExtendLine && (pit < 2); pit++) {
1310     if(pit == 0)
1311       previousPoint.Parameters(u1,v1,u2,v2); 
1312     else {
1313       if(aSeqOfNewPoint.Length() > 0)
1314         aSeqOfNewPoint.Value(aSeqOfNewPoint.Length()).Parameters(u1,v1,u2,v2); 
1315       else
1316         break;
1317     }
1318
1319     if(((u1 - Um1) < ResoU1) ||
1320        ((UM1 - u1) < ResoU1) ||
1321        ((u2 - Um2) < ResoU2) ||
1322        ((UM2 - u2) < ResoU2) ||
1323        ((v1 - Vm1) < ResoV1) ||
1324        ((VM1 - v1) < ResoV1) ||
1325        ((v2 - Vm2) < ResoV2) ||
1326        ((VM2 - v2) < ResoV2))
1327       bExtendLine = Standard_True;
1328   }
1329
1330   if(!bExtendLine) {
1331     //    if(Status == IntWalk_OK || Status == IntWalk_ArretSurPoint) {
1332     if(Status == IntWalk_OK) {
1333       bExtendLine = Standard_True;
1334
1335       if(aSeqOfNewPoint.Length() > 1) {
1336         TColStd_Array1OfReal FirstParams(0, 3), LastParams(0, 3), Resolutions(0, 3);
1337         Resolutions(0) = ResoU1; Resolutions(1) = ResoV1; Resolutions(2) = ResoU2; Resolutions(3) = ResoV2;
1338
1339         aSeqOfNewPoint(1).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1340                                      FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1341         aSeqOfNewPoint(aSeqOfNewPoint.Length()).Parameters(LastParams.ChangeValue(0), 
1342                                                            LastParams.ChangeValue(1),
1343                                                            LastParams.ChangeValue(2), 
1344                                                            LastParams.ChangeValue(3)); 
1345         Standard_Integer indexofiso = 0;
1346
1347         if(theChoixIso == IntImp_UIsoparametricOnCaro1) indexofiso = 0;
1348         if(theChoixIso == IntImp_VIsoparametricOnCaro1) indexofiso = 1;
1349         if(theChoixIso == IntImp_UIsoparametricOnCaro2) indexofiso = 2;
1350         if(theChoixIso == IntImp_VIsoparametricOnCaro2) indexofiso = 3;
1351
1352         Standard_Integer afirstindex = (indexofiso < 2) ? 0 : 2;
1353         gp_Vec2d aTangentZoneDir(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)),
1354                                  gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1)));
1355
1356         gp_Dir2d anIsoDir(0, 1);
1357
1358         if((indexofiso == 1) || (indexofiso == 3))
1359           anIsoDir = gp_Dir2d(1, 0);
1360
1361         if(aTangentZoneDir.SquareMagnitude() > gp::Resolution()) {
1362           Standard_Real piquota = M_PI*0.25;
1363
1364           if(fabs(aTangentZoneDir.Angle(anIsoDir)) > piquota) {
1365             Standard_Integer ii = 1, nextii = 2;
1366             gp_Vec2d d1(0, 0);
1367             Standard_Real asqresol = gp::Resolution();
1368             asqresol *= asqresol;
1369
1370             do {
1371               aSeqOfNewPoint(ii).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1372                                             FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1373               aSeqOfNewPoint(ii + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1374                                                   LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1375               d1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1376                                      FirstParams.Value(afirstindex + 1)),
1377                             gp_Pnt2d(LastParams.Value(afirstindex),
1378                                      LastParams.Value(afirstindex + 1)));
1379               ii++;
1380             }
1381             while((d1.SquareMagnitude() < asqresol) &&
1382                   (ii < aSeqOfNewPoint.Length()));
1383
1384             nextii = ii;
1385
1386             while(nextii < aSeqOfNewPoint.Length()) {
1387
1388               gp_Vec2d nextd1(0, 0);
1389               Standard_Integer jj = nextii;
1390
1391               do {
1392                 aSeqOfNewPoint(jj).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1393                                               FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1394                 aSeqOfNewPoint(jj + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1395                                                   LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1396                 nextd1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1397                                            FirstParams.Value(afirstindex + 1)),
1398                                   gp_Pnt2d(LastParams.Value(afirstindex),
1399                                            LastParams.Value(afirstindex + 1)));
1400                 jj++;
1401                 
1402               }
1403               while((nextd1.SquareMagnitude() < asqresol) &&
1404                     (jj < aSeqOfNewPoint.Length()));
1405               nextii = jj;
1406               
1407               if(fabs(d1.Angle(nextd1)) > piquota) {
1408                 bExtendLine = Standard_False;
1409                 break;
1410               }
1411               d1 = nextd1;
1412             }
1413           }
1414           // end if(fabs(aTangentZoneDir.Angle(anIsoDir)
1415         }
1416       }
1417     }
1418   }
1419
1420   if(!bExtendLine) {
1421     return Standard_False;
1422   }
1423   Standard_Integer i = 0;
1424
1425   for(i = 1; i <= aSeqOfNewPoint.Length(); i++) {
1426     AddAPoint(line, aSeqOfNewPoint.Value(i));
1427   }
1428
1429   return bOutOfTangentZone;
1430 }