Commit | Line | Data |
---|---|---|
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 | |
7fd59977 | 15 | //-- IntWalk_IWalking_2.gxx |
16 | ||
d07a6c39 | 17 | #include <Bnd_Range.hxx> |
8d795b51 | 18 | #include <TColStd_MapOfInteger.hxx> |
19 | ||
0797d9d3 | 20 | #ifndef OCCT_DEBUG |
7fd59977 | 21 | #define No_Standard_RangeError |
22 | #define No_Standard_OutOfRange | |
23 | #endif | |
24 | ||
25 | ||
26 | // _______________________________________________ | |
27 | // | |
b1c5c4e6 | 28 | // Location of point (u, v) in the natural domain of a surface AND update |
29 | // of couple (u, v) for the calculation of the next point. | |
7fd59977 | 30 | // |
31 | Standard_Boolean IntWalk_IWalking::Cadrage | |
32 | (math_Vector& BornInf, | |
33 | math_Vector& BornSup, | |
34 | math_Vector& UVap, | |
35 | Standard_Real& Step, | |
36 | // Standard_Real& StepV, | |
37 | const Standard_Integer StepSign) const | |
38 | ||
b1c5c4e6 | 39 | // there are always : |
7fd59977 | 40 | // BorInf(1) <= UVap(1) <= BornSup(1) et BorInf(2) <= UVap(2) <= BornSup(2) |
b1c5c4e6 | 41 | // 1) check if the process point is out of the natural domain of the surface. |
42 | // 2) if yes the approximated point is located on border taking the best direction | |
43 | // the step and a limit blocating one of the parameters during the recent call of | |
44 | // FunctionSetRoot are modified; | |
45 | // 3) couple (u, v) is recomputed by approximation for the calculation of the next point. | |
46 | // 4) return Standard_True if location, Standard_False if no location. | |
7fd59977 | 47 | { |
48 | Standard_Real Duvx = previousd2d.X(); | |
49 | Standard_Real Duvy = previousd2d.Y(); | |
50 | ||
51 | if (!reversed) { | |
52 | previousPoint.ParametersOnS2(UVap(1),UVap(2)); | |
53 | } | |
54 | else { | |
55 | previousPoint.ParametersOnS1(UVap(1),UVap(2)); | |
56 | } | |
57 | ||
58 | Standard_Real U1 = UVap(1) + Step * Duvx * StepSign; | |
59 | Standard_Real V1 = UVap(2) + Step * Duvy * StepSign; | |
60 | ||
61 | ||
62 | Standard_Boolean infu = (U1 <= BornInf(1)+Precision::PConfusion()); | |
63 | Standard_Boolean supu = (U1 >= BornSup(1)-Precision::PConfusion()); | |
64 | Standard_Boolean infv = (V1 <= BornInf(2)+Precision::PConfusion()); | |
65 | Standard_Boolean supv = (V1 >= BornSup(2)-Precision::PConfusion()); | |
66 | ||
67 | Standard_Real theStepU,theStepV; | |
68 | ||
69 | if (!infu && !supu && !infv && !supv) { | |
70 | UVap(1) = U1; | |
71 | UVap(2) = V1; | |
72 | return Standard_False; | |
73 | } | |
74 | ||
75 | if ((infu || supu) && (infv || supv)) { | |
76 | if (infu) { // jag 940616 | |
77 | if(Duvx) { | |
78 | theStepU = Abs((BornInf(1) - UVap(1)) / Duvx); // iso U =BornInf(1) | |
79 | } | |
80 | else { | |
81 | theStepU = Step; | |
82 | } | |
83 | } | |
84 | else { | |
85 | if(Duvx) { | |
86 | theStepU = Abs((BornSup(1) - UVap(1)) / Duvx); // iso U =BornSup(1) | |
87 | } | |
88 | else { | |
89 | theStepU = Step; | |
90 | } | |
91 | } | |
92 | if (infv) { // jag 940616 | |
93 | if(Duvy) { | |
94 | theStepV = Abs((BornInf(2) - UVap(2)) / Duvy); // iso V =BornInf(2) | |
95 | } | |
96 | else { | |
97 | theStepV = Step; | |
98 | } | |
99 | } | |
100 | else { | |
101 | if(Duvy) { | |
102 | theStepV = Abs((BornSup(2) - UVap(2)) / Duvy); // iso V =BornSup(2) | |
103 | } | |
104 | else { | |
105 | theStepV = Step; | |
106 | } | |
107 | } | |
108 | ||
109 | ||
110 | if (theStepU <= theStepV) { | |
111 | Step = theStepU; | |
112 | if (infu) { | |
113 | UVap(1) = BornInf(1); | |
114 | BornSup(1) = BornInf(1); | |
115 | } | |
116 | else { | |
117 | UVap(1) = BornSup(1); | |
118 | BornInf(1) = BornSup(1); | |
119 | } | |
120 | UVap(2) += Step*Duvy*StepSign; | |
121 | } | |
122 | else { | |
123 | Step = theStepV; | |
124 | if (infv) { | |
125 | UVap(2) = BornInf(2); | |
126 | BornSup(2) = BornInf(2); | |
127 | } | |
128 | else { | |
129 | UVap(2) = BornSup(2); | |
130 | BornInf(2) = BornSup(2); | |
131 | } | |
132 | UVap(1) += Step*Duvx*StepSign; | |
133 | } | |
134 | return Standard_True; | |
135 | } | |
136 | ||
137 | else if (infu) { // jag 940616 | |
138 | if(Duvx) { | |
139 | Standard_Real aStep = Abs((BornInf(1) - UVap(1)) / Duvx); // iso U =BornInf(1) | |
140 | if(aStep<Step) Step=aStep; | |
141 | } | |
b1c5c4e6 | 142 | BornSup(1) = BornInf(1); // limit the parameter |
7fd59977 | 143 | UVap(1) = BornInf(1); |
144 | UVap(2) += Step*Duvy*StepSign;; | |
145 | return Standard_True; | |
146 | } | |
147 | else if (supu) { // jag 940616 | |
148 | if(Duvx) { | |
149 | Standard_Real aStep = Abs((BornSup(1) - UVap(1)) / Duvx); // iso U =BornSup(1) | |
150 | if(aStep<Step) Step=aStep; | |
151 | } | |
b1c5c4e6 | 152 | BornInf(1) = BornSup(1); // limit the parameter |
7fd59977 | 153 | UVap(1) = BornSup(1); |
154 | UVap(2) += Step*Duvy*StepSign; | |
155 | return Standard_True; | |
156 | } | |
157 | else if (infv) { // jag 940616 | |
158 | if(Duvy) { | |
159 | Standard_Real aStep = Abs((BornInf(2) - UVap(2)) / Duvy); // iso V =BornInf(2) | |
160 | if(aStep<Step) Step=aStep; | |
161 | } | |
162 | BornSup(2) = BornInf(2); | |
163 | UVap(1) += Step*Duvx*StepSign; | |
164 | UVap(2) = BornInf(2); | |
165 | return Standard_True; | |
166 | } | |
167 | else if (supv) { // jag 940616 | |
168 | if(Duvy) { | |
169 | Standard_Real aStep = Abs((BornSup(2) - UVap(2)) / Duvy); // iso V =BornSup(2) | |
170 | if(aStep<Step) Step=aStep; | |
171 | } | |
172 | BornInf(2) = BornSup(2); | |
173 | UVap(1) += Step*Duvx*StepSign; | |
174 | UVap(2) = BornSup(2); | |
175 | return Standard_True; | |
176 | } | |
177 | return Standard_True; | |
178 | } | |
179 | ||
180 | ||
181 | Standard_Boolean IntWalk_IWalking::TestArretPassage | |
182 | (const TColStd_SequenceOfReal& Umult, | |
183 | const TColStd_SequenceOfReal& Vmult, | |
184 | TheIWFunction& sp, | |
185 | math_Vector& UV, | |
186 | Standard_Integer& Irang) | |
187 | ||
b1c5c4e6 | 188 | // Umult et Vmult : table of stop (or crossing) points on border, |
189 | // here only the crossing points are taken into account. | |
190 | // UV : the current point. | |
191 | // Irang : at exit : give index of the stop point in uvstart1 or 0. | |
192 | // consider that there is no risk of crossing only if there is one crossing point. | |
7fd59977 | 193 | |
194 | ||
b1c5c4e6 | 195 | // test of stop for an OPEN intersection line |
196 | // 1) crossing test on all interior points | |
197 | // 2) stop test on all start points | |
198 | // if a stop is detected, the index of the stop point (Irang) is returned | |
199 | // in the iterator of start points and the associated parameters in UV space. | |
7fd59977 | 200 | { |
201 | Standard_Real Up, Vp, Du, Dv, Dup, Dvp, Utest,Vtest; | |
96a85238 | 202 | Standard_Integer j, N, ind; |
7fd59977 | 203 | Standard_Real tolu = tolerance(1); |
204 | Standard_Real tolv = tolerance(2); | |
205 | Standard_Real tolu2 = 10.*tolerance(1); | |
206 | Standard_Real tolv2 = 10.*tolerance(2); | |
207 | ||
208 | Standard_Boolean Arrive = Standard_False; | |
209 | ||
b1c5c4e6 | 210 | // crossing test on point that can start a loop; mark |
211 | // as processed if passes through an open line | |
7fd59977 | 212 | |
213 | if (!reversed) { | |
214 | previousPoint.ParametersOnS2(Up,Vp); | |
215 | } | |
216 | else { | |
217 | previousPoint.ParametersOnS1(Up,Vp); | |
218 | } | |
219 | ||
96a85238 RL |
220 | for (size_t i = 1; i < wd2.size(); i++) { |
221 | if (wd2[i].etat > 0) { | |
7fd59977 | 222 | // debug jag 05.04.94 |
223 | ||
96a85238 RL |
224 | // if ((Up-wd2[i].ustart)*(UV(1)-wd2[i].ustart) + |
225 | // (Vp-wd2[i].vstart)*(UV(2)-wd2[i].vstart) <= 0) | |
226 | Utest = wd2[i].ustart; | |
227 | Vtest = wd2[i].vstart; | |
7fd59977 | 228 | |
229 | Du = UV(1)-Utest; | |
230 | Dv = UV(2)-Vtest; | |
231 | Dup = Up - Utest; | |
232 | Dvp = Vp - Vtest; | |
233 | ||
234 | //-- lbr le 30 oct 97 | |
235 | ||
236 | //IFV for OCC20285 | |
237 | ||
7fd59977 | 238 | if ((Abs(Du) < tolu2 && Abs(Dv) < tolv2) || |
239 | (Abs(Dup) < tolu2 && Abs(Dvp) < tolv2)) { | |
240 | ||
96a85238 | 241 | wd2[i].etat = -wd2[i].etat; |
7fd59977 | 242 | } |
243 | else { | |
244 | Standard_Real DDu = (UV(1)-Up); | |
245 | Standard_Real DDv = (UV(2)-Vp); | |
246 | Standard_Real DDD = DDu*DDu+DDv*DDv; | |
247 | Standard_Real DD1 = Du*Du+Dv*Dv; | |
248 | if(DD1<=DDD) { | |
249 | Standard_Real DD2 = Dup*Dup+Dvp*Dvp; | |
250 | if(DD2<=DDD && ((Du*Dup) + (Dv*Dvp*tolu/tolv) <= 0.)) { | |
96a85238 | 251 | wd2[i].etat = -wd2[i].etat; |
7fd59977 | 252 | } |
253 | } | |
254 | } | |
255 | } | |
256 | } | |
257 | ||
b1c5c4e6 | 258 | // stop test on point given at input and not yet processed |
7fd59977 | 259 | |
260 | // Modified by Sergey KHROMOV - Tue Nov 20 10:55:01 2001 Begin | |
261 | // Check of all path points in the following order: | |
262 | // * First check all not treated points; | |
263 | // * After that check of already treated ones. | |
264 | Standard_Integer l; | |
265 | ||
266 | //// Modified by jgv, 28.07.2010 for OCC21914 //// | |
267 | // There are several path points between (Up,Vp) and UV | |
268 | // So several path points satisfy the condition | |
269 | // Dup*UV1mUtest + Dvp*UV2mVtest) < 0 | |
270 | // We choose from them the path point with | |
271 | // minimum distance to (Up,Vp) | |
272 | TColStd_SequenceOfInteger i_candidates; | |
273 | TColStd_SequenceOfReal SqDist_candidates; | |
274 | ||
275 | for (l = 1; l <= 2 && !Arrive; l++) { | |
276 | Standard_Boolean isToCheck; | |
277 | ||
96a85238 | 278 | for (size_t i = 1; i < wd1.size(); i++) { |
7fd59977 | 279 | if (l == 1) |
96a85238 | 280 | isToCheck = (wd1[i].etat > 0); |
7fd59977 | 281 | else |
96a85238 | 282 | isToCheck = (wd1[i].etat < 0); |
7fd59977 | 283 | |
284 | if (isToCheck) { | |
285 | // Modified by Sergey KHROMOV - Tue Nov 20 11:03:16 2001 End | |
286 | ||
287 | // debug jag voir avec isg | |
288 | ||
96a85238 RL |
289 | Utest = wd1[i].ustart; |
290 | Vtest = wd1[i].vstart; | |
7fd59977 | 291 | Dup = Up - Utest; |
292 | Dvp = Vp - Vtest; | |
293 | if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) { | |
294 | Standard_Real UV1mUtest = UV(1)-Utest; | |
295 | Standard_Real UV2mVtest = UV(2)-Vtest; | |
296 | if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) || | |
297 | ( Abs(UV1mUtest) < tolu | |
298 | && Abs(UV2mVtest) < tolv)) { | |
7dc9e047 | 299 | i_candidates.Append((Standard_Integer)i); |
7fd59977 | 300 | SqDist_candidates.Append(Dup*Dup + Dvp*Dvp); |
301 | /* | |
302 | Irang=i; | |
303 | Arrive = Standard_True; | |
304 | UV(1) = Utest; | |
305 | UV(2) = Vtest; | |
306 | */ | |
307 | } | |
96a85238 | 308 | else if (nbMultiplicities[i] > 0 && i_candidates.IsEmpty()) { |
7fd59977 | 309 | N=0; |
96a85238 RL |
310 | for (size_t k = 1; k < i; k++) { |
311 | N+=nbMultiplicities[k]; | |
7fd59977 | 312 | } |
96a85238 | 313 | for (j = N + 1; j <= N + nbMultiplicities[i]; j++) { |
7fd59977 | 314 | if (((Up-Umult(j))*(UV(1)-Umult(j)) + |
315 | (Vp-Vmult(j))*(UV(2)-Vmult(j)) < 0) || | |
316 | (Abs(UV(1)-Umult(j)) < tolu && | |
317 | Abs(UV(2)-Vmult(j)) < tolv)) { | |
7dc9e047 | 318 | Irang=(Standard_Integer)i; |
7fd59977 | 319 | Arrive = Standard_True; |
320 | UV(1) = Utest; | |
321 | UV(2) = Vtest; | |
322 | break; | |
323 | } | |
324 | } | |
325 | } | |
326 | if (Arrive) { | |
1ef32e96 RL |
327 | Standard_Real abidF[1], abidD[1][2]; |
328 | math_Vector bidF(abidF,1,1); | |
329 | math_Matrix bidD(abidD,1,1,1,2); | |
6e6cd5d9 | 330 | sp.Values(UV,bidF,bidD); |
7fd59977 | 331 | break; |
332 | } | |
333 | } | |
334 | } | |
96a85238 | 335 | } //end of for (i = 1; i < wd1.size(); i++) |
7fd59977 | 336 | if (!i_candidates.IsEmpty()) |
337 | { | |
338 | Standard_Real MinSqDist = RealLast(); | |
339 | for (ind = 1; ind <= i_candidates.Length(); ind++) | |
340 | if (SqDist_candidates(ind) < MinSqDist) | |
341 | { | |
342 | MinSqDist = SqDist_candidates(ind); | |
343 | Irang = i_candidates(ind); | |
344 | } | |
345 | Arrive = Standard_True; | |
96a85238 RL |
346 | UV(1) = wd1[Irang].ustart; |
347 | UV(2) = wd1[Irang].vstart; | |
7fd59977 | 348 | } |
349 | } //end of for (l = 1; l <= 2 && !Arrive; l++) | |
350 | return Arrive; | |
351 | } | |
352 | ||
353 | Standard_Boolean IntWalk_IWalking::TestArretPassage | |
354 | (const TColStd_SequenceOfReal& Umult, | |
355 | const TColStd_SequenceOfReal& Vmult, | |
356 | const math_Vector& UV, | |
357 | const Standard_Integer Index, | |
358 | Standard_Integer& Irang) | |
359 | { | |
b1c5c4e6 | 360 | // Umult, Vmult : table of stop (or crossing) points on border, here |
361 | // only crossing points are taken into account. | |
362 | // UV : the current point. | |
363 | // Index : index of the start point in uvstart2 of the current line | |
364 | // (this is an interior point). | |
365 | // Irang : at output : gives the index of the point passing in uvstart1 or 0. | |
366 | // consider that there is risk to cross only one crossing point. | |
367 | ||
368 | // test of stop for a CLOSED intersection line. | |
369 | // 1) test of crossing on all interior points. | |
370 | // 2) test of crossing on all crossing points. | |
7fd59977 | 371 | |
372 | Standard_Real Up, Vp, Scal; | |
373 | Standard_Boolean Arrive = Standard_False; | |
374 | Standard_Integer N, k, i; | |
375 | Standard_Real Utest,Vtest; | |
376 | Standard_Real tolu = tolerance(1); | |
377 | Standard_Real tolv = tolerance(2); | |
378 | ||
379 | ||
b1c5c4e6 | 380 | // tests of stop and of crossing on all interior points. |
7fd59977 | 381 | |
382 | if (!reversed) { | |
383 | previousPoint.ParametersOnS2(Up,Vp); | |
384 | } | |
385 | else { | |
386 | previousPoint.ParametersOnS1(Up,Vp); | |
387 | } | |
388 | ||
389 | Standard_Real UV1=UV(1); | |
390 | Standard_Real UV2=UV(2); | |
391 | ||
392 | ||
d07a6c39 | 393 | //Normalizing factor. If it is less than 1.0 then the range will be expanded. |
394 | //This is no good for computation. Therefore, it is limited. | |
395 | const Standard_Real deltau = mySRangeU.IsVoid() ? UM - Um : Max(mySRangeU.Delta(), 1.0); | |
396 | const Standard_Real deltav = mySRangeV.IsVoid() ? VM - Vm : Max(mySRangeV.Delta(), 1.0); | |
7fd59977 | 397 | |
398 | Up/=deltau; UV1/=deltau; | |
399 | Vp/=deltav; UV2/=deltav; | |
400 | ||
401 | tolu/=deltau; | |
402 | tolv/=deltav; | |
403 | ||
404 | Standard_Real tolu2=tolu+tolu; | |
405 | Standard_Real tolv2=tolv+tolv; | |
406 | ||
407 | ||
408 | Standard_Real dPreviousCurrent = (Up-UV1)*(Up-UV1)+(Vp-UV2)*(Vp-UV2); | |
96a85238 RL |
409 | for (k = 1; k < (int)wd2.size(); k++) { |
410 | if (wd2[k].etat > 0) { | |
411 | Utest = wd2[k].ustart; | |
412 | Vtest = wd2[k].vstart; | |
7fd59977 | 413 | |
414 | Utest/=deltau; | |
415 | Vtest/=deltav; | |
416 | ||
417 | Standard_Real UV1mUtest=UV1-Utest; | |
418 | Standard_Real UV2mVtest=UV2-Vtest; | |
419 | if( (UV1mUtest<tolu2 && UV1mUtest>-tolu2) | |
420 | && (UV2mVtest<tolv2 && UV2mVtest>-tolv2)) { | |
421 | if(Index!=k) { | |
422 | //-- cout<<"* etat2 : ("<<k<<")"<<endl; | |
b1c5c4e6 | 423 | wd2[k].etat=-wd2[k].etat; //-- mark the point as a crossing point |
7fd59977 | 424 | } |
425 | else { //-- Index == k | |
426 | //-- cout<<"* Arrive"<<endl; | |
427 | Arrive=Standard_True; | |
428 | } | |
429 | } | |
430 | else { | |
431 | Standard_Real UpmUtest = (Up-Utest); | |
432 | Standard_Real VpmVtest = (Vp-Vtest); | |
433 | Standard_Real dPreviousStart = (UpmUtest)*(UpmUtest)+(VpmVtest)*(VpmVtest); | |
434 | Standard_Real dCurrentStart = UV1mUtest * UV1mUtest + UV2mVtest * UV2mVtest; | |
435 | ||
436 | Scal=(UpmUtest)*(UV1mUtest)+(VpmVtest)*(UV2mVtest); | |
437 | if( (Abs(UpmUtest)<tolu && Abs(VpmVtest)<tolv)) { | |
438 | if(Index != k ) { | |
439 | //-- cout<<"** etat2 : ("<<k<<")"<<endl; | |
96a85238 | 440 | wd2[k].etat = -wd2[k].etat; |
7fd59977 | 441 | } |
442 | } | |
443 | else if(Scal<0 && (dPreviousStart+dCurrentStart < dPreviousCurrent)) { | |
444 | if (Index == k ) { // on a boucle. | |
445 | Arrive = Standard_True; | |
446 | //-- cout<<"** Arrive : k="<<k<<endl; | |
447 | } | |
448 | else { | |
449 | //-- cout<<"*** etat2 : ("<<k<<")"<<endl; | |
b1c5c4e6 | 450 | wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point |
7fd59977 | 451 | } |
452 | } | |
453 | else if(k!=Index) { | |
454 | if(dPreviousStart < dPreviousCurrent*0.25) { | |
b1c5c4e6 | 455 | wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point |
7fd59977 | 456 | //-- cout<<"**** etat2 : ("<<k<<")"<<endl; |
457 | } | |
458 | else { | |
459 | if(dCurrentStart < dPreviousCurrent*0.25) { | |
460 | //-- cout<<"***** etat2 : ("<<k<<")"<<endl; | |
b1c5c4e6 | 461 | wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point |
7fd59977 | 462 | } |
463 | else { | |
464 | Standard_Real UMidUtest = 0.5*(UV1+Up)-Utest; | |
465 | Standard_Real VMidVtest = 0.5*(UV2+Vp)-Vtest; | |
466 | Standard_Real dMiddleStart = UMidUtest* UMidUtest+VMidVtest*VMidVtest; | |
467 | ||
468 | if(dMiddleStart < dPreviousCurrent*0.5) { | |
469 | //-- cout<<"*********** etat2 : ("<<k<<")"<<endl; | |
b1c5c4e6 | 470 | wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point |
7fd59977 | 471 | } |
472 | } | |
473 | } | |
474 | } | |
475 | } | |
476 | } | |
477 | } | |
478 | ||
b1c5c4e6 | 479 | // crossing test on crossing points. |
7fd59977 | 480 | |
481 | Irang =0; | |
96a85238 | 482 | for (i = 1; i < (int)wd1.size(); i++) { |
b1c5c4e6 | 483 | if (wd1[i].etat > 0 && wd1[i].etat < 11) { //test of crossing points |
96a85238 RL |
484 | Utest = wd1[i].ustart; |
485 | Vtest = wd1[i].vstart; | |
7fd59977 | 486 | Utest/=deltau; |
487 | Vtest/=deltav; | |
488 | ||
489 | if (((Up-Utest) * (UV1-Utest) + (Vp-Vtest) * (UV2-Vtest) < 0) || | |
490 | (Abs(UV1-Utest) < tolu && Abs(UV2-Vtest) < tolv)) | |
491 | Irang = i; | |
96a85238 | 492 | else if (nbMultiplicities[i] > 0) { |
7fd59977 | 493 | N=0; |
96a85238 RL |
494 | for (k = 1; k < i; k++) N = N + nbMultiplicities[k]; |
495 | for (Standard_Integer j = N + 1; j <= N + nbMultiplicities[i]; j++) { | |
7fd59977 | 496 | Standard_Real Umultj = Umult(j)/deltau; |
497 | Standard_Real Vmultj = Vmult(j)/deltav; | |
498 | if (((Up-Umultj)*(UV1-Umultj) + | |
499 | (Vp-Vmultj)*(UV2-Vmultj) < 0) || | |
500 | (Abs(UV1-Umultj) < tolu && | |
501 | Abs(UV2-Vmultj) < tolv)) { | |
502 | Irang=i; | |
503 | break; | |
504 | } | |
505 | } | |
506 | } | |
507 | } | |
508 | } | |
509 | return Arrive; | |
510 | } | |
511 | ||
512 | ||
513 | Standard_Boolean IntWalk_IWalking::TestArretAjout | |
514 | (TheIWFunction& sp, | |
515 | math_Vector& UV, | |
516 | Standard_Integer& Irang, | |
517 | IntSurf_PntOn2S& Psol) | |
518 | ||
b1c5c4e6 | 519 | // test of stop on added points |
520 | // these are the points on the natural biorder that were not given at input | |
521 | // return : Psol, the added point. | |
522 | // Irang, index in the iterator of added points. | |
523 | // UV, parameter of the added point. | |
7fd59977 | 524 | // |
525 | { | |
526 | Standard_Boolean Arrive = Standard_False; | |
527 | Standard_Real U1,V1; | |
528 | Standard_Real Up,Vp; | |
529 | ||
530 | if (!reversed) { | |
531 | previousPoint.ParametersOnS2(Up,Vp); | |
532 | } | |
533 | else { | |
534 | previousPoint.ParametersOnS1(Up,Vp); | |
535 | } | |
536 | ||
537 | Standard_Integer nbAjout = seqAjout.Length(); | |
538 | for (Standard_Integer i = 1; i <= nbAjout; i++) { | |
539 | Irang = seqAjout.Value(i); | |
540 | ||
b1c5c4e6 | 541 | // add test Abs(Irang) <= lines.Length() for the case when |
542 | // a closed line is opened by adding a 1 point on this same | |
543 | // line. Anyway there is a huge problem as 2 points will be | |
544 | // added on this line... | |
7fd59977 | 545 | |
546 | if (Abs(Irang) <= lines.Length()) { | |
547 | ||
548 | const Handle(IntWalk_TheIWLine)& Line = lines.Value(Abs(Irang)); | |
549 | if (Irang>0) | |
550 | Psol = Line->Value(Line->NbPoints()); | |
551 | else | |
552 | Psol = Line->Value(1); | |
553 | if (!reversed) { | |
554 | Psol.ParametersOnS2(U1, V1); | |
555 | } | |
556 | else { | |
557 | Psol.ParametersOnS1(U1, V1); | |
558 | } | |
559 | if (((Up-U1) * (UV(1)-U1) + | |
560 | (Vp-V1) * (UV(2)-V1)) < 0 || | |
561 | (Abs(UV(1)-U1) < tolerance(1) && | |
562 | Abs(UV(2)-V1) < tolerance(2))) { | |
563 | //jag 940615 Irang= -Abs(Irang); | |
564 | Arrive = Standard_True; | |
565 | UV(1) = U1; | |
566 | UV(2) = V1; | |
1ef32e96 RL |
567 | Standard_Real abidF[1], abidD[1][2]; |
568 | math_Vector bidF(abidF,1,1); | |
569 | math_Matrix bidD(abidD,1,1,1,2); | |
6e6cd5d9 | 570 | sp.Values(UV,bidF,bidD); |
7fd59977 | 571 | break; |
572 | } | |
573 | } | |
574 | } | |
575 | return Arrive; | |
576 | } | |
577 | ||
8d795b51 | 578 | void IntWalk_IWalking::FillPntsInHoles(TheIWFunction& sp, |
579 | TColStd_SequenceOfInteger& CopySeqAlone, | |
580 | IntSurf_SequenceOfInteriorPoint& PntsInHoles) | |
581 | { | |
582 | math_Vector BornInf(1,2), BornSup(1,2); | |
583 | BornInf(1) = Um; | |
584 | BornSup(1) = UM; | |
585 | BornInf(2) = Vm; | |
586 | BornSup(2) = VM; | |
587 | PointLineLine.Clear(); | |
588 | TColStd_SequenceOfInteger SeqToRemove; | |
589 | TColStd_MapOfInteger BadSolutions; | |
590 | ||
591 | for (Standard_Integer i = 1; i < CopySeqAlone.Length(); i++) | |
592 | { | |
593 | Standard_Integer Irang1 = CopySeqAlone(i); | |
594 | if (Irang1 == 0) | |
595 | continue; | |
596 | Standard_Boolean ToRemove = Standard_False; | |
597 | IntSurf_PntOn2S PointAlone1, PointAlone2; | |
598 | const Handle(IntWalk_TheIWLine)& Line1 = lines.Value(Abs(Irang1)); | |
599 | if (Irang1 > 0) | |
600 | PointAlone1 = Line1->Value(Line1->NbPoints()); | |
601 | else | |
602 | PointAlone1 = Line1->Value(1); | |
603 | gp_Pnt2d P2d1 = PointAlone1.ValueOnSurface(reversed), P2d2; | |
604 | Standard_Real MinSqDist = RealLast(); | |
605 | Standard_Integer MinRang = 0, MinIndex = 0; | |
606 | for (Standard_Integer j = i+1; j <= CopySeqAlone.Length(); j++) | |
607 | { | |
608 | Standard_Integer Irang2 = CopySeqAlone(j); | |
609 | if (Irang2 == 0 || | |
610 | BadSolutions.Contains(Irang2)) | |
611 | continue; | |
612 | const Handle(IntWalk_TheIWLine)& Line2 = lines.Value(Abs(Irang2)); | |
613 | if (Irang2 > 0) | |
614 | PointAlone2 = Line2->Value(Line2->NbPoints()); | |
615 | else | |
616 | PointAlone2 = Line2->Value(1); | |
617 | P2d2 = PointAlone2.ValueOnSurface(reversed); | |
618 | Standard_Real aSqDist = P2d1.SquareDistance(P2d2); | |
619 | if (aSqDist < MinSqDist) | |
620 | { | |
621 | MinSqDist = aSqDist; | |
622 | MinRang = Irang2; | |
623 | MinIndex = j; | |
624 | } | |
625 | } | |
626 | //processing points from Irang1 and MinRang | |
627 | if (MinRang == 0) | |
628 | { | |
629 | SeqToRemove.Append(Irang1); | |
630 | BadSolutions.Clear(); | |
631 | continue; | |
632 | } | |
633 | //Ends of same line | |
634 | if (Abs(Irang1) == Abs(MinRang) && | |
635 | lines.Value(Abs(Irang1))->NbPoints() == 2) | |
636 | { | |
637 | SeqToRemove.Append(Irang1); | |
638 | SeqToRemove.Append(MinRang); | |
639 | CopySeqAlone(i) = 0; | |
640 | CopySeqAlone(MinIndex) = 0; | |
641 | BadSolutions.Clear(); | |
642 | continue; | |
643 | } | |
644 | /////////////////// | |
645 | const Handle(IntWalk_TheIWLine)& Line2 = lines.Value(Abs(MinRang)); | |
646 | if (MinRang > 0) | |
647 | PointAlone2 = Line2->Value(Line2->NbPoints()); | |
648 | else | |
649 | PointAlone2 = Line2->Value(1); | |
650 | gp_Pnt Pnt1 = PointAlone1.Value(); | |
651 | gp_Pnt Pnt2 = PointAlone2.Value(); | |
652 | P2d2 = PointAlone2.ValueOnSurface(reversed); | |
653 | Standard_Real MinSqDist3d = Pnt1.SquareDistance(Pnt2); | |
654 | if (MinSqDist3d <= epsilon || | |
655 | (Abs(P2d1.X() - P2d2.X()) <= tolerance(1) && | |
656 | Abs(P2d1.Y() - P2d2.Y()) <= tolerance(2))) //close points | |
657 | ToRemove = Standard_True; | |
658 | else //real curve | |
659 | { | |
660 | math_Vector UVap(1,2), UV(1,2); | |
661 | UVap(1) = (P2d1.X() + P2d2.X())/2; | |
662 | UVap(2) = (P2d1.Y() + P2d2.Y())/2; | |
663 | math_FunctionSetRoot Rsnld(sp, tolerance); | |
664 | Rsnld.Perform(sp, UVap, BornInf, BornSup); | |
665 | if (Rsnld.IsDone() && | |
666 | Abs(sp.Root()) <= sp.Tolerance() && | |
667 | !sp.IsTangent()) | |
668 | { | |
669 | Rsnld.Root(UV); | |
670 | gp_Pnt2d Pmid(UV(1),UV(2)); | |
671 | gp_Vec2d P1P2(P2d1, P2d2); | |
672 | gp_Vec2d P1Pmid(P2d1, Pmid); | |
673 | gp_Vec2d P2Pmid(P2d2, Pmid); | |
674 | Standard_Real ScalProd1 = P1P2 * P1Pmid; | |
675 | Standard_Real ScalProd2 = P1P2 * P2Pmid; | |
676 | Standard_Boolean IsPmidValid = (ScalProd1 > 0. && ScalProd2 < 0); //Pmid is in the middle | |
677 | if (IsPmidValid) | |
678 | { | |
679 | for (Standard_Integer iline = 1; iline <= lines.Length(); iline++) | |
680 | if (IsPointOnLine(Pmid,iline)) | |
681 | { | |
682 | IsPmidValid = Standard_False; | |
683 | break; | |
684 | } | |
685 | } | |
686 | if (IsPmidValid) | |
687 | { | |
688 | IntSurf_InteriorPoint aPoint(sp.Point(), UV(1), UV(2), | |
689 | sp.Direction3d(), | |
690 | sp.Direction2d()); | |
691 | PntsInHoles.Append(aPoint); | |
692 | TColStd_ListOfInteger LineLine; | |
693 | LineLine.Append(Irang1); | |
694 | LineLine.Append(MinRang); | |
695 | PointLineLine.Bind(PntsInHoles.Length(), LineLine); | |
696 | } | |
697 | else | |
698 | { | |
699 | BadSolutions.Add(MinRang); | |
700 | i--; | |
701 | continue; | |
702 | } | |
703 | } | |
704 | else | |
705 | { | |
706 | BadSolutions.Add(MinRang); | |
707 | i--; | |
708 | continue; | |
709 | } | |
710 | } | |
711 | CopySeqAlone(i) = 0; | |
712 | CopySeqAlone(MinIndex) = 0; | |
713 | if (ToRemove) | |
714 | { | |
715 | SeqToRemove.Append(Irang1); | |
716 | SeqToRemove.Append(MinRang); | |
717 | } | |
718 | BadSolutions.Clear(); | |
719 | } | |
720 | ||
721 | for (Standard_Integer i = 1; i <= SeqToRemove.Length(); i++) | |
722 | for (Standard_Integer j = 1; j <= seqAlone.Length(); j++) | |
723 | if (seqAlone(j) == SeqToRemove(i)) | |
724 | { | |
725 | seqAlone.Remove(j); | |
726 | break; | |
727 | } | |
728 | } | |
729 | ||
7fd59977 | 730 | void IntWalk_IWalking::TestArretCadre |
731 | (const TColStd_SequenceOfReal& Umult, | |
732 | const TColStd_SequenceOfReal& Vmult, | |
733 | const Handle(IntWalk_TheIWLine)& Line, | |
734 | TheIWFunction& sp, | |
735 | math_Vector& UV, | |
736 | Standard_Integer& Irang) | |
737 | ||
b1c5c4e6 | 738 | // test of stop when located on border. |
739 | // tried all tests of stop and arrived. | |
740 | // test of stop on all given departure points already marked and on the entire current line. | |
741 | // This line can be shortened if the stop point is found. | |
742 | // Abs(Irang) = index in the iterator of departure points or 0 | |
743 | // if Irang <0 , it is necessary to add this point on the line (no Line->Cut) | |
744 | // UV = parameter of the departure point | |
7fd59977 | 745 | { |
746 | Standard_Real Scal, Up, Vp, Uc, Vc; | |
747 | Standard_Integer N; | |
748 | Standard_Boolean Found = Standard_False; | |
749 | ||
750 | ||
751 | Irang =0; | |
96a85238 RL |
752 | for (Standard_Integer i = 1; i < (int)wd1.size(); i++) { |
753 | if (wd1[i].etat < 0) { | |
b1c5c4e6 | 754 | N=0; // range in UVMult. |
96a85238 | 755 | if (nbMultiplicities[i] > 0) { |
7fd59977 | 756 | for (Standard_Integer k = 1; k < i; k++) |
96a85238 | 757 | N+=nbMultiplicities[k]; |
7fd59977 | 758 | } |
759 | if (!reversed) { | |
760 | Line->Value(1).ParametersOnS2(Up,Vp); | |
761 | } | |
762 | else { | |
763 | Line->Value(1).ParametersOnS1(Up,Vp); | |
764 | } | |
765 | Standard_Integer nbp= Line->NbPoints(); | |
766 | for (Standard_Integer j = 2; j <= nbp; j++) { | |
767 | if (!reversed) { | |
768 | Line->Value(j).ParametersOnS2(Uc,Vc); | |
769 | } | |
770 | else { | |
771 | Line->Value(j).ParametersOnS1(Uc,Vc); | |
772 | } | |
773 | ||
96a85238 RL |
774 | Scal = (Up-wd1[i].ustart) * (Uc-wd1[i].ustart) + |
775 | (Vp-wd1[i].vstart) * (Vc-wd1[i].vstart); | |
b1c5c4e6 | 776 | // if a stop point is found: stop the line on this point. |
7fd59977 | 777 | if (Scal < 0) { |
778 | Line->Cut(j); nbp= Line->NbPoints(); | |
779 | Irang = i; | |
96a85238 RL |
780 | UV(1) = wd1[Irang].ustart; |
781 | UV(2) = wd1[Irang].vstart; | |
7fd59977 | 782 | Found = Standard_True; |
783 | } | |
96a85238 RL |
784 | else if (Abs(Uc-wd1[i].ustart) < tolerance(1) && |
785 | Abs(Vc-wd1[i].vstart) < tolerance(2) ) { | |
7fd59977 | 786 | Line->Cut(j); nbp= Line->NbPoints(); |
787 | Irang=i; | |
96a85238 RL |
788 | UV(1) = wd1[Irang].ustart; |
789 | UV(2) = wd1[Irang].vstart; | |
7fd59977 | 790 | Found = Standard_True; |
791 | } | |
96a85238 RL |
792 | else if (nbMultiplicities[i] > 0) { |
793 | for (Standard_Integer k = N+1; k <= N + nbMultiplicities[i]; k++) { | |
7fd59977 | 794 | Scal = (Up-Umult(k)) * (Uc-Umult(k)) + |
795 | (Vp-Vmult(k)) * (Vc-Vmult(k)); | |
796 | if (Scal < 0) { | |
797 | Line->Cut(j); nbp= Line->NbPoints(); | |
798 | Irang=i; | |
96a85238 RL |
799 | UV(1) = wd1[Irang].ustart; |
800 | UV(2) = wd1[Irang].vstart; | |
7fd59977 | 801 | Found = Standard_True; |
802 | break; | |
803 | } | |
804 | else if (Abs(Uc-Umult(k)) < tolerance(1) && | |
805 | Abs(Vc-Vmult(k)) < tolerance(2)) { | |
806 | Line->Cut(j); nbp= Line->NbPoints(); | |
807 | Irang=i; | |
96a85238 RL |
808 | UV(1) = wd1[Irang].ustart; |
809 | UV(2) = wd1[Irang].vstart; | |
7fd59977 | 810 | Found = Standard_True; |
811 | break; | |
812 | } | |
813 | } | |
814 | } | |
815 | if (Found) { | |
1ef32e96 RL |
816 | Standard_Real abidF[1], abidD[1][2]; |
817 | math_Vector bidF(abidF,1,1); | |
818 | math_Matrix bidD(abidD,1,1,1,2); | |
6e6cd5d9 | 819 | sp.Values(UV,bidF,bidD); |
7fd59977 | 820 | Standard_Integer NBP = Line->NbPoints(); |
821 | Standard_Integer Indextg; | |
822 | Line->TangentVector(Indextg); | |
823 | if(Indextg > NBP) { | |
824 | if(j>3 && j<=NBP+1) { | |
825 | gp_Vec Dir3d = sp.Direction3d(); | |
826 | gp_Vec Dir3d1 = gp_Vec(Line->Value(j-2).Value(),Line->Value(j-1).Value()); | |
827 | Standard_Real dot = Dir3d.Dot(Dir3d1); | |
b1c5c4e6 | 828 | if(dot<0.0) { // Normally this Function should not be used often !!! |
7fd59977 | 829 | Dir3d.Reverse(); |
830 | //-- cout<<" IntWalk_IWalking_2.gxx REVERSE "<<endl; | |
831 | } | |
832 | Line->SetTangentVector(previousd3d,j-1); | |
833 | } | |
0797d9d3 | 834 | #ifdef OCCT_DEBUG |
7fd59977 | 835 | else { |
04232180 | 836 | std::cout<<" IntWalk_IWalking_2.gxx : bizarrerie 30 10 97 "<<std::endl; |
7fd59977 | 837 | } |
838 | #endif | |
839 | } | |
840 | ||
841 | return; | |
842 | } | |
843 | Up = Uc; | |
844 | Vp = Vc; | |
845 | } | |
846 | ||
b1c5c4e6 | 847 | // now the last point of the line and the last calculated point are compated. |
848 | // there will be no need to "Cut" | |
7fd59977 | 849 | |
96a85238 RL |
850 | Scal = (Up-wd1[i].ustart) * (UV(1)-wd1[i].ustart) + |
851 | // (Vp-wd1[i].vstart) * (UV(2)-wd1[i].vstart); | |
7fd59977 | 852 | // modified by NIZHNY-MKK Fri Oct 27 12:29:41 2000 |
96a85238 | 853 | (Vp-wd1[i].vstart) * (UV(2)-wd1[i].vstart); |
7fd59977 | 854 | |
855 | if (Scal < 0) { | |
856 | Irang = i; | |
96a85238 RL |
857 | UV(1) = wd1[Irang].ustart; |
858 | UV(2) = wd1[Irang].vstart; | |
7fd59977 | 859 | Found = Standard_True; |
860 | } | |
96a85238 RL |
861 | else if (Abs(UV(1)-wd1[i].ustart) < tolerance(1) && |
862 | Abs(UV(2)-wd1[i].vstart) < tolerance(2)) { | |
7fd59977 | 863 | Irang=i; |
96a85238 RL |
864 | UV(1) = wd1[Irang].ustart; |
865 | UV(2) = wd1[Irang].vstart; | |
7fd59977 | 866 | Found = Standard_True; |
867 | } | |
96a85238 RL |
868 | else if (nbMultiplicities[i] > 0) { |
869 | for (Standard_Integer j = N+1; j <= N+nbMultiplicities[i]; j++) { | |
7fd59977 | 870 | Scal = (Up-Umult(j)) * (UV(1)-Umult(j)) + |
871 | (Vp-Vmult(j)) * (UV(2)-Vmult(j)); | |
872 | if (Scal < 0) { | |
873 | Irang=i; | |
96a85238 RL |
874 | UV(1) = wd1[Irang].ustart; |
875 | UV(2) = wd1[Irang].vstart; | |
7fd59977 | 876 | Found = Standard_True; |
877 | break; | |
878 | } | |
879 | else if (Abs(UV(1)-Umult(j)) < tolerance(1) && | |
880 | Abs(UV(2)-Vmult(j)) < tolerance(2)) { | |
881 | Irang=i; | |
96a85238 RL |
882 | UV(1) = wd1[Irang].ustart; |
883 | UV(2) = wd1[Irang].vstart; | |
7fd59977 | 884 | Found = Standard_True; |
885 | break; | |
886 | } | |
887 | } | |
888 | } | |
889 | if (Found) { | |
890 | Irang = -Irang; // jag 941017 | |
1ef32e96 RL |
891 | Standard_Real abidF[1], abidD[1][2]; |
892 | math_Vector bidF(abidF,1,1); | |
893 | math_Matrix bidD(abidD,1,1,1,2); | |
6e6cd5d9 | 894 | sp.Values(UV,bidF,bidD); |
7fd59977 | 895 | return; |
896 | } | |
897 | } | |
898 | } | |
899 | } | |
900 | ||
901 |