0023388: Boolean operations hang up trying to build section of two customer's shapes
[occt.git] / src / IntWalk / IntWalk_PWalking_1.gxx
CommitLineData
b311480e 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
7fd59977 19//-----------------------------
20//-- IntWalk_PWalking_1.gxx
21//--
22
23#include <Precision.hxx>
24#include <math_FunctionSetRoot.hxx>
25
26//#define KELARG 20.0
27
28//==================================================================================
29// function : IntWalk_PWalking::IntWalk_PWalking
30// purpose :
31// estimation des max pas : Pour eviter des changenets
32// trop brusques lors des changements d isos
33//==================================================================================
34void ComputePasInit(Standard_Real *pasuv,
35 Standard_Real Um1,Standard_Real UM1,
36 Standard_Real Vm1,Standard_Real VM1,
37 Standard_Real Um2,Standard_Real UM2,
38 Standard_Real Vm2,Standard_Real VM2,
39 Standard_Real _Um1,Standard_Real _UM1,
40 Standard_Real _Vm1,Standard_Real _VM1,
41 Standard_Real _Um2,Standard_Real _UM2,
42 Standard_Real _Vm2,Standard_Real _VM2,
43 const ThePSurface& ,
44 const ThePSurface& ,
45 const Standard_Real Increment)
46{
47 Standard_Real du1=Abs(UM1-Um1);
48 Standard_Real dv1=Abs(VM1-Vm1);
49 Standard_Real du2=Abs(UM2-Um2);
50 Standard_Real dv2=Abs(VM2-Vm2);
51
52 Standard_Real _du1=Abs(_UM1-_Um1);
53 Standard_Real _dv1=Abs(_VM1-_Vm1);
54 Standard_Real _du2=Abs(_UM2-_Um2);
55 Standard_Real _dv2=Abs(_VM2-_Vm2);
56
57 //-- On limite la reduction de l estimation de la boite uv a 0.01 la boite naturelle
58 //-- du1 : Sur boite des Inter
59 //-- _du1 : Sur espace parametrique
60 if(_du1<1e50 && du1<0.01*_du1) du1=0.01*_du1;
61 if(_dv1<1e50 && dv1<0.01*_dv1) dv1=0.01*_dv1;
62 if(_du2<1e50 && du2<0.01*_du2) du2=0.01*_du2;
63 if(_dv2<1e50 && dv2<0.01*_dv2) dv2=0.01*_dv2;
64
65 pasuv[0]=Increment*du1;
66 pasuv[1]=Increment*dv1;
67 pasuv[2]=Increment*du2;
68 pasuv[3]=Increment*dv2;
69}
70//==================================================================================
71// function : IntWalk_PWalking::IntWalk_PWalking
72// purpose :
73//==================================================================================
74IntWalk_PWalking::IntWalk_PWalking(const ThePSurface& Caro1,
75 const ThePSurface& Caro2,
76 const Standard_Real TolTangency,
77 const Standard_Real Epsilon,
78 const Standard_Real Deflection,
79 const Standard_Real Increment )
80 :
81
82 done(Standard_True),
83 close(Standard_False),
84 fleche(Deflection),
85 tolconf(Epsilon),
86 sensCheminement(1),
87 myIntersectionOn2S(Caro1,Caro2,TolTangency)
88{
89 Standard_Real KELARG=20.;
90 //
91 pasMax=Increment*0.2; //-- le 25 juin 99 suite a des pbs de precision
92 Um1 = ThePSurfaceTool::FirstUParameter(Caro1);
93 Vm1 = ThePSurfaceTool::FirstVParameter(Caro1);
94 UM1 = ThePSurfaceTool::LastUParameter(Caro1);
95 VM1 = ThePSurfaceTool::LastVParameter(Caro1);
96
97 Um2 = ThePSurfaceTool::FirstUParameter(Caro2);
98 Vm2 = ThePSurfaceTool::FirstVParameter(Caro2);
99 UM2 = ThePSurfaceTool::LastUParameter(Caro2);
100 VM2 = ThePSurfaceTool::LastVParameter(Caro2);
101
102 ResoU1 = ThePSurfaceTool::UResolution(Caro1,Precision::Confusion());
103 ResoV1 = ThePSurfaceTool::VResolution(Caro1,Precision::Confusion());
104
105 ResoU2 = ThePSurfaceTool::UResolution(Caro2,Precision::Confusion());
106 ResoV2 = ThePSurfaceTool::VResolution(Caro2,Precision::Confusion());
107
108 Standard_Real NEWRESO;
109 Standard_Real MAXVAL;
110 Standard_Real MAXVAL2;
111 //
112 MAXVAL = Abs(Um1); MAXVAL2 = Abs(UM1);
113 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
114 NEWRESO = ResoU1 * MAXVAL ;
115 if(NEWRESO > ResoU1 &&NEWRESO<10) { ResoU1 = NEWRESO; }
116
117
118 MAXVAL = Abs(Um2); MAXVAL2 = Abs(UM2);
119 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
120 NEWRESO = ResoU2 * MAXVAL ;
121 if(NEWRESO > ResoU2 && NEWRESO<10) { ResoU2 = NEWRESO; }
122
123
124 MAXVAL = Abs(Vm1); MAXVAL2 = Abs(VM1);
125 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
126 NEWRESO = ResoV1 * MAXVAL ;
127 if(NEWRESO > ResoV1 && NEWRESO<10) { ResoV1 = NEWRESO; }
128
129
130 MAXVAL = Abs(Vm2); MAXVAL2 = Abs(VM2);
131 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
132 NEWRESO = ResoV2 * MAXVAL ;
133 if(NEWRESO > ResoV2 && NEWRESO<10) { ResoV2 = NEWRESO; }
134
135 pasuv[0]=pasMax*Abs(UM1-Um1);
136 pasuv[1]=pasMax*Abs(VM1-Vm1);
137 pasuv[2]=pasMax*Abs(UM2-Um2);
138 pasuv[3]=pasMax*Abs(VM2-Vm2);
139
140 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
141 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
142 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
143 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
144
145
146 if(ThePSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
e9a6ce82 147 //UM1+=KELARG*pasuv[0]; Um1-=KELARG*pasuv[0];
7fd59977 148 }
149 else {
150 Standard_Real t = UM1-Um1;
151 if(t<ThePSurfaceTool::UPeriod(Caro1)) {
152 t=0.5*(ThePSurfaceTool::UPeriod(Caro1)-t);
153 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
154 UM1+=t; Um1-=t;
155 }
156 }
157
158 if(ThePSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
e9a6ce82 159 //VM1+=KELARG*pasuv[1]; Vm1-=KELARG*pasuv[1];
7fd59977 160 }
161 else {
162 Standard_Real t = VM1-Vm1;
163 if(t<ThePSurfaceTool::VPeriod(Caro1)) {
164 t=0.5*(ThePSurfaceTool::VPeriod(Caro1)-t);
165 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
166 VM1+=t; Vm1-=t;
167 }
168 }
169
170 if(ThePSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
e9a6ce82 171 //UM2+=KELARG*pasuv[2]; Um2-=KELARG*pasuv[2];
7fd59977 172 }
173 else {
174 Standard_Real t = UM2-Um2;
175 if(t<ThePSurfaceTool::UPeriod(Caro2)) {
176 t=0.5*(ThePSurfaceTool::UPeriod(Caro2)-t);
177 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
178 UM2+=t; Um2-=t;
179 }
180 }
181
182 if(ThePSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
e9a6ce82 183 //VM2+=KELARG*pasuv[3]; Vm2-=KELARG*pasuv[3];
7fd59977 184 }
185 else {
186 Standard_Real t = VM2-Vm2;
187 if(t<ThePSurfaceTool::VPeriod(Caro2)) {
188 t=0.5*(ThePSurfaceTool::VPeriod(Caro2)-t);
189 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
190 VM2+=t; Vm2-=t;
191 }
192 }
193
194 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
195
196 for (Standard_Integer i = 0; i<=3;i++) {
197 if(pasuv[i]>10)
198 pasuv[i] = 10;
199 pasInit[i] = pasSav[i] = pasuv[i];
200 }
201
202
203}
204//==================================================================================
205// function : IntWalk_PWalking
206// purpose :
207//==================================================================================
208IntWalk_PWalking::IntWalk_PWalking(const ThePSurface& Caro1,
209 const ThePSurface& Caro2,
210 const Standard_Real TolTangency,
211 const Standard_Real Epsilon,
212 const Standard_Real Deflection,
213 const Standard_Real Increment,
214 const Standard_Real U1,
215 const Standard_Real V1,
216 const Standard_Real U2,
217 const Standard_Real V2)
218 :
219
220 done(Standard_True),
221 close(Standard_False),
222 fleche(Deflection),
223 tolconf(Epsilon),
224 sensCheminement(1),
225 myIntersectionOn2S(Caro1,Caro2,TolTangency)
226{
227 Standard_Real KELARG=20.;
228 //
229 pasMax=Increment*0.2; //-- le 25 juin 99 suite a des pbs de precision
230 //
231 Um1 = ThePSurfaceTool::FirstUParameter(Caro1);
232 Vm1 = ThePSurfaceTool::FirstVParameter(Caro1);
233 UM1 = ThePSurfaceTool::LastUParameter(Caro1);
234 VM1 = ThePSurfaceTool::LastVParameter(Caro1);
235
236 Um2 = ThePSurfaceTool::FirstUParameter(Caro2);
237 Vm2 = ThePSurfaceTool::FirstVParameter(Caro2);
238 UM2 = ThePSurfaceTool::LastUParameter(Caro2);
239 VM2 = ThePSurfaceTool::LastVParameter(Caro2);
240
241 ResoU1 = ThePSurfaceTool::UResolution(Caro1,Precision::Confusion());
242 ResoV1 = ThePSurfaceTool::VResolution(Caro1,Precision::Confusion());
243
244 ResoU2 = ThePSurfaceTool::UResolution(Caro2,Precision::Confusion());
245 ResoV2 = ThePSurfaceTool::VResolution(Caro2,Precision::Confusion());
246 //
247 Standard_Real NEWRESO, MAXVAL, MAXVAL2;
248 //
249 MAXVAL = Abs(Um1);
250 MAXVAL2 = Abs(UM1);
251 if(MAXVAL2 > MAXVAL) {
252 MAXVAL = MAXVAL2;
253 }
254 NEWRESO = ResoU1 * MAXVAL ;
255 if(NEWRESO > ResoU1) {
256 ResoU1 = NEWRESO;
257 }
258 //
259 MAXVAL = Abs(Um2);
260 MAXVAL2 = Abs(UM2);
261 if(MAXVAL2 > MAXVAL){
262 MAXVAL = MAXVAL2;
263 }
264 NEWRESO = ResoU2 * MAXVAL ;
265 if(NEWRESO > ResoU2) {
266 ResoU2 = NEWRESO;
267 }
268 //
269 MAXVAL = Abs(Vm1);
270 MAXVAL2 = Abs(VM1);
271 if(MAXVAL2 > MAXVAL) {
272 MAXVAL = MAXVAL2;
273 }
274 NEWRESO = ResoV1 * MAXVAL ;
275 if(NEWRESO > ResoV1) {
276 ResoV1 = NEWRESO;
277 }
278 //
279 MAXVAL = Abs(Vm2);
280 MAXVAL2 = Abs(VM2);
281 if(MAXVAL2 > MAXVAL){
282 MAXVAL = MAXVAL2;
283 }
284 NEWRESO = ResoV2 * MAXVAL ;
285 if(NEWRESO > ResoV2) {
286 ResoV2 = NEWRESO;
287 }
288 //
289 pasuv[0]=pasMax*Abs(UM1-Um1);
290 pasuv[1]=pasMax*Abs(VM1-Vm1);
291 pasuv[2]=pasMax*Abs(UM2-Um2);
292 pasuv[3]=pasMax*Abs(VM2-Vm2);
293 //
294 if(ThePSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
295 UM1+=KELARG*pasuv[0];
296 Um1-=KELARG*pasuv[0];
297 }
298 else {
299 Standard_Real t = UM1-Um1;
300 if(t<ThePSurfaceTool::UPeriod(Caro1)) {
301 t=0.5*(ThePSurfaceTool::UPeriod(Caro1)-t);
302 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
303 UM1+=t;
304 Um1-=t;
305 }
306 }
307 //
308 if(ThePSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
309 VM1+=KELARG*pasuv[1];
310 Vm1-=KELARG*pasuv[1];
311 }
312 else {
313 Standard_Real t = VM1-Vm1;
314 if(t<ThePSurfaceTool::VPeriod(Caro1)) {
315 t=0.5*(ThePSurfaceTool::VPeriod(Caro1)-t);
316 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
317 VM1+=t; Vm1-=t;
318 }
319 }
320 //
321 if(ThePSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
322 UM2+=KELARG*pasuv[2];
323 Um2-=KELARG*pasuv[2];
324 }
325 else {
326 Standard_Real t = UM2-Um2;
327 if(t<ThePSurfaceTool::UPeriod(Caro2)) {
328 t=0.5*(ThePSurfaceTool::UPeriod(Caro2)-t);
329 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
330 UM2+=t;
331 Um2-=t;
332 }
333 }
334
335 if(ThePSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
336 VM2+=KELARG*pasuv[3];
337 Vm2-=KELARG*pasuv[3];
338 }
339 else {
340 Standard_Real t = VM2-Vm2;
341 if(t<ThePSurfaceTool::UPeriod(Caro2)) {
342 t=0.5*(ThePSurfaceTool::VPeriod(Caro2)-t);
343 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
344 VM2+=t;
345 Vm2-=t;
346 }
347 }
348 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
349
350 for (Standard_Integer i = 0; i<=3;i++) {
351 pasInit[i] = pasSav[i] = pasuv[i];
352 }
353
354 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
355 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
356 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
357 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
358 //
359 TColStd_Array1OfReal Par(1,4);
360 Par(1) = U1;
361 Par(2) = V1;
362 Par(3) = U2;
363 Par(4) = V2;
364 Perform(Par);
365}
366
367//==================================================================================
368// function : PerformFirstPoint
369// purpose :
370//==================================================================================
371Standard_Boolean IntWalk_PWalking::PerformFirstPoint (const TColStd_Array1OfReal& ParDep,
372 IntSurf_PntOn2S& FirstPoint)
373{
374 sensCheminement = 1;
375 close = Standard_False;
376 //
377 Standard_Integer i;
378 Standard_Real aTmp;
379 TColStd_Array1OfReal Param(1,4);
380 //
381 for (i=1; i<=4; ++i) {
382 aTmp = ParDep(i);
383 Param(i) = ParDep(i);
384 }
385 //-- calcul du premier point solution
386 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
387 //
388 myIntersectionOn2S.Perform(Param,Rsnld);
389 if (!myIntersectionOn2S.IsDone()) {
390 return Standard_False;
391 }
392 if (myIntersectionOn2S.IsEmpty()) {
393 return Standard_False;
394 }
395 FirstPoint = myIntersectionOn2S.Point();
396 return Standard_True;
397}
398//==================================================================================
399// function : Perform
400// purpose :
401//==================================================================================
402void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep)
403{
404 Perform(ParDep,Um1,Vm1,Um2,Vm2,UM1,VM1,UM2,VM2);
405}
406//==================================================================================
407// function : Perform
408// purpose :
409//==================================================================================
410void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
411 const Standard_Real u1min,
412 const Standard_Real v1min,
413 const Standard_Real u2min,
414 const Standard_Real v2min,
415 const Standard_Real u1max,
416 const Standard_Real v1max,
417 const Standard_Real u2max,
418 const Standard_Real v2max)
419{
420 //xf
7fd59977 421 Standard_Integer i, NbPasOKConseq;
422 Standard_Real UFirst1, VFirst1, ULast1, VLast1, UFirst2, VFirst2, ULast2, VLast2;
423 Standard_Real pasMaxSV[4], aTmp;
424 TColStd_Array1OfReal Param(1,4);
425 IntImp_ConstIsoparametric ChoixIso;
426 //xt
427 //
428 done = Standard_False;
429 NbPasOKConseq=0;
430 //
431 // Caro1 and Caro2
432 const ThePSurface& Caro1 =myIntersectionOn2S.Function().AuxillarSurface1();
433 const ThePSurface& Caro2 =myIntersectionOn2S.Function().AuxillarSurface2();
434 //
435 UFirst1 = ThePSurfaceTool::FirstUParameter(Caro1);
436 VFirst1 = ThePSurfaceTool::FirstVParameter(Caro1);
437 ULast1 = ThePSurfaceTool::LastUParameter (Caro1);
438 VLast1 = ThePSurfaceTool::LastVParameter (Caro1);
439 //
440 UFirst2 = ThePSurfaceTool::FirstUParameter(Caro2);
441 VFirst2 = ThePSurfaceTool::FirstVParameter(Caro2);
442 ULast2 = ThePSurfaceTool::LastUParameter (Caro2);
443 VLast2 = ThePSurfaceTool::LastVParameter (Caro2);
444 //
445 ComputePasInit(pasuv,u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max,
446 Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2,pasMax+pasMax);
447 //
448 if(pasuv[0]<100*ResoU1) {
449 pasuv[0]=100*ResoU1;
450 }
451 if(pasuv[1]<100*ResoV1) {
452 pasuv[1]=100*ResoV1;
453 }
454 if(pasuv[2]<100*ResoU2) {
455 pasuv[2]=100*ResoU2;
456 }
457 if(pasuv[3]<100*ResoV2) {
458 pasuv[3]=100*ResoV2;
459 }
460 //
461 for (i=0; i<4; ++i) {
462 if(pasuv[i]>10) {
463 pasuv[i] = 10;
464 }
465 pasInit[i] = pasSav[i] = pasuv[i];
466 }
467 //
468 line = new IntSurf_LineOn2S ();
469 //
470 for (i=1; i<=4; ++i) {
471 aTmp=ParDep(i);
472 Param(i)=ParDep(i);
473 }
474 //-- reprise des pas uv lies aux surfaces Caro1 et Caro2
475 //-- pasuv[] et pasSav[] sont modifies lors du cheminement
476 for(i = 0; i < 4; ++i) {
477 pasMaxSV[i] = pasSav[i] = pasuv[i] = pasInit[i];
478 }
479
480 //-- calcul du premier point solution
481 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
482 //
483 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld);
484 if (!myIntersectionOn2S.IsDone()) {
485 return;
486 }
487 //
488 if (myIntersectionOn2S.IsEmpty()) {
489 return;
490 }
491 //
492 if(myIntersectionOn2S.IsTangent()) {
493 return;
494 }
495 //
496 Standard_Boolean Arrive, DejaReparti;
497 Standard_Integer IncKey, RejectIndex;
498 gp_Pnt pf,pl;
499 //
500 DejaReparti = Standard_False;
501 IncKey = 0;
502 RejectIndex = 0;
503 //
504 previousPoint = myIntersectionOn2S.Point();
505 previoustg = Standard_False;
506 previousd = myIntersectionOn2S.Direction();
507 previousd1 = myIntersectionOn2S.DirectionOnS1();
508 previousd2 = myIntersectionOn2S.DirectionOnS2();
509 indextg = 1;
510 tgdir = previousd;
511 firstd1 = previousd1;
512 firstd2 = previousd2;
513 tgfirst = tglast = Standard_False;
514 choixIsoSav = ChoixIso;
515 //------------------------------------------------------------
516 //-- On Teste si le premier point de cheminement correspond
517 //-- a un point sur frontiere.
518 //-- Dans ce cas, DejaReparti est initialise a True
519 //--
520 pf = previousPoint.Value();
521 Standard_Boolean bTestFirstPoint = Standard_True;
522
523 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
524 AddAPoint(line,previousPoint);
525 //
526 IntWalk_StatusDeflection Status = IntWalk_OK;
527 Standard_Boolean NoTestDeflection = Standard_False;
528 Standard_Real SvParam[4], f;
529 Standard_Integer LevelOfEmptyInmyIntersectionOn2S=0;
530 Standard_Integer LevelOfPointConfondu = 0;
531 Standard_Integer LevelOfIterWithoutAppend = -1;
532 //
533 Arrive = Standard_False;
534 while(!Arrive) {//010
535 LevelOfIterWithoutAppend++;
536 if(LevelOfIterWithoutAppend>20) {
537 Arrive = Standard_True;
538 if(DejaReparti) {
539 break;
540 }
541 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
542 LevelOfIterWithoutAppend = 0;
543 }
544 //
545 // compute f
546 f = 0.;
547 switch (ChoixIso) {
548 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
549 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
550 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
551 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
552 default:break;
553 }
554 //
555 if(f<0.1) {
556 f=0.1;
557 }
558 //
559 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
560 //
561 //--ofv.begin
562 Standard_Real aIncKey, aEps, dP1, dP2, dP3, dP4;
563 //
564 dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
565 dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
566 dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
567 dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
568 //
569 aIncKey=5.*(Standard_Real)IncKey;
570 aEps=1.e-7;
571 if(ChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < aEps) {
572 dP1 *= aIncKey;
573 }
574 if(ChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < aEps) {
575 dP2 *= aIncKey;
576 }
577 if(ChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < aEps) {
578 dP3 *= aIncKey;
579 }
580 if(ChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < aEps) {
581 dP4 *= aIncKey;
582 }
583 //--ofv.end
584 //
585 Param(1) += dP1;
586 Param(2) += dP2;
587 Param(3) += dP3;
588 Param(4) += dP4;
589 //==========================
590 SvParam[0]=Param(1);
591 SvParam[1]=Param(2);
592 SvParam[2]=Param(3);
593 SvParam[3]=Param(4);
594 //
595 ChoixIso= myIntersectionOn2S.Perform(Param, Rsnld, ChoixIso);
596 //
597 if (!myIntersectionOn2S.IsDone()) {
598 //arret de la ligne,division
599 Arrive = Standard_False;
600 Param(1)=SvParam[0];
601 Param(2)=SvParam[1];
602 Param(3)=SvParam[2];
603 Param(4)=SvParam[3];
604 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
605 }
606 else {//009
607 //== Le calcul du point exact a partir de Param(.) est possible
608 if (myIntersectionOn2S.IsEmpty()) {
609 Standard_Real u1,v1,u2,v2;
610 previousPoint.Parameters(u1,v1,u2,v2);
611 //
612 Arrive = Standard_False;
613 if(u1<UFirst1 || u1>ULast1) {
614 Arrive=Standard_True;
615 }
616 if(u2<UFirst2 || u2>ULast2) {
617 Arrive=Standard_True;
618 }
619 if(v1<VFirst1 || v1>VLast1) {
620 Arrive=Standard_True;
621 }
622 if(v2<VFirst2 || v2>VLast2) {
623 Arrive=Standard_True;
624 }
625 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
626 LevelOfEmptyInmyIntersectionOn2S++;
627 //
628 if(LevelOfEmptyInmyIntersectionOn2S>10) {
629 pasuv[0]=pasSav[0];
630 pasuv[1]=pasSav[1];
631 pasuv[2]=pasSav[2];
632 pasuv[3]=pasSav[3];
633 }
634 }
635 else {//008
636 //============================================================
637 //== Un point a ete trouve : T E S T D E F L E C T I O N
638 //============================================================
639 if(NoTestDeflection) {
640 NoTestDeflection = Standard_False;
641 }
642 else {
643 if(--LevelOfEmptyInmyIntersectionOn2S<=0) {
644 LevelOfEmptyInmyIntersectionOn2S=0;
645 if(LevelOfIterWithoutAppend < 10) {
646 Status = TestDeflection();
647 }
648 else {
649 pasuv[0]*=0.5;
650 pasuv[1]*=0.5;
651 pasuv[2]*=0.5;
652 pasuv[3]*=0.5;
653 }
654 }
655 }
656 //============================================================
657 //== T r a i t e m e n t s u r S t a t u s ==
658 //============================================================
659 if(LevelOfPointConfondu > 5) {
660 Status = IntWalk_ArretSurPoint;
661 LevelOfPointConfondu = 0;
662 }
663 //
664 if(Status==IntWalk_OK) {
665 NbPasOKConseq++;
666 if(NbPasOKConseq >= 5) {
667 NbPasOKConseq=0;
668 Standard_Boolean pastroppetit;
669 Standard_Real t;
670 //
671 do {
672 pastroppetit=Standard_True;
673 //
674 if(pasuv[0]<pasInit[0]) {
675 t = (pasInit[0]-pasuv[0])*0.25;
676 if(t>0.1*pasInit[0]) {
677 t=0.1*pasuv[0];
678 }
679 pasuv[0]+=t;
680 pastroppetit=Standard_False;
681 }
682 if(pasuv[1]<pasInit[1]) {
683 t = (pasInit[1]-pasuv[1])*0.25;
684 if(t>0.1*pasInit[1]) {
685 t=0.1*pasuv[1];
686 }
687 pasuv[1]+=t;
688 pastroppetit=Standard_False;
689 }
690 if(pasuv[2]<pasInit[2]){
691 t = (pasInit[2]-pasuv[2])*0.25;
692 if(t>0.1*pasInit[2]) {
693 t=0.1*pasuv[2];
694 }
695 pasuv[2]+=t;
696 pastroppetit=Standard_False;
697 }
698 if(pasuv[3]<pasInit[3]) {
699 t = (pasInit[3]-pasuv[3])*0.25;
700 if(t>0.1*pasInit[3]) {
701 t=0.1*pasuv[3];
702 }
703 pasuv[3]+=t;
704 pastroppetit=Standard_False;
705 }
706 if(pastroppetit) {
707 if(pasMax<0.1){
708 pasMax*=1.1;
709 pasInit[0]*=1.1;
710 pasInit[1]*=1.1;
711 pasInit[2]*=1.1;
712 pasInit[3]*=1.1;
713 }
714 else {
715 pastroppetit=Standard_False;
716 }
717 }
718 } while(pastroppetit);
719 }
720 }//Status==IntWalk_OK
721 else NbPasOKConseq=0;
722 //
723 switch(Status) {//007
724 case IntWalk_ArretSurPointPrecedent: {
725 Arrive = Standard_False;
726 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
727 break;
728 }
729 case IntWalk_PasTropGrand: {
730 Param(1)=SvParam[0];
731 Param(2)=SvParam[1];
732 Param(3)=SvParam[2];
733 Param(4)=SvParam[3];
734 if(LevelOfIterWithoutAppend > 5) {
735 if(pasSav[0]<pasInit[0]) {
736 pasInit[0]-=(pasInit[0]-pasSav[0])*0.25;
737 LevelOfIterWithoutAppend=0;
738 }
739 if(pasSav[1]<pasInit[1]) {
740 pasInit[1]-=(pasInit[1]-pasSav[1])*0.25;
741 LevelOfIterWithoutAppend=0;
742 }
743 if(pasSav[2]<pasInit[2]) {
744 pasInit[2]-=(pasInit[2]-pasSav[2])*0.25;
745 LevelOfIterWithoutAppend=0;
746 }
747 if(pasSav[3]<pasInit[3]) {
748 pasInit[3]-=(pasInit[3]-pasSav[3])*0.25;
749 LevelOfIterWithoutAppend=0;
750 }
751 }
752 break;
753 }
754 case IntWalk_PointConfondu: {
755 LevelOfPointConfondu++;
756 if(LevelOfPointConfondu>5) {
757 Standard_Boolean pastroppetit;
758 //
759 do {
760 pastroppetit=Standard_True;
761 if(pasuv[0]<pasInit[0]) {
762 pasuv[0]+=(pasInit[0]-pasuv[0])*0.25;
763 pastroppetit=Standard_False;
764 }
765 if(pasuv[1]<pasInit[1]) {
766 pasuv[1]+=(pasInit[1]-pasuv[1])*0.25;
767 pastroppetit=Standard_False;
768 }
769 if(pasuv[2]<pasInit[2]) {
770 pasuv[2]+=(pasInit[2]-pasuv[2])*0.25;
771 pastroppetit=Standard_False;
772 }
773 if(pasuv[3]<pasInit[3]) {
774 pasuv[3]+=(pasInit[3]-pasuv[3])*0.25;
775 pastroppetit=Standard_False;
776 }
777 if(pastroppetit) {
778 if(pasMax<0.1){
779 pasMax*=1.1;
780 pasInit[0]*=1.1;
781 pasInit[1]*=1.1;
782 pasInit[2]*=1.1;
783 pasInit[3]*=1.1;
784 }
785 else{
786 pastroppetit=Standard_False;
787 }
788 }
789 } while(pastroppetit);
790 }
791 break;
792 }
793 case IntWalk_OK:
794 case IntWalk_ArretSurPoint: {//006
795 //=======================================================
796 //== T e s t A r r e t : Cadrage sur Param(.) ==
797 //=======================================================
798 //xft arrive here
799 Arrive = TestArret(DejaReparti,Param,ChoixIso);
800 // JMB 30th December 1999.
801 // Some statement below should not be put in comment because they are useful.
802 // See grid CTO 909 A1 which infinitely loops
803 if(Arrive==Standard_False && Status==IntWalk_ArretSurPoint) {
804 Arrive=Standard_True;
805#ifdef DEB
806 cout << "Compile avec option DEB :Si Pb d intersection : ";
807 cout << "IntWalk_PWalking_1.gxx (lbr le 1erdec98)"<<endl;
808#endif
809 }
810 if(Arrive) {
811 NbPasOKConseq = -10;
812 }
813 if(!Arrive) {//005
814 //=====================================================
815 //== Param(.) est dans les bornes ==
816 //== et ne finit pas une ligne fermee ==
817 //=====================================================
818 //== Verification sur Le Point Courant de myInters
819 Standard_Boolean pointisvalid = Standard_False;
820 {
821 Standard_Real u1,v1,u2,v2;
822 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
823 //
824 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
825 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
826 v1 >= Vm1 && v2 >= Vm2) {
827 pointisvalid=Standard_True;
828 }
829 }
830 //
831 if(pointisvalid) {
832 previousPoint = myIntersectionOn2S.Point();
833 previoustg = myIntersectionOn2S.IsTangent();
834 if(!previoustg) {
835 previousd = myIntersectionOn2S.Direction();
836 previousd1 = myIntersectionOn2S.DirectionOnS1();
837 previousd2 = myIntersectionOn2S.DirectionOnS2();
838 }
839 //=====================================================
840 //== Verification sur Previous Point
841 {
842 Standard_Real u1,v1,u2,v2;
843 previousPoint.Parameters(u1,v1,u2,v2);
844 if( u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
845 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
846 v1 >= Vm1 && v2 >= Vm2) {
847 pl = previousPoint.Value();
848 if(bTestFirstPoint) {
849 if(pf.Distance(pl) < 1.e-7){
850 IncKey++;
851 if(IncKey == 5000)
852 return;
853 else
854 continue;
855 }
856 else {
857 bTestFirstPoint = Standard_False;
858 }
859 }
860 //
861 AddAPoint(line,previousPoint);
862 RejectIndex++;
863 if(RejectIndex >= 250000) {
864 break;
865 };
866 //
867 LevelOfIterWithoutAppend = 0;
868 }
869 }
870 }//pointisvalid
871 //====================================================
872 if(Status == IntWalk_ArretSurPoint) {
873 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
874 }
875 else{
876 if (line->NbPoints() == 2) {
877 pasSav[0] = pasuv[0];
878 pasSav[1] = pasuv[1];
879 pasSav[2] = pasuv[2];
880 pasSav[3] = pasuv[3];
881 }
882 }
883 }//005 if(!Arrive)
884 //
885 else {//004
886 if(close) {
887 //================= la ligne est fermee ===============
888 AddAPoint(line,line->Value(1)); //ligne fermee
889 LevelOfIterWithoutAppend=0;
890 }
891 else {//$$$
892 //====================================================
893 //== Param n etait pas dans les bornes (a ete recadre)
894 //====================================================
895 Standard_Boolean bPrevNotTangent = !previoustg || !myIntersectionOn2S.IsTangent();
896
897 IntImp_ConstIsoparametric SauvChoixIso = ChoixIso;
898 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
899 //
900 if(!myIntersectionOn2S.IsEmpty()) { //002
901 // debordement sur le carreau reciproque ou intersection en coin
902 if(TestArret(Standard_True,Param,ChoixIso)) {
903 NbPasOKConseq = -10;
904 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
905 if(!myIntersectionOn2S.IsEmpty()) {
906 previousPoint = myIntersectionOn2S.Point();
907 previoustg = myIntersectionOn2S.IsTangent();
908 if (!previoustg) {
909 previousd = myIntersectionOn2S.Direction();
910 previousd1 = myIntersectionOn2S.DirectionOnS1();
911 previousd2 = myIntersectionOn2S.DirectionOnS2();
912 }
913 pl = previousPoint.Value();
914 if(bTestFirstPoint) {
915 if(pf.Distance(pl) < 1.e-7){
916 IncKey++;
917 if(IncKey == 5000)
918 return;
919 else
920 continue;
921 }
922 else {
923 bTestFirstPoint = Standard_False;
924 }
925 }
926 //
927 AddAPoint(line,previousPoint);
928 RejectIndex++;
929 if(RejectIndex >= 250000) {
930 break;
931 };
932 //
933 LevelOfIterWithoutAppend=0;
934 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
935 }
936 else {
937 //echec cadrage diviser le pas
938 Arrive = Standard_False;
939 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
940 NoTestDeflection = Standard_True;
941 ChoixIso = SauvChoixIso;
942 }
943 }//if(TestArret())
944 else {
945 // save the last point
946 // to revert to it if the current point is out of bounds
947 IntSurf_PntOn2S previousPointSave = previousPoint;
948 Standard_Boolean previoustgSave = previoustg;
949 gp_Dir previousdSave = previousd;
950 gp_Dir2d previousd1Save = previousd1;
951 gp_Dir2d previousd2Save = previousd2;
952
953 previousPoint = myIntersectionOn2S.Point();
954 previoustg = myIntersectionOn2S.IsTangent();
955 Arrive = Standard_False;
956 if(!previoustg) {
957 previousd = myIntersectionOn2S.Direction();
958 previousd1 = myIntersectionOn2S.DirectionOnS1();
959 previousd2 = myIntersectionOn2S.DirectionOnS2();
960 }
961 //========================================
962 //== Verification sur PreviousPoint @@
963 {
964 Standard_Real u1,v1,u2,v2;
965 previousPoint.Parameters(u1,v1,u2,v2);
966 Param(1) = u1;
967 Param(2) = v1;
968 Param(3) = u2;
969 Param(4) = v2;
970 //
971 //xf
972 Standard_Boolean bFlag1, bFlag2;
973 Standard_Real aTol2D=1.e-11;
974 //
975 bFlag1=u1 >= Um1-aTol2D && v1 >= Vm1-aTol2D && u1 <= UM1+aTol2D && v1 <= VM1+aTol2D;
976 bFlag2=u2 >= Um2-aTol2D && v2 >= Vm2-aTol2D && u2 <= UM2+aTol2D && v2 <= VM2+aTol2D;
977 if (bFlag1 && bFlag2) {
978 /*
979 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
980 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
981 v1 >= Vm1 && v2 >= Vm2) {
982 */
983 //xt
984 pl = previousPoint.Value();
985 if(bTestFirstPoint) {
986 if(pf.Distance(pl) < 1.e-7) {
987 IncKey++;
988 if(IncKey == 5000)
989 return;
990 else
991 continue;
992 }
993 else {
994 bTestFirstPoint = Standard_False;
995 }
996 }
997 AddAPoint(line,previousPoint);
998 RejectIndex++;
999 if(RejectIndex >= 250000) {
1000 break;
1001 }
1002 //
1003 LevelOfIterWithoutAppend=0;
1004 Arrive = Standard_True;
1005 }
1006 else {
1007 // revert to the last correctly calculated point
1008 previousPoint = previousPointSave;
1009 previoustg = previoustgSave;
1010 previousd = previousdSave;
1011 previousd1 = previousd1Save;
1012 previousd2 = previousd2Save;
1013 }
1014 }
1015 //
1016 Standard_Boolean wasExtended = Standard_False;
1017
1018 if(Arrive && myIntersectionOn2S.IsTangent() && bPrevNotTangent) {
1019 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti)) {
1020 wasExtended = Standard_True;
1021 Arrive = Standard_False;
1022 ChoixIso = SauvChoixIso;
1023 }
1024 }
1025
1026 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1027 if(Arrive &&
1028 myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() &&
1029 myIntersectionOn2S.IsTangent() && bPrevNotTangent &&
1030 !wasExtended) {
1031
1032 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti)) {
1033 wasExtended = Standard_True;
1034 Arrive = Standard_False;
1035 ChoixIso = SauvChoixIso;
1036 }
1037 }
1038 }//else !TestArret() $
1039 } //$$ fin succes cadrage sur frontiere (!myIntersectionOn2S.IsEmpty())
1040 else {
1041 //echec cadrage sur frontiere;division du pas
1042 Arrive = Standard_False;
1043 NoTestDeflection = Standard_True;
1044 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1045 }
1046 }//$$$ fin cadrage sur frontiere (!close)
1047 } //004 fin TestArret retourne Arrive = True
1048 } // 006case IntWalk_ArretSurPoint: fin Traitement Status = OK ou ArretSurPoint
1049 } //007 switch(Status)
1050 } //008 fin traitement point en court (TEST DEFLECTION)
1051 } //009 fin traitement ligne (else if myIntersectionOn2S.IsDone())
1052 } //010 fin si premier point de depart a permis un cheminement while(!Arrive)
1053 done = Standard_True;
1054}
1055// ===========================================================================================================
1056// function: ExtendLineInCommonZone
1057// purpose: Extends already computed line inside tangent zone in the direction given by theChoixIso.
1058// Returns Standard_True if the line was extended through tangent zone and the last computed point
1059// is outside the tangent zone (but it is not put into the line). Otherwise returns Standard_False.
1060// ===========================================================================================================
1061Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso,
1062 const Standard_Boolean theDirectionFlag)
1063{
1064 Standard_Boolean bOutOfTangentZone = Standard_False;
1065 Standard_Boolean bStop = !myIntersectionOn2S.IsTangent();
1066 Standard_Integer dIncKey = 1;
1067 TColStd_Array1OfReal Param(1,4);
1068 IntWalk_StatusDeflection Status = IntWalk_OK;
1069 Standard_Integer nbIterWithoutAppend = 0;
1070 Standard_Integer nbEqualPoints = 0;
1071 Standard_Integer parit = 0;
1072 Standard_Integer uvit = 0;
1073 IntSurf_SequenceOfPntOn2S aSeqOfNewPoint;
1074
1075 while (!bStop) {
1076 nbIterWithoutAppend++;
1077
1078 if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) {
1079#ifdef DEB
1080 cout<<"Compile with option DEB:";
1081 cout<<"Infinite loop has detected. Stop iterations (IntWalk_PWalking_1.gxx)" << endl;
1082#endif
1083 bStop = Standard_True;
1084 break;
1085 }
1086 Standard_Real f = 0.;
1087
1088 switch (theChoixIso)
1089 {
1090 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
1091 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
1092 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
1093 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
1094 }
1095
1096 if(f<0.1) f=0.1;
1097
1098 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
1099
1100 Standard_Real dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
1101 Standard_Real dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
1102 Standard_Real dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
1103 Standard_Real dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
1104
1105 if(theChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < 1.e-7) dP1 *= (5. * (Standard_Real)dIncKey);
1106 if(theChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < 1.e-7) dP2 *= (5. * (Standard_Real)dIncKey);
1107 if(theChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < 1.e-7) dP3 *= (5. * (Standard_Real)dIncKey);
1108 if(theChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < 1.e-7) dP4 *= (5. * (Standard_Real)dIncKey);
1109
1110 Param(1) += dP1;
1111 Param(2) += dP2;
1112 Param(3) += dP3;
1113 Param(4) += dP4;
1114 Standard_Real SvParam[4];
1115 IntImp_ConstIsoparametric ChoixIso = theChoixIso;
1116
1117 for(parit = 0; parit < 4; parit++) {
1118 SvParam[parit] = Param(parit+1);
1119 }
1120 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
1121 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld, theChoixIso);
1122
1123 if (!myIntersectionOn2S.IsDone()) {
1124 return bOutOfTangentZone;
1125 }
1126 else {
1127 if (myIntersectionOn2S.IsEmpty()) {
1128 return bOutOfTangentZone;
1129 }
1130
1131 Status = TestDeflection();
1132
1133 if(Status == IntWalk_OK) {
1134
1135 for(uvit = 0; uvit < 4; uvit++) {
1136 if(pasuv[uvit] < pasInit[uvit]) {
1137 pasuv[uvit] = pasInit[uvit];
1138 }
1139 }
1140 }
1141
1142 switch(Status) {
1143 case IntWalk_ArretSurPointPrecedent:
1144 {
1145 bStop = Standard_True;
1146 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1147 break;
1148 }
1149 case IntWalk_PasTropGrand:
1150 {
1151 for(parit = 0; parit < 4; parit++) {
1152 Param(parit+1) = SvParam[parit];
1153 }
1154 Standard_Boolean bDecrease = Standard_False;
1155
1156 for(uvit = 0; uvit < 4; uvit++) {
1157 if(pasSav[uvit] < pasInit[uvit]) {
1158 pasInit[uvit] -= (pasInit[uvit] - pasSav[uvit]) * 0.1;
1159 bDecrease = Standard_True;
1160 }
1161 }
1162
1163 if(bDecrease) nbIterWithoutAppend--;
1164 break;
1165 }
1166 case IntWalk_PointConfondu:
1167 {
1168 for(uvit = 0; uvit < 4; uvit++) {
1169 if(pasuv[uvit] < pasInit[uvit]) {
1170 pasuv[uvit] += (pasInit[uvit] - pasuv[uvit]) * 0.1;
1171 }
1172 }
1173 break;
1174 }
1175 case IntWalk_OK:
1176 case IntWalk_ArretSurPoint:
1177 {
1178 //
1179 bStop = TestArret(theDirectionFlag, Param, ChoixIso);
1180 //
1181
1182 //
1183 if(!bStop) {
1184 Standard_Real u11,v11,u12,v12;
1185 myIntersectionOn2S.Point().Parameters(u11,v11,u12,v12);
1186 Standard_Real u21,v21,u22,v22;
1187 previousPoint.Parameters(u21,v21,u22,v22);
1188
1189 if(((fabs(u11-u21) < ResoU1) && (fabs(v11-v21) < ResoV1)) ||
1190 ((fabs(u12-u22) < ResoU2) && (fabs(v12-v22) < ResoV2))) {
1191 nbEqualPoints++;
1192 }
1193 else {
1194 nbEqualPoints = 0;
1195 }
1196 }
1197 //
1198
1199 bStop = bStop || !myIntersectionOn2S.IsTangent();
1200 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1201
1202 if(!bStop) {
1203 Standard_Boolean pointisvalid = Standard_False;
1204 Standard_Real u1,v1,u2,v2;
1205 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1206
1207 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1208 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1209 v1 >= Vm1 && v2 >= Vm2)
1210 pointisvalid = Standard_True;
1211
1212 if(pointisvalid) {
1213 previousPoint = myIntersectionOn2S.Point();
1214 previoustg = myIntersectionOn2S.IsTangent();
1215
1216 if(!previoustg) {
1217 previousd = myIntersectionOn2S.Direction();
1218 previousd1 = myIntersectionOn2S.DirectionOnS1();
1219 previousd2 = myIntersectionOn2S.DirectionOnS2();
1220 }
1221 Standard_Boolean bAddPoint = Standard_True;
1222
1223 if(line->NbPoints() >= 1) {
1224 gp_Pnt pf = line->Value(1).Value();
1225 gp_Pnt pl = previousPoint.Value();
1226
1227 if(pf.Distance(pl) < Precision::Confusion()) {
1228 dIncKey++;
1229 if(dIncKey == 5000) return bOutOfTangentZone;
1230 else bAddPoint = Standard_False;
1231 }
1232 }
1233
1234 if(bAddPoint) {
1235 aSeqOfNewPoint.Append(previousPoint);
1236 nbIterWithoutAppend = 0;
1237 }
1238 }
1239
1240 if (line->NbPoints() == 2) {
1241 for(uvit = 0; uvit < 4; uvit++) {
1242 pasSav[uvit] = pasuv[uvit];
1243 }
1244 }
1245
1246 if ( !pointisvalid ) {
1247 // decrease step if out of bounds
1248 // otherwise the same calculations will be
1249 // repeated several times
1250 if ( ( u1 > UM1 ) || ( u1 < Um1 ) )
1251 pasuv[0] *= 0.5;
1252
1253 if ( ( v1 > VM1 ) || ( v1 < Vm1 ) )
1254 pasuv[1] *= 0.5;
1255
1256 if ( ( u2 > UM2 ) || ( u2 < Um2 ) )
1257 pasuv[2] *= 0.5;
1258
1259 if ( ( v2 > VM2 ) || ( v2 < Vm2 ) )
1260 pasuv[3] *= 0.5;
1261 }
1262 } // end if(!bStop)
1263 else { //if(bStop)
1264 if(close && (line->NbPoints() >= 1)) {
1265
1266 if(!bOutOfTangentZone) {
1267 aSeqOfNewPoint.Append(line->Value(1)); // line end
1268 }
1269 nbIterWithoutAppend = 0;
1270 }
1271 else {
1272 ChoixIso = myIntersectionOn2S.Perform(Param, Rsnld, theChoixIso);
1273
1274 if(myIntersectionOn2S.IsEmpty()) {
1275 bStop = !myIntersectionOn2S.IsTangent();
1276 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1277 }
1278 else {
1279 Standard_Boolean bAddPoint = Standard_True;
1280 Standard_Boolean pointisvalid = Standard_False;
1281
1282 previousPoint = myIntersectionOn2S.Point();
1283 Standard_Real u1,v1,u2,v2;
1284 previousPoint.Parameters(u1,v1,u2,v2);
1285
1286 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1287 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1288 v1 >= Vm1 && v2 >= Vm2)
1289 pointisvalid = Standard_True;
1290
1291 if(pointisvalid) {
1292
1293 if(line->NbPoints() >= 1) {
1294 gp_Pnt pf = line->Value(1).Value();
1295 gp_Pnt pl = previousPoint.Value();
1296
1297 if(pf.Distance(pl) < Precision::Confusion()) {
1298 dIncKey++;
1299 if(dIncKey == 5000) return bOutOfTangentZone;
1300 else bAddPoint = Standard_False;
1301 }
1302 }
1303
1304 if(bAddPoint && !bOutOfTangentZone) {
1305 aSeqOfNewPoint.Append(previousPoint);
1306 nbIterWithoutAppend = 0;
1307 }
1308 }
1309 }
1310 }
1311 }
1312 break;
1313 }
1314 default:
1315 {
1316 break;
1317 }
1318 }
1319 }
1320 }
1321 Standard_Boolean bExtendLine = Standard_False;
1322 Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
1323
1324 Standard_Integer pit = 0;
1325
1326 for(pit = 0; !bExtendLine && (pit < 2); pit++) {
1327 if(pit == 0)
1328 previousPoint.Parameters(u1,v1,u2,v2);
1329 else {
1330 if(aSeqOfNewPoint.Length() > 0)
1331 aSeqOfNewPoint.Value(aSeqOfNewPoint.Length()).Parameters(u1,v1,u2,v2);
1332 else
1333 break;
1334 }
1335
1336 if(((u1 - Um1) < ResoU1) ||
1337 ((UM1 - u1) < ResoU1) ||
1338 ((u2 - Um2) < ResoU2) ||
1339 ((UM2 - u2) < ResoU2) ||
1340 ((v1 - Vm1) < ResoV1) ||
1341 ((VM1 - v1) < ResoV1) ||
1342 ((v2 - Vm2) < ResoV2) ||
1343 ((VM2 - v2) < ResoV2))
1344 bExtendLine = Standard_True;
1345 }
1346
1347 if(!bExtendLine) {
1348 // if(Status == IntWalk_OK || Status == IntWalk_ArretSurPoint) {
1349 if(Status == IntWalk_OK) {
1350 bExtendLine = Standard_True;
1351
1352 if(aSeqOfNewPoint.Length() > 1) {
1353 TColStd_Array1OfReal FirstParams(0, 3), LastParams(0, 3), Resolutions(0, 3);
1354 Resolutions(0) = ResoU1; Resolutions(1) = ResoV1; Resolutions(2) = ResoU2; Resolutions(3) = ResoV2;
1355
1356 aSeqOfNewPoint(1).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1357 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1358 aSeqOfNewPoint(aSeqOfNewPoint.Length()).Parameters(LastParams.ChangeValue(0),
1359 LastParams.ChangeValue(1),
1360 LastParams.ChangeValue(2),
1361 LastParams.ChangeValue(3));
1362 Standard_Integer indexofiso = 0;
1363
1364 if(theChoixIso == IntImp_UIsoparametricOnCaro1) indexofiso = 0;
1365 if(theChoixIso == IntImp_VIsoparametricOnCaro1) indexofiso = 1;
1366 if(theChoixIso == IntImp_UIsoparametricOnCaro2) indexofiso = 2;
1367 if(theChoixIso == IntImp_VIsoparametricOnCaro2) indexofiso = 3;
1368
1369 Standard_Integer afirstindex = (indexofiso < 2) ? 0 : 2;
1370 gp_Vec2d aTangentZoneDir(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)),
1371 gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1)));
1372
1373 gp_Dir2d anIsoDir(0, 1);
1374
1375 if((indexofiso == 1) || (indexofiso == 3))
1376 anIsoDir = gp_Dir2d(1, 0);
1377
1378 if(aTangentZoneDir.SquareMagnitude() > gp::Resolution()) {
c6541a0c 1379 Standard_Real piquota = M_PI*0.25;
7fd59977 1380
1381 if(fabs(aTangentZoneDir.Angle(anIsoDir)) > piquota) {
1382 Standard_Integer ii = 1, nextii = 2;
1383 gp_Vec2d d1(0, 0);
1384 Standard_Real asqresol = gp::Resolution();
1385 asqresol *= asqresol;
1386
1387 do {
1388 aSeqOfNewPoint(ii).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1389 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1390 aSeqOfNewPoint(ii + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1391 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1392 d1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1393 FirstParams.Value(afirstindex + 1)),
1394 gp_Pnt2d(LastParams.Value(afirstindex),
1395 LastParams.Value(afirstindex + 1)));
1396 ii++;
1397 }
1398 while((d1.SquareMagnitude() < asqresol) &&
1399 (ii < aSeqOfNewPoint.Length()));
1400
1401 nextii = ii;
1402
1403 while(nextii < aSeqOfNewPoint.Length()) {
1404
1405 gp_Vec2d nextd1(0, 0);
1406 Standard_Integer jj = nextii;
1407
1408 do {
1409 aSeqOfNewPoint(jj).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1410 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1411 aSeqOfNewPoint(jj + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1412 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1413 nextd1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1414 FirstParams.Value(afirstindex + 1)),
1415 gp_Pnt2d(LastParams.Value(afirstindex),
1416 LastParams.Value(afirstindex + 1)));
1417 jj++;
1418
1419 }
1420 while((nextd1.SquareMagnitude() < asqresol) &&
1421 (jj < aSeqOfNewPoint.Length()));
1422 nextii = jj;
1423
1424 if(fabs(d1.Angle(nextd1)) > piquota) {
1425 bExtendLine = Standard_False;
1426 break;
1427 }
1428 d1 = nextd1;
1429 }
1430 }
1431 // end if(fabs(aTangentZoneDir.Angle(anIsoDir)
1432 }
1433 }
1434 }
1435 }
1436
1437 if(!bExtendLine) {
1438 return Standard_False;
1439 }
1440 Standard_Integer i = 0;
1441
1442 for(i = 1; i <= aSeqOfNewPoint.Length(); i++) {
1443 AddAPoint(line, aSeqOfNewPoint.Value(i));
1444 }
1445
1446 return bOutOfTangentZone;
1447}