0024737: Coding - remove <br> tag from header files
[occt.git] / src / IntWalk / IntWalk_PWalking_1.gxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 15//-----------------------------
16//-- IntWalk_PWalking_1.gxx
17//--
18
19#include <Precision.hxx>
20#include <math_FunctionSetRoot.hxx>
21
00302ba4 22#include <Geom_Surface.hxx>
23
7fd59977 24//#define KELARG 20.0
25
26//==================================================================================
27// function : IntWalk_PWalking::IntWalk_PWalking
28// purpose :
b1c5c4e6 29// estimate of max step : To avoid abrupt changes
30// during change of isos
7fd59977 31//==================================================================================
32void ComputePasInit(Standard_Real *pasuv,
00302ba4 33 Standard_Real Um1,Standard_Real UM1,
34 Standard_Real Vm1,Standard_Real VM1,
35 Standard_Real Um2,Standard_Real UM2,
36 Standard_Real Vm2,Standard_Real VM2,
37 Standard_Real _Um1,Standard_Real _UM1,
38 Standard_Real _Vm1,Standard_Real _VM1,
39 Standard_Real _Um2,Standard_Real _UM2,
40 Standard_Real _Vm2,Standard_Real _VM2,
41 const ThePSurface& ,
42 const ThePSurface& ,
43 const Standard_Real Increment)
7fd59977 44{
45 Standard_Real du1=Abs(UM1-Um1);
46 Standard_Real dv1=Abs(VM1-Vm1);
47 Standard_Real du2=Abs(UM2-Um2);
48 Standard_Real dv2=Abs(VM2-Vm2);
00302ba4 49
7fd59977 50 Standard_Real _du1=Abs(_UM1-_Um1);
51 Standard_Real _dv1=Abs(_VM1-_Vm1);
52 Standard_Real _du2=Abs(_UM2-_Um2);
53 Standard_Real _dv2=Abs(_VM2-_Vm2);
00302ba4 54
b1c5c4e6 55 //-- limit the reduction of uv box estimate to 0.01 natural box
56 //-- du1 : On box of Inter
57 //-- _du1 : On parametric space
7fd59977 58 if(_du1<1e50 && du1<0.01*_du1) du1=0.01*_du1;
59 if(_dv1<1e50 && dv1<0.01*_dv1) dv1=0.01*_dv1;
60 if(_du2<1e50 && du2<0.01*_du2) du2=0.01*_du2;
61 if(_dv2<1e50 && dv2<0.01*_dv2) dv2=0.01*_dv2;
00302ba4 62
7fd59977 63 pasuv[0]=Increment*du1;
64 pasuv[1]=Increment*dv1;
65 pasuv[2]=Increment*du2;
66 pasuv[3]=Increment*dv2;
67}
c2c2f2b6 68
69//=======================================================================
70//function : IsParallel
71//purpose : Checks if theLine is parallel of some boundary of given
72// surface (it is determined by theCheckSurf1 flag).
73// Parallelism assumes small oscillations (swing is less or
74// equal than theToler).
75// Small lines (if first and last parameters in the Surface
76// are almost equal) are classified as parallel (as same as
77// any point can be considered as parallel of any line).
78//=======================================================================
79static void IsParallel(const Handle(IntSurf_LineOn2S)& theLine,
80 const Standard_Boolean theCheckSurf1,
81 const Standard_Real theToler,
82 Standard_Boolean& theIsUparallel,
83 Standard_Boolean& theIsVparallel)
84{
85 const Standard_Integer aNbPointsMAX = 23;
86
87 theIsUparallel = theIsVparallel = Standard_True;
88
89 Standard_Integer aNbPoints = theLine->NbPoints();
90 if(aNbPoints > aNbPointsMAX)
91 {
92 aNbPoints = aNbPointsMAX;
93 }
94 else if(aNbPoints < 3)
95 {
96 //Here we cannot estimate parallelism.
97 //Do all same as for small lines
98 return;
99 }
100
101 Standard_Real aStep = IntToReal(theLine->NbPoints()) / aNbPoints;
102 Standard_Real aNPoint = 1.0;
103
104 Standard_Real aUmin = RealLast(), aUmax = RealFirst(), aVmin = RealLast(), aVmax = RealFirst();
105 for(Standard_Integer aNum = 1; aNum <= aNbPoints; aNum++, aNPoint += aStep)
106 {
107 if(aNPoint > aNbPoints)
108 {
109 aNPoint = aNbPoints;
110 }
111
112 Standard_Real u, v;
113 if(theCheckSurf1)
114 theLine->Value(RealToInt(aNPoint)).ParametersOnS1(u, v);
115 else
116 theLine->Value(RealToInt(aNPoint)).ParametersOnS2(u, v);
117
118 if(u < aUmin)
119 aUmin = u;
120
121 if(u > aUmax)
122 aUmax = u;
123
124 if(v < aVmin)
125 aVmin = v;
126
127 if(v > aVmax)
128 aVmax = v;
129 }
130
131 theIsVparallel = ((aUmax - aUmin) < theToler);
132 theIsUparallel = ((aVmax - aVmin) < theToler);
133}
134
135//=======================================================================
136//function : Checking
137//purpose : Check, if given point is in surface's boundaries.
138// If "yes" then theFactTol = 0.0, else theFactTol is
139// equal maximal deviation.
140//=======================================================================
141static Standard_Boolean Checking( const Handle(Adaptor3d_HSurface)& theASurf1,
142 const Handle(Adaptor3d_HSurface)& theASurf2,
143 Standard_Real& theU1,
144 Standard_Real& theV1,
145 Standard_Real& theU2,
146 Standard_Real& theV2,
147 Standard_Real& theFactTol)
148{
149 const Standard_Real aTol = Precision::PConfusion();
150 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
151 const Standard_Real aU1bLast = theASurf1->LastUParameter();
152 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
153 const Standard_Real aU2bLast = theASurf2->LastUParameter();
154 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
155 const Standard_Real aV1bLast = theASurf1->LastVParameter();
156 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
157 const Standard_Real aV2bLast = theASurf2->LastVParameter();
158
159 Standard_Boolean isOnOrIn = Standard_True;
160 theFactTol = 0.0;
161
162 Standard_Real aDelta = aU1bFirst - theU1;
163 if(aDelta > aTol)
164 {
165 theU1 = aU1bFirst;
166 theFactTol = Max(theFactTol, aDelta);
167 isOnOrIn = Standard_False;
168 }
169
170 aDelta = theU1 - aU1bLast;
171 if(aDelta > aTol)
172 {
173 theU1 = aU1bLast;
174 theFactTol = Max(theFactTol, aDelta);
175 isOnOrIn = Standard_False;
176 }
177
178 aDelta = aV1bFirst - theV1;
179 if(aDelta > aTol)
180 {
181 theV1 = aV1bFirst;
182 theFactTol = Max(theFactTol, aDelta);
183 isOnOrIn = Standard_False;
184 }
185
186 aDelta = theV1 - aV1bLast;
187 if(aDelta > aTol)
188 {
189 theV1 = aV1bLast;
190 theFactTol = Max(theFactTol, aDelta);
191 isOnOrIn = Standard_False;
192 }
193
194 aDelta = aU2bFirst - theU2;
195 if(aDelta > aTol)
196 {
197 theU2 = aU2bFirst;
198 theFactTol = Max(theFactTol, aDelta);
199 isOnOrIn = Standard_False;
200 }
201
202 aDelta = theU2 - aU2bLast;
203 if(aDelta > aTol)
204 {
205 theU2 = aU2bLast;
206 theFactTol = Max(theFactTol, aDelta);
207 isOnOrIn = Standard_False;
208 }
209
210 aDelta = aV2bFirst - theV2;
211 if(aDelta > aTol)
212 {
213 theV2 = aV2bFirst;
214 theFactTol = Max(theFactTol, aDelta);
215 isOnOrIn = Standard_False;
216 }
217
218 aDelta = theV2 - aV2bLast;
219 if(aDelta > aTol)
220 {
221 theV2 = aV2bLast;
222 theFactTol = Max(theFactTol, aDelta);
223 isOnOrIn = Standard_False;
224 }
225
226 return isOnOrIn;
227}
228
7fd59977 229//==================================================================================
230// function : IntWalk_PWalking::IntWalk_PWalking
231// purpose :
232//==================================================================================
233IntWalk_PWalking::IntWalk_PWalking(const ThePSurface& Caro1,
00302ba4 234 const ThePSurface& Caro2,
235 const Standard_Real TolTangency,
236 const Standard_Real Epsilon,
237 const Standard_Real Deflection,
238 const Standard_Real Increment )
239 :
240
241done(Standard_True),
242close(Standard_False),
243fleche(Deflection),
244tolconf(Epsilon),
245sensCheminement(1),
246myIntersectionOn2S(Caro1,Caro2,TolTangency),
247STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
248STATIC_PRECEDENT_INFLEXION(0)
7fd59977 249{
250 Standard_Real KELARG=20.;
251 //
b1c5c4e6 252 pasMax=Increment*0.2; //-- June 25 99 after problems with precision
7fd59977 253 Um1 = ThePSurfaceTool::FirstUParameter(Caro1);
254 Vm1 = ThePSurfaceTool::FirstVParameter(Caro1);
255 UM1 = ThePSurfaceTool::LastUParameter(Caro1);
256 VM1 = ThePSurfaceTool::LastVParameter(Caro1);
257
258 Um2 = ThePSurfaceTool::FirstUParameter(Caro2);
259 Vm2 = ThePSurfaceTool::FirstVParameter(Caro2);
260 UM2 = ThePSurfaceTool::LastUParameter(Caro2);
261 VM2 = ThePSurfaceTool::LastVParameter(Caro2);
262
263 ResoU1 = ThePSurfaceTool::UResolution(Caro1,Precision::Confusion());
264 ResoV1 = ThePSurfaceTool::VResolution(Caro1,Precision::Confusion());
265
266 ResoU2 = ThePSurfaceTool::UResolution(Caro2,Precision::Confusion());
267 ResoV2 = ThePSurfaceTool::VResolution(Caro2,Precision::Confusion());
268
269 Standard_Real NEWRESO;
270 Standard_Real MAXVAL;
271 Standard_Real MAXVAL2;
272 //
273 MAXVAL = Abs(Um1); MAXVAL2 = Abs(UM1);
274 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
275 NEWRESO = ResoU1 * MAXVAL ;
276 if(NEWRESO > ResoU1 &&NEWRESO<10) { ResoU1 = NEWRESO; }
277
278
279 MAXVAL = Abs(Um2); MAXVAL2 = Abs(UM2);
280 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
281 NEWRESO = ResoU2 * MAXVAL ;
282 if(NEWRESO > ResoU2 && NEWRESO<10) { ResoU2 = NEWRESO; }
283
284
285 MAXVAL = Abs(Vm1); MAXVAL2 = Abs(VM1);
286 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
287 NEWRESO = ResoV1 * MAXVAL ;
288 if(NEWRESO > ResoV1 && NEWRESO<10) { ResoV1 = NEWRESO; }
289
290
291 MAXVAL = Abs(Vm2); MAXVAL2 = Abs(VM2);
292 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
293 NEWRESO = ResoV2 * MAXVAL ;
294 if(NEWRESO > ResoV2 && NEWRESO<10) { ResoV2 = NEWRESO; }
295
296 pasuv[0]=pasMax*Abs(UM1-Um1);
297 pasuv[1]=pasMax*Abs(VM1-Vm1);
298 pasuv[2]=pasMax*Abs(UM2-Um2);
299 pasuv[3]=pasMax*Abs(VM2-Vm2);
300
301 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
302 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
303 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
304 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
305
306
307 if(ThePSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
e9a6ce82 308 //UM1+=KELARG*pasuv[0]; Um1-=KELARG*pasuv[0];
7fd59977 309 }
310 else {
311 Standard_Real t = UM1-Um1;
312 if(t<ThePSurfaceTool::UPeriod(Caro1)) {
313 t=0.5*(ThePSurfaceTool::UPeriod(Caro1)-t);
314 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
315 UM1+=t; Um1-=t;
316 }
317 }
00302ba4 318
7fd59977 319 if(ThePSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
e9a6ce82 320 //VM1+=KELARG*pasuv[1]; Vm1-=KELARG*pasuv[1];
7fd59977 321 }
322 else {
323 Standard_Real t = VM1-Vm1;
324 if(t<ThePSurfaceTool::VPeriod(Caro1)) {
325 t=0.5*(ThePSurfaceTool::VPeriod(Caro1)-t);
326 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
327 VM1+=t; Vm1-=t;
328 }
329 }
00302ba4 330
7fd59977 331 if(ThePSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
e9a6ce82 332 //UM2+=KELARG*pasuv[2]; Um2-=KELARG*pasuv[2];
7fd59977 333 }
334 else {
335 Standard_Real t = UM2-Um2;
336 if(t<ThePSurfaceTool::UPeriod(Caro2)) {
337 t=0.5*(ThePSurfaceTool::UPeriod(Caro2)-t);
338 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
339 UM2+=t; Um2-=t;
340 }
341 }
00302ba4 342
7fd59977 343 if(ThePSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
e9a6ce82 344 //VM2+=KELARG*pasuv[3]; Vm2-=KELARG*pasuv[3];
7fd59977 345 }
346 else {
347 Standard_Real t = VM2-Vm2;
348 if(t<ThePSurfaceTool::VPeriod(Caro2)) {
349 t=0.5*(ThePSurfaceTool::VPeriod(Caro2)-t);
350 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
351 VM2+=t; Vm2-=t;
352 }
353 }
354
355 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
356
357 for (Standard_Integer i = 0; i<=3;i++) {
358 if(pasuv[i]>10)
359 pasuv[i] = 10;
360 pasInit[i] = pasSav[i] = pasuv[i];
361 }
362
363
364}
365//==================================================================================
366// function : IntWalk_PWalking
367// purpose :
368//==================================================================================
369IntWalk_PWalking::IntWalk_PWalking(const ThePSurface& Caro1,
00302ba4 370 const ThePSurface& Caro2,
371 const Standard_Real TolTangency,
372 const Standard_Real Epsilon,
373 const Standard_Real Deflection,
374 const Standard_Real Increment,
375 const Standard_Real U1,
376 const Standard_Real V1,
377 const Standard_Real U2,
378 const Standard_Real V2)
379 :
380
381done(Standard_True),
382close(Standard_False),
383fleche(Deflection),
384tolconf(Epsilon),
385sensCheminement(1),
386myIntersectionOn2S(Caro1,Caro2,TolTangency),
387STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
388STATIC_PRECEDENT_INFLEXION(0)
7fd59977 389{
390 Standard_Real KELARG=20.;
391 //
b1c5c4e6 392 pasMax=Increment*0.2; //-- June 25 99 after problems with precision
7fd59977 393 //
394 Um1 = ThePSurfaceTool::FirstUParameter(Caro1);
395 Vm1 = ThePSurfaceTool::FirstVParameter(Caro1);
396 UM1 = ThePSurfaceTool::LastUParameter(Caro1);
397 VM1 = ThePSurfaceTool::LastVParameter(Caro1);
398
399 Um2 = ThePSurfaceTool::FirstUParameter(Caro2);
400 Vm2 = ThePSurfaceTool::FirstVParameter(Caro2);
401 UM2 = ThePSurfaceTool::LastUParameter(Caro2);
402 VM2 = ThePSurfaceTool::LastVParameter(Caro2);
403
404 ResoU1 = ThePSurfaceTool::UResolution(Caro1,Precision::Confusion());
405 ResoV1 = ThePSurfaceTool::VResolution(Caro1,Precision::Confusion());
406
407 ResoU2 = ThePSurfaceTool::UResolution(Caro2,Precision::Confusion());
408 ResoV2 = ThePSurfaceTool::VResolution(Caro2,Precision::Confusion());
409 //
410 Standard_Real NEWRESO, MAXVAL, MAXVAL2;
411 //
412 MAXVAL = Abs(Um1);
413 MAXVAL2 = Abs(UM1);
414 if(MAXVAL2 > MAXVAL) {
415 MAXVAL = MAXVAL2;
416 }
417 NEWRESO = ResoU1 * MAXVAL ;
418 if(NEWRESO > ResoU1) {
419 ResoU1 = NEWRESO;
420 }
421 //
422 MAXVAL = Abs(Um2);
423 MAXVAL2 = Abs(UM2);
424 if(MAXVAL2 > MAXVAL){
425 MAXVAL = MAXVAL2;
426 }
427 NEWRESO = ResoU2 * MAXVAL ;
428 if(NEWRESO > ResoU2) {
429 ResoU2 = NEWRESO;
430 }
431 //
432 MAXVAL = Abs(Vm1);
433 MAXVAL2 = Abs(VM1);
434 if(MAXVAL2 > MAXVAL) {
435 MAXVAL = MAXVAL2;
436 }
437 NEWRESO = ResoV1 * MAXVAL ;
438 if(NEWRESO > ResoV1) {
439 ResoV1 = NEWRESO;
440 }
441 //
442 MAXVAL = Abs(Vm2);
443 MAXVAL2 = Abs(VM2);
444 if(MAXVAL2 > MAXVAL){
445 MAXVAL = MAXVAL2;
446 }
447 NEWRESO = ResoV2 * MAXVAL ;
448 if(NEWRESO > ResoV2) {
449 ResoV2 = NEWRESO;
450 }
451 //
452 pasuv[0]=pasMax*Abs(UM1-Um1);
453 pasuv[1]=pasMax*Abs(VM1-Vm1);
454 pasuv[2]=pasMax*Abs(UM2-Um2);
455 pasuv[3]=pasMax*Abs(VM2-Vm2);
456 //
457 if(ThePSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
458 UM1+=KELARG*pasuv[0];
459 Um1-=KELARG*pasuv[0];
460 }
461 else {
462 Standard_Real t = UM1-Um1;
463 if(t<ThePSurfaceTool::UPeriod(Caro1)) {
464 t=0.5*(ThePSurfaceTool::UPeriod(Caro1)-t);
465 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
466 UM1+=t;
467 Um1-=t;
468 }
469 }
470 //
471 if(ThePSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
472 VM1+=KELARG*pasuv[1];
473 Vm1-=KELARG*pasuv[1];
474 }
475 else {
476 Standard_Real t = VM1-Vm1;
477 if(t<ThePSurfaceTool::VPeriod(Caro1)) {
478 t=0.5*(ThePSurfaceTool::VPeriod(Caro1)-t);
479 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
480 VM1+=t; Vm1-=t;
481 }
482 }
483 //
484 if(ThePSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
485 UM2+=KELARG*pasuv[2];
486 Um2-=KELARG*pasuv[2];
487 }
488 else {
489 Standard_Real t = UM2-Um2;
490 if(t<ThePSurfaceTool::UPeriod(Caro2)) {
491 t=0.5*(ThePSurfaceTool::UPeriod(Caro2)-t);
492 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
493 UM2+=t;
494 Um2-=t;
495 }
496 }
00302ba4 497
7fd59977 498 if(ThePSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
499 VM2+=KELARG*pasuv[3];
500 Vm2-=KELARG*pasuv[3];
501 }
502 else {
503 Standard_Real t = VM2-Vm2;
b92f3572 504 if(t<ThePSurfaceTool::VPeriod(Caro2)) {
7fd59977 505 t=0.5*(ThePSurfaceTool::VPeriod(Caro2)-t);
506 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
507 VM2+=t;
508 Vm2-=t;
509 }
510 }
511 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
512
513 for (Standard_Integer i = 0; i<=3;i++) {
514 pasInit[i] = pasSav[i] = pasuv[i];
515 }
516
517 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
518 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
519 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
520 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
521 //
522 TColStd_Array1OfReal Par(1,4);
523 Par(1) = U1;
524 Par(2) = V1;
525 Par(3) = U2;
526 Par(4) = V2;
527 Perform(Par);
528}
529
530//==================================================================================
531// function : PerformFirstPoint
532// purpose :
533//==================================================================================
534Standard_Boolean IntWalk_PWalking::PerformFirstPoint (const TColStd_Array1OfReal& ParDep,
00302ba4 535 IntSurf_PntOn2S& FirstPoint)
7fd59977 536{
537 sensCheminement = 1;
538 close = Standard_False;
539 //
540 Standard_Integer i;
7fd59977 541 TColStd_Array1OfReal Param(1,4);
542 //
543 for (i=1; i<=4; ++i) {
7fd59977 544 Param(i) = ParDep(i);
545 }
b1c5c4e6 546 //-- calculate the first solution point
7fd59977 547 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
548 //
549 myIntersectionOn2S.Perform(Param,Rsnld);
550 if (!myIntersectionOn2S.IsDone()) {
551 return Standard_False;
552 }
c63628e8 553
7fd59977 554 if (myIntersectionOn2S.IsEmpty()) {
555 return Standard_False;
556 }
c63628e8 557
7fd59977 558 FirstPoint = myIntersectionOn2S.Point();
559 return Standard_True;
560}
561//==================================================================================
562// function : Perform
563// purpose :
564//==================================================================================
565void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep)
566{
567 Perform(ParDep,Um1,Vm1,Um2,Vm2,UM1,VM1,UM2,VM2);
568}
569//==================================================================================
570// function : Perform
571// purpose :
572//==================================================================================
573void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
00302ba4 574 const Standard_Real u1min,
575 const Standard_Real v1min,
576 const Standard_Real u2min,
577 const Standard_Real v2min,
578 const Standard_Real u1max,
579 const Standard_Real v1max,
580 const Standard_Real u2max,
581 const Standard_Real v2max)
7fd59977 582{
00302ba4 583 const Standard_Real aSQDistMax = 1.0e-14;
7fd59977 584 //xf
00302ba4 585
586 Standard_Integer NbPasOKConseq=0;
587 Standard_Real pasMaxSV[4], aTmp;
7fd59977 588 TColStd_Array1OfReal Param(1,4);
589 IntImp_ConstIsoparametric ChoixIso;
590 //xt
591 //
592 done = Standard_False;
7fd59977 593 //
594 // Caro1 and Caro2
595 const ThePSurface& Caro1 =myIntersectionOn2S.Function().AuxillarSurface1();
596 const ThePSurface& Caro2 =myIntersectionOn2S.Function().AuxillarSurface2();
597 //
00302ba4 598 const Standard_Real UFirst1 = ThePSurfaceTool::FirstUParameter(Caro1);
599 const Standard_Real VFirst1 = ThePSurfaceTool::FirstVParameter(Caro1);
600 const Standard_Real ULast1 = ThePSurfaceTool::LastUParameter (Caro1);
601 const Standard_Real VLast1 = ThePSurfaceTool::LastVParameter (Caro1);
602
603 const Standard_Real UFirst2 = ThePSurfaceTool::FirstUParameter(Caro2);
604 const Standard_Real VFirst2 = ThePSurfaceTool::FirstVParameter(Caro2);
605 const Standard_Real ULast2 = ThePSurfaceTool::LastUParameter (Caro2);
606 const Standard_Real VLast2 = ThePSurfaceTool::LastVParameter (Caro2);
7fd59977 607 //
608 ComputePasInit(pasuv,u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max,
00302ba4 609 Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2,pasMax+pasMax);
7fd59977 610 //
00302ba4 611 if(pasuv[0]<100.0*ResoU1) {
612 pasuv[0]=100.0*ResoU1;
7fd59977 613 }
00302ba4 614 if(pasuv[1]<100.0*ResoV1) {
615 pasuv[1]=100.0*ResoV1;
7fd59977 616 }
00302ba4 617 if(pasuv[2]<100.0*ResoU2) {
618 pasuv[2]=100.0*ResoU2;
7fd59977 619 }
00302ba4 620 if(pasuv[3]<100.0*ResoV2) {
621 pasuv[3]=100.0*ResoV2;
7fd59977 622 }
623 //
00302ba4 624 for (Standard_Integer i=0; i<4; ++i)
625 {
626 if(pasuv[i]>10)
627 {
7fd59977 628 pasuv[i] = 10;
629 }
00302ba4 630
7fd59977 631 pasInit[i] = pasSav[i] = pasuv[i];
632 }
633 //
634 line = new IntSurf_LineOn2S ();
635 //
00302ba4 636 for (Standard_Integer i=1; i<=4; ++i)
637 {
638 aTmp=ParDep(i);
7fd59977 639 Param(i)=ParDep(i);
640 }
b1c5c4e6 641 //-- reproduce steps uv connected to surfaces Caro1 and Caro2
642 //-- pasuv[] and pasSav[] are modified during the marching
00302ba4 643 for(Standard_Integer i = 0; i < 4; ++i)
644 {
645 pasMaxSV[i] = pasSav[i] = pasuv[i] = pasInit[i];
7fd59977 646 }
647
b1c5c4e6 648 //-- calculate the first solution point
7fd59977 649 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
650 //
651 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld);
00302ba4 652 if (!myIntersectionOn2S.IsDone())
653 {
7fd59977 654 return;
655 }
00302ba4 656
7fd59977 657 //
00302ba4 658 if (myIntersectionOn2S.IsEmpty())
659 {
7fd59977 660 return;
661 }
662 //
00302ba4 663 if(myIntersectionOn2S.IsTangent())
664 {
7fd59977 665 return;
666 }
667 //
668 Standard_Boolean Arrive, DejaReparti;
00302ba4 669 const Standard_Integer RejectIndexMAX = 250000;
7fd59977 670 Standard_Integer IncKey, RejectIndex;
671 gp_Pnt pf,pl;
672 //
673 DejaReparti = Standard_False;
674 IncKey = 0;
675 RejectIndex = 0;
676 //
677 previousPoint = myIntersectionOn2S.Point();
678 previoustg = Standard_False;
679 previousd = myIntersectionOn2S.Direction();
680 previousd1 = myIntersectionOn2S.DirectionOnS1();
681 previousd2 = myIntersectionOn2S.DirectionOnS2();
682 indextg = 1;
683 tgdir = previousd;
684 firstd1 = previousd1;
685 firstd2 = previousd2;
686 tgfirst = tglast = Standard_False;
687 choixIsoSav = ChoixIso;
688 //------------------------------------------------------------
b1c5c4e6 689 //-- Test if the first point of marching corresponds
690 //-- to a point on borders.
691 //-- In this case, DejaReparti is initialized as True
7fd59977 692 //--
693 pf = previousPoint.Value();
694 Standard_Boolean bTestFirstPoint = Standard_True;
00302ba4 695
696 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
7fd59977 697 AddAPoint(line,previousPoint);
698 //
699 IntWalk_StatusDeflection Status = IntWalk_OK;
700 Standard_Boolean NoTestDeflection = Standard_False;
701 Standard_Real SvParam[4], f;
702 Standard_Integer LevelOfEmptyInmyIntersectionOn2S=0;
703 Standard_Integer LevelOfPointConfondu = 0;
704 Standard_Integer LevelOfIterWithoutAppend = -1;
705 //
706 Arrive = Standard_False;
00302ba4 707 while(!Arrive) //010
708 {
7fd59977 709 LevelOfIterWithoutAppend++;
00302ba4 710 if(LevelOfIterWithoutAppend>20)
711 {
7fd59977 712 Arrive = Standard_True;
713 if(DejaReparti) {
00302ba4 714 break;
7fd59977 715 }
716 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
717 LevelOfIterWithoutAppend = 0;
718 }
719 //
720 // compute f
721 f = 0.;
722 switch (ChoixIso) {
723 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
724 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
725 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
726 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
727 default:break;
728 }
729 //
730 if(f<0.1) {
731 f=0.1;
732 }
733 //
734 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
735 //
736 //--ofv.begin
737 Standard_Real aIncKey, aEps, dP1, dP2, dP3, dP4;
738 //
739 dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
740 dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
741 dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
742 dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
743 //
744 aIncKey=5.*(Standard_Real)IncKey;
745 aEps=1.e-7;
00302ba4 746 if(ChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < aEps)
747 {
7fd59977 748 dP1 *= aIncKey;
749 }
00302ba4 750
751 if(ChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < aEps)
752 {
7fd59977 753 dP2 *= aIncKey;
754 }
00302ba4 755
756 if(ChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < aEps)
757 {
7fd59977 758 dP3 *= aIncKey;
759 }
00302ba4 760
761 if(ChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < aEps)
762 {
7fd59977 763 dP4 *= aIncKey;
764 }
765 //--ofv.end
766 //
767 Param(1) += dP1;
768 Param(2) += dP2;
769 Param(3) += dP3;
770 Param(4) += dP4;
771 //==========================
772 SvParam[0]=Param(1);
773 SvParam[1]=Param(2);
774 SvParam[2]=Param(3);
775 SvParam[3]=Param(4);
776 //
777 ChoixIso= myIntersectionOn2S.Perform(Param, Rsnld, ChoixIso);
778 //
00302ba4 779 if (!myIntersectionOn2S.IsDone())
780 {
b1c5c4e6 781 //end of line, division
7fd59977 782 Arrive = Standard_False;
783 Param(1)=SvParam[0];
784 Param(2)=SvParam[1];
785 Param(3)=SvParam[2];
786 Param(4)=SvParam[3];
787 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
788 }
00302ba4 789 else //009
790 {
b1c5c4e6 791 //== Calculation of exact point from Param(.) is possible
00302ba4 792 if (myIntersectionOn2S.IsEmpty())
793 {
794 Standard_Real u1,v1,u2,v2;
795 previousPoint.Parameters(u1,v1,u2,v2);
796 //
797 Arrive = Standard_False;
798 if(u1<UFirst1 || u1>ULast1)
799 {
800 Arrive=Standard_True;
801 }
802
803 if(u2<UFirst2 || u2>ULast2)
804 {
805 Arrive=Standard_True;
806 }
807
808 if(v1<VFirst1 || v1>VLast1)
809 {
810 Arrive=Standard_True;
811 }
812
813 if(v2<VFirst2 || v2>VLast2)
814 {
815 Arrive=Standard_True;
816 }
817
818 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
819 LevelOfEmptyInmyIntersectionOn2S++;
820 //
821 if(LevelOfEmptyInmyIntersectionOn2S>10)
822 {
823 pasuv[0]=pasSav[0];
824 pasuv[1]=pasSav[1];
825 pasuv[2]=pasSav[2];
826 pasuv[3]=pasSav[3];
827 }
7fd59977 828 }
00302ba4 829 else //008
830 {
831 //============================================================
832 //== A point has been found : T E S T D E F L E C T I O N
833 //============================================================
834 if(NoTestDeflection)
835 {
836 NoTestDeflection = Standard_False;
837 }
838 else
839 {
840 if(--LevelOfEmptyInmyIntersectionOn2S<=0)
841 {
842 LevelOfEmptyInmyIntersectionOn2S=0;
843 if(LevelOfIterWithoutAppend < 10)
844 {
845 Status = TestDeflection();
846 }
847 else
848 {
849 pasuv[0]*=0.5;
850 pasuv[1]*=0.5;
851 pasuv[2]*=0.5;
852 pasuv[3]*=0.5;
853 }
854 }
855 }
856
857 //============================================================
858 //== T r a i t e m e n t s u r S t a t u s ==
859 //============================================================
860 if(LevelOfPointConfondu > 5)
861 {
862 Status = IntWalk_ArretSurPoint;
863 LevelOfPointConfondu = 0;
864 }
865 //
866 if(Status==IntWalk_OK)
867 {
868 NbPasOKConseq++;
869 if(NbPasOKConseq >= 5)
870 {
871 NbPasOKConseq=0;
872 Standard_Boolean pastroppetit;
873 Standard_Real t;
874 //
875 do
876 {
877 pastroppetit=Standard_True;
878 //
879 if(pasuv[0]<pasInit[0])
880 {
881 t = (pasInit[0]-pasuv[0])*0.25;
882 if(t>0.1*pasInit[0])
883 {
884 t=0.1*pasuv[0];
885 }
886
887 pasuv[0]+=t;
888 pastroppetit=Standard_False;
889 }
890
891 if(pasuv[1]<pasInit[1])
892 {
893 t = (pasInit[1]-pasuv[1])*0.25;
894 if(t>0.1*pasInit[1]) {
895 t=0.1*pasuv[1];
896 }
897
898 pasuv[1]+=t;
899 pastroppetit=Standard_False;
900 }
901
902 if(pasuv[2]<pasInit[2])
903 {
904 t = (pasInit[2]-pasuv[2])*0.25;
905 if(t>0.1*pasInit[2])
906 {
907 t=0.1*pasuv[2];
908 }
909
910 pasuv[2]+=t;
911 pastroppetit=Standard_False;
912 }
913
914 if(pasuv[3]<pasInit[3])
915 {
916 t = (pasInit[3]-pasuv[3])*0.25;
917 if(t>0.1*pasInit[3]) {
918 t=0.1*pasuv[3];
919 }
920 pasuv[3]+=t;
921 pastroppetit=Standard_False;
922 }
923 if(pastroppetit)
924 {
925 if(pasMax<0.1)
926 {
927 pasMax*=1.1;
928 pasInit[0]*=1.1;
929 pasInit[1]*=1.1;
930 pasInit[2]*=1.1;
931 pasInit[3]*=1.1;
932 }
933 else
934 {
935 pastroppetit=Standard_False;
936 }
937 }
938 }
939 while(pastroppetit);
940 }
941 }//Status==IntWalk_OK
942 else
943 NbPasOKConseq=0;
944
945 //
946 switch(Status)//007
947 {
948 case IntWalk_ArretSurPointPrecedent:
949 {
950 Arrive = Standard_False;
951 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
952 break;
953 }
954 case IntWalk_PasTropGrand:
955 {
956 Param(1)=SvParam[0];
957 Param(2)=SvParam[1];
958 Param(3)=SvParam[2];
959 Param(4)=SvParam[3];
960
961 if(LevelOfIterWithoutAppend > 5)
962 {
963 if(pasSav[0]<pasInit[0])
964 {
965 pasInit[0]-=(pasInit[0]-pasSav[0])*0.25;
966 LevelOfIterWithoutAppend=0;
967 }
968
969 if(pasSav[1]<pasInit[1])
970 {
971 pasInit[1]-=(pasInit[1]-pasSav[1])*0.25;
972 LevelOfIterWithoutAppend=0;
973 }
974
975 if(pasSav[2]<pasInit[2])
976 {
977 pasInit[2]-=(pasInit[2]-pasSav[2])*0.25;
978 LevelOfIterWithoutAppend=0;
979 }
980
981 if(pasSav[3]<pasInit[3])
982 {
983 pasInit[3]-=(pasInit[3]-pasSav[3])*0.25;
984 LevelOfIterWithoutAppend=0;
985 }
986 }
987
988 break;
989 }
990 case IntWalk_PointConfondu:
991 {
992 LevelOfPointConfondu++;
993
994 if(LevelOfPointConfondu>5)
995 {
996 Standard_Boolean pastroppetit;
997 //
998 do
999 {
1000 pastroppetit=Standard_True;
1001
1002 if(pasuv[0]<pasInit[0])
1003 {
1004 pasuv[0]+=(pasInit[0]-pasuv[0])*0.25;
1005 pastroppetit=Standard_False;
1006 }
1007
1008 if(pasuv[1]<pasInit[1])
1009 {
1010 pasuv[1]+=(pasInit[1]-pasuv[1])*0.25;
1011 pastroppetit=Standard_False;
1012 }
1013
1014 if(pasuv[2]<pasInit[2])
1015 {
1016 pasuv[2]+=(pasInit[2]-pasuv[2])*0.25;
1017 pastroppetit=Standard_False;
1018 }
1019
1020 if(pasuv[3]<pasInit[3])
1021 {
1022 pasuv[3]+=(pasInit[3]-pasuv[3])*0.25;
1023 pastroppetit=Standard_False;
1024 }
1025
1026 if(pastroppetit)
1027 {
1028 if(pasMax<0.1)
1029 {
1030 pasMax*=1.1;
1031 pasInit[0]*=1.1;
1032 pasInit[1]*=1.1;
1033 pasInit[2]*=1.1;
1034 pasInit[3]*=1.1;
1035 }
1036 else
1037 {
1038 pastroppetit=Standard_False;
1039 }
1040 }
1041 }
1042 while(pastroppetit);
1043 }
1044
1045 break;
1046 }
1047 case IntWalk_OK:
1048 case IntWalk_ArretSurPoint://006
1049 {
1050 //=======================================================
1051 //== Stop Test t : Frame on Param(.) ==
1052 //=======================================================
1053 //xft arrive here
1054 Arrive = TestArret(DejaReparti,Param,ChoixIso);
1055 // JMB 30th December 1999.
1056 // Some statement below should not be put in comment because they are useful.
1057 // See grid CTO 909 A1 which infinitely loops
1058 if(Arrive==Standard_False && Status==IntWalk_ArretSurPoint)
1059 {
1060 Arrive=Standard_True;
7fd59977 1061#ifdef DEB
00302ba4 1062 cout << "Compile with option DEB : if problems with intersection : ";
1063 cout << "IntWalk_PWalking_1.gxx (lbr le 1erdec98)"<<endl;
7fd59977 1064#endif
00302ba4 1065 }
1066
1067 if(Arrive)
1068 {
1069 NbPasOKConseq = -10;
1070 }
1071
1072 if(!Arrive)//005
1073 {
1074 //=====================================================
1075 //== Param(.) is in the limits ==
1076 //== and does not end a closed line ==
1077 //=====================================================
1078 //== Check on the current point of myInters
1079 Standard_Boolean pointisvalid = Standard_False;
1080 {
1081 Standard_Real u1,v1,u2,v2;
1082 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1083
1084 //
1085 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1086 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1087 v1 >= Vm1 && v2 >= Vm2)
1088 {
1089 pointisvalid=Standard_True;
1090 }
1091 }
1092
1093 //
1094 if(pointisvalid)
1095 {
1096 previousPoint = myIntersectionOn2S.Point();
1097 previoustg = myIntersectionOn2S.IsTangent();
1098
1099 if(!previoustg)
1100 {
1101 previousd = myIntersectionOn2S.Direction();
1102 previousd1 = myIntersectionOn2S.DirectionOnS1();
1103 previousd2 = myIntersectionOn2S.DirectionOnS2();
1104 }
1105 //=====================================================
1106 //== Check on the previous Point
1107 {
1108 Standard_Real u1,v1,u2,v2;
1109 previousPoint.Parameters(u1,v1,u2,v2);
1110 if( u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1111 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1112 v1 >= Vm1 && v2 >= Vm2)
1113 {
1114 pl = previousPoint.Value();
1115 if(bTestFirstPoint)
1116 {
1117 if(pf.SquareDistance(pl) < aSQDistMax)
1118 {
1119 IncKey++;
1120 if(IncKey == 5000)
1121 return;
1122 else
1123 continue;
1124 }
1125 else
1126 {
1127 bTestFirstPoint = Standard_False;
1128 }
1129 }
1130 //
1131 AddAPoint(line,previousPoint);
1132 RejectIndex++;
1133
1134 if(RejectIndex >= RejectIndexMAX)
1135 {
1136 break;
1137 }
1138
1139 //
1140 LevelOfIterWithoutAppend = 0;
1141 }
1142 }
1143 }//pointisvalid
1144 //====================================================
1145
1146 if(Status == IntWalk_ArretSurPoint)
1147 {
1148 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1149 }
1150 else
1151 {
1152 if (line->NbPoints() == 2)
1153 {
1154 pasSav[0] = pasuv[0];
1155 pasSav[1] = pasuv[1];
1156 pasSav[2] = pasuv[2];
1157 pasSav[3] = pasuv[3];
1158 }
1159 }
1160 }//005 if(!Arrive)
1161 else //004
1162 {
1163 if(close)
1164 {
1165 //================= la ligne est fermee ===============
1166 AddAPoint(line,line->Value(1)); //ligne fermee
1167 LevelOfIterWithoutAppend=0;
1168 }
1169 else //$$$
1170 {
1171 //====================================================
1172 //== Param was not in the limits (was reframed)
1173 //====================================================
1174 Standard_Boolean bPrevNotTangent = !previoustg || !myIntersectionOn2S.IsTangent();
1175
1176 IntImp_ConstIsoparametric SauvChoixIso = ChoixIso;
1177 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1178 //
1179 if(!myIntersectionOn2S.IsEmpty()) //002
1180 {
1181 // mutially outpasses in the square or intersection in corner
1182
1183 if(TestArret(Standard_True,Param,ChoixIso))
1184 {
1185 NbPasOKConseq = -10;
1186 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1187
1188 if(!myIntersectionOn2S.IsEmpty())
1189 {
1190 previousPoint = myIntersectionOn2S.Point();
1191 previoustg = myIntersectionOn2S.IsTangent();
1192
1193 if (!previoustg)
1194 {
1195 previousd = myIntersectionOn2S.Direction();
1196 previousd1 = myIntersectionOn2S.DirectionOnS1();
1197 previousd2 = myIntersectionOn2S.DirectionOnS2();
1198 }
1199
1200 pl = previousPoint.Value();
1201
1202 if(bTestFirstPoint)
1203 {
1204 if(pf.SquareDistance(pl) < aSQDistMax)
1205 {
1206 IncKey++;
1207 if(IncKey == 5000)
1208 return;
1209 else
1210 continue;
1211 }
1212 else
1213 {
1214 bTestFirstPoint = Standard_False;
1215 }
1216 }
1217 //
1218 AddAPoint(line,previousPoint);
1219 RejectIndex++;
1220
1221 if(RejectIndex >= RejectIndexMAX)
1222 {
1223 break;
1224 }
1225
1226 //
1227 LevelOfIterWithoutAppend=0;
1228 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1229 }
1230 else
1231 {
1232 //fail framing divides the step
1233 Arrive = Standard_False;
1234 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1235 NoTestDeflection = Standard_True;
1236 ChoixIso = SauvChoixIso;
1237 }
1238 }//if(TestArret())
1239 else
1240 {
1241 // save the last point
1242 // to revert to it if the current point is out of bounds
1243
1244 IntSurf_PntOn2S previousPointSave = previousPoint;
1245 Standard_Boolean previoustgSave = previoustg;
1246 gp_Dir previousdSave = previousd;
1247 gp_Dir2d previousd1Save = previousd1;
1248 gp_Dir2d previousd2Save = previousd2;
1249
1250 previousPoint = myIntersectionOn2S.Point();
1251 previoustg = myIntersectionOn2S.IsTangent();
1252 Arrive = Standard_False;
1253
1254 if(!previoustg)
1255 {
1256 previousd = myIntersectionOn2S.Direction();
1257 previousd1 = myIntersectionOn2S.DirectionOnS1();
1258 previousd2 = myIntersectionOn2S.DirectionOnS2();
1259 }
1260
1261 //========================================
1262 //== Check on PreviousPoint @@
1263
1264 {
1265 Standard_Real u1,v1,u2,v2;
1266 previousPoint.Parameters(u1,v1,u2,v2);
1267
b1c5c4e6 1268 //To save initial 2d points
1269 gp_Pnt2d ParamPntOnS1(Param(1), Param(2));
1270 gp_Pnt2d ParamPntOnS2(Param(3), Param(4));
00302ba4 1271
b1c5c4e6 1272 ///////////////////////////
00302ba4 1273 Param(1) = u1;
1274 Param(2) = v1;
1275 Param(3) = u2;
1276 Param(4) = v2;
1277 //
1278
1279 //xf
1280 Standard_Boolean bFlag1, bFlag2;
1281 Standard_Real aTol2D=1.e-11;
1282 //
1283 bFlag1=u1 >= Um1-aTol2D && v1 >= Vm1-aTol2D && u1 <= UM1+aTol2D && v1 <= VM1+aTol2D;
1284 bFlag2=u2 >= Um2-aTol2D && v2 >= Vm2-aTol2D && u2 <= UM2+aTol2D && v2 <= VM2+aTol2D;
1285 if (bFlag1 && bFlag2)
1286 {
1287 /*
1288 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1289 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1290 v1 >= Vm1 && v2 >= Vm2) {
1291 */
1292 //xt
1293 pl = previousPoint.Value();
1294
1295 if(bTestFirstPoint)
1296 {
1297 if(pf.SquareDistance(pl) < aSQDistMax)
1298 {
1299 IncKey++;
1300
1301 if(IncKey == 5000)
1302 return;
1303 else
1304 continue;
1305 }
1306 else
1307 {
1308 bTestFirstPoint = Standard_False;
1309 }
1310 }
1311
b1c5c4e6 1312 //To avoid walking around the same point
1313 //in the tangent zone near a border
00302ba4 1314
b1c5c4e6 1315 if (previoustg)
1316 {
1317 Standard_Real prevU1, prevV1, prevU2, prevV2;
1318 previousPointSave.Parameters(prevU1, prevV1, prevU2, prevV2);
1319 gp_Pnt2d prevPntOnS1(prevU1, prevV1), prevPntOnS2(prevU2, prevV2);
1320 gp_Pnt2d curPntOnS1(u1, v1), curPntOnS2(u2, v2);
1321 gp_Vec2d PrevToParamOnS1(prevPntOnS1, ParamPntOnS1);
1322 gp_Vec2d PrevToCurOnS1(prevPntOnS1, curPntOnS1);
1323 gp_Vec2d PrevToParamOnS2(prevPntOnS2, ParamPntOnS2);
1324 gp_Vec2d PrevToCurOnS2(prevPntOnS2, curPntOnS2);
1325 Standard_Real MaxAngle = 3*M_PI/4;
00302ba4 1326
b1c5c4e6 1327 if (Abs(PrevToParamOnS1.Angle(PrevToCurOnS1)) > MaxAngle &&
00302ba4 1328 Abs(PrevToParamOnS2.Angle(PrevToCurOnS2)) > MaxAngle)
b1c5c4e6 1329 {
1330 Arrive = Standard_True;
1331 break;
1332 }
1333 }
00302ba4 1334
b1c5c4e6 1335 ////////////////////////////////////////
00302ba4 1336 AddAPoint(line,previousPoint);
1337 RejectIndex++;
1338
1339 if(RejectIndex >= RejectIndexMAX)
1340 {
1341 break;
1342 }
1343
1344 //
1345
1346 LevelOfIterWithoutAppend=0;
1347 Arrive = Standard_True;
1348 }
1349 else
1350 {
1351 // revert to the last correctly calculated point
1352 previousPoint = previousPointSave;
1353 previoustg = previoustgSave;
1354 previousd = previousdSave;
1355 previousd1 = previousd1Save;
1356 previousd2 = previousd2Save;
1357 }
1358 }
1359
1360 //
1361 Standard_Boolean wasExtended = Standard_False;
1362
1363 if(Arrive && myIntersectionOn2S.IsTangent() && bPrevNotTangent)
1364 {
1365 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1366 {
1367 wasExtended = Standard_True;
1368 Arrive = Standard_False;
1369 ChoixIso = SauvChoixIso;
1370 }
1371 }
1372
1373 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1374
1375 if(Arrive &&
1376 myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() &&
1377 myIntersectionOn2S.IsTangent() && bPrevNotTangent &&
1378 !wasExtended)
1379 {
1380 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1381 {
1382 wasExtended = Standard_True;
1383 Arrive = Standard_False;
1384 ChoixIso = SauvChoixIso;
1385 }
1386 }
1387 }//else !TestArret() $
1388 }//$$ end successful framing on border (!myIntersectionOn2S.IsEmpty())
1389 else
1390 {
1391 //echec framing on border; division of step
1392 Arrive = Standard_False;
1393 NoTestDeflection = Standard_True;
1394 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1395 }
1396 }//$$$ end framing on border (!close)
1397 }//004 fin TestArret return Arrive = True
1398 } // 006case IntWalk_ArretSurPoint: end Processing Status = OK or ArretSurPoint
1399 } //007 switch(Status)
b1c5c4e6 1400 } //008 end processing point (TEST DEFLECTION)
1401 } //009 end processing line (else if myIntersectionOn2S.IsDone())
1402 } //010 end if first departure point allows marching while (!Arrive)
00302ba4 1403
7fd59977 1404 done = Standard_True;
1405}
1406// ===========================================================================================================
1407// function: ExtendLineInCommonZone
1408// purpose: Extends already computed line inside tangent zone in the direction given by theChoixIso.
1409// Returns Standard_True if the line was extended through tangent zone and the last computed point
1410// is outside the tangent zone (but it is not put into the line). Otherwise returns Standard_False.
1411// ===========================================================================================================
1412Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso,
00302ba4 1413 const Standard_Boolean theDirectionFlag)
7fd59977 1414{
1415 Standard_Boolean bOutOfTangentZone = Standard_False;
1416 Standard_Boolean bStop = !myIntersectionOn2S.IsTangent();
1417 Standard_Integer dIncKey = 1;
1418 TColStd_Array1OfReal Param(1,4);
1419 IntWalk_StatusDeflection Status = IntWalk_OK;
1420 Standard_Integer nbIterWithoutAppend = 0;
1421 Standard_Integer nbEqualPoints = 0;
1422 Standard_Integer parit = 0;
1423 Standard_Integer uvit = 0;
1424 IntSurf_SequenceOfPntOn2S aSeqOfNewPoint;
1425
1426 while (!bStop) {
1427 nbIterWithoutAppend++;
1428
1429 if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) {
1430#ifdef DEB
1431 cout<<"Compile with option DEB:";
1432 cout<<"Infinite loop has detected. Stop iterations (IntWalk_PWalking_1.gxx)" << endl;
1433#endif
1434 bStop = Standard_True;
1435 break;
1436 }
1437 Standard_Real f = 0.;
1438
1439 switch (theChoixIso)
00302ba4 1440 {
1441 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
1442 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
1443 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
1444 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
1445 }
7fd59977 1446
1447 if(f<0.1) f=0.1;
00302ba4 1448
7fd59977 1449 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
1450
1451 Standard_Real dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
1452 Standard_Real dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
1453 Standard_Real dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
1454 Standard_Real dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
1455
1456 if(theChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < 1.e-7) dP1 *= (5. * (Standard_Real)dIncKey);
1457 if(theChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < 1.e-7) dP2 *= (5. * (Standard_Real)dIncKey);
1458 if(theChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < 1.e-7) dP3 *= (5. * (Standard_Real)dIncKey);
1459 if(theChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < 1.e-7) dP4 *= (5. * (Standard_Real)dIncKey);
00302ba4 1460
7fd59977 1461 Param(1) += dP1;
1462 Param(2) += dP2;
1463 Param(3) += dP3;
1464 Param(4) += dP4;
1465 Standard_Real SvParam[4];
1466 IntImp_ConstIsoparametric ChoixIso = theChoixIso;
1467
1468 for(parit = 0; parit < 4; parit++) {
1469 SvParam[parit] = Param(parit+1);
1470 }
1471 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
1472 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld, theChoixIso);
1473
1474 if (!myIntersectionOn2S.IsDone()) {
1475 return bOutOfTangentZone;
1476 }
1477 else {
1478 if (myIntersectionOn2S.IsEmpty()) {
00302ba4 1479 return bOutOfTangentZone;
7fd59977 1480 }
1481
1482 Status = TestDeflection();
1483
1484 if(Status == IntWalk_OK) {
1485
00302ba4 1486 for(uvit = 0; uvit < 4; uvit++) {
1487 if(pasuv[uvit] < pasInit[uvit]) {
1488 pasuv[uvit] = pasInit[uvit];
1489 }
1490 }
7fd59977 1491 }
1492
1493 switch(Status) {
1494 case IntWalk_ArretSurPointPrecedent:
00302ba4 1495 {
1496 bStop = Standard_True;
1497 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1498 break;
1499 }
7fd59977 1500 case IntWalk_PasTropGrand:
00302ba4 1501 {
1502 for(parit = 0; parit < 4; parit++) {
1503 Param(parit+1) = SvParam[parit];
1504 }
1505 Standard_Boolean bDecrease = Standard_False;
1506
1507 for(uvit = 0; uvit < 4; uvit++) {
1508 if(pasSav[uvit] < pasInit[uvit]) {
1509 pasInit[uvit] -= (pasInit[uvit] - pasSav[uvit]) * 0.1;
1510 bDecrease = Standard_True;
1511 }
1512 }
1513
1514 if(bDecrease) nbIterWithoutAppend--;
1515 break;
1516 }
7fd59977 1517 case IntWalk_PointConfondu:
00302ba4 1518 {
1519 for(uvit = 0; uvit < 4; uvit++) {
1520 if(pasuv[uvit] < pasInit[uvit]) {
1521 pasuv[uvit] += (pasInit[uvit] - pasuv[uvit]) * 0.1;
1522 }
1523 }
1524 break;
1525 }
7fd59977 1526 case IntWalk_OK:
1527 case IntWalk_ArretSurPoint:
00302ba4 1528 {
1529 //
1530 bStop = TestArret(theDirectionFlag, Param, ChoixIso);
1531 //
1532
1533 //
1534 if(!bStop) {
1535 Standard_Real u11,v11,u12,v12;
1536 myIntersectionOn2S.Point().Parameters(u11,v11,u12,v12);
1537 Standard_Real u21,v21,u22,v22;
1538 previousPoint.Parameters(u21,v21,u22,v22);
1539
1540 if(((fabs(u11-u21) < ResoU1) && (fabs(v11-v21) < ResoV1)) ||
1541 ((fabs(u12-u22) < ResoU2) && (fabs(v12-v22) < ResoV2))) {
1542 nbEqualPoints++;
1543 }
1544 else {
1545 nbEqualPoints = 0;
1546 }
1547 }
1548 //
1549
1550 bStop = bStop || !myIntersectionOn2S.IsTangent();
1551 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1552
1553 if(!bStop) {
1554 Standard_Boolean pointisvalid = Standard_False;
1555 Standard_Real u1,v1,u2,v2;
1556 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1557
1558 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1559 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1560 v1 >= Vm1 && v2 >= Vm2)
1561 pointisvalid = Standard_True;
1562
1563 if(pointisvalid) {
1564 previousPoint = myIntersectionOn2S.Point();
1565 previoustg = myIntersectionOn2S.IsTangent();
1566
1567 if(!previoustg) {
1568 previousd = myIntersectionOn2S.Direction();
1569 previousd1 = myIntersectionOn2S.DirectionOnS1();
1570 previousd2 = myIntersectionOn2S.DirectionOnS2();
1571 }
1572 Standard_Boolean bAddPoint = Standard_True;
1573
1574 if(line->NbPoints() >= 1) {
1575 gp_Pnt pf = line->Value(1).Value();
1576 gp_Pnt pl = previousPoint.Value();
1577
1578 if(pf.Distance(pl) < Precision::Confusion()) {
1579 dIncKey++;
1580 if(dIncKey == 5000) return bOutOfTangentZone;
1581 else bAddPoint = Standard_False;
1582 }
1583 }
1584
1585 if(bAddPoint) {
1586 aSeqOfNewPoint.Append(previousPoint);
1587 nbIterWithoutAppend = 0;
1588 }
1589 }
1590
1591 if (line->NbPoints() == 2) {
1592 for(uvit = 0; uvit < 4; uvit++) {
1593 pasSav[uvit] = pasuv[uvit];
1594 }
1595 }
1596
1597 if ( !pointisvalid ) {
1598 // decrease step if out of bounds
1599 // otherwise the same calculations will be
1600 // repeated several times
1601 if ( ( u1 > UM1 ) || ( u1 < Um1 ) )
1602 pasuv[0] *= 0.5;
1603
1604 if ( ( v1 > VM1 ) || ( v1 < Vm1 ) )
1605 pasuv[1] *= 0.5;
1606
1607 if ( ( u2 > UM2 ) || ( u2 < Um2 ) )
1608 pasuv[2] *= 0.5;
1609
1610 if ( ( v2 > VM2 ) || ( v2 < Vm2 ) )
1611 pasuv[3] *= 0.5;
1612 }
1613 } // end if(!bStop)
1614 else { //if(bStop)
1615 if(close && (line->NbPoints() >= 1)) {
1616
1617 if(!bOutOfTangentZone) {
1618 aSeqOfNewPoint.Append(line->Value(1)); // line end
1619 }
1620 nbIterWithoutAppend = 0;
1621 }
1622 else {
1623 ChoixIso = myIntersectionOn2S.Perform(Param, Rsnld, theChoixIso);
1624
1625 if(myIntersectionOn2S.IsEmpty()) {
1626 bStop = !myIntersectionOn2S.IsTangent();
1627 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1628 }
1629 else {
1630 Standard_Boolean bAddPoint = Standard_True;
1631 Standard_Boolean pointisvalid = Standard_False;
1632
1633 previousPoint = myIntersectionOn2S.Point();
1634 Standard_Real u1,v1,u2,v2;
1635 previousPoint.Parameters(u1,v1,u2,v2);
1636
1637 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1638 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1639 v1 >= Vm1 && v2 >= Vm2)
1640 pointisvalid = Standard_True;
1641
1642 if(pointisvalid) {
1643
1644 if(line->NbPoints() >= 1) {
1645 gp_Pnt pf = line->Value(1).Value();
1646 gp_Pnt pl = previousPoint.Value();
1647
1648 if(pf.Distance(pl) < Precision::Confusion()) {
1649 dIncKey++;
1650 if(dIncKey == 5000) return bOutOfTangentZone;
1651 else bAddPoint = Standard_False;
1652 }
1653 }
1654
1655 if(bAddPoint && !bOutOfTangentZone) {
1656 aSeqOfNewPoint.Append(previousPoint);
1657 nbIterWithoutAppend = 0;
1658 }
1659 }
1660 }
1661 }
1662 }
1663 break;
1664 }
7fd59977 1665 default:
00302ba4 1666 {
1667 break;
1668 }
7fd59977 1669 }
1670 }
1671 }
1672 Standard_Boolean bExtendLine = Standard_False;
1673 Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
1674
1675 Standard_Integer pit = 0;
1676
1677 for(pit = 0; !bExtendLine && (pit < 2); pit++) {
1678 if(pit == 0)
1679 previousPoint.Parameters(u1,v1,u2,v2);
1680 else {
1681 if(aSeqOfNewPoint.Length() > 0)
00302ba4 1682 aSeqOfNewPoint.Value(aSeqOfNewPoint.Length()).Parameters(u1,v1,u2,v2);
7fd59977 1683 else
00302ba4 1684 break;
7fd59977 1685 }
1686
1687 if(((u1 - Um1) < ResoU1) ||
00302ba4 1688 ((UM1 - u1) < ResoU1) ||
1689 ((u2 - Um2) < ResoU2) ||
1690 ((UM2 - u2) < ResoU2) ||
1691 ((v1 - Vm1) < ResoV1) ||
1692 ((VM1 - v1) < ResoV1) ||
1693 ((v2 - Vm2) < ResoV2) ||
1694 ((VM2 - v2) < ResoV2))
7fd59977 1695 bExtendLine = Standard_True;
1696 }
1697
1698 if(!bExtendLine) {
1699 // if(Status == IntWalk_OK || Status == IntWalk_ArretSurPoint) {
1700 if(Status == IntWalk_OK) {
1701 bExtendLine = Standard_True;
1702
1703 if(aSeqOfNewPoint.Length() > 1) {
00302ba4 1704 TColStd_Array1OfReal FirstParams(0, 3), LastParams(0, 3), Resolutions(0, 3);
1705 Resolutions(0) = ResoU1; Resolutions(1) = ResoV1; Resolutions(2) = ResoU2; Resolutions(3) = ResoV2;
1706
1707 aSeqOfNewPoint(1).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1708 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1709 aSeqOfNewPoint(aSeqOfNewPoint.Length()).Parameters(LastParams.ChangeValue(0),
1710 LastParams.ChangeValue(1),
1711 LastParams.ChangeValue(2),
1712 LastParams.ChangeValue(3));
1713 Standard_Integer indexofiso = 0;
1714
1715 if(theChoixIso == IntImp_UIsoparametricOnCaro1) indexofiso = 0;
1716 if(theChoixIso == IntImp_VIsoparametricOnCaro1) indexofiso = 1;
1717 if(theChoixIso == IntImp_UIsoparametricOnCaro2) indexofiso = 2;
1718 if(theChoixIso == IntImp_VIsoparametricOnCaro2) indexofiso = 3;
1719
1720 Standard_Integer afirstindex = (indexofiso < 2) ? 0 : 2;
1721 gp_Vec2d aTangentZoneDir(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)),
1722 gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1)));
1723
1724 gp_Dir2d anIsoDir(0, 1);
1725
1726 if((indexofiso == 1) || (indexofiso == 3))
1727 anIsoDir = gp_Dir2d(1, 0);
1728
1729 if(aTangentZoneDir.SquareMagnitude() > gp::Resolution()) {
1730 Standard_Real piquota = M_PI*0.25;
1731
1732 if(fabs(aTangentZoneDir.Angle(anIsoDir)) > piquota) {
1733 Standard_Integer ii = 1, nextii = 2;
1734 gp_Vec2d d1(0, 0);
1735 Standard_Real asqresol = gp::Resolution();
1736 asqresol *= asqresol;
1737
1738 do {
1739 aSeqOfNewPoint(ii).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1740 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1741 aSeqOfNewPoint(ii + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1742 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1743 d1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1744 FirstParams.Value(afirstindex + 1)),
1745 gp_Pnt2d(LastParams.Value(afirstindex),
1746 LastParams.Value(afirstindex + 1)));
1747 ii++;
1748 }
1749 while((d1.SquareMagnitude() < asqresol) &&
1750 (ii < aSeqOfNewPoint.Length()));
1751
1752 nextii = ii;
1753
1754 while(nextii < aSeqOfNewPoint.Length()) {
1755
1756 gp_Vec2d nextd1(0, 0);
1757 Standard_Integer jj = nextii;
1758
1759 do {
1760 aSeqOfNewPoint(jj).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1761 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1762 aSeqOfNewPoint(jj + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1763 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1764 nextd1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1765 FirstParams.Value(afirstindex + 1)),
1766 gp_Pnt2d(LastParams.Value(afirstindex),
1767 LastParams.Value(afirstindex + 1)));
1768 jj++;
1769
1770 }
1771 while((nextd1.SquareMagnitude() < asqresol) &&
1772 (jj < aSeqOfNewPoint.Length()));
1773 nextii = jj;
1774
1775 if(fabs(d1.Angle(nextd1)) > piquota) {
1776 bExtendLine = Standard_False;
1777 break;
1778 }
1779 d1 = nextd1;
1780 }
1781 }
1782 // end if(fabs(aTangentZoneDir.Angle(anIsoDir)
1783 }
7fd59977 1784 }
1785 }
1786 }
1787
1788 if(!bExtendLine) {
1789 return Standard_False;
1790 }
1791 Standard_Integer i = 0;
1792
1793 for(i = 1; i <= aSeqOfNewPoint.Length(); i++) {
1794 AddAPoint(line, aSeqOfNewPoint.Value(i));
1795 }
1796
1797 return bOutOfTangentZone;
1798}
00302ba4 1799
c2c2f2b6 1800//=======================================================================
1801//function : DistanceMinimizeByGradient
1802//purpose :
1803//=======================================================================
1804Standard_Boolean IntWalk_PWalking::
1805 DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
1806 const Handle(Adaptor3d_HSurface)& theASurf2,
1807 Standard_Real& theU1,
1808 Standard_Real& theV1,
1809 Standard_Real& theU2,
1810 Standard_Real& theV2,
1811 const Standard_Real theStep0U1V1,
1812 const Standard_Real theStep0U2V2)
00302ba4 1813{
1814 const Standard_Integer aNbIterMAX = 60;
1815 const Standard_Real aTol = 1.0e-14;
1816 Handle(Geom_Surface) aS1, aS2;
1817
1818 switch(theASurf1->GetType())
1819 {
1820 case GeomAbs_BezierSurface:
1821 aS1 = theASurf1->Surface().Bezier();
1822 break;
1823 case GeomAbs_BSplineSurface:
1824 aS1 = theASurf1->Surface().BSpline();
1825 break;
1826 default:
1827 return Standard_True;
1828 }
1829
1830 switch(theASurf2->GetType())
1831 {
1832 case GeomAbs_BezierSurface:
1833 aS2 = theASurf2->Surface().Bezier();
1834 break;
1835 case GeomAbs_BSplineSurface:
1836 aS2 = theASurf2->Surface().BSpline();
1837 break;
1838 default:
1839 return Standard_True;
1840 }
1841
1842 Standard_Boolean aStatus = Standard_False;
1843
1844 gp_Pnt aP1, aP2;
1845 gp_Vec aD1u, aD1v, aD2U, aD2V;
1846
1847 aS1->D1(theU1, theV1, aP1, aD1u, aD1v);
1848 aS2->D1(theU2, theV2, aP2, aD2U, aD2V);
1849
1850 Standard_Real aSQDistPrev = aP1.SquareDistance(aP2);
1851
1852 gp_Vec aP12(aP1, aP2);
1853
1854 Standard_Real aGradFu(-aP12.Dot(aD1u));
1855 Standard_Real aGradFv(-aP12.Dot(aD1v));
1856 Standard_Real aGradFU( aP12.Dot(aD2U));
1857 Standard_Real aGradFV( aP12.Dot(aD2V));
1858
1859 Standard_Real aSTEPuv = theStep0U1V1, aStepUV = theStep0U2V2;
1860
1861 Standard_Boolean flRepeat = Standard_True;
1862 Standard_Integer aNbIter = aNbIterMAX;
1863
1864 while(flRepeat)
1865 {
1866 Standard_Real anAdd = aGradFu*aSTEPuv;
c2c2f2b6 1867 Standard_Real aPARu = (anAdd >= 0.0)?
1868 (theU1 - Max(anAdd, Epsilon(theU1))) :
1869 (theU1 + Max(-anAdd, Epsilon(theU1)));
00302ba4 1870 anAdd = aGradFv*aSTEPuv;
c2c2f2b6 1871 Standard_Real aPARv = (anAdd >= 0.0)?
1872 (theV1 - Max(anAdd, Epsilon(theV1))) :
1873 (theV1 + Max(-anAdd, Epsilon(theV1)));
00302ba4 1874 anAdd = aGradFU*aStepUV;
c2c2f2b6 1875 Standard_Real aParU = (anAdd >= 0.0)?
1876 (theU2 - Max(anAdd, Epsilon(theU2))) :
1877 (theU2 + Max(-anAdd, Epsilon(theU2)));
00302ba4 1878 anAdd = aGradFV*aStepUV;
c2c2f2b6 1879 Standard_Real aParV = (anAdd >= 0.0)?
1880 (theV2 - Max(anAdd, Epsilon(theV2))) :
1881 (theV2 + Max(-anAdd, Epsilon(theV2)));
00302ba4 1882
1883 gp_Pnt aPt1, aPt2;
1884
1885 aS1->D1(aPARu, aPARv, aPt1, aD1u, aD1v);
1886 aS2->D1(aParU, aParV, aPt2, aD2U, aD2V);
1887
1888 Standard_Real aSQDist = aPt1.SquareDistance(aPt2);
1889
1890 if(aSQDist < aSQDistPrev)
1891 {
1892 aSQDistPrev = aSQDist;
1893 theU1 = aPARu;
1894 theV1 = aPARv;
1895 theU2 = aParU;
1896 theV2 = aParV;
1897
1898 aStatus = aSQDistPrev < aTol;
1899 aSTEPuv *= 1.2;
1900 aStepUV *= 1.2;
1901 }
1902 else
1903 {
1904 if(--aNbIter < 0)
1905 {
1906 flRepeat = Standard_False;
1907 }
1908 else
1909 {
1910 aS1->D1(theU1, theV1, aPt1, aD1u, aD1v);
1911 aS2->D1(theU2, theV2, aPt2, aD2U, aD2V);
1912
1913 gp_Vec aP12(aPt1, aPt2);
1914 aGradFu = -aP12.Dot(aD1u);
1915 aGradFv = -aP12.Dot(aD1v);
1916 aGradFU = aP12.Dot(aD2U);
1917 aGradFV = aP12.Dot(aD2V);
1918 aSTEPuv = theStep0U1V1;
1919 aStepUV = theStep0U2V2;
1920 }
1921 }
1922 }
1923
1924 return aStatus;
1925}
1926
c2c2f2b6 1927//=======================================================================
1928//function : DistanceMinimizeByExtrema
1929//purpose :
1930//=======================================================================
1931Standard_Boolean IntWalk_PWalking::
1932 DistanceMinimizeByExtrema(const Handle(Adaptor3d_HSurface)& theASurf,
1933 const gp_Pnt& theP0,
1934 Standard_Real& theU0,
1935 Standard_Real& theV0,
1936 const Standard_Real theStep0U,
1937 const Standard_Real theStep0V)
00302ba4 1938{
1939 const Standard_Real aTol = 1.0e-14;
1940 gp_Pnt aPS;
1941 gp_Vec aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp;
1942 Standard_Real aSQDistPrev = RealLast();
1943 Standard_Real aU = theU0, aV = theV0;
1944
1945 Standard_Integer aNbIter = 10;
1946 do
1947 {
1948 theASurf->D2(aU, aV, aPS, aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp);
1949
1950 gp_Vec aVec(theP0, aPS);
1951
1952 Standard_Real aSQDist = aVec.SquareMagnitude();
1953
1954 if(aSQDist >= aSQDistPrev)
1955 break;
1956
1957 aSQDistPrev = aSQDist;
1958 theU0 = aU;
1959 theV0 = aV;
1960 aNbIter--;
1961
1962 if(aSQDistPrev < aTol)
1963 break;
1964
1965 //Functions
1966 const Standard_Real aF1 = aD1Su.Dot(aVec), aF2 = aD1Sv.Dot(aVec);
1967
1968 //Derivatives
1969 const Standard_Real aDf1u = aD2Su.Dot(aVec) + aD1Su.Dot(aD1Su),
1970 aDf1v = aD2Su.Dot(aD1Sv),
1971 aDf2u = aDf1v,
1972 aDf2v = aD2Sv.Dot(aVec) + aD1Sv.Dot(aD1Sv);
1973
1974 const Standard_Real aDet = aDf1u*aDf2v - aDf1v*aDf2u;
1975 aU -= theStep0U*(aDf2v*aF1 - aDf1v*aF2)/aDet;
1976 aV += theStep0V*(aDf2u*aF1 - aDf1u*aF2)/aDet;
1977 }
1978 while(aNbIter > 0);
1979
1980 return (aSQDistPrev < aTol);
1981}
1982
c2c2f2b6 1983//=======================================================================
1984//function : SeekPointOnBoundary
1985//purpose :
1986//=======================================================================
1987Standard_Boolean IntWalk_PWalking::
1988 SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
1989 const Handle(Adaptor3d_HSurface)& theASurf2,
1990 const Standard_Real theU1,
1991 const Standard_Real theV1,
1992 const Standard_Real theU2,
1993 const Standard_Real theV2,
1994 const Standard_Boolean isTheFirst)
1995{
1996 const Standard_Real aTol = 1.0e-14;
1997 Standard_Boolean isOK = Standard_False;
1998 Standard_Real U1prec = theU1, V1prec = theV1, U2prec = theU2, V2prec = theV2;
1999
2000 Standard_Boolean flFinish = Standard_False;
2001
2002 Standard_Integer aNbIter = 20;
2003 while(!flFinish)
2004 {
2005 flFinish = Standard_False;
2006 Standard_Boolean aStatus = Standard_False;
2007
2008 do
2009 {
2010 aNbIter--;
2011 aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec);
2012 if(aStatus)
2013 {
2014 break;
2015 }
2016
2017 aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec);
2018 if(aStatus)
2019 {
2020 break;
2021 }
2022
2023 aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec);
2024 if(aStatus)
2025 {
2026 break;
2027 }
2028 }
2029 while(!aStatus && (aNbIter > 0));
2030
2031 if(aStatus)
2032 {
2033 const Standard_Real aTolMax = 1.0e-8;
2034 Standard_Real aTolF = 0.0;
2035
2036 Standard_Real u1 = U1prec, v1 = V1prec, u2 = U2prec, v2 = V2prec;
2037
2038 flFinish = Checking(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec, aTolF);
2039
2040 if(aTolF <= aTolMax)
2041 {
2042 gp_Pnt aP1 = theASurf1->Value(u1, v1),
2043 aP2 = theASurf2->Value(u2, v2);
2044 gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2045
2046 const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
2047 aSQDist2 = aPInt.SquareDistance(aP2);
2048 if((aSQDist1 < aTol) && (aSQDist2 < aTol))
2049 {
2050 IntSurf_PntOn2S anIP;
2051 anIP.SetValue(aPInt, u1, v1, u2, v2);
2052
2053 if(isTheFirst)
2054 line->InsertBefore(1,anIP);
2055 else
2056 line->Add(anIP);
2057
2058 isOK = Standard_True;
2059 }
2060 }
2061 }
2062 else
2063 {
2064 break;
2065 }
2066
2067 if(aNbIter < 0)
2068 break;
2069 }
2070
2071 return isOK;
2072}
2073
2074//=======================================================================
2075//function : PutToBoundary
2076//purpose :
2077//=======================================================================
2078Standard_Boolean IntWalk_PWalking::
2079 PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
2080 const Handle(Adaptor3d_HSurface)& theASurf2)
2081{
2082 const Standard_Real aTolMin = Precision::Confusion();
2083
2084 Standard_Boolean hasBeenAdded = Standard_False;
2085
2086 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2087 const Standard_Real aU1bLast = theASurf1->LastUParameter();
2088 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2089 const Standard_Real aU2bLast = theASurf2->LastUParameter();
2090 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2091 const Standard_Real aV1bLast = theASurf1->LastVParameter();
2092 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2093 const Standard_Real aV2bLast = theASurf2->LastVParameter();
2094
2095 Standard_Real aTol = 1.0;
2096 aTol = Min(aTol, aU1bLast - aU1bFirst);
2097 aTol = Min(aTol, aU2bLast - aU2bFirst);
2098 aTol = Min(aTol, aV1bLast - aV1bFirst);
2099 aTol = Min(aTol, aV2bLast - aV2bFirst)*1.0e-3;
2100
2101 if(aTol <= 2.0*aTolMin)
2102 return hasBeenAdded;
2103
2104 Standard_Boolean isNeedAdding = Standard_False;
2105 Standard_Boolean isU1parallel = Standard_False, isV1parallel = Standard_False;
2106 Standard_Boolean isU2parallel = Standard_False, isV2parallel = Standard_False;
2107 IsParallel(line, Standard_True, aTol, isU1parallel, isV1parallel);
2108 IsParallel(line, Standard_False, aTol, isU2parallel, isV2parallel);
2109
2110 const Standard_Integer aNbPnts = line->NbPoints();
2111 Standard_Real u1, v1, u2, v2;
2112 line->Value(1).Parameters(u1, v1, u2, v2);
2113 Standard_Real aDelta = 0.0;
2114
2115 if(!isV1parallel)
2116 {
2117 aDelta = u1 - aU1bFirst;
2118 if((aTolMin < aDelta) && (aDelta < aTol))
2119 {
2120 u1 = aU1bFirst - aDelta;
2121 isNeedAdding = Standard_True;
2122 }
2123 else
2124 {
2125 aDelta = aU1bLast - u1;
2126 if((aTolMin < aDelta) && (aDelta < aTol))
2127 {
2128 u1 = aU1bLast + aDelta;
2129 isNeedAdding = Standard_True;
2130 }
2131 }
2132 }
2133
2134 if(!isV2parallel)
2135 {
2136 aDelta = u2 - aU2bFirst;
2137 if((aTolMin < aDelta) && (aDelta < aTol))
2138 {
2139 u2 = aU2bFirst - aDelta;
2140 isNeedAdding = Standard_True;
2141 }
2142 else
2143 {
2144 aDelta = aU2bLast - u2;
2145 if((aTolMin < aDelta) && (aDelta < aTol))
2146 {
2147 u2 = aU2bLast + aDelta;
2148 isNeedAdding = Standard_True;
2149 }
2150 }
2151 }
2152
2153 if(!isU1parallel)
2154 {
2155 aDelta = v1 - aV1bFirst;
2156 if((aTolMin < aDelta) && (aDelta < aTol))
2157 {
2158 v1 = aV1bFirst - aDelta;
2159 isNeedAdding = Standard_True;
2160 }
2161 else
2162 {
2163 aDelta = aV1bLast - v1;
2164 if((aTolMin < aDelta) && (aDelta < aTol))
2165 {
2166 v1 = aV1bLast + aDelta;
2167 isNeedAdding = Standard_True;
2168 }
2169 }
2170 }
2171
2172 if(!isU2parallel)
2173 {
2174 aDelta = v2 - aV2bFirst;
2175 if((aTolMin < aDelta) && (aDelta < aTol))
2176 {
2177 v2 = aV2bFirst - aDelta;
2178 isNeedAdding = Standard_True;
2179 }
2180 else
2181 {
2182 aDelta = aV2bLast - v2;
2183 if((aTolMin < aDelta) && (aDelta < aTol))
2184 {
2185 v2 = aV2bLast + aDelta;
2186 isNeedAdding = Standard_True;
2187 }
2188 }
2189 }
2190
2191 if(isNeedAdding)
2192 {
2193 hasBeenAdded =
2194 SeekPointOnBoundary(theASurf1, theASurf2, u1,
2195 v1, u2, v2, Standard_True);
2196 }
2197
2198 isNeedAdding = Standard_False;
2199 line->Value(aNbPnts).Parameters(u1, v1, u2, v2);
2200
2201 if(!isV1parallel)
2202 {
2203 aDelta = u1 - aU1bFirst;
2204 if((aTolMin < aDelta) && (aDelta < aTol))
2205 {
2206 u1 = aU1bFirst - aDelta;
2207 isNeedAdding = Standard_True;
2208 }
2209 else
2210 {
2211 aDelta = aU1bLast - u1;
2212 if((aTolMin < aDelta) && (aDelta < aTol))
2213 {
2214 u1 = aU1bLast + aDelta;
2215 isNeedAdding = Standard_True;
2216 }
2217 }
2218 }
2219
2220 if(!isV2parallel)
2221 {
2222 aDelta = u2 - aU2bFirst;
2223 if((aTolMin < aDelta) && (aDelta < aTol))
2224 {
2225 u2 = aU2bFirst - aDelta;
2226 isNeedAdding = Standard_True;
2227 }
2228 else
2229 {
2230 aDelta = aU2bLast - u2;
2231 if((aTolMin < aDelta) && (aDelta < aTol))
2232 {
2233 u2 = aU2bLast + aDelta;
2234 isNeedAdding = Standard_True;
2235 }
2236 }
2237 }
2238
2239 if(!isU1parallel)
2240 {
2241 aDelta = v1 - aV1bFirst;
2242 if((aTolMin < aDelta) && (aDelta < aTol))
2243 {
2244 v1 = aV1bFirst - aDelta;
2245 isNeedAdding = Standard_True;
2246 }
2247 else
2248 {
2249 aDelta = aV1bLast - v1;
2250 if((aTolMin < aDelta) && (aDelta < aTol))
2251 {
2252 v1 = aV1bLast + aDelta;
2253 isNeedAdding = Standard_True;
2254 }
2255 }
2256 }
2257
2258 if(!isU2parallel)
2259 {
2260 aDelta = v2 - aV2bFirst;
2261 if((aTolMin < aDelta) && (aDelta < aTol))
2262 {
2263 v2 = aV2bFirst - aDelta;
2264 isNeedAdding = Standard_True;
2265 }
2266 else
2267 {
2268 aDelta = aV2bLast - v2;
2269 if((aTolMin < aDelta) && (aDelta < aTol))
2270 {
2271 v2 = aV2bLast + aDelta;
2272 isNeedAdding = Standard_True;
2273 }
2274 }
2275 }
2276
2277 if(isNeedAdding)
2278 {
2279 hasBeenAdded =
2280 SeekPointOnBoundary(theASurf1, theASurf2, u1,
2281 v1, u2, v2, Standard_False);
2282 }
2283
2284 return hasBeenAdded;
2285}
2286
2287//=======================================================================
2288//function : SeekAdditionalPoints
2289//purpose :
2290//=======================================================================
2291Standard_Boolean IntWalk_PWalking::
2292 SeekAdditionalPoints( const Handle(Adaptor3d_HSurface)& theASurf1,
2293 const Handle(Adaptor3d_HSurface)& theASurf2,
2294 const Standard_Integer theMinNbPoints)
00302ba4 2295{
2296 const Standard_Real aTol = 1.0e-14;
2297 Standard_Integer aNbPoints = line->NbPoints();
2298 if(aNbPoints > theMinNbPoints)
2299 return Standard_True;
2300
2301 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2302 const Standard_Real aU1bLast = theASurf1->LastUParameter();
2303 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2304 const Standard_Real aU2bLast = theASurf2->LastUParameter();
2305 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2306 const Standard_Real aV1bLast = theASurf1->LastVParameter();
2307 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2308 const Standard_Real aV2bLast = theASurf2->LastVParameter();
2309
2310
2311 Standard_Boolean isPrecise = Standard_False;
2312
2313 Standard_Real U1prec = 0.0, V1prec = 0.0, U2prec = 0.0, V2prec = 0.0;
2314
2315 Standard_Integer aNbPointsPrev = 0;
2316 while(aNbPoints < theMinNbPoints && (aNbPoints != aNbPointsPrev))
2317 {
2318 aNbPointsPrev = aNbPoints;
2319 for(Standard_Integer fp = 1, lp = 2; fp < aNbPoints; fp = lp + 1)
2320 {
2321 Standard_Real U1f, V1f, U2f, V2f; //first point in 1st and 2nd surafaces
2322 Standard_Real U1l, V1l, U2l, V2l; //last point in 1st and 2nd surafaces
2323
2324 lp = fp+1;
2325 line->Value(fp).Parameters(U1f, V1f, U2f, V2f);
2326 line->Value(lp).Parameters(U1l, V1l, U2l, V2l);
2327
2328 U1prec = 0.5*(U1f+U1l);
2329 if(U1prec < aU1bFirst)
2330 U1prec = aU1bFirst;
2331 if(U1prec > aU1bLast)
2332 U1prec = aU1bLast;
2333
2334 V1prec = 0.5*(V1f+V1l);
2335 if(V1prec < aV1bFirst)
2336 V1prec = aV1bFirst;
2337 if(V1prec > aV1bLast)
2338 V1prec = aV1bLast;
2339
2340 U2prec = 0.5*(U2f+U2l);
2341 if(U2prec < aU2bFirst)
2342 U2prec = aU2bFirst;
2343 if(U2prec > aU2bLast)
2344 U2prec = aU2bLast;
2345
2346 V2prec = 0.5*(V2f+V2l);
2347 if(V2prec < aV2bFirst)
2348 V2prec = aV2bFirst;
2349 if(V2prec > aV2bLast)
2350 V2prec = aV2bLast;
2351
2352 Standard_Boolean aStatus = Standard_False;
2353 Standard_Integer aNbIter = 5;
2354 do
2355 {
2356 aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec);
2357 if(aStatus)
2358 {
2359 break;
2360 }
2361
2362 aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec);
2363 if(aStatus)
2364 {
2365 break;
2366 }
2367
2368 aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec);
2369 if(aStatus)
2370 {
2371 break;
2372 }
2373 }
2374 while(!aStatus && (--aNbIter > 0));
2375
2376 if(aStatus)
2377 {
2378 gp_Pnt aP1 = theASurf1->Value(U1prec, V1prec),
2379 aP2 = theASurf2->Value(U2prec, V2prec);
2380 gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2381
2382 const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
2383 aSQDist2 = aPInt.SquareDistance(aP2);
2384
2385 if((aSQDist1 < aTol) && (aSQDist2 < aTol))
2386 {
2387 IntSurf_PntOn2S anIP;
2388 anIP.SetValue(aPInt, U1prec, V1prec, U2prec, V2prec);
2389 line->InsertBefore(lp, anIP);
2390
2391 isPrecise = Standard_True;
2392
2393 if(++aNbPoints >= theMinNbPoints)
2394 break;
2395 }
2396 else
2397 {
2398 lp--;
2399 }
2400 }
2401 }
2402 }
2403
2404 return isPrecise;
2405}
c2c2f2b6 2406
2407