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