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