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