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