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