0025890: Intersection algorithm produces curves overlaped
[occt.git] / src / IntWalk / IntWalk_PWalking.cxx
... / ...
CommitLineData
1// Copyright (c) 1995-1999 Matra Datavision
2// Copyright (c) 1999-2014 OPEN CASCADE SAS
3//
4// This file is part of Open CASCADE Technology software library.
5//
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
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.
11//
12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
14
15#include <IntWalk_PWalking.ixx>
16
17#include <IntWalk_StatusDeflection.hxx>
18
19#include <TColgp_Array1OfPnt.hxx>
20#include <TColStd_Array1OfReal.hxx>
21
22#include <IntImp_ComputeTangence.hxx>
23
24#include <Adaptor3d_HSurface.hxx>
25#include <Adaptor3d_HSurfaceTool.hxx>
26
27#include <Precision.hxx>
28
29#include <math_FunctionSetRoot.hxx>
30#include <Geom_Surface.hxx>
31
32#include <Standard_Failure.hxx>
33#include <gp_Pnt2d.hxx>
34
35//==================================================================================
36// function : IntWalk_PWalking::IntWalk_PWalking
37// purpose :
38// estimate of max step : To avoid abrupt changes
39// during change of isos
40//==================================================================================
41void ComputePasInit(Standard_Real *pasuv,
42 Standard_Real Um1,Standard_Real UM1,
43 Standard_Real Vm1,Standard_Real VM1,
44 Standard_Real Um2,Standard_Real UM2,
45 Standard_Real Vm2,Standard_Real VM2,
46 Standard_Real _Um1,Standard_Real _UM1,
47 Standard_Real _Vm1,Standard_Real _VM1,
48 Standard_Real _Um2,Standard_Real _UM2,
49 Standard_Real _Vm2,Standard_Real _VM2,
50 const Handle(Adaptor3d_HSurface)& ,
51 const Handle(Adaptor3d_HSurface)& ,
52 const Standard_Real Increment)
53{
54 Standard_Real du1=Abs(UM1-Um1);
55 Standard_Real dv1=Abs(VM1-Vm1);
56 Standard_Real du2=Abs(UM2-Um2);
57 Standard_Real dv2=Abs(VM2-Vm2);
58
59 Standard_Real _du1=Abs(_UM1-_Um1);
60 Standard_Real _dv1=Abs(_VM1-_Vm1);
61 Standard_Real _du2=Abs(_UM2-_Um2);
62 Standard_Real _dv2=Abs(_VM2-_Vm2);
63
64 //-- limit the reduction of uv box estimate to 0.01 natural box
65 //-- du1 : On box of Inter
66 //-- _du1 : On parametric space
67 if(_du1<1e50 && du1<0.01*_du1) du1=0.01*_du1;
68 if(_dv1<1e50 && dv1<0.01*_dv1) dv1=0.01*_dv1;
69 if(_du2<1e50 && du2<0.01*_du2) du2=0.01*_du2;
70 if(_dv2<1e50 && dv2<0.01*_dv2) dv2=0.01*_dv2;
71
72 pasuv[0]=Increment*du1;
73 pasuv[1]=Increment*dv1;
74 pasuv[2]=Increment*du2;
75 pasuv[3]=Increment*dv2;
76}
77
78//=======================================================================
79//function : IsParallel
80//purpose : Checks if theLine is parallel of some boundary of given
81// surface (it is determined by theCheckSurf1 flag).
82// Parallelism assumes small oscillations (swing is less or
83// equal than theToler).
84// Small lines (if first and last parameters in the Surface
85// are almost equal) are classified as parallel (as same as
86// any point can be considered as parallel of any line).
87//=======================================================================
88static void IsParallel(const Handle(IntSurf_LineOn2S)& theLine,
89 const Standard_Boolean theCheckSurf1,
90 const Standard_Real theToler,
91 Standard_Boolean& theIsUparallel,
92 Standard_Boolean& theIsVparallel)
93{
94 const Standard_Integer aNbPointsMAX = 23;
95
96 theIsUparallel = theIsVparallel = Standard_True;
97
98 Standard_Integer aNbPoints = theLine->NbPoints();
99 if(aNbPoints > aNbPointsMAX)
100 {
101 aNbPoints = aNbPointsMAX;
102 }
103 else if(aNbPoints < 3)
104 {
105 //Here we cannot estimate parallelism.
106 //Do all same as for small lines
107 return;
108 }
109
110 Standard_Real aStep = IntToReal(theLine->NbPoints()) / aNbPoints;
111 Standard_Real aNPoint = 1.0;
112
113 Standard_Real aUmin = RealLast(), aUmax = RealFirst(), aVmin = RealLast(), aVmax = RealFirst();
114 for(Standard_Integer aNum = 1; aNum <= aNbPoints; aNum++, aNPoint += aStep)
115 {
116 if(aNPoint > aNbPoints)
117 {
118 aNPoint = aNbPoints;
119 }
120
121 Standard_Real u, v;
122 if(theCheckSurf1)
123 theLine->Value(RealToInt(aNPoint)).ParametersOnS1(u, v);
124 else
125 theLine->Value(RealToInt(aNPoint)).ParametersOnS2(u, v);
126
127 if(u < aUmin)
128 aUmin = u;
129
130 if(u > aUmax)
131 aUmax = u;
132
133 if(v < aVmin)
134 aVmin = v;
135
136 if(v > aVmax)
137 aVmax = v;
138 }
139
140 theIsVparallel = ((aUmax - aUmin) < theToler);
141 theIsUparallel = ((aVmax - aVmin) < theToler);
142}
143
144//=======================================================================
145//function : Checking
146//purpose : Check, if given point is in surface's boundaries.
147// If "yes" then theFactTol = 0.0, else theFactTol is
148// equal maximal deviation.
149//=======================================================================
150static Standard_Boolean Checking( const Handle(Adaptor3d_HSurface)& theASurf1,
151 const Handle(Adaptor3d_HSurface)& theASurf2,
152 Standard_Real& theU1,
153 Standard_Real& theV1,
154 Standard_Real& theU2,
155 Standard_Real& theV2,
156 Standard_Real& theFactTol)
157{
158 const Standard_Real aTol = Precision::PConfusion();
159 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
160 const Standard_Real aU1bLast = theASurf1->LastUParameter();
161 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
162 const Standard_Real aU2bLast = theASurf2->LastUParameter();
163 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
164 const Standard_Real aV1bLast = theASurf1->LastVParameter();
165 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
166 const Standard_Real aV2bLast = theASurf2->LastVParameter();
167
168 Standard_Boolean isOnOrIn = Standard_True;
169 theFactTol = 0.0;
170
171 Standard_Real aDelta = aU1bFirst - theU1;
172 if(aDelta > aTol)
173 {
174 theU1 = aU1bFirst;
175 theFactTol = Max(theFactTol, aDelta);
176 isOnOrIn = Standard_False;
177 }
178
179 aDelta = theU1 - aU1bLast;
180 if(aDelta > aTol)
181 {
182 theU1 = aU1bLast;
183 theFactTol = Max(theFactTol, aDelta);
184 isOnOrIn = Standard_False;
185 }
186
187 aDelta = aV1bFirst - theV1;
188 if(aDelta > aTol)
189 {
190 theV1 = aV1bFirst;
191 theFactTol = Max(theFactTol, aDelta);
192 isOnOrIn = Standard_False;
193 }
194
195 aDelta = theV1 - aV1bLast;
196 if(aDelta > aTol)
197 {
198 theV1 = aV1bLast;
199 theFactTol = Max(theFactTol, aDelta);
200 isOnOrIn = Standard_False;
201 }
202
203 aDelta = aU2bFirst - theU2;
204 if(aDelta > aTol)
205 {
206 theU2 = aU2bFirst;
207 theFactTol = Max(theFactTol, aDelta);
208 isOnOrIn = Standard_False;
209 }
210
211 aDelta = theU2 - aU2bLast;
212 if(aDelta > aTol)
213 {
214 theU2 = aU2bLast;
215 theFactTol = Max(theFactTol, aDelta);
216 isOnOrIn = Standard_False;
217 }
218
219 aDelta = aV2bFirst - theV2;
220 if(aDelta > aTol)
221 {
222 theV2 = aV2bFirst;
223 theFactTol = Max(theFactTol, aDelta);
224 isOnOrIn = Standard_False;
225 }
226
227 aDelta = theV2 - aV2bLast;
228 if(aDelta > aTol)
229 {
230 theV2 = aV2bLast;
231 theFactTol = Max(theFactTol, aDelta);
232 isOnOrIn = Standard_False;
233 }
234
235 return isOnOrIn;
236}
237
238//==================================================================================
239// function : IntWalk_PWalking::IntWalk_PWalking
240// purpose :
241//==================================================================================
242IntWalk_PWalking::IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1,
243 const Handle(Adaptor3d_HSurface)& Caro2,
244 const Standard_Real TolTangency,
245 const Standard_Real Epsilon,
246 const Standard_Real Deflection,
247 const Standard_Real Increment )
248 :
249
250done(Standard_True),
251close(Standard_False),
252fleche(Deflection),
253tolconf(Epsilon),
254sensCheminement(1),
255myIntersectionOn2S(Caro1,Caro2,TolTangency),
256STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
257STATIC_PRECEDENT_INFLEXION(0)
258{
259 Standard_Real KELARG=20.;
260 //
261 pasMax=Increment*0.2; //-- June 25 99 after problems with precision
262 Um1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
263 Vm1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
264 UM1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1);
265 VM1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1);
266
267 Um2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
268 Vm2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
269 UM2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2);
270 VM2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2);
271
272 ResoU1 = Adaptor3d_HSurfaceTool::UResolution(Caro1,Precision::Confusion());
273 ResoV1 = Adaptor3d_HSurfaceTool::VResolution(Caro1,Precision::Confusion());
274
275 ResoU2 = Adaptor3d_HSurfaceTool::UResolution(Caro2,Precision::Confusion());
276 ResoV2 = Adaptor3d_HSurfaceTool::VResolution(Caro2,Precision::Confusion());
277
278 Standard_Real NEWRESO;
279 Standard_Real MAXVAL;
280 Standard_Real MAXVAL2;
281 //
282 MAXVAL = Abs(Um1); MAXVAL2 = Abs(UM1);
283 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
284 NEWRESO = ResoU1 * MAXVAL ;
285 if(NEWRESO > ResoU1 &&NEWRESO<10) { ResoU1 = NEWRESO; }
286
287
288 MAXVAL = Abs(Um2); MAXVAL2 = Abs(UM2);
289 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
290 NEWRESO = ResoU2 * MAXVAL ;
291 if(NEWRESO > ResoU2 && NEWRESO<10) { ResoU2 = NEWRESO; }
292
293
294 MAXVAL = Abs(Vm1); MAXVAL2 = Abs(VM1);
295 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
296 NEWRESO = ResoV1 * MAXVAL ;
297 if(NEWRESO > ResoV1 && NEWRESO<10) { ResoV1 = NEWRESO; }
298
299
300 MAXVAL = Abs(Vm2); MAXVAL2 = Abs(VM2);
301 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
302 NEWRESO = ResoV2 * MAXVAL ;
303 if(NEWRESO > ResoV2 && NEWRESO<10) { ResoV2 = NEWRESO; }
304
305 pasuv[0]=pasMax*Abs(UM1-Um1);
306 pasuv[1]=pasMax*Abs(VM1-Vm1);
307 pasuv[2]=pasMax*Abs(UM2-Um2);
308 pasuv[3]=pasMax*Abs(VM2-Vm2);
309
310 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
311 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
312 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
313 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
314
315
316 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
317 //UM1+=KELARG*pasuv[0]; Um1-=KELARG*pasuv[0];
318 }
319 else {
320 Standard_Real t = UM1-Um1;
321 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro1)) {
322 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro1)-t);
323 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
324 UM1+=t; Um1-=t;
325 }
326 }
327
328 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
329 //VM1+=KELARG*pasuv[1]; Vm1-=KELARG*pasuv[1];
330 }
331 else {
332 Standard_Real t = VM1-Vm1;
333 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro1)) {
334 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro1)-t);
335 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
336 VM1+=t; Vm1-=t;
337 }
338 }
339
340 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
341 //UM2+=KELARG*pasuv[2]; Um2-=KELARG*pasuv[2];
342 }
343 else {
344 Standard_Real t = UM2-Um2;
345 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro2)) {
346 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro2)-t);
347 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
348 UM2+=t; Um2-=t;
349 }
350 }
351
352 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
353 //VM2+=KELARG*pasuv[3]; Vm2-=KELARG*pasuv[3];
354 }
355 else {
356 Standard_Real t = VM2-Vm2;
357 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro2)) {
358 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro2)-t);
359 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
360 VM2+=t; Vm2-=t;
361 }
362 }
363
364 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
365
366 for (Standard_Integer i = 0; i<=3;i++) {
367 if(pasuv[i]>10)
368 pasuv[i] = 10;
369 pasInit[i] = pasSav[i] = pasuv[i];
370 }
371
372
373}
374//==================================================================================
375// function : IntWalk_PWalking
376// purpose :
377//==================================================================================
378IntWalk_PWalking::IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1,
379 const Handle(Adaptor3d_HSurface)& Caro2,
380 const Standard_Real TolTangency,
381 const Standard_Real Epsilon,
382 const Standard_Real Deflection,
383 const Standard_Real Increment,
384 const Standard_Real U1,
385 const Standard_Real V1,
386 const Standard_Real U2,
387 const Standard_Real V2)
388 :
389
390done(Standard_True),
391close(Standard_False),
392fleche(Deflection),
393tolconf(Epsilon),
394sensCheminement(1),
395myIntersectionOn2S(Caro1,Caro2,TolTangency),
396STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
397STATIC_PRECEDENT_INFLEXION(0)
398{
399 Standard_Real KELARG=20.;
400 //
401 pasMax=Increment*0.2; //-- June 25 99 after problems with precision
402 //
403 Um1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
404 Vm1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
405 UM1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1);
406 VM1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1);
407
408 Um2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
409 Vm2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
410 UM2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2);
411 VM2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2);
412
413 ResoU1 = Adaptor3d_HSurfaceTool::UResolution(Caro1,Precision::Confusion());
414 ResoV1 = Adaptor3d_HSurfaceTool::VResolution(Caro1,Precision::Confusion());
415
416 ResoU2 = Adaptor3d_HSurfaceTool::UResolution(Caro2,Precision::Confusion());
417 ResoV2 = Adaptor3d_HSurfaceTool::VResolution(Caro2,Precision::Confusion());
418 //
419 Standard_Real NEWRESO, MAXVAL, MAXVAL2;
420 //
421 MAXVAL = Abs(Um1);
422 MAXVAL2 = Abs(UM1);
423 if(MAXVAL2 > MAXVAL) {
424 MAXVAL = MAXVAL2;
425 }
426 NEWRESO = ResoU1 * MAXVAL ;
427 if(NEWRESO > ResoU1) {
428 ResoU1 = NEWRESO;
429 }
430 //
431 MAXVAL = Abs(Um2);
432 MAXVAL2 = Abs(UM2);
433 if(MAXVAL2 > MAXVAL){
434 MAXVAL = MAXVAL2;
435 }
436 NEWRESO = ResoU2 * MAXVAL ;
437 if(NEWRESO > ResoU2) {
438 ResoU2 = NEWRESO;
439 }
440 //
441 MAXVAL = Abs(Vm1);
442 MAXVAL2 = Abs(VM1);
443 if(MAXVAL2 > MAXVAL) {
444 MAXVAL = MAXVAL2;
445 }
446 NEWRESO = ResoV1 * MAXVAL ;
447 if(NEWRESO > ResoV1) {
448 ResoV1 = NEWRESO;
449 }
450 //
451 MAXVAL = Abs(Vm2);
452 MAXVAL2 = Abs(VM2);
453 if(MAXVAL2 > MAXVAL){
454 MAXVAL = MAXVAL2;
455 }
456 NEWRESO = ResoV2 * MAXVAL ;
457 if(NEWRESO > ResoV2) {
458 ResoV2 = NEWRESO;
459 }
460 //
461 pasuv[0]=pasMax*Abs(UM1-Um1);
462 pasuv[1]=pasMax*Abs(VM1-Vm1);
463 pasuv[2]=pasMax*Abs(UM2-Um2);
464 pasuv[3]=pasMax*Abs(VM2-Vm2);
465 //
466 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
467 UM1+=KELARG*pasuv[0];
468 Um1-=KELARG*pasuv[0];
469 }
470 else {
471 Standard_Real t = UM1-Um1;
472 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro1)) {
473 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro1)-t);
474 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
475 UM1+=t;
476 Um1-=t;
477 }
478 }
479 //
480 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
481 VM1+=KELARG*pasuv[1];
482 Vm1-=KELARG*pasuv[1];
483 }
484 else {
485 Standard_Real t = VM1-Vm1;
486 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro1)) {
487 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro1)-t);
488 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
489 VM1+=t; Vm1-=t;
490 }
491 }
492 //
493 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
494 UM2+=KELARG*pasuv[2];
495 Um2-=KELARG*pasuv[2];
496 }
497 else {
498 Standard_Real t = UM2-Um2;
499 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro2)) {
500 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro2)-t);
501 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
502 UM2+=t;
503 Um2-=t;
504 }
505 }
506
507 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
508 VM2+=KELARG*pasuv[3];
509 Vm2-=KELARG*pasuv[3];
510 }
511 else {
512 Standard_Real t = VM2-Vm2;
513 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro2)) {
514 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro2)-t);
515 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
516 VM2+=t;
517 Vm2-=t;
518 }
519 }
520 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
521
522 for (Standard_Integer i = 0; i<=3;i++) {
523 pasInit[i] = pasSav[i] = pasuv[i];
524 }
525
526 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
527 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
528 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
529 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
530 //
531 TColStd_Array1OfReal Par(1,4);
532 Par(1) = U1;
533 Par(2) = V1;
534 Par(3) = U2;
535 Par(4) = V2;
536 Perform(Par);
537}
538
539//==================================================================================
540// function : PerformFirstPoint
541// purpose :
542//==================================================================================
543Standard_Boolean IntWalk_PWalking::PerformFirstPoint (const TColStd_Array1OfReal& ParDep,
544 IntSurf_PntOn2S& FirstPoint)
545{
546 sensCheminement = 1;
547 close = Standard_False;
548 //
549 Standard_Integer i;
550 TColStd_Array1OfReal Param(1,4);
551 //
552 for (i=1; i<=4; ++i) {
553 Param(i) = ParDep(i);
554 }
555 //-- calculate the first solution point
556 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
557 //
558 myIntersectionOn2S.Perform(Param,Rsnld);
559 if (!myIntersectionOn2S.IsDone()) {
560 return Standard_False;
561 }
562
563 if (myIntersectionOn2S.IsEmpty()) {
564 return Standard_False;
565 }
566
567 FirstPoint = myIntersectionOn2S.Point();
568 return Standard_True;
569}
570//==================================================================================
571// function : Perform
572// purpose :
573//==================================================================================
574void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep)
575{
576 Perform(ParDep,Um1,Vm1,Um2,Vm2,UM1,VM1,UM2,VM2);
577}
578//==================================================================================
579// function : Perform
580// purpose :
581//==================================================================================
582void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
583 const Standard_Real u1min,
584 const Standard_Real v1min,
585 const Standard_Real u2min,
586 const Standard_Real v2min,
587 const Standard_Real u1max,
588 const Standard_Real v1max,
589 const Standard_Real u2max,
590 const Standard_Real v2max)
591{
592 const Standard_Real aSQDistMax = 1.0e-14;
593 //xf
594
595 Standard_Integer NbPasOKConseq=0;
596 TColStd_Array1OfReal Param(1,4);
597 IntImp_ConstIsoparametric ChoixIso;
598 //xt
599 //
600 done = Standard_False;
601 //
602 // Caro1 and Caro2
603 const Handle(Adaptor3d_HSurface)& Caro1 =myIntersectionOn2S.Function().AuxillarSurface1();
604 const Handle(Adaptor3d_HSurface)& Caro2 =myIntersectionOn2S.Function().AuxillarSurface2();
605 //
606 const Standard_Real UFirst1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
607 const Standard_Real VFirst1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
608 const Standard_Real ULast1 = Adaptor3d_HSurfaceTool::LastUParameter (Caro1);
609 const Standard_Real VLast1 = Adaptor3d_HSurfaceTool::LastVParameter (Caro1);
610
611 const Standard_Real UFirst2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
612 const Standard_Real VFirst2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
613 const Standard_Real ULast2 = Adaptor3d_HSurfaceTool::LastUParameter (Caro2);
614 const Standard_Real VLast2 = Adaptor3d_HSurfaceTool::LastVParameter (Caro2);
615 //
616 ComputePasInit(pasuv,u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max,
617 Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2,pasMax+pasMax);
618 //
619 if(pasuv[0]<100.0*ResoU1) {
620 pasuv[0]=100.0*ResoU1;
621 }
622 if(pasuv[1]<100.0*ResoV1) {
623 pasuv[1]=100.0*ResoV1;
624 }
625 if(pasuv[2]<100.0*ResoU2) {
626 pasuv[2]=100.0*ResoU2;
627 }
628 if(pasuv[3]<100.0*ResoV2) {
629 pasuv[3]=100.0*ResoV2;
630 }
631 //
632 for (Standard_Integer i=0; i<4; ++i)
633 {
634 if(pasuv[i]>10)
635 {
636 pasuv[i] = 10;
637 }
638
639 pasInit[i] = pasSav[i] = pasuv[i];
640 }
641 //
642 line = new IntSurf_LineOn2S ();
643 //
644 for (Standard_Integer i=1; i<=4; ++i)
645 {
646 Param(i)=ParDep(i);
647 }
648 //-- reproduce steps uv connected to surfaces Caro1 and Caro2
649 //-- pasuv[] and pasSav[] are modified during the marching
650 for(Standard_Integer i = 0; i < 4; ++i)
651 {
652 pasSav[i] = pasuv[i] = pasInit[i];
653 }
654
655 //-- calculate the first solution point
656 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
657 //
658 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld);
659 if (!myIntersectionOn2S.IsDone())
660 {
661 return;
662 }
663
664 //
665 if (myIntersectionOn2S.IsEmpty())
666 {
667 return;
668 }
669 //
670 if(myIntersectionOn2S.IsTangent())
671 {
672 return;
673 }
674 //
675 Standard_Boolean Arrive, DejaReparti;
676 const Standard_Integer RejectIndexMAX = 250000;
677 Standard_Integer IncKey, RejectIndex;
678 gp_Pnt pf,pl;
679 //
680 DejaReparti = Standard_False;
681 IncKey = 0;
682 RejectIndex = 0;
683 //
684 previousPoint = myIntersectionOn2S.Point();
685 previoustg = Standard_False;
686 previousd = myIntersectionOn2S.Direction();
687 previousd1 = myIntersectionOn2S.DirectionOnS1();
688 previousd2 = myIntersectionOn2S.DirectionOnS2();
689 indextg = 1;
690 tgdir = previousd;
691 firstd1 = previousd1;
692 firstd2 = previousd2;
693 tgfirst = tglast = Standard_False;
694 choixIsoSav = ChoixIso;
695 //------------------------------------------------------------
696 //-- Test if the first point of marching corresponds
697 //-- to a point on borders.
698 //-- In this case, DejaReparti is initialized as True
699 //--
700 pf = previousPoint.Value();
701 Standard_Boolean bTestFirstPoint = Standard_True;
702
703 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
704 AddAPoint(line,previousPoint);
705 //
706 IntWalk_StatusDeflection Status = IntWalk_OK;
707 Standard_Boolean NoTestDeflection = Standard_False;
708 Standard_Real SvParam[4], f;
709 Standard_Integer LevelOfEmptyInmyIntersectionOn2S=0;
710 Standard_Integer LevelOfPointConfondu = 0;
711 Standard_Integer LevelOfIterWithoutAppend = -1;
712 //
713
714 const Standard_Real aTol[4] = { Epsilon(u1max - u1min),
715 Epsilon(v1max - v1min),
716 Epsilon(u2max - u2min),
717 Epsilon(v2max - v2min)};
718 Arrive = Standard_False;
719 while(!Arrive) //010
720 {
721 LevelOfIterWithoutAppend++;
722 if(LevelOfIterWithoutAppend>20)
723 {
724 Arrive = Standard_True;
725 if(DejaReparti) {
726 break;
727 }
728 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
729 LevelOfIterWithoutAppend = 0;
730 }
731 //
732 // compute f
733 f = 0.;
734 switch (ChoixIso) {
735 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
736 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
737 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
738 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
739 default:break;
740 }
741 //
742 if(f<0.1) {
743 f=0.1;
744 }
745 //
746 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
747 //
748 //--ofv.begin
749 Standard_Real aIncKey, aEps, dP1, dP2, dP3, dP4;
750 //
751 dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
752 dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
753 dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
754 dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
755 //
756 aIncKey=5.*(Standard_Real)IncKey;
757 aEps=1.e-7;
758 if(ChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < aEps)
759 {
760 dP1 *= aIncKey;
761 }
762
763 if(ChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < aEps)
764 {
765 dP2 *= aIncKey;
766 }
767
768 if(ChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < aEps)
769 {
770 dP3 *= aIncKey;
771 }
772
773 if(ChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < aEps)
774 {
775 dP4 *= aIncKey;
776 }
777 //--ofv.end
778 //
779 Param(1) += dP1;
780 Param(2) += dP2;
781 Param(3) += dP3;
782 Param(4) += dP4;
783 //==========================
784 SvParam[0]=Param(1);
785 SvParam[1]=Param(2);
786 SvParam[2]=Param(3);
787 SvParam[3]=Param(4);
788 //
789 Standard_Integer aTryNumber = 0;
790 Standard_Real isBadPoint = Standard_False;
791 IntImp_ConstIsoparametric aBestIso = ChoixIso;
792 do
793 {
794 isBadPoint = Standard_False;
795
796 ChoixIso= myIntersectionOn2S.Perform(Param, Rsnld, aBestIso);
797
798 if (myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty())
799 {
800 //If we go along any surface boundary then it is possible
801 //to find "outboundaried" point.
802 //Nevertheless, if this deflection is quite small, we will be
803 //able to adjust this point to the boundary.
804
805 Standard_Real aNewPnt[4], anAbsParamDist[4];
806 myIntersectionOn2S.Point().Parameters(aNewPnt[0], aNewPnt[1], aNewPnt[2], aNewPnt[3]);
807 const Standard_Real aParMin[4] = {u1min, v1min, u2min, v2min};
808 const Standard_Real aParMax[4] = {u1max, v1max, u2max, v2max};
809
810 for(Standard_Integer i = 0; i < 4; i++)
811 {
812 if(Abs(aNewPnt[i] - aParMin[i]) < aTol[i])
813 aNewPnt[i] = aParMin[i];
814 else if(Abs(aNewPnt[i] - aParMax[i]) < aTol[i])
815 aNewPnt[i] = aParMax[i];
816 }
817
818 if (aNewPnt[0] < u1min || aNewPnt[0] > u1max ||
819 aNewPnt[1] < v1min || aNewPnt[1] > v1max ||
820 aNewPnt[2] < u2min || aNewPnt[2] > u2max ||
821 aNewPnt[3] < v2min || aNewPnt[3] > v2max)
822 {
823 break; // Out of borders, handle this later.
824 }
825
826 myIntersectionOn2S.ChangePoint().SetValue(aNewPnt[0],
827 aNewPnt[1],
828 aNewPnt[2],
829 aNewPnt[3]);
830
831 anAbsParamDist[0] = Abs(Param(1) - dP1 - aNewPnt[0]);
832 anAbsParamDist[1] = Abs(Param(2) - dP2 - aNewPnt[1]);
833 anAbsParamDist[2] = Abs(Param(3) - dP3 - aNewPnt[2]);
834 anAbsParamDist[3] = Abs(Param(4) - dP4 - aNewPnt[3]);
835 if (anAbsParamDist[0] < ResoU1 &&
836 anAbsParamDist[1] < ResoV1 &&
837 anAbsParamDist[2] < ResoU2 &&
838 anAbsParamDist[3] < ResoV2 &&
839 Status != IntWalk_PasTropGrand)
840 {
841 isBadPoint = Standard_True;
842 aBestIso = IntImp_ConstIsoparametric((aBestIso + 1) % 4);
843 }
844 }
845 } while (isBadPoint && ++aTryNumber <= 4);
846 //
847 if (!myIntersectionOn2S.IsDone())
848 {
849 //end of line, division
850 Arrive = Standard_False;
851 Param(1)=SvParam[0];
852 Param(2)=SvParam[1];
853 Param(3)=SvParam[2];
854 Param(4)=SvParam[3];
855 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
856 }
857 else //009
858 {
859 //== Calculation of exact point from Param(.) is possible
860 if (myIntersectionOn2S.IsEmpty())
861 {
862 Standard_Real u1,v1,u2,v2;
863 previousPoint.Parameters(u1,v1,u2,v2);
864 //
865 Arrive = Standard_False;
866 if(u1<UFirst1 || u1>ULast1)
867 {
868 Arrive=Standard_True;
869 }
870
871 if(u2<UFirst2 || u2>ULast2)
872 {
873 Arrive=Standard_True;
874 }
875
876 if(v1<VFirst1 || v1>VLast1)
877 {
878 Arrive=Standard_True;
879 }
880
881 if(v2<VFirst2 || v2>VLast2)
882 {
883 Arrive=Standard_True;
884 }
885
886 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
887 LevelOfEmptyInmyIntersectionOn2S++;
888 //
889 if(LevelOfEmptyInmyIntersectionOn2S>10)
890 {
891 pasuv[0]=pasSav[0];
892 pasuv[1]=pasSav[1];
893 pasuv[2]=pasSav[2];
894 pasuv[3]=pasSav[3];
895 }
896 }
897 else //008
898 {
899 //============================================================
900 //== A point has been found : T E S T D E F L E C T I O N
901 //============================================================
902 if(NoTestDeflection)
903 {
904 NoTestDeflection = Standard_False;
905 }
906 else
907 {
908 if(--LevelOfEmptyInmyIntersectionOn2S<=0)
909 {
910 LevelOfEmptyInmyIntersectionOn2S=0;
911 if(LevelOfIterWithoutAppend < 10)
912 {
913 Status = TestDeflection();
914 }
915 else
916 {
917 pasuv[0]*=0.5;
918 pasuv[1]*=0.5;
919 pasuv[2]*=0.5;
920 pasuv[3]*=0.5;
921 }
922 }
923 }
924
925 //============================================================
926 //== T r a i t e m e n t s u r S t a t u s ==
927 //============================================================
928 if(LevelOfPointConfondu > 5)
929 {
930 Status = IntWalk_ArretSurPoint;
931 LevelOfPointConfondu = 0;
932 }
933 //
934 if(Status==IntWalk_OK)
935 {
936 NbPasOKConseq++;
937 if(NbPasOKConseq >= 5)
938 {
939 NbPasOKConseq=0;
940 Standard_Boolean pastroppetit;
941 Standard_Real t;
942 //
943 do
944 {
945 pastroppetit=Standard_True;
946 //
947 if(pasuv[0]<pasInit[0])
948 {
949 t = (pasInit[0]-pasuv[0])*0.25;
950 if(t>0.1*pasInit[0])
951 {
952 t=0.1*pasuv[0];
953 }
954
955 pasuv[0]+=t;
956 pastroppetit=Standard_False;
957 }
958
959 if(pasuv[1]<pasInit[1])
960 {
961 t = (pasInit[1]-pasuv[1])*0.25;
962 if(t>0.1*pasInit[1]) {
963 t=0.1*pasuv[1];
964 }
965
966 pasuv[1]+=t;
967 pastroppetit=Standard_False;
968 }
969
970 if(pasuv[2]<pasInit[2])
971 {
972 t = (pasInit[2]-pasuv[2])*0.25;
973 if(t>0.1*pasInit[2])
974 {
975 t=0.1*pasuv[2];
976 }
977
978 pasuv[2]+=t;
979 pastroppetit=Standard_False;
980 }
981
982 if(pasuv[3]<pasInit[3])
983 {
984 t = (pasInit[3]-pasuv[3])*0.25;
985 if(t>0.1*pasInit[3]) {
986 t=0.1*pasuv[3];
987 }
988 pasuv[3]+=t;
989 pastroppetit=Standard_False;
990 }
991 if(pastroppetit)
992 {
993 if(pasMax<0.1)
994 {
995 pasMax*=1.1;
996 pasInit[0]*=1.1;
997 pasInit[1]*=1.1;
998 pasInit[2]*=1.1;
999 pasInit[3]*=1.1;
1000 }
1001 else
1002 {
1003 pastroppetit=Standard_False;
1004 }
1005 }
1006 }
1007 while(pastroppetit);
1008 }
1009 }//Status==IntWalk_OK
1010 else
1011 NbPasOKConseq=0;
1012
1013 //
1014 switch(Status)//007
1015 {
1016 case IntWalk_ArretSurPointPrecedent:
1017 {
1018 Arrive = Standard_False;
1019 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
1020 break;
1021 }
1022 case IntWalk_PasTropGrand:
1023 {
1024 Param(1)=SvParam[0];
1025 Param(2)=SvParam[1];
1026 Param(3)=SvParam[2];
1027 Param(4)=SvParam[3];
1028
1029 if(LevelOfIterWithoutAppend > 5)
1030 {
1031 for (Standard_Integer i = 0; i < 4; i++)
1032 {
1033 if (pasSav[i] > pasInit[i])
1034 continue;
1035
1036 const Standard_Real aDelta = (pasInit[i]-pasSav[i])*0.25;
1037
1038 if(aDelta > Epsilon(pasInit[i]))
1039 {
1040 pasInit[i] -= aDelta;
1041 LevelOfIterWithoutAppend=0;
1042 }
1043 }
1044 }
1045
1046 break;
1047 }
1048 case IntWalk_PointConfondu:
1049 {
1050 LevelOfPointConfondu++;
1051
1052 if(LevelOfPointConfondu>5)
1053 {
1054 Standard_Boolean pastroppetit;
1055 //
1056 do
1057 {
1058 pastroppetit=Standard_True;
1059
1060 if(pasuv[0]<pasInit[0])
1061 {
1062 pasuv[0]+=(pasInit[0]-pasuv[0])*0.25;
1063 pastroppetit=Standard_False;
1064 }
1065
1066 if(pasuv[1]<pasInit[1])
1067 {
1068 pasuv[1]+=(pasInit[1]-pasuv[1])*0.25;
1069 pastroppetit=Standard_False;
1070 }
1071
1072 if(pasuv[2]<pasInit[2])
1073 {
1074 pasuv[2]+=(pasInit[2]-pasuv[2])*0.25;
1075 pastroppetit=Standard_False;
1076 }
1077
1078 if(pasuv[3]<pasInit[3])
1079 {
1080 pasuv[3]+=(pasInit[3]-pasuv[3])*0.25;
1081 pastroppetit=Standard_False;
1082 }
1083
1084 if(pastroppetit)
1085 {
1086 if(pasMax<0.1)
1087 {
1088 pasMax*=1.1;
1089 pasInit[0]*=1.1;
1090 pasInit[1]*=1.1;
1091 pasInit[2]*=1.1;
1092 pasInit[3]*=1.1;
1093 }
1094 else
1095 {
1096 pastroppetit=Standard_False;
1097 }
1098 }
1099 }
1100 while(pastroppetit);
1101 }
1102
1103 break;
1104 }
1105 case IntWalk_OK:
1106 case IntWalk_ArretSurPoint://006
1107 {
1108 //=======================================================
1109 //== Stop Test t : Frame on Param(.) ==
1110 //=======================================================
1111 //xft arrive here
1112 Arrive = TestArret(DejaReparti,Param,ChoixIso);
1113 // JMB 30th December 1999.
1114 // Some statement below should not be put in comment because they are useful.
1115 // See grid CTO 909 A1 which infinitely loops
1116 if(Arrive==Standard_False && Status==IntWalk_ArretSurPoint)
1117 {
1118 Arrive=Standard_True;
1119#ifdef OCCT_DEBUG
1120 cout << "IntWalk_PWalking_1.gxx: Problems with intersection"<<endl;
1121#endif
1122 }
1123
1124 if(Arrive)
1125 {
1126 NbPasOKConseq = -10;
1127 }
1128
1129 if(!Arrive)//005
1130 {
1131 //=====================================================
1132 //== Param(.) is in the limits ==
1133 //== and does not end a closed line ==
1134 //=====================================================
1135 //== Check on the current point of myInters
1136 Standard_Boolean pointisvalid = Standard_False;
1137 {
1138 Standard_Real u1,v1,u2,v2;
1139 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1140
1141 //
1142 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1143 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1144 v1 >= Vm1 && v2 >= Vm2)
1145 {
1146 pointisvalid=Standard_True;
1147 }
1148 }
1149
1150 //
1151 if(pointisvalid)
1152 {
1153 previousPoint = myIntersectionOn2S.Point();
1154 previoustg = myIntersectionOn2S.IsTangent();
1155
1156 if(!previoustg)
1157 {
1158 previousd = myIntersectionOn2S.Direction();
1159 previousd1 = myIntersectionOn2S.DirectionOnS1();
1160 previousd2 = myIntersectionOn2S.DirectionOnS2();
1161 }
1162 //=====================================================
1163 //== Check on the previous Point
1164 {
1165 Standard_Real u1,v1,u2,v2;
1166 previousPoint.Parameters(u1,v1,u2,v2);
1167 if( u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1168 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1169 v1 >= Vm1 && v2 >= Vm2)
1170 {
1171 pl = previousPoint.Value();
1172 if(bTestFirstPoint)
1173 {
1174 if(pf.SquareDistance(pl) < aSQDistMax)
1175 {
1176 IncKey++;
1177 if(IncKey == 5000)
1178 return;
1179 else
1180 continue;
1181 }
1182 else
1183 {
1184 bTestFirstPoint = Standard_False;
1185 }
1186 }
1187 //
1188 AddAPoint(line,previousPoint);
1189 RejectIndex++;
1190
1191 if(RejectIndex >= RejectIndexMAX)
1192 {
1193 break;
1194 }
1195
1196 //
1197 LevelOfIterWithoutAppend = 0;
1198 }
1199 }
1200 }//pointisvalid
1201 //====================================================
1202
1203 if(Status == IntWalk_ArretSurPoint)
1204 {
1205 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1206 }
1207 else
1208 {
1209 if (line->NbPoints() == 2)
1210 {
1211 pasSav[0] = pasuv[0];
1212 pasSav[1] = pasuv[1];
1213 pasSav[2] = pasuv[2];
1214 pasSav[3] = pasuv[3];
1215 }
1216 }
1217 }//005 if(!Arrive)
1218 else //004
1219 {
1220 if(close)
1221 {
1222 //================= la ligne est fermee ===============
1223 AddAPoint(line,line->Value(1)); //ligne fermee
1224 LevelOfIterWithoutAppend=0;
1225 }
1226 else //$$$
1227 {
1228 //====================================================
1229 //== Param was not in the limits (was reframed)
1230 //====================================================
1231 Standard_Boolean bPrevNotTangent = !previoustg || !myIntersectionOn2S.IsTangent();
1232
1233 IntImp_ConstIsoparametric SauvChoixIso = ChoixIso;
1234 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1235 //
1236 if(!myIntersectionOn2S.IsEmpty()) //002
1237 {
1238 // mutially outpasses in the square or intersection in corner
1239
1240 if(TestArret(Standard_True,Param,ChoixIso))
1241 {
1242 NbPasOKConseq = -10;
1243 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1244
1245 if(!myIntersectionOn2S.IsEmpty())
1246 {
1247 previousPoint = myIntersectionOn2S.Point();
1248 previoustg = myIntersectionOn2S.IsTangent();
1249
1250 if (!previoustg)
1251 {
1252 previousd = myIntersectionOn2S.Direction();
1253 previousd1 = myIntersectionOn2S.DirectionOnS1();
1254 previousd2 = myIntersectionOn2S.DirectionOnS2();
1255 }
1256
1257 pl = previousPoint.Value();
1258
1259 if(bTestFirstPoint)
1260 {
1261 if(pf.SquareDistance(pl) < aSQDistMax)
1262 {
1263 IncKey++;
1264 if(IncKey == 5000)
1265 return;
1266 else
1267 continue;
1268 }
1269 else
1270 {
1271 bTestFirstPoint = Standard_False;
1272 }
1273 }
1274 //
1275 AddAPoint(line,previousPoint);
1276 RejectIndex++;
1277
1278 if(RejectIndex >= RejectIndexMAX)
1279 {
1280 break;
1281 }
1282
1283 //
1284 LevelOfIterWithoutAppend=0;
1285 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1286 }
1287 else
1288 {
1289 //fail framing divides the step
1290 Arrive = Standard_False;
1291 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1292 NoTestDeflection = Standard_True;
1293 ChoixIso = SauvChoixIso;
1294 }
1295 }//if(TestArret())
1296 else
1297 {
1298 // save the last point
1299 // to revert to it if the current point is out of bounds
1300
1301 IntSurf_PntOn2S previousPointSave = previousPoint;
1302 Standard_Boolean previoustgSave = previoustg;
1303 gp_Dir previousdSave = previousd;
1304 gp_Dir2d previousd1Save = previousd1;
1305 gp_Dir2d previousd2Save = previousd2;
1306
1307 previousPoint = myIntersectionOn2S.Point();
1308 previoustg = myIntersectionOn2S.IsTangent();
1309 Arrive = Standard_False;
1310
1311 if(!previoustg)
1312 {
1313 previousd = myIntersectionOn2S.Direction();
1314 previousd1 = myIntersectionOn2S.DirectionOnS1();
1315 previousd2 = myIntersectionOn2S.DirectionOnS2();
1316 }
1317
1318 //========================================
1319 //== Check on PreviousPoint @@
1320
1321 {
1322 Standard_Real u1,v1,u2,v2;
1323 previousPoint.Parameters(u1,v1,u2,v2);
1324
1325 //To save initial 2d points
1326 gp_Pnt2d ParamPntOnS1(Param(1), Param(2));
1327 gp_Pnt2d ParamPntOnS2(Param(3), Param(4));
1328
1329 ///////////////////////////
1330 Param(1) = u1;
1331 Param(2) = v1;
1332 Param(3) = u2;
1333 Param(4) = v2;
1334 //
1335
1336 //xf
1337 Standard_Boolean bFlag1, bFlag2;
1338 Standard_Real aTol2D=1.e-11;
1339 //
1340 bFlag1=u1 >= Um1-aTol2D && v1 >= Vm1-aTol2D && u1 <= UM1+aTol2D && v1 <= VM1+aTol2D;
1341 bFlag2=u2 >= Um2-aTol2D && v2 >= Vm2-aTol2D && u2 <= UM2+aTol2D && v2 <= VM2+aTol2D;
1342 if (bFlag1 && bFlag2)
1343 {
1344 if (line->NbPoints() > 1)
1345 {
1346 IntSurf_PntOn2S prevprevPoint = line->Value(line->NbPoints()-1);
1347 Standard_Real ppU1, ppV1, ppU2, ppV2;
1348 prevprevPoint.Parameters(ppU1, ppV1, ppU2, ppV2);
1349 Standard_Real pU1, pV1, pU2, pV2;
1350 previousPointSave.Parameters(pU1, pV1, pU2, pV2);
1351 gp_Vec2d V1onS1(gp_Pnt2d(ppU1, ppV1), gp_Pnt2d(pU1, pV1));
1352 gp_Vec2d V2onS1(gp_Pnt2d(pU1, pV1), gp_Pnt2d(u1, v1));
1353 gp_Vec2d V1onS2(gp_Pnt2d(ppU2, ppV2), gp_Pnt2d(pU2, pV2));
1354 gp_Vec2d V2onS2(gp_Pnt2d(pU2, pV2), gp_Pnt2d(u2, v2));
1355
1356 const Standard_Real aDot1 = V1onS1 * V2onS1;
1357 const Standard_Real aDot2 = V1onS2 * V2onS2;
1358
1359 if ((aDot1 < 0.0) || (aDot2 < 0.0))
1360 {
1361 Arrive = Standard_True;
1362 break;
1363 }
1364 }
1365 /*
1366 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1367 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1368 v1 >= Vm1 && v2 >= Vm2) {
1369 */
1370 //xt
1371 pl = previousPoint.Value();
1372
1373 if(bTestFirstPoint)
1374 {
1375 if(pf.SquareDistance(pl) < aSQDistMax)
1376 {
1377 IncKey++;
1378
1379 if(IncKey == 5000)
1380 return;
1381 else
1382 continue;
1383 }
1384 else
1385 {
1386 bTestFirstPoint = Standard_False;
1387 }
1388 }
1389
1390 //To avoid walking around the same point
1391 //in the tangent zone near a border
1392
1393 if (previoustg)
1394 {
1395 //There are three consecutive points:
1396 //previousPointSave -> ParamPnt -> curPnt.
1397
1398 Standard_Real prevU1, prevV1, prevU2, prevV2;
1399 previousPointSave.Parameters(prevU1, prevV1, prevU2, prevV2);
1400 gp_Pnt2d prevPntOnS1(prevU1, prevV1), prevPntOnS2(prevU2, prevV2);
1401 gp_Pnt2d curPntOnS1(u1, v1), curPntOnS2(u2, v2);
1402 gp_Vec2d PrevToParamOnS1(prevPntOnS1, ParamPntOnS1);
1403 gp_Vec2d PrevToCurOnS1(prevPntOnS1, curPntOnS1);
1404 gp_Vec2d PrevToParamOnS2(prevPntOnS2, ParamPntOnS2);
1405 gp_Vec2d PrevToCurOnS2(prevPntOnS2, curPntOnS2);
1406 Standard_Real MaxAngle = 3*M_PI/4;
1407 Standard_Real anAngleS1 = 0.0, anAngleS2 = 0.0;
1408 const Standard_Real aSQMParS1 = PrevToParamOnS1.SquareMagnitude();
1409 const Standard_Real aSQMParS2 = PrevToParamOnS2.SquareMagnitude();
1410 const Standard_Real aSQMCurS1 = PrevToCurOnS1.SquareMagnitude();
1411 const Standard_Real aSQMCurS2 = PrevToCurOnS2.SquareMagnitude();
1412
1413 if(aSQMCurS1 < gp::Resolution())
1414 {
1415 //We came back to the one of previos point.
1416 //Therefore, we must break;
1417
1418 anAngleS1 = M_PI;
1419 }
1420 else if(aSQMParS1 < gp::Resolution())
1421 {
1422 //We are walking along tangent zone.
1423 //It should be continued.
1424 anAngleS1 = 0.0;
1425 }
1426 else
1427 {
1428 anAngleS1 = Abs(PrevToParamOnS1.Angle(PrevToCurOnS1));
1429 }
1430
1431 if(aSQMCurS2 < gp::Resolution())
1432 {
1433 //We came back to the one of previos point.
1434 //Therefore, we must break;
1435
1436 anAngleS2 = M_PI;
1437 }
1438 else if(aSQMParS2 < gp::Resolution())
1439 {
1440 //We are walking along tangent zone.
1441 //It should be continued;
1442 anAngleS2 = 0.0;
1443 }
1444 else
1445 {
1446 anAngleS2 = Abs(PrevToParamOnS2.Angle(PrevToCurOnS2));
1447 }
1448
1449 if ((anAngleS1 > MaxAngle) && (anAngleS2 > MaxAngle))
1450 {
1451 Arrive = Standard_True;
1452 break;
1453 }
1454
1455 {
1456 //Check singularity.
1457 //I.e. check if we are walking along direction, which does not
1458 //result in comming to any point (i.e. derivative
1459 //3D-intersection curve along this direction is equal to 0).
1460 //A sphere with direction {dU=1, dV=0} from point
1461 //(U=0, V=M_PI/2) can be considered as example for
1462 //this case (we cannot find another 3D-point if we go thus).
1463
1464 //Direction chosen along 1st and 2nd surface correspondingly
1465 const gp_Vec2d aDirS1(prevPntOnS1, curPntOnS1),
1466 aDirS2(prevPntOnS2, curPntOnS2);
1467
1468 gp_Pnt aPtemp;
1469 gp_Vec aDuS1, aDvS1, aDuS2, aDvS2;
1470
1471 myIntersectionOn2S.Function().AuxillarSurface1()->
1472 D1(curPntOnS1.X(), curPntOnS1.Y(), aPtemp, aDuS1, aDvS1);
1473 myIntersectionOn2S.Function().AuxillarSurface2()->
1474 D1(curPntOnS2.X(), curPntOnS2.Y(), aPtemp, aDuS2, aDvS2);
1475
1476 //Derivative WLine along (it is vector-function indeed)
1477 //directions chosen
1478 //(https://en.wikipedia.org/wiki/Directional_derivative#Variation_using_only_direction_of_vector).
1479 //F1 - on the 1st surface, F2 - on the 2nd surface.
1480 //x, y, z - coordinates of derivative vector.
1481 const Standard_Real aF1x = aDuS1.X()*aDirS1.X() +
1482 aDvS1.X()*aDirS1.Y();
1483 const Standard_Real aF1y = aDuS1.Y()*aDirS1.X() +
1484 aDvS1.Y()*aDirS1.Y();
1485 const Standard_Real aF1z = aDuS1.Z()*aDirS1.X() +
1486 aDvS1.Z()*aDirS1.Y();
1487 const Standard_Real aF2x = aDuS2.X()*aDirS2.X() +
1488 aDvS2.X()*aDirS2.Y();
1489 const Standard_Real aF2y = aDuS2.Y()*aDirS2.X() +
1490 aDvS2.Y()*aDirS2.Y();
1491 const Standard_Real aF2z = aDuS2.Z()*aDirS2.X() +
1492 aDvS2.Z()*aDirS2.Y();
1493
1494 const Standard_Real aF1 = aF1x*aF1x + aF1y*aF1y + aF1z*aF1z;
1495 const Standard_Real aF2 = aF2x*aF2x + aF2y*aF2y + aF2z*aF2z;
1496
1497 if((aF1 < gp::Resolution()) && (aF2 < gp::Resolution()))
1498 {
1499 //All derivative are equal to 0. Therefore, there is
1500 //no point in going along direction chosen.
1501 Arrive = Standard_True;
1502 break;
1503 }
1504 }
1505 }//if (previoustg) cond.
1506
1507 ////////////////////////////////////////
1508 AddAPoint(line,previousPoint);
1509 RejectIndex++;
1510
1511 if(RejectIndex >= RejectIndexMAX)
1512 {
1513 break;
1514 }
1515
1516 //
1517
1518 LevelOfIterWithoutAppend=0;
1519 Arrive = Standard_True;
1520 }
1521 else
1522 {
1523 // revert to the last correctly calculated point
1524 previousPoint = previousPointSave;
1525 previoustg = previoustgSave;
1526 previousd = previousdSave;
1527 previousd1 = previousd1Save;
1528 previousd2 = previousd2Save;
1529 }
1530 }
1531
1532 //
1533 Standard_Boolean wasExtended = Standard_False;
1534
1535 if(Arrive && myIntersectionOn2S.IsTangent() && bPrevNotTangent)
1536 {
1537 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1538 {
1539 wasExtended = Standard_True;
1540 Arrive = Standard_False;
1541 ChoixIso = SauvChoixIso;
1542 }
1543 }
1544
1545 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1546
1547 if(Arrive &&
1548 myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() &&
1549 myIntersectionOn2S.IsTangent() && bPrevNotTangent &&
1550 !wasExtended)
1551 {
1552 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1553 {
1554 wasExtended = Standard_True;
1555 Arrive = Standard_False;
1556 ChoixIso = SauvChoixIso;
1557 }
1558 }
1559 }//else !TestArret() $
1560 }//$$ end successful framing on border (!myIntersectionOn2S.IsEmpty())
1561 else
1562 {
1563 //echec framing on border; division of step
1564 Arrive = Standard_False;
1565 NoTestDeflection = Standard_True;
1566 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1567 }
1568 }//$$$ end framing on border (!close)
1569 }//004 fin TestArret return Arrive = True
1570 } // 006case IntWalk_ArretSurPoint: end Processing Status = OK or ArretSurPoint
1571 } //007 switch(Status)
1572 } //008 end processing point (TEST DEFLECTION)
1573 } //009 end processing line (else if myIntersectionOn2S.IsDone())
1574 } //010 end if first departure point allows marching while (!Arrive)
1575
1576 done = Standard_True;
1577}
1578// ===========================================================================================================
1579// function: ExtendLineInCommonZone
1580// purpose: Extends already computed line inside tangent zone in the direction given by theChoixIso.
1581// Returns Standard_True if the line was extended through tangent zone and the last computed point
1582// is outside the tangent zone (but it is not put into the line). Otherwise returns Standard_False.
1583// ===========================================================================================================
1584Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso,
1585 const Standard_Boolean theDirectionFlag)
1586{
1587 Standard_Boolean bOutOfTangentZone = Standard_False;
1588 Standard_Boolean bStop = !myIntersectionOn2S.IsTangent();
1589 Standard_Integer dIncKey = 1;
1590 TColStd_Array1OfReal Param(1,4);
1591 IntWalk_StatusDeflection Status = IntWalk_OK;
1592 Standard_Integer nbIterWithoutAppend = 0;
1593 Standard_Integer nbEqualPoints = 0;
1594 Standard_Integer parit = 0;
1595 Standard_Integer uvit = 0;
1596 IntSurf_SequenceOfPntOn2S aSeqOfNewPoint;
1597
1598 while (!bStop) {
1599 nbIterWithoutAppend++;
1600
1601 if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) {
1602#ifdef OCCT_DEBUG
1603 cout<<"Infinite loop detected. Stop iterations (IntWalk_PWalking_1.gxx)" << endl;
1604#endif
1605 bStop = Standard_True;
1606 break;
1607 }
1608 Standard_Real f = 0.;
1609
1610 switch (theChoixIso)
1611 {
1612 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
1613 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
1614 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
1615 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
1616 }
1617
1618 if(f<0.1) f=0.1;
1619
1620 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
1621
1622 Standard_Real dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
1623 Standard_Real dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
1624 Standard_Real dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
1625 Standard_Real dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
1626
1627 if(theChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < 1.e-7) dP1 *= (5. * (Standard_Real)dIncKey);
1628 if(theChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < 1.e-7) dP2 *= (5. * (Standard_Real)dIncKey);
1629 if(theChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < 1.e-7) dP3 *= (5. * (Standard_Real)dIncKey);
1630 if(theChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < 1.e-7) dP4 *= (5. * (Standard_Real)dIncKey);
1631
1632 Param(1) += dP1;
1633 Param(2) += dP2;
1634 Param(3) += dP3;
1635 Param(4) += dP4;
1636 Standard_Real SvParam[4];
1637 IntImp_ConstIsoparametric ChoixIso = theChoixIso;
1638
1639 for(parit = 0; parit < 4; parit++) {
1640 SvParam[parit] = Param(parit+1);
1641 }
1642 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
1643 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld, theChoixIso);
1644
1645 if (!myIntersectionOn2S.IsDone()) {
1646 return bOutOfTangentZone;
1647 }
1648 else {
1649 if (myIntersectionOn2S.IsEmpty()) {
1650 return bOutOfTangentZone;
1651 }
1652
1653 Status = TestDeflection();
1654
1655 if(Status == IntWalk_OK) {
1656
1657 for(uvit = 0; uvit < 4; uvit++) {
1658 if(pasuv[uvit] < pasInit[uvit]) {
1659 pasuv[uvit] = pasInit[uvit];
1660 }
1661 }
1662 }
1663
1664 switch(Status) {
1665 case IntWalk_ArretSurPointPrecedent:
1666 {
1667 bStop = Standard_True;
1668 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1669 break;
1670 }
1671 case IntWalk_PasTropGrand:
1672 {
1673 for(parit = 0; parit < 4; parit++) {
1674 Param(parit+1) = SvParam[parit];
1675 }
1676 Standard_Boolean bDecrease = Standard_False;
1677
1678 for(uvit = 0; uvit < 4; uvit++) {
1679 if(pasSav[uvit] < pasInit[uvit]) {
1680 pasInit[uvit] -= (pasInit[uvit] - pasSav[uvit]) * 0.1;
1681 bDecrease = Standard_True;
1682 }
1683 }
1684
1685 if(bDecrease) nbIterWithoutAppend--;
1686 break;
1687 }
1688 case IntWalk_PointConfondu:
1689 {
1690 for(uvit = 0; uvit < 4; uvit++) {
1691 if(pasuv[uvit] < pasInit[uvit]) {
1692 pasuv[uvit] += (pasInit[uvit] - pasuv[uvit]) * 0.1;
1693 }
1694 }
1695 break;
1696 }
1697 case IntWalk_OK:
1698 case IntWalk_ArretSurPoint:
1699 {
1700 //
1701 bStop = TestArret(theDirectionFlag, Param, ChoixIso);
1702 //
1703
1704 //
1705 if(!bStop) {
1706 Standard_Real u11,v11,u12,v12;
1707 myIntersectionOn2S.Point().Parameters(u11,v11,u12,v12);
1708 Standard_Real u21,v21,u22,v22;
1709 previousPoint.Parameters(u21,v21,u22,v22);
1710
1711 if(((fabs(u11-u21) < ResoU1) && (fabs(v11-v21) < ResoV1)) ||
1712 ((fabs(u12-u22) < ResoU2) && (fabs(v12-v22) < ResoV2))) {
1713 nbEqualPoints++;
1714 }
1715 else {
1716 nbEqualPoints = 0;
1717 }
1718 }
1719 //
1720
1721 bStop = bStop || !myIntersectionOn2S.IsTangent();
1722 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1723
1724 if(!bStop) {
1725 Standard_Boolean pointisvalid = Standard_False;
1726 Standard_Real u1,v1,u2,v2;
1727 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1728
1729 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1730 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1731 v1 >= Vm1 && v2 >= Vm2)
1732 pointisvalid = Standard_True;
1733
1734 if(pointisvalid) {
1735 previousPoint = myIntersectionOn2S.Point();
1736 previoustg = myIntersectionOn2S.IsTangent();
1737
1738 if(!previoustg) {
1739 previousd = myIntersectionOn2S.Direction();
1740 previousd1 = myIntersectionOn2S.DirectionOnS1();
1741 previousd2 = myIntersectionOn2S.DirectionOnS2();
1742 }
1743 Standard_Boolean bAddPoint = Standard_True;
1744
1745 if(line->NbPoints() >= 1) {
1746 gp_Pnt pf = line->Value(1).Value();
1747 gp_Pnt pl = previousPoint.Value();
1748
1749 if(pf.Distance(pl) < Precision::Confusion()) {
1750 dIncKey++;
1751 if(dIncKey == 5000) return bOutOfTangentZone;
1752 else bAddPoint = Standard_False;
1753 }
1754 }
1755
1756 if(bAddPoint) {
1757 aSeqOfNewPoint.Append(previousPoint);
1758 nbIterWithoutAppend = 0;
1759 }
1760 }
1761
1762 if (line->NbPoints() == 2) {
1763 for(uvit = 0; uvit < 4; uvit++) {
1764 pasSav[uvit] = pasuv[uvit];
1765 }
1766 }
1767
1768 if ( !pointisvalid ) {
1769 // decrease step if out of bounds
1770 // otherwise the same calculations will be
1771 // repeated several times
1772 if ( ( u1 > UM1 ) || ( u1 < Um1 ) )
1773 pasuv[0] *= 0.5;
1774
1775 if ( ( v1 > VM1 ) || ( v1 < Vm1 ) )
1776 pasuv[1] *= 0.5;
1777
1778 if ( ( u2 > UM2 ) || ( u2 < Um2 ) )
1779 pasuv[2] *= 0.5;
1780
1781 if ( ( v2 > VM2 ) || ( v2 < Vm2 ) )
1782 pasuv[3] *= 0.5;
1783 }
1784 } // end if(!bStop)
1785 else { //if(bStop)
1786 if(close && (line->NbPoints() >= 1)) {
1787
1788 if(!bOutOfTangentZone) {
1789 aSeqOfNewPoint.Append(line->Value(1)); // line end
1790 }
1791 nbIterWithoutAppend = 0;
1792 }
1793 else {
1794 ChoixIso = myIntersectionOn2S.Perform(Param, Rsnld, theChoixIso);
1795
1796 if(myIntersectionOn2S.IsEmpty()) {
1797 bStop = !myIntersectionOn2S.IsTangent();
1798 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1799 }
1800 else {
1801 Standard_Boolean bAddPoint = Standard_True;
1802 Standard_Boolean pointisvalid = Standard_False;
1803
1804 previousPoint = myIntersectionOn2S.Point();
1805 Standard_Real u1,v1,u2,v2;
1806 previousPoint.Parameters(u1,v1,u2,v2);
1807
1808 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1809 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1810 v1 >= Vm1 && v2 >= Vm2)
1811 pointisvalid = Standard_True;
1812
1813 if(pointisvalid) {
1814
1815 if(line->NbPoints() >= 1) {
1816 gp_Pnt pf = line->Value(1).Value();
1817 gp_Pnt pl = previousPoint.Value();
1818
1819 if(pf.Distance(pl) < Precision::Confusion()) {
1820 dIncKey++;
1821 if(dIncKey == 5000) return bOutOfTangentZone;
1822 else bAddPoint = Standard_False;
1823 }
1824 }
1825
1826 if(bAddPoint && !bOutOfTangentZone) {
1827 aSeqOfNewPoint.Append(previousPoint);
1828 nbIterWithoutAppend = 0;
1829 }
1830 }
1831 }
1832 }
1833 }
1834 break;
1835 }
1836 default:
1837 {
1838 break;
1839 }
1840 }
1841 }
1842 }
1843 Standard_Boolean bExtendLine = Standard_False;
1844 Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
1845
1846 Standard_Integer pit = 0;
1847
1848 for(pit = 0; !bExtendLine && (pit < 2); pit++) {
1849 if(pit == 0)
1850 previousPoint.Parameters(u1,v1,u2,v2);
1851 else {
1852 if(aSeqOfNewPoint.Length() > 0)
1853 aSeqOfNewPoint.Value(aSeqOfNewPoint.Length()).Parameters(u1,v1,u2,v2);
1854 else
1855 break;
1856 }
1857
1858 if(((u1 - Um1) < ResoU1) ||
1859 ((UM1 - u1) < ResoU1) ||
1860 ((u2 - Um2) < ResoU2) ||
1861 ((UM2 - u2) < ResoU2) ||
1862 ((v1 - Vm1) < ResoV1) ||
1863 ((VM1 - v1) < ResoV1) ||
1864 ((v2 - Vm2) < ResoV2) ||
1865 ((VM2 - v2) < ResoV2))
1866 bExtendLine = Standard_True;
1867 }
1868
1869 if(!bExtendLine) {
1870 // if(Status == IntWalk_OK || Status == IntWalk_ArretSurPoint) {
1871 if(Status == IntWalk_OK) {
1872 bExtendLine = Standard_True;
1873
1874 if(aSeqOfNewPoint.Length() > 1) {
1875 TColStd_Array1OfReal FirstParams(0, 3), LastParams(0, 3), Resolutions(0, 3);
1876 Resolutions(0) = ResoU1; Resolutions(1) = ResoV1; Resolutions(2) = ResoU2; Resolutions(3) = ResoV2;
1877
1878 aSeqOfNewPoint(1).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1879 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1880 aSeqOfNewPoint(aSeqOfNewPoint.Length()).Parameters(LastParams.ChangeValue(0),
1881 LastParams.ChangeValue(1),
1882 LastParams.ChangeValue(2),
1883 LastParams.ChangeValue(3));
1884 Standard_Integer indexofiso = 0;
1885
1886 if(theChoixIso == IntImp_UIsoparametricOnCaro1) indexofiso = 0;
1887 if(theChoixIso == IntImp_VIsoparametricOnCaro1) indexofiso = 1;
1888 if(theChoixIso == IntImp_UIsoparametricOnCaro2) indexofiso = 2;
1889 if(theChoixIso == IntImp_VIsoparametricOnCaro2) indexofiso = 3;
1890
1891 Standard_Integer afirstindex = (indexofiso < 2) ? 0 : 2;
1892 gp_Vec2d aTangentZoneDir(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)),
1893 gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1)));
1894
1895 gp_Dir2d anIsoDir(0, 1);
1896
1897 if((indexofiso == 1) || (indexofiso == 3))
1898 anIsoDir = gp_Dir2d(1, 0);
1899
1900 if(aTangentZoneDir.SquareMagnitude() > gp::Resolution()) {
1901 Standard_Real piquota = M_PI*0.25;
1902
1903 if(fabs(aTangentZoneDir.Angle(anIsoDir)) > piquota) {
1904 Standard_Integer ii = 1, nextii = 2;
1905 gp_Vec2d d1(0, 0);
1906 Standard_Real asqresol = gp::Resolution();
1907 asqresol *= asqresol;
1908
1909 do {
1910 aSeqOfNewPoint(ii).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1911 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1912 aSeqOfNewPoint(ii + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1913 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1914 d1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1915 FirstParams.Value(afirstindex + 1)),
1916 gp_Pnt2d(LastParams.Value(afirstindex),
1917 LastParams.Value(afirstindex + 1)));
1918 ii++;
1919 }
1920 while((d1.SquareMagnitude() < asqresol) &&
1921 (ii < aSeqOfNewPoint.Length()));
1922
1923 nextii = ii;
1924
1925 while(nextii < aSeqOfNewPoint.Length()) {
1926
1927 gp_Vec2d nextd1(0, 0);
1928 Standard_Integer jj = nextii;
1929
1930 do {
1931 aSeqOfNewPoint(jj).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1932 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1933 aSeqOfNewPoint(jj + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1934 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1935 nextd1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1936 FirstParams.Value(afirstindex + 1)),
1937 gp_Pnt2d(LastParams.Value(afirstindex),
1938 LastParams.Value(afirstindex + 1)));
1939 jj++;
1940
1941 }
1942 while((nextd1.SquareMagnitude() < asqresol) &&
1943 (jj < aSeqOfNewPoint.Length()));
1944 nextii = jj;
1945
1946 if(fabs(d1.Angle(nextd1)) > piquota) {
1947 bExtendLine = Standard_False;
1948 break;
1949 }
1950 d1 = nextd1;
1951 }
1952 }
1953 // end if(fabs(aTangentZoneDir.Angle(anIsoDir)
1954 }
1955 }
1956 }
1957 }
1958
1959 if(!bExtendLine) {
1960 return Standard_False;
1961 }
1962 Standard_Integer i = 0;
1963
1964 for(i = 1; i <= aSeqOfNewPoint.Length(); i++) {
1965 AddAPoint(line, aSeqOfNewPoint.Value(i));
1966 }
1967
1968 return bOutOfTangentZone;
1969}
1970
1971//=======================================================================
1972//function : DistanceMinimizeByGradient
1973//purpose :
1974//=======================================================================
1975Standard_Boolean IntWalk_PWalking::
1976DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
1977 const Handle(Adaptor3d_HSurface)& theASurf2,
1978 Standard_Real& theU1,
1979 Standard_Real& theV1,
1980 Standard_Real& theU2,
1981 Standard_Real& theV2,
1982 const Standard_Real theStep0U1V1,
1983 const Standard_Real theStep0U2V2)
1984{
1985 const Standard_Integer aNbIterMAX = 60;
1986 const Standard_Real aTol = 1.0e-14;
1987 Handle(Geom_Surface) aS1, aS2;
1988
1989 switch(theASurf1->GetType())
1990 {
1991 case GeomAbs_BezierSurface:
1992 aS1 = theASurf1->Surface().Bezier();
1993 break;
1994 case GeomAbs_BSplineSurface:
1995 aS1 = theASurf1->Surface().BSpline();
1996 break;
1997 default:
1998 return Standard_True;
1999 }
2000
2001 switch(theASurf2->GetType())
2002 {
2003 case GeomAbs_BezierSurface:
2004 aS2 = theASurf2->Surface().Bezier();
2005 break;
2006 case GeomAbs_BSplineSurface:
2007 aS2 = theASurf2->Surface().BSpline();
2008 break;
2009 default:
2010 return Standard_True;
2011 }
2012
2013 Standard_Boolean aStatus = Standard_False;
2014
2015 gp_Pnt aP1, aP2;
2016 gp_Vec aD1u, aD1v, aD2U, aD2V;
2017
2018 aS1->D1(theU1, theV1, aP1, aD1u, aD1v);
2019 aS2->D1(theU2, theV2, aP2, aD2U, aD2V);
2020
2021 Standard_Real aSQDistPrev = aP1.SquareDistance(aP2);
2022
2023 gp_Vec aP12(aP1, aP2);
2024
2025 Standard_Real aGradFu(-aP12.Dot(aD1u));
2026 Standard_Real aGradFv(-aP12.Dot(aD1v));
2027 Standard_Real aGradFU( aP12.Dot(aD2U));
2028 Standard_Real aGradFV( aP12.Dot(aD2V));
2029
2030 Standard_Real aSTEPuv = theStep0U1V1, aStepUV = theStep0U2V2;
2031
2032 Standard_Boolean flRepeat = Standard_True;
2033 Standard_Integer aNbIter = aNbIterMAX;
2034
2035 while(flRepeat)
2036 {
2037 Standard_Real anAdd = aGradFu*aSTEPuv;
2038 Standard_Real aPARu = (anAdd >= 0.0)?
2039 (theU1 - Max(anAdd, Epsilon(theU1))) :
2040 (theU1 + Max(-anAdd, Epsilon(theU1)));
2041 anAdd = aGradFv*aSTEPuv;
2042 Standard_Real aPARv = (anAdd >= 0.0)?
2043 (theV1 - Max(anAdd, Epsilon(theV1))) :
2044 (theV1 + Max(-anAdd, Epsilon(theV1)));
2045 anAdd = aGradFU*aStepUV;
2046 Standard_Real aParU = (anAdd >= 0.0)?
2047 (theU2 - Max(anAdd, Epsilon(theU2))) :
2048 (theU2 + Max(-anAdd, Epsilon(theU2)));
2049 anAdd = aGradFV*aStepUV;
2050 Standard_Real aParV = (anAdd >= 0.0)?
2051 (theV2 - Max(anAdd, Epsilon(theV2))) :
2052 (theV2 + Max(-anAdd, Epsilon(theV2)));
2053
2054 gp_Pnt aPt1, aPt2;
2055
2056 aS1->D1(aPARu, aPARv, aPt1, aD1u, aD1v);
2057 aS2->D1(aParU, aParV, aPt2, aD2U, aD2V);
2058
2059 Standard_Real aSQDist = aPt1.SquareDistance(aPt2);
2060
2061 if(aSQDist < aSQDistPrev)
2062 {
2063 aSQDistPrev = aSQDist;
2064 theU1 = aPARu;
2065 theV1 = aPARv;
2066 theU2 = aParU;
2067 theV2 = aParV;
2068
2069 aStatus = aSQDistPrev < aTol;
2070 aSTEPuv *= 1.2;
2071 aStepUV *= 1.2;
2072 }
2073 else
2074 {
2075 if(--aNbIter < 0)
2076 {
2077 flRepeat = Standard_False;
2078 }
2079 else
2080 {
2081 aS1->D1(theU1, theV1, aPt1, aD1u, aD1v);
2082 aS2->D1(theU2, theV2, aPt2, aD2U, aD2V);
2083
2084 gp_Vec aP12(aPt1, aPt2);
2085 aGradFu = -aP12.Dot(aD1u);
2086 aGradFv = -aP12.Dot(aD1v);
2087 aGradFU = aP12.Dot(aD2U);
2088 aGradFV = aP12.Dot(aD2V);
2089 aSTEPuv = theStep0U1V1;
2090 aStepUV = theStep0U2V2;
2091 }
2092 }
2093 }
2094
2095 return aStatus;
2096}
2097
2098//=======================================================================
2099//function : DistanceMinimizeByExtrema
2100//purpose :
2101//=======================================================================
2102Standard_Boolean IntWalk_PWalking::
2103DistanceMinimizeByExtrema(const Handle(Adaptor3d_HSurface)& theASurf,
2104 const gp_Pnt& theP0,
2105 Standard_Real& theU0,
2106 Standard_Real& theV0,
2107 const Standard_Real theStep0U,
2108 const Standard_Real theStep0V)
2109{
2110 const Standard_Real aTol = 1.0e-14;
2111 gp_Pnt aPS;
2112 gp_Vec aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp;
2113 Standard_Real aSQDistPrev = RealLast();
2114 Standard_Real aU = theU0, aV = theV0;
2115
2116 Standard_Integer aNbIter = 10;
2117 do
2118 {
2119 theASurf->D2(aU, aV, aPS, aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp);
2120
2121 gp_Vec aVec(theP0, aPS);
2122
2123 Standard_Real aSQDist = aVec.SquareMagnitude();
2124
2125 if(aSQDist >= aSQDistPrev)
2126 break;
2127
2128 aSQDistPrev = aSQDist;
2129 theU0 = aU;
2130 theV0 = aV;
2131 aNbIter--;
2132
2133 if(aSQDistPrev < aTol)
2134 break;
2135
2136 //Functions
2137 const Standard_Real aF1 = aD1Su.Dot(aVec), aF2 = aD1Sv.Dot(aVec);
2138
2139 //Derivatives
2140 const Standard_Real aDf1u = aD2Su.Dot(aVec) + aD1Su.Dot(aD1Su),
2141 aDf1v = aD2Su.Dot(aD1Sv),
2142 aDf2u = aDf1v,
2143 aDf2v = aD2Sv.Dot(aVec) + aD1Sv.Dot(aD1Sv);
2144
2145 const Standard_Real aDet = aDf1u*aDf2v - aDf1v*aDf2u;
2146 aU -= theStep0U*(aDf2v*aF1 - aDf1v*aF2)/aDet;
2147 aV += theStep0V*(aDf2u*aF1 - aDf1u*aF2)/aDet;
2148 }
2149 while(aNbIter > 0);
2150
2151 return (aSQDistPrev < aTol);
2152}
2153
2154//=======================================================================
2155//function : SeekPointOnBoundary
2156//purpose :
2157//=======================================================================
2158Standard_Boolean IntWalk_PWalking::
2159SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
2160 const Handle(Adaptor3d_HSurface)& theASurf2,
2161 const Standard_Real theU1,
2162 const Standard_Real theV1,
2163 const Standard_Real theU2,
2164 const Standard_Real theV2,
2165 const Standard_Boolean isTheFirst)
2166{
2167 const Standard_Real aTol = 1.0e-14;
2168 Standard_Boolean isOK = Standard_False;
2169 Standard_Real U1prec = theU1, V1prec = theV1, U2prec = theU2, V2prec = theV2;
2170
2171 Standard_Boolean flFinish = Standard_False;
2172
2173 Standard_Integer aNbIter = 20;
2174 while(!flFinish)
2175 {
2176 flFinish = Standard_False;
2177 Standard_Boolean aStatus = Standard_False;
2178
2179 do
2180 {
2181 aNbIter--;
2182 aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec);
2183 if(aStatus)
2184 {
2185 break;
2186 }
2187
2188 aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec);
2189 if(aStatus)
2190 {
2191 break;
2192 }
2193
2194 aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec);
2195 if(aStatus)
2196 {
2197 break;
2198 }
2199 }
2200 while(!aStatus && (aNbIter > 0));
2201
2202 if(aStatus)
2203 {
2204 const Standard_Real aTolMax = 1.0e-8;
2205 Standard_Real aTolF = 0.0;
2206
2207 Standard_Real u1 = U1prec, v1 = V1prec, u2 = U2prec, v2 = V2prec;
2208
2209 flFinish = Checking(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec, aTolF);
2210
2211 if(aTolF <= aTolMax)
2212 {
2213 gp_Pnt aP1 = theASurf1->Value(u1, v1),
2214 aP2 = theASurf2->Value(u2, v2);
2215 gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2216
2217 const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
2218 aSQDist2 = aPInt.SquareDistance(aP2);
2219 if((aSQDist1 < aTol) && (aSQDist2 < aTol))
2220 {
2221 IntSurf_PntOn2S anIP;
2222 anIP.SetValue(aPInt, u1, v1, u2, v2);
2223
2224 if(isTheFirst)
2225 line->InsertBefore(1,anIP);
2226 else
2227 line->Add(anIP);
2228
2229 isOK = Standard_True;
2230 }
2231 }
2232 }
2233 else
2234 {
2235 break;
2236 }
2237
2238 if(aNbIter < 0)
2239 break;
2240 }
2241
2242 return isOK;
2243}
2244
2245//=======================================================================
2246//function : PutToBoundary
2247//purpose :
2248//=======================================================================
2249Standard_Boolean IntWalk_PWalking::
2250PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
2251 const Handle(Adaptor3d_HSurface)& theASurf2)
2252{
2253 const Standard_Real aTolMin = Precision::Confusion();
2254
2255 Standard_Boolean hasBeenAdded = Standard_False;
2256
2257 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2258 const Standard_Real aU1bLast = theASurf1->LastUParameter();
2259 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2260 const Standard_Real aU2bLast = theASurf2->LastUParameter();
2261 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2262 const Standard_Real aV1bLast = theASurf1->LastVParameter();
2263 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2264 const Standard_Real aV2bLast = theASurf2->LastVParameter();
2265
2266 Standard_Real aTol = 1.0;
2267 aTol = Min(aTol, aU1bLast - aU1bFirst);
2268 aTol = Min(aTol, aU2bLast - aU2bFirst);
2269 aTol = Min(aTol, aV1bLast - aV1bFirst);
2270 aTol = Min(aTol, aV2bLast - aV2bFirst)*1.0e-3;
2271
2272 if(aTol <= 2.0*aTolMin)
2273 return hasBeenAdded;
2274
2275 Standard_Boolean isNeedAdding = Standard_False;
2276 Standard_Boolean isU1parallel = Standard_False, isV1parallel = Standard_False;
2277 Standard_Boolean isU2parallel = Standard_False, isV2parallel = Standard_False;
2278 IsParallel(line, Standard_True, aTol, isU1parallel, isV1parallel);
2279 IsParallel(line, Standard_False, aTol, isU2parallel, isV2parallel);
2280
2281 const Standard_Integer aNbPnts = line->NbPoints();
2282 Standard_Real u1, v1, u2, v2;
2283 line->Value(1).Parameters(u1, v1, u2, v2);
2284 Standard_Real aDelta = 0.0;
2285
2286 if(!isV1parallel)
2287 {
2288 aDelta = u1 - aU1bFirst;
2289 if((aTolMin < aDelta) && (aDelta < aTol))
2290 {
2291 u1 = aU1bFirst - aDelta;
2292 isNeedAdding = Standard_True;
2293 }
2294 else
2295 {
2296 aDelta = aU1bLast - u1;
2297 if((aTolMin < aDelta) && (aDelta < aTol))
2298 {
2299 u1 = aU1bLast + aDelta;
2300 isNeedAdding = Standard_True;
2301 }
2302 }
2303 }
2304
2305 if(!isV2parallel)
2306 {
2307 aDelta = u2 - aU2bFirst;
2308 if((aTolMin < aDelta) && (aDelta < aTol))
2309 {
2310 u2 = aU2bFirst - aDelta;
2311 isNeedAdding = Standard_True;
2312 }
2313 else
2314 {
2315 aDelta = aU2bLast - u2;
2316 if((aTolMin < aDelta) && (aDelta < aTol))
2317 {
2318 u2 = aU2bLast + aDelta;
2319 isNeedAdding = Standard_True;
2320 }
2321 }
2322 }
2323
2324 if(!isU1parallel)
2325 {
2326 aDelta = v1 - aV1bFirst;
2327 if((aTolMin < aDelta) && (aDelta < aTol))
2328 {
2329 v1 = aV1bFirst - aDelta;
2330 isNeedAdding = Standard_True;
2331 }
2332 else
2333 {
2334 aDelta = aV1bLast - v1;
2335 if((aTolMin < aDelta) && (aDelta < aTol))
2336 {
2337 v1 = aV1bLast + aDelta;
2338 isNeedAdding = Standard_True;
2339 }
2340 }
2341 }
2342
2343 if(!isU2parallel)
2344 {
2345 aDelta = v2 - aV2bFirst;
2346 if((aTolMin < aDelta) && (aDelta < aTol))
2347 {
2348 v2 = aV2bFirst - aDelta;
2349 isNeedAdding = Standard_True;
2350 }
2351 else
2352 {
2353 aDelta = aV2bLast - v2;
2354 if((aTolMin < aDelta) && (aDelta < aTol))
2355 {
2356 v2 = aV2bLast + aDelta;
2357 isNeedAdding = Standard_True;
2358 }
2359 }
2360 }
2361
2362 if(isNeedAdding)
2363 {
2364 hasBeenAdded =
2365 SeekPointOnBoundary(theASurf1, theASurf2, u1,
2366 v1, u2, v2, Standard_True);
2367 }
2368
2369 isNeedAdding = Standard_False;
2370 line->Value(aNbPnts).Parameters(u1, v1, u2, v2);
2371
2372 if(!isV1parallel)
2373 {
2374 aDelta = u1 - aU1bFirst;
2375 if((aTolMin < aDelta) && (aDelta < aTol))
2376 {
2377 u1 = aU1bFirst - aDelta;
2378 isNeedAdding = Standard_True;
2379 }
2380 else
2381 {
2382 aDelta = aU1bLast - u1;
2383 if((aTolMin < aDelta) && (aDelta < aTol))
2384 {
2385 u1 = aU1bLast + aDelta;
2386 isNeedAdding = Standard_True;
2387 }
2388 }
2389 }
2390
2391 if(!isV2parallel)
2392 {
2393 aDelta = u2 - aU2bFirst;
2394 if((aTolMin < aDelta) && (aDelta < aTol))
2395 {
2396 u2 = aU2bFirst - aDelta;
2397 isNeedAdding = Standard_True;
2398 }
2399 else
2400 {
2401 aDelta = aU2bLast - u2;
2402 if((aTolMin < aDelta) && (aDelta < aTol))
2403 {
2404 u2 = aU2bLast + aDelta;
2405 isNeedAdding = Standard_True;
2406 }
2407 }
2408 }
2409
2410 if(!isU1parallel)
2411 {
2412 aDelta = v1 - aV1bFirst;
2413 if((aTolMin < aDelta) && (aDelta < aTol))
2414 {
2415 v1 = aV1bFirst - aDelta;
2416 isNeedAdding = Standard_True;
2417 }
2418 else
2419 {
2420 aDelta = aV1bLast - v1;
2421 if((aTolMin < aDelta) && (aDelta < aTol))
2422 {
2423 v1 = aV1bLast + aDelta;
2424 isNeedAdding = Standard_True;
2425 }
2426 }
2427 }
2428
2429 if(!isU2parallel)
2430 {
2431 aDelta = v2 - aV2bFirst;
2432 if((aTolMin < aDelta) && (aDelta < aTol))
2433 {
2434 v2 = aV2bFirst - aDelta;
2435 isNeedAdding = Standard_True;
2436 }
2437 else
2438 {
2439 aDelta = aV2bLast - v2;
2440 if((aTolMin < aDelta) && (aDelta < aTol))
2441 {
2442 v2 = aV2bLast + aDelta;
2443 isNeedAdding = Standard_True;
2444 }
2445 }
2446 }
2447
2448 if(isNeedAdding)
2449 {
2450 hasBeenAdded =
2451 SeekPointOnBoundary(theASurf1, theASurf2, u1,
2452 v1, u2, v2, Standard_False);
2453 }
2454
2455 return hasBeenAdded;
2456}
2457
2458//=======================================================================
2459//function : SeekAdditionalPoints
2460//purpose :
2461//=======================================================================
2462Standard_Boolean IntWalk_PWalking::
2463SeekAdditionalPoints( const Handle(Adaptor3d_HSurface)& theASurf1,
2464 const Handle(Adaptor3d_HSurface)& theASurf2,
2465 const Standard_Integer theMinNbPoints)
2466{
2467 const Standard_Real aTol = 1.0e-14;
2468 Standard_Integer aNbPoints = line->NbPoints();
2469 if(aNbPoints > theMinNbPoints)
2470 return Standard_True;
2471
2472 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2473 const Standard_Real aU1bLast = theASurf1->LastUParameter();
2474 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2475 const Standard_Real aU2bLast = theASurf2->LastUParameter();
2476 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2477 const Standard_Real aV1bLast = theASurf1->LastVParameter();
2478 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2479 const Standard_Real aV2bLast = theASurf2->LastVParameter();
2480
2481
2482 Standard_Boolean isPrecise = Standard_False;
2483
2484 Standard_Real U1prec = 0.0, V1prec = 0.0, U2prec = 0.0, V2prec = 0.0;
2485
2486 Standard_Integer aNbPointsPrev = 0;
2487 while(aNbPoints < theMinNbPoints && (aNbPoints != aNbPointsPrev))
2488 {
2489 aNbPointsPrev = aNbPoints;
2490 for(Standard_Integer fp = 1, lp = 2; fp < aNbPoints; fp = lp + 1)
2491 {
2492 Standard_Real U1f, V1f, U2f, V2f; //first point in 1st and 2nd surafaces
2493 Standard_Real U1l, V1l, U2l, V2l; //last point in 1st and 2nd surafaces
2494
2495 lp = fp+1;
2496 line->Value(fp).Parameters(U1f, V1f, U2f, V2f);
2497 line->Value(lp).Parameters(U1l, V1l, U2l, V2l);
2498
2499 U1prec = 0.5*(U1f+U1l);
2500 if(U1prec < aU1bFirst)
2501 U1prec = aU1bFirst;
2502 if(U1prec > aU1bLast)
2503 U1prec = aU1bLast;
2504
2505 V1prec = 0.5*(V1f+V1l);
2506 if(V1prec < aV1bFirst)
2507 V1prec = aV1bFirst;
2508 if(V1prec > aV1bLast)
2509 V1prec = aV1bLast;
2510
2511 U2prec = 0.5*(U2f+U2l);
2512 if(U2prec < aU2bFirst)
2513 U2prec = aU2bFirst;
2514 if(U2prec > aU2bLast)
2515 U2prec = aU2bLast;
2516
2517 V2prec = 0.5*(V2f+V2l);
2518 if(V2prec < aV2bFirst)
2519 V2prec = aV2bFirst;
2520 if(V2prec > aV2bLast)
2521 V2prec = aV2bLast;
2522
2523 Standard_Boolean aStatus = Standard_False;
2524 Standard_Integer aNbIter = 5;
2525 do
2526 {
2527 aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec);
2528 if(aStatus)
2529 {
2530 break;
2531 }
2532
2533 aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec);
2534 if(aStatus)
2535 {
2536 break;
2537 }
2538
2539 aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec);
2540 if(aStatus)
2541 {
2542 break;
2543 }
2544 }
2545 while(!aStatus && (--aNbIter > 0));
2546
2547 if(aStatus)
2548 {
2549 gp_Pnt aP1 = theASurf1->Value(U1prec, V1prec),
2550 aP2 = theASurf2->Value(U2prec, V2prec);
2551 gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2552
2553 const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
2554 aSQDist2 = aPInt.SquareDistance(aP2);
2555
2556 if((aSQDist1 < aTol) && (aSQDist2 < aTol))
2557 {
2558 IntSurf_PntOn2S anIP;
2559 anIP.SetValue(aPInt, U1prec, V1prec, U2prec, V2prec);
2560 line->InsertBefore(lp, anIP);
2561
2562 isPrecise = Standard_True;
2563
2564 if(++aNbPoints >= theMinNbPoints)
2565 break;
2566 }
2567 else
2568 {
2569 lp--;
2570 }
2571 }
2572 }
2573 }
2574
2575 return isPrecise;
2576}
2577
2578void IntWalk_PWalking::
2579RepartirOuDiviser(Standard_Boolean& DejaReparti,
2580 IntImp_ConstIsoparametric& ChoixIso,
2581 Standard_Boolean& Arrive)
2582
2583 // at the neighborhood of a point, there is a fail of marching
2584 // it is required to divide the steps to try to continue
2585 // if the step is too small if we are on border
2586 // restart in another direction if it was not done, otherwise stop
2587
2588{
2589 // Standard_Integer i;
2590 if (Arrive) { //restart in the other direction
2591 if (!DejaReparti ) {
2592 Arrive = Standard_False;
2593 DejaReparti = Standard_True;
2594 previousPoint = line->Value(1);
2595 previoustg = Standard_False;
2596 previousd1 = firstd1;
2597 previousd2 = firstd2;
2598 previousd = tgdir;
2599 indextg = line->NbPoints();
2600 tgdir.Reverse();
2601 line->Reverse();
2602
2603 //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg);
2604 sensCheminement = -1;
2605 tgfirst = tglast;
2606 tglast = Standard_False;
2607 ChoixIso = choixIsoSav;
2608#if 0
2609 pasuv[0]=pasSav[0];
2610 pasuv[1]=pasSav[1];
2611 pasuv[2]=pasSav[2];
2612 pasuv[3]=pasSav[3];
2613#else
2614 Standard_Real u1,v1,u2,v2;
2615 Standard_Real U1,V1,U2,V2;
2616 Standard_Integer nn=line->NbPoints();
2617 if(nn>2) {
2618 line->Value(nn).Parameters(u1,v1,u2,v2);
2619 line->Value(nn-1).Parameters(U1,V1,U2,V2);
2620 pasuv[0]=Abs(u1-U1);
2621 pasuv[1]=Abs(v1-V1);
2622 pasuv[2]=Abs(u2-U2);
2623 pasuv[3]=Abs(v2-V2);
2624 }
2625#endif
2626
2627 }
2628 }
2629 else {
2630 if ( pasuv[0]*0.5 < ResoU1
2631 && pasuv[1]*0.5 < ResoV1
2632 && pasuv[2]*0.5 < ResoU2
2633 && pasuv[3]*0.5 < ResoV2
2634 ) {
2635 if (!previoustg) {
2636 tglast = Standard_True; // IS IT ENOUGH ????
2637 }
2638
2639 if (!DejaReparti) { //restart in the other direction
2640 DejaReparti = Standard_True;
2641 previousPoint = line->Value(1);
2642 previoustg = Standard_False;
2643 previousd1 = firstd1;
2644 previousd2 = firstd2;
2645 previousd = tgdir;
2646 indextg = line->NbPoints();
2647 tgdir.Reverse();
2648 line->Reverse();
2649
2650 //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg);
2651
2652 sensCheminement = -1;
2653 tgfirst = tglast;
2654 tglast = Standard_False;
2655 ChoixIso = choixIsoSav;
2656
2657#if 0
2658 pasuv[0]=pasSav[0];
2659 pasuv[1]=pasSav[1];
2660 pasuv[2]=pasSav[2];
2661 pasuv[3]=pasSav[3];
2662#else
2663 Standard_Real u1,v1,u2,v2;
2664 Standard_Real U1,V1,U2,V2;
2665 Standard_Integer nn=line->NbPoints();
2666 if(nn>2) {
2667 line->Value(nn).Parameters(u1,v1,u2,v2);
2668 line->Value(nn-1).Parameters(U1,V1,U2,V2);
2669 pasuv[0]=Abs(u1-U1);
2670 pasuv[1]=Abs(v1-V1);
2671 pasuv[2]=Abs(u2-U2);
2672 pasuv[3]=Abs(v2-V2);
2673 }
2674#endif
2675 }
2676 else Arrive = Standard_True;
2677 }
2678 else {
2679 pasuv[0]*=0.5;
2680 pasuv[1]*=0.5;
2681 pasuv[2]*=0.5;
2682 pasuv[3]*=0.5;
2683 }
2684 }
2685}
2686
2687namespace {
2688 //OCC431(apo): modified ->
2689 static const Standard_Real CosRef2D = Cos(M_PI/9.0), AngRef2D = M_PI/2.0;
2690
2691 static const Standard_Real d = 7.0;
2692}
2693
2694IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection()
2695
2696// test if vector is observed by calculating an increase of vector
2697// or the previous point and its tangent, the new calculated point and its
2698// tangent; it is possible to find a cube passing by the 2 points and having as a
2699// derivative the tangents of the intersection
2700// calculate the point with parameter 0.5 on cube=p1
2701// calculate the medium point of 2 points of intersection=p2
2702// if arrow/2<=||p1p2||<= arrow consider that the vector is observed
2703// otherwise adjust the step depending on the ratio ||p1p2||/vector
2704// and the previous step
2705// test if in 2 tangent planes of surfaces there is no too great angle2d
2706// grand : if yes divide the step
2707// test if there is no change of side
2708//
2709{
2710 if(line->NbPoints() ==1 ) {
2711 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=STATIC_PRECEDENT_INFLEXION=0;
2712 }
2713
2714 IntWalk_StatusDeflection Status = IntWalk_OK;
2715 Standard_Real FlecheCourante ,Ratio;
2716
2717
2718 const IntSurf_PntOn2S& CurrentPoint = myIntersectionOn2S.Point();
2719 //==================================================================================
2720 //========= S t o p o n p o i n t ============
2721 //==================================================================================
2722 if (myIntersectionOn2S.IsTangent()) {
2723 return IntWalk_ArretSurPoint;
2724 }
2725
2726 const gp_Dir& TgCourante = myIntersectionOn2S.Direction();
2727
2728 //==================================================================================
2729 //========= R i s k o f i n f l e x i o n p o i n t ============
2730 //==================================================================================
2731 if (TgCourante.Dot(previousd)<0) {
2732 //------------------------------------------------------------
2733 //-- Risk of inflexion point : Divide the step by 2
2734 //-- Initialize STATIC_PRECEDENT_INFLEXION so that
2735 //-- at the next call to return Pas_OK if there is no
2736 //-- more risk of the point of inflexion
2737 //------------------------------------------------------------
2738
2739 pasuv[0]*=0.5;
2740 pasuv[1]*=0.5;
2741 pasuv[2]*=0.5;
2742 pasuv[3]*=0.5;
2743 STATIC_PRECEDENT_INFLEXION+=3;
2744 if (pasuv[0] < ResoU1 && pasuv[1] <ResoV1 && pasuv[2] <ResoU2 && pasuv[3] < ResoV2)
2745 return IntWalk_ArretSurPointPrecedent;
2746 else
2747 return IntWalk_PasTropGrand;
2748 }
2749
2750 else {
2751 if(STATIC_PRECEDENT_INFLEXION > 0) {
2752 STATIC_PRECEDENT_INFLEXION -- ;
2753 return IntWalk_OK;
2754 }
2755 }
2756
2757 //==================================================================================
2758 //========= D e t e c t c o n f u s e d P o in t s ===========
2759 //==================================================================================
2760
2761 Standard_Real Dist = previousPoint.Value().
2762 SquareDistance(CurrentPoint.Value());
2763
2764
2765 if (Dist < tolconf*tolconf ) {
2766 pasuv[0] = Max(5.*ResoU1,Min(1.5*pasuv[0],pasInit[0]));
2767 pasuv[1] = Max(5.*ResoV1,Min(1.5*pasuv[1],pasInit[1]));
2768 pasuv[2] = Max(5.*ResoU2,Min(1.5*pasuv[2],pasInit[2]));
2769 pasuv[3] = Max(5.*ResoV2,Min(1.5*pasuv[3],pasInit[3]));
2770 Status = IntWalk_PointConfondu;
2771 }
2772
2773 //==================================================================================
2774 Standard_Real Up1,Vp1,Uc1,Vc1,Du1,Dv1,AbsDu1,AbsDu2,AbsDv1,AbsDv2;
2775 Standard_Real Up2,Vp2,Uc2,Vc2,Du2,Dv2;
2776
2777 previousPoint.Parameters(Up1,Vp1,Up2,Vp2);
2778 CurrentPoint.Parameters(Uc1,Vc1,Uc2,Vc2);
2779
2780 Du1 = Uc1 - Up1; Dv1 = Vc1 - Vp1;
2781 Du2 = Uc2 - Up2; Dv2 = Vc2 - Vp2;
2782
2783 AbsDu1 = Abs(Du1);
2784 AbsDu2 = Abs(Du2);
2785 AbsDv1 = Abs(Dv1);
2786 AbsDv2 = Abs(Dv2);
2787 //=================================================================================
2788 //==== S t e p o f p r o g r e s s i o n (between previous and Current) =======
2789 //=================================================================================
2790 if ( AbsDu1 < ResoU1 && AbsDv1 < ResoV1
2791 && AbsDu2 < ResoU2 && AbsDv2 < ResoV2) {
2792 pasuv[0] = ResoU1; pasuv[1] = ResoV1; pasuv[2] = ResoU2; pasuv[3] = ResoV2;
2793 return(IntWalk_ArretSurPointPrecedent);
2794 }
2795 //==================================================================================
2796
2797 Standard_Real tolArea = 100.0;
2798 if (ResoU1 < Precision::PConfusion() ||
2799 ResoV1 < Precision::PConfusion() ||
2800 ResoU2 < Precision::PConfusion() ||
2801 ResoV2 < Precision::PConfusion() )
2802 tolArea = tolArea*2.0;
2803
2804 Standard_Real Cosi1, CosRef1, Ang1, AngRef1, ResoUV1, Duv1, d1, tolCoeff1;
2805 Standard_Real Cosi2, CosRef2, Ang2, AngRef2, ResoUV2, Duv2, d2, tolCoeff2;
2806 Cosi1 = Du1*previousd1.X() + Dv1*previousd1.Y();
2807 Cosi2 = Du2*previousd2.X() + Dv2*previousd2.Y();
2808 Duv1 = Du1*Du1 + Dv1*Dv1;
2809 Duv2 = Du2*Du2 + Dv2*Dv2;
2810 ResoUV1 = ResoU1*ResoU1 + ResoV1*ResoV1;
2811 ResoUV2 = ResoU2*ResoU2 + ResoV2*ResoV2;
2812 //
2813 //modified by NIZNHY-PKV Wed Nov 13 12:25:44 2002 f
2814 //
2815 Standard_Real aMinDiv2=Precision::Confusion();
2816 aMinDiv2=aMinDiv2*aMinDiv2;
2817 //
2818 d1=d;
2819 if (Duv1>aMinDiv2) {
2820 d1 = Abs(ResoUV1/Duv1);
2821 d1 = Min(Sqrt(d1)*tolArea, d);
2822 }
2823 //d1 = Abs(ResoUV1/Duv1);
2824 //d1 = Min(Sqrt(d1)*tolArea,d);
2825 //modified by NIZNHY-PKV Wed Nov 13 12:34:30 2002 t
2826 tolCoeff1 = Exp(d1);
2827 //
2828 //modified by NIZNHY-PKV Wed Nov 13 12:34:43 2002 f
2829 d2=d;
2830 if (Duv2>aMinDiv2) {
2831 d2 = Abs(ResoUV2/Duv2);
2832 d2 = Min(Sqrt(d2)*tolArea,d);
2833 }
2834 //d2 = Abs(ResoUV2/Duv2);
2835 //d2 = Min(Sqrt(d2)*tolArea,d);
2836 //modified by NIZNHY-PKV Wed Nov 13 12:34:53 2002 t
2837 tolCoeff2 = Exp(d2);
2838 CosRef1 = CosRef2D/tolCoeff1;
2839 CosRef2 = CosRef2D/tolCoeff2;
2840 //
2841 //==================================================================================
2842 //== The points are not confused : ==
2843 //== D e t e c t t h e S t o p a t p r e v i o u s p o i n t ==
2844 //== N o t T o o G r e a t (angle in space UV) ==
2845 //== C h a n g e o f s i d e ==
2846 //==================================================================================
2847 if (Status != IntWalk_PointConfondu) {
2848 if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2) {
2849 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
2850 if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2) {
2851 return(IntWalk_ArretSurPointPrecedent);
2852 }
2853 else {
2854 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
2855 return(IntWalk_PasTropGrand);
2856 }
2857 }
2858 const gp_Dir2d& Tg2dcourante1 = myIntersectionOn2S.DirectionOnS1();
2859 const gp_Dir2d& Tg2dcourante2 = myIntersectionOn2S.DirectionOnS2();
2860 Cosi1 = Du1*Tg2dcourante1.X() + Dv1*Tg2dcourante1.Y();
2861 Cosi2 = Du2*Tg2dcourante2.X() + Dv2*Tg2dcourante2.Y();
2862 Ang1 = Abs(previousd1.Angle(Tg2dcourante1));
2863 Ang2 = Abs(previousd2.Angle(Tg2dcourante2));
2864 AngRef1 = AngRef2D*tolCoeff1;
2865 AngRef2 = AngRef2D*tolCoeff2;
2866 //-------------------------------------------------------
2867 //-- Test : Angle too great in space UV -----
2868 //-- Change of side -----
2869 //-------------------------------------------------------
2870 if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2 || Ang1 > AngRef1 || Ang2 > AngRef2) {
2871 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
2872 if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2)
2873 return(IntWalk_ArretSurPoint);
2874 else
2875 return(IntWalk_PasTropGrand);
2876 }
2877 }
2878 //<-OCC431(apo)
2879 //==================================================================================
2880 //== D e t e c t i o n o f : Step Too Small
2881 //== STEP TOO Great
2882 //==================================================================================
2883
2884 //---------------------------------------
2885 //-- Estimate of the vector --
2886 //---------------------------------------
2887 FlecheCourante =
2888 Sqrt(Abs((previousd.XYZ()-TgCourante.XYZ()).SquareModulus()*Dist))/8.;
2889
2890 if ( FlecheCourante<= fleche*0.5) { //-- Current step too small
2891 if(FlecheCourante>1e-16) {
2892 Ratio = 0.5*(fleche/FlecheCourante);
2893 }
2894 else {
2895 Ratio = 10.0;
2896 }
2897 Standard_Real pasSu1 = pasuv[0];
2898 Standard_Real pasSv1 = pasuv[1];
2899 Standard_Real pasSu2 = pasuv[2];
2900 Standard_Real pasSv2 = pasuv[3];
2901
2902 //-- In case if
2903 //-- a point at U+DeltaU is required, ....
2904 //-- return a point at U + Epsilon
2905 //-- Epsilon << DeltaU.
2906
2907 if(pasuv[0]< AbsDu1) pasuv[0] = AbsDu1;
2908 if(pasuv[1]< AbsDv1) pasuv[1] = AbsDv1;
2909 if(pasuv[2]< AbsDu2) pasuv[2] = AbsDu2;
2910 if(pasuv[3]< AbsDv2) pasuv[3] = AbsDv2;
2911
2912 if(pasuv[0]<ResoU1) pasuv[0]=ResoU1;
2913 if(pasuv[1]<ResoV1) pasuv[1]=ResoV1;
2914 if(pasuv[2]<ResoU2) pasuv[2]=ResoU2;
2915 if(pasuv[3]<ResoV2) pasuv[3]=ResoV2;
2916 //-- if(Ratio>10.0 ) { Ratio=10.0; }
2917 Standard_Real R1,R = pasInit[0]/pasuv[0];
2918 R1= pasInit[1]/pasuv[1]; if(R1<R) R=R1;
2919 R1= pasInit[2]/pasuv[2]; if(R1<R) R=R1;
2920 R1= pasInit[3]/pasuv[3]; if(R1<R) R=R1;
2921 if(Ratio > R) Ratio=R;
2922 pasuv[0] = Min(Ratio*pasuv[0],pasInit[0]);
2923 pasuv[1] = Min(Ratio*pasuv[1],pasInit[1]);
2924 pasuv[2] = Min(Ratio*pasuv[2],pasInit[2]);
2925 pasuv[3] = Min(Ratio*pasuv[3],pasInit[3]);
2926 if (pasuv[0] != pasSu1 || pasuv[2] != pasSu2||
2927 pasuv[1] != pasSv1 || pasuv[3] != pasSv2) {
2928 if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
2929 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
2930 return IntWalk_PasTropGrand;
2931 }
2932 }
2933 if(Status == IntWalk_OK) {
2934 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
2935 //-- Try to increase the step
2936 }
2937 return Status;
2938 }
2939 else { //-- CurrentVector > vector*0.5
2940 if (FlecheCourante > fleche) { //-- Current step too Great
2941 Ratio = fleche/FlecheCourante;
2942 pasuv[0] = Ratio*pasuv[0];
2943 pasuv[1] = Ratio*pasuv[1];
2944 pasuv[2] = Ratio*pasuv[2];
2945 pasuv[3] = Ratio*pasuv[3];
2946 //if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
2947 // STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
2948 return IntWalk_PasTropGrand;
2949 //}
2950 }
2951 else { //-- vector/2 < CurrentVector <= vector
2952 Ratio = 0.75 * (fleche / FlecheCourante);
2953 }
2954 }
2955 pasuv[0] = Max(5.*ResoU1,Min(Min(Ratio*AbsDu1,pasuv[0]),pasInit[0]));
2956 pasuv[1] = Max(5.*ResoV1,Min(Min(Ratio*AbsDv1,pasuv[1]),pasInit[1]));
2957 pasuv[2] = Max(5.*ResoU2,Min(Min(Ratio*AbsDu2,pasuv[2]),pasInit[2]));
2958 pasuv[3] = Max(5.*ResoV2,Min(Min(Ratio*AbsDv2,pasuv[3]),pasInit[3]));
2959 if(Status == IntWalk_OK) STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
2960 return Status;
2961}
2962
2963Standard_Boolean IntWalk_PWalking::
2964TestArret(const Standard_Boolean DejaReparti,
2965 TColStd_Array1OfReal& Param,
2966 IntImp_ConstIsoparametric& ChoixIso)
2967
2968 //
2969 // test if the point of intersection set by these parameters remains in the
2970 // natural domain of each square.
2971 // if the point outpasses reframe to find the best iso (border)
2972 // that intersects easiest the other square
2973 // otherwise test if closed line is present
2974 //
2975{
2976 Standard_Real Uvd[4],Uvf[4],Epsuv[4],Duv[4],Uvp[4],dv,dv2,ParC[4];
2977 Standard_Real DPc,DPb;
2978 Standard_Integer i = 0, k = 0;
2979 Epsuv[0] = ResoU1;
2980 Epsuv[1] = ResoV1;
2981 Epsuv[2] = ResoU2;
2982 Epsuv[3] = ResoV2;
2983 previousPoint.Parameters(Uvp[0],Uvp[1],Uvp[2],Uvp[3]);
2984
2985 Standard_Real SolParam[4];
2986 myIntersectionOn2S.Point().Parameters(SolParam[0],SolParam[1],SolParam[2],SolParam[3]);
2987
2988 Standard_Boolean Trouve = Standard_False;
2989
2990 Uvd[0]=Um1; Uvf[0]=UM1; Uvd[1]=Vm1; Uvf[1]=VM1;
2991 Uvd[2]=Um2; Uvf[2]=UM2; Uvd[3]=Vm2; Uvf[3]=VM2;
2992
2993 Standard_Integer im1;
2994 for ( i = 1,im1 = 0;i<=4;i++,im1++) {
2995 switch(i) {
2996 case 1: k=2; break;
2997 case 2: k=1; break;
2998 case 3: k=4; break;
2999 case 4: k=3; break;
3000 }
3001 if (Param(i) < (Uvd[im1]-Epsuv[im1]) ||
3002 SolParam[im1] < (Uvd[im1]-Epsuv[im1])) //-- Current ----- Bound Inf ----- Previous
3003 {
3004 Trouve = Standard_True; //--
3005 DPc = Uvp[im1]-Param(i); //-- Previous - Current
3006 DPb = Uvp[im1]-Uvd[im1]; //-- Previous - Bound Inf
3007 ParC[im1] = Uvd[im1]; //-- ParamCorrige
3008 dv = Param(k)-Uvp[k-1]; //-- Current - Previous (other Direction)
3009 dv2 = dv*dv;
3010 if(dv2>RealEpsilon()) { //-- Progress at the other Direction ?
3011 Duv[im1] = DPc*DPb + dv2;
3012 Duv[im1] = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
3013 }
3014 else {
3015 Duv[im1]=-1.0; //-- If no progress, do not change
3016 } //-- the choice of iso
3017 }
3018 else if (Param(i) > (Uvf[im1] + Epsuv[im1]) ||
3019 SolParam[im1] > (Uvf[im1] + Epsuv[im1]))//-- Previous ----- Bound Sup ----- Current
3020 {
3021 Trouve = Standard_True; //--
3022 DPc = Param(i)-Uvp[im1]; //-- Current - Previous
3023 DPb = Uvf[im1]-Uvp[im1]; //-- Bound Sup - Previous
3024 ParC[im1] = Uvf[im1]; //-- Param Corrige
3025 dv = Param(k)-Uvp[k-1]; //-- Current - Previous (other Direction)
3026 dv2 = dv*dv;
3027 if(dv2>RealEpsilon()) { //-- Progress in other Direction ?
3028 Duv[im1] = DPc*DPb + dv2;
3029 Duv[im1] = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
3030 }
3031 else {
3032 Duv[im1]=-1.0; //-- If no progress, do not change
3033 } //-- the choice of iso
3034 }
3035 else {
3036 Duv[im1]= -1.;
3037 ParC[im1]=Param(i);
3038 }
3039 }
3040
3041 if (Trouve) {
3042 //--------------------------------------------------
3043 //-- One of Parameters u1,v1,u2,v2 is outside of --
3044 //-- the natural limits. --
3045 //-- Find the best direction of --
3046 //-- progress and reframe the parameters. --
3047 //--------------------------------------------------
3048 Standard_Real ddv = -1.0;
3049 k=-1;
3050 for (i=0;i<=3;i++) {
3051 Param(i+1) = ParC[i];
3052 if(Duv[i]>ddv) {
3053 ddv = Duv[i];
3054 k=i;
3055 }
3056 }
3057 if(k!=-1) {
3058 ChoixIso = ChoixRef[k];
3059 }
3060 else {
3061 if((ParC[0]<=Uvd[0]+Epsuv[0]) || (ParC[0]>=Uvf[0]-Epsuv[0])) {
3062 ChoixIso = IntImp_UIsoparametricOnCaro1;
3063 }
3064 else if((ParC[1]<=Uvd[1]+Epsuv[1]) || (ParC[1]>=Uvf[1]-Epsuv[1])) {
3065 ChoixIso = IntImp_VIsoparametricOnCaro1;
3066 }
3067 else if((ParC[2]<=Uvd[2]+Epsuv[2]) || (ParC[2]>=Uvf[2]-Epsuv[2])) {
3068 ChoixIso = IntImp_UIsoparametricOnCaro2;
3069 }
3070 else if((ParC[3]<=Uvd[3]+Epsuv[3]) || (ParC[3]>=Uvf[3]-Epsuv[3])) {
3071 ChoixIso = IntImp_VIsoparametricOnCaro2;
3072 }
3073 }
3074 close = Standard_False;
3075 return Standard_True;
3076 }
3077 else
3078 {
3079 if (!DejaReparti) { // find if line closed
3080
3081 Standard_Real u,v;
3082 const IntSurf_PntOn2S& POn2S1=line->Value(1);
3083 //On S1
3084 POn2S1.ParametersOnS1(u,v);
3085 gp_Pnt2d P1uvS1(u,v);
3086 previousPoint.ParametersOnS1(u,v);
3087 gp_Pnt2d PrevuvS1(u,v);
3088 myIntersectionOn2S.Point().ParametersOnS1(u,v);
3089 gp_Pnt2d myIntersuvS1(u,v);
3090 Standard_Boolean close2dS1 = (P1uvS1.XY()-PrevuvS1.XY())*
3091 (P1uvS1.XY()-myIntersuvS1.XY()) < 0.0;
3092 //On S2
3093 POn2S1.ParametersOnS2(u,v);
3094 gp_Pnt2d P1uvS2(u,v);
3095 previousPoint.ParametersOnS2(u,v);
3096 gp_Pnt2d PrevuvS2(u,v);
3097 myIntersectionOn2S.Point().ParametersOnS2(u,v);
3098 gp_Pnt2d myIntersuvS2(u,v);
3099 Standard_Boolean close2dS2 = (P1uvS2.XY()-PrevuvS2.XY())*
3100 (P1uvS2.XY()-myIntersuvS2.XY()) < 0.0;
3101
3102 close = close2dS1 && close2dS2;
3103 return close;
3104 }
3105 else return Standard_False;
3106 }
3107}
3108