1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
19 //-- IntWalk_IWalking_2.gxx
22 #define No_Standard_RangeError
23 #define No_Standard_OutOfRange
27 // _______________________________________________
29 // Location of point (u, v) in the natural domain of a surface AND update
30 // of couple (u, v) for the calculation of the next point.
32 Standard_Boolean IntWalk_IWalking::Cadrage
33 (math_Vector& BornInf,
37 // Standard_Real& StepV,
38 const Standard_Integer StepSign) const
41 // BorInf(1) <= UVap(1) <= BornSup(1) et BorInf(2) <= UVap(2) <= BornSup(2)
42 // 1) check if the process point is out of the natural domain of the surface.
43 // 2) if yes the approximated point is located on border taking the best direction
44 // the step and a limit blocating one of the parameters during the recent call of
45 // FunctionSetRoot are modified;
46 // 3) couple (u, v) is recomputed by approximation for the calculation of the next point.
47 // 4) return Standard_True if location, Standard_False if no location.
49 Standard_Real Duvx = previousd2d.X();
50 Standard_Real Duvy = previousd2d.Y();
53 previousPoint.ParametersOnS2(UVap(1),UVap(2));
56 previousPoint.ParametersOnS1(UVap(1),UVap(2));
59 Standard_Real U1 = UVap(1) + Step * Duvx * StepSign;
60 Standard_Real V1 = UVap(2) + Step * Duvy * StepSign;
63 Standard_Boolean infu = (U1 <= BornInf(1)+Precision::PConfusion());
64 Standard_Boolean supu = (U1 >= BornSup(1)-Precision::PConfusion());
65 Standard_Boolean infv = (V1 <= BornInf(2)+Precision::PConfusion());
66 Standard_Boolean supv = (V1 >= BornSup(2)-Precision::PConfusion());
68 Standard_Real theStepU,theStepV;
70 if (!infu && !supu && !infv && !supv) {
73 return Standard_False;
76 if ((infu || supu) && (infv || supv)) {
77 if (infu) { // jag 940616
79 theStepU = Abs((BornInf(1) - UVap(1)) / Duvx); // iso U =BornInf(1)
87 theStepU = Abs((BornSup(1) - UVap(1)) / Duvx); // iso U =BornSup(1)
93 if (infv) { // jag 940616
95 theStepV = Abs((BornInf(2) - UVap(2)) / Duvy); // iso V =BornInf(2)
103 theStepV = Abs((BornSup(2) - UVap(2)) / Duvy); // iso V =BornSup(2)
111 if (theStepU <= theStepV) {
114 UVap(1) = BornInf(1);
115 BornSup(1) = BornInf(1);
118 UVap(1) = BornSup(1);
119 BornInf(1) = BornSup(1);
121 UVap(2) += Step*Duvy*StepSign;
126 UVap(2) = BornInf(2);
127 BornSup(2) = BornInf(2);
130 UVap(2) = BornSup(2);
131 BornInf(2) = BornSup(2);
133 UVap(1) += Step*Duvx*StepSign;
135 return Standard_True;
138 else if (infu) { // jag 940616
140 Standard_Real aStep = Abs((BornInf(1) - UVap(1)) / Duvx); // iso U =BornInf(1)
141 if(aStep<Step) Step=aStep;
143 BornSup(1) = BornInf(1); // limit the parameter
144 UVap(1) = BornInf(1);
145 UVap(2) += Step*Duvy*StepSign;;
146 return Standard_True;
148 else if (supu) { // jag 940616
150 Standard_Real aStep = Abs((BornSup(1) - UVap(1)) / Duvx); // iso U =BornSup(1)
151 if(aStep<Step) Step=aStep;
153 BornInf(1) = BornSup(1); // limit the parameter
154 UVap(1) = BornSup(1);
155 UVap(2) += Step*Duvy*StepSign;
156 return Standard_True;
158 else if (infv) { // jag 940616
160 Standard_Real aStep = Abs((BornInf(2) - UVap(2)) / Duvy); // iso V =BornInf(2)
161 if(aStep<Step) Step=aStep;
163 BornSup(2) = BornInf(2);
164 UVap(1) += Step*Duvx*StepSign;
165 UVap(2) = BornInf(2);
166 return Standard_True;
168 else if (supv) { // jag 940616
170 Standard_Real aStep = Abs((BornSup(2) - UVap(2)) / Duvy); // iso V =BornSup(2)
171 if(aStep<Step) Step=aStep;
173 BornInf(2) = BornSup(2);
174 UVap(1) += Step*Duvx*StepSign;
175 UVap(2) = BornSup(2);
176 return Standard_True;
178 return Standard_True;
182 Standard_Boolean IntWalk_IWalking::TestArretPassage
183 (const TColStd_SequenceOfReal& Umult,
184 const TColStd_SequenceOfReal& Vmult,
187 Standard_Integer& Irang)
189 // Umult et Vmult : table of stop (or crossing) points on border,
190 // here only the crossing points are taken into account.
191 // UV : the current point.
192 // Irang : at exit : give index of the stop point in uvstart1 or 0.
193 // consider that there is no risk of crossing only if there is one crossing point.
196 // test of stop for an OPEN intersection line
197 // 1) crossing test on all interior points
198 // 2) stop test on all start points
199 // if a stop is detected, the index of the stop point (Irang) is returned
200 // in the iterator of start points and the associated parameters in UV space.
202 Standard_Real Up, Vp, Du, Dv, Dup, Dvp, Utest,Vtest;
203 Standard_Integer j, N, ind;
204 Standard_Real tolu = tolerance(1);
205 Standard_Real tolv = tolerance(2);
206 Standard_Real tolu2 = 10.*tolerance(1);
207 Standard_Real tolv2 = 10.*tolerance(2);
209 Standard_Boolean Arrive = Standard_False;
211 // crossing test on point that can start a loop; mark
212 // as processed if passes through an open line
215 previousPoint.ParametersOnS2(Up,Vp);
218 previousPoint.ParametersOnS1(Up,Vp);
221 for (size_t i = 1; i < wd2.size(); i++) {
222 if (wd2[i].etat > 0) {
223 // debug jag 05.04.94
225 // if ((Up-wd2[i].ustart)*(UV(1)-wd2[i].ustart) +
226 // (Vp-wd2[i].vstart)*(UV(2)-wd2[i].vstart) <= 0)
227 Utest = wd2[i].ustart;
228 Vtest = wd2[i].vstart;
235 //-- lbr le 30 oct 97
239 if ((Abs(Du) < tolu2 && Abs(Dv) < tolv2) ||
240 (Abs(Dup) < tolu2 && Abs(Dvp) < tolv2)) {
242 wd2[i].etat = -wd2[i].etat;
245 Standard_Real DDu = (UV(1)-Up);
246 Standard_Real DDv = (UV(2)-Vp);
247 Standard_Real DDD = DDu*DDu+DDv*DDv;
248 Standard_Real DD1 = Du*Du+Dv*Dv;
250 Standard_Real DD2 = Dup*Dup+Dvp*Dvp;
251 if(DD2<=DDD && ((Du*Dup) + (Dv*Dvp*tolu/tolv) <= 0.)) {
252 wd2[i].etat = -wd2[i].etat;
259 // stop test on point given at input and not yet processed
261 // Modified by Sergey KHROMOV - Tue Nov 20 10:55:01 2001 Begin
262 // Check of all path points in the following order:
263 // * First check all not treated points;
264 // * After that check of already treated ones.
267 //// Modified by jgv, 28.07.2010 for OCC21914 ////
268 // There are several path points between (Up,Vp) and UV
269 // So several path points satisfy the condition
270 // Dup*UV1mUtest + Dvp*UV2mVtest) < 0
271 // We choose from them the path point with
272 // minimum distance to (Up,Vp)
273 TColStd_SequenceOfInteger i_candidates;
274 TColStd_SequenceOfReal SqDist_candidates;
276 for (l = 1; l <= 2 && !Arrive; l++) {
277 Standard_Boolean isToCheck;
279 for (size_t i = 1; i < wd1.size(); i++) {
281 isToCheck = (wd1[i].etat > 0);
283 isToCheck = (wd1[i].etat < 0);
286 // Modified by Sergey KHROMOV - Tue Nov 20 11:03:16 2001 End
288 // debug jag voir avec isg
290 Utest = wd1[i].ustart;
291 Vtest = wd1[i].vstart;
294 if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) {
295 Standard_Real UV1mUtest = UV(1)-Utest;
296 Standard_Real UV2mVtest = UV(2)-Vtest;
297 if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) ||
298 ( Abs(UV1mUtest) < tolu
299 && Abs(UV2mVtest) < tolv)) {
300 i_candidates.Append((Standard_Integer)i);
301 SqDist_candidates.Append(Dup*Dup + Dvp*Dvp);
304 Arrive = Standard_True;
309 else if (nbMultiplicities[i] > 0 && i_candidates.IsEmpty()) {
311 for (size_t k = 1; k < i; k++) {
312 N+=nbMultiplicities[k];
314 for (j = N + 1; j <= N + nbMultiplicities[i]; j++) {
315 if (((Up-Umult(j))*(UV(1)-Umult(j)) +
316 (Vp-Vmult(j))*(UV(2)-Vmult(j)) < 0) ||
317 (Abs(UV(1)-Umult(j)) < tolu &&
318 Abs(UV(2)-Vmult(j)) < tolv)) {
319 Irang=(Standard_Integer)i;
320 Arrive = Standard_True;
328 Standard_Real abidF[1], abidD[1][2];
329 math_Vector bidF(abidF,1,1);
330 math_Matrix bidD(abidD,1,1,1,2);
331 sp.Values(UV,bidF,bidD);
336 } //end of for (i = 1; i < wd1.size(); i++)
337 if (!i_candidates.IsEmpty())
339 Standard_Real MinSqDist = RealLast();
340 for (ind = 1; ind <= i_candidates.Length(); ind++)
341 if (SqDist_candidates(ind) < MinSqDist)
343 MinSqDist = SqDist_candidates(ind);
344 Irang = i_candidates(ind);
346 Arrive = Standard_True;
347 UV(1) = wd1[Irang].ustart;
348 UV(2) = wd1[Irang].vstart;
350 } //end of for (l = 1; l <= 2 && !Arrive; l++)
354 Standard_Boolean IntWalk_IWalking::TestArretPassage
355 (const TColStd_SequenceOfReal& Umult,
356 const TColStd_SequenceOfReal& Vmult,
357 const math_Vector& UV,
358 const Standard_Integer Index,
359 Standard_Integer& Irang)
361 // Umult, Vmult : table of stop (or crossing) points on border, here
362 // only crossing points are taken into account.
363 // UV : the current point.
364 // Index : index of the start point in uvstart2 of the current line
365 // (this is an interior point).
366 // Irang : at output : gives the index of the point passing in uvstart1 or 0.
367 // consider that there is risk to cross only one crossing point.
369 // test of stop for a CLOSED intersection line.
370 // 1) test of crossing on all interior points.
371 // 2) test of crossing on all crossing points.
373 Standard_Real Up, Vp, Scal;
374 Standard_Boolean Arrive = Standard_False;
375 Standard_Integer N, k, i;
376 Standard_Real Utest,Vtest;
377 Standard_Real tolu = tolerance(1);
378 Standard_Real tolv = tolerance(2);
381 // tests of stop and of crossing on all interior points.
384 previousPoint.ParametersOnS2(Up,Vp);
387 previousPoint.ParametersOnS1(Up,Vp);
390 Standard_Real UV1=UV(1);
391 Standard_Real UV2=UV(2);
394 //-- Put everything in one box 0 1 x 0 1
395 //-- actually it is necessary to carry out tests in 3D
397 Standard_Real deltau=UM-Um;
398 Standard_Real deltav=VM-Vm;
400 Up/=deltau; UV1/=deltau;
401 Vp/=deltav; UV2/=deltav;
406 Standard_Real tolu2=tolu+tolu;
407 Standard_Real tolv2=tolv+tolv;
410 Standard_Real dPreviousCurrent = (Up-UV1)*(Up-UV1)+(Vp-UV2)*(Vp-UV2);
411 for (k = 1; k < (int)wd2.size(); k++) {
412 if (wd2[k].etat > 0) {
413 Utest = wd2[k].ustart;
414 Vtest = wd2[k].vstart;
419 Standard_Real UV1mUtest=UV1-Utest;
420 Standard_Real UV2mVtest=UV2-Vtest;
421 if( (UV1mUtest<tolu2 && UV1mUtest>-tolu2)
422 && (UV2mVtest<tolv2 && UV2mVtest>-tolv2)) {
424 //-- cout<<"* etat2 : ("<<k<<")"<<endl;
425 wd2[k].etat=-wd2[k].etat; //-- mark the point as a crossing point
427 else { //-- Index == k
428 //-- cout<<"* Arrive"<<endl;
429 Arrive=Standard_True;
433 Standard_Real UpmUtest = (Up-Utest);
434 Standard_Real VpmVtest = (Vp-Vtest);
435 Standard_Real dPreviousStart = (UpmUtest)*(UpmUtest)+(VpmVtest)*(VpmVtest);
436 Standard_Real dCurrentStart = UV1mUtest * UV1mUtest + UV2mVtest * UV2mVtest;
438 Scal=(UpmUtest)*(UV1mUtest)+(VpmVtest)*(UV2mVtest);
439 if( (Abs(UpmUtest)<tolu && Abs(VpmVtest)<tolv)) {
441 //-- cout<<"** etat2 : ("<<k<<")"<<endl;
442 wd2[k].etat = -wd2[k].etat;
445 else if(Scal<0 && (dPreviousStart+dCurrentStart < dPreviousCurrent)) {
446 if (Index == k ) { // on a boucle.
447 Arrive = Standard_True;
448 //-- cout<<"** Arrive : k="<<k<<endl;
451 //-- cout<<"*** etat2 : ("<<k<<")"<<endl;
452 wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point
456 if(dPreviousStart < dPreviousCurrent*0.25) {
457 wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point
458 //-- cout<<"**** etat2 : ("<<k<<")"<<endl;
461 if(dCurrentStart < dPreviousCurrent*0.25) {
462 //-- cout<<"***** etat2 : ("<<k<<")"<<endl;
463 wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point
466 Standard_Real UMidUtest = 0.5*(UV1+Up)-Utest;
467 Standard_Real VMidVtest = 0.5*(UV2+Vp)-Vtest;
468 Standard_Real dMiddleStart = UMidUtest* UMidUtest+VMidVtest*VMidVtest;
470 if(dMiddleStart < dPreviousCurrent*0.5) {
471 //-- cout<<"*********** etat2 : ("<<k<<")"<<endl;
472 wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point
481 // crossing test on crossing points.
484 for (i = 1; i < (int)wd1.size(); i++) {
485 if (wd1[i].etat > 0 && wd1[i].etat < 11) { //test of crossing points
486 Utest = wd1[i].ustart;
487 Vtest = wd1[i].vstart;
491 if (((Up-Utest) * (UV1-Utest) + (Vp-Vtest) * (UV2-Vtest) < 0) ||
492 (Abs(UV1-Utest) < tolu && Abs(UV2-Vtest) < tolv))
494 else if (nbMultiplicities[i] > 0) {
496 for (k = 1; k < i; k++) N = N + nbMultiplicities[k];
497 for (Standard_Integer j = N + 1; j <= N + nbMultiplicities[i]; j++) {
498 Standard_Real Umultj = Umult(j)/deltau;
499 Standard_Real Vmultj = Vmult(j)/deltav;
500 if (((Up-Umultj)*(UV1-Umultj) +
501 (Vp-Vmultj)*(UV2-Vmultj) < 0) ||
502 (Abs(UV1-Umultj) < tolu &&
503 Abs(UV2-Vmultj) < tolv)) {
515 Standard_Boolean IntWalk_IWalking::TestArretAjout
518 Standard_Integer& Irang,
519 IntSurf_PntOn2S& Psol)
521 // test of stop on added points
522 // these are the points on the natural biorder that were not given at input
523 // return : Psol, the added point.
524 // Irang, index in the iterator of added points.
525 // UV, parameter of the added point.
528 Standard_Boolean Arrive = Standard_False;
533 previousPoint.ParametersOnS2(Up,Vp);
536 previousPoint.ParametersOnS1(Up,Vp);
539 Standard_Integer nbAjout = seqAjout.Length();
540 for (Standard_Integer i = 1; i <= nbAjout; i++) {
541 Irang = seqAjout.Value(i);
543 // add test Abs(Irang) <= lines.Length() for the case when
544 // a closed line is opened by adding a 1 point on this same
545 // line. Anyway there is a huge problem as 2 points will be
546 // added on this line...
548 if (Abs(Irang) <= lines.Length()) {
550 const Handle(IntWalk_TheIWLine)& Line = lines.Value(Abs(Irang));
552 Psol = Line->Value(Line->NbPoints());
554 Psol = Line->Value(1);
556 Psol.ParametersOnS2(U1, V1);
559 Psol.ParametersOnS1(U1, V1);
561 if (((Up-U1) * (UV(1)-U1) +
562 (Vp-V1) * (UV(2)-V1)) < 0 ||
563 (Abs(UV(1)-U1) < tolerance(1) &&
564 Abs(UV(2)-V1) < tolerance(2))) {
565 //jag 940615 Irang= -Abs(Irang);
566 Arrive = Standard_True;
569 Standard_Real abidF[1], abidD[1][2];
570 math_Vector bidF(abidF,1,1);
571 math_Matrix bidD(abidD,1,1,1,2);
572 sp.Values(UV,bidF,bidD);
580 void IntWalk_IWalking::TestArretCadre
581 (const TColStd_SequenceOfReal& Umult,
582 const TColStd_SequenceOfReal& Vmult,
583 const Handle(IntWalk_TheIWLine)& Line,
586 Standard_Integer& Irang)
588 // test of stop when located on border.
589 // tried all tests of stop and arrived.
590 // test of stop on all given departure points already marked and on the entire current line.
591 // This line can be shortened if the stop point is found.
592 // Abs(Irang) = index in the iterator of departure points or 0
593 // if Irang <0 , it is necessary to add this point on the line (no Line->Cut)
594 // UV = parameter of the departure point
596 Standard_Real Scal, Up, Vp, Uc, Vc;
598 Standard_Boolean Found = Standard_False;
602 for (Standard_Integer i = 1; i < (int)wd1.size(); i++) {
603 if (wd1[i].etat < 0) {
604 N=0; // range in UVMult.
605 if (nbMultiplicities[i] > 0) {
606 for (Standard_Integer k = 1; k < i; k++)
607 N+=nbMultiplicities[k];
610 Line->Value(1).ParametersOnS2(Up,Vp);
613 Line->Value(1).ParametersOnS1(Up,Vp);
615 Standard_Integer nbp= Line->NbPoints();
616 for (Standard_Integer j = 2; j <= nbp; j++) {
618 Line->Value(j).ParametersOnS2(Uc,Vc);
621 Line->Value(j).ParametersOnS1(Uc,Vc);
624 Scal = (Up-wd1[i].ustart) * (Uc-wd1[i].ustart) +
625 (Vp-wd1[i].vstart) * (Vc-wd1[i].vstart);
626 // if a stop point is found: stop the line on this point.
628 Line->Cut(j); nbp= Line->NbPoints();
630 UV(1) = wd1[Irang].ustart;
631 UV(2) = wd1[Irang].vstart;
632 Found = Standard_True;
634 else if (Abs(Uc-wd1[i].ustart) < tolerance(1) &&
635 Abs(Vc-wd1[i].vstart) < tolerance(2) ) {
636 Line->Cut(j); nbp= Line->NbPoints();
638 UV(1) = wd1[Irang].ustart;
639 UV(2) = wd1[Irang].vstart;
640 Found = Standard_True;
642 else if (nbMultiplicities[i] > 0) {
643 for (Standard_Integer k = N+1; k <= N + nbMultiplicities[i]; k++) {
644 Scal = (Up-Umult(k)) * (Uc-Umult(k)) +
645 (Vp-Vmult(k)) * (Vc-Vmult(k));
647 Line->Cut(j); nbp= Line->NbPoints();
649 UV(1) = wd1[Irang].ustart;
650 UV(2) = wd1[Irang].vstart;
651 Found = Standard_True;
654 else if (Abs(Uc-Umult(k)) < tolerance(1) &&
655 Abs(Vc-Vmult(k)) < tolerance(2)) {
656 Line->Cut(j); nbp= Line->NbPoints();
658 UV(1) = wd1[Irang].ustart;
659 UV(2) = wd1[Irang].vstart;
660 Found = Standard_True;
666 Standard_Real abidF[1], abidD[1][2];
667 math_Vector bidF(abidF,1,1);
668 math_Matrix bidD(abidD,1,1,1,2);
669 sp.Values(UV,bidF,bidD);
670 Standard_Integer NBP = Line->NbPoints();
671 Standard_Integer Indextg;
672 Line->TangentVector(Indextg);
674 if(j>3 && j<=NBP+1) {
675 gp_Vec Dir3d = sp.Direction3d();
676 gp_Vec Dir3d1 = gp_Vec(Line->Value(j-2).Value(),Line->Value(j-1).Value());
677 Standard_Real dot = Dir3d.Dot(Dir3d1);
678 if(dot<0.0) { // Normally this Function should not be used often !!!
680 //-- cout<<" IntWalk_IWalking_2.gxx REVERSE "<<endl;
682 Line->SetTangentVector(previousd3d,j-1);
686 cout<<" IntWalk_IWalking_2.gxx : bizarrerie 30 10 97 "<<endl;
697 // now the last point of the line and the last calculated point are compated.
698 // there will be no need to "Cut"
700 Scal = (Up-wd1[i].ustart) * (UV(1)-wd1[i].ustart) +
701 // (Vp-wd1[i].vstart) * (UV(2)-wd1[i].vstart);
702 // modified by NIZHNY-MKK Fri Oct 27 12:29:41 2000
703 (Vp-wd1[i].vstart) * (UV(2)-wd1[i].vstart);
707 UV(1) = wd1[Irang].ustart;
708 UV(2) = wd1[Irang].vstart;
709 Found = Standard_True;
711 else if (Abs(UV(1)-wd1[i].ustart) < tolerance(1) &&
712 Abs(UV(2)-wd1[i].vstart) < tolerance(2)) {
714 UV(1) = wd1[Irang].ustart;
715 UV(2) = wd1[Irang].vstart;
716 Found = Standard_True;
718 else if (nbMultiplicities[i] > 0) {
719 for (Standard_Integer j = N+1; j <= N+nbMultiplicities[i]; j++) {
720 Scal = (Up-Umult(j)) * (UV(1)-Umult(j)) +
721 (Vp-Vmult(j)) * (UV(2)-Vmult(j));
724 UV(1) = wd1[Irang].ustart;
725 UV(2) = wd1[Irang].vstart;
726 Found = Standard_True;
729 else if (Abs(UV(1)-Umult(j)) < tolerance(1) &&
730 Abs(UV(2)-Vmult(j)) < tolerance(2)) {
732 UV(1) = wd1[Irang].ustart;
733 UV(2) = wd1[Irang].vstart;
734 Found = Standard_True;
740 Irang = -Irang; // jag 941017
741 Standard_Real abidF[1], abidD[1][2];
742 math_Vector bidF(abidF,1,1);
743 math_Matrix bidD(abidD,1,1,1,2);
744 sp.Values(UV,bidF,bidD);