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