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