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