0025380: Intersection curve cannot reach boundary of surface
[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   Standard_Real pasMaxSV[4], aTmp;
597   TColStd_Array1OfReal Param(1,4);
598   IntImp_ConstIsoparametric ChoixIso;
599   //xt
600   //
601   done = Standard_False;
602   //
603   // Caro1 and Caro2
604   const Handle(Adaptor3d_HSurface)& Caro1 =myIntersectionOn2S.Function().AuxillarSurface1();
605   const Handle(Adaptor3d_HSurface)& Caro2 =myIntersectionOn2S.Function().AuxillarSurface2();
606   //
607   const Standard_Real UFirst1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
608   const Standard_Real VFirst1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
609   const Standard_Real ULast1  = Adaptor3d_HSurfaceTool::LastUParameter (Caro1);
610   const Standard_Real VLast1  = Adaptor3d_HSurfaceTool::LastVParameter (Caro1);
611
612   const Standard_Real UFirst2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
613   const Standard_Real VFirst2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
614   const Standard_Real ULast2  = Adaptor3d_HSurfaceTool::LastUParameter (Caro2);
615   const Standard_Real VLast2  = Adaptor3d_HSurfaceTool::LastVParameter (Caro2);
616   //
617   ComputePasInit(pasuv,u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max,
618     Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2,pasMax+pasMax);
619   //
620   if(pasuv[0]<100.0*ResoU1) {
621     pasuv[0]=100.0*ResoU1; 
622   }
623   if(pasuv[1]<100.0*ResoV1) {
624     pasuv[1]=100.0*ResoV1; 
625   }
626   if(pasuv[2]<100.0*ResoU2) {
627     pasuv[2]=100.0*ResoU2;
628   }
629   if(pasuv[3]<100.0*ResoV2) {
630     pasuv[3]=100.0*ResoV2;
631   }
632   //
633   for (Standard_Integer i=0; i<4; ++i)
634   {
635     if(pasuv[i]>10)
636     {
637       pasuv[i] = 10;
638     }
639
640     pasInit[i] = pasSav[i] = pasuv[i]; 
641   }
642   //
643   line = new IntSurf_LineOn2S ();
644   //
645   for (Standard_Integer i=1; i<=4; ++i)
646   {
647     aTmp=ParDep(i);
648     Param(i)=ParDep(i);
649   }
650   //-- reproduce steps uv connected to surfaces Caro1 and Caro2
651   //-- pasuv[] and pasSav[] are modified during the marching
652   for(Standard_Integer i = 0; i < 4; ++i)
653   {
654     pasMaxSV[i] = pasSav[i] = pasuv[i] = pasInit[i]; 
655   }
656
657   //-- calculate the first solution point
658   math_FunctionSetRoot  Rsnld(myIntersectionOn2S.Function());
659   //
660   ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld);
661   if (!myIntersectionOn2S.IsDone())
662   {
663     return;
664   }
665
666   //
667   if (myIntersectionOn2S.IsEmpty())
668   {
669     return;
670   }
671   //
672   if(myIntersectionOn2S.IsTangent())
673   {
674     return;
675   }
676   //
677   Standard_Boolean Arrive, DejaReparti;
678   const Standard_Integer RejectIndexMAX = 250000;
679   Standard_Integer IncKey, RejectIndex;
680   gp_Pnt pf,pl;
681   //
682   DejaReparti = Standard_False;
683   IncKey = 0;
684   RejectIndex = 0;
685   //
686   previousPoint = myIntersectionOn2S.Point();
687   previoustg = Standard_False;
688   previousd  = myIntersectionOn2S.Direction();
689   previousd1 = myIntersectionOn2S.DirectionOnS1();
690   previousd2 = myIntersectionOn2S.DirectionOnS2();
691   indextg = 1;
692   tgdir   = previousd;
693   firstd1 = previousd1;
694   firstd2 = previousd2;
695   tgfirst = tglast = Standard_False;
696   choixIsoSav  =  ChoixIso;
697   //------------------------------------------------------------
698   //-- Test if the first point of marching corresponds 
699   //-- to a point on borders. 
700   //-- In this case, DejaReparti is initialized as True
701   //-- 
702   pf = previousPoint.Value();
703   Standard_Boolean bTestFirstPoint = Standard_True;
704
705   previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
706   AddAPoint(line,previousPoint);
707   //
708   IntWalk_StatusDeflection Status = IntWalk_OK;
709   Standard_Boolean NoTestDeflection = Standard_False;
710   Standard_Real SvParam[4], f;
711   Standard_Integer LevelOfEmptyInmyIntersectionOn2S=0;
712   Standard_Integer LevelOfPointConfondu = 0; 
713   Standard_Integer LevelOfIterWithoutAppend = -1;
714   //
715   Arrive = Standard_False;
716   while(!Arrive) //010
717   {
718     LevelOfIterWithoutAppend++;
719     if(LevelOfIterWithoutAppend>20)
720     {
721       Arrive = Standard_True; 
722       if(DejaReparti) {
723         break;
724       }
725       RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
726       LevelOfIterWithoutAppend = 0;
727     }
728     //
729     // compute f
730     f = 0.;
731     switch (ChoixIso) { 
732       case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
733       case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
734       case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
735       case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
736       default:break;
737     }
738     //
739     if(f<0.1) {
740       f=0.1;
741     }
742     //
743     previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
744     //
745     //--ofv.begin
746     Standard_Real aIncKey, aEps, dP1, dP2, dP3, dP4;
747     //
748     dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
749     dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
750     dP3 = sensCheminement * pasuv[2] * previousd2.X() /f; 
751     dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
752     //
753     aIncKey=5.*(Standard_Real)IncKey;
754     aEps=1.e-7;
755     if(ChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < aEps)
756     {
757       dP1 *= aIncKey;
758     }
759
760     if(ChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < aEps)
761     {
762       dP2 *= aIncKey;
763     }
764
765     if(ChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < aEps)
766     {
767       dP3 *= aIncKey;
768     }
769
770     if(ChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < aEps)
771     {
772       dP4 *= aIncKey;
773     }
774     //--ofv.end
775     //
776     Param(1) += dP1;
777     Param(2) += dP2;
778     Param(3) += dP3; 
779     Param(4) += dP4;
780     //==========================
781     SvParam[0]=Param(1); 
782     SvParam[1]=Param(2);
783     SvParam[2]=Param(3);
784     SvParam[3]=Param(4);
785     //
786     Standard_Integer aTryNumber = 0;
787     Standard_Real    isBadPoint = Standard_False;
788     IntImp_ConstIsoparametric aBestIso = ChoixIso;
789     do
790     {
791       isBadPoint = Standard_False;
792
793       ChoixIso= myIntersectionOn2S.Perform(Param, Rsnld, aBestIso);
794
795       if (myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty())
796       {
797         Standard_Real aNewPnt[4], anAbsParamDist[4];
798         myIntersectionOn2S.Point().Parameters(aNewPnt[0], aNewPnt[1], aNewPnt[2], aNewPnt[3]);
799
800         if (aNewPnt[0] < u1min || aNewPnt[0] > u1max ||
801             aNewPnt[1] < v1min || aNewPnt[1] > v1max ||
802             aNewPnt[2] < u2min || aNewPnt[2] > u2max ||
803             aNewPnt[3] < v2min || aNewPnt[3] > v2max)
804         {
805           break; // Out of borders, handle this later.
806         }
807
808         anAbsParamDist[0] = Abs(Param(1) - dP1 - aNewPnt[0]);
809         anAbsParamDist[1] = Abs(Param(2) - dP2 - aNewPnt[1]);
810         anAbsParamDist[2] = Abs(Param(3) - dP3 - aNewPnt[2]);
811         anAbsParamDist[3] = Abs(Param(4) - dP4 - aNewPnt[3]);
812         if (anAbsParamDist[0] < ResoU1 &&
813             anAbsParamDist[1] < ResoV1 &&
814             anAbsParamDist[2] < ResoU2 &&
815             anAbsParamDist[3] < ResoV2 &&
816             Status != IntWalk_PasTropGrand)
817         {
818           isBadPoint = Standard_True;
819           aBestIso = IntImp_ConstIsoparametric((aBestIso + 1) % 4);
820         }
821       }
822     } while (isBadPoint && ++aTryNumber <= 4);
823     //
824     if (!myIntersectionOn2S.IsDone())
825     {
826       //end of line, division
827       Arrive = Standard_False;
828       Param(1)=SvParam[0]; 
829       Param(2)=SvParam[1]; 
830       Param(3)=SvParam[2];
831       Param(4)=SvParam[3];
832       RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
833     }
834     else  //009 
835     {
836       //== Calculation of exact point from Param(.) is possible
837       if (myIntersectionOn2S.IsEmpty())
838       {
839         Standard_Real u1,v1,u2,v2;
840         previousPoint.Parameters(u1,v1,u2,v2);
841         //
842         Arrive = Standard_False;
843         if(u1<UFirst1 || u1>ULast1)
844         {
845           Arrive=Standard_True;
846         }       
847
848         if(u2<UFirst2 || u2>ULast2)
849         {
850           Arrive=Standard_True;
851         }
852
853         if(v1<VFirst1 || v1>VLast1)
854         {
855           Arrive=Standard_True;
856         }
857
858         if(v2<VFirst2 || v2>VLast2)
859         {
860           Arrive=Standard_True;
861         }
862
863         RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
864         LevelOfEmptyInmyIntersectionOn2S++;
865         //
866         if(LevelOfEmptyInmyIntersectionOn2S>10)
867         {
868           pasuv[0]=pasSav[0]; 
869           pasuv[1]=pasSav[1]; 
870           pasuv[2]=pasSav[2]; 
871           pasuv[3]=pasSav[3];
872         }
873       }
874       else //008
875       {
876         //============================================================
877         //== A point has been found :  T E S T   D E F L E C T I O N 
878         //============================================================
879         if(NoTestDeflection)
880         {
881           NoTestDeflection = Standard_False;
882         }                 
883         else
884         {
885           if(--LevelOfEmptyInmyIntersectionOn2S<=0)
886           {
887             LevelOfEmptyInmyIntersectionOn2S=0;
888             if(LevelOfIterWithoutAppend < 10)
889             {
890               Status = TestDeflection();
891             }                   
892             else
893             {
894               pasuv[0]*=0.5; 
895               pasuv[1]*=0.5; 
896               pasuv[2]*=0.5; 
897               pasuv[3]*=0.5;
898             }
899           }
900         }
901
902         //============================================================
903         //==       T r a i t e m e n t   s u r   S t a t u s        ==
904         //============================================================
905         if(LevelOfPointConfondu > 5)
906         { 
907           Status = IntWalk_ArretSurPoint; 
908           LevelOfPointConfondu = 0;  
909         }
910         //
911         if(Status==IntWalk_OK)
912         { 
913           NbPasOKConseq++;
914           if(NbPasOKConseq >= 5)
915           {
916             NbPasOKConseq=0;
917             Standard_Boolean pastroppetit;
918             Standard_Real t;
919             //
920             do
921             {
922               pastroppetit=Standard_True;
923               //
924               if(pasuv[0]<pasInit[0])
925               {
926                 t = (pasInit[0]-pasuv[0])*0.25;
927                 if(t>0.1*pasInit[0])
928                 {
929                   t=0.1*pasuv[0];
930                 }
931
932                 pasuv[0]+=t; 
933                 pastroppetit=Standard_False;
934               }
935
936               if(pasuv[1]<pasInit[1])
937               {
938                 t = (pasInit[1]-pasuv[1])*0.25;
939                 if(t>0.1*pasInit[1]) {
940                   t=0.1*pasuv[1];
941                 }               
942
943                 pasuv[1]+=t; 
944                 pastroppetit=Standard_False;
945               }
946
947               if(pasuv[2]<pasInit[2])
948               {
949                 t = (pasInit[2]-pasuv[2])*0.25;
950                 if(t>0.1*pasInit[2])
951                 {
952                   t=0.1*pasuv[2];
953                 }
954
955                 pasuv[2]+=t; 
956                 pastroppetit=Standard_False;
957               }
958
959               if(pasuv[3]<pasInit[3])
960               {
961                 t = (pasInit[3]-pasuv[3])*0.25;
962                 if(t>0.1*pasInit[3]) {
963                   t=0.1*pasuv[3];
964                 }
965                 pasuv[3]+=t; 
966                 pastroppetit=Standard_False;
967               }
968               if(pastroppetit)
969               {
970                 if(pasMax<0.1)
971                 {
972                   pasMax*=1.1;
973                   pasInit[0]*=1.1; 
974                   pasInit[1]*=1.1; 
975                   pasInit[2]*=1.1; 
976                   pasInit[3]*=1.1; 
977                 }
978                 else
979                 {
980                   pastroppetit=Standard_False;
981                 }
982               }
983             }
984             while(pastroppetit);
985           }
986         }//Status==IntWalk_OK
987         else
988           NbPasOKConseq=0;
989
990         //
991         switch(Status)//007 
992         {
993         case IntWalk_ArretSurPointPrecedent:
994           {
995             Arrive = Standard_False;
996             RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
997             break;
998           }
999         case IntWalk_PasTropGrand:
1000           {
1001             Param(1)=SvParam[0];
1002             Param(2)=SvParam[1]; 
1003             Param(3)=SvParam[2]; 
1004             Param(4)=SvParam[3];
1005
1006             if(LevelOfIterWithoutAppend > 5)
1007             {
1008               if(pasSav[0]<pasInit[0])
1009               {
1010                 pasInit[0]-=(pasInit[0]-pasSav[0])*0.25;
1011                 LevelOfIterWithoutAppend=0;
1012               }
1013
1014               if(pasSav[1]<pasInit[1])
1015               {
1016                 pasInit[1]-=(pasInit[1]-pasSav[1])*0.25;
1017                 LevelOfIterWithoutAppend=0;
1018               }
1019
1020               if(pasSav[2]<pasInit[2])
1021               {
1022                 pasInit[2]-=(pasInit[2]-pasSav[2])*0.25;
1023                 LevelOfIterWithoutAppend=0;
1024               }
1025
1026               if(pasSav[3]<pasInit[3])
1027               {
1028                 pasInit[3]-=(pasInit[3]-pasSav[3])*0.25;
1029                 LevelOfIterWithoutAppend=0;
1030               }
1031             }
1032
1033             break;
1034           }
1035         case IntWalk_PointConfondu:
1036           {
1037             LevelOfPointConfondu++;
1038
1039             if(LevelOfPointConfondu>5)
1040             {
1041               Standard_Boolean pastroppetit;
1042               //
1043               do
1044               {
1045                 pastroppetit=Standard_True;
1046
1047                 if(pasuv[0]<pasInit[0])
1048                 {
1049                   pasuv[0]+=(pasInit[0]-pasuv[0])*0.25;
1050                   pastroppetit=Standard_False;
1051                 }
1052
1053                 if(pasuv[1]<pasInit[1])
1054                 {
1055                   pasuv[1]+=(pasInit[1]-pasuv[1])*0.25;
1056                   pastroppetit=Standard_False;
1057                 }
1058
1059                 if(pasuv[2]<pasInit[2])
1060                 {
1061                   pasuv[2]+=(pasInit[2]-pasuv[2])*0.25;
1062                   pastroppetit=Standard_False; 
1063                 }
1064
1065                 if(pasuv[3]<pasInit[3])
1066                 {
1067                   pasuv[3]+=(pasInit[3]-pasuv[3])*0.25;
1068                   pastroppetit=Standard_False;
1069                 }
1070
1071                 if(pastroppetit)
1072                 {
1073                   if(pasMax<0.1)
1074                   {
1075                     pasMax*=1.1;
1076                     pasInit[0]*=1.1;
1077                     pasInit[1]*=1.1;
1078                     pasInit[2]*=1.1;
1079                     pasInit[3]*=1.1; 
1080                   }
1081                   else
1082                   {
1083                     pastroppetit=Standard_False;
1084                   }
1085                 }
1086               }
1087               while(pastroppetit);
1088             }
1089
1090             break;
1091           }
1092         case IntWalk_OK:
1093         case IntWalk_ArretSurPoint://006
1094           {
1095             //=======================================================
1096             //== Stop Test t   :  Frame on Param(.)     ==
1097             //=======================================================
1098             //xft arrive here
1099             Arrive = TestArret(DejaReparti,Param,ChoixIso); 
1100             // JMB 30th December 1999. 
1101             // Some statement below should not be put in comment because they are useful.
1102             // See grid CTO 909 A1 which infinitely loops 
1103             if(Arrive==Standard_False && Status==IntWalk_ArretSurPoint)
1104             {
1105               Arrive=Standard_True;
1106 #ifdef DEB
1107               cout << "Compile with option DEB : if problems with intersection : ";
1108               cout << "IntWalk_PWalking_1.gxx (lbr le 1erdec98)"<<endl;
1109 #endif
1110             }
1111
1112             if(Arrive)
1113             {
1114               NbPasOKConseq = -10;
1115             }
1116
1117             if(!Arrive)//005
1118             {
1119               //=====================================================
1120               //== Param(.) is in the limits                       ==
1121               //==  and does not end a closed  line                ==
1122               //=====================================================
1123               //== Check on the current point of myInters
1124               Standard_Boolean pointisvalid = Standard_False;
1125               {
1126                 Standard_Real u1,v1,u2,v2; 
1127                 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1128
1129                 //
1130                 if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 && 
1131                   v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
1132                   v1 >= Vm1  && v2 >= Vm2)
1133                 {
1134                   pointisvalid=Standard_True;
1135                 }
1136               }
1137
1138               //
1139               if(pointisvalid)
1140               {
1141                 previousPoint = myIntersectionOn2S.Point();
1142                 previoustg = myIntersectionOn2S.IsTangent();
1143
1144                 if(!previoustg)
1145                 {
1146                   previousd  = myIntersectionOn2S.Direction();
1147                   previousd1 = myIntersectionOn2S.DirectionOnS1();
1148                   previousd2 = myIntersectionOn2S.DirectionOnS2();
1149                 }
1150                 //=====================================================
1151                 //== Check on the previous Point
1152                 {
1153                   Standard_Real u1,v1,u2,v2;
1154                   previousPoint.Parameters(u1,v1,u2,v2); 
1155                   if( u1 <= UM1  && u2 <= UM2 && v1 <= VM1 &&
1156                     v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
1157                     v1 >= Vm1  && v2 >= Vm2)
1158                   {
1159                     pl = previousPoint.Value();
1160                     if(bTestFirstPoint)
1161                     {
1162                       if(pf.SquareDistance(pl) < aSQDistMax)
1163                       {
1164                         IncKey++;
1165                         if(IncKey == 5000)
1166                           return;
1167                         else
1168                           continue;
1169                       }
1170                       else
1171                       {
1172                         bTestFirstPoint = Standard_False;
1173                       }
1174                     }
1175                     //
1176                     AddAPoint(line,previousPoint);
1177                     RejectIndex++;
1178
1179                     if(RejectIndex >= RejectIndexMAX)
1180                     {
1181                       break;
1182                     }
1183
1184                     //
1185                     LevelOfIterWithoutAppend = 0;
1186                   }
1187                 }
1188               }//pointisvalid
1189               //====================================================
1190
1191               if(Status == IntWalk_ArretSurPoint)
1192               {
1193                 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1194               }
1195               else
1196               {
1197                 if (line->NbPoints() == 2)
1198                 {
1199                   pasSav[0] = pasuv[0];
1200                   pasSav[1] = pasuv[1];
1201                   pasSav[2] = pasuv[2];
1202                   pasSav[3] = pasuv[3];
1203                 }
1204               }
1205             }//005 if(!Arrive)
1206             else  //004
1207             {
1208               if(close)
1209               {
1210                 //================= la ligne est fermee ===============
1211                 AddAPoint(line,line->Value(1)); //ligne fermee
1212                 LevelOfIterWithoutAppend=0;
1213               }
1214               else    //$$$
1215               {
1216                 //====================================================
1217                 //== Param was not in the limits (was reframed)
1218                 //====================================================
1219                 Standard_Boolean bPrevNotTangent = !previoustg || !myIntersectionOn2S.IsTangent();
1220
1221                 IntImp_ConstIsoparametric SauvChoixIso = ChoixIso;
1222                 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1223                 //
1224                 if(!myIntersectionOn2S.IsEmpty()) //002
1225                 {
1226                   // mutially outpasses in the square or intersection in corner
1227
1228                   if(TestArret(Standard_True,Param,ChoixIso))
1229                   {
1230                     NbPasOKConseq = -10;
1231                     ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1232
1233                     if(!myIntersectionOn2S.IsEmpty())
1234                     {
1235                       previousPoint = myIntersectionOn2S.Point();
1236                       previoustg = myIntersectionOn2S.IsTangent();
1237
1238                       if (!previoustg)
1239                       {
1240                         previousd  = myIntersectionOn2S.Direction();
1241                         previousd1 = myIntersectionOn2S.DirectionOnS1();
1242                         previousd2 = myIntersectionOn2S.DirectionOnS2();
1243                       }
1244
1245                       pl = previousPoint.Value();
1246
1247                       if(bTestFirstPoint)
1248                       {
1249                         if(pf.SquareDistance(pl) < aSQDistMax)
1250                         {
1251                           IncKey++;
1252                           if(IncKey == 5000)
1253                             return;
1254                           else
1255                             continue;
1256                         }
1257                         else
1258                         {
1259                           bTestFirstPoint = Standard_False;
1260                         }
1261                       }
1262                       //
1263                       AddAPoint(line,previousPoint);
1264                       RejectIndex++;
1265
1266                       if(RejectIndex >= RejectIndexMAX)
1267                       {
1268                         break;
1269                       }
1270
1271                       //
1272                       LevelOfIterWithoutAppend=0;
1273                       RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1274                     }
1275                     else
1276                     {
1277                       //fail framing divides the step
1278                       Arrive = Standard_False;
1279                       RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1280                       NoTestDeflection = Standard_True;
1281                       ChoixIso = SauvChoixIso;
1282                     }
1283                   }//if(TestArret())
1284                   else
1285                   {
1286                     // save the last point
1287                     // to revert to it if the current point is out of bounds
1288
1289                     IntSurf_PntOn2S previousPointSave = previousPoint;
1290                     Standard_Boolean previoustgSave   = previoustg;
1291                     gp_Dir previousdSave              = previousd;
1292                     gp_Dir2d previousd1Save           = previousd1;
1293                     gp_Dir2d previousd2Save           = previousd2;
1294
1295                     previousPoint = myIntersectionOn2S.Point();
1296                     previoustg = myIntersectionOn2S.IsTangent();
1297                     Arrive = Standard_False;
1298
1299                     if(!previoustg)
1300                     {
1301                       previousd  = myIntersectionOn2S.Direction();
1302                       previousd1 = myIntersectionOn2S.DirectionOnS1();
1303                       previousd2 = myIntersectionOn2S.DirectionOnS2();
1304                     }
1305
1306                     //========================================
1307                     //== Check on PreviousPoint @@
1308
1309                     {
1310                       Standard_Real u1,v1,u2,v2;
1311                       previousPoint.Parameters(u1,v1,u2,v2);
1312
1313                       //To save initial 2d points
1314                       gp_Pnt2d ParamPntOnS1(Param(1), Param(2));
1315                       gp_Pnt2d ParamPntOnS2(Param(3), Param(4));
1316
1317                       ///////////////////////////
1318                       Param(1) = u1;
1319                       Param(2) = v1;
1320                       Param(3) = u2;
1321                       Param(4) = v2;
1322                       //
1323
1324                       //xf
1325                       Standard_Boolean bFlag1, bFlag2;
1326                       Standard_Real aTol2D=1.e-11;
1327                       //
1328                       bFlag1=u1 >= Um1-aTol2D && v1 >= Vm1-aTol2D && u1 <= UM1+aTol2D && v1 <= VM1+aTol2D;
1329                       bFlag2=u2 >= Um2-aTol2D && v2 >= Vm2-aTol2D && u2 <= UM2+aTol2D && v2 <= VM2+aTol2D;
1330                       if (bFlag1 && bFlag2)
1331                       {
1332                         /*
1333                         if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 &&
1334                         v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
1335                         v1 >= Vm1  && v2 >= Vm2)  {
1336                         */                      
1337                         //xt
1338                         pl = previousPoint.Value();
1339
1340                         if(bTestFirstPoint)
1341                         {
1342                           if(pf.SquareDistance(pl) < aSQDistMax)
1343                           {
1344                             IncKey++;
1345
1346                             if(IncKey == 5000)
1347                               return;
1348                             else
1349                               continue;
1350                           }
1351                           else
1352                           {
1353                             bTestFirstPoint = Standard_False;
1354                           }
1355                         }
1356
1357                         //To avoid walking around the same point
1358                         //in the tangent zone near a border
1359
1360                         if (previoustg)
1361                         {
1362                           Standard_Real prevU1, prevV1, prevU2, prevV2;
1363                           previousPointSave.Parameters(prevU1, prevV1, prevU2, prevV2);
1364                           gp_Pnt2d prevPntOnS1(prevU1, prevV1), prevPntOnS2(prevU2, prevV2);
1365                           gp_Pnt2d curPntOnS1(u1, v1), curPntOnS2(u2, v2);
1366                           gp_Vec2d PrevToParamOnS1(prevPntOnS1, ParamPntOnS1);
1367                           gp_Vec2d PrevToCurOnS1(prevPntOnS1, curPntOnS1);
1368                           gp_Vec2d PrevToParamOnS2(prevPntOnS2, ParamPntOnS2);
1369                           gp_Vec2d PrevToCurOnS2(prevPntOnS2, curPntOnS2);
1370                           Standard_Real MaxAngle = 3*M_PI/4;
1371
1372                           if (Abs(PrevToParamOnS1.Angle(PrevToCurOnS1)) > MaxAngle &&
1373                             Abs(PrevToParamOnS2.Angle(PrevToCurOnS2)) > MaxAngle)
1374                           {
1375                             Arrive = Standard_True;
1376                             break;
1377                           }
1378                         }
1379
1380                         ////////////////////////////////////////
1381                         AddAPoint(line,previousPoint);
1382                         RejectIndex++;
1383
1384                         if(RejectIndex >= RejectIndexMAX)
1385                         {
1386                           break;
1387                         }
1388
1389                         //
1390
1391                         LevelOfIterWithoutAppend=0;
1392                         Arrive = Standard_True;
1393                       }
1394                       else
1395                       {
1396                         // revert to the last correctly calculated point
1397                         previousPoint = previousPointSave;
1398                         previoustg    = previoustgSave;
1399                         previousd     = previousdSave;
1400                         previousd1    = previousd1Save;
1401                         previousd2    = previousd2Save;
1402                       }
1403                     }
1404
1405                     //
1406                     Standard_Boolean wasExtended = Standard_False;
1407
1408                     if(Arrive && myIntersectionOn2S.IsTangent() && bPrevNotTangent)
1409                     {
1410                       if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1411                       {
1412                         wasExtended = Standard_True;
1413                         Arrive = Standard_False;
1414                         ChoixIso = SauvChoixIso;
1415                       }
1416                     }
1417
1418                     RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1419
1420                     if(Arrive && 
1421                       myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() &&
1422                       myIntersectionOn2S.IsTangent() && bPrevNotTangent &&
1423                       !wasExtended)
1424                     {
1425                       if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1426                       {
1427                         wasExtended = Standard_True;
1428                         Arrive = Standard_False;
1429                         ChoixIso = SauvChoixIso;
1430                       }
1431                     }
1432                   }//else !TestArret() $
1433                 }//$$ end successful framing on border (!myIntersectionOn2S.IsEmpty())
1434                 else
1435                 {
1436                   //echec framing on border; division of step 
1437                   Arrive = Standard_False;
1438                   NoTestDeflection = Standard_True;
1439                   RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1440                 }
1441               }//$$$ end framing on border (!close)
1442             }//004 fin TestArret return Arrive = True
1443           } // 006case IntWalk_ArretSurPoint:  end Processing Status = OK  or ArretSurPoint 
1444         } //007  switch(Status) 
1445       } //008 end processing point  (TEST DEFLECTION)
1446     } //009 end processing line (else if myIntersectionOn2S.IsDone())
1447   }  //010 end if first departure point allows marching  while (!Arrive)
1448
1449   done = Standard_True;
1450 }
1451 // ===========================================================================================================
1452 // function: ExtendLineInCommonZone
1453 // purpose:  Extends already computed line inside tangent zone in the direction given by theChoixIso.
1454 //           Returns Standard_True if the line was extended through tangent zone and the last computed point 
1455 //           is outside the tangent zone (but it is not put into the line). Otherwise returns Standard_False.
1456 // ===========================================================================================================
1457 Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso,
1458                                                           const Standard_Boolean          theDirectionFlag) 
1459 {
1460   Standard_Boolean bOutOfTangentZone = Standard_False;
1461   Standard_Boolean bStop = !myIntersectionOn2S.IsTangent();
1462   Standard_Integer dIncKey = 1;
1463   TColStd_Array1OfReal Param(1,4);
1464   IntWalk_StatusDeflection Status = IntWalk_OK;
1465   Standard_Integer nbIterWithoutAppend = 0;
1466   Standard_Integer nbEqualPoints = 0;
1467   Standard_Integer parit = 0;
1468   Standard_Integer uvit = 0;
1469   IntSurf_SequenceOfPntOn2S aSeqOfNewPoint;
1470
1471   while (!bStop) {
1472     nbIterWithoutAppend++;
1473
1474     if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) {
1475 #ifdef DEB
1476       cout<<"Compile with option DEB:";
1477       cout<<"Infinite loop has detected. Stop iterations (IntWalk_PWalking_1.gxx)" << endl;
1478 #endif
1479       bStop = Standard_True;
1480       break;
1481     }
1482     Standard_Real f = 0.;
1483
1484     switch (theChoixIso)
1485     { 
1486     case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
1487     case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
1488     case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
1489     case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
1490     }
1491
1492     if(f<0.1) f=0.1;
1493
1494     previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
1495
1496     Standard_Real dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
1497     Standard_Real dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
1498     Standard_Real dP3 = sensCheminement * pasuv[2] * previousd2.X() /f; 
1499     Standard_Real dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
1500
1501     if(theChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < 1.e-7) dP1 *= (5. * (Standard_Real)dIncKey);
1502     if(theChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < 1.e-7) dP2 *= (5. * (Standard_Real)dIncKey);
1503     if(theChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < 1.e-7) dP3 *= (5. * (Standard_Real)dIncKey);
1504     if(theChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < 1.e-7) dP4 *= (5. * (Standard_Real)dIncKey);
1505
1506     Param(1) += dP1;
1507     Param(2) += dP2;
1508     Param(3) += dP3; 
1509     Param(4) += dP4;
1510     Standard_Real SvParam[4];
1511     IntImp_ConstIsoparametric ChoixIso = theChoixIso;
1512
1513     for(parit = 0; parit < 4; parit++) {
1514       SvParam[parit] = Param(parit+1);
1515     }
1516     math_FunctionSetRoot  Rsnld(myIntersectionOn2S.Function());
1517     ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld, theChoixIso);
1518
1519     if (!myIntersectionOn2S.IsDone()) {
1520       return bOutOfTangentZone;
1521     }
1522     else {
1523       if (myIntersectionOn2S.IsEmpty()) {
1524         return bOutOfTangentZone;
1525       }
1526
1527       Status = TestDeflection();
1528
1529       if(Status == IntWalk_OK) {
1530
1531         for(uvit = 0; uvit < 4; uvit++) {
1532           if(pasuv[uvit] < pasInit[uvit]) {
1533             pasuv[uvit] = pasInit[uvit];
1534           }
1535         }
1536       }
1537
1538       switch(Status) {
1539       case  IntWalk_ArretSurPointPrecedent:
1540         {
1541           bStop = Standard_True;
1542           bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1543           break;
1544         }
1545       case IntWalk_PasTropGrand:
1546         {
1547           for(parit = 0; parit < 4; parit++) {
1548             Param(parit+1) = SvParam[parit];
1549           }
1550           Standard_Boolean bDecrease = Standard_False;
1551
1552           for(uvit = 0; uvit < 4; uvit++) {
1553             if(pasSav[uvit] < pasInit[uvit]) { 
1554               pasInit[uvit] -= (pasInit[uvit] - pasSav[uvit]) * 0.1;
1555               bDecrease = Standard_True;
1556             }
1557           }
1558
1559           if(bDecrease) nbIterWithoutAppend--;
1560           break;
1561         }
1562       case IntWalk_PointConfondu:
1563         {
1564           for(uvit = 0; uvit < 4; uvit++) {
1565             if(pasuv[uvit] < pasInit[uvit]) {
1566               pasuv[uvit] += (pasInit[uvit] - pasuv[uvit]) * 0.1;
1567             }
1568           }
1569           break;
1570         }
1571       case IntWalk_OK:
1572       case IntWalk_ArretSurPoint:
1573         {
1574           //
1575           bStop = TestArret(theDirectionFlag, Param, ChoixIso);
1576           //
1577
1578           //
1579           if(!bStop) {
1580             Standard_Real u11,v11,u12,v12; 
1581             myIntersectionOn2S.Point().Parameters(u11,v11,u12,v12); 
1582             Standard_Real u21,v21,u22,v22;
1583             previousPoint.Parameters(u21,v21,u22,v22); 
1584
1585             if(((fabs(u11-u21) < ResoU1) && (fabs(v11-v21) < ResoV1)) ||
1586               ((fabs(u12-u22) < ResoU2) && (fabs(v12-v22) < ResoV2))) {
1587                 nbEqualPoints++;
1588             }
1589             else {
1590               nbEqualPoints = 0;
1591             }
1592           }
1593           //
1594
1595           bStop = bStop || !myIntersectionOn2S.IsTangent();
1596           bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1597
1598           if(!bStop) {
1599             Standard_Boolean pointisvalid = Standard_False;
1600             Standard_Real u1,v1,u2,v2; 
1601             myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2); 
1602
1603             if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 && 
1604               v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
1605               v1 >= Vm1  && v2 >= Vm2) 
1606               pointisvalid = Standard_True;
1607
1608             if(pointisvalid) {
1609               previousPoint = myIntersectionOn2S.Point();
1610               previoustg = myIntersectionOn2S.IsTangent();
1611
1612               if(!previoustg) {
1613                 previousd  = myIntersectionOn2S.Direction();
1614                 previousd1 = myIntersectionOn2S.DirectionOnS1();
1615                 previousd2 = myIntersectionOn2S.DirectionOnS2();
1616               }
1617               Standard_Boolean bAddPoint = Standard_True;
1618
1619               if(line->NbPoints() >= 1) {
1620                 gp_Pnt pf = line->Value(1).Value();
1621                 gp_Pnt pl = previousPoint.Value(); 
1622
1623                 if(pf.Distance(pl) < Precision::Confusion()) { 
1624                   dIncKey++; 
1625                   if(dIncKey == 5000) return bOutOfTangentZone; 
1626                   else bAddPoint = Standard_False;
1627                 }
1628               }
1629
1630               if(bAddPoint) {
1631                 aSeqOfNewPoint.Append(previousPoint);
1632                 nbIterWithoutAppend = 0;
1633               }
1634             }
1635
1636             if (line->NbPoints() == 2) {
1637               for(uvit = 0; uvit < 4; uvit++) {
1638                 pasSav[uvit] = pasuv[uvit]; 
1639               }
1640             }
1641
1642             if ( !pointisvalid ) {
1643               // decrease step if out of bounds
1644               // otherwise the same calculations will be 
1645               // repeated several times
1646               if ( ( u1 > UM1 ) || ( u1 < Um1 ) )
1647                 pasuv[0] *= 0.5;
1648
1649               if ( ( v1 > VM1 ) || ( v1 < Vm1 ) ) 
1650                 pasuv[1] *= 0.5;
1651
1652               if ( ( u2 > UM2 ) || ( u2 < Um2 ) )
1653                 pasuv[2] *= 0.5;
1654
1655               if ( ( v2 > VM2 ) || ( v2 < Vm2 ) )
1656                 pasuv[3] *= 0.5;
1657             }
1658           } // end if(!bStop)
1659           else { //if(bStop)
1660             if(close && (line->NbPoints() >= 1)) { 
1661
1662               if(!bOutOfTangentZone) {
1663                 aSeqOfNewPoint.Append(line->Value(1)); // line end
1664               }
1665               nbIterWithoutAppend = 0;
1666             }
1667             else {
1668               ChoixIso = myIntersectionOn2S.Perform(Param, Rsnld, theChoixIso);
1669
1670               if(myIntersectionOn2S.IsEmpty()) { 
1671                 bStop = !myIntersectionOn2S.IsTangent();
1672                 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1673               }
1674               else {
1675                 Standard_Boolean bAddPoint = Standard_True;
1676                 Standard_Boolean pointisvalid = Standard_False;
1677
1678                 previousPoint = myIntersectionOn2S.Point();
1679                 Standard_Real u1,v1,u2,v2; 
1680                 previousPoint.Parameters(u1,v1,u2,v2); 
1681
1682                 if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 && 
1683                   v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
1684                   v1 >= Vm1  && v2 >= Vm2) 
1685                   pointisvalid = Standard_True;
1686
1687                 if(pointisvalid) {
1688
1689                   if(line->NbPoints() >= 1) {
1690                     gp_Pnt pf = line->Value(1).Value();
1691                     gp_Pnt pl = previousPoint.Value(); 
1692
1693                     if(pf.Distance(pl) < Precision::Confusion()) { 
1694                       dIncKey++; 
1695                       if(dIncKey == 5000) return bOutOfTangentZone; 
1696                       else bAddPoint = Standard_False;
1697                     }
1698                   }
1699
1700                   if(bAddPoint && !bOutOfTangentZone) {
1701                     aSeqOfNewPoint.Append(previousPoint);
1702                     nbIterWithoutAppend = 0;
1703                   }
1704                 }
1705               }
1706             }
1707           }
1708           break;
1709         }
1710       default:
1711         {
1712           break;
1713         }
1714       }
1715     }
1716   }
1717   Standard_Boolean bExtendLine = Standard_False;
1718   Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.; 
1719
1720   Standard_Integer pit = 0;
1721
1722   for(pit = 0; !bExtendLine && (pit < 2); pit++) {
1723     if(pit == 0)
1724       previousPoint.Parameters(u1,v1,u2,v2); 
1725     else {
1726       if(aSeqOfNewPoint.Length() > 0)
1727         aSeqOfNewPoint.Value(aSeqOfNewPoint.Length()).Parameters(u1,v1,u2,v2); 
1728       else
1729         break;
1730     }
1731
1732     if(((u1 - Um1) < ResoU1) ||
1733       ((UM1 - u1) < ResoU1) ||
1734       ((u2 - Um2) < ResoU2) ||
1735       ((UM2 - u2) < ResoU2) ||
1736       ((v1 - Vm1) < ResoV1) ||
1737       ((VM1 - v1) < ResoV1) ||
1738       ((v2 - Vm2) < ResoV2) ||
1739       ((VM2 - v2) < ResoV2))
1740       bExtendLine = Standard_True;
1741   }
1742
1743   if(!bExtendLine) {
1744     //    if(Status == IntWalk_OK || Status == IntWalk_ArretSurPoint) {
1745     if(Status == IntWalk_OK) {
1746       bExtendLine = Standard_True;
1747
1748       if(aSeqOfNewPoint.Length() > 1) {
1749         TColStd_Array1OfReal FirstParams(0, 3), LastParams(0, 3), Resolutions(0, 3);
1750         Resolutions(0) = ResoU1; Resolutions(1) = ResoV1; Resolutions(2) = ResoU2; Resolutions(3) = ResoV2;
1751
1752         aSeqOfNewPoint(1).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1753           FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1754         aSeqOfNewPoint(aSeqOfNewPoint.Length()).Parameters(LastParams.ChangeValue(0), 
1755           LastParams.ChangeValue(1),
1756           LastParams.ChangeValue(2), 
1757           LastParams.ChangeValue(3)); 
1758         Standard_Integer indexofiso = 0;
1759
1760         if(theChoixIso == IntImp_UIsoparametricOnCaro1) indexofiso = 0;
1761         if(theChoixIso == IntImp_VIsoparametricOnCaro1) indexofiso = 1;
1762         if(theChoixIso == IntImp_UIsoparametricOnCaro2) indexofiso = 2;
1763         if(theChoixIso == IntImp_VIsoparametricOnCaro2) indexofiso = 3;
1764
1765         Standard_Integer afirstindex = (indexofiso < 2) ? 0 : 2;
1766         gp_Vec2d aTangentZoneDir(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)),
1767           gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1)));
1768
1769         gp_Dir2d anIsoDir(0, 1);
1770
1771         if((indexofiso == 1) || (indexofiso == 3))
1772           anIsoDir = gp_Dir2d(1, 0);
1773
1774         if(aTangentZoneDir.SquareMagnitude() > gp::Resolution()) {
1775           Standard_Real piquota = M_PI*0.25;
1776
1777           if(fabs(aTangentZoneDir.Angle(anIsoDir)) > piquota) {
1778             Standard_Integer ii = 1, nextii = 2;
1779             gp_Vec2d d1(0, 0);
1780             Standard_Real asqresol = gp::Resolution();
1781             asqresol *= asqresol;
1782
1783             do {
1784               aSeqOfNewPoint(ii).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1785                 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1786               aSeqOfNewPoint(ii + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1787                 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1788               d1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1789                 FirstParams.Value(afirstindex + 1)),
1790                 gp_Pnt2d(LastParams.Value(afirstindex),
1791                 LastParams.Value(afirstindex + 1)));
1792               ii++;
1793             }
1794             while((d1.SquareMagnitude() < asqresol) &&
1795               (ii < aSeqOfNewPoint.Length()));
1796
1797             nextii = ii;
1798
1799             while(nextii < aSeqOfNewPoint.Length()) {
1800
1801               gp_Vec2d nextd1(0, 0);
1802               Standard_Integer jj = nextii;
1803
1804               do {
1805                 aSeqOfNewPoint(jj).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1806                   FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1807                 aSeqOfNewPoint(jj + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1808                   LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1809                 nextd1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1810                   FirstParams.Value(afirstindex + 1)),
1811                   gp_Pnt2d(LastParams.Value(afirstindex),
1812                   LastParams.Value(afirstindex + 1)));
1813                 jj++;
1814
1815               }
1816               while((nextd1.SquareMagnitude() < asqresol) &&
1817                 (jj < aSeqOfNewPoint.Length()));
1818               nextii = jj;
1819
1820               if(fabs(d1.Angle(nextd1)) > piquota) {
1821                 bExtendLine = Standard_False;
1822                 break;
1823               }
1824               d1 = nextd1;
1825             }
1826           }
1827           // end if(fabs(aTangentZoneDir.Angle(anIsoDir)
1828         }
1829       }
1830     }
1831   }
1832
1833   if(!bExtendLine) {
1834     return Standard_False;
1835   }
1836   Standard_Integer i = 0;
1837
1838   for(i = 1; i <= aSeqOfNewPoint.Length(); i++) {
1839     AddAPoint(line, aSeqOfNewPoint.Value(i));
1840   }
1841
1842   return bOutOfTangentZone;
1843 }
1844
1845 //=======================================================================
1846 //function : DistanceMinimizeByGradient
1847 //purpose  : 
1848 //=======================================================================
1849 Standard_Boolean IntWalk_PWalking::
1850 DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
1851                            const Handle(Adaptor3d_HSurface)& theASurf2,
1852                            Standard_Real& theU1,
1853                            Standard_Real& theV1,
1854                            Standard_Real& theU2,
1855                            Standard_Real& theV2,
1856                            const Standard_Real theStep0U1V1,
1857                            const Standard_Real theStep0U2V2)
1858 {
1859   const Standard_Integer aNbIterMAX = 60;
1860   const Standard_Real aTol = 1.0e-14;
1861   Handle(Geom_Surface) aS1, aS2;
1862
1863   switch(theASurf1->GetType())
1864   {
1865   case GeomAbs_BezierSurface:
1866     aS1 = theASurf1->Surface().Bezier();
1867     break;
1868   case GeomAbs_BSplineSurface:
1869     aS1 = theASurf1->Surface().BSpline();
1870     break;
1871   default:
1872     return Standard_True;
1873   }
1874
1875   switch(theASurf2->GetType())
1876   {
1877   case GeomAbs_BezierSurface:
1878     aS2 = theASurf2->Surface().Bezier();
1879     break;
1880   case GeomAbs_BSplineSurface:
1881     aS2 = theASurf2->Surface().BSpline();
1882     break;
1883   default:
1884     return Standard_True;
1885   }
1886
1887   Standard_Boolean aStatus = Standard_False;
1888
1889   gp_Pnt aP1, aP2;
1890   gp_Vec aD1u, aD1v, aD2U, aD2V;
1891
1892   aS1->D1(theU1, theV1, aP1, aD1u, aD1v);
1893   aS2->D1(theU2, theV2, aP2, aD2U, aD2V);
1894
1895   Standard_Real aSQDistPrev = aP1.SquareDistance(aP2);
1896
1897   gp_Vec aP12(aP1, aP2);
1898
1899   Standard_Real aGradFu(-aP12.Dot(aD1u));
1900   Standard_Real aGradFv(-aP12.Dot(aD1v));
1901   Standard_Real aGradFU( aP12.Dot(aD2U));
1902   Standard_Real aGradFV( aP12.Dot(aD2V));
1903
1904   Standard_Real aSTEPuv = theStep0U1V1, aStepUV = theStep0U2V2;
1905
1906   Standard_Boolean flRepeat = Standard_True;
1907   Standard_Integer aNbIter = aNbIterMAX;
1908
1909   while(flRepeat)
1910   {
1911     Standard_Real anAdd = aGradFu*aSTEPuv;
1912     Standard_Real aPARu = (anAdd >= 0.0)?
1913       (theU1 - Max(anAdd, Epsilon(theU1))) :
1914     (theU1 + Max(-anAdd, Epsilon(theU1)));
1915     anAdd = aGradFv*aSTEPuv;
1916     Standard_Real aPARv = (anAdd >= 0.0)?
1917       (theV1 - Max(anAdd, Epsilon(theV1))) :
1918     (theV1 + Max(-anAdd, Epsilon(theV1)));
1919     anAdd = aGradFU*aStepUV;
1920     Standard_Real aParU = (anAdd >= 0.0)?
1921       (theU2 - Max(anAdd, Epsilon(theU2))) :
1922     (theU2 + Max(-anAdd, Epsilon(theU2)));
1923     anAdd = aGradFV*aStepUV;
1924     Standard_Real aParV = (anAdd >= 0.0)?
1925       (theV2 - Max(anAdd, Epsilon(theV2))) :
1926     (theV2 + Max(-anAdd, Epsilon(theV2)));
1927
1928     gp_Pnt aPt1, aPt2;
1929
1930     aS1->D1(aPARu, aPARv, aPt1, aD1u, aD1v);
1931     aS2->D1(aParU, aParV, aPt2, aD2U, aD2V);
1932
1933     Standard_Real aSQDist = aPt1.SquareDistance(aPt2);
1934
1935     if(aSQDist < aSQDistPrev)
1936     {
1937       aSQDistPrev = aSQDist;
1938       theU1 = aPARu;
1939       theV1 = aPARv;
1940       theU2 = aParU;
1941       theV2 = aParV;
1942
1943       aStatus = aSQDistPrev < aTol;
1944       aSTEPuv *= 1.2;
1945       aStepUV *= 1.2;
1946     }
1947     else
1948     {
1949       if(--aNbIter < 0)
1950       {
1951         flRepeat = Standard_False;
1952       }
1953       else
1954       {
1955         aS1->D1(theU1, theV1, aPt1, aD1u, aD1v);
1956         aS2->D1(theU2, theV2, aPt2, aD2U, aD2V);
1957
1958         gp_Vec aP12(aPt1, aPt2);
1959         aGradFu = -aP12.Dot(aD1u);
1960         aGradFv = -aP12.Dot(aD1v);
1961         aGradFU = aP12.Dot(aD2U);
1962         aGradFV = aP12.Dot(aD2V);
1963         aSTEPuv = theStep0U1V1;
1964         aStepUV = theStep0U2V2;
1965       }
1966     }
1967   }
1968
1969   return aStatus;
1970 }
1971
1972 //=======================================================================
1973 //function : DistanceMinimizeByExtrema
1974 //purpose  : 
1975 //=======================================================================
1976 Standard_Boolean IntWalk_PWalking::
1977 DistanceMinimizeByExtrema(const Handle(Adaptor3d_HSurface)& theASurf, 
1978                           const gp_Pnt& theP0,
1979                           Standard_Real& theU0,
1980                           Standard_Real& theV0,
1981                           const Standard_Real theStep0U,
1982                           const Standard_Real theStep0V)
1983 {
1984   const Standard_Real aTol = 1.0e-14;
1985   gp_Pnt aPS;
1986   gp_Vec aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp;
1987   Standard_Real aSQDistPrev = RealLast();
1988   Standard_Real aU = theU0, aV = theV0;
1989
1990   Standard_Integer aNbIter = 10;
1991   do
1992   {
1993     theASurf->D2(aU, aV, aPS, aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp);
1994
1995     gp_Vec aVec(theP0, aPS);
1996
1997     Standard_Real aSQDist = aVec.SquareMagnitude();
1998
1999     if(aSQDist >= aSQDistPrev)
2000       break;
2001
2002     aSQDistPrev = aSQDist;
2003     theU0 = aU;
2004     theV0 = aV;
2005     aNbIter--;
2006
2007     if(aSQDistPrev < aTol)
2008       break;
2009
2010     //Functions
2011     const Standard_Real aF1 = aD1Su.Dot(aVec), aF2 = aD1Sv.Dot(aVec);
2012
2013     //Derivatives
2014     const Standard_Real aDf1u = aD2Su.Dot(aVec) + aD1Su.Dot(aD1Su),
2015       aDf1v = aD2Su.Dot(aD1Sv),
2016       aDf2u = aDf1v,
2017       aDf2v = aD2Sv.Dot(aVec) + aD1Sv.Dot(aD1Sv);
2018
2019     const Standard_Real aDet = aDf1u*aDf2v - aDf1v*aDf2u;
2020     aU -= theStep0U*(aDf2v*aF1 - aDf1v*aF2)/aDet;
2021     aV += theStep0V*(aDf2u*aF1 - aDf1u*aF2)/aDet;
2022   }
2023   while(aNbIter > 0);
2024
2025   return (aSQDistPrev < aTol);
2026 }
2027
2028 //=======================================================================
2029 //function : SeekPointOnBoundary
2030 //purpose  : 
2031 //=======================================================================
2032 Standard_Boolean IntWalk_PWalking::
2033 SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
2034                     const Handle(Adaptor3d_HSurface)& theASurf2,
2035                     const Standard_Real theU1,
2036                     const Standard_Real theV1,
2037                     const Standard_Real theU2,
2038                     const Standard_Real theV2,
2039                     const Standard_Boolean isTheFirst)
2040 {
2041   const Standard_Real aTol = 1.0e-14;
2042   Standard_Boolean isOK = Standard_False;
2043   Standard_Real U1prec = theU1, V1prec = theV1, U2prec = theU2, V2prec = theV2;
2044
2045   Standard_Boolean flFinish = Standard_False;
2046
2047   Standard_Integer aNbIter = 20;
2048   while(!flFinish)
2049   {
2050     flFinish = Standard_False;
2051     Standard_Boolean aStatus = Standard_False;
2052
2053     do
2054     {
2055       aNbIter--;
2056       aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec);
2057       if(aStatus)
2058       {
2059         break;
2060       }
2061
2062       aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec);
2063       if(aStatus)
2064       {
2065         break;
2066       }
2067
2068       aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec);
2069       if(aStatus)
2070       {
2071         break;
2072       }
2073     }
2074     while(!aStatus && (aNbIter > 0));
2075
2076     if(aStatus)
2077     {
2078       const Standard_Real aTolMax = 1.0e-8;
2079       Standard_Real aTolF = 0.0;
2080
2081       Standard_Real u1 = U1prec, v1 = V1prec, u2 = U2prec, v2 = V2prec;
2082
2083       flFinish = Checking(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec, aTolF);
2084
2085       if(aTolF <= aTolMax)
2086       {
2087         gp_Pnt  aP1 = theASurf1->Value(u1, v1),
2088           aP2 = theASurf2->Value(u2, v2);
2089         gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2090
2091         const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
2092           aSQDist2 = aPInt.SquareDistance(aP2);
2093         if((aSQDist1 < aTol) && (aSQDist2 < aTol))
2094         {
2095           IntSurf_PntOn2S anIP;
2096           anIP.SetValue(aPInt, u1, v1, u2, v2);
2097
2098           if(isTheFirst)
2099             line->InsertBefore(1,anIP);
2100           else
2101             line->Add(anIP);
2102
2103           isOK = Standard_True;
2104         }
2105       }
2106     }
2107     else
2108     {
2109       break;
2110     }
2111
2112     if(aNbIter < 0)
2113       break;
2114   }
2115
2116   return isOK;
2117 }
2118
2119 //=======================================================================
2120 //function : PutToBoundary
2121 //purpose  : 
2122 //=======================================================================
2123 Standard_Boolean IntWalk_PWalking::
2124 PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
2125               const Handle(Adaptor3d_HSurface)& theASurf2)
2126 {
2127   const Standard_Real aTolMin = Precision::Confusion();
2128
2129   Standard_Boolean hasBeenAdded = Standard_False;
2130
2131   const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2132   const Standard_Real aU1bLast = theASurf1->LastUParameter();
2133   const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2134   const Standard_Real aU2bLast = theASurf2->LastUParameter();
2135   const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2136   const Standard_Real aV1bLast = theASurf1->LastVParameter();
2137   const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2138   const Standard_Real aV2bLast = theASurf2->LastVParameter();
2139
2140   Standard_Real aTol = 1.0;
2141   aTol = Min(aTol, aU1bLast - aU1bFirst);
2142   aTol = Min(aTol, aU2bLast - aU2bFirst);
2143   aTol = Min(aTol, aV1bLast - aV1bFirst);
2144   aTol = Min(aTol, aV2bLast - aV2bFirst)*1.0e-3;
2145
2146   if(aTol <= 2.0*aTolMin)
2147     return hasBeenAdded;
2148
2149   Standard_Boolean isNeedAdding = Standard_False;
2150   Standard_Boolean isU1parallel = Standard_False, isV1parallel = Standard_False;
2151   Standard_Boolean isU2parallel = Standard_False, isV2parallel = Standard_False;
2152   IsParallel(line, Standard_True, aTol, isU1parallel, isV1parallel);
2153   IsParallel(line, Standard_False, aTol, isU2parallel, isV2parallel);
2154
2155   const Standard_Integer aNbPnts = line->NbPoints();
2156   Standard_Real u1, v1, u2, v2;
2157   line->Value(1).Parameters(u1, v1, u2, v2);
2158   Standard_Real aDelta = 0.0;
2159
2160   if(!isV1parallel)
2161   {
2162     aDelta = u1 - aU1bFirst;
2163     if((aTolMin < aDelta) && (aDelta < aTol))
2164     {
2165       u1 = aU1bFirst - aDelta;
2166       isNeedAdding = Standard_True;
2167     }
2168     else
2169     {
2170       aDelta = aU1bLast - u1;
2171       if((aTolMin < aDelta) && (aDelta < aTol))
2172       {
2173         u1 = aU1bLast + aDelta;
2174         isNeedAdding = Standard_True;
2175       }
2176     }
2177   }
2178
2179   if(!isV2parallel)
2180   {
2181     aDelta = u2 - aU2bFirst;
2182     if((aTolMin < aDelta) && (aDelta < aTol))
2183     {
2184       u2 = aU2bFirst - aDelta;
2185       isNeedAdding = Standard_True;
2186     }
2187     else
2188     {
2189       aDelta = aU2bLast - u2;
2190       if((aTolMin < aDelta) && (aDelta < aTol))
2191       {
2192         u2 = aU2bLast + aDelta;
2193         isNeedAdding = Standard_True;
2194       }
2195     }
2196   }
2197
2198   if(!isU1parallel)
2199   {
2200     aDelta = v1 - aV1bFirst;
2201     if((aTolMin < aDelta) && (aDelta < aTol))
2202     {
2203       v1 = aV1bFirst - aDelta;
2204       isNeedAdding = Standard_True;
2205     }
2206     else
2207     {
2208       aDelta = aV1bLast - v1;
2209       if((aTolMin < aDelta) && (aDelta < aTol))
2210       {
2211         v1 = aV1bLast + aDelta;
2212         isNeedAdding = Standard_True;
2213       }
2214     }
2215   }
2216
2217   if(!isU2parallel)
2218   {
2219     aDelta = v2 - aV2bFirst;
2220     if((aTolMin < aDelta) && (aDelta < aTol))
2221     {
2222       v2 = aV2bFirst - aDelta;
2223       isNeedAdding = Standard_True;
2224     }
2225     else
2226     {
2227       aDelta = aV2bLast - v2;
2228       if((aTolMin < aDelta) && (aDelta < aTol))
2229       {
2230         v2 = aV2bLast + aDelta;
2231         isNeedAdding = Standard_True;
2232       }
2233     }
2234   }
2235
2236   if(isNeedAdding)
2237   {
2238     hasBeenAdded = 
2239       SeekPointOnBoundary(theASurf1, theASurf2, u1, 
2240       v1, u2, v2, Standard_True);
2241   }
2242
2243   isNeedAdding = Standard_False;
2244   line->Value(aNbPnts).Parameters(u1, v1, u2, v2);
2245
2246   if(!isV1parallel)
2247   {
2248     aDelta = u1 - aU1bFirst;
2249     if((aTolMin < aDelta) && (aDelta < aTol))
2250     {
2251       u1 = aU1bFirst - aDelta;
2252       isNeedAdding = Standard_True;
2253     }
2254     else
2255     {
2256       aDelta = aU1bLast - u1;
2257       if((aTolMin < aDelta) && (aDelta < aTol))
2258       {
2259         u1 = aU1bLast + aDelta;
2260         isNeedAdding = Standard_True;
2261       }
2262     }
2263   }
2264
2265   if(!isV2parallel)
2266   {
2267     aDelta = u2 - aU2bFirst;
2268     if((aTolMin < aDelta) && (aDelta < aTol))
2269     {
2270       u2 = aU2bFirst - aDelta;
2271       isNeedAdding = Standard_True;
2272     }
2273     else
2274     {
2275       aDelta = aU2bLast - u2;
2276       if((aTolMin < aDelta) && (aDelta < aTol))
2277       {
2278         u2 = aU2bLast + aDelta;
2279         isNeedAdding = Standard_True;
2280       }
2281     }
2282   }
2283
2284   if(!isU1parallel)
2285   {
2286     aDelta = v1 - aV1bFirst;
2287     if((aTolMin < aDelta) && (aDelta < aTol))
2288     {
2289       v1 = aV1bFirst - aDelta;
2290       isNeedAdding = Standard_True;
2291     }
2292     else
2293     {
2294       aDelta = aV1bLast - v1;
2295       if((aTolMin < aDelta) && (aDelta < aTol))
2296       {
2297         v1 = aV1bLast + aDelta;
2298         isNeedAdding = Standard_True;
2299       }
2300     }
2301   }
2302
2303   if(!isU2parallel)
2304   {
2305     aDelta = v2 - aV2bFirst;
2306     if((aTolMin < aDelta) && (aDelta < aTol))
2307     {
2308       v2 = aV2bFirst - aDelta;
2309       isNeedAdding = Standard_True;
2310     }
2311     else
2312     {
2313       aDelta = aV2bLast - v2;
2314       if((aTolMin < aDelta) && (aDelta < aTol))
2315       {
2316         v2 = aV2bLast + aDelta;
2317         isNeedAdding = Standard_True;
2318       }
2319     }
2320   }
2321
2322   if(isNeedAdding)
2323   {
2324     hasBeenAdded = 
2325       SeekPointOnBoundary(theASurf1, theASurf2, u1, 
2326       v1, u2, v2, Standard_False);
2327   }
2328
2329   return hasBeenAdded;
2330 }
2331
2332 //=======================================================================
2333 //function : SeekAdditionalPoints
2334 //purpose  : 
2335 //=======================================================================
2336 Standard_Boolean IntWalk_PWalking::
2337 SeekAdditionalPoints( const Handle(Adaptor3d_HSurface)& theASurf1,
2338                      const Handle(Adaptor3d_HSurface)& theASurf2,
2339                      const Standard_Integer theMinNbPoints)
2340 {
2341   const Standard_Real aTol = 1.0e-14;
2342   Standard_Integer aNbPoints = line->NbPoints();
2343   if(aNbPoints > theMinNbPoints)
2344     return Standard_True;
2345
2346   const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2347   const Standard_Real aU1bLast = theASurf1->LastUParameter();
2348   const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2349   const Standard_Real aU2bLast = theASurf2->LastUParameter();
2350   const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2351   const Standard_Real aV1bLast = theASurf1->LastVParameter();
2352   const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2353   const Standard_Real aV2bLast = theASurf2->LastVParameter();
2354
2355
2356   Standard_Boolean isPrecise = Standard_False;
2357
2358   Standard_Real U1prec = 0.0, V1prec = 0.0, U2prec = 0.0, V2prec = 0.0;
2359
2360   Standard_Integer aNbPointsPrev = 0;
2361   while(aNbPoints < theMinNbPoints && (aNbPoints != aNbPointsPrev))
2362   {
2363     aNbPointsPrev = aNbPoints;
2364     for(Standard_Integer fp = 1, lp = 2; fp < aNbPoints; fp = lp + 1)
2365     {
2366       Standard_Real U1f, V1f, U2f, V2f; //first point in 1st and 2nd surafaces
2367       Standard_Real U1l, V1l, U2l, V2l; //last  point in 1st and 2nd surafaces
2368
2369       lp = fp+1;
2370       line->Value(fp).Parameters(U1f, V1f, U2f, V2f);
2371       line->Value(lp).Parameters(U1l, V1l, U2l, V2l);
2372
2373       U1prec = 0.5*(U1f+U1l);
2374       if(U1prec < aU1bFirst)
2375         U1prec = aU1bFirst;
2376       if(U1prec > aU1bLast)
2377         U1prec = aU1bLast;
2378
2379       V1prec = 0.5*(V1f+V1l);
2380       if(V1prec < aV1bFirst)
2381         V1prec = aV1bFirst;
2382       if(V1prec > aV1bLast)
2383         V1prec = aV1bLast;
2384
2385       U2prec = 0.5*(U2f+U2l);
2386       if(U2prec < aU2bFirst)
2387         U2prec = aU2bFirst;
2388       if(U2prec > aU2bLast)
2389         U2prec = aU2bLast;
2390
2391       V2prec = 0.5*(V2f+V2l);
2392       if(V2prec < aV2bFirst)
2393         V2prec = aV2bFirst;
2394       if(V2prec > aV2bLast)
2395         V2prec = aV2bLast;
2396
2397       Standard_Boolean aStatus = Standard_False;
2398       Standard_Integer aNbIter = 5;
2399       do
2400       {
2401         aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec);
2402         if(aStatus)
2403         {
2404           break;
2405         }
2406
2407         aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec);
2408         if(aStatus)
2409         {
2410           break;
2411         }
2412
2413         aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec);
2414         if(aStatus)
2415         {
2416           break;
2417         }
2418       }
2419       while(!aStatus && (--aNbIter > 0));
2420
2421       if(aStatus)
2422       {
2423         gp_Pnt  aP1 = theASurf1->Value(U1prec, V1prec),
2424           aP2 = theASurf2->Value(U2prec, V2prec);
2425         gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2426
2427         const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
2428           aSQDist2 = aPInt.SquareDistance(aP2);
2429
2430         if((aSQDist1 < aTol) && (aSQDist2 < aTol))
2431         {
2432           IntSurf_PntOn2S anIP;
2433           anIP.SetValue(aPInt, U1prec, V1prec, U2prec, V2prec);
2434           line->InsertBefore(lp, anIP);
2435
2436           isPrecise = Standard_True;
2437
2438           if(++aNbPoints >= theMinNbPoints)
2439             break;
2440         }
2441         else
2442         {
2443           lp--;
2444         }
2445       }
2446     }
2447   }
2448
2449   return isPrecise;
2450 }
2451
2452 void IntWalk_PWalking::
2453 RepartirOuDiviser(Standard_Boolean& DejaReparti,
2454                   IntImp_ConstIsoparametric& ChoixIso,
2455                   Standard_Boolean& Arrive) 
2456
2457                   // at the neighborhood of a point, there is a fail of marching 
2458                   // it is required to divide the steps to try to continue
2459                   // if the step is too small if we are on border
2460                   // restart in another direction if it was not done, otherwise stop
2461
2462 {
2463   //  Standard_Integer i;
2464   if (Arrive) {    //restart in the other direction
2465     if (!DejaReparti ) {
2466       Arrive        = Standard_False; 
2467       DejaReparti   = Standard_True;
2468       previousPoint = line->Value(1);
2469       previoustg    = Standard_False;
2470       previousd1    = firstd1;
2471       previousd2    = firstd2;
2472       previousd     = tgdir;
2473       indextg       = line->NbPoints();
2474       tgdir.Reverse();
2475       line->Reverse();
2476
2477       //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg);
2478       sensCheminement = -1;
2479       tgfirst      = tglast;
2480       tglast       = Standard_False;
2481       ChoixIso     = choixIsoSav;
2482 #if 0
2483       pasuv[0]=pasSav[0];
2484       pasuv[1]=pasSav[1];
2485       pasuv[2]=pasSav[2];
2486       pasuv[3]=pasSav[3];
2487 #else 
2488       Standard_Real u1,v1,u2,v2;
2489       Standard_Real U1,V1,U2,V2;
2490       Standard_Integer nn=line->NbPoints();
2491       if(nn>2) { 
2492         line->Value(nn).Parameters(u1,v1,u2,v2);
2493         line->Value(nn-1).Parameters(U1,V1,U2,V2);
2494         pasuv[0]=Abs(u1-U1);
2495         pasuv[1]=Abs(v1-V1);
2496         pasuv[2]=Abs(u2-U2);
2497         pasuv[3]=Abs(v2-V2);
2498       }
2499 #endif
2500
2501     }
2502   }  
2503   else  {
2504     if (    pasuv[0]*0.5 < ResoU1
2505       &&  pasuv[1]*0.5 < ResoV1
2506       &&  pasuv[2]*0.5 < ResoU2
2507       &&  pasuv[3]*0.5 < ResoV2
2508       ) {
2509         if (!previoustg) {
2510           tglast = Standard_True;      // IS IT ENOUGH ????
2511         }
2512
2513         if (!DejaReparti) {  //restart in the other direction
2514           DejaReparti       = Standard_True;
2515           previousPoint     = line->Value(1);
2516           previoustg        = Standard_False;
2517           previousd1        = firstd1;
2518           previousd2        = firstd2;
2519           previousd         = tgdir;
2520           indextg           = line->NbPoints();
2521           tgdir.Reverse();
2522           line->Reverse();
2523
2524           //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg);
2525
2526           sensCheminement   = -1;
2527           tgfirst           = tglast;
2528           tglast            = Standard_False;
2529           ChoixIso          = choixIsoSav;
2530
2531 #if 0 
2532           pasuv[0]=pasSav[0];
2533           pasuv[1]=pasSav[1];
2534           pasuv[2]=pasSav[2];
2535           pasuv[3]=pasSav[3];
2536 #else 
2537           Standard_Real u1,v1,u2,v2;
2538           Standard_Real U1,V1,U2,V2;
2539           Standard_Integer nn=line->NbPoints();
2540           if(nn>2) { 
2541             line->Value(nn).Parameters(u1,v1,u2,v2);
2542             line->Value(nn-1).Parameters(U1,V1,U2,V2);
2543             pasuv[0]=Abs(u1-U1);
2544             pasuv[1]=Abs(v1-V1);
2545             pasuv[2]=Abs(u2-U2);
2546             pasuv[3]=Abs(v2-V2);
2547           }
2548 #endif
2549         }
2550         else Arrive = Standard_True;
2551     }
2552     else {
2553       pasuv[0]*=0.5;
2554       pasuv[1]*=0.5;
2555       pasuv[2]*=0.5;
2556       pasuv[3]*=0.5; 
2557     }
2558   }
2559 }
2560
2561 namespace {
2562   //OCC431(apo): modified ->
2563   static const Standard_Real CosRef2D =  Cos(M_PI/9.0),  AngRef2D = M_PI/2.0; 
2564
2565   static const Standard_Real d = 7.0;
2566 }
2567
2568 IntWalk_StatusDeflection  IntWalk_PWalking::TestDeflection()
2569
2570 // test if vector is observed by calculating an increase of vector 
2571 //     or the previous point and its tangent, the new calculated point and its  
2572 //     tangent; it is possible to find a cube passing by the 2 points and having as a 
2573 //     derivative the tangents of the intersection
2574 //     calculate the point with parameter 0.5 on cube=p1 
2575 //     calculate the medium point of 2 points of intersection=p2
2576 //   if arrow/2<=||p1p2||<= arrow consider that the vector is observed
2577 //   otherwise adjust the step depending on the ratio ||p1p2||/vector
2578 //   and the previous step 
2579 // test if in  2 tangent planes of surfaces there is no too great angle2d 
2580 // grand : if yes divide the step
2581 // test if there is no change of side
2582 //  
2583 {
2584   if(line->NbPoints() ==1 ) { 
2585     STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=STATIC_PRECEDENT_INFLEXION=0;
2586   }
2587
2588   IntWalk_StatusDeflection Status = IntWalk_OK;
2589   Standard_Real FlecheCourante ,Ratio;
2590
2591
2592   const IntSurf_PntOn2S& CurrentPoint = myIntersectionOn2S.Point(); 
2593   //==================================================================================
2594   //=========               S t o p   o n   p o i n t                 ============
2595   //================================================================================== 
2596   if (myIntersectionOn2S.IsTangent())  { 
2597     return IntWalk_ArretSurPoint;  
2598   }
2599
2600   const gp_Dir& TgCourante = myIntersectionOn2S.Direction();
2601
2602   //==================================================================================
2603   //=========   R i s k   o f    i n f l e x i o n   p o i n t  ============
2604   //==================================================================================  
2605   if (TgCourante.Dot(previousd)<0) {
2606     //------------------------------------------------------------
2607     //-- Risk of inflexion point : Divide the step by 2
2608     //-- Initialize STATIC_PRECEDENT_INFLEXION so that 
2609     //-- at the next call to return Pas_OK if there is no 
2610     //-- more risk of the point of inflexion
2611     //------------------------------------------------------------
2612
2613     pasuv[0]*=0.5;
2614     pasuv[1]*=0.5;
2615     pasuv[2]*=0.5;
2616     pasuv[3]*=0.5;
2617     STATIC_PRECEDENT_INFLEXION+=3; 
2618     if (pasuv[0] < ResoU1 && pasuv[1] <ResoV1 && pasuv[2] <ResoU2 && pasuv[3] < ResoV2)
2619       return IntWalk_ArretSurPointPrecedent;
2620     else 
2621       return IntWalk_PasTropGrand;
2622   }
2623
2624   else {
2625     if(STATIC_PRECEDENT_INFLEXION  > 0) { 
2626       STATIC_PRECEDENT_INFLEXION -- ;
2627       return IntWalk_OK;
2628     }
2629   }
2630
2631   //==================================================================================
2632   //=========  D e t e c t    c o n f u s e d    P o in t s       ===========
2633   //==================================================================================
2634
2635   Standard_Real Dist = previousPoint.Value().
2636     SquareDistance(CurrentPoint.Value());
2637
2638
2639   if (Dist < tolconf*tolconf ) { 
2640     pasuv[0] = Max(5.*ResoU1,Min(1.5*pasuv[0],pasInit[0]));
2641     pasuv[1] = Max(5.*ResoV1,Min(1.5*pasuv[1],pasInit[1]));
2642     pasuv[2] = Max(5.*ResoU2,Min(1.5*pasuv[2],pasInit[2]));
2643     pasuv[3] = Max(5.*ResoV2,Min(1.5*pasuv[3],pasInit[3]));
2644     Status = IntWalk_PointConfondu;
2645   }
2646
2647   //==================================================================================
2648   Standard_Real Up1,Vp1,Uc1,Vc1,Du1,Dv1,AbsDu1,AbsDu2,AbsDv1,AbsDv2;
2649   Standard_Real Up2,Vp2,Uc2,Vc2,Du2,Dv2;
2650
2651   previousPoint.Parameters(Up1,Vp1,Up2,Vp2);
2652   CurrentPoint.Parameters(Uc1,Vc1,Uc2,Vc2);               
2653
2654   Du1 = Uc1 - Up1;   Dv1 = Vc1 - Vp1;
2655   Du2 = Uc2 - Up2;   Dv2 = Vc2 - Vp2;
2656
2657   AbsDu1 = Abs(Du1);
2658   AbsDu2 = Abs(Du2);
2659   AbsDv1 = Abs(Dv1);
2660   AbsDv2 = Abs(Dv2);
2661   //=================================================================================
2662   //====   S t e p   o f   p  r o g r e s s i o n (between previous and Current)   =======
2663   //=================================================================================
2664   if (   AbsDu1 < ResoU1 && AbsDv1 < ResoV1 
2665     && AbsDu2 < ResoU2 && AbsDv2 < ResoV2) {
2666       pasuv[0] = ResoU1; pasuv[1] = ResoV1; pasuv[2] = ResoU2; pasuv[3] = ResoV2;
2667       return(IntWalk_ArretSurPointPrecedent);
2668   }
2669   //==================================================================================
2670
2671   Standard_Real tolArea = 100.0;
2672   if (ResoU1 < Precision::PConfusion() ||
2673     ResoV1 < Precision::PConfusion() ||
2674     ResoU2 < Precision::PConfusion() ||
2675     ResoV2 < Precision::PConfusion() )
2676     tolArea =  tolArea*2.0;
2677
2678   Standard_Real Cosi1, CosRef1, Ang1, AngRef1, ResoUV1, Duv1, d1, tolCoeff1;   
2679   Standard_Real Cosi2, CosRef2, Ang2, AngRef2, ResoUV2, Duv2, d2, tolCoeff2;   
2680   Cosi1 = Du1*previousd1.X() + Dv1*previousd1.Y();
2681   Cosi2 = Du2*previousd2.X() + Dv2*previousd2.Y();
2682   Duv1 = Du1*Du1 + Dv1*Dv1;
2683   Duv2 = Du2*Du2 + Dv2*Dv2;
2684   ResoUV1 = ResoU1*ResoU1 + ResoV1*ResoV1;
2685   ResoUV2 = ResoU2*ResoU2 + ResoV2*ResoV2;
2686   //
2687   //modified by NIZNHY-PKV Wed Nov 13 12:25:44 2002 f
2688   //
2689   Standard_Real aMinDiv2=Precision::Confusion();
2690   aMinDiv2=aMinDiv2*aMinDiv2;
2691   //
2692   d1=d;
2693   if (Duv1>aMinDiv2)  {
2694     d1 = Abs(ResoUV1/Duv1);
2695     d1 = Min(Sqrt(d1)*tolArea, d);  
2696   } 
2697   //d1 = Abs(ResoUV1/Duv1); 
2698   //d1 = Min(Sqrt(d1)*tolArea,d);  
2699   //modified by NIZNHY-PKV Wed Nov 13 12:34:30 2002 t
2700   tolCoeff1 = Exp(d1);
2701   //
2702   //modified by NIZNHY-PKV Wed Nov 13 12:34:43 2002 f
2703   d2=d;
2704   if (Duv2>aMinDiv2) {
2705     d2 = Abs(ResoUV2/Duv2); 
2706     d2 = Min(Sqrt(d2)*tolArea,d); 
2707   }
2708   //d2 = Abs(ResoUV2/Duv2); 
2709   //d2 = Min(Sqrt(d2)*tolArea,d);  
2710   //modified by NIZNHY-PKV Wed Nov 13 12:34:53 2002 t
2711   tolCoeff2 = Exp(d2);
2712   CosRef1 = CosRef2D/tolCoeff1;
2713   CosRef2 = CosRef2D/tolCoeff2;
2714   //
2715   //==================================================================================
2716   //== The points are not confused :                                           ==
2717   //== 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 ==
2718   //==                           N o t    T o o    G r e a t (angle in space UV)    ==
2719   //==                           C h a n g e    o f    s i d e                ==
2720   //==================================================================================
2721   if (Status != IntWalk_PointConfondu) { 
2722     if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2) {
2723       pasuv[0]*=0.5;  pasuv[1]*=0.5;  pasuv[2]*=0.5;  pasuv[3]*=0.5;
2724       if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2) { 
2725         return(IntWalk_ArretSurPointPrecedent);
2726       }
2727       else {
2728         pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
2729         return(IntWalk_PasTropGrand);
2730       }
2731     }
2732     const gp_Dir2d& Tg2dcourante1 = myIntersectionOn2S.DirectionOnS1();
2733     const gp_Dir2d& Tg2dcourante2 = myIntersectionOn2S.DirectionOnS2();
2734     Cosi1 = Du1*Tg2dcourante1.X() + Dv1*Tg2dcourante1.Y();
2735     Cosi2 = Du2*Tg2dcourante2.X() + Dv2*Tg2dcourante2.Y();
2736     Ang1 = Abs(previousd1.Angle(Tg2dcourante1));  
2737     Ang2 = Abs(previousd2.Angle(Tg2dcourante2));  
2738     AngRef1 = AngRef2D*tolCoeff1;
2739     AngRef2 = AngRef2D*tolCoeff2;
2740     //-------------------------------------------------------
2741     //-- Test : Angle too great in space UV       -----
2742     //--        Change of  side                      -----
2743     //-------------------------------------------------------
2744     if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2 || Ang1 > AngRef1 || Ang2 > AngRef2) {
2745       pasuv[0]*=0.5;  pasuv[1]*=0.5;  pasuv[2]*=0.5;  pasuv[3]*=0.5;
2746       if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2) 
2747         return(IntWalk_ArretSurPoint);
2748       else 
2749         return(IntWalk_PasTropGrand);
2750     }
2751   }
2752   //<-OCC431(apo)
2753   //==================================================================================
2754   //== D e t e c t i o n   o f    :  Step Too Small 
2755   //==                               STEP TOO Great 
2756   //==================================================================================
2757
2758   //---------------------------------------
2759   //-- Estimate of the vector           --
2760   //---------------------------------------
2761   FlecheCourante =
2762     Sqrt(Abs((previousd.XYZ()-TgCourante.XYZ()).SquareModulus()*Dist))/8.;
2763
2764   if ( FlecheCourante<= fleche*0.5) {     //-- Current step too small
2765     if(FlecheCourante>1e-16) { 
2766       Ratio = 0.5*(fleche/FlecheCourante);
2767     }
2768     else { 
2769       Ratio = 10.0;
2770     }
2771     Standard_Real pasSu1 = pasuv[0];
2772     Standard_Real pasSv1 = pasuv[1];
2773     Standard_Real pasSu2 = pasuv[2];
2774     Standard_Real pasSv2 = pasuv[3];
2775
2776     //-- In  case if 
2777     //-- a point at U+DeltaU is required, ....
2778     //-- return a point at U + Epsilon
2779     //-- Epsilon << DeltaU.
2780
2781     if(pasuv[0]< AbsDu1) pasuv[0] = AbsDu1;
2782     if(pasuv[1]< AbsDv1) pasuv[1] = AbsDv1;
2783     if(pasuv[2]< AbsDu2) pasuv[2] = AbsDu2;
2784     if(pasuv[3]< AbsDv2) pasuv[3] = AbsDv2;
2785
2786     if(pasuv[0]<ResoU1) pasuv[0]=ResoU1;
2787     if(pasuv[1]<ResoV1) pasuv[1]=ResoV1;
2788     if(pasuv[2]<ResoU2) pasuv[2]=ResoU2;
2789     if(pasuv[3]<ResoV2) pasuv[3]=ResoV2;
2790     //-- if(Ratio>10.0 ) { Ratio=10.0; } 
2791     Standard_Real R1,R = pasInit[0]/pasuv[0];
2792     R1= pasInit[1]/pasuv[1];     if(R1<R) R=R1;
2793     R1= pasInit[2]/pasuv[2];     if(R1<R) R=R1;
2794     R1= pasInit[3]/pasuv[3];     if(R1<R) R=R1;
2795     if(Ratio > R) Ratio=R;
2796     pasuv[0] = Min(Ratio*pasuv[0],pasInit[0]);
2797     pasuv[1] = Min(Ratio*pasuv[1],pasInit[1]);
2798     pasuv[2] = Min(Ratio*pasuv[2],pasInit[2]);
2799     pasuv[3] = Min(Ratio*pasuv[3],pasInit[3]);
2800     if (pasuv[0] != pasSu1 || pasuv[2] != pasSu2|| 
2801       pasuv[1] != pasSv1 || pasuv[3] != pasSv2) {
2802         if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
2803           STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
2804           return IntWalk_PasTropGrand; 
2805         }
2806     }
2807     if(Status == IntWalk_OK) { 
2808       STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
2809       //-- Try to increase the step
2810     }
2811     return Status;
2812   }
2813   else {                                //-- CurrentVector > vector*0.5 
2814     if (FlecheCourante > fleche) {      //-- Current step too Great
2815       Ratio = fleche/FlecheCourante; 
2816       pasuv[0] = Ratio*pasuv[0];
2817       pasuv[1] = Ratio*pasuv[1];
2818       pasuv[2] = Ratio*pasuv[2];
2819       pasuv[3] = Ratio*pasuv[3];
2820       //if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
2821       //        STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
2822       return IntWalk_PasTropGrand; 
2823       //}
2824     }
2825     else {                             //-- vector/2  <  CurrentVector <= vector   
2826       Ratio = 0.75 * (fleche / FlecheCourante);
2827     }
2828   }
2829   pasuv[0] = Max(5.*ResoU1,Min(Min(Ratio*AbsDu1,pasuv[0]),pasInit[0]));
2830   pasuv[1] = Max(5.*ResoV1,Min(Min(Ratio*AbsDv1,pasuv[1]),pasInit[1]));
2831   pasuv[2] = Max(5.*ResoU2,Min(Min(Ratio*AbsDu2,pasuv[2]),pasInit[2]));
2832   pasuv[3] = Max(5.*ResoV2,Min(Min(Ratio*AbsDv2,pasuv[3]),pasInit[3]));
2833   if(Status == IntWalk_OK) STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
2834   return Status;
2835 }
2836
2837 Standard_Boolean IntWalk_PWalking::
2838 TestArret(const Standard_Boolean DejaReparti,
2839           TColStd_Array1OfReal& Param,
2840           IntImp_ConstIsoparametric&  ChoixIso)
2841
2842           //
2843           // test if the point of intersection set by these parameters remains in the 
2844           // natural domain of each square.
2845           // if the point outpasses reframe to find the best iso (border)
2846           // that intersects easiest the other square
2847           // otherwise test if closed line is present  
2848           // 
2849 {
2850   Standard_Real Uvd[4],Uvf[4],Epsuv[4],Duv[4],Uvp[4],dv,dv2,ParC[4];
2851   Standard_Real DPc,DPb;
2852   Standard_Integer i = 0, k = 0;
2853   Epsuv[0] = ResoU1;
2854   Epsuv[1] = ResoV1;
2855   Epsuv[2] = ResoU2;
2856   Epsuv[3] = ResoV2;
2857   previousPoint.Parameters(Uvp[0],Uvp[1],Uvp[2],Uvp[3]);
2858
2859   Standard_Real SolParam[4];
2860   myIntersectionOn2S.Point().Parameters(SolParam[0],SolParam[1],SolParam[2],SolParam[3]);
2861
2862   Standard_Boolean Trouve = Standard_False;
2863
2864   Uvd[0]=Um1;   Uvf[0]=UM1;   Uvd[1]=Vm1;   Uvf[1]=VM1;
2865   Uvd[2]=Um2;   Uvf[2]=UM2;   Uvd[3]=Vm2;   Uvf[3]=VM2;
2866
2867   Standard_Integer im1;
2868   for ( i = 1,im1 = 0;i<=4;i++,im1++) {
2869     switch(i) { 
2870     case 1: k=2; break;
2871     case 2: k=1; break;
2872     case 3: k=4; break;
2873     case 4: k=3; break;
2874     }
2875     if (Param(i) < (Uvd[im1]-Epsuv[im1]) ||
2876       SolParam[im1] < (Uvd[im1]-Epsuv[im1]))     //--     Current -----  Bound Inf -----  Previous
2877     {
2878       Trouve    = Standard_True;                   //-- 
2879       DPc       = Uvp[im1]-Param(i);               //--     Previous  - Current
2880       DPb       = Uvp[im1]-Uvd[im1];               //--     Previous  - Bound Inf
2881       ParC[im1] = Uvd[im1];                        //--     ParamCorrige
2882       dv        = Param(k)-Uvp[k-1];               //--     Current   - Previous (other Direction)
2883       dv2       = dv*dv;         
2884       if(dv2>RealEpsilon()) {                       //--    Progress at the other Direction ?
2885         Duv[im1]  = DPc*DPb + dv2;
2886         Duv[im1]  = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
2887       }
2888       else {
2889         Duv[im1]=-1.0;                              //--    If no progress, do not change  
2890       }                                             //--    the choice of iso 
2891     }   
2892     else if (Param(i) > (Uvf[im1] + Epsuv[im1]) ||
2893       SolParam[im1] > (Uvf[im1] + Epsuv[im1]))//--    Previous -----  Bound Sup -----  Current
2894     {
2895       Trouve    = Standard_True;                    //-- 
2896       DPc       = Param(i)-Uvp[im1];                //--     Current   - Previous
2897       DPb       = Uvf[im1]-Uvp[im1];                //--     Bound Sup - Previous 
2898       ParC[im1] = Uvf[im1];                         //--     Param Corrige
2899       dv        = Param(k)-Uvp[k-1];                //--     Current   - Previous (other Direction)
2900       dv2       = dv*dv;
2901       if(dv2>RealEpsilon()) {                       //--     Progress in other Direction ?
2902         Duv[im1]  =  DPc*DPb + dv2;
2903         Duv[im1]  = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
2904       }
2905       else {
2906         Duv[im1]=-1.0;                              //--    If no progress, do not change 
2907       }                                             //--    the choice of iso 
2908     }
2909     else { 
2910       Duv[im1]= -1.;
2911       ParC[im1]=Param(i);
2912     }
2913   }
2914
2915   if (Trouve) {
2916     //--------------------------------------------------
2917     //-- One of Parameters u1,v1,u2,v2 is outside of  --
2918     //-- the natural limits.                          -- 
2919     //-- Find the best direction of                   -- 
2920     //-- progress and reframe the parameters.        --
2921     //--------------------------------------------------
2922     Standard_Real ddv = -1.0;
2923     k=-1;
2924     for (i=0;i<=3;i++) {
2925       Param(i+1) = ParC[i];
2926       if(Duv[i]>ddv) { 
2927         ddv = Duv[i];
2928         k=i;
2929       }
2930     }
2931     if(k!=-1) { 
2932       ChoixIso   = ChoixRef[k];
2933     }
2934     else { 
2935       if((ParC[0]<=Uvd[0]+Epsuv[0]) || (ParC[0]>=Uvf[0]-Epsuv[0])) {
2936         ChoixIso = IntImp_UIsoparametricOnCaro1;
2937       }
2938       else if((ParC[1]<=Uvd[1]+Epsuv[1]) || (ParC[1]>=Uvf[1]-Epsuv[1])) {
2939         ChoixIso = IntImp_VIsoparametricOnCaro1;
2940       }
2941       else if((ParC[2]<=Uvd[2]+Epsuv[2]) || (ParC[2]>=Uvf[2]-Epsuv[2])) {
2942         ChoixIso = IntImp_UIsoparametricOnCaro2;
2943       }
2944       else if((ParC[3]<=Uvd[3]+Epsuv[3]) || (ParC[3]>=Uvf[3]-Epsuv[3])) {
2945         ChoixIso = IntImp_VIsoparametricOnCaro2;
2946       }
2947     }
2948     close = Standard_False;
2949     return Standard_True;
2950   }
2951   else 
2952   {  
2953     if (!DejaReparti) { // find if line closed
2954
2955       Standard_Real u,v;
2956       const IntSurf_PntOn2S& POn2S1=line->Value(1);
2957       //On S1
2958       POn2S1.ParametersOnS1(u,v);
2959       gp_Pnt2d P1uvS1(u,v);
2960       previousPoint.ParametersOnS1(u,v);
2961       gp_Pnt2d PrevuvS1(u,v);
2962       myIntersectionOn2S.Point().ParametersOnS1(u,v);
2963       gp_Pnt2d myIntersuvS1(u,v);
2964       Standard_Boolean close2dS1 = (P1uvS1.XY()-PrevuvS1.XY())*
2965         (P1uvS1.XY()-myIntersuvS1.XY()) < 0.0;
2966       //On S2
2967       POn2S1.ParametersOnS2(u,v);
2968       gp_Pnt2d P1uvS2(u,v);
2969       previousPoint.ParametersOnS2(u,v);
2970       gp_Pnt2d PrevuvS2(u,v);
2971       myIntersectionOn2S.Point().ParametersOnS2(u,v);
2972       gp_Pnt2d myIntersuvS2(u,v);
2973       Standard_Boolean close2dS2 = (P1uvS2.XY()-PrevuvS2.XY())*
2974         (P1uvS2.XY()-myIntersuvS2.XY()) < 0.0;
2975
2976       close = close2dS1 && close2dS2;
2977       return close;
2978     }
2979     else return Standard_False;
2980   }
2981 }
2982