0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[occt.git] / src / IntWalk / IntWalk_IWalking_2.gxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
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//
31Standard_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
181Standard_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
353Standard_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
513Standard_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 578void 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 730void 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