1 //-----------------------------
2 //-- IntWalk_PWalking_1.gxx
5 #include <Precision.hxx>
6 #include <math_FunctionSetRoot.hxx>
10 //==================================================================================
11 // function : IntWalk_PWalking::IntWalk_PWalking
13 // estimation des max pas : Pour eviter des changenets
14 // trop brusques lors des changements d isos
15 //==================================================================================
16 void ComputePasInit(Standard_Real *pasuv,
17 Standard_Real Um1,Standard_Real UM1,
18 Standard_Real Vm1,Standard_Real VM1,
19 Standard_Real Um2,Standard_Real UM2,
20 Standard_Real Vm2,Standard_Real VM2,
21 Standard_Real _Um1,Standard_Real _UM1,
22 Standard_Real _Vm1,Standard_Real _VM1,
23 Standard_Real _Um2,Standard_Real _UM2,
24 Standard_Real _Vm2,Standard_Real _VM2,
27 const Standard_Real Increment)
29 Standard_Real du1=Abs(UM1-Um1);
30 Standard_Real dv1=Abs(VM1-Vm1);
31 Standard_Real du2=Abs(UM2-Um2);
32 Standard_Real dv2=Abs(VM2-Vm2);
34 Standard_Real _du1=Abs(_UM1-_Um1);
35 Standard_Real _dv1=Abs(_VM1-_Vm1);
36 Standard_Real _du2=Abs(_UM2-_Um2);
37 Standard_Real _dv2=Abs(_VM2-_Vm2);
39 //-- On limite la reduction de l estimation de la boite uv a 0.01 la boite naturelle
40 //-- du1 : Sur boite des Inter
41 //-- _du1 : Sur espace parametrique
42 if(_du1<1e50 && du1<0.01*_du1) du1=0.01*_du1;
43 if(_dv1<1e50 && dv1<0.01*_dv1) dv1=0.01*_dv1;
44 if(_du2<1e50 && du2<0.01*_du2) du2=0.01*_du2;
45 if(_dv2<1e50 && dv2<0.01*_dv2) dv2=0.01*_dv2;
47 pasuv[0]=Increment*du1;
48 pasuv[1]=Increment*dv1;
49 pasuv[2]=Increment*du2;
50 pasuv[3]=Increment*dv2;
52 //==================================================================================
53 // function : IntWalk_PWalking::IntWalk_PWalking
55 //==================================================================================
56 IntWalk_PWalking::IntWalk_PWalking(const ThePSurface& Caro1,
57 const ThePSurface& Caro2,
58 const Standard_Real TolTangency,
59 const Standard_Real Epsilon,
60 const Standard_Real Deflection,
61 const Standard_Real Increment )
65 close(Standard_False),
69 myIntersectionOn2S(Caro1,Caro2,TolTangency)
71 Standard_Real KELARG=20.;
73 pasMax=Increment*0.2; //-- le 25 juin 99 suite a des pbs de precision
74 Um1 = ThePSurfaceTool::FirstUParameter(Caro1);
75 Vm1 = ThePSurfaceTool::FirstVParameter(Caro1);
76 UM1 = ThePSurfaceTool::LastUParameter(Caro1);
77 VM1 = ThePSurfaceTool::LastVParameter(Caro1);
79 Um2 = ThePSurfaceTool::FirstUParameter(Caro2);
80 Vm2 = ThePSurfaceTool::FirstVParameter(Caro2);
81 UM2 = ThePSurfaceTool::LastUParameter(Caro2);
82 VM2 = ThePSurfaceTool::LastVParameter(Caro2);
84 ResoU1 = ThePSurfaceTool::UResolution(Caro1,Precision::Confusion());
85 ResoV1 = ThePSurfaceTool::VResolution(Caro1,Precision::Confusion());
87 ResoU2 = ThePSurfaceTool::UResolution(Caro2,Precision::Confusion());
88 ResoV2 = ThePSurfaceTool::VResolution(Caro2,Precision::Confusion());
90 Standard_Real NEWRESO;
92 Standard_Real MAXVAL2;
94 MAXVAL = Abs(Um1); MAXVAL2 = Abs(UM1);
95 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
96 NEWRESO = ResoU1 * MAXVAL ;
97 if(NEWRESO > ResoU1 &&NEWRESO<10) { ResoU1 = NEWRESO; }
100 MAXVAL = Abs(Um2); MAXVAL2 = Abs(UM2);
101 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
102 NEWRESO = ResoU2 * MAXVAL ;
103 if(NEWRESO > ResoU2 && NEWRESO<10) { ResoU2 = NEWRESO; }
106 MAXVAL = Abs(Vm1); MAXVAL2 = Abs(VM1);
107 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
108 NEWRESO = ResoV1 * MAXVAL ;
109 if(NEWRESO > ResoV1 && NEWRESO<10) { ResoV1 = NEWRESO; }
112 MAXVAL = Abs(Vm2); MAXVAL2 = Abs(VM2);
113 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
114 NEWRESO = ResoV2 * MAXVAL ;
115 if(NEWRESO > ResoV2 && NEWRESO<10) { ResoV2 = NEWRESO; }
117 pasuv[0]=pasMax*Abs(UM1-Um1);
118 pasuv[1]=pasMax*Abs(VM1-Vm1);
119 pasuv[2]=pasMax*Abs(UM2-Um2);
120 pasuv[3]=pasMax*Abs(VM2-Vm2);
122 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
123 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
124 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
125 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
128 if(ThePSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
129 UM1+=KELARG*pasuv[0]; Um1-=KELARG*pasuv[0];
132 Standard_Real t = UM1-Um1;
133 if(t<ThePSurfaceTool::UPeriod(Caro1)) {
134 t=0.5*(ThePSurfaceTool::UPeriod(Caro1)-t);
135 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
140 if(ThePSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
141 VM1+=KELARG*pasuv[1]; Vm1-=KELARG*pasuv[1];
144 Standard_Real t = VM1-Vm1;
145 if(t<ThePSurfaceTool::VPeriod(Caro1)) {
146 t=0.5*(ThePSurfaceTool::VPeriod(Caro1)-t);
147 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
152 if(ThePSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
153 UM2+=KELARG*pasuv[2]; Um2-=KELARG*pasuv[2];
156 Standard_Real t = UM2-Um2;
157 if(t<ThePSurfaceTool::UPeriod(Caro2)) {
158 t=0.5*(ThePSurfaceTool::UPeriod(Caro2)-t);
159 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
164 if(ThePSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
165 VM2+=KELARG*pasuv[3]; Vm2-=KELARG*pasuv[3];
168 Standard_Real t = VM2-Vm2;
169 if(t<ThePSurfaceTool::VPeriod(Caro2)) {
170 t=0.5*(ThePSurfaceTool::VPeriod(Caro2)-t);
171 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
176 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
178 for (Standard_Integer i = 0; i<=3;i++) {
181 pasInit[i] = pasSav[i] = pasuv[i];
186 //==================================================================================
187 // function : IntWalk_PWalking
189 //==================================================================================
190 IntWalk_PWalking::IntWalk_PWalking(const ThePSurface& Caro1,
191 const ThePSurface& Caro2,
192 const Standard_Real TolTangency,
193 const Standard_Real Epsilon,
194 const Standard_Real Deflection,
195 const Standard_Real Increment,
196 const Standard_Real U1,
197 const Standard_Real V1,
198 const Standard_Real U2,
199 const Standard_Real V2)
203 close(Standard_False),
207 myIntersectionOn2S(Caro1,Caro2,TolTangency)
209 Standard_Real KELARG=20.;
211 pasMax=Increment*0.2; //-- le 25 juin 99 suite a des pbs de precision
213 Um1 = ThePSurfaceTool::FirstUParameter(Caro1);
214 Vm1 = ThePSurfaceTool::FirstVParameter(Caro1);
215 UM1 = ThePSurfaceTool::LastUParameter(Caro1);
216 VM1 = ThePSurfaceTool::LastVParameter(Caro1);
218 Um2 = ThePSurfaceTool::FirstUParameter(Caro2);
219 Vm2 = ThePSurfaceTool::FirstVParameter(Caro2);
220 UM2 = ThePSurfaceTool::LastUParameter(Caro2);
221 VM2 = ThePSurfaceTool::LastVParameter(Caro2);
223 ResoU1 = ThePSurfaceTool::UResolution(Caro1,Precision::Confusion());
224 ResoV1 = ThePSurfaceTool::VResolution(Caro1,Precision::Confusion());
226 ResoU2 = ThePSurfaceTool::UResolution(Caro2,Precision::Confusion());
227 ResoV2 = ThePSurfaceTool::VResolution(Caro2,Precision::Confusion());
229 Standard_Real NEWRESO, MAXVAL, MAXVAL2;
233 if(MAXVAL2 > MAXVAL) {
236 NEWRESO = ResoU1 * MAXVAL ;
237 if(NEWRESO > ResoU1) {
243 if(MAXVAL2 > MAXVAL){
246 NEWRESO = ResoU2 * MAXVAL ;
247 if(NEWRESO > ResoU2) {
253 if(MAXVAL2 > MAXVAL) {
256 NEWRESO = ResoV1 * MAXVAL ;
257 if(NEWRESO > ResoV1) {
263 if(MAXVAL2 > MAXVAL){
266 NEWRESO = ResoV2 * MAXVAL ;
267 if(NEWRESO > ResoV2) {
271 pasuv[0]=pasMax*Abs(UM1-Um1);
272 pasuv[1]=pasMax*Abs(VM1-Vm1);
273 pasuv[2]=pasMax*Abs(UM2-Um2);
274 pasuv[3]=pasMax*Abs(VM2-Vm2);
276 if(ThePSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
277 UM1+=KELARG*pasuv[0];
278 Um1-=KELARG*pasuv[0];
281 Standard_Real t = UM1-Um1;
282 if(t<ThePSurfaceTool::UPeriod(Caro1)) {
283 t=0.5*(ThePSurfaceTool::UPeriod(Caro1)-t);
284 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
290 if(ThePSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
291 VM1+=KELARG*pasuv[1];
292 Vm1-=KELARG*pasuv[1];
295 Standard_Real t = VM1-Vm1;
296 if(t<ThePSurfaceTool::VPeriod(Caro1)) {
297 t=0.5*(ThePSurfaceTool::VPeriod(Caro1)-t);
298 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
303 if(ThePSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
304 UM2+=KELARG*pasuv[2];
305 Um2-=KELARG*pasuv[2];
308 Standard_Real t = UM2-Um2;
309 if(t<ThePSurfaceTool::UPeriod(Caro2)) {
310 t=0.5*(ThePSurfaceTool::UPeriod(Caro2)-t);
311 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
317 if(ThePSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
318 VM2+=KELARG*pasuv[3];
319 Vm2-=KELARG*pasuv[3];
322 Standard_Real t = VM2-Vm2;
323 if(t<ThePSurfaceTool::UPeriod(Caro2)) {
324 t=0.5*(ThePSurfaceTool::VPeriod(Caro2)-t);
325 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
330 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
332 for (Standard_Integer i = 0; i<=3;i++) {
333 pasInit[i] = pasSav[i] = pasuv[i];
336 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
337 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
338 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
339 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
341 TColStd_Array1OfReal Par(1,4);
349 //==================================================================================
350 // function : PerformFirstPoint
352 //==================================================================================
353 Standard_Boolean IntWalk_PWalking::PerformFirstPoint (const TColStd_Array1OfReal& ParDep,
354 IntSurf_PntOn2S& FirstPoint)
357 close = Standard_False;
361 TColStd_Array1OfReal Param(1,4);
363 for (i=1; i<=4; ++i) {
365 Param(i) = ParDep(i);
367 //-- calcul du premier point solution
368 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
370 myIntersectionOn2S.Perform(Param,Rsnld);
371 if (!myIntersectionOn2S.IsDone()) {
372 return Standard_False;
374 if (myIntersectionOn2S.IsEmpty()) {
375 return Standard_False;
377 FirstPoint = myIntersectionOn2S.Point();
378 return Standard_True;
380 //==================================================================================
381 // function : Perform
383 //==================================================================================
384 void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep)
386 Perform(ParDep,Um1,Vm1,Um2,Vm2,UM1,VM1,UM2,VM2);
388 //==================================================================================
389 // function : Perform
391 //==================================================================================
392 void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
393 const Standard_Real u1min,
394 const Standard_Real v1min,
395 const Standard_Real u2min,
396 const Standard_Real v2min,
397 const Standard_Real u1max,
398 const Standard_Real v1max,
399 const Standard_Real u2max,
400 const Standard_Real v2max)
403 Standard_Integer iCnt=0;
404 Standard_Integer i, NbPasOKConseq;
405 Standard_Real UFirst1, VFirst1, ULast1, VLast1, UFirst2, VFirst2, ULast2, VLast2;
406 Standard_Real pasMaxSV[4], aTmp;
407 TColStd_Array1OfReal Param(1,4);
408 IntImp_ConstIsoparametric ChoixIso;
411 done = Standard_False;
415 const ThePSurface& Caro1 =myIntersectionOn2S.Function().AuxillarSurface1();
416 const ThePSurface& Caro2 =myIntersectionOn2S.Function().AuxillarSurface2();
418 UFirst1 = ThePSurfaceTool::FirstUParameter(Caro1);
419 VFirst1 = ThePSurfaceTool::FirstVParameter(Caro1);
420 ULast1 = ThePSurfaceTool::LastUParameter (Caro1);
421 VLast1 = ThePSurfaceTool::LastVParameter (Caro1);
423 UFirst2 = ThePSurfaceTool::FirstUParameter(Caro2);
424 VFirst2 = ThePSurfaceTool::FirstVParameter(Caro2);
425 ULast2 = ThePSurfaceTool::LastUParameter (Caro2);
426 VLast2 = ThePSurfaceTool::LastVParameter (Caro2);
428 ComputePasInit(pasuv,u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max,
429 Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2,pasMax+pasMax);
431 if(pasuv[0]<100*ResoU1) {
434 if(pasuv[1]<100*ResoV1) {
437 if(pasuv[2]<100*ResoU2) {
440 if(pasuv[3]<100*ResoV2) {
444 for (i=0; i<4; ++i) {
448 pasInit[i] = pasSav[i] = pasuv[i];
451 line = new IntSurf_LineOn2S ();
453 for (i=1; i<=4; ++i) {
457 //-- reprise des pas uv lies aux surfaces Caro1 et Caro2
458 //-- pasuv[] et pasSav[] sont modifies lors du cheminement
459 for(i = 0; i < 4; ++i) {
460 pasMaxSV[i] = pasSav[i] = pasuv[i] = pasInit[i];
463 //-- calcul du premier point solution
464 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
466 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld);
467 if (!myIntersectionOn2S.IsDone()) {
471 if (myIntersectionOn2S.IsEmpty()) {
475 if(myIntersectionOn2S.IsTangent()) {
479 Standard_Boolean Arrive, DejaReparti;
480 Standard_Integer IncKey, RejectIndex;
483 DejaReparti = Standard_False;
487 previousPoint = myIntersectionOn2S.Point();
488 previoustg = Standard_False;
489 previousd = myIntersectionOn2S.Direction();
490 previousd1 = myIntersectionOn2S.DirectionOnS1();
491 previousd2 = myIntersectionOn2S.DirectionOnS2();
494 firstd1 = previousd1;
495 firstd2 = previousd2;
496 tgfirst = tglast = Standard_False;
497 choixIsoSav = ChoixIso;
498 //------------------------------------------------------------
499 //-- On Teste si le premier point de cheminement correspond
500 //-- a un point sur frontiere.
501 //-- Dans ce cas, DejaReparti est initialise a True
503 pf = previousPoint.Value();
504 Standard_Boolean bTestFirstPoint = Standard_True;
506 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
507 AddAPoint(line,previousPoint);
509 IntWalk_StatusDeflection Status = IntWalk_OK;
510 Standard_Boolean NoTestDeflection = Standard_False;
511 Standard_Real SvParam[4], f;
512 Standard_Integer LevelOfEmptyInmyIntersectionOn2S=0;
513 Standard_Integer LevelOfPointConfondu = 0;
514 Standard_Integer LevelOfIterWithoutAppend = -1;
516 Arrive = Standard_False;
517 while(!Arrive) {//010
518 LevelOfIterWithoutAppend++;
519 if(LevelOfIterWithoutAppend>20) {
520 Arrive = Standard_True;
524 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
525 LevelOfIterWithoutAppend = 0;
531 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
532 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
533 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
534 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
542 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
545 Standard_Real aIncKey, aEps, dP1, dP2, dP3, dP4;
547 dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
548 dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
549 dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
550 dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
552 aIncKey=5.*(Standard_Real)IncKey;
554 if(ChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < aEps) {
557 if(ChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < aEps) {
560 if(ChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < aEps) {
563 if(ChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < aEps) {
572 //==========================
578 ChoixIso= myIntersectionOn2S.Perform(Param, Rsnld, ChoixIso);
580 if (!myIntersectionOn2S.IsDone()) {
581 //arret de la ligne,division
582 Arrive = Standard_False;
587 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
590 //== Le calcul du point exact a partir de Param(.) est possible
591 if (myIntersectionOn2S.IsEmpty()) {
592 Standard_Real u1,v1,u2,v2;
593 previousPoint.Parameters(u1,v1,u2,v2);
595 Arrive = Standard_False;
596 if(u1<UFirst1 || u1>ULast1) {
597 Arrive=Standard_True;
599 if(u2<UFirst2 || u2>ULast2) {
600 Arrive=Standard_True;
602 if(v1<VFirst1 || v1>VLast1) {
603 Arrive=Standard_True;
605 if(v2<VFirst2 || v2>VLast2) {
606 Arrive=Standard_True;
608 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
609 LevelOfEmptyInmyIntersectionOn2S++;
611 if(LevelOfEmptyInmyIntersectionOn2S>10) {
619 //============================================================
620 //== Un point a ete trouve : T E S T D E F L E C T I O N
621 //============================================================
622 if(NoTestDeflection) {
623 NoTestDeflection = Standard_False;
626 if(--LevelOfEmptyInmyIntersectionOn2S<=0) {
627 LevelOfEmptyInmyIntersectionOn2S=0;
628 if(LevelOfIterWithoutAppend < 10) {
629 Status = TestDeflection();
639 //============================================================
640 //== T r a i t e m e n t s u r S t a t u s ==
641 //============================================================
642 if(LevelOfPointConfondu > 5) {
643 Status = IntWalk_ArretSurPoint;
644 LevelOfPointConfondu = 0;
647 if(Status==IntWalk_OK) {
649 if(NbPasOKConseq >= 5) {
651 Standard_Boolean pastroppetit;
655 pastroppetit=Standard_True;
657 if(pasuv[0]<pasInit[0]) {
658 t = (pasInit[0]-pasuv[0])*0.25;
659 if(t>0.1*pasInit[0]) {
663 pastroppetit=Standard_False;
665 if(pasuv[1]<pasInit[1]) {
666 t = (pasInit[1]-pasuv[1])*0.25;
667 if(t>0.1*pasInit[1]) {
671 pastroppetit=Standard_False;
673 if(pasuv[2]<pasInit[2]){
674 t = (pasInit[2]-pasuv[2])*0.25;
675 if(t>0.1*pasInit[2]) {
679 pastroppetit=Standard_False;
681 if(pasuv[3]<pasInit[3]) {
682 t = (pasInit[3]-pasuv[3])*0.25;
683 if(t>0.1*pasInit[3]) {
687 pastroppetit=Standard_False;
698 pastroppetit=Standard_False;
701 } while(pastroppetit);
703 }//Status==IntWalk_OK
704 else NbPasOKConseq=0;
706 switch(Status) {//007
707 case IntWalk_ArretSurPointPrecedent: {
708 Arrive = Standard_False;
709 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
712 case IntWalk_PasTropGrand: {
717 if(LevelOfIterWithoutAppend > 5) {
718 if(pasSav[0]<pasInit[0]) {
719 pasInit[0]-=(pasInit[0]-pasSav[0])*0.25;
720 LevelOfIterWithoutAppend=0;
722 if(pasSav[1]<pasInit[1]) {
723 pasInit[1]-=(pasInit[1]-pasSav[1])*0.25;
724 LevelOfIterWithoutAppend=0;
726 if(pasSav[2]<pasInit[2]) {
727 pasInit[2]-=(pasInit[2]-pasSav[2])*0.25;
728 LevelOfIterWithoutAppend=0;
730 if(pasSav[3]<pasInit[3]) {
731 pasInit[3]-=(pasInit[3]-pasSav[3])*0.25;
732 LevelOfIterWithoutAppend=0;
737 case IntWalk_PointConfondu: {
738 LevelOfPointConfondu++;
739 if(LevelOfPointConfondu>5) {
740 Standard_Boolean pastroppetit;
743 pastroppetit=Standard_True;
744 if(pasuv[0]<pasInit[0]) {
745 pasuv[0]+=(pasInit[0]-pasuv[0])*0.25;
746 pastroppetit=Standard_False;
748 if(pasuv[1]<pasInit[1]) {
749 pasuv[1]+=(pasInit[1]-pasuv[1])*0.25;
750 pastroppetit=Standard_False;
752 if(pasuv[2]<pasInit[2]) {
753 pasuv[2]+=(pasInit[2]-pasuv[2])*0.25;
754 pastroppetit=Standard_False;
756 if(pasuv[3]<pasInit[3]) {
757 pasuv[3]+=(pasInit[3]-pasuv[3])*0.25;
758 pastroppetit=Standard_False;
769 pastroppetit=Standard_False;
772 } while(pastroppetit);
777 case IntWalk_ArretSurPoint: {//006
778 //=======================================================
779 //== T e s t A r r e t : Cadrage sur Param(.) ==
780 //=======================================================
782 Arrive = TestArret(DejaReparti,Param,ChoixIso);
783 // JMB 30th December 1999.
784 // Some statement below should not be put in comment because they are useful.
785 // See grid CTO 909 A1 which infinitely loops
786 if(Arrive==Standard_False && Status==IntWalk_ArretSurPoint) {
787 Arrive=Standard_True;
789 cout << "Compile avec option DEB :Si Pb d intersection : ";
790 cout << "IntWalk_PWalking_1.gxx (lbr le 1erdec98)"<<endl;
797 //=====================================================
798 //== Param(.) est dans les bornes ==
799 //== et ne finit pas une ligne fermee ==
800 //=====================================================
801 //== Verification sur Le Point Courant de myInters
802 Standard_Boolean pointisvalid = Standard_False;
804 Standard_Real u1,v1,u2,v2;
805 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
807 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
808 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
809 v1 >= Vm1 && v2 >= Vm2) {
810 pointisvalid=Standard_True;
815 previousPoint = myIntersectionOn2S.Point();
816 previoustg = myIntersectionOn2S.IsTangent();
818 previousd = myIntersectionOn2S.Direction();
819 previousd1 = myIntersectionOn2S.DirectionOnS1();
820 previousd2 = myIntersectionOn2S.DirectionOnS2();
822 //=====================================================
823 //== Verification sur Previous Point
825 Standard_Real u1,v1,u2,v2;
826 previousPoint.Parameters(u1,v1,u2,v2);
827 if( u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
828 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
829 v1 >= Vm1 && v2 >= Vm2) {
830 pl = previousPoint.Value();
831 if(bTestFirstPoint) {
832 if(pf.Distance(pl) < 1.e-7){
840 bTestFirstPoint = Standard_False;
844 AddAPoint(line,previousPoint);
846 if(RejectIndex >= 250000) {
850 LevelOfIterWithoutAppend = 0;
854 //====================================================
855 if(Status == IntWalk_ArretSurPoint) {
856 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
859 if (line->NbPoints() == 2) {
860 pasSav[0] = pasuv[0];
861 pasSav[1] = pasuv[1];
862 pasSav[2] = pasuv[2];
863 pasSav[3] = pasuv[3];
870 //================= la ligne est fermee ===============
871 AddAPoint(line,line->Value(1)); //ligne fermee
872 LevelOfIterWithoutAppend=0;
875 //====================================================
876 //== Param n etait pas dans les bornes (a ete recadre)
877 //====================================================
878 Standard_Boolean bPrevNotTangent = !previoustg || !myIntersectionOn2S.IsTangent();
880 IntImp_ConstIsoparametric SauvChoixIso = ChoixIso;
881 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
883 if(!myIntersectionOn2S.IsEmpty()) { //002
884 // debordement sur le carreau reciproque ou intersection en coin
885 if(TestArret(Standard_True,Param,ChoixIso)) {
887 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
888 if(!myIntersectionOn2S.IsEmpty()) {
889 previousPoint = myIntersectionOn2S.Point();
890 previoustg = myIntersectionOn2S.IsTangent();
892 previousd = myIntersectionOn2S.Direction();
893 previousd1 = myIntersectionOn2S.DirectionOnS1();
894 previousd2 = myIntersectionOn2S.DirectionOnS2();
896 pl = previousPoint.Value();
897 if(bTestFirstPoint) {
898 if(pf.Distance(pl) < 1.e-7){
906 bTestFirstPoint = Standard_False;
910 AddAPoint(line,previousPoint);
912 if(RejectIndex >= 250000) {
916 LevelOfIterWithoutAppend=0;
917 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
920 //echec cadrage diviser le pas
921 Arrive = Standard_False;
922 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
923 NoTestDeflection = Standard_True;
924 ChoixIso = SauvChoixIso;
928 // save the last point
929 // to revert to it if the current point is out of bounds
930 IntSurf_PntOn2S previousPointSave = previousPoint;
931 Standard_Boolean previoustgSave = previoustg;
932 gp_Dir previousdSave = previousd;
933 gp_Dir2d previousd1Save = previousd1;
934 gp_Dir2d previousd2Save = previousd2;
936 previousPoint = myIntersectionOn2S.Point();
937 previoustg = myIntersectionOn2S.IsTangent();
938 Arrive = Standard_False;
940 previousd = myIntersectionOn2S.Direction();
941 previousd1 = myIntersectionOn2S.DirectionOnS1();
942 previousd2 = myIntersectionOn2S.DirectionOnS2();
944 //========================================
945 //== Verification sur PreviousPoint @@
947 Standard_Real u1,v1,u2,v2;
948 previousPoint.Parameters(u1,v1,u2,v2);
955 Standard_Boolean bFlag1, bFlag2;
956 Standard_Real aTol2D=1.e-11;
958 bFlag1=u1 >= Um1-aTol2D && v1 >= Vm1-aTol2D && u1 <= UM1+aTol2D && v1 <= VM1+aTol2D;
959 bFlag2=u2 >= Um2-aTol2D && v2 >= Vm2-aTol2D && u2 <= UM2+aTol2D && v2 <= VM2+aTol2D;
960 if (bFlag1 && bFlag2) {
962 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
963 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
964 v1 >= Vm1 && v2 >= Vm2) {
967 pl = previousPoint.Value();
968 if(bTestFirstPoint) {
969 if(pf.Distance(pl) < 1.e-7) {
977 bTestFirstPoint = Standard_False;
980 AddAPoint(line,previousPoint);
982 if(RejectIndex >= 250000) {
986 LevelOfIterWithoutAppend=0;
987 Arrive = Standard_True;
990 // revert to the last correctly calculated point
991 previousPoint = previousPointSave;
992 previoustg = previoustgSave;
993 previousd = previousdSave;
994 previousd1 = previousd1Save;
995 previousd2 = previousd2Save;
999 Standard_Boolean wasExtended = Standard_False;
1001 if(Arrive && myIntersectionOn2S.IsTangent() && bPrevNotTangent) {
1002 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti)) {
1003 wasExtended = Standard_True;
1004 Arrive = Standard_False;
1005 ChoixIso = SauvChoixIso;
1009 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1011 myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() &&
1012 myIntersectionOn2S.IsTangent() && bPrevNotTangent &&
1015 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti)) {
1016 wasExtended = Standard_True;
1017 Arrive = Standard_False;
1018 ChoixIso = SauvChoixIso;
1021 }//else !TestArret() $
1022 } //$$ fin succes cadrage sur frontiere (!myIntersectionOn2S.IsEmpty())
1024 //echec cadrage sur frontiere;division du pas
1025 Arrive = Standard_False;
1026 NoTestDeflection = Standard_True;
1027 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1029 }//$$$ fin cadrage sur frontiere (!close)
1030 } //004 fin TestArret retourne Arrive = True
1031 } // 006case IntWalk_ArretSurPoint: fin Traitement Status = OK ou ArretSurPoint
1032 } //007 switch(Status)
1033 } //008 fin traitement point en court (TEST DEFLECTION)
1034 } //009 fin traitement ligne (else if myIntersectionOn2S.IsDone())
1035 } //010 fin si premier point de depart a permis un cheminement while(!Arrive)
1036 done = Standard_True;
1038 // ===========================================================================================================
1039 // function: ExtendLineInCommonZone
1040 // purpose: Extends already computed line inside tangent zone in the direction given by theChoixIso.
1041 // Returns Standard_True if the line was extended through tangent zone and the last computed point
1042 // is outside the tangent zone (but it is not put into the line). Otherwise returns Standard_False.
1043 // ===========================================================================================================
1044 Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso,
1045 const Standard_Boolean theDirectionFlag)
1047 Standard_Boolean bOutOfTangentZone = Standard_False;
1048 Standard_Boolean bStop = !myIntersectionOn2S.IsTangent();
1049 Standard_Integer dIncKey = 1;
1050 TColStd_Array1OfReal Param(1,4);
1051 IntWalk_StatusDeflection Status = IntWalk_OK;
1052 Standard_Integer nbIterWithoutAppend = 0;
1053 Standard_Integer nbEqualPoints = 0;
1054 Standard_Integer parit = 0;
1055 Standard_Integer uvit = 0;
1056 IntSurf_SequenceOfPntOn2S aSeqOfNewPoint;
1059 nbIterWithoutAppend++;
1061 if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) {
1063 cout<<"Compile with option DEB:";
1064 cout<<"Infinite loop has detected. Stop iterations (IntWalk_PWalking_1.gxx)" << endl;
1066 bStop = Standard_True;
1069 Standard_Real f = 0.;
1071 switch (theChoixIso)
1073 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
1074 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
1075 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
1076 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
1081 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
1083 Standard_Real dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
1084 Standard_Real dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
1085 Standard_Real dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
1086 Standard_Real dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
1088 if(theChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < 1.e-7) dP1 *= (5. * (Standard_Real)dIncKey);
1089 if(theChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < 1.e-7) dP2 *= (5. * (Standard_Real)dIncKey);
1090 if(theChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < 1.e-7) dP3 *= (5. * (Standard_Real)dIncKey);
1091 if(theChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < 1.e-7) dP4 *= (5. * (Standard_Real)dIncKey);
1097 Standard_Real SvParam[4];
1098 IntImp_ConstIsoparametric ChoixIso = theChoixIso;
1100 for(parit = 0; parit < 4; parit++) {
1101 SvParam[parit] = Param(parit+1);
1103 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
1104 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld, theChoixIso);
1106 if (!myIntersectionOn2S.IsDone()) {
1107 return bOutOfTangentZone;
1110 if (myIntersectionOn2S.IsEmpty()) {
1111 return bOutOfTangentZone;
1114 Status = TestDeflection();
1116 if(Status == IntWalk_OK) {
1118 for(uvit = 0; uvit < 4; uvit++) {
1119 if(pasuv[uvit] < pasInit[uvit]) {
1120 pasuv[uvit] = pasInit[uvit];
1126 case IntWalk_ArretSurPointPrecedent:
1128 bStop = Standard_True;
1129 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1132 case IntWalk_PasTropGrand:
1134 for(parit = 0; parit < 4; parit++) {
1135 Param(parit+1) = SvParam[parit];
1137 Standard_Boolean bDecrease = Standard_False;
1139 for(uvit = 0; uvit < 4; uvit++) {
1140 if(pasSav[uvit] < pasInit[uvit]) {
1141 pasInit[uvit] -= (pasInit[uvit] - pasSav[uvit]) * 0.1;
1142 bDecrease = Standard_True;
1146 if(bDecrease) nbIterWithoutAppend--;
1149 case IntWalk_PointConfondu:
1151 for(uvit = 0; uvit < 4; uvit++) {
1152 if(pasuv[uvit] < pasInit[uvit]) {
1153 pasuv[uvit] += (pasInit[uvit] - pasuv[uvit]) * 0.1;
1159 case IntWalk_ArretSurPoint:
1162 bStop = TestArret(theDirectionFlag, Param, ChoixIso);
1167 Standard_Real u11,v11,u12,v12;
1168 myIntersectionOn2S.Point().Parameters(u11,v11,u12,v12);
1169 Standard_Real u21,v21,u22,v22;
1170 previousPoint.Parameters(u21,v21,u22,v22);
1172 if(((fabs(u11-u21) < ResoU1) && (fabs(v11-v21) < ResoV1)) ||
1173 ((fabs(u12-u22) < ResoU2) && (fabs(v12-v22) < ResoV2))) {
1182 bStop = bStop || !myIntersectionOn2S.IsTangent();
1183 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1186 Standard_Boolean pointisvalid = Standard_False;
1187 Standard_Real u1,v1,u2,v2;
1188 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1190 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1191 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1192 v1 >= Vm1 && v2 >= Vm2)
1193 pointisvalid = Standard_True;
1196 previousPoint = myIntersectionOn2S.Point();
1197 previoustg = myIntersectionOn2S.IsTangent();
1200 previousd = myIntersectionOn2S.Direction();
1201 previousd1 = myIntersectionOn2S.DirectionOnS1();
1202 previousd2 = myIntersectionOn2S.DirectionOnS2();
1204 Standard_Boolean bAddPoint = Standard_True;
1206 if(line->NbPoints() >= 1) {
1207 gp_Pnt pf = line->Value(1).Value();
1208 gp_Pnt pl = previousPoint.Value();
1210 if(pf.Distance(pl) < Precision::Confusion()) {
1212 if(dIncKey == 5000) return bOutOfTangentZone;
1213 else bAddPoint = Standard_False;
1218 aSeqOfNewPoint.Append(previousPoint);
1219 nbIterWithoutAppend = 0;
1223 if (line->NbPoints() == 2) {
1224 for(uvit = 0; uvit < 4; uvit++) {
1225 pasSav[uvit] = pasuv[uvit];
1229 if ( !pointisvalid ) {
1230 // decrease step if out of bounds
1231 // otherwise the same calculations will be
1232 // repeated several times
1233 if ( ( u1 > UM1 ) || ( u1 < Um1 ) )
1236 if ( ( v1 > VM1 ) || ( v1 < Vm1 ) )
1239 if ( ( u2 > UM2 ) || ( u2 < Um2 ) )
1242 if ( ( v2 > VM2 ) || ( v2 < Vm2 ) )
1247 if(close && (line->NbPoints() >= 1)) {
1249 if(!bOutOfTangentZone) {
1250 aSeqOfNewPoint.Append(line->Value(1)); // line end
1252 nbIterWithoutAppend = 0;
1255 ChoixIso = myIntersectionOn2S.Perform(Param, Rsnld, theChoixIso);
1257 if(myIntersectionOn2S.IsEmpty()) {
1258 bStop = !myIntersectionOn2S.IsTangent();
1259 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1262 Standard_Boolean bAddPoint = Standard_True;
1263 Standard_Boolean pointisvalid = Standard_False;
1265 previousPoint = myIntersectionOn2S.Point();
1266 Standard_Real u1,v1,u2,v2;
1267 previousPoint.Parameters(u1,v1,u2,v2);
1269 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1270 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1271 v1 >= Vm1 && v2 >= Vm2)
1272 pointisvalid = Standard_True;
1276 if(line->NbPoints() >= 1) {
1277 gp_Pnt pf = line->Value(1).Value();
1278 gp_Pnt pl = previousPoint.Value();
1280 if(pf.Distance(pl) < Precision::Confusion()) {
1282 if(dIncKey == 5000) return bOutOfTangentZone;
1283 else bAddPoint = Standard_False;
1287 if(bAddPoint && !bOutOfTangentZone) {
1288 aSeqOfNewPoint.Append(previousPoint);
1289 nbIterWithoutAppend = 0;
1304 Standard_Boolean bExtendLine = Standard_False;
1305 Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
1307 Standard_Integer pit = 0;
1309 for(pit = 0; !bExtendLine && (pit < 2); pit++) {
1311 previousPoint.Parameters(u1,v1,u2,v2);
1313 if(aSeqOfNewPoint.Length() > 0)
1314 aSeqOfNewPoint.Value(aSeqOfNewPoint.Length()).Parameters(u1,v1,u2,v2);
1319 if(((u1 - Um1) < ResoU1) ||
1320 ((UM1 - u1) < ResoU1) ||
1321 ((u2 - Um2) < ResoU2) ||
1322 ((UM2 - u2) < ResoU2) ||
1323 ((v1 - Vm1) < ResoV1) ||
1324 ((VM1 - v1) < ResoV1) ||
1325 ((v2 - Vm2) < ResoV2) ||
1326 ((VM2 - v2) < ResoV2))
1327 bExtendLine = Standard_True;
1331 // if(Status == IntWalk_OK || Status == IntWalk_ArretSurPoint) {
1332 if(Status == IntWalk_OK) {
1333 bExtendLine = Standard_True;
1335 if(aSeqOfNewPoint.Length() > 1) {
1336 TColStd_Array1OfReal FirstParams(0, 3), LastParams(0, 3), Resolutions(0, 3);
1337 Resolutions(0) = ResoU1; Resolutions(1) = ResoV1; Resolutions(2) = ResoU2; Resolutions(3) = ResoV2;
1339 aSeqOfNewPoint(1).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1340 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1341 aSeqOfNewPoint(aSeqOfNewPoint.Length()).Parameters(LastParams.ChangeValue(0),
1342 LastParams.ChangeValue(1),
1343 LastParams.ChangeValue(2),
1344 LastParams.ChangeValue(3));
1345 Standard_Integer indexofiso = 0;
1347 if(theChoixIso == IntImp_UIsoparametricOnCaro1) indexofiso = 0;
1348 if(theChoixIso == IntImp_VIsoparametricOnCaro1) indexofiso = 1;
1349 if(theChoixIso == IntImp_UIsoparametricOnCaro2) indexofiso = 2;
1350 if(theChoixIso == IntImp_VIsoparametricOnCaro2) indexofiso = 3;
1352 Standard_Integer afirstindex = (indexofiso < 2) ? 0 : 2;
1353 gp_Vec2d aTangentZoneDir(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)),
1354 gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1)));
1356 gp_Dir2d anIsoDir(0, 1);
1358 if((indexofiso == 1) || (indexofiso == 3))
1359 anIsoDir = gp_Dir2d(1, 0);
1361 if(aTangentZoneDir.SquareMagnitude() > gp::Resolution()) {
1362 Standard_Real piquota = M_PI*0.25;
1364 if(fabs(aTangentZoneDir.Angle(anIsoDir)) > piquota) {
1365 Standard_Integer ii = 1, nextii = 2;
1367 Standard_Real asqresol = gp::Resolution();
1368 asqresol *= asqresol;
1371 aSeqOfNewPoint(ii).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1372 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1373 aSeqOfNewPoint(ii + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1374 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1375 d1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1376 FirstParams.Value(afirstindex + 1)),
1377 gp_Pnt2d(LastParams.Value(afirstindex),
1378 LastParams.Value(afirstindex + 1)));
1381 while((d1.SquareMagnitude() < asqresol) &&
1382 (ii < aSeqOfNewPoint.Length()));
1386 while(nextii < aSeqOfNewPoint.Length()) {
1388 gp_Vec2d nextd1(0, 0);
1389 Standard_Integer jj = nextii;
1392 aSeqOfNewPoint(jj).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1393 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1394 aSeqOfNewPoint(jj + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1395 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1396 nextd1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1397 FirstParams.Value(afirstindex + 1)),
1398 gp_Pnt2d(LastParams.Value(afirstindex),
1399 LastParams.Value(afirstindex + 1)));
1403 while((nextd1.SquareMagnitude() < asqresol) &&
1404 (jj < aSeqOfNewPoint.Length()));
1407 if(fabs(d1.Angle(nextd1)) > piquota) {
1408 bExtendLine = Standard_False;
1414 // end if(fabs(aTangentZoneDir.Angle(anIsoDir)
1421 return Standard_False;
1423 Standard_Integer i = 0;
1425 for(i = 1; i <= aSeqOfNewPoint.Length(); i++) {
1426 AddAPoint(line, aSeqOfNewPoint.Value(i));
1429 return bOutOfTangentZone;