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