6126c81284d1e13fc6b7fb7b3a6f32808f713f67
[occt.git] / src / IntWalk / IntWalk_IWalking_2.gxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19 //-- IntWalk_IWalking_2.gxx
20
21 #ifndef DEB
22 #define No_Standard_RangeError
23 #define No_Standard_OutOfRange
24 #endif
25
26
27 // _______________________________________________
28 //
29 // Cadrage d un point (u, v) dans le domaine naturel d une surface ET mise 
30 // a jour du couple (u, v) pour le calcul du point suivant.
31 //
32 Standard_Boolean IntWalk_IWalking::Cadrage 
33   (math_Vector& BornInf,
34    math_Vector& BornSup,
35    math_Vector& UVap,
36    Standard_Real& Step,
37 //   Standard_Real& StepV,
38    const Standard_Integer StepSign) const 
39
40 // on a toujours :
41 // BorInf(1) <= UVap(1) <= BornSup(1) et BorInf(2) <= UVap(2) <= BornSup(2)
42 // 1) on verifier si le point approche ne depasse pas le domaine naturel de 
43 //  la surface
44 // 2) si c est le cas on cadre le point approche sur frontiere en prenant la
45 //  meilleure direction. On MODIFIE alors le pas d avancement et une des 
46 //  bornes bloquer un des parametres lors du prochain appel a FunctionSetRoot;
47 // 3) on recalcule couple (u, v) approche pour le le calcul du point suivant.
48 // 4) return Standard_True si cadrage, Standard_False si pas de cadrage.
49 {
50   Standard_Real Duvx = previousd2d.X();
51   Standard_Real Duvy = previousd2d.Y();
52
53   if (!reversed) {
54     previousPoint.ParametersOnS2(UVap(1),UVap(2));
55   }
56   else {
57     previousPoint.ParametersOnS1(UVap(1),UVap(2));
58   }
59
60   Standard_Real U1 = UVap(1) + Step * Duvx * StepSign;
61   Standard_Real V1 = UVap(2) + Step * Duvy * StepSign;
62
63
64   Standard_Boolean infu = (U1 <= BornInf(1)+Precision::PConfusion());
65   Standard_Boolean supu = (U1 >= BornSup(1)-Precision::PConfusion());
66   Standard_Boolean infv = (V1 <= BornInf(2)+Precision::PConfusion());
67   Standard_Boolean supv = (V1 >= BornSup(2)-Precision::PConfusion());
68
69   Standard_Real theStepU,theStepV;
70
71   if (!infu && !supu && !infv && !supv) {
72     UVap(1) = U1;
73     UVap(2) = V1;
74     return Standard_False;
75   }
76
77   if ((infu || supu) && (infv || supv)) {
78     if (infu) { // jag 940616
79       if(Duvx) { 
80         theStepU = Abs((BornInf(1) - UVap(1)) / Duvx);  // iso U =BornInf(1)
81       }
82       else { 
83         theStepU = Step; 
84       }
85     }
86     else {
87       if(Duvx) { 
88         theStepU = Abs((BornSup(1) - UVap(1)) / Duvx);  // iso U =BornSup(1)
89       }
90       else { 
91         theStepU = Step;
92       }
93     }
94     if (infv) { // jag 940616
95       if(Duvy) { 
96         theStepV = Abs((BornInf(2) - UVap(2)) / Duvy);  // iso V =BornInf(2)
97       }
98       else { 
99         theStepV = Step;
100       }
101     }
102     else {
103       if(Duvy) { 
104         theStepV = Abs((BornSup(2) - UVap(2)) / Duvy);  // iso V =BornSup(2)
105       }
106       else { 
107         theStepV = Step; 
108       }
109     }
110
111
112     if (theStepU <= theStepV) {
113       Step = theStepU;
114       if (infu) {
115         UVap(1) = BornInf(1);
116         BornSup(1) = BornInf(1);
117       }
118       else {
119         UVap(1) = BornSup(1);
120         BornInf(1) = BornSup(1);
121       }
122       UVap(2) += Step*Duvy*StepSign;
123     }
124     else {
125       Step = theStepV;
126       if (infv) {
127         UVap(2) = BornInf(2);
128         BornSup(2) = BornInf(2); 
129       }
130       else {
131         UVap(2) = BornSup(2);
132         BornInf(2) = BornSup(2); 
133       }
134       UVap(1) += Step*Duvx*StepSign;
135     }
136     return Standard_True;
137   }
138
139   else if (infu) { // jag 940616
140     if(Duvx) { 
141       Standard_Real aStep = Abs((BornInf(1) - UVap(1)) / Duvx);  // iso U =BornInf(1)
142       if(aStep<Step) Step=aStep;
143     }
144     BornSup(1) = BornInf(1);                     // on bloque le parametre
145     UVap(1) = BornInf(1);
146     UVap(2) += Step*Duvy*StepSign;;
147     return Standard_True;
148   }
149   else if (supu) { // jag 940616
150     if(Duvx) { 
151       Standard_Real aStep = Abs((BornSup(1) - UVap(1)) / Duvx);  // iso U =BornSup(1)
152       if(aStep<Step) Step=aStep;
153     }
154     BornInf(1) = BornSup(1);                    // on bloque le parametre
155     UVap(1) = BornSup(1);
156     UVap(2) += Step*Duvy*StepSign;
157     return Standard_True;
158   }
159   else if (infv) { // jag 940616
160     if(Duvy) { 
161       Standard_Real aStep = Abs((BornInf(2) - UVap(2)) / Duvy);  // iso V =BornInf(2) 
162       if(aStep<Step) Step=aStep;
163     }
164     BornSup(2) = BornInf(2);
165     UVap(1) += Step*Duvx*StepSign;
166     UVap(2) = BornInf(2);
167     return Standard_True;
168   }
169   else if (supv) { // jag 940616
170     if(Duvy) { 
171       Standard_Real aStep = Abs((BornSup(2) - UVap(2)) / Duvy);  // iso V =BornSup(2)
172       if(aStep<Step) Step=aStep;
173     }
174     BornInf(2) = BornSup(2);
175     UVap(1) += Step*Duvx*StepSign;
176     UVap(2) = BornSup(2);
177     return Standard_True;
178   }
179   return Standard_True;
180 }
181
182
183 Standard_Boolean IntWalk_IWalking::TestArretPassage
184   (const TColStd_SequenceOfReal& Umult,
185    const TColStd_SequenceOfReal& Vmult,
186    TheIWFunction& sp,
187    math_Vector& UV,
188    Standard_Integer& Irang)
189
190 // Umult et Vmult : tableau des points d arret (ou passant) sur frontiere, ici
191 //          on ne s interesse qu aux points passant.
192 // UV     : le point courant.
193 // Irang  : en sortie : donne l index du point d arret dans uvstart1 ou 0.
194 //          on considere qu on ne risque de passer que sur un seul point
195 //          passant.
196
197
198 // test d arret pour une ligne d intersection OUVERTE
199 // 1) test de passage sur l ensemble des points interieur
200 // 2) test d arret sur l ensemble des points depart
201 // si on detecte un arret on renvoie l index du point d arret (Irang) dans 
202 // l iterateur des points de depart et les parametres associes dans 
203 // l espace UV.
204 {
205   Standard_Real Up, Vp, Du, Dv, Dup, Dvp, Utest,Vtest; 
206   Standard_Integer j, N, ind;
207   Standard_Real tolu = tolerance(1);
208   Standard_Real tolv = tolerance(2);
209   Standard_Real tolu2 = 10.*tolerance(1);
210   Standard_Real tolv2 = 10.*tolerance(2);
211   
212   Standard_Boolean Arrive = Standard_False;
213   
214   // test de passage sur point pouvant demarrer une boucle;les marquer traites
215   // si passe sur la ligne ouverte
216   
217   if (!reversed) {
218     previousPoint.ParametersOnS2(Up,Vp);
219   }
220   else {
221     previousPoint.ParametersOnS1(Up,Vp);
222   }
223
224   for (size_t i = 1; i < wd2.size(); i++) { 
225     if (wd2[i].etat > 0) { 
226       // debug jag 05.04.94
227
228 //      if ((Up-wd2[i].ustart)*(UV(1)-wd2[i].ustart) +
229 //        (Vp-wd2[i].vstart)*(UV(2)-wd2[i].vstart) <= 0)
230       Utest = wd2[i].ustart;
231       Vtest = wd2[i].vstart;
232
233       Du  = UV(1)-Utest;
234       Dv  = UV(2)-Vtest;
235       Dup = Up - Utest;
236       Dvp = Vp - Vtest;
237       
238 //-- lbr le 30 oct 97 
239
240       //IFV for OCC20285
241
242       if ((Abs(Du) < tolu2 && Abs(Dv) < tolv2) ||
243           (Abs(Dup) < tolu2 && Abs(Dvp) < tolv2)) { 
244             
245         wd2[i].etat = -wd2[i].etat;
246       }
247       else {
248         Standard_Real DDu = (UV(1)-Up);
249         Standard_Real DDv = (UV(2)-Vp);
250         Standard_Real DDD = DDu*DDu+DDv*DDv;
251         Standard_Real DD1 = Du*Du+Dv*Dv;
252         if(DD1<=DDD) { 
253           Standard_Real DD2 = Dup*Dup+Dvp*Dvp;
254           if(DD2<=DDD && ((Du*Dup) + (Dv*Dvp*tolu/tolv) <= 0.)) {       
255             wd2[i].etat = -wd2[i].etat;
256           }
257         }
258       }
259     }
260   }
261
262   // test d arret sur point donne en entree et non encore traite
263
264 //  Modified by Sergey KHROMOV - Tue Nov 20 10:55:01 2001 Begin
265 // Check of all path points in the following order:
266 //   * First check all not treated points;
267 //   * After that check of already treated ones.
268   Standard_Integer l;
269
270   //// Modified by jgv, 28.07.2010 for OCC21914 ////
271   // There are several path points between (Up,Vp) and UV
272   // So several path points satisfy the condition
273   // Dup*UV1mUtest + Dvp*UV2mVtest) < 0
274   // We choose from them the path point with
275   // minimum distance to (Up,Vp)
276   TColStd_SequenceOfInteger i_candidates;
277   TColStd_SequenceOfReal    SqDist_candidates;
278
279   for (l = 1; l <= 2 && !Arrive; l++) {
280     Standard_Boolean isToCheck;
281
282     for (size_t i = 1; i < wd1.size(); i++) {
283       if (l == 1)
284         isToCheck = (wd1[i].etat > 0);
285       else
286         isToCheck = (wd1[i].etat < 0);
287         
288       if (isToCheck) {
289 //  Modified by Sergey KHROMOV - Tue Nov 20 11:03:16 2001 End
290
291         // debug jag voir avec isg
292
293         Utest = wd1[i].ustart;
294         Vtest = wd1[i].vstart;
295         Dup = Up - Utest;
296         Dvp = Vp - Vtest;
297         if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) {
298           Standard_Real UV1mUtest = UV(1)-Utest;
299           Standard_Real UV2mVtest = UV(2)-Vtest;
300           if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) ||
301              (   Abs(UV1mUtest) < tolu 
302               && Abs(UV2mVtest) < tolv)) {
303             i_candidates.Append(i);
304             SqDist_candidates.Append(Dup*Dup + Dvp*Dvp);
305             /*
306             Irang=i;
307             Arrive = Standard_True;
308             UV(1) = Utest;
309             UV(2) = Vtest;
310             */
311           }
312           else if (nbMultiplicities[i] > 0 && i_candidates.IsEmpty()) {
313             N=0;
314             for (size_t k = 1; k < i; k++) { 
315               N+=nbMultiplicities[k];
316             }
317             for (j = N + 1; j <= N + nbMultiplicities[i]; j++) {
318               if (((Up-Umult(j))*(UV(1)-Umult(j)) +
319                    (Vp-Vmult(j))*(UV(2)-Vmult(j)) < 0) ||
320                   (Abs(UV(1)-Umult(j)) < tolu &&
321                    Abs(UV(2)-Vmult(j)) < tolv)) {
322                 Irang=i;
323                 Arrive = Standard_True;
324                 UV(1) = Utest;
325                 UV(2) = Vtest;
326                 break;
327               }
328             }
329           }
330           if (Arrive) {
331             Standard_Real abidF[1], abidD[1][2];
332             math_Vector bidF(abidF,1,1);
333             math_Matrix bidD(abidD,1,1,1,2);
334         sp.Values(UV,bidF,bidD);
335             break;
336           }
337         }
338       }
339     } //end of for (i = 1; i < wd1.size(); i++)
340     if (!i_candidates.IsEmpty())
341       {
342         Standard_Real MinSqDist = RealLast();
343         for (ind = 1; ind <= i_candidates.Length(); ind++)
344           if (SqDist_candidates(ind) < MinSqDist)
345             {
346               MinSqDist = SqDist_candidates(ind);
347               Irang = i_candidates(ind);
348             }
349         Arrive = Standard_True;
350         UV(1) = wd1[Irang].ustart;
351         UV(2) = wd1[Irang].vstart;
352       }
353   } //end of for (l = 1; l <= 2 && !Arrive; l++)
354   return  Arrive;
355 }
356
357 Standard_Boolean IntWalk_IWalking::TestArretPassage
358   (const TColStd_SequenceOfReal& Umult,
359    const TColStd_SequenceOfReal& Vmult,
360    const math_Vector& UV, 
361    const Standard_Integer Index, 
362    Standard_Integer& Irang)
363 {
364 // Umult, Vmult : tableau des points d arret (ou passant) sur frontiere, ici
365 //          on ne s interesse qu aux points passant.
366 // UV     : le point courant.
367 // Index  : l index du point de demarrage dans uvstart2 de la ligne en cours
368 //          (c est un point interieur).
369 // Irang  : en sortie : donne l index du point passant dans uvstart1 ou 0.
370 //          on considere qu on ne risque de passer que sur un seul point
371 //          passant.
372
373 // test d arret pour une ligne d intersection FERMEE.
374 // 1) test de passage sur l ensemble des points interieur
375 // 2) test de passage sur les points passant.
376
377   Standard_Real Up, Vp, Scal;
378   Standard_Boolean Arrive = Standard_False;
379   Standard_Integer N, k, i;
380   Standard_Real Utest,Vtest;
381   Standard_Real tolu = tolerance(1);
382   Standard_Real tolv = tolerance(2);
383
384   
385   // tests d arret et de passage sur points interieurs.
386
387   if (!reversed) {
388     previousPoint.ParametersOnS2(Up,Vp);
389   }
390   else {
391     previousPoint.ParametersOnS1(Up,Vp);
392   }
393
394   Standard_Real UV1=UV(1);
395   Standard_Real UV2=UV(2);
396
397
398   //-- On met tout le monde ds une boite 0 1  x 0 1 
399   //-- en tourte rigueur il faudrait faire les test en 3d
400
401   Standard_Real deltau=UM-Um;
402   Standard_Real deltav=VM-Vm;
403
404   Up/=deltau; UV1/=deltau; 
405   Vp/=deltav; UV2/=deltav;
406
407   tolu/=deltau;
408   tolv/=deltav;
409
410   Standard_Real tolu2=tolu+tolu;
411   Standard_Real tolv2=tolv+tolv;
412
413   
414   Standard_Real dPreviousCurrent = (Up-UV1)*(Up-UV1)+(Vp-UV2)*(Vp-UV2);
415   for (k = 1; k < (int)wd2.size(); k++) { 
416     if (wd2[k].etat > 0) {
417       Utest = wd2[k].ustart;
418       Vtest = wd2[k].vstart;
419       
420       Utest/=deltau;
421       Vtest/=deltav;
422       
423       Standard_Real UV1mUtest=UV1-Utest;
424       Standard_Real UV2mVtest=UV2-Vtest;
425       if(   (UV1mUtest<tolu2 && UV1mUtest>-tolu2)
426          && (UV2mVtest<tolv2 && UV2mVtest>-tolv2)) { 
427         if(Index!=k) { 
428           //-- cout<<"* etat2 : ("<<k<<")"<<endl;
429           wd2[k].etat=-wd2[k].etat; //-- marque le point comme point de passage 
430         }
431         else {  //-- Index == k
432           //-- cout<<"* Arrive"<<endl;
433           Arrive=Standard_True;
434         }
435       }
436       else { 
437         Standard_Real UpmUtest = (Up-Utest);
438         Standard_Real VpmVtest = (Vp-Vtest);
439         Standard_Real dPreviousStart = (UpmUtest)*(UpmUtest)+(VpmVtest)*(VpmVtest);
440         Standard_Real dCurrentStart  = UV1mUtest * UV1mUtest + UV2mVtest * UV2mVtest;
441
442         Scal=(UpmUtest)*(UV1mUtest)+(VpmVtest)*(UV2mVtest);
443         if( (Abs(UpmUtest)<tolu && Abs(VpmVtest)<tolv)) { 
444           if(Index != k ) { 
445             //-- cout<<"** etat2 : ("<<k<<")"<<endl;
446             wd2[k].etat = -wd2[k].etat;
447           }
448         }
449         else if(Scal<0 && (dPreviousStart+dCurrentStart < dPreviousCurrent)) { 
450           if (Index == k ) { // on a boucle.
451             Arrive = Standard_True;
452             //-- cout<<"** Arrive  : k="<<k<<endl;
453           }
454           else {
455             //-- cout<<"*** etat2 : ("<<k<<")"<<endl;
456             wd2[k].etat = -wd2[k].etat; // marque le point point de passage 
457           }
458         }
459         else if(k!=Index) {
460           if(dPreviousStart < dPreviousCurrent*0.25) { 
461             wd2[k].etat = -wd2[k].etat; // marque le point point de passage 
462             //-- cout<<"**** etat2 : ("<<k<<")"<<endl;
463           }
464           else { 
465             if(dCurrentStart < dPreviousCurrent*0.25) {
466               //-- cout<<"***** etat2 : ("<<k<<")"<<endl;
467               wd2[k].etat = -wd2[k].etat; // marque le point point de passage 
468             }
469             else { 
470               Standard_Real UMidUtest = 0.5*(UV1+Up)-Utest;
471               Standard_Real VMidVtest = 0.5*(UV2+Vp)-Vtest;         
472               Standard_Real dMiddleStart =  UMidUtest* UMidUtest+VMidVtest*VMidVtest;
473
474               if(dMiddleStart < dPreviousCurrent*0.5) { 
475                 //-- cout<<"*********** etat2 : ("<<k<<")"<<endl;
476                 wd2[k].etat = -wd2[k].etat; // marque le point point de passage 
477               }
478             }
479           }
480         }
481       }
482     }
483   }
484
485   // test de passage sur points passant.
486   
487   Irang =0;
488   for (i = 1; i < (int)wd1.size(); i++) {
489     if (wd1[i].etat > 0 && wd1[i].etat < 11) { //test des points passant
490       Utest = wd1[i].ustart;
491       Vtest = wd1[i].vstart;
492       Utest/=deltau;
493       Vtest/=deltav;
494       
495       if (((Up-Utest) * (UV1-Utest) + (Vp-Vtest) * (UV2-Vtest) < 0) ||
496           (Abs(UV1-Utest) < tolu &&  Abs(UV2-Vtest) < tolv)) 
497         Irang = i;
498       else if (nbMultiplicities[i] > 0) {
499         N=0;
500         for (k = 1; k < i; k++) N = N + nbMultiplicities[k];
501         for (Standard_Integer j = N + 1; j <= N + nbMultiplicities[i]; j++) {
502           Standard_Real Umultj = Umult(j)/deltau;
503           Standard_Real Vmultj = Vmult(j)/deltav;         
504           if (((Up-Umultj)*(UV1-Umultj) +
505                (Vp-Vmultj)*(UV2-Vmultj) < 0) ||
506               (Abs(UV1-Umultj) < tolu &&
507                Abs(UV2-Vmultj) < tolv)) {
508             Irang=i;
509             break;
510           }
511         }
512       }
513     }    
514   }
515   return Arrive;
516 }
517
518
519 Standard_Boolean IntWalk_IWalking::TestArretAjout
520   (TheIWFunction& sp,
521    math_Vector& UV, 
522    Standard_Integer& Irang,
523    IntSurf_PntOn2S& Psol) 
524
525 // test d arret sur les points rajoutes 
526 // ces points sont des points sur frontiere naturelle qui n ont pas ete 
527 // donnes en entree
528 // on renvoit : Psol,  le point rajoute.
529 //              Irang, l index dans l iterateur des points rajoutes.
530 //              UV,     parametre du point rajoute.
531 //
532 {
533   Standard_Boolean Arrive = Standard_False;
534   Standard_Real U1,V1;
535   Standard_Real Up,Vp; 
536
537   if (!reversed) {
538     previousPoint.ParametersOnS2(Up,Vp);
539   }
540   else {
541     previousPoint.ParametersOnS1(Up,Vp);
542   }
543
544   Standard_Integer nbAjout = seqAjout.Length();
545   for (Standard_Integer i = 1; i <= nbAjout; i++) {
546     Irang = seqAjout.Value(i);
547
548 // on rajoute le test Abs(Irang) <= lines.Length() pour le cas ou
549 // on ouvre une ligne fermee suite a l ajout 1 point sur cette meme
550 // ligne. De toute facon on a un gros pb , car on va avoir 2 points
551 // rajoutes sur cette ligne...
552
553     if (Abs(Irang) <= lines.Length()) {
554
555       const Handle(IntWalk_TheIWLine)& Line = lines.Value(Abs(Irang));
556       if (Irang>0) 
557         Psol = Line->Value(Line->NbPoints()); 
558       else 
559         Psol = Line->Value(1);
560       if (!reversed) {
561         Psol.ParametersOnS2(U1, V1);
562       }
563       else {
564         Psol.ParametersOnS1(U1, V1);
565       }
566       if (((Up-U1) * (UV(1)-U1) + 
567            (Vp-V1) * (UV(2)-V1)) < 0 ||
568           (Abs(UV(1)-U1) < tolerance(1) &&  
569            Abs(UV(2)-V1) < tolerance(2))) {
570 //jag 940615    Irang= -Abs(Irang); 
571         Arrive = Standard_True; 
572         UV(1) = U1;
573         UV(2) = V1;
574         Standard_Real abidF[1], abidD[1][2];
575         math_Vector bidF(abidF,1,1);
576         math_Matrix bidD(abidD,1,1,1,2);
577     sp.Values(UV,bidF,bidD);
578         break;
579       }
580     }
581   }
582   return Arrive;
583 }
584
585 void IntWalk_IWalking::TestArretCadre
586   (const TColStd_SequenceOfReal& Umult,
587    const TColStd_SequenceOfReal& Vmult,
588    const Handle(IntWalk_TheIWLine)& Line,
589    TheIWFunction& sp,
590    math_Vector& UV,
591    Standard_Integer& Irang)
592
593 // test d arret alors qu on est sur frontiere.
594 // on a essaye tous les tests d  arret et on est arrive.
595 // test d  arret sur les points donne au depart deja marques et sur 
596 // l  ensemble de la ligne courante. Cette ligne peut etre racourcie si
597 // on trouve in point d arret.
598 // Abs(Irang) = index dans l  iterateur des points de depart ou 0
599 //  si Irang <0 , il faut ajouter ce point a la ligne ( pas de Line->Cut)
600 // UV = parametre du point de depart
601 {
602   Standard_Real Scal, Up, Vp, Uc, Vc;
603   Standard_Integer N;
604   Standard_Boolean Found = Standard_False;
605
606
607   Irang =0;
608   for (Standard_Integer i = 1; i < (int)wd1.size(); i++) {
609     if (wd1[i].etat < 0) {
610       N=0; // rang dans UVMult.
611       if (nbMultiplicities[i] > 0) {
612         for (Standard_Integer k = 1; k < i; k++) 
613           N+=nbMultiplicities[k];
614       }
615       if (!reversed) {
616         Line->Value(1).ParametersOnS2(Up,Vp);
617       }
618       else {
619         Line->Value(1).ParametersOnS1(Up,Vp);
620       }
621       Standard_Integer nbp= Line->NbPoints();
622       for (Standard_Integer j = 2; j <= nbp; j++) {
623         if (!reversed) {
624           Line->Value(j).ParametersOnS2(Uc,Vc);
625         }
626         else {
627           Line->Value(j).ParametersOnS1(Uc,Vc);
628         }
629
630         Scal = (Up-wd1[i].ustart) * (Uc-wd1[i].ustart) +
631                (Vp-wd1[i].vstart) * (Vc-wd1[i].vstart);
632         // si on a trouve un point d arret : on arrete la ligne sur ce point.
633         if (Scal < 0) { 
634           Line->Cut(j);  nbp= Line->NbPoints();
635           Irang = i;
636           UV(1) = wd1[Irang].ustart;
637           UV(2) = wd1[Irang].vstart;
638           Found = Standard_True;
639         }
640         else if (Abs(Uc-wd1[i].ustart) < tolerance(1) &&
641                  Abs(Vc-wd1[i].vstart) < tolerance(2) ) {
642           Line->Cut(j);  nbp= Line->NbPoints();
643           Irang=i; 
644           UV(1) = wd1[Irang].ustart;
645           UV(2) = wd1[Irang].vstart;
646           Found = Standard_True;
647         }
648         else if (nbMultiplicities[i] > 0) {
649           for (Standard_Integer k = N+1; k <= N + nbMultiplicities[i]; k++) {
650             Scal = (Up-Umult(k)) * (Uc-Umult(k)) +
651                    (Vp-Vmult(k)) * (Vc-Vmult(k));
652             if (Scal < 0) { 
653               Line->Cut(j);  nbp= Line->NbPoints();
654               Irang=i;
655               UV(1) = wd1[Irang].ustart;
656               UV(2) = wd1[Irang].vstart;
657               Found = Standard_True;
658               break;
659             }
660             else if (Abs(Uc-Umult(k)) < tolerance(1) &&
661                      Abs(Vc-Vmult(k)) < tolerance(2)) {
662               Line->Cut(j);  nbp= Line->NbPoints();
663               Irang=i; 
664               UV(1) = wd1[Irang].ustart;
665               UV(2) = wd1[Irang].vstart;
666               Found = Standard_True;
667               break;
668             }
669           }
670         }
671         if (Found) {
672           Standard_Real abidF[1], abidD[1][2];
673           math_Vector bidF(abidF,1,1);
674           math_Matrix bidD(abidD,1,1,1,2);
675       sp.Values(UV,bidF,bidD);
676           Standard_Integer NBP =  Line->NbPoints();
677           Standard_Integer Indextg;       
678           Line->TangentVector(Indextg);
679           if(Indextg > NBP) { 
680             if(j>3 && j<=NBP+1) { 
681               gp_Vec Dir3d = sp.Direction3d();
682               gp_Vec Dir3d1 = gp_Vec(Line->Value(j-2).Value(),Line->Value(j-1).Value());
683               Standard_Real dot = Dir3d.Dot(Dir3d1);
684               if(dot<0.0) { // Normalement on ne doit pas passer souvent ds cette Fonction !!! 
685                 Dir3d.Reverse();
686                 //-- cout<<" IntWalk_IWalking_2.gxx REVERSE "<<endl;
687               }
688               Line->SetTangentVector(previousd3d,j-1);
689             }
690 #ifdef DEB
691             else { 
692               cout<<" IntWalk_IWalking_2.gxx : bizarrerie 30 10 97 "<<endl;
693             }
694 #endif
695           }
696
697           return;
698         }
699         Up = Uc;
700         Vp = Vc;
701       }
702
703       // et maintenant on compare le dernier point de la ligne et le dernier
704       // point calcule.
705       // il n y aura pas besoin de "Cuter"
706
707       Scal = (Up-wd1[i].ustart) * (UV(1)-wd1[i].ustart) +
708         //      (Vp-wd1[i].vstart) * (UV(2)-wd1[i].vstart);
709       // modified by NIZHNY-MKK  Fri Oct 27 12:29:41 2000
710         (Vp-wd1[i].vstart) * (UV(2)-wd1[i].vstart);
711
712       if (Scal < 0) { 
713         Irang = i;
714         UV(1) = wd1[Irang].ustart;
715         UV(2) = wd1[Irang].vstart;
716         Found = Standard_True;
717       }
718       else if (Abs(UV(1)-wd1[i].ustart) < tolerance(1) &&
719                Abs(UV(2)-wd1[i].vstart) < tolerance(2)) {
720         Irang=i; 
721         UV(1) = wd1[Irang].ustart;
722         UV(2) = wd1[Irang].vstart;
723         Found = Standard_True;
724       }
725       else if (nbMultiplicities[i] > 0) {
726         for (Standard_Integer j = N+1; j <= N+nbMultiplicities[i]; j++) {
727           Scal = (Up-Umult(j)) * (UV(1)-Umult(j)) +
728                  (Vp-Vmult(j)) * (UV(2)-Vmult(j));
729           if (Scal < 0) { 
730             Irang=i;
731             UV(1) = wd1[Irang].ustart;
732             UV(2) = wd1[Irang].vstart;
733             Found = Standard_True;
734             break;
735           }
736           else if (Abs(UV(1)-Umult(j)) < tolerance(1) &&
737                    Abs(UV(2)-Vmult(j)) < tolerance(2)) {
738             Irang=i; 
739             UV(1) = wd1[Irang].ustart;
740             UV(2) = wd1[Irang].vstart;
741             Found = Standard_True;
742             break;
743           }
744         }
745       }
746       if (Found) {
747         Irang = -Irang; // jag 941017
748         Standard_Real abidF[1], abidD[1][2];
749         math_Vector bidF(abidF,1,1);
750         math_Matrix bidD(abidD,1,1,1,2);
751     sp.Values(UV,bidF,bidD);
752         return;
753       }
754     }
755   } 
756 }
757
758