1 //-- IntWalk_IWalking_2.gxx
4 #define No_Standard_RangeError
5 #define No_Standard_OutOfRange
9 // _______________________________________________
11 // Cadrage d un point (u, v) dans le domaine naturel d une surface ET mise
12 // a jour du couple (u, v) pour le calcul du point suivant.
14 Standard_Boolean IntWalk_IWalking::Cadrage
15 (math_Vector& BornInf,
19 // Standard_Real& StepV,
20 const Standard_Integer StepSign) const
23 // BorInf(1) <= UVap(1) <= BornSup(1) et BorInf(2) <= UVap(2) <= BornSup(2)
24 // 1) on verifier si le point approche ne depasse pas le domaine naturel de
26 // 2) si c est le cas on cadre le point approche sur frontiere en prenant la
27 // meilleure direction. On MODIFIE alors le pas d avancement et une des
28 // bornes bloquer un des parametres lors du prochain appel a FunctionSetRoot;
29 // 3) on recalcule couple (u, v) approche pour le le calcul du point suivant.
30 // 4) return Standard_True si cadrage, Standard_False si pas de cadrage.
32 Standard_Real Duvx = previousd2d.X();
33 Standard_Real Duvy = previousd2d.Y();
36 previousPoint.ParametersOnS2(UVap(1),UVap(2));
39 previousPoint.ParametersOnS1(UVap(1),UVap(2));
42 Standard_Real U1 = UVap(1) + Step * Duvx * StepSign;
43 Standard_Real V1 = UVap(2) + Step * Duvy * StepSign;
46 Standard_Boolean infu = (U1 <= BornInf(1)+Precision::PConfusion());
47 Standard_Boolean supu = (U1 >= BornSup(1)-Precision::PConfusion());
48 Standard_Boolean infv = (V1 <= BornInf(2)+Precision::PConfusion());
49 Standard_Boolean supv = (V1 >= BornSup(2)-Precision::PConfusion());
51 Standard_Real theStepU,theStepV;
53 if (!infu && !supu && !infv && !supv) {
56 return Standard_False;
59 if ((infu || supu) && (infv || supv)) {
60 if (infu) { // jag 940616
62 theStepU = Abs((BornInf(1) - UVap(1)) / Duvx); // iso U =BornInf(1)
70 theStepU = Abs((BornSup(1) - UVap(1)) / Duvx); // iso U =BornSup(1)
76 if (infv) { // jag 940616
78 theStepV = Abs((BornInf(2) - UVap(2)) / Duvy); // iso V =BornInf(2)
86 theStepV = Abs((BornSup(2) - UVap(2)) / Duvy); // iso V =BornSup(2)
94 if (theStepU <= theStepV) {
98 BornSup(1) = BornInf(1);
101 UVap(1) = BornSup(1);
102 BornInf(1) = BornSup(1);
104 UVap(2) += Step*Duvy*StepSign;
109 UVap(2) = BornInf(2);
110 BornSup(2) = BornInf(2);
113 UVap(2) = BornSup(2);
114 BornInf(2) = BornSup(2);
116 UVap(1) += Step*Duvx*StepSign;
118 return Standard_True;
121 else if (infu) { // jag 940616
123 Standard_Real aStep = Abs((BornInf(1) - UVap(1)) / Duvx); // iso U =BornInf(1)
124 if(aStep<Step) Step=aStep;
126 BornSup(1) = BornInf(1); // on bloque le parametre
127 UVap(1) = BornInf(1);
128 UVap(2) += Step*Duvy*StepSign;;
129 return Standard_True;
131 else if (supu) { // jag 940616
133 Standard_Real aStep = Abs((BornSup(1) - UVap(1)) / Duvx); // iso U =BornSup(1)
134 if(aStep<Step) Step=aStep;
136 BornInf(1) = BornSup(1); // on bloque le parametre
137 UVap(1) = BornSup(1);
138 UVap(2) += Step*Duvy*StepSign;
139 return Standard_True;
141 else if (infv) { // jag 940616
143 Standard_Real aStep = Abs((BornInf(2) - UVap(2)) / Duvy); // iso V =BornInf(2)
144 if(aStep<Step) Step=aStep;
146 BornSup(2) = BornInf(2);
147 UVap(1) += Step*Duvx*StepSign;
148 UVap(2) = BornInf(2);
149 return Standard_True;
151 else if (supv) { // jag 940616
153 Standard_Real aStep = Abs((BornSup(2) - UVap(2)) / Duvy); // iso V =BornSup(2)
154 if(aStep<Step) Step=aStep;
156 BornInf(2) = BornSup(2);
157 UVap(1) += Step*Duvx*StepSign;
158 UVap(2) = BornSup(2);
159 return Standard_True;
161 return Standard_True;
165 Standard_Boolean IntWalk_IWalking::TestArretPassage
166 (const TColStd_SequenceOfReal& Umult,
167 const TColStd_SequenceOfReal& Vmult,
170 Standard_Integer& Irang)
172 // Umult et Vmult : tableau des points d arret (ou passant) sur frontiere, ici
173 // on ne s interesse qu aux points passant.
174 // UV : le point courant.
175 // Irang : en sortie : donne l index du point d arret dans uvstart1 ou 0.
176 // on considere qu on ne risque de passer que sur un seul point
180 // test d arret pour une ligne d intersection OUVERTE
181 // 1) test de passage sur l ensemble des points interieur
182 // 2) test d arret sur l ensemble des points depart
183 // si on detecte un arret on renvoie l index du point d arret (Irang) dans
184 // l iterateur des points de depart et les parametres associes dans
187 Standard_Real Up, Vp, Du, Dv, Dup, Dvp, Utest,Vtest;
188 Standard_Integer i, j, k, N, ind;
189 Standard_Real tolu = tolerance(1);
190 Standard_Real tolv = tolerance(2);
191 Standard_Real tolu2 = 10.*tolerance(1);
192 Standard_Real tolv2 = 10.*tolerance(2);
194 Standard_Boolean Arrive = Standard_False;
196 // test de passage sur point pouvant demarrer une boucle;les marquer traites
197 // si passe sur la ligne ouverte
200 previousPoint.ParametersOnS2(Up,Vp);
203 previousPoint.ParametersOnS1(Up,Vp);
206 for (i = 1; i <= etat2.Length(); i++) {
208 // debug jag 05.04.94
210 // if ((Up-ustart2(i))*(UV(1)-ustart2(i)) +
211 // (Vp-vstart2(i))*(UV(2)-vstart2(i)) <= 0)
220 //-- lbr le 30 oct 97
225 Standard_Real tolustolv=tolu/tolv;
227 if ((Abs(Du) < tolu2 && Abs(Dv) < tolv2) ||
228 (Abs(Dup) < tolu2 && Abs(Dvp) < tolv2)) {
230 etat2(i) = -etat2(i);
233 Standard_Real DDu = (UV(1)-Up);
234 Standard_Real DDv = (UV(2)-Vp);
235 Standard_Real DDD = DDu*DDu+DDv*DDv;
236 Standard_Real DD1 = Du*Du+Dv*Dv;
238 Standard_Real DD2 = Dup*Dup+Dvp*Dvp;
239 if(DD2<=DDD && ((Du*Dup) + (Dv*Dvp*tolu/tolv) <= 0.)) {
240 etat2(i) = -etat2(i);
247 // test d arret sur point donne en entree et non encore traite
249 // Modified by Sergey KHROMOV - Tue Nov 20 10:55:01 2001 Begin
250 // Check of all path points in the following order:
251 // * First check all not treated points;
252 // * After that check of already treated ones.
255 //// Modified by jgv, 28.07.2010 for OCC21914 ////
256 // There are several path points between (Up,Vp) and UV
257 // So several path points satisfy the condition
258 // Dup*UV1mUtest + Dvp*UV2mVtest) < 0
259 // We choose from them the path point with
260 // minimum distance to (Up,Vp)
261 TColStd_SequenceOfInteger i_candidates;
262 TColStd_SequenceOfReal SqDist_candidates;
264 for (l = 1; l <= 2 && !Arrive; l++) {
265 Standard_Boolean isToCheck;
267 for (i = 1; i <= etat1.Length(); i++) {
269 isToCheck = (etat1(i) > 0);
271 isToCheck = (etat1(i) < 0);
274 // Modified by Sergey KHROMOV - Tue Nov 20 11:03:16 2001 End
276 // debug jag voir avec isg
282 if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) {
283 Standard_Real UV1mUtest = UV(1)-Utest;
284 Standard_Real UV2mVtest = UV(2)-Vtest;
285 if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) ||
286 ( Abs(UV1mUtest) < tolu
287 && Abs(UV2mVtest) < tolv)) {
288 i_candidates.Append(i);
289 SqDist_candidates.Append(Dup*Dup + Dvp*Dvp);
292 Arrive = Standard_True;
297 else if (nbMultiplicities(i) > 0 && i_candidates.IsEmpty()) {
299 for (k = 1; k < i; k++) {
300 N+=nbMultiplicities(k);
302 for (j = N + 1; j <= N + nbMultiplicities(i); j++) {
303 if (((Up-Umult(j))*(UV(1)-Umult(j)) +
304 (Vp-Vmult(j))*(UV(2)-Vmult(j)) < 0) ||
305 (Abs(UV(1)-Umult(j)) < tolu &&
306 Abs(UV(2)-Vmult(j)) < tolv)) {
308 Arrive = Standard_True;
316 static math_Vector bidF(1,1);
317 static math_Matrix bidD(1,1,1,2);
319 Standard_Boolean bidB =
321 sp.Values(UV,bidF,bidD);
326 } //end of for (i = 1; i <= etat1.Length(); i++)
327 if (!i_candidates.IsEmpty())
329 Standard_Real MinSqDist = RealLast();
330 for (ind = 1; ind <= i_candidates.Length(); ind++)
331 if (SqDist_candidates(ind) < MinSqDist)
333 MinSqDist = SqDist_candidates(ind);
334 Irang = i_candidates(ind);
336 Arrive = Standard_True;
337 UV(1) = ustart1(Irang);
338 UV(2) = vstart1(Irang);
340 } //end of for (l = 1; l <= 2 && !Arrive; l++)
344 Standard_Boolean IntWalk_IWalking::TestArretPassage
345 (const TColStd_SequenceOfReal& Umult,
346 const TColStd_SequenceOfReal& Vmult,
347 const math_Vector& UV,
348 const Standard_Integer Index,
349 Standard_Integer& Irang)
351 // Umult, Vmult : tableau des points d arret (ou passant) sur frontiere, ici
352 // on ne s interesse qu aux points passant.
353 // UV : le point courant.
354 // Index : l index du point de demarrage dans uvstart2 de la ligne en cours
355 // (c est un point interieur).
356 // Irang : en sortie : donne l index du point passant dans uvstart1 ou 0.
357 // on considere qu on ne risque de passer que sur un seul point
360 // test d arret pour une ligne d intersection FERMEE.
361 // 1) test de passage sur l ensemble des points interieur
362 // 2) test de passage sur les points passant.
364 Standard_Real Up, Vp, Scal;
365 Standard_Boolean Arrive = Standard_False;
366 Standard_Integer N, k, i;
367 Standard_Real Utest,Vtest;
368 Standard_Real tolu = tolerance(1);
369 Standard_Real tolv = tolerance(2);
372 // tests d arret et de passage sur points interieurs.
375 previousPoint.ParametersOnS2(Up,Vp);
378 previousPoint.ParametersOnS1(Up,Vp);
381 Standard_Real UV1=UV(1);
382 Standard_Real UV2=UV(2);
385 //-- On met tout le monde ds une boite 0 1 x 0 1
386 //-- en tourte rigueur il faudrait faire les test en 3d
388 Standard_Real deltau=UM-Um;
389 Standard_Real deltav=VM-Vm;
391 Up/=deltau; UV1/=deltau;
392 Vp/=deltav; UV2/=deltav;
397 Standard_Real tolu2=tolu+tolu;
398 Standard_Real tolv2=tolv+tolv;
401 Standard_Real dPreviousCurrent = (Up-UV1)*(Up-UV1)+(Vp-UV2)*(Vp-UV2);
402 for (k = 1; k <= etat2.Length(); k++) {
410 Standard_Real UV1mUtest=UV1-Utest;
411 Standard_Real UV2mVtest=UV2-Vtest;
412 if( (UV1mUtest<tolu2 && UV1mUtest>-tolu2)
413 && (UV2mVtest<tolv2 && UV2mVtest>-tolv2)) {
415 //-- cout<<"* etat2 : ("<<k<<")"<<endl;
416 etat2(k)=-etat2(k); //-- marque le point comme point de passage
418 else { //-- Index == k
419 //-- cout<<"* Arrive"<<endl;
420 Arrive=Standard_True;
424 Standard_Real UpmUtest = (Up-Utest);
425 Standard_Real VpmVtest = (Vp-Vtest);
426 Standard_Real dPreviousStart = (UpmUtest)*(UpmUtest)+(VpmVtest)*(VpmVtest);
427 Standard_Real dCurrentStart = UV1mUtest * UV1mUtest + UV2mVtest * UV2mVtest;
429 Scal=(UpmUtest)*(UV1mUtest)+(VpmVtest)*(UV2mVtest);
430 if( (Abs(UpmUtest)<tolu && Abs(VpmVtest)<tolv)) {
432 //-- cout<<"** etat2 : ("<<k<<")"<<endl;
433 etat2(k) = -etat2(k);
436 else if(Scal<0 && (dPreviousStart+dCurrentStart < dPreviousCurrent)) {
437 if (Index == k ) { // on a boucle.
438 Arrive = Standard_True;
439 //-- cout<<"** Arrive : k="<<k<<endl;
442 //-- cout<<"*** etat2 : ("<<k<<")"<<endl;
443 etat2(k) = -etat2(k); // marque le point point de passage
447 if(dPreviousStart < dPreviousCurrent*0.25) {
448 etat2(k) = -etat2(k); // marque le point point de passage
449 //-- cout<<"**** etat2 : ("<<k<<")"<<endl;
452 if(dCurrentStart < dPreviousCurrent*0.25) {
453 //-- cout<<"***** etat2 : ("<<k<<")"<<endl;
454 etat2(k) = -etat2(k); // marque le point point de passage
457 Standard_Real UMidUtest = 0.5*(UV1+Up)-Utest;
458 Standard_Real VMidVtest = 0.5*(UV2+Vp)-Vtest;
459 Standard_Real dMiddleStart = UMidUtest* UMidUtest+VMidVtest*VMidVtest;
461 if(dMiddleStart < dPreviousCurrent*0.5) {
462 //-- cout<<"*********** etat2 : ("<<k<<")"<<endl;
463 etat2(k) = -etat2(k); // marque le point point de passage
472 // test de passage sur points passant.
475 for (i = 1; i <= etat1.Length(); i++) {
476 if (etat1(i) > 0 && etat1(i) < 11) { //test des points passant
482 if (((Up-Utest) * (UV1-Utest) + (Vp-Vtest) * (UV2-Vtest) < 0) ||
483 (Abs(UV1-Utest) < tolu && Abs(UV2-Vtest) < tolv))
485 else if (nbMultiplicities(i) > 0) {
487 for (k = 1; k < i; k++) N = N + nbMultiplicities(k);
488 for (Standard_Integer j = N + 1; j <= N + nbMultiplicities(i); j++) {
489 Standard_Real Umultj = Umult(j)/deltau;
490 Standard_Real Vmultj = Vmult(j)/deltav;
491 if (((Up-Umultj)*(UV1-Umultj) +
492 (Vp-Vmultj)*(UV2-Vmultj) < 0) ||
493 (Abs(UV1-Umultj) < tolu &&
494 Abs(UV2-Vmultj) < tolv)) {
506 Standard_Boolean IntWalk_IWalking::TestArretAjout
509 Standard_Integer& Irang,
510 IntSurf_PntOn2S& Psol)
512 // test d arret sur les points rajoutes
513 // ces points sont des points sur frontiere naturelle qui n ont pas ete
515 // on renvoit : Psol, le point rajoute.
516 // Irang, l index dans l iterateur des points rajoutes.
517 // UV, parametre du point rajoute.
520 Standard_Boolean Arrive = Standard_False;
525 previousPoint.ParametersOnS2(Up,Vp);
528 previousPoint.ParametersOnS1(Up,Vp);
531 Standard_Integer nbAjout = seqAjout.Length();
532 for (Standard_Integer i = 1; i <= nbAjout; i++) {
533 Irang = seqAjout.Value(i);
535 // on rajoute le test Abs(Irang) <= lines.Length() pour le cas ou
536 // on ouvre une ligne fermee suite a l ajout 1 point sur cette meme
537 // ligne. De toute facon on a un gros pb , car on va avoir 2 points
538 // rajoutes sur cette ligne...
540 if (Abs(Irang) <= lines.Length()) {
542 const Handle(IntWalk_TheIWLine)& Line = lines.Value(Abs(Irang));
544 Psol = Line->Value(Line->NbPoints());
546 Psol = Line->Value(1);
548 Psol.ParametersOnS2(U1, V1);
551 Psol.ParametersOnS1(U1, V1);
553 if (((Up-U1) * (UV(1)-U1) +
554 (Vp-V1) * (UV(2)-V1)) < 0 ||
555 (Abs(UV(1)-U1) < tolerance(1) &&
556 Abs(UV(2)-V1) < tolerance(2))) {
557 //jag 940615 Irang= -Abs(Irang);
558 Arrive = Standard_True;
561 static math_Vector bidF(1,1);
562 static math_Matrix bidD(1,1,1,2);
564 Standard_Boolean bidB =
566 sp.Values(UV,bidF,bidD);
574 void IntWalk_IWalking::TestArretCadre
575 (const TColStd_SequenceOfReal& Umult,
576 const TColStd_SequenceOfReal& Vmult,
577 const Handle(IntWalk_TheIWLine)& Line,
580 Standard_Integer& Irang)
582 // test d arret alors qu on est sur frontiere.
583 // on a essaye tous les tests d arret et on est arrive.
584 // test d arret sur les points donne au depart deja marques et sur
585 // l ensemble de la ligne courante. Cette ligne peut etre racourcie si
586 // on trouve in point d arret.
587 // Abs(Irang) = index dans l iterateur des points de depart ou 0
588 // si Irang <0 , il faut ajouter ce point a la ligne ( pas de Line->Cut)
589 // UV = parametre du point de depart
591 Standard_Real Scal, Up, Vp, Uc, Vc;
593 Standard_Boolean Found = Standard_False;
597 for (Standard_Integer i = 1; i <= etat1.Length(); i++) {
599 N=0; // rang dans UVMult.
600 if (nbMultiplicities(i) > 0) {
601 for (Standard_Integer k = 1; k < i; k++)
602 N+=nbMultiplicities(k);
605 Line->Value(1).ParametersOnS2(Up,Vp);
608 Line->Value(1).ParametersOnS1(Up,Vp);
610 Standard_Integer nbp= Line->NbPoints();
611 for (Standard_Integer j = 2; j <= nbp; j++) {
613 Line->Value(j).ParametersOnS2(Uc,Vc);
616 Line->Value(j).ParametersOnS1(Uc,Vc);
619 Scal = (Up-ustart1(i)) * (Uc-ustart1(i)) +
620 (Vp-vstart1(i)) * (Vc-vstart1(i));
621 // si on a trouve un point d arret : on arrete la ligne sur ce point.
623 Line->Cut(j); nbp= Line->NbPoints();
625 UV(1) = ustart1(Irang);
626 UV(2) = vstart1(Irang);
627 Found = Standard_True;
629 else if (Abs(Uc-ustart1(i)) < tolerance(1) &&
630 Abs(Vc-vstart1(i)) < tolerance(2) ) {
631 Line->Cut(j); nbp= Line->NbPoints();
633 UV(1) = ustart1(Irang);
634 UV(2) = vstart1(Irang);
635 Found = Standard_True;
637 else if (nbMultiplicities(i) > 0) {
638 for (Standard_Integer k = N+1; k <= N + nbMultiplicities(i); k++) {
639 Scal = (Up-Umult(k)) * (Uc-Umult(k)) +
640 (Vp-Vmult(k)) * (Vc-Vmult(k));
642 Line->Cut(j); nbp= Line->NbPoints();
644 UV(1) = ustart1(Irang);
645 UV(2) = vstart1(Irang);
646 Found = Standard_True;
649 else if (Abs(Uc-Umult(k)) < tolerance(1) &&
650 Abs(Vc-Vmult(k)) < tolerance(2)) {
651 Line->Cut(j); nbp= Line->NbPoints();
653 UV(1) = ustart1(Irang);
654 UV(2) = vstart1(Irang);
655 Found = Standard_True;
661 static math_Vector bidF(1,1);
662 static math_Matrix bidD(1,1,1,2);
664 Standard_Boolean bidB =
666 sp.Values(UV,bidF,bidD);
667 Standard_Integer NBP = Line->NbPoints();
668 Standard_Integer Indextg;
669 Line->TangentVector(Indextg);
671 if(j>3 && j<=NBP+1) {
672 gp_Vec Dir3d = sp.Direction3d();
673 gp_Vec Dir3d1 = gp_Vec(Line->Value(j-2).Value(),Line->Value(j-1).Value());
674 Standard_Real dot = Dir3d.Dot(Dir3d1);
675 if(dot<0.0) { // Normalement on ne doit pas passer souvent ds cette Fonction !!!
677 //-- cout<<" IntWalk_IWalking_2.gxx REVERSE "<<endl;
679 Line->SetTangentVector(previousd3d,j-1);
683 cout<<" IntWalk_IWalking_2.gxx : bizarrerie 30 10 97 "<<endl;
694 // et maintenant on compare le dernier point de la ligne et le dernier
696 // il n y aura pas besoin de "Cuter"
698 Scal = (Up-ustart1(i)) * (UV(1)-ustart1(i)) +
699 // (Vp-ustart1(i)) * (UV(2)-vstart1(i));
700 // modified by NIZHNY-MKK Fri Oct 27 12:29:41 2000
701 (Vp-vstart1(i)) * (UV(2)-vstart1(i));
705 UV(1) = ustart1(Irang);
706 UV(2) = vstart1(Irang);
707 Found = Standard_True;
709 else if (Abs(UV(1)-ustart1(i)) < tolerance(1) &&
710 Abs(UV(2)-vstart1(i)) < tolerance(2)) {
712 UV(1) = ustart1(Irang);
713 UV(2) = vstart1(Irang);
714 Found = Standard_True;
716 else if (nbMultiplicities(i) > 0) {
717 for (Standard_Integer j = N+1; j <= N+nbMultiplicities(i); j++) {
718 Scal = (Up-Umult(j)) * (UV(1)-Umult(j)) +
719 (Vp-Vmult(j)) * (UV(2)-Vmult(j));
722 UV(1) = ustart1(Irang);
723 UV(2) = vstart1(Irang);
724 Found = Standard_True;
727 else if (Abs(UV(1)-Umult(j)) < tolerance(1) &&
728 Abs(UV(2)-Vmult(j)) < tolerance(2)) {
730 UV(1) = ustart1(Irang);
731 UV(2) = vstart1(Irang);
732 Found = Standard_True;
738 Irang = -Irang; // jag 941017
739 static math_Vector bidF(1,1);
740 static math_Matrix bidD(1,1,1,2);
742 Standard_Boolean bidB =
744 sp.Values(UV,bidF,bidD);