0024682: Move out B-spline cache from curves and surfaces to dedicated classes BSplCL...
[occt.git] / src / IntWalk / IntWalk_PWalking.cxx
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 under
7 // the terms of the GNU Lesser General Public License 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 #include <IntWalk_PWalking.ixx>
16
17 #include <IntWalk_StatusDeflection.hxx>
18
19 #include <TColgp_Array1OfPnt.hxx>
20 #include <TColStd_Array1OfReal.hxx>
21
22 #include <IntImp_ComputeTangence.hxx>
23
24 #include <Adaptor3d_HSurface.hxx>
25 #include <Adaptor3d_HSurfaceTool.hxx>
26
27 #include <Precision.hxx>
28
29 #include <math_FunctionSetRoot.hxx>
30 #include <Geom_Surface.hxx>
31
32 #include <Standard_Failure.hxx>
33 #include <gp_Pnt2d.hxx>
34
35 //==================================================================================
36 // function : IntWalk_PWalking::IntWalk_PWalking
37 // purpose  :
38 // estimate of max step : To avoid abrupt changes 
39 // during change of isos 
40 //==================================================================================
41 void ComputePasInit(Standard_Real *pasuv,
42                     Standard_Real Um1,Standard_Real UM1,
43                     Standard_Real Vm1,Standard_Real VM1,
44                     Standard_Real Um2,Standard_Real UM2,
45                     Standard_Real Vm2,Standard_Real VM2,
46                     Standard_Real _Um1,Standard_Real _UM1,
47                     Standard_Real _Vm1,Standard_Real _VM1,
48                     Standard_Real _Um2,Standard_Real _UM2,
49                     Standard_Real _Vm2,Standard_Real _VM2,
50                     const Handle(Adaptor3d_HSurface)& ,
51                     const Handle(Adaptor3d_HSurface)& ,
52                     const Standard_Real Increment) 
53
54   Standard_Real du1=Abs(UM1-Um1);
55   Standard_Real dv1=Abs(VM1-Vm1);
56   Standard_Real du2=Abs(UM2-Um2);
57   Standard_Real dv2=Abs(VM2-Vm2);
58
59   Standard_Real _du1=Abs(_UM1-_Um1);
60   Standard_Real _dv1=Abs(_VM1-_Vm1);
61   Standard_Real _du2=Abs(_UM2-_Um2);
62   Standard_Real _dv2=Abs(_VM2-_Vm2);
63
64   //-- limit the reduction of uv box estimate to 0.01 natural box
65   //--  du1 : On box of Inter
66   //-- _du1 : On parametric space
67   if(_du1<1e50 && du1<0.01*_du1) du1=0.01*_du1;
68   if(_dv1<1e50 && dv1<0.01*_dv1) dv1=0.01*_dv1;
69   if(_du2<1e50 && du2<0.01*_du2) du2=0.01*_du2;
70   if(_dv2<1e50 && dv2<0.01*_dv2) dv2=0.01*_dv2;
71
72   pasuv[0]=Increment*du1;
73   pasuv[1]=Increment*dv1;
74   pasuv[2]=Increment*du2;
75   pasuv[3]=Increment*dv2;
76 }
77
78 //=======================================================================
79 //function : IsParallel
80 //purpose  : Checks if theLine is parallel of some boundary of given
81 //            surface (it is determined by theCheckSurf1 flag). 
82 //            Parallelism assumes small oscillations (swing is less or 
83 //            equal than theToler).
84 //            Small lines (if first and last parameters in the Surface 
85 //            are almost equal) are classified as parallel (as same as 
86 //            any point can be considered as parallel of any line).
87 //=======================================================================
88 static void IsParallel(const Handle(IntSurf_LineOn2S)& theLine,
89                        const Standard_Boolean theCheckSurf1,
90                        const Standard_Real theToler,
91                        Standard_Boolean& theIsUparallel,
92                        Standard_Boolean& theIsVparallel)
93 {
94   const Standard_Integer aNbPointsMAX = 23;
95
96   theIsUparallel = theIsVparallel = Standard_True;
97
98   Standard_Integer aNbPoints = theLine->NbPoints();
99   if(aNbPoints > aNbPointsMAX)
100   {
101     aNbPoints = aNbPointsMAX;
102   }
103   else if(aNbPoints < 3)
104   {
105     //Here we cannot estimate parallelism.
106     //Do all same as for small lines 
107     return;
108   }
109
110   Standard_Real aStep = IntToReal(theLine->NbPoints()) / aNbPoints;
111   Standard_Real aNPoint = 1.0;
112
113   Standard_Real aUmin = RealLast(), aUmax = RealFirst(), aVmin = RealLast(), aVmax = RealFirst();
114   for(Standard_Integer aNum = 1; aNum <= aNbPoints; aNum++, aNPoint += aStep)
115   {
116     if(aNPoint > aNbPoints)
117     {
118       aNPoint = aNbPoints;
119     }
120
121     Standard_Real u, v;
122     if(theCheckSurf1)
123       theLine->Value(RealToInt(aNPoint)).ParametersOnS1(u, v);
124     else
125       theLine->Value(RealToInt(aNPoint)).ParametersOnS2(u, v);
126
127     if(u < aUmin)
128       aUmin = u;
129
130     if(u > aUmax)
131       aUmax = u;
132
133     if(v < aVmin)
134       aVmin = v;
135
136     if(v > aVmax)
137       aVmax = v;
138   }
139
140   theIsVparallel = ((aUmax - aUmin) < theToler);
141   theIsUparallel = ((aVmax - aVmin) < theToler);
142 }
143
144 //=======================================================================
145 //function : Checking
146 //purpose  : Check, if given point is in surface's boundaries.
147 //            If "yes" then theFactTol = 0.0, else theFactTol is
148 //            equal maximal deviation.
149 //=======================================================================
150 static Standard_Boolean Checking( const Handle(Adaptor3d_HSurface)& theASurf1,
151                                  const Handle(Adaptor3d_HSurface)& theASurf2,
152                                  Standard_Real& theU1,
153                                  Standard_Real& theV1,
154                                  Standard_Real& theU2,
155                                  Standard_Real& theV2,
156                                  Standard_Real& theFactTol)
157 {
158   const Standard_Real aTol = Precision::PConfusion();
159   const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
160   const Standard_Real aU1bLast = theASurf1->LastUParameter();
161   const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
162   const Standard_Real aU2bLast = theASurf2->LastUParameter();
163   const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
164   const Standard_Real aV1bLast = theASurf1->LastVParameter();
165   const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
166   const Standard_Real aV2bLast = theASurf2->LastVParameter();
167
168   Standard_Boolean isOnOrIn = Standard_True;
169   theFactTol = 0.0;
170
171   Standard_Real aDelta = aU1bFirst - theU1;
172   if(aDelta > aTol)
173   {
174     theU1 = aU1bFirst;
175     theFactTol = Max(theFactTol, aDelta);
176     isOnOrIn = Standard_False;
177   }
178
179   aDelta = theU1 - aU1bLast;
180   if(aDelta > aTol)
181   {
182     theU1 = aU1bLast;
183     theFactTol = Max(theFactTol, aDelta);
184     isOnOrIn = Standard_False;
185   }
186
187   aDelta = aV1bFirst - theV1;
188   if(aDelta > aTol)
189   {
190     theV1 = aV1bFirst;
191     theFactTol = Max(theFactTol, aDelta);
192     isOnOrIn = Standard_False;
193   }
194
195   aDelta = theV1 - aV1bLast;
196   if(aDelta > aTol)
197   {
198     theV1 = aV1bLast;
199     theFactTol = Max(theFactTol, aDelta);
200     isOnOrIn = Standard_False;
201   }
202
203   aDelta = aU2bFirst - theU2;
204   if(aDelta > aTol)
205   {
206     theU2 = aU2bFirst;
207     theFactTol = Max(theFactTol, aDelta);
208     isOnOrIn = Standard_False;
209   }
210
211   aDelta = theU2 - aU2bLast;
212   if(aDelta > aTol)
213   {
214     theU2 = aU2bLast;
215     theFactTol = Max(theFactTol, aDelta);
216     isOnOrIn = Standard_False;
217   }
218
219   aDelta = aV2bFirst - theV2;
220   if(aDelta > aTol)
221   {
222     theV2 = aV2bFirst;
223     theFactTol = Max(theFactTol, aDelta);
224     isOnOrIn = Standard_False;
225   }
226
227   aDelta = theV2 - aV2bLast;
228   if(aDelta > aTol)
229   {
230     theV2 = aV2bLast;
231     theFactTol = Max(theFactTol, aDelta);
232     isOnOrIn = Standard_False;
233   }
234
235   return isOnOrIn;
236 }
237
238 //==================================================================================
239 // function : IntWalk_PWalking::IntWalk_PWalking
240 // purpose  : 
241 //==================================================================================
242 IntWalk_PWalking::IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1,
243                                    const Handle(Adaptor3d_HSurface)& Caro2,
244                                    const Standard_Real TolTangency,
245                                    const Standard_Real Epsilon,
246                                    const Standard_Real Deflection,
247                                    const Standard_Real Increment ) 
248                                    :
249
250 done(Standard_True),
251 close(Standard_False),
252 fleche(Deflection),
253 tolconf(Epsilon),
254 sensCheminement(1),
255 myIntersectionOn2S(Caro1,Caro2,TolTangency),
256 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
257 STATIC_PRECEDENT_INFLEXION(0)
258 {
259   Standard_Real KELARG=20.;
260   //
261   pasMax=Increment*0.2; //-- June 25 99 after problems with precision 
262   Um1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
263   Vm1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
264   UM1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1);
265   VM1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1);
266
267   Um2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
268   Vm2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
269   UM2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2);
270   VM2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2);
271
272   ResoU1 = Adaptor3d_HSurfaceTool::UResolution(Caro1,Precision::Confusion());
273   ResoV1 = Adaptor3d_HSurfaceTool::VResolution(Caro1,Precision::Confusion());
274
275   ResoU2 = Adaptor3d_HSurfaceTool::UResolution(Caro2,Precision::Confusion());
276   ResoV2 = Adaptor3d_HSurfaceTool::VResolution(Caro2,Precision::Confusion());
277
278   Standard_Real NEWRESO;
279   Standard_Real MAXVAL;
280   Standard_Real MAXVAL2;
281   //
282   MAXVAL  = Abs(Um1);  MAXVAL2 = Abs(UM1);
283   if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
284   NEWRESO = ResoU1 * MAXVAL ;
285   if(NEWRESO > ResoU1 &&NEWRESO<10) {    ResoU1 = NEWRESO;  }
286
287
288   MAXVAL  = Abs(Um2);   MAXVAL2 = Abs(UM2);
289   if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
290   NEWRESO = ResoU2 * MAXVAL ;
291   if(NEWRESO > ResoU2 && NEWRESO<10) {     ResoU2 = NEWRESO;  }
292
293
294   MAXVAL  = Abs(Vm1);  MAXVAL2 = Abs(VM1);
295   if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
296   NEWRESO = ResoV1 * MAXVAL ;
297   if(NEWRESO > ResoV1 && NEWRESO<10) {     ResoV1 = NEWRESO;  }
298
299
300   MAXVAL  = Abs(Vm2);  MAXVAL2 = Abs(VM2);
301   if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
302   NEWRESO = ResoV2 * MAXVAL ;
303   if(NEWRESO > ResoV2 && NEWRESO<10) {     ResoV2 = NEWRESO;  }
304
305   pasuv[0]=pasMax*Abs(UM1-Um1);
306   pasuv[1]=pasMax*Abs(VM1-Vm1);
307   pasuv[2]=pasMax*Abs(UM2-Um2);
308   pasuv[3]=pasMax*Abs(VM2-Vm2);
309
310   if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
311   if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
312   if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
313   if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
314
315
316   if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro1)==Standard_False) { 
317     //UM1+=KELARG*pasuv[0];  Um1-=KELARG*pasuv[0];
318   }
319   else { 
320     Standard_Real t = UM1-Um1; 
321     if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro1)) { 
322       t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro1)-t);
323       t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
324       UM1+=t;  Um1-=t;
325     }
326   }
327
328   if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro1)==Standard_False) { 
329     //VM1+=KELARG*pasuv[1];  Vm1-=KELARG*pasuv[1];
330   }
331   else { 
332     Standard_Real t = VM1-Vm1; 
333     if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro1)) { 
334       t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro1)-t);
335       t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
336       VM1+=t;  Vm1-=t;
337     }
338   }
339
340   if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro2)==Standard_False) { 
341     //UM2+=KELARG*pasuv[2];  Um2-=KELARG*pasuv[2];
342   }
343   else { 
344     Standard_Real t = UM2-Um2; 
345     if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro2)) { 
346       t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro2)-t);
347       t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
348       UM2+=t;  Um2-=t;
349     }
350   }
351
352   if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {   
353     //VM2+=KELARG*pasuv[3];  Vm2-=KELARG*pasuv[3];
354   }
355   else { 
356     Standard_Real t = VM2-Vm2; 
357     if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro2)) { 
358       t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro2)-t);
359       t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
360       VM2+=t;  Vm2-=t;
361     }
362   }
363
364   //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
365
366   for (Standard_Integer i = 0; i<=3;i++) {
367     if(pasuv[i]>10) 
368       pasuv[i] = 10; 
369     pasInit[i] = pasSav[i] = pasuv[i]; 
370   }
371
372
373 }
374 //==================================================================================
375 // function : IntWalk_PWalking
376 // purpose  : 
377 //==================================================================================
378 IntWalk_PWalking::IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1,
379                                    const Handle(Adaptor3d_HSurface)& Caro2,
380                                    const Standard_Real TolTangency,
381                                    const Standard_Real Epsilon,
382                                    const Standard_Real Deflection,
383                                    const Standard_Real Increment, 
384                                    const Standard_Real U1,
385                                    const Standard_Real V1,
386                                    const Standard_Real U2, 
387                                    const Standard_Real V2)
388                                    :
389
390 done(Standard_True),
391 close(Standard_False),
392 fleche(Deflection),
393 tolconf(Epsilon),
394 sensCheminement(1),       
395 myIntersectionOn2S(Caro1,Caro2,TolTangency),
396 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
397 STATIC_PRECEDENT_INFLEXION(0)
398 {
399   Standard_Real KELARG=20.;
400   //
401   pasMax=Increment*0.2; //-- June 25 99 after problems with precision 
402   //
403   Um1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
404   Vm1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
405   UM1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1);
406   VM1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1);
407
408   Um2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
409   Vm2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
410   UM2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2);
411   VM2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2);
412
413   ResoU1 = Adaptor3d_HSurfaceTool::UResolution(Caro1,Precision::Confusion());
414   ResoV1 = Adaptor3d_HSurfaceTool::VResolution(Caro1,Precision::Confusion());
415
416   ResoU2 = Adaptor3d_HSurfaceTool::UResolution(Caro2,Precision::Confusion());
417   ResoV2 = Adaptor3d_HSurfaceTool::VResolution(Caro2,Precision::Confusion());
418   //
419   Standard_Real NEWRESO, MAXVAL, MAXVAL2;
420   //
421   MAXVAL  = Abs(Um1);  
422   MAXVAL2 = Abs(UM1);
423   if(MAXVAL2 > MAXVAL) {
424     MAXVAL = MAXVAL2;
425   }
426   NEWRESO = ResoU1 * MAXVAL ;
427   if(NEWRESO > ResoU1) {
428     ResoU1 = NEWRESO;  
429   }
430   //
431   MAXVAL  = Abs(Um2);   
432   MAXVAL2 = Abs(UM2);
433   if(MAXVAL2 > MAXVAL){
434     MAXVAL = MAXVAL2;
435   }  
436   NEWRESO = ResoU2 * MAXVAL ;
437   if(NEWRESO > ResoU2) {
438     ResoU2 = NEWRESO;  
439   }
440   //
441   MAXVAL  = Abs(Vm1);  
442   MAXVAL2 = Abs(VM1);
443   if(MAXVAL2 > MAXVAL) {
444     MAXVAL = MAXVAL2;
445   }
446   NEWRESO = ResoV1 * MAXVAL ;
447   if(NEWRESO > ResoV1) {    
448     ResoV1 = NEWRESO; 
449   }
450   //
451   MAXVAL  = Abs(Vm2);  
452   MAXVAL2 = Abs(VM2);
453   if(MAXVAL2 > MAXVAL){
454     MAXVAL = MAXVAL2;
455   }  
456   NEWRESO = ResoV2 * MAXVAL ;
457   if(NEWRESO > ResoV2) {  
458     ResoV2 = NEWRESO;
459   }
460   //
461   pasuv[0]=pasMax*Abs(UM1-Um1);
462   pasuv[1]=pasMax*Abs(VM1-Vm1);
463   pasuv[2]=pasMax*Abs(UM2-Um2);
464   pasuv[3]=pasMax*Abs(VM2-Vm2);
465   //
466   if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro1)==Standard_False) { 
467     UM1+=KELARG*pasuv[0];  
468     Um1-=KELARG*pasuv[0];
469   }
470   else { 
471     Standard_Real t = UM1-Um1; 
472     if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro1)) { 
473       t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro1)-t);
474       t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
475       UM1+=t;  
476       Um1-=t;
477     }
478   }
479   //
480   if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro1)==Standard_False) { 
481     VM1+=KELARG*pasuv[1];
482     Vm1-=KELARG*pasuv[1];
483   }
484   else { 
485     Standard_Real t = VM1-Vm1; 
486     if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro1)) { 
487       t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro1)-t);
488       t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
489       VM1+=t;  Vm1-=t;
490     }
491   }
492   //
493   if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro2)==Standard_False) { 
494     UM2+=KELARG*pasuv[2];  
495     Um2-=KELARG*pasuv[2];
496   }
497   else { 
498     Standard_Real t = UM2-Um2; 
499     if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro2)) { 
500       t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro2)-t);
501       t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
502       UM2+=t;  
503       Um2-=t;
504     }
505   }
506
507   if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {   
508     VM2+=KELARG*pasuv[3];  
509     Vm2-=KELARG*pasuv[3];
510   }
511   else { 
512     Standard_Real t = VM2-Vm2; 
513     if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro2)) { 
514       t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro2)-t);
515       t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
516       VM2+=t;  
517       Vm2-=t;
518     }
519   }
520   //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
521
522   for (Standard_Integer i = 0; i<=3;i++) {
523     pasInit[i] = pasSav[i] = pasuv[i]; 
524   }  
525
526   if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
527   if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
528   if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
529   if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
530   //
531   TColStd_Array1OfReal Par(1,4);
532   Par(1) = U1;
533   Par(2) = V1;
534   Par(3) = U2;
535   Par(4) = V2;
536   Perform(Par);
537 }
538
539 //==================================================================================
540 // function : PerformFirstPoint
541 // purpose  : 
542 //==================================================================================
543 Standard_Boolean IntWalk_PWalking::PerformFirstPoint  (const TColStd_Array1OfReal& ParDep,
544                                                        IntSurf_PntOn2S& FirstPoint)   
545 {
546   sensCheminement = 1;
547   close = Standard_False;
548   //
549   Standard_Integer i;
550   TColStd_Array1OfReal Param(1,4);
551   //
552   for (i=1; i<=4; ++i) {
553     Param(i) = ParDep(i);
554   }
555   //-- calculate the first solution point
556   math_FunctionSetRoot  Rsnld(myIntersectionOn2S.Function());
557   //
558   myIntersectionOn2S.Perform(Param,Rsnld);
559   if (!myIntersectionOn2S.IsDone())  { 
560     return Standard_False;
561   }
562
563   if (myIntersectionOn2S.IsEmpty()) {
564     return Standard_False;
565   }
566
567   FirstPoint = myIntersectionOn2S.Point();
568   return Standard_True;
569 }
570 //==================================================================================
571 // function : Perform
572 // purpose  : 
573 //==================================================================================
574 void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep)    
575 {
576   Perform(ParDep,Um1,Vm1,Um2,Vm2,UM1,VM1,UM2,VM2);
577 }
578 //==================================================================================
579 // function : Perform
580 // purpose  : 
581 //==================================================================================
582 void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
583                                const Standard_Real u1min,
584                                const Standard_Real v1min,
585                                const Standard_Real u2min,
586                                const Standard_Real v2min,
587                                const Standard_Real u1max,
588                                const Standard_Real v1max,
589                                const Standard_Real u2max,
590                                const Standard_Real v2max)
591 {
592   const Standard_Real aSQDistMax = 1.0e-14;
593   //xf
594
595   Standard_Integer NbPasOKConseq=0;
596   TColStd_Array1OfReal Param(1,4);
597   IntImp_ConstIsoparametric ChoixIso;
598   //xt
599   //
600   done = Standard_False;
601   //
602   // Caro1 and Caro2
603   const Handle(Adaptor3d_HSurface)& Caro1 =myIntersectionOn2S.Function().AuxillarSurface1();
604   const Handle(Adaptor3d_HSurface)& Caro2 =myIntersectionOn2S.Function().AuxillarSurface2();
605   //
606   const Standard_Real UFirst1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
607   const Standard_Real VFirst1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
608   const Standard_Real ULast1  = Adaptor3d_HSurfaceTool::LastUParameter (Caro1);
609   const Standard_Real VLast1  = Adaptor3d_HSurfaceTool::LastVParameter (Caro1);
610
611   const Standard_Real UFirst2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
612   const Standard_Real VFirst2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
613   const Standard_Real ULast2  = Adaptor3d_HSurfaceTool::LastUParameter (Caro2);
614   const Standard_Real VLast2  = Adaptor3d_HSurfaceTool::LastVParameter (Caro2);
615   //
616   ComputePasInit(pasuv,u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max,
617     Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2,pasMax+pasMax);
618   //
619   if(pasuv[0]<100.0*ResoU1) {
620     pasuv[0]=100.0*ResoU1; 
621   }
622   if(pasuv[1]<100.0*ResoV1) {
623     pasuv[1]=100.0*ResoV1; 
624   }
625   if(pasuv[2]<100.0*ResoU2) {
626     pasuv[2]=100.0*ResoU2;
627   }
628   if(pasuv[3]<100.0*ResoV2) {
629     pasuv[3]=100.0*ResoV2;
630   }
631   //
632   for (Standard_Integer i=0; i<4; ++i)
633   {
634     if(pasuv[i]>10)
635     {
636       pasuv[i] = 10;
637     }
638
639     pasInit[i] = pasSav[i] = pasuv[i]; 
640   }
641   //
642   line = new IntSurf_LineOn2S ();
643   //
644   for (Standard_Integer i=1; i<=4; ++i)
645   {
646     Param(i)=ParDep(i);
647   }
648   //-- reproduce steps uv connected to surfaces Caro1 and Caro2
649   //-- pasuv[] and pasSav[] are modified during the marching
650   for(Standard_Integer i = 0; i < 4; ++i)
651   {
652     pasSav[i] = pasuv[i] = pasInit[i];
653   }
654
655   //-- calculate the first solution point
656   math_FunctionSetRoot  Rsnld(myIntersectionOn2S.Function());
657   //
658   ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld);
659   if (!myIntersectionOn2S.IsDone())
660   {
661     return;
662   }
663
664   //
665   if (myIntersectionOn2S.IsEmpty())
666   {
667     return;
668   }
669   //
670   if(myIntersectionOn2S.IsTangent())
671   {
672     return;
673   }
674   //
675   Standard_Boolean Arrive, DejaReparti;
676   const Standard_Integer RejectIndexMAX = 250000;
677   Standard_Integer IncKey, RejectIndex;
678   gp_Pnt pf,pl;
679   //
680   DejaReparti = Standard_False;
681   IncKey = 0;
682   RejectIndex = 0;
683   //
684   previousPoint = myIntersectionOn2S.Point();
685   previoustg = Standard_False;
686   previousd  = myIntersectionOn2S.Direction();
687   previousd1 = myIntersectionOn2S.DirectionOnS1();
688   previousd2 = myIntersectionOn2S.DirectionOnS2();
689   indextg = 1;
690   tgdir   = previousd;
691   firstd1 = previousd1;
692   firstd2 = previousd2;
693   tgfirst = tglast = Standard_False;
694   choixIsoSav  =  ChoixIso;
695   //------------------------------------------------------------
696   //-- Test if the first point of marching corresponds 
697   //-- to a point on borders. 
698   //-- In this case, DejaReparti is initialized as True
699   //-- 
700   pf = previousPoint.Value();
701   Standard_Boolean bTestFirstPoint = Standard_True;
702
703   previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
704   AddAPoint(line,previousPoint);
705   //
706   IntWalk_StatusDeflection Status = IntWalk_OK;
707   Standard_Boolean NoTestDeflection = Standard_False;
708   Standard_Real SvParam[4], f;
709   Standard_Integer LevelOfEmptyInmyIntersectionOn2S=0;
710   Standard_Integer LevelOfPointConfondu = 0; 
711   Standard_Integer LevelOfIterWithoutAppend = -1;
712   //
713
714   const Standard_Real aTol[4] = { Epsilon(u1max - u1min),
715                                   Epsilon(v1max - v1min),
716                                   Epsilon(u2max - u2min),
717                                   Epsilon(v2max - v2min)};
718   Arrive = Standard_False;
719   while(!Arrive) //010
720   {
721     LevelOfIterWithoutAppend++;
722     if(LevelOfIterWithoutAppend>20)
723     {
724       Arrive = Standard_True; 
725       if(DejaReparti) {
726         break;
727       }
728       RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
729       LevelOfIterWithoutAppend = 0;
730     }
731     //
732     // compute f
733     f = 0.;
734     switch (ChoixIso) { 
735       case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
736       case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
737       case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
738       case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
739       default:break;
740     }
741     //
742     if(f<0.1) {
743       f=0.1;
744     }
745     //
746     previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
747     //
748     //--ofv.begin
749     Standard_Real aIncKey, aEps, dP1, dP2, dP3, dP4;
750     //
751     dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
752     dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
753     dP3 = sensCheminement * pasuv[2] * previousd2.X() /f; 
754     dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
755     //
756     aIncKey=5.*(Standard_Real)IncKey;
757     aEps=1.e-7;
758     if(ChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < aEps)
759     {
760       dP1 *= aIncKey;
761     }
762
763     if(ChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < aEps)
764     {
765       dP2 *= aIncKey;
766     }
767
768     if(ChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < aEps)
769     {
770       dP3 *= aIncKey;
771     }
772
773     if(ChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < aEps)
774     {
775       dP4 *= aIncKey;
776     }
777     //--ofv.end
778     //
779     Param(1) += dP1;
780     Param(2) += dP2;
781     Param(3) += dP3; 
782     Param(4) += dP4;
783     //==========================
784     SvParam[0]=Param(1); 
785     SvParam[1]=Param(2);
786     SvParam[2]=Param(3);
787     SvParam[3]=Param(4);
788     //
789     Standard_Integer aTryNumber = 0;
790     Standard_Real    isBadPoint = Standard_False;
791     IntImp_ConstIsoparametric aBestIso = ChoixIso;
792     do
793     {
794       isBadPoint = Standard_False;
795
796       ChoixIso= myIntersectionOn2S.Perform(Param, Rsnld, aBestIso);
797
798       if (myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty())
799       {
800         //If we go along any surface boundary then it is possible 
801         //to find "outboundaried" point.
802         //Nevertheless, if this deflection is quite small, we will be
803         //able to adjust this point to the boundary.
804
805         Standard_Real aNewPnt[4], anAbsParamDist[4];
806         myIntersectionOn2S.Point().Parameters(aNewPnt[0], aNewPnt[1], aNewPnt[2], aNewPnt[3]);
807         const Standard_Real aParMin[4] = {u1min, v1min, u2min, v2min};
808         const Standard_Real aParMax[4] = {u1max, v1max, u2max, v2max};
809
810         for(Standard_Integer i = 0; i < 4; i++)
811         {
812           if(Abs(aNewPnt[i] - aParMin[i]) < aTol[i])
813             aNewPnt[i] = aParMin[i];
814           else if(Abs(aNewPnt[i] - aParMax[i]) < aTol[i])
815             aNewPnt[i] = aParMax[i];
816         }
817
818         if (aNewPnt[0] < u1min || aNewPnt[0] > u1max ||
819             aNewPnt[1] < v1min || aNewPnt[1] > v1max ||
820             aNewPnt[2] < u2min || aNewPnt[2] > u2max ||
821             aNewPnt[3] < v2min || aNewPnt[3] > v2max)
822         {
823           break; // Out of borders, handle this later.
824         }
825
826         myIntersectionOn2S.ChangePoint().SetValue(aNewPnt[0],
827                                                   aNewPnt[1],
828                                                   aNewPnt[2],
829                                                   aNewPnt[3]);
830
831         anAbsParamDist[0] = Abs(Param(1) - dP1 - aNewPnt[0]);
832         anAbsParamDist[1] = Abs(Param(2) - dP2 - aNewPnt[1]);
833         anAbsParamDist[2] = Abs(Param(3) - dP3 - aNewPnt[2]);
834         anAbsParamDist[3] = Abs(Param(4) - dP4 - aNewPnt[3]);
835         if (anAbsParamDist[0] < ResoU1 &&
836             anAbsParamDist[1] < ResoV1 &&
837             anAbsParamDist[2] < ResoU2 &&
838             anAbsParamDist[3] < ResoV2 &&
839             Status != IntWalk_PasTropGrand)
840         {
841           isBadPoint = Standard_True;
842           aBestIso = IntImp_ConstIsoparametric((aBestIso + 1) % 4);
843         }
844       }
845     } while (isBadPoint && ++aTryNumber <= 4);
846     //
847     if (!myIntersectionOn2S.IsDone())
848     {
849       //end of line, division
850       Arrive = Standard_False;
851       Param(1)=SvParam[0]; 
852       Param(2)=SvParam[1]; 
853       Param(3)=SvParam[2];
854       Param(4)=SvParam[3];
855       RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
856     }
857     else  //009 
858     {
859       //== Calculation of exact point from Param(.) is possible
860       if (myIntersectionOn2S.IsEmpty())
861       {
862         Standard_Real u1,v1,u2,v2;
863         previousPoint.Parameters(u1,v1,u2,v2);
864         //
865         Arrive = Standard_False;
866         if(u1<UFirst1 || u1>ULast1)
867         {
868           Arrive=Standard_True;
869         }       
870
871         if(u2<UFirst2 || u2>ULast2)
872         {
873           Arrive=Standard_True;
874         }
875
876         if(v1<VFirst1 || v1>VLast1)
877         {
878           Arrive=Standard_True;
879         }
880
881         if(v2<VFirst2 || v2>VLast2)
882         {
883           Arrive=Standard_True;
884         }
885
886         RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
887         LevelOfEmptyInmyIntersectionOn2S++;
888         //
889         if(LevelOfEmptyInmyIntersectionOn2S>10)
890         {
891           pasuv[0]=pasSav[0]; 
892           pasuv[1]=pasSav[1]; 
893           pasuv[2]=pasSav[2]; 
894           pasuv[3]=pasSav[3];
895         }
896       }
897       else //008
898       {
899         //============================================================
900         //== A point has been found :  T E S T   D E F L E C T I O N 
901         //============================================================
902         if(NoTestDeflection)
903         {
904           NoTestDeflection = Standard_False;
905         }                 
906         else
907         {
908           if(--LevelOfEmptyInmyIntersectionOn2S<=0)
909           {
910             LevelOfEmptyInmyIntersectionOn2S=0;
911             if(LevelOfIterWithoutAppend < 10)
912             {
913               Status = TestDeflection();
914             }                   
915             else
916             {
917               pasuv[0]*=0.5; 
918               pasuv[1]*=0.5; 
919               pasuv[2]*=0.5; 
920               pasuv[3]*=0.5;
921             }
922           }
923         }
924
925         //============================================================
926         //==       T r a i t e m e n t   s u r   S t a t u s        ==
927         //============================================================
928         if(LevelOfPointConfondu > 5)
929         { 
930           Status = IntWalk_ArretSurPoint; 
931           LevelOfPointConfondu = 0;  
932         }
933         //
934         if(Status==IntWalk_OK)
935         { 
936           NbPasOKConseq++;
937           if(NbPasOKConseq >= 5)
938           {
939             NbPasOKConseq=0;
940             Standard_Boolean pastroppetit;
941             Standard_Real t;
942             //
943             do
944             {
945               pastroppetit=Standard_True;
946               //
947               if(pasuv[0]<pasInit[0])
948               {
949                 t = (pasInit[0]-pasuv[0])*0.25;
950                 if(t>0.1*pasInit[0])
951                 {
952                   t=0.1*pasuv[0];
953                 }
954
955                 pasuv[0]+=t; 
956                 pastroppetit=Standard_False;
957               }
958
959               if(pasuv[1]<pasInit[1])
960               {
961                 t = (pasInit[1]-pasuv[1])*0.25;
962                 if(t>0.1*pasInit[1]) {
963                   t=0.1*pasuv[1];
964                 }               
965
966                 pasuv[1]+=t; 
967                 pastroppetit=Standard_False;
968               }
969
970               if(pasuv[2]<pasInit[2])
971               {
972                 t = (pasInit[2]-pasuv[2])*0.25;
973                 if(t>0.1*pasInit[2])
974                 {
975                   t=0.1*pasuv[2];
976                 }
977
978                 pasuv[2]+=t; 
979                 pastroppetit=Standard_False;
980               }
981
982               if(pasuv[3]<pasInit[3])
983               {
984                 t = (pasInit[3]-pasuv[3])*0.25;
985                 if(t>0.1*pasInit[3]) {
986                   t=0.1*pasuv[3];
987                 }
988                 pasuv[3]+=t; 
989                 pastroppetit=Standard_False;
990               }
991               if(pastroppetit)
992               {
993                 if(pasMax<0.1)
994                 {
995                   pasMax*=1.1;
996                   pasInit[0]*=1.1; 
997                   pasInit[1]*=1.1; 
998                   pasInit[2]*=1.1; 
999                   pasInit[3]*=1.1; 
1000                 }
1001                 else
1002                 {
1003                   pastroppetit=Standard_False;
1004                 }
1005               }
1006             }
1007             while(pastroppetit);
1008           }
1009         }//Status==IntWalk_OK
1010         else
1011           NbPasOKConseq=0;
1012
1013         //
1014         switch(Status)//007 
1015         {
1016         case IntWalk_ArretSurPointPrecedent:
1017           {
1018             Arrive = Standard_False;
1019             RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
1020             break;
1021           }
1022         case IntWalk_PasTropGrand:
1023           {
1024             Param(1)=SvParam[0];
1025             Param(2)=SvParam[1]; 
1026             Param(3)=SvParam[2]; 
1027             Param(4)=SvParam[3];
1028
1029             if(LevelOfIterWithoutAppend > 5)
1030             {
1031               for (Standard_Integer i = 0; i < 4; i++)
1032               {
1033                 if (pasSav[i] > pasInit[i])
1034                   continue;
1035
1036                 const Standard_Real aDelta = (pasInit[i]-pasSav[i])*0.25;
1037
1038                 if(aDelta > Epsilon(pasInit[i]))
1039                 {
1040                   pasInit[i] -= aDelta;
1041                   LevelOfIterWithoutAppend=0;
1042                 }
1043               }
1044             }
1045
1046             break;
1047           }
1048         case IntWalk_PointConfondu:
1049           {
1050             LevelOfPointConfondu++;
1051
1052             if(LevelOfPointConfondu>5)
1053             {
1054               Standard_Boolean pastroppetit;
1055               //
1056               do
1057               {
1058                 pastroppetit=Standard_True;
1059
1060                 if(pasuv[0]<pasInit[0])
1061                 {
1062                   pasuv[0]+=(pasInit[0]-pasuv[0])*0.25;
1063                   pastroppetit=Standard_False;
1064                 }
1065
1066                 if(pasuv[1]<pasInit[1])
1067                 {
1068                   pasuv[1]+=(pasInit[1]-pasuv[1])*0.25;
1069                   pastroppetit=Standard_False;
1070                 }
1071
1072                 if(pasuv[2]<pasInit[2])
1073                 {
1074                   pasuv[2]+=(pasInit[2]-pasuv[2])*0.25;
1075                   pastroppetit=Standard_False; 
1076                 }
1077
1078                 if(pasuv[3]<pasInit[3])
1079                 {
1080                   pasuv[3]+=(pasInit[3]-pasuv[3])*0.25;
1081                   pastroppetit=Standard_False;
1082                 }
1083
1084                 if(pastroppetit)
1085                 {
1086                   if(pasMax<0.1)
1087                   {
1088                     pasMax*=1.1;
1089                     pasInit[0]*=1.1;
1090                     pasInit[1]*=1.1;
1091                     pasInit[2]*=1.1;
1092                     pasInit[3]*=1.1; 
1093                   }
1094                   else
1095                   {
1096                     pastroppetit=Standard_False;
1097                   }
1098                 }
1099               }
1100               while(pastroppetit);
1101             }
1102
1103             break;
1104           }
1105         case IntWalk_OK:
1106         case IntWalk_ArretSurPoint://006
1107           {
1108             //=======================================================
1109             //== Stop Test t   :  Frame on Param(.)     ==
1110             //=======================================================
1111             //xft arrive here
1112             Arrive = TestArret(DejaReparti,Param,ChoixIso); 
1113             // JMB 30th December 1999. 
1114             // Some statement below should not be put in comment because they are useful.
1115             // See grid CTO 909 A1 which infinitely loops 
1116             if(Arrive==Standard_False && Status==IntWalk_ArretSurPoint)
1117             {
1118               Arrive=Standard_True;
1119 #ifdef OCCT_DEBUG
1120               cout << "IntWalk_PWalking_1.gxx: Problems with intersection"<<endl;
1121 #endif
1122             }
1123
1124             if(Arrive)
1125             {
1126               NbPasOKConseq = -10;
1127             }
1128
1129             if(!Arrive)//005
1130             {
1131               //=====================================================
1132               //== Param(.) is in the limits                       ==
1133               //==  and does not end a closed  line                ==
1134               //=====================================================
1135               //== Check on the current point of myInters
1136               Standard_Boolean pointisvalid = Standard_False;
1137               {
1138                 Standard_Real u1,v1,u2,v2; 
1139                 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1140
1141                 //
1142                 if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 && 
1143                   v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
1144                   v1 >= Vm1  && v2 >= Vm2)
1145                 {
1146                   pointisvalid=Standard_True;
1147                 }
1148               }
1149
1150               //
1151               if(pointisvalid)
1152               {
1153                 previousPoint = myIntersectionOn2S.Point();
1154                 previoustg = myIntersectionOn2S.IsTangent();
1155
1156                 if(!previoustg)
1157                 {
1158                   previousd  = myIntersectionOn2S.Direction();
1159                   previousd1 = myIntersectionOn2S.DirectionOnS1();
1160                   previousd2 = myIntersectionOn2S.DirectionOnS2();
1161                 }
1162                 //=====================================================
1163                 //== Check on the previous Point
1164                 {
1165                   Standard_Real u1,v1,u2,v2;
1166                   previousPoint.Parameters(u1,v1,u2,v2); 
1167                   if( u1 <= UM1  && u2 <= UM2 && v1 <= VM1 &&
1168                     v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
1169                     v1 >= Vm1  && v2 >= Vm2)
1170                   {
1171                     pl = previousPoint.Value();
1172                     if(bTestFirstPoint)
1173                     {
1174                       if(pf.SquareDistance(pl) < aSQDistMax)
1175                       {
1176                         IncKey++;
1177                         if(IncKey == 5000)
1178                           return;
1179                         else
1180                           continue;
1181                       }
1182                       else
1183                       {
1184                         bTestFirstPoint = Standard_False;
1185                       }
1186                     }
1187                     //
1188                     AddAPoint(line,previousPoint);
1189                     RejectIndex++;
1190
1191                     if(RejectIndex >= RejectIndexMAX)
1192                     {
1193                       break;
1194                     }
1195
1196                     //
1197                     LevelOfIterWithoutAppend = 0;
1198                   }
1199                 }
1200               }//pointisvalid
1201               //====================================================
1202
1203               if(Status == IntWalk_ArretSurPoint)
1204               {
1205                 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1206               }
1207               else
1208               {
1209                 if (line->NbPoints() == 2)
1210                 {
1211                   pasSav[0] = pasuv[0];
1212                   pasSav[1] = pasuv[1];
1213                   pasSav[2] = pasuv[2];
1214                   pasSav[3] = pasuv[3];
1215                 }
1216               }
1217             }//005 if(!Arrive)
1218             else  //004
1219             {
1220               if(close)
1221               {
1222                 //================= la ligne est fermee ===============
1223                 AddAPoint(line,line->Value(1)); //ligne fermee
1224                 LevelOfIterWithoutAppend=0;
1225               }
1226               else    //$$$
1227               {
1228                 //====================================================
1229                 //== Param was not in the limits (was reframed)
1230                 //====================================================
1231                 Standard_Boolean bPrevNotTangent = !previoustg || !myIntersectionOn2S.IsTangent();
1232
1233                 IntImp_ConstIsoparametric SauvChoixIso = ChoixIso;
1234                 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1235                 //
1236                 if(!myIntersectionOn2S.IsEmpty()) //002
1237                 {
1238                   // mutially outpasses in the square or intersection in corner
1239
1240                   if(TestArret(Standard_True,Param,ChoixIso))
1241                   {
1242                     NbPasOKConseq = -10;
1243                     ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1244
1245                     if(!myIntersectionOn2S.IsEmpty())
1246                     {
1247                       previousPoint = myIntersectionOn2S.Point();
1248                       previoustg = myIntersectionOn2S.IsTangent();
1249
1250                       if (!previoustg)
1251                       {
1252                         previousd  = myIntersectionOn2S.Direction();
1253                         previousd1 = myIntersectionOn2S.DirectionOnS1();
1254                         previousd2 = myIntersectionOn2S.DirectionOnS2();
1255                       }
1256
1257                       pl = previousPoint.Value();
1258
1259                       if(bTestFirstPoint)
1260                       {
1261                         if(pf.SquareDistance(pl) < aSQDistMax)
1262                         {
1263                           IncKey++;
1264                           if(IncKey == 5000)
1265                             return;
1266                           else
1267                             continue;
1268                         }
1269                         else
1270                         {
1271                           bTestFirstPoint = Standard_False;
1272                         }
1273                       }
1274                       //
1275                       AddAPoint(line,previousPoint);
1276                       RejectIndex++;
1277
1278                       if(RejectIndex >= RejectIndexMAX)
1279                       {
1280                         break;
1281                       }
1282
1283                       //
1284                       LevelOfIterWithoutAppend=0;
1285                       RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1286                     }
1287                     else
1288                     {
1289                       //fail framing divides the step
1290                       Arrive = Standard_False;
1291                       RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1292                       NoTestDeflection = Standard_True;
1293                       ChoixIso = SauvChoixIso;
1294                     }
1295                   }//if(TestArret())
1296                   else
1297                   {
1298                     // save the last point
1299                     // to revert to it if the current point is out of bounds
1300
1301                     IntSurf_PntOn2S previousPointSave = previousPoint;
1302                     Standard_Boolean previoustgSave   = previoustg;
1303                     gp_Dir previousdSave              = previousd;
1304                     gp_Dir2d previousd1Save           = previousd1;
1305                     gp_Dir2d previousd2Save           = previousd2;
1306
1307                     previousPoint = myIntersectionOn2S.Point();
1308                     previoustg = myIntersectionOn2S.IsTangent();
1309                     Arrive = Standard_False;
1310
1311                     if(!previoustg)
1312                     {
1313                       previousd  = myIntersectionOn2S.Direction();
1314                       previousd1 = myIntersectionOn2S.DirectionOnS1();
1315                       previousd2 = myIntersectionOn2S.DirectionOnS2();
1316                     }
1317
1318                     //========================================
1319                     //== Check on PreviousPoint @@
1320
1321                     {
1322                       Standard_Real u1,v1,u2,v2;
1323                       previousPoint.Parameters(u1,v1,u2,v2);
1324
1325                       //To save initial 2d points
1326                       gp_Pnt2d ParamPntOnS1(Param(1), Param(2));
1327                       gp_Pnt2d ParamPntOnS2(Param(3), Param(4));
1328
1329                       ///////////////////////////
1330                       Param(1) = u1;
1331                       Param(2) = v1;
1332                       Param(3) = u2;
1333                       Param(4) = v2;
1334                       //
1335
1336                       //xf
1337                       Standard_Boolean bFlag1, bFlag2;
1338                       Standard_Real aTol2D=1.e-11;
1339                       //
1340                       bFlag1=u1 >= Um1-aTol2D && v1 >= Vm1-aTol2D && u1 <= UM1+aTol2D && v1 <= VM1+aTol2D;
1341                       bFlag2=u2 >= Um2-aTol2D && v2 >= Vm2-aTol2D && u2 <= UM2+aTol2D && v2 <= VM2+aTol2D;
1342                       if (bFlag1 && bFlag2)
1343                       {
1344                         if (line->NbPoints() > 1)
1345                         {
1346                           IntSurf_PntOn2S prevprevPoint = line->Value(line->NbPoints()-1);
1347                           Standard_Real ppU1, ppV1, ppU2, ppV2;
1348                           prevprevPoint.Parameters(ppU1, ppV1, ppU2, ppV2);
1349                           Standard_Real pU1, pV1, pU2, pV2;
1350                           previousPointSave.Parameters(pU1, pV1, pU2, pV2);
1351                           gp_Vec2d V1onS1(gp_Pnt2d(ppU1, ppV1), gp_Pnt2d(pU1, pV1));
1352                           gp_Vec2d V2onS1(gp_Pnt2d(pU1, pV1), gp_Pnt2d(u1, v1));
1353                           gp_Vec2d V1onS2(gp_Pnt2d(ppU2, ppV2), gp_Pnt2d(pU2, pV2));
1354                           gp_Vec2d V2onS2(gp_Pnt2d(pU2, pV2), gp_Pnt2d(u2, v2));
1355
1356                           const Standard_Real aDot1 = V1onS1 * V2onS1;
1357                           const Standard_Real aDot2 = V1onS2 * V2onS2;
1358
1359                           if ((aDot1 < 0.0) || (aDot2 < 0.0))
1360                           {
1361                             Arrive = Standard_True;
1362                             break;
1363                           }
1364                         }
1365                         /*
1366                         if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 &&
1367                         v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
1368                         v1 >= Vm1  && v2 >= Vm2)  {
1369                         */                      
1370                         //xt
1371                         pl = previousPoint.Value();
1372
1373                         if(bTestFirstPoint)
1374                         {
1375                           if(pf.SquareDistance(pl) < aSQDistMax)
1376                           {
1377                             IncKey++;
1378
1379                             if(IncKey == 5000)
1380                               return;
1381                             else
1382                               continue;
1383                           }
1384                           else
1385                           {
1386                             bTestFirstPoint = Standard_False;
1387                           }
1388                         }
1389
1390                         //To avoid walking around the same point
1391                         //in the tangent zone near a border
1392
1393                         if (previoustg)
1394                         {
1395                           //There are three consecutive points:
1396                           //previousPointSave -> ParamPnt -> curPnt.
1397
1398                           Standard_Real prevU1, prevV1, prevU2, prevV2;
1399                           previousPointSave.Parameters(prevU1, prevV1, prevU2, prevV2);
1400                           gp_Pnt2d prevPntOnS1(prevU1, prevV1), prevPntOnS2(prevU2, prevV2);
1401                           gp_Pnt2d curPntOnS1(u1, v1), curPntOnS2(u2, v2);
1402                           gp_Vec2d PrevToParamOnS1(prevPntOnS1, ParamPntOnS1);
1403                           gp_Vec2d PrevToCurOnS1(prevPntOnS1, curPntOnS1);
1404                           gp_Vec2d PrevToParamOnS2(prevPntOnS2, ParamPntOnS2);
1405                           gp_Vec2d PrevToCurOnS2(prevPntOnS2, curPntOnS2);
1406                           Standard_Real MaxAngle = 3*M_PI/4;
1407                           Standard_Real anAngleS1 = 0.0, anAngleS2 = 0.0;
1408                           const Standard_Real aSQMParS1 = PrevToParamOnS1.SquareMagnitude();
1409                           const Standard_Real aSQMParS2 = PrevToParamOnS2.SquareMagnitude();
1410                           const Standard_Real aSQMCurS1 = PrevToCurOnS1.SquareMagnitude();
1411                           const Standard_Real aSQMCurS2 = PrevToCurOnS2.SquareMagnitude();
1412
1413                           if(aSQMCurS1 < gp::Resolution())
1414                           {
1415                             //We came back to the one of previos point.
1416                             //Therefore, we must break;
1417
1418                             anAngleS1 = M_PI;
1419                           }
1420                           else if(aSQMParS1 < gp::Resolution())
1421                           {
1422                             //We are walking along tangent zone.
1423                             //It should be continued.
1424                             anAngleS1 = 0.0;
1425                           }
1426                           else
1427                           {
1428                             anAngleS1 = Abs(PrevToParamOnS1.Angle(PrevToCurOnS1));
1429                           }
1430
1431                           if(aSQMCurS2 < gp::Resolution())
1432                           {
1433                             //We came back to the one of previos point.
1434                             //Therefore, we must break;
1435
1436                             anAngleS2 = M_PI;
1437                           }
1438                           else if(aSQMParS2 < gp::Resolution())
1439                           {
1440                             //We are walking along tangent zone.
1441                             //It should be continued;
1442                             anAngleS2 = 0.0;
1443                           }
1444                           else
1445                           {
1446                             anAngleS2 = Abs(PrevToParamOnS2.Angle(PrevToCurOnS2));
1447                           }
1448
1449                           if ((anAngleS1 > MaxAngle) && (anAngleS2 > MaxAngle))
1450                           {
1451                             Arrive = Standard_True;
1452                             break;
1453                           }
1454
1455                           {
1456                             //Check singularity.
1457                             //I.e. check if we are walking along direction, which does not
1458                             //result in comming to any point (i.e. derivative 
1459                             //3D-intersection curve along this direction is equal to 0).
1460                             //A sphere with direction {dU=1, dV=0} from point
1461                             //(U=0, V=M_PI/2) can be considered as example for
1462                             //this case (we cannot find another 3D-point if we go thus).
1463
1464                             //Direction chosen along 1st and 2nd surface correspondingly
1465                             const gp_Vec2d  aDirS1(prevPntOnS1, curPntOnS1),
1466                                             aDirS2(prevPntOnS2, curPntOnS2);
1467
1468                             gp_Pnt aPtemp;
1469                             gp_Vec aDuS1, aDvS1, aDuS2, aDvS2;
1470
1471                             myIntersectionOn2S.Function().AuxillarSurface1()->
1472                                   D1(curPntOnS1.X(), curPntOnS1.Y(), aPtemp, aDuS1, aDvS1);
1473                             myIntersectionOn2S.Function().AuxillarSurface2()->
1474                                   D1(curPntOnS2.X(), curPntOnS2.Y(), aPtemp, aDuS2, aDvS2);
1475
1476                             //Derivative WLine along (it is vector-function indeed)
1477                             //directions chosen
1478                             //(https://en.wikipedia.org/wiki/Directional_derivative#Variation_using_only_direction_of_vector).
1479                             //F1 - on the 1st surface, F2 - on the 2nd surface.
1480                             //x, y, z - coordinates of derivative vector.
1481                             const Standard_Real aF1x =  aDuS1.X()*aDirS1.X() + 
1482                                                         aDvS1.X()*aDirS1.Y();
1483                             const Standard_Real aF1y =  aDuS1.Y()*aDirS1.X() +
1484                                                         aDvS1.Y()*aDirS1.Y();
1485                             const Standard_Real aF1z =  aDuS1.Z()*aDirS1.X() +
1486                                                         aDvS1.Z()*aDirS1.Y();
1487                             const Standard_Real aF2x =  aDuS2.X()*aDirS2.X() +
1488                                                         aDvS2.X()*aDirS2.Y();
1489                             const Standard_Real aF2y =  aDuS2.Y()*aDirS2.X() +
1490                                                         aDvS2.Y()*aDirS2.Y();
1491                             const Standard_Real aF2z =  aDuS2.Z()*aDirS2.X() +
1492                                                         aDvS2.Z()*aDirS2.Y();
1493
1494                             const Standard_Real aF1 = aF1x*aF1x + aF1y*aF1y + aF1z*aF1z;
1495                             const Standard_Real aF2 = aF2x*aF2x + aF2y*aF2y + aF2z*aF2z;
1496
1497                             if((aF1 < gp::Resolution()) && (aF2 < gp::Resolution()))
1498                             {
1499                               //All derivative are equal to 0. Therefore, there is
1500                               //no point in going along direction chosen.
1501                               Arrive = Standard_True;
1502                               break;
1503                             }
1504                           }
1505                         }//if (previoustg) cond.
1506
1507                         ////////////////////////////////////////
1508                         AddAPoint(line,previousPoint);
1509                         RejectIndex++;
1510
1511                         if(RejectIndex >= RejectIndexMAX)
1512                         {
1513                           break;
1514                         }
1515
1516                         //
1517
1518                         LevelOfIterWithoutAppend=0;
1519                         Arrive = Standard_True;
1520                       }
1521                       else
1522                       {
1523                         // revert to the last correctly calculated point
1524                         previousPoint = previousPointSave;
1525                         previoustg    = previoustgSave;
1526                         previousd     = previousdSave;
1527                         previousd1    = previousd1Save;
1528                         previousd2    = previousd2Save;
1529                       }
1530                     }
1531
1532                     //
1533                     Standard_Boolean wasExtended = Standard_False;
1534
1535                     if(Arrive && myIntersectionOn2S.IsTangent() && bPrevNotTangent)
1536                     {
1537                       if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1538                       {
1539                         wasExtended = Standard_True;
1540                         Arrive = Standard_False;
1541                         ChoixIso = SauvChoixIso;
1542                       }
1543                     }
1544
1545                     RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1546
1547                     if(Arrive && 
1548                       myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() &&
1549                       myIntersectionOn2S.IsTangent() && bPrevNotTangent &&
1550                       !wasExtended)
1551                     {
1552                       if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1553                       {
1554                         wasExtended = Standard_True;
1555                         Arrive = Standard_False;
1556                         ChoixIso = SauvChoixIso;
1557                       }
1558                     }
1559                   }//else !TestArret() $
1560                 }//$$ end successful framing on border (!myIntersectionOn2S.IsEmpty())
1561                 else
1562                 {
1563                   //echec framing on border; division of step 
1564                   Arrive = Standard_False;
1565                   NoTestDeflection = Standard_True;
1566                   RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1567                 }
1568               }//$$$ end framing on border (!close)
1569             }//004 fin TestArret return Arrive = True
1570           } // 006case IntWalk_ArretSurPoint:  end Processing Status = OK  or ArretSurPoint 
1571         } //007  switch(Status) 
1572       } //008 end processing point  (TEST DEFLECTION)
1573     } //009 end processing line (else if myIntersectionOn2S.IsDone())
1574   }  //010 end if first departure point allows marching  while (!Arrive)
1575
1576   done = Standard_True;
1577 }
1578 // ===========================================================================================================
1579 // function: ExtendLineInCommonZone
1580 // purpose:  Extends already computed line inside tangent zone in the direction given by theChoixIso.
1581 //           Returns Standard_True if the line was extended through tangent zone and the last computed point 
1582 //           is outside the tangent zone (but it is not put into the line). Otherwise returns Standard_False.
1583 // ===========================================================================================================
1584 Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso,
1585                                                           const Standard_Boolean          theDirectionFlag) 
1586 {
1587   Standard_Boolean bOutOfTangentZone = Standard_False;
1588   Standard_Boolean bStop = !myIntersectionOn2S.IsTangent();
1589   Standard_Integer dIncKey = 1;
1590   TColStd_Array1OfReal Param(1,4);
1591   IntWalk_StatusDeflection Status = IntWalk_OK;
1592   Standard_Integer nbIterWithoutAppend = 0;
1593   Standard_Integer nbEqualPoints = 0;
1594   Standard_Integer parit = 0;
1595   Standard_Integer uvit = 0;
1596   IntSurf_SequenceOfPntOn2S aSeqOfNewPoint;
1597
1598   while (!bStop) {
1599     nbIterWithoutAppend++;
1600
1601     if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) {
1602 #ifdef OCCT_DEBUG
1603       cout<<"Infinite loop detected. Stop iterations (IntWalk_PWalking_1.gxx)" << endl;
1604 #endif
1605       bStop = Standard_True;
1606       break;
1607     }
1608     Standard_Real f = 0.;
1609
1610     switch (theChoixIso)
1611     { 
1612     case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
1613     case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
1614     case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
1615     case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
1616     }
1617
1618     if(f<0.1) f=0.1;
1619
1620     previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
1621
1622     Standard_Real dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
1623     Standard_Real dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
1624     Standard_Real dP3 = sensCheminement * pasuv[2] * previousd2.X() /f; 
1625     Standard_Real dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
1626
1627     if(theChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < 1.e-7) dP1 *= (5. * (Standard_Real)dIncKey);
1628     if(theChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < 1.e-7) dP2 *= (5. * (Standard_Real)dIncKey);
1629     if(theChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < 1.e-7) dP3 *= (5. * (Standard_Real)dIncKey);
1630     if(theChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < 1.e-7) dP4 *= (5. * (Standard_Real)dIncKey);
1631
1632     Param(1) += dP1;
1633     Param(2) += dP2;
1634     Param(3) += dP3; 
1635     Param(4) += dP4;
1636     Standard_Real SvParam[4];
1637     IntImp_ConstIsoparametric ChoixIso = theChoixIso;
1638
1639     for(parit = 0; parit < 4; parit++) {
1640       SvParam[parit] = Param(parit+1);
1641     }
1642     math_FunctionSetRoot  Rsnld(myIntersectionOn2S.Function());
1643     ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld, theChoixIso);
1644
1645     if (!myIntersectionOn2S.IsDone()) {
1646       return bOutOfTangentZone;
1647     }
1648     else {
1649       if (myIntersectionOn2S.IsEmpty()) {
1650         return bOutOfTangentZone;
1651       }
1652
1653       Status = TestDeflection();
1654
1655       if(Status == IntWalk_OK) {
1656
1657         for(uvit = 0; uvit < 4; uvit++) {
1658           if(pasuv[uvit] < pasInit[uvit]) {
1659             pasuv[uvit] = pasInit[uvit];
1660           }
1661         }
1662       }
1663
1664       switch(Status) {
1665       case  IntWalk_ArretSurPointPrecedent:
1666         {
1667           bStop = Standard_True;
1668           bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1669           break;
1670         }
1671       case IntWalk_PasTropGrand:
1672         {
1673           for(parit = 0; parit < 4; parit++) {
1674             Param(parit+1) = SvParam[parit];
1675           }
1676           Standard_Boolean bDecrease = Standard_False;
1677
1678           for(uvit = 0; uvit < 4; uvit++) {
1679             if(pasSav[uvit] < pasInit[uvit]) { 
1680               pasInit[uvit] -= (pasInit[uvit] - pasSav[uvit]) * 0.1;
1681               bDecrease = Standard_True;
1682             }
1683           }
1684
1685           if(bDecrease) nbIterWithoutAppend--;
1686           break;
1687         }
1688       case IntWalk_PointConfondu:
1689         {
1690           for(uvit = 0; uvit < 4; uvit++) {
1691             if(pasuv[uvit] < pasInit[uvit]) {
1692               pasuv[uvit] += (pasInit[uvit] - pasuv[uvit]) * 0.1;
1693             }
1694           }
1695           break;
1696         }
1697       case IntWalk_OK:
1698       case IntWalk_ArretSurPoint:
1699         {
1700           //
1701           bStop = TestArret(theDirectionFlag, Param, ChoixIso);
1702           //
1703
1704           //
1705           if(!bStop) {
1706             Standard_Real u11,v11,u12,v12; 
1707             myIntersectionOn2S.Point().Parameters(u11,v11,u12,v12); 
1708             Standard_Real u21,v21,u22,v22;
1709             previousPoint.Parameters(u21,v21,u22,v22); 
1710
1711             if(((fabs(u11-u21) < ResoU1) && (fabs(v11-v21) < ResoV1)) ||
1712               ((fabs(u12-u22) < ResoU2) && (fabs(v12-v22) < ResoV2))) {
1713                 nbEqualPoints++;
1714             }
1715             else {
1716               nbEqualPoints = 0;
1717             }
1718           }
1719           //
1720
1721           bStop = bStop || !myIntersectionOn2S.IsTangent();
1722           bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1723
1724           if(!bStop) {
1725             Standard_Boolean pointisvalid = Standard_False;
1726             Standard_Real u1,v1,u2,v2; 
1727             myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2); 
1728
1729             if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 && 
1730               v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
1731               v1 >= Vm1  && v2 >= Vm2) 
1732               pointisvalid = Standard_True;
1733
1734             if(pointisvalid) {
1735               previousPoint = myIntersectionOn2S.Point();
1736               previoustg = myIntersectionOn2S.IsTangent();
1737
1738               if(!previoustg) {
1739                 previousd  = myIntersectionOn2S.Direction();
1740                 previousd1 = myIntersectionOn2S.DirectionOnS1();
1741                 previousd2 = myIntersectionOn2S.DirectionOnS2();
1742               }
1743               Standard_Boolean bAddPoint = Standard_True;
1744
1745               if(line->NbPoints() >= 1) {
1746                 gp_Pnt pf = line->Value(1).Value();
1747                 gp_Pnt pl = previousPoint.Value(); 
1748
1749                 if(pf.Distance(pl) < Precision::Confusion()) { 
1750                   dIncKey++; 
1751                   if(dIncKey == 5000) return bOutOfTangentZone; 
1752                   else bAddPoint = Standard_False;
1753                 }
1754               }
1755
1756               if(bAddPoint) {
1757                 aSeqOfNewPoint.Append(previousPoint);
1758                 nbIterWithoutAppend = 0;
1759               }
1760             }
1761
1762             if (line->NbPoints() == 2) {
1763               for(uvit = 0; uvit < 4; uvit++) {
1764                 pasSav[uvit] = pasuv[uvit]; 
1765               }
1766             }
1767
1768             if ( !pointisvalid ) {
1769               // decrease step if out of bounds
1770               // otherwise the same calculations will be 
1771               // repeated several times
1772               if ( ( u1 > UM1 ) || ( u1 < Um1 ) )
1773                 pasuv[0] *= 0.5;
1774
1775               if ( ( v1 > VM1 ) || ( v1 < Vm1 ) ) 
1776                 pasuv[1] *= 0.5;
1777
1778               if ( ( u2 > UM2 ) || ( u2 < Um2 ) )
1779                 pasuv[2] *= 0.5;
1780
1781               if ( ( v2 > VM2 ) || ( v2 < Vm2 ) )
1782                 pasuv[3] *= 0.5;
1783             }
1784           } // end if(!bStop)
1785           else { //if(bStop)
1786             if(close && (line->NbPoints() >= 1)) { 
1787
1788               if(!bOutOfTangentZone) {
1789                 aSeqOfNewPoint.Append(line->Value(1)); // line end
1790               }
1791               nbIterWithoutAppend = 0;
1792             }
1793             else {
1794               ChoixIso = myIntersectionOn2S.Perform(Param, Rsnld, theChoixIso);
1795
1796               if(myIntersectionOn2S.IsEmpty()) { 
1797                 bStop = !myIntersectionOn2S.IsTangent();
1798                 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1799               }
1800               else {
1801                 Standard_Boolean bAddPoint = Standard_True;
1802                 Standard_Boolean pointisvalid = Standard_False;
1803
1804                 previousPoint = myIntersectionOn2S.Point();
1805                 Standard_Real u1,v1,u2,v2; 
1806                 previousPoint.Parameters(u1,v1,u2,v2); 
1807
1808                 if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 && 
1809                   v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
1810                   v1 >= Vm1  && v2 >= Vm2) 
1811                   pointisvalid = Standard_True;
1812
1813                 if(pointisvalid) {
1814
1815                   if(line->NbPoints() >= 1) {
1816                     gp_Pnt pf = line->Value(1).Value();
1817                     gp_Pnt pl = previousPoint.Value(); 
1818
1819                     if(pf.Distance(pl) < Precision::Confusion()) { 
1820                       dIncKey++; 
1821                       if(dIncKey == 5000) return bOutOfTangentZone; 
1822                       else bAddPoint = Standard_False;
1823                     }
1824                   }
1825
1826                   if(bAddPoint && !bOutOfTangentZone) {
1827                     aSeqOfNewPoint.Append(previousPoint);
1828                     nbIterWithoutAppend = 0;
1829                   }
1830                 }
1831               }
1832             }
1833           }
1834           break;
1835         }
1836       default:
1837         {
1838           break;
1839         }
1840       }
1841     }
1842   }
1843   Standard_Boolean bExtendLine = Standard_False;
1844   Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.; 
1845
1846   Standard_Integer pit = 0;
1847
1848   for(pit = 0; !bExtendLine && (pit < 2); pit++) {
1849     if(pit == 0)
1850       previousPoint.Parameters(u1,v1,u2,v2); 
1851     else {
1852       if(aSeqOfNewPoint.Length() > 0)
1853         aSeqOfNewPoint.Value(aSeqOfNewPoint.Length()).Parameters(u1,v1,u2,v2); 
1854       else
1855         break;
1856     }
1857
1858     if(((u1 - Um1) < ResoU1) ||
1859       ((UM1 - u1) < ResoU1) ||
1860       ((u2 - Um2) < ResoU2) ||
1861       ((UM2 - u2) < ResoU2) ||
1862       ((v1 - Vm1) < ResoV1) ||
1863       ((VM1 - v1) < ResoV1) ||
1864       ((v2 - Vm2) < ResoV2) ||
1865       ((VM2 - v2) < ResoV2))
1866       bExtendLine = Standard_True;
1867   }
1868
1869   if(!bExtendLine) {
1870     //    if(Status == IntWalk_OK || Status == IntWalk_ArretSurPoint) {
1871     if(Status == IntWalk_OK) {
1872       bExtendLine = Standard_True;
1873
1874       if(aSeqOfNewPoint.Length() > 1) {
1875         TColStd_Array1OfReal FirstParams(0, 3), LastParams(0, 3), Resolutions(0, 3);
1876         Resolutions(0) = ResoU1; Resolutions(1) = ResoV1; Resolutions(2) = ResoU2; Resolutions(3) = ResoV2;
1877
1878         aSeqOfNewPoint(1).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1879           FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1880         aSeqOfNewPoint(aSeqOfNewPoint.Length()).Parameters(LastParams.ChangeValue(0), 
1881           LastParams.ChangeValue(1),
1882           LastParams.ChangeValue(2), 
1883           LastParams.ChangeValue(3)); 
1884         Standard_Integer indexofiso = 0;
1885
1886         if(theChoixIso == IntImp_UIsoparametricOnCaro1) indexofiso = 0;
1887         if(theChoixIso == IntImp_VIsoparametricOnCaro1) indexofiso = 1;
1888         if(theChoixIso == IntImp_UIsoparametricOnCaro2) indexofiso = 2;
1889         if(theChoixIso == IntImp_VIsoparametricOnCaro2) indexofiso = 3;
1890
1891         Standard_Integer afirstindex = (indexofiso < 2) ? 0 : 2;
1892         gp_Vec2d aTangentZoneDir(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)),
1893           gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1)));
1894
1895         gp_Dir2d anIsoDir(0, 1);
1896
1897         if((indexofiso == 1) || (indexofiso == 3))
1898           anIsoDir = gp_Dir2d(1, 0);
1899
1900         if(aTangentZoneDir.SquareMagnitude() > gp::Resolution()) {
1901           Standard_Real piquota = M_PI*0.25;
1902
1903           if(fabs(aTangentZoneDir.Angle(anIsoDir)) > piquota) {
1904             Standard_Integer ii = 1, nextii = 2;
1905             gp_Vec2d d1(0, 0);
1906             Standard_Real asqresol = gp::Resolution();
1907             asqresol *= asqresol;
1908
1909             do {
1910               aSeqOfNewPoint(ii).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1911                 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1912               aSeqOfNewPoint(ii + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1913                 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1914               d1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1915                 FirstParams.Value(afirstindex + 1)),
1916                 gp_Pnt2d(LastParams.Value(afirstindex),
1917                 LastParams.Value(afirstindex + 1)));
1918               ii++;
1919             }
1920             while((d1.SquareMagnitude() < asqresol) &&
1921               (ii < aSeqOfNewPoint.Length()));
1922
1923             nextii = ii;
1924
1925             while(nextii < aSeqOfNewPoint.Length()) {
1926
1927               gp_Vec2d nextd1(0, 0);
1928               Standard_Integer jj = nextii;
1929
1930               do {
1931                 aSeqOfNewPoint(jj).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1932                   FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1933                 aSeqOfNewPoint(jj + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1934                   LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1935                 nextd1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1936                   FirstParams.Value(afirstindex + 1)),
1937                   gp_Pnt2d(LastParams.Value(afirstindex),
1938                   LastParams.Value(afirstindex + 1)));
1939                 jj++;
1940
1941               }
1942               while((nextd1.SquareMagnitude() < asqresol) &&
1943                 (jj < aSeqOfNewPoint.Length()));
1944               nextii = jj;
1945
1946               if(fabs(d1.Angle(nextd1)) > piquota) {
1947                 bExtendLine = Standard_False;
1948                 break;
1949               }
1950               d1 = nextd1;
1951             }
1952           }
1953           // end if(fabs(aTangentZoneDir.Angle(anIsoDir)
1954         }
1955       }
1956     }
1957   }
1958
1959   if(!bExtendLine) {
1960     return Standard_False;
1961   }
1962   Standard_Integer i = 0;
1963
1964   for(i = 1; i <= aSeqOfNewPoint.Length(); i++) {
1965     AddAPoint(line, aSeqOfNewPoint.Value(i));
1966   }
1967
1968   return bOutOfTangentZone;
1969 }
1970
1971 //=======================================================================
1972 //function : DistanceMinimizeByGradient
1973 //purpose  : 
1974 //=======================================================================
1975 Standard_Boolean IntWalk_PWalking::
1976 DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
1977                            const Handle(Adaptor3d_HSurface)& theASurf2,
1978                            Standard_Real& theU1,
1979                            Standard_Real& theV1,
1980                            Standard_Real& theU2,
1981                            Standard_Real& theV2,
1982                            const Standard_Real theStep0U1V1,
1983                            const Standard_Real theStep0U2V2)
1984 {
1985   const Standard_Integer aNbIterMAX = 60;
1986   const Standard_Real aTol = 1.0e-14;
1987   Handle(Geom_Surface) aS1, aS2;
1988
1989   if (theASurf1->GetType() != GeomAbs_BezierSurface &&
1990       theASurf1->GetType() != GeomAbs_BSplineSurface)
1991       return Standard_True;
1992   if (theASurf2->GetType() != GeomAbs_BezierSurface &&
1993       theASurf2->GetType() != GeomAbs_BSplineSurface)
1994       return Standard_True;
1995
1996   Standard_Boolean aStatus = Standard_False;
1997
1998   gp_Pnt aP1, aP2;
1999   gp_Vec aD1u, aD1v, aD2U, aD2V;
2000
2001   theASurf1->D1(theU1, theV1, aP1, aD1u, aD1v);
2002   theASurf2->D1(theU2, theV2, aP2, aD2U, aD2V);
2003
2004   Standard_Real aSQDistPrev = aP1.SquareDistance(aP2);
2005
2006   gp_Vec aP12(aP1, aP2);
2007
2008   Standard_Real aGradFu(-aP12.Dot(aD1u));
2009   Standard_Real aGradFv(-aP12.Dot(aD1v));
2010   Standard_Real aGradFU( aP12.Dot(aD2U));
2011   Standard_Real aGradFV( aP12.Dot(aD2V));
2012
2013   Standard_Real aSTEPuv = theStep0U1V1, aStepUV = theStep0U2V2;
2014
2015   Standard_Boolean flRepeat = Standard_True;
2016   Standard_Integer aNbIter = aNbIterMAX;
2017
2018   while(flRepeat)
2019   {
2020     Standard_Real anAdd = aGradFu*aSTEPuv;
2021     Standard_Real aPARu = (anAdd >= 0.0)?
2022       (theU1 - Max(anAdd, Epsilon(theU1))) :
2023     (theU1 + Max(-anAdd, Epsilon(theU1)));
2024     anAdd = aGradFv*aSTEPuv;
2025     Standard_Real aPARv = (anAdd >= 0.0)?
2026       (theV1 - Max(anAdd, Epsilon(theV1))) :
2027     (theV1 + Max(-anAdd, Epsilon(theV1)));
2028     anAdd = aGradFU*aStepUV;
2029     Standard_Real aParU = (anAdd >= 0.0)?
2030       (theU2 - Max(anAdd, Epsilon(theU2))) :
2031     (theU2 + Max(-anAdd, Epsilon(theU2)));
2032     anAdd = aGradFV*aStepUV;
2033     Standard_Real aParV = (anAdd >= 0.0)?
2034       (theV2 - Max(anAdd, Epsilon(theV2))) :
2035     (theV2 + Max(-anAdd, Epsilon(theV2)));
2036
2037     gp_Pnt aPt1, aPt2;
2038
2039     theASurf1->D1(aPARu, aPARv, aPt1, aD1u, aD1v);
2040     theASurf2->D1(aParU, aParV, aPt2, aD2U, aD2V);
2041
2042     Standard_Real aSQDist = aPt1.SquareDistance(aPt2);
2043
2044     if(aSQDist < aSQDistPrev)
2045     {
2046       aSQDistPrev = aSQDist;
2047       theU1 = aPARu;
2048       theV1 = aPARv;
2049       theU2 = aParU;
2050       theV2 = aParV;
2051
2052       aStatus = aSQDistPrev < aTol;
2053       aSTEPuv *= 1.2;
2054       aStepUV *= 1.2;
2055     }
2056     else
2057     {
2058       if(--aNbIter < 0)
2059       {
2060         flRepeat = Standard_False;
2061       }
2062       else
2063       {
2064         theASurf1->D1(theU1, theV1, aPt1, aD1u, aD1v);
2065         theASurf2->D1(theU2, theV2, aPt2, aD2U, aD2V);
2066
2067         gp_Vec aP12(aPt1, aPt2);
2068         aGradFu = -aP12.Dot(aD1u);
2069         aGradFv = -aP12.Dot(aD1v);
2070         aGradFU = aP12.Dot(aD2U);
2071         aGradFV = aP12.Dot(aD2V);
2072         aSTEPuv = theStep0U1V1;
2073         aStepUV = theStep0U2V2;
2074       }
2075     }
2076   }
2077
2078   return aStatus;
2079 }
2080
2081 //=======================================================================
2082 //function : DistanceMinimizeByExtrema
2083 //purpose  : 
2084 //=======================================================================
2085 Standard_Boolean IntWalk_PWalking::
2086 DistanceMinimizeByExtrema(const Handle(Adaptor3d_HSurface)& theASurf, 
2087                           const gp_Pnt& theP0,
2088                           Standard_Real& theU0,
2089                           Standard_Real& theV0,
2090                           const Standard_Real theStep0U,
2091                           const Standard_Real theStep0V)
2092 {
2093   const Standard_Real aTol = 1.0e-14;
2094   gp_Pnt aPS;
2095   gp_Vec aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp;
2096   Standard_Real aSQDistPrev = RealLast();
2097   Standard_Real aU = theU0, aV = theV0;
2098
2099   Standard_Integer aNbIter = 10;
2100   do
2101   {
2102     theASurf->D2(aU, aV, aPS, aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp);
2103
2104     gp_Vec aVec(theP0, aPS);
2105
2106     Standard_Real aSQDist = aVec.SquareMagnitude();
2107
2108     if(aSQDist >= aSQDistPrev)
2109       break;
2110
2111     aSQDistPrev = aSQDist;
2112     theU0 = aU;
2113     theV0 = aV;
2114     aNbIter--;
2115
2116     if(aSQDistPrev < aTol)
2117       break;
2118
2119     //Functions
2120     const Standard_Real aF1 = aD1Su.Dot(aVec), aF2 = aD1Sv.Dot(aVec);
2121
2122     //Derivatives
2123     const Standard_Real aDf1u = aD2Su.Dot(aVec) + aD1Su.Dot(aD1Su),
2124       aDf1v = aD2Su.Dot(aD1Sv),
2125       aDf2u = aDf1v,
2126       aDf2v = aD2Sv.Dot(aVec) + aD1Sv.Dot(aD1Sv);
2127
2128     const Standard_Real aDet = aDf1u*aDf2v - aDf1v*aDf2u;
2129     aU -= theStep0U*(aDf2v*aF1 - aDf1v*aF2)/aDet;
2130     aV += theStep0V*(aDf2u*aF1 - aDf1u*aF2)/aDet;
2131   }
2132   while(aNbIter > 0);
2133
2134   return (aSQDistPrev < aTol);
2135 }
2136
2137 //=======================================================================
2138 //function : SeekPointOnBoundary
2139 //purpose  : 
2140 //=======================================================================
2141 Standard_Boolean IntWalk_PWalking::
2142 SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
2143                     const Handle(Adaptor3d_HSurface)& theASurf2,
2144                     const Standard_Real theU1,
2145                     const Standard_Real theV1,
2146                     const Standard_Real theU2,
2147                     const Standard_Real theV2,
2148                     const Standard_Boolean isTheFirst)
2149 {
2150   const Standard_Real aTol = 1.0e-14;
2151   Standard_Boolean isOK = Standard_False;
2152   Standard_Real U1prec = theU1, V1prec = theV1, U2prec = theU2, V2prec = theV2;
2153
2154   Standard_Boolean flFinish = Standard_False;
2155
2156   Standard_Integer aNbIter = 20;
2157   while(!flFinish)
2158   {
2159     flFinish = Standard_False;
2160     Standard_Boolean aStatus = Standard_False;
2161
2162     do
2163     {
2164       aNbIter--;
2165       aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec);
2166       if(aStatus)
2167       {
2168         break;
2169       }
2170
2171       aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec);
2172       if(aStatus)
2173       {
2174         break;
2175       }
2176
2177       aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec);
2178       if(aStatus)
2179       {
2180         break;
2181       }
2182     }
2183     while(!aStatus && (aNbIter > 0));
2184
2185     if(aStatus)
2186     {
2187       const Standard_Real aTolMax = 1.0e-8;
2188       Standard_Real aTolF = 0.0;
2189
2190       Standard_Real u1 = U1prec, v1 = V1prec, u2 = U2prec, v2 = V2prec;
2191
2192       flFinish = Checking(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec, aTolF);
2193
2194       if(aTolF <= aTolMax)
2195       {
2196         gp_Pnt  aP1 = theASurf1->Value(u1, v1),
2197           aP2 = theASurf2->Value(u2, v2);
2198         gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2199
2200         const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
2201           aSQDist2 = aPInt.SquareDistance(aP2);
2202         if((aSQDist1 < aTol) && (aSQDist2 < aTol))
2203         {
2204           IntSurf_PntOn2S anIP;
2205           anIP.SetValue(aPInt, u1, v1, u2, v2);
2206
2207           if(isTheFirst)
2208             line->InsertBefore(1,anIP);
2209           else
2210             line->Add(anIP);
2211
2212           isOK = Standard_True;
2213         }
2214       }
2215     }
2216     else
2217     {
2218       break;
2219     }
2220
2221     if(aNbIter < 0)
2222       break;
2223   }
2224
2225   return isOK;
2226 }
2227
2228 //=======================================================================
2229 //function : PutToBoundary
2230 //purpose  : 
2231 //=======================================================================
2232 Standard_Boolean IntWalk_PWalking::
2233 PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
2234               const Handle(Adaptor3d_HSurface)& theASurf2)
2235 {
2236   const Standard_Real aTolMin = Precision::Confusion();
2237
2238   Standard_Boolean hasBeenAdded = Standard_False;
2239
2240   const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2241   const Standard_Real aU1bLast = theASurf1->LastUParameter();
2242   const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2243   const Standard_Real aU2bLast = theASurf2->LastUParameter();
2244   const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2245   const Standard_Real aV1bLast = theASurf1->LastVParameter();
2246   const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2247   const Standard_Real aV2bLast = theASurf2->LastVParameter();
2248
2249   Standard_Real aTol = 1.0;
2250   aTol = Min(aTol, aU1bLast - aU1bFirst);
2251   aTol = Min(aTol, aU2bLast - aU2bFirst);
2252   aTol = Min(aTol, aV1bLast - aV1bFirst);
2253   aTol = Min(aTol, aV2bLast - aV2bFirst)*1.0e-3;
2254
2255   if(aTol <= 2.0*aTolMin)
2256     return hasBeenAdded;
2257
2258   Standard_Boolean isNeedAdding = Standard_False;
2259   Standard_Boolean isU1parallel = Standard_False, isV1parallel = Standard_False;
2260   Standard_Boolean isU2parallel = Standard_False, isV2parallel = Standard_False;
2261   IsParallel(line, Standard_True, aTol, isU1parallel, isV1parallel);
2262   IsParallel(line, Standard_False, aTol, isU2parallel, isV2parallel);
2263
2264   Standard_Real u1, v1, u2, v2;
2265   line->Value(1).Parameters(u1, v1, u2, v2);
2266   Standard_Real aDelta = 0.0;
2267
2268   if(!isV1parallel)
2269   {
2270     aDelta = u1 - aU1bFirst;
2271     if((aTolMin < aDelta) && (aDelta < aTol))
2272     {
2273       u1 = aU1bFirst - aDelta;
2274       isNeedAdding = Standard_True;
2275     }
2276     else
2277     {
2278       aDelta = aU1bLast - u1;
2279       if((aTolMin < aDelta) && (aDelta < aTol))
2280       {
2281         u1 = aU1bLast + aDelta;
2282         isNeedAdding = Standard_True;
2283       }
2284     }
2285   }
2286
2287   if(!isV2parallel)
2288   {
2289     aDelta = u2 - aU2bFirst;
2290     if((aTolMin < aDelta) && (aDelta < aTol))
2291     {
2292       u2 = aU2bFirst - aDelta;
2293       isNeedAdding = Standard_True;
2294     }
2295     else
2296     {
2297       aDelta = aU2bLast - u2;
2298       if((aTolMin < aDelta) && (aDelta < aTol))
2299       {
2300         u2 = aU2bLast + aDelta;
2301         isNeedAdding = Standard_True;
2302       }
2303     }
2304   }
2305
2306   if(!isU1parallel)
2307   {
2308     aDelta = v1 - aV1bFirst;
2309     if((aTolMin < aDelta) && (aDelta < aTol))
2310     {
2311       v1 = aV1bFirst - aDelta;
2312       isNeedAdding = Standard_True;
2313     }
2314     else
2315     {
2316       aDelta = aV1bLast - v1;
2317       if((aTolMin < aDelta) && (aDelta < aTol))
2318       {
2319         v1 = aV1bLast + aDelta;
2320         isNeedAdding = Standard_True;
2321       }
2322     }
2323   }
2324
2325   if(!isU2parallel)
2326   {
2327     aDelta = v2 - aV2bFirst;
2328     if((aTolMin < aDelta) && (aDelta < aTol))
2329     {
2330       v2 = aV2bFirst - aDelta;
2331       isNeedAdding = Standard_True;
2332     }
2333     else
2334     {
2335       aDelta = aV2bLast - v2;
2336       if((aTolMin < aDelta) && (aDelta < aTol))
2337       {
2338         v2 = aV2bLast + aDelta;
2339         isNeedAdding = Standard_True;
2340       }
2341     }
2342   }
2343
2344   if(isNeedAdding)
2345   {
2346     hasBeenAdded = 
2347       SeekPointOnBoundary(theASurf1, theASurf2, u1, 
2348       v1, u2, v2, Standard_True);
2349   }
2350
2351   const Standard_Integer aNbPnts = line->NbPoints();
2352   isNeedAdding = Standard_False;
2353   line->Value(aNbPnts).Parameters(u1, v1, u2, v2);
2354
2355   if(!isV1parallel)
2356   {
2357     aDelta = u1 - aU1bFirst;
2358     if((aTolMin < aDelta) && (aDelta < aTol))
2359     {
2360       u1 = aU1bFirst - aDelta;
2361       isNeedAdding = Standard_True;
2362     }
2363     else
2364     {
2365       aDelta = aU1bLast - u1;
2366       if((aTolMin < aDelta) && (aDelta < aTol))
2367       {
2368         u1 = aU1bLast + aDelta;
2369         isNeedAdding = Standard_True;
2370       }
2371     }
2372   }
2373
2374   if(!isV2parallel)
2375   {
2376     aDelta = u2 - aU2bFirst;
2377     if((aTolMin < aDelta) && (aDelta < aTol))
2378     {
2379       u2 = aU2bFirst - aDelta;
2380       isNeedAdding = Standard_True;
2381     }
2382     else
2383     {
2384       aDelta = aU2bLast - u2;
2385       if((aTolMin < aDelta) && (aDelta < aTol))
2386       {
2387         u2 = aU2bLast + aDelta;
2388         isNeedAdding = Standard_True;
2389       }
2390     }
2391   }
2392
2393   if(!isU1parallel)
2394   {
2395     aDelta = v1 - aV1bFirst;
2396     if((aTolMin < aDelta) && (aDelta < aTol))
2397     {
2398       v1 = aV1bFirst - aDelta;
2399       isNeedAdding = Standard_True;
2400     }
2401     else
2402     {
2403       aDelta = aV1bLast - v1;
2404       if((aTolMin < aDelta) && (aDelta < aTol))
2405       {
2406         v1 = aV1bLast + aDelta;
2407         isNeedAdding = Standard_True;
2408       }
2409     }
2410   }
2411
2412   if(!isU2parallel)
2413   {
2414     aDelta = v2 - aV2bFirst;
2415     if((aTolMin < aDelta) && (aDelta < aTol))
2416     {
2417       v2 = aV2bFirst - aDelta;
2418       isNeedAdding = Standard_True;
2419     }
2420     else
2421     {
2422       aDelta = aV2bLast - v2;
2423       if((aTolMin < aDelta) && (aDelta < aTol))
2424       {
2425         v2 = aV2bLast + aDelta;
2426         isNeedAdding = Standard_True;
2427       }
2428     }
2429   }
2430
2431   if(isNeedAdding)
2432   {
2433     hasBeenAdded = 
2434       SeekPointOnBoundary(theASurf1, theASurf2, u1, 
2435       v1, u2, v2, Standard_False);
2436   }
2437
2438   return hasBeenAdded;
2439 }
2440
2441 //=======================================================================
2442 //function : SeekAdditionalPoints
2443 //purpose  : 
2444 //=======================================================================
2445 Standard_Boolean IntWalk_PWalking::
2446 SeekAdditionalPoints( const Handle(Adaptor3d_HSurface)& theASurf1,
2447                      const Handle(Adaptor3d_HSurface)& theASurf2,
2448                      const Standard_Integer theMinNbPoints)
2449 {
2450   const Standard_Real aTol = 1.0e-14;
2451   Standard_Integer aNbPoints = line->NbPoints();
2452   if(aNbPoints > theMinNbPoints)
2453     return Standard_True;
2454
2455   const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2456   const Standard_Real aU1bLast = theASurf1->LastUParameter();
2457   const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2458   const Standard_Real aU2bLast = theASurf2->LastUParameter();
2459   const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2460   const Standard_Real aV1bLast = theASurf1->LastVParameter();
2461   const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2462   const Standard_Real aV2bLast = theASurf2->LastVParameter();
2463
2464
2465   Standard_Boolean isPrecise = Standard_False;
2466
2467   Standard_Real U1prec = 0.0, V1prec = 0.0, U2prec = 0.0, V2prec = 0.0;
2468
2469   Standard_Integer aNbPointsPrev = 0;
2470   while(aNbPoints < theMinNbPoints && (aNbPoints != aNbPointsPrev))
2471   {
2472     aNbPointsPrev = aNbPoints;
2473     for(Standard_Integer fp = 1, lp = 2; fp < aNbPoints; fp = lp + 1)
2474     {
2475       Standard_Real U1f, V1f, U2f, V2f; //first point in 1st and 2nd surafaces
2476       Standard_Real U1l, V1l, U2l, V2l; //last  point in 1st and 2nd surafaces
2477
2478       lp = fp+1;
2479       line->Value(fp).Parameters(U1f, V1f, U2f, V2f);
2480       line->Value(lp).Parameters(U1l, V1l, U2l, V2l);
2481
2482       U1prec = 0.5*(U1f+U1l);
2483       if(U1prec < aU1bFirst)
2484         U1prec = aU1bFirst;
2485       if(U1prec > aU1bLast)
2486         U1prec = aU1bLast;
2487
2488       V1prec = 0.5*(V1f+V1l);
2489       if(V1prec < aV1bFirst)
2490         V1prec = aV1bFirst;
2491       if(V1prec > aV1bLast)
2492         V1prec = aV1bLast;
2493
2494       U2prec = 0.5*(U2f+U2l);
2495       if(U2prec < aU2bFirst)
2496         U2prec = aU2bFirst;
2497       if(U2prec > aU2bLast)
2498         U2prec = aU2bLast;
2499
2500       V2prec = 0.5*(V2f+V2l);
2501       if(V2prec < aV2bFirst)
2502         V2prec = aV2bFirst;
2503       if(V2prec > aV2bLast)
2504         V2prec = aV2bLast;
2505
2506       Standard_Boolean aStatus = Standard_False;
2507       Standard_Integer aNbIter = 5;
2508       do
2509       {
2510         aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec);
2511         if(aStatus)
2512         {
2513           break;
2514         }
2515
2516         aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec);
2517         if(aStatus)
2518         {
2519           break;
2520         }
2521
2522         aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec);
2523         if(aStatus)
2524         {
2525           break;
2526         }
2527       }
2528       while(!aStatus && (--aNbIter > 0));
2529
2530       if(aStatus)
2531       {
2532         gp_Pnt  aP1 = theASurf1->Value(U1prec, V1prec),
2533           aP2 = theASurf2->Value(U2prec, V2prec);
2534         gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2535
2536         const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
2537           aSQDist2 = aPInt.SquareDistance(aP2);
2538
2539         if((aSQDist1 < aTol) && (aSQDist2 < aTol))
2540         {
2541           IntSurf_PntOn2S anIP;
2542           anIP.SetValue(aPInt, U1prec, V1prec, U2prec, V2prec);
2543           line->InsertBefore(lp, anIP);
2544
2545           isPrecise = Standard_True;
2546
2547           if(++aNbPoints >= theMinNbPoints)
2548             break;
2549         }
2550         else
2551         {
2552           lp--;
2553         }
2554       }
2555     }
2556   }
2557
2558   return isPrecise;
2559 }
2560
2561 void IntWalk_PWalking::
2562 RepartirOuDiviser(Standard_Boolean& DejaReparti,
2563                   IntImp_ConstIsoparametric& ChoixIso,
2564                   Standard_Boolean& Arrive) 
2565
2566                   // at the neighborhood of a point, there is a fail of marching 
2567                   // it is required to divide the steps to try to continue
2568                   // if the step is too small if we are on border
2569                   // restart in another direction if it was not done, otherwise stop
2570
2571 {
2572   //  Standard_Integer i;
2573   if (Arrive) {    //restart in the other direction
2574     if (!DejaReparti ) {
2575       Arrive        = Standard_False; 
2576       DejaReparti   = Standard_True;
2577       previousPoint = line->Value(1);
2578       previoustg    = Standard_False;
2579       previousd1    = firstd1;
2580       previousd2    = firstd2;
2581       previousd     = tgdir;
2582       indextg       = line->NbPoints();
2583       tgdir.Reverse();
2584       line->Reverse();
2585
2586       //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg);
2587       sensCheminement = -1;
2588       tgfirst      = tglast;
2589       tglast       = Standard_False;
2590       ChoixIso     = choixIsoSav;
2591 #if 0
2592       pasuv[0]=pasSav[0];
2593       pasuv[1]=pasSav[1];
2594       pasuv[2]=pasSav[2];
2595       pasuv[3]=pasSav[3];
2596 #else 
2597       Standard_Real u1,v1,u2,v2;
2598       Standard_Real U1,V1,U2,V2;
2599       Standard_Integer nn=line->NbPoints();
2600       if(nn>2) { 
2601         line->Value(nn).Parameters(u1,v1,u2,v2);
2602         line->Value(nn-1).Parameters(U1,V1,U2,V2);
2603         pasuv[0]=Abs(u1-U1);
2604         pasuv[1]=Abs(v1-V1);
2605         pasuv[2]=Abs(u2-U2);
2606         pasuv[3]=Abs(v2-V2);
2607       }
2608 #endif
2609
2610     }
2611   }  
2612   else  {
2613     if (    pasuv[0]*0.5 < ResoU1
2614       &&  pasuv[1]*0.5 < ResoV1
2615       &&  pasuv[2]*0.5 < ResoU2
2616       &&  pasuv[3]*0.5 < ResoV2
2617       ) {
2618         if (!previoustg) {
2619           tglast = Standard_True;      // IS IT ENOUGH ????
2620         }
2621
2622         if (!DejaReparti) {  //restart in the other direction
2623           DejaReparti       = Standard_True;
2624           previousPoint     = line->Value(1);
2625           previoustg        = Standard_False;
2626           previousd1        = firstd1;
2627           previousd2        = firstd2;
2628           previousd         = tgdir;
2629           indextg           = line->NbPoints();
2630           tgdir.Reverse();
2631           line->Reverse();
2632
2633           //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg);
2634
2635           sensCheminement   = -1;
2636           tgfirst           = tglast;
2637           tglast            = Standard_False;
2638           ChoixIso          = choixIsoSav;
2639
2640 #if 0 
2641           pasuv[0]=pasSav[0];
2642           pasuv[1]=pasSav[1];
2643           pasuv[2]=pasSav[2];
2644           pasuv[3]=pasSav[3];
2645 #else 
2646           Standard_Real u1,v1,u2,v2;
2647           Standard_Real U1,V1,U2,V2;
2648           Standard_Integer nn=line->NbPoints();
2649           if(nn>2) { 
2650             line->Value(nn).Parameters(u1,v1,u2,v2);
2651             line->Value(nn-1).Parameters(U1,V1,U2,V2);
2652             pasuv[0]=Abs(u1-U1);
2653             pasuv[1]=Abs(v1-V1);
2654             pasuv[2]=Abs(u2-U2);
2655             pasuv[3]=Abs(v2-V2);
2656           }
2657 #endif
2658         }
2659         else Arrive = Standard_True;
2660     }
2661     else {
2662       pasuv[0]*=0.5;
2663       pasuv[1]*=0.5;
2664       pasuv[2]*=0.5;
2665       pasuv[3]*=0.5; 
2666     }
2667   }
2668 }
2669
2670 namespace {
2671   //OCC431(apo): modified ->
2672   static const Standard_Real CosRef2D =  Cos(M_PI/9.0),  AngRef2D = M_PI/2.0; 
2673
2674   static const Standard_Real d = 7.0;
2675 }
2676
2677 IntWalk_StatusDeflection  IntWalk_PWalking::TestDeflection()
2678
2679 // test if vector is observed by calculating an increase of vector 
2680 //     or the previous point and its tangent, the new calculated point and its  
2681 //     tangent; it is possible to find a cube passing by the 2 points and having as a 
2682 //     derivative the tangents of the intersection
2683 //     calculate the point with parameter 0.5 on cube=p1 
2684 //     calculate the medium point of 2 points of intersection=p2
2685 //   if arrow/2<=||p1p2||<= arrow consider that the vector is observed
2686 //   otherwise adjust the step depending on the ratio ||p1p2||/vector
2687 //   and the previous step 
2688 // test if in  2 tangent planes of surfaces there is no too great angle2d 
2689 // grand : if yes divide the step
2690 // test if there is no change of side
2691 //  
2692 {
2693   if(line->NbPoints() ==1 ) { 
2694     STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=STATIC_PRECEDENT_INFLEXION=0;
2695   }
2696
2697   IntWalk_StatusDeflection Status = IntWalk_OK;
2698   Standard_Real FlecheCourante ,Ratio;
2699
2700
2701   const IntSurf_PntOn2S& CurrentPoint = myIntersectionOn2S.Point(); 
2702   //==================================================================================
2703   //=========               S t o p   o n   p o i n t                 ============
2704   //================================================================================== 
2705   if (myIntersectionOn2S.IsTangent())  { 
2706     return IntWalk_ArretSurPoint;  
2707   }
2708
2709   const gp_Dir& TgCourante = myIntersectionOn2S.Direction();
2710
2711   //==================================================================================
2712   //=========   R i s k   o f    i n f l e x i o n   p o i n t  ============
2713   //==================================================================================  
2714   if (TgCourante.Dot(previousd)<0) {
2715     //------------------------------------------------------------
2716     //-- Risk of inflexion point : Divide the step by 2
2717     //-- Initialize STATIC_PRECEDENT_INFLEXION so that 
2718     //-- at the next call to return Pas_OK if there is no 
2719     //-- more risk of the point of inflexion
2720     //------------------------------------------------------------
2721
2722     pasuv[0]*=0.5;
2723     pasuv[1]*=0.5;
2724     pasuv[2]*=0.5;
2725     pasuv[3]*=0.5;
2726     STATIC_PRECEDENT_INFLEXION+=3; 
2727     if (pasuv[0] < ResoU1 && pasuv[1] <ResoV1 && pasuv[2] <ResoU2 && pasuv[3] < ResoV2)
2728       return IntWalk_ArretSurPointPrecedent;
2729     else 
2730       return IntWalk_PasTropGrand;
2731   }
2732
2733   else {
2734     if(STATIC_PRECEDENT_INFLEXION  > 0) { 
2735       STATIC_PRECEDENT_INFLEXION -- ;
2736       return IntWalk_OK;
2737     }
2738   }
2739
2740   //==================================================================================
2741   //=========  D e t e c t    c o n f u s e d    P o in t s       ===========
2742   //==================================================================================
2743
2744   Standard_Real Dist = previousPoint.Value().
2745     SquareDistance(CurrentPoint.Value());
2746
2747
2748   if (Dist < tolconf*tolconf ) { 
2749     pasuv[0] = Max(5.*ResoU1,Min(1.5*pasuv[0],pasInit[0]));
2750     pasuv[1] = Max(5.*ResoV1,Min(1.5*pasuv[1],pasInit[1]));
2751     pasuv[2] = Max(5.*ResoU2,Min(1.5*pasuv[2],pasInit[2]));
2752     pasuv[3] = Max(5.*ResoV2,Min(1.5*pasuv[3],pasInit[3]));
2753     Status = IntWalk_PointConfondu;
2754   }
2755
2756   //==================================================================================
2757   Standard_Real Up1,Vp1,Uc1,Vc1,Du1,Dv1,AbsDu1,AbsDu2,AbsDv1,AbsDv2;
2758   Standard_Real Up2,Vp2,Uc2,Vc2,Du2,Dv2;
2759
2760   previousPoint.Parameters(Up1,Vp1,Up2,Vp2);
2761   CurrentPoint.Parameters(Uc1,Vc1,Uc2,Vc2);               
2762
2763   Du1 = Uc1 - Up1;   Dv1 = Vc1 - Vp1;
2764   Du2 = Uc2 - Up2;   Dv2 = Vc2 - Vp2;
2765
2766   AbsDu1 = Abs(Du1);
2767   AbsDu2 = Abs(Du2);
2768   AbsDv1 = Abs(Dv1);
2769   AbsDv2 = Abs(Dv2);
2770   //=================================================================================
2771   //====   S t e p   o f   p  r o g r e s s i o n (between previous and Current)   =======
2772   //=================================================================================
2773   if (   AbsDu1 < ResoU1 && AbsDv1 < ResoV1 
2774     && AbsDu2 < ResoU2 && AbsDv2 < ResoV2) {
2775       pasuv[0] = ResoU1; pasuv[1] = ResoV1; pasuv[2] = ResoU2; pasuv[3] = ResoV2;
2776       return(IntWalk_ArretSurPointPrecedent);
2777   }
2778   //==================================================================================
2779
2780   Standard_Real tolArea = 100.0;
2781   if (ResoU1 < Precision::PConfusion() ||
2782     ResoV1 < Precision::PConfusion() ||
2783     ResoU2 < Precision::PConfusion() ||
2784     ResoV2 < Precision::PConfusion() )
2785     tolArea =  tolArea*2.0;
2786
2787   Standard_Real Cosi1, CosRef1, Ang1, AngRef1, ResoUV1, Duv1, d1, tolCoeff1;   
2788   Standard_Real Cosi2, CosRef2, Ang2, AngRef2, ResoUV2, Duv2, d2, tolCoeff2;   
2789   Cosi1 = Du1*previousd1.X() + Dv1*previousd1.Y();
2790   Cosi2 = Du2*previousd2.X() + Dv2*previousd2.Y();
2791   Duv1 = Du1*Du1 + Dv1*Dv1;
2792   Duv2 = Du2*Du2 + Dv2*Dv2;
2793   ResoUV1 = ResoU1*ResoU1 + ResoV1*ResoV1;
2794   ResoUV2 = ResoU2*ResoU2 + ResoV2*ResoV2;
2795   //
2796   //modified by NIZNHY-PKV Wed Nov 13 12:25:44 2002 f
2797   //
2798   Standard_Real aMinDiv2=Precision::Confusion();
2799   aMinDiv2=aMinDiv2*aMinDiv2;
2800   //
2801   d1=d;
2802   if (Duv1>aMinDiv2)  {
2803     d1 = Abs(ResoUV1/Duv1);
2804     d1 = Min(Sqrt(d1)*tolArea, d);  
2805   } 
2806   //d1 = Abs(ResoUV1/Duv1); 
2807   //d1 = Min(Sqrt(d1)*tolArea,d);  
2808   //modified by NIZNHY-PKV Wed Nov 13 12:34:30 2002 t
2809   tolCoeff1 = Exp(d1);
2810   //
2811   //modified by NIZNHY-PKV Wed Nov 13 12:34:43 2002 f
2812   d2=d;
2813   if (Duv2>aMinDiv2) {
2814     d2 = Abs(ResoUV2/Duv2); 
2815     d2 = Min(Sqrt(d2)*tolArea,d); 
2816   }
2817   //d2 = Abs(ResoUV2/Duv2); 
2818   //d2 = Min(Sqrt(d2)*tolArea,d);  
2819   //modified by NIZNHY-PKV Wed Nov 13 12:34:53 2002 t
2820   tolCoeff2 = Exp(d2);
2821   CosRef1 = CosRef2D/tolCoeff1;
2822   CosRef2 = CosRef2D/tolCoeff2;
2823   //
2824   //==================================================================================
2825   //== The points are not confused :                                           ==
2826   //== D e t e c t    t h e   S t o p   a  t   p r e v i o u s  p o i n t ==
2827   //==                           N o t    T o o    G r e a t (angle in space UV)    ==
2828   //==                           C h a n g e    o f    s i d e                ==
2829   //==================================================================================
2830   if (Status != IntWalk_PointConfondu) { 
2831     if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2) {
2832       pasuv[0]*=0.5;  pasuv[1]*=0.5;  pasuv[2]*=0.5;  pasuv[3]*=0.5;
2833       if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2) { 
2834         return(IntWalk_ArretSurPointPrecedent);
2835       }
2836       else {
2837         pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
2838         return(IntWalk_PasTropGrand);
2839       }
2840     }
2841     const gp_Dir2d& Tg2dcourante1 = myIntersectionOn2S.DirectionOnS1();
2842     const gp_Dir2d& Tg2dcourante2 = myIntersectionOn2S.DirectionOnS2();
2843     Cosi1 = Du1*Tg2dcourante1.X() + Dv1*Tg2dcourante1.Y();
2844     Cosi2 = Du2*Tg2dcourante2.X() + Dv2*Tg2dcourante2.Y();
2845     Ang1 = Abs(previousd1.Angle(Tg2dcourante1));  
2846     Ang2 = Abs(previousd2.Angle(Tg2dcourante2));  
2847     AngRef1 = AngRef2D*tolCoeff1;
2848     AngRef2 = AngRef2D*tolCoeff2;
2849     //-------------------------------------------------------
2850     //-- Test : Angle too great in space UV       -----
2851     //--        Change of  side                      -----
2852     //-------------------------------------------------------
2853     if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2 || Ang1 > AngRef1 || Ang2 > AngRef2) {
2854       pasuv[0]*=0.5;  pasuv[1]*=0.5;  pasuv[2]*=0.5;  pasuv[3]*=0.5;
2855       if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2) 
2856         return(IntWalk_ArretSurPoint);
2857       else 
2858         return(IntWalk_PasTropGrand);
2859     }
2860   }
2861   //<-OCC431(apo)
2862   //==================================================================================
2863   //== D e t e c t i o n   o f    :  Step Too Small 
2864   //==                               STEP TOO Great 
2865   //==================================================================================
2866
2867   //---------------------------------------
2868   //-- Estimate of the vector           --
2869   //---------------------------------------
2870   FlecheCourante =
2871     Sqrt(Abs((previousd.XYZ()-TgCourante.XYZ()).SquareModulus()*Dist))/8.;
2872
2873   if ( FlecheCourante<= fleche*0.5) {     //-- Current step too small
2874     if(FlecheCourante>1e-16) { 
2875       Ratio = 0.5*(fleche/FlecheCourante);
2876     }
2877     else { 
2878       Ratio = 10.0;
2879     }
2880     Standard_Real pasSu1 = pasuv[0];
2881     Standard_Real pasSv1 = pasuv[1];
2882     Standard_Real pasSu2 = pasuv[2];
2883     Standard_Real pasSv2 = pasuv[3];
2884
2885     //-- In  case if 
2886     //-- a point at U+DeltaU is required, ....
2887     //-- return a point at U + Epsilon
2888     //-- Epsilon << DeltaU.
2889
2890     if(pasuv[0]< AbsDu1) pasuv[0] = AbsDu1;
2891     if(pasuv[1]< AbsDv1) pasuv[1] = AbsDv1;
2892     if(pasuv[2]< AbsDu2) pasuv[2] = AbsDu2;
2893     if(pasuv[3]< AbsDv2) pasuv[3] = AbsDv2;
2894
2895     if(pasuv[0]<ResoU1) pasuv[0]=ResoU1;
2896     if(pasuv[1]<ResoV1) pasuv[1]=ResoV1;
2897     if(pasuv[2]<ResoU2) pasuv[2]=ResoU2;
2898     if(pasuv[3]<ResoV2) pasuv[3]=ResoV2;
2899     //-- if(Ratio>10.0 ) { Ratio=10.0; } 
2900     Standard_Real R1,R = pasInit[0]/pasuv[0];
2901     R1= pasInit[1]/pasuv[1];     if(R1<R) R=R1;
2902     R1= pasInit[2]/pasuv[2];     if(R1<R) R=R1;
2903     R1= pasInit[3]/pasuv[3];     if(R1<R) R=R1;
2904     if(Ratio > R) Ratio=R;
2905     pasuv[0] = Min(Ratio*pasuv[0],pasInit[0]);
2906     pasuv[1] = Min(Ratio*pasuv[1],pasInit[1]);
2907     pasuv[2] = Min(Ratio*pasuv[2],pasInit[2]);
2908     pasuv[3] = Min(Ratio*pasuv[3],pasInit[3]);
2909     if (pasuv[0] != pasSu1 || pasuv[2] != pasSu2|| 
2910       pasuv[1] != pasSv1 || pasuv[3] != pasSv2) {
2911         if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
2912           STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
2913           return IntWalk_PasTropGrand; 
2914         }
2915     }
2916     if(Status == IntWalk_OK) { 
2917       STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
2918       //-- Try to increase the step
2919     }
2920     return Status;
2921   }
2922   else {                                //-- CurrentVector > vector*0.5 
2923     if (FlecheCourante > fleche) {      //-- Current step too Great
2924       Ratio = fleche/FlecheCourante; 
2925       pasuv[0] = Ratio*pasuv[0];
2926       pasuv[1] = Ratio*pasuv[1];
2927       pasuv[2] = Ratio*pasuv[2];
2928       pasuv[3] = Ratio*pasuv[3];
2929       //if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
2930       //        STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
2931       return IntWalk_PasTropGrand; 
2932       //}
2933     }
2934     else {                             //-- vector/2  <  CurrentVector <= vector   
2935       Ratio = 0.75 * (fleche / FlecheCourante);
2936     }
2937   }
2938   pasuv[0] = Max(5.*ResoU1,Min(Min(Ratio*AbsDu1,pasuv[0]),pasInit[0]));
2939   pasuv[1] = Max(5.*ResoV1,Min(Min(Ratio*AbsDv1,pasuv[1]),pasInit[1]));
2940   pasuv[2] = Max(5.*ResoU2,Min(Min(Ratio*AbsDu2,pasuv[2]),pasInit[2]));
2941   pasuv[3] = Max(5.*ResoV2,Min(Min(Ratio*AbsDv2,pasuv[3]),pasInit[3]));
2942   if(Status == IntWalk_OK) STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
2943   return Status;
2944 }
2945
2946 Standard_Boolean IntWalk_PWalking::
2947 TestArret(const Standard_Boolean DejaReparti,
2948           TColStd_Array1OfReal& Param,
2949           IntImp_ConstIsoparametric&  ChoixIso)
2950
2951           //
2952           // test if the point of intersection set by these parameters remains in the 
2953           // natural domain of each square.
2954           // if the point outpasses reframe to find the best iso (border)
2955           // that intersects easiest the other square
2956           // otherwise test if closed line is present  
2957           // 
2958 {
2959   Standard_Real Uvd[4],Uvf[4],Epsuv[4],Duv[4],Uvp[4],dv,dv2,ParC[4];
2960   Standard_Real DPc,DPb;
2961   Standard_Integer i = 0, k = 0;
2962   Epsuv[0] = ResoU1;
2963   Epsuv[1] = ResoV1;
2964   Epsuv[2] = ResoU2;
2965   Epsuv[3] = ResoV2;
2966   previousPoint.Parameters(Uvp[0],Uvp[1],Uvp[2],Uvp[3]);
2967
2968   Standard_Real SolParam[4];
2969   myIntersectionOn2S.Point().Parameters(SolParam[0],SolParam[1],SolParam[2],SolParam[3]);
2970
2971   Standard_Boolean Trouve = Standard_False;
2972
2973   Uvd[0]=Um1;   Uvf[0]=UM1;   Uvd[1]=Vm1;   Uvf[1]=VM1;
2974   Uvd[2]=Um2;   Uvf[2]=UM2;   Uvd[3]=Vm2;   Uvf[3]=VM2;
2975
2976   Standard_Integer im1;
2977   for ( i = 1,im1 = 0;i<=4;i++,im1++) {
2978     switch(i) { 
2979     case 1: k=2; break;
2980     case 2: k=1; break;
2981     case 3: k=4; break;
2982     case 4: k=3; break;
2983     }
2984     if (Param(i) < (Uvd[im1]-Epsuv[im1]) ||
2985       SolParam[im1] < (Uvd[im1]-Epsuv[im1]))     //--     Current -----  Bound Inf -----  Previous
2986     {
2987       Trouve    = Standard_True;                   //-- 
2988       DPc       = Uvp[im1]-Param(i);               //--     Previous  - Current
2989       DPb       = Uvp[im1]-Uvd[im1];               //--     Previous  - Bound Inf
2990       ParC[im1] = Uvd[im1];                        //--     ParamCorrige
2991       dv        = Param(k)-Uvp[k-1];               //--     Current   - Previous (other Direction)
2992       dv2       = dv*dv;         
2993       if(dv2>RealEpsilon()) {                       //--    Progress at the other Direction ?
2994         Duv[im1]  = DPc*DPb + dv2;
2995         Duv[im1]  = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
2996       }
2997       else {
2998         Duv[im1]=-1.0;                              //--    If no progress, do not change  
2999       }                                             //--    the choice of iso 
3000     }   
3001     else if (Param(i) > (Uvf[im1] + Epsuv[im1]) ||
3002       SolParam[im1] > (Uvf[im1] + Epsuv[im1]))//--    Previous -----  Bound Sup -----  Current
3003     {
3004       Trouve    = Standard_True;                    //-- 
3005       DPc       = Param(i)-Uvp[im1];                //--     Current   - Previous
3006       DPb       = Uvf[im1]-Uvp[im1];                //--     Bound Sup - Previous 
3007       ParC[im1] = Uvf[im1];                         //--     Param Corrige
3008       dv        = Param(k)-Uvp[k-1];                //--     Current   - Previous (other Direction)
3009       dv2       = dv*dv;
3010       if(dv2>RealEpsilon()) {                       //--     Progress in other Direction ?
3011         Duv[im1]  =  DPc*DPb + dv2;
3012         Duv[im1]  = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
3013       }
3014       else {
3015         Duv[im1]=-1.0;                              //--    If no progress, do not change 
3016       }                                             //--    the choice of iso 
3017     }
3018     else { 
3019       Duv[im1]= -1.;
3020       ParC[im1]=Param(i);
3021     }
3022   }
3023
3024   if (Trouve) {
3025     //--------------------------------------------------
3026     //-- One of Parameters u1,v1,u2,v2 is outside of  --
3027     //-- the natural limits.                          -- 
3028     //-- Find the best direction of                   -- 
3029     //-- progress and reframe the parameters.        --
3030     //--------------------------------------------------
3031     Standard_Real ddv = -1.0;
3032     k=-1;
3033     for (i=0;i<=3;i++) {
3034       Param(i+1) = ParC[i];
3035       if(Duv[i]>ddv) { 
3036         ddv = Duv[i];
3037         k=i;
3038       }
3039     }
3040     if(k!=-1) { 
3041       ChoixIso   = ChoixRef[k];
3042     }
3043     else { 
3044       if((ParC[0]<=Uvd[0]+Epsuv[0]) || (ParC[0]>=Uvf[0]-Epsuv[0])) {
3045         ChoixIso = IntImp_UIsoparametricOnCaro1;
3046       }
3047       else if((ParC[1]<=Uvd[1]+Epsuv[1]) || (ParC[1]>=Uvf[1]-Epsuv[1])) {
3048         ChoixIso = IntImp_VIsoparametricOnCaro1;
3049       }
3050       else if((ParC[2]<=Uvd[2]+Epsuv[2]) || (ParC[2]>=Uvf[2]-Epsuv[2])) {
3051         ChoixIso = IntImp_UIsoparametricOnCaro2;
3052       }
3053       else if((ParC[3]<=Uvd[3]+Epsuv[3]) || (ParC[3]>=Uvf[3]-Epsuv[3])) {
3054         ChoixIso = IntImp_VIsoparametricOnCaro2;
3055       }
3056     }
3057     close = Standard_False;
3058     return Standard_True;
3059   }
3060   else 
3061   {  
3062     if (!DejaReparti) { // find if line closed
3063
3064       Standard_Real u,v;
3065       const IntSurf_PntOn2S& POn2S1=line->Value(1);
3066       //On S1
3067       POn2S1.ParametersOnS1(u,v);
3068       gp_Pnt2d P1uvS1(u,v);
3069       previousPoint.ParametersOnS1(u,v);
3070       gp_Pnt2d PrevuvS1(u,v);
3071       myIntersectionOn2S.Point().ParametersOnS1(u,v);
3072       gp_Pnt2d myIntersuvS1(u,v);
3073       Standard_Boolean close2dS1 = (P1uvS1.XY()-PrevuvS1.XY())*
3074         (P1uvS1.XY()-myIntersuvS1.XY()) < 0.0;
3075       //On S2
3076       POn2S1.ParametersOnS2(u,v);
3077       gp_Pnt2d P1uvS2(u,v);
3078       previousPoint.ParametersOnS2(u,v);
3079       gp_Pnt2d PrevuvS2(u,v);
3080       myIntersectionOn2S.Point().ParametersOnS2(u,v);
3081       gp_Pnt2d myIntersuvS2(u,v);
3082       Standard_Boolean close2dS2 = (P1uvS2.XY()-PrevuvS2.XY())*
3083         (P1uvS2.XY()-myIntersuvS2.XY()) < 0.0;
3084
3085       close = close2dS1 && close2dS2;
3086       return close;
3087     }
3088     else return Standard_False;
3089   }
3090 }
3091