Warning, /include/opencascade/IntWalk_IWalking_2.gxx is written in an unsupported language. File is not indexed.
0001 // Copyright (c) 1995-1999 Matra Datavision
0002 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014
0015 //-- IntWalk_IWalking_2.gxx
0016
0017 #include <Bnd_Range.hxx>
0018 #include <TColStd_MapOfInteger.hxx>
0019
0020 #ifndef OCCT_DEBUG
0021 #define No_Standard_RangeError
0022 #define No_Standard_OutOfRange
0023 #endif
0024
0025 static void CutVectorByTolerances (gp_Vec2d& theVector,
0026 const math_Vector& theTolerance)
0027 {
0028 if (Abs(theVector.X()) < theTolerance(1))
0029 theVector.SetX (0.);
0030 if (Abs(theVector.Y()) < theTolerance(2))
0031 theVector.SetY (0.);
0032 }
0033
0034 // _______________________________________________
0035 //
0036 // Location of point (u, v) in the natural domain of a surface AND update
0037 // of couple (u, v) for the calculation of the next point.
0038 //
0039 Standard_Boolean IntWalk_IWalking::Cadrage
0040 (math_Vector& BornInf,
0041 math_Vector& BornSup,
0042 math_Vector& UVap,
0043 Standard_Real& Step,
0044 // Standard_Real& StepV,
0045 const Standard_Integer StepSign) const
0046
0047 // there are always :
0048 // BorInf(1) <= UVap(1) <= BornSup(1) et BorInf(2) <= UVap(2) <= BornSup(2)
0049 // 1) check if the process point is out of the natural domain of the surface.
0050 // 2) if yes the approximated point is located on border taking the best direction
0051 // the step and a limit blocating one of the parameters during the recent call of
0052 // FunctionSetRoot are modified;
0053 // 3) couple (u, v) is recomputed by approximation for the calculation of the next point.
0054 // 4) return Standard_True if location, Standard_False if no location.
0055 {
0056 Standard_Real Duvx = previousd2d.X();
0057 Standard_Real Duvy = previousd2d.Y();
0058
0059 if (!reversed) {
0060 previousPoint.ParametersOnS2(UVap(1),UVap(2));
0061 }
0062 else {
0063 previousPoint.ParametersOnS1(UVap(1),UVap(2));
0064 }
0065
0066 Standard_Real U1 = UVap(1) + Step * Duvx * StepSign;
0067 Standard_Real V1 = UVap(2) + Step * Duvy * StepSign;
0068
0069
0070 Standard_Boolean infu = (U1 <= BornInf(1)+Precision::PConfusion());
0071 Standard_Boolean supu = (U1 >= BornSup(1)-Precision::PConfusion());
0072 Standard_Boolean infv = (V1 <= BornInf(2)+Precision::PConfusion());
0073 Standard_Boolean supv = (V1 >= BornSup(2)-Precision::PConfusion());
0074
0075 Standard_Real theStepU,theStepV;
0076
0077 if (!infu && !supu && !infv && !supv) {
0078 UVap(1) = U1;
0079 UVap(2) = V1;
0080 return Standard_False;
0081 }
0082
0083 if ((infu || supu) && (infv || supv)) {
0084 if (infu) { // jag 940616
0085 if(Duvx) {
0086 theStepU = Abs((BornInf(1) - UVap(1)) / Duvx); // iso U =BornInf(1)
0087 }
0088 else {
0089 theStepU = Step;
0090 }
0091 }
0092 else {
0093 if(Duvx) {
0094 theStepU = Abs((BornSup(1) - UVap(1)) / Duvx); // iso U =BornSup(1)
0095 }
0096 else {
0097 theStepU = Step;
0098 }
0099 }
0100 if (infv) { // jag 940616
0101 if(Duvy) {
0102 theStepV = Abs((BornInf(2) - UVap(2)) / Duvy); // iso V =BornInf(2)
0103 }
0104 else {
0105 theStepV = Step;
0106 }
0107 }
0108 else {
0109 if(Duvy) {
0110 theStepV = Abs((BornSup(2) - UVap(2)) / Duvy); // iso V =BornSup(2)
0111 }
0112 else {
0113 theStepV = Step;
0114 }
0115 }
0116
0117
0118 if (theStepU <= theStepV) {
0119 Step = theStepU;
0120 if (infu) {
0121 UVap(1) = BornInf(1);
0122 BornSup(1) = BornInf(1);
0123 }
0124 else {
0125 UVap(1) = BornSup(1);
0126 BornInf(1) = BornSup(1);
0127 }
0128 UVap(2) += Step*Duvy*StepSign;
0129 }
0130 else {
0131 Step = theStepV;
0132 if (infv) {
0133 UVap(2) = BornInf(2);
0134 BornSup(2) = BornInf(2);
0135 }
0136 else {
0137 UVap(2) = BornSup(2);
0138 BornInf(2) = BornSup(2);
0139 }
0140 UVap(1) += Step*Duvx*StepSign;
0141 }
0142 return Standard_True;
0143 }
0144
0145 else if (infu) { // jag 940616
0146 if(Duvx) {
0147 Standard_Real aStep = Abs((BornInf(1) - UVap(1)) / Duvx); // iso U =BornInf(1)
0148 if(aStep<Step) Step=aStep;
0149 }
0150 BornSup(1) = BornInf(1); // limit the parameter
0151 UVap(1) = BornInf(1);
0152 UVap(2) += Step*Duvy*StepSign;
0153 return Standard_True;
0154 }
0155 else if (supu) { // jag 940616
0156 if(Duvx) {
0157 Standard_Real aStep = Abs((BornSup(1) - UVap(1)) / Duvx); // iso U =BornSup(1)
0158 if(aStep<Step) Step=aStep;
0159 }
0160 BornInf(1) = BornSup(1); // limit the parameter
0161 UVap(1) = BornSup(1);
0162 UVap(2) += Step*Duvy*StepSign;
0163 return Standard_True;
0164 }
0165 else if (infv) { // jag 940616
0166 if(Duvy) {
0167 Standard_Real aStep = Abs((BornInf(2) - UVap(2)) / Duvy); // iso V =BornInf(2)
0168 if(aStep<Step) Step=aStep;
0169 }
0170 BornSup(2) = BornInf(2);
0171 UVap(1) += Step*Duvx*StepSign;
0172 UVap(2) = BornInf(2);
0173 return Standard_True;
0174 }
0175 else if (supv) { // jag 940616
0176 if(Duvy) {
0177 Standard_Real aStep = Abs((BornSup(2) - UVap(2)) / Duvy); // iso V =BornSup(2)
0178 if(aStep<Step) Step=aStep;
0179 }
0180 BornInf(2) = BornSup(2);
0181 UVap(1) += Step*Duvx*StepSign;
0182 UVap(2) = BornSup(2);
0183 return Standard_True;
0184 }
0185 return Standard_True;
0186 }
0187
0188
0189 Standard_Boolean IntWalk_IWalking::TestArretPassage
0190 (const TColStd_SequenceOfReal& Umult,
0191 const TColStd_SequenceOfReal& Vmult,
0192 TheIWFunction& sp,
0193 math_Vector& UV,
0194 Standard_Integer& Irang)
0195
0196 // Umult et Vmult : table of stop (or crossing) points on border,
0197 // here only the crossing points are taken into account.
0198 // UV : the current point.
0199 // Irang : at exit : give index of the stop point in uvstart1 or 0.
0200 // consider that there is no risk of crossing only if there is one crossing point.
0201
0202
0203 // test of stop for an OPEN intersection line
0204 // 1) crossing test on all interior points
0205 // 2) stop test on all start points
0206 // if a stop is detected, the index of the stop point (Irang) is returned
0207 // in the iterator of start points and the associated parameters in UV space.
0208 {
0209 Standard_Real Up, Vp, Du, Dv, Dup, Dvp, Utest,Vtest;
0210 Standard_Integer j, N, ind;
0211 Standard_Real tolu = tolerance(1);
0212 Standard_Real tolv = tolerance(2);
0213 Standard_Real tolu2 = 10.*tolerance(1);
0214 Standard_Real tolv2 = 10.*tolerance(2);
0215
0216 Standard_Boolean Arrive = Standard_False;
0217
0218 // crossing test on point that can start a loop; mark
0219 // as processed if passes through an open line
0220
0221 if (!reversed) {
0222 previousPoint.ParametersOnS2(Up,Vp);
0223 }
0224 else {
0225 previousPoint.ParametersOnS1(Up,Vp);
0226 }
0227
0228 for (size_t i = 1; i < wd2.size(); i++) {
0229 if (wd2[i].etat > 0) {
0230 // debug jag 05.04.94
0231
0232 // if ((Up-wd2[i].ustart)*(UV(1)-wd2[i].ustart) +
0233 // (Vp-wd2[i].vstart)*(UV(2)-wd2[i].vstart) <= 0)
0234 Utest = wd2[i].ustart;
0235 Vtest = wd2[i].vstart;
0236
0237 Du = UV(1)-Utest;
0238 Dv = UV(2)-Vtest;
0239 Dup = Up - Utest;
0240 Dvp = Vp - Vtest;
0241
0242 //-- lbr le 30 oct 97
0243
0244 //IFV for OCC20285
0245
0246 if ((Abs(Du) < tolu2 && Abs(Dv) < tolv2) ||
0247 (Abs(Dup) < tolu2 && Abs(Dvp) < tolv2)) {
0248
0249 wd2[i].etat = -wd2[i].etat;
0250 }
0251 else {
0252 Standard_Real DDu = (UV(1)-Up);
0253 Standard_Real DDv = (UV(2)-Vp);
0254 Standard_Real DDD = DDu*DDu+DDv*DDv;
0255 Standard_Real DD1 = Du*Du+Dv*Dv;
0256 if(DD1<=DDD) {
0257 Standard_Real DD2 = Dup*Dup+Dvp*Dvp;
0258 if(DD2<=DDD && ((Du*Dup) + (Dv*Dvp*tolu/tolv) <= 0.)) {
0259 wd2[i].etat = -wd2[i].etat;
0260 }
0261 }
0262 }
0263 }
0264 }
0265
0266 // stop test on point given at input and not yet processed
0267
0268 // Modified by Sergey KHROMOV - Tue Nov 20 10:55:01 2001 Begin
0269 // Check of all path points in the following order:
0270 // * First check all not treated points;
0271 // * After that check of already treated ones.
0272 Standard_Integer l;
0273
0274 //// Modified by jgv, 28.07.2010 for OCC21914 ////
0275 // There are several path points between (Up,Vp) and UV
0276 // So several path points satisfy the condition
0277 // Dup*UV1mUtest + Dvp*UV2mVtest) < 0
0278 // We choose from them the path point with
0279 // minimum distance to (Up,Vp)
0280 TColStd_SequenceOfInteger i_candidates;
0281 TColStd_SequenceOfReal SqDist_candidates;
0282
0283 for (l = 1; l <= 2 && !Arrive; l++) {
0284 Standard_Boolean isToCheck;
0285
0286 for (size_t i = 1; i < wd1.size(); i++) {
0287 if (l == 1)
0288 isToCheck = (wd1[i].etat > 0);
0289 else
0290 isToCheck = (wd1[i].etat < 0);
0291
0292 if (isToCheck) {
0293 // Modified by Sergey KHROMOV - Tue Nov 20 11:03:16 2001 End
0294
0295 // debug jag voir avec isg
0296
0297 Utest = wd1[i].ustart;
0298 Vtest = wd1[i].vstart;
0299 Dup = Up - Utest;
0300 Dvp = Vp - Vtest;
0301 if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) {
0302 Standard_Real UV1mUtest = UV(1)-Utest;
0303 Standard_Real UV2mVtest = UV(2)-Vtest;
0304 if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) ||
0305 ( Abs(UV1mUtest) < tolu
0306 && Abs(UV2mVtest) < tolv)) {
0307 i_candidates.Append((Standard_Integer)i);
0308 SqDist_candidates.Append(Dup*Dup + Dvp*Dvp);
0309 /*
0310 Irang=i;
0311 Arrive = Standard_True;
0312 UV(1) = Utest;
0313 UV(2) = Vtest;
0314 */
0315 }
0316 else if (nbMultiplicities[i] > 0 && i_candidates.IsEmpty()) {
0317 N=0;
0318 for (size_t k = 1; k < i; k++) {
0319 N+=nbMultiplicities[k];
0320 }
0321 for (j = N + 1; j <= N + nbMultiplicities[i]; j++) {
0322 if (((Up-Umult(j))*(UV(1)-Umult(j)) +
0323 (Vp-Vmult(j))*(UV(2)-Vmult(j)) < 0) ||
0324 (Abs(UV(1)-Umult(j)) < tolu &&
0325 Abs(UV(2)-Vmult(j)) < tolv)) {
0326 Irang=(Standard_Integer)i;
0327 Arrive = Standard_True;
0328 UV(1) = Utest;
0329 UV(2) = Vtest;
0330 break;
0331 }
0332 }
0333 }
0334 if (Arrive) {
0335 Standard_Real abidF[1], abidD[1][2];
0336 math_Vector bidF(abidF,1,1);
0337 math_Matrix bidD(abidD,1,1,1,2);
0338 sp.Values(UV,bidF,bidD);
0339 break;
0340 }
0341 }
0342 }
0343 } //end of for (i = 1; i < wd1.size(); i++)
0344 if (!i_candidates.IsEmpty())
0345 {
0346 Standard_Real MinSqDist = RealLast();
0347 for (ind = 1; ind <= i_candidates.Length(); ind++)
0348 if (SqDist_candidates(ind) < MinSqDist)
0349 {
0350 MinSqDist = SqDist_candidates(ind);
0351 Irang = i_candidates(ind);
0352 }
0353 Arrive = Standard_True;
0354 UV(1) = wd1[Irang].ustart;
0355 UV(2) = wd1[Irang].vstart;
0356 }
0357 } //end of for (l = 1; l <= 2 && !Arrive; l++)
0358 return Arrive;
0359 }
0360
0361 Standard_Boolean IntWalk_IWalking::TestArretPassage
0362 (const TColStd_SequenceOfReal& Umult,
0363 const TColStd_SequenceOfReal& Vmult,
0364 const math_Vector& UV,
0365 const Standard_Integer Index,
0366 Standard_Integer& Irang)
0367 {
0368 // Umult, Vmult : table of stop (or crossing) points on border, here
0369 // only crossing points are taken into account.
0370 // UV : the current point.
0371 // Index : index of the start point in uvstart2 of the current line
0372 // (this is an interior point).
0373 // Irang : at output : gives the index of the point passing in uvstart1 or 0.
0374 // consider that there is risk to cross only one crossing point.
0375
0376 // test of stop for a CLOSED intersection line.
0377 // 1) test of crossing on all interior points.
0378 // 2) test of crossing on all crossing points.
0379
0380 Standard_Real Up, Vp, Scal;
0381 Standard_Boolean Arrive = Standard_False;
0382 Standard_Integer N, k, i;
0383 Standard_Real Utest,Vtest;
0384 Standard_Real tolu = tolerance(1);
0385 Standard_Real tolv = tolerance(2);
0386
0387
0388 // tests of stop and of crossing on all interior points.
0389
0390 if (!reversed) {
0391 previousPoint.ParametersOnS2(Up,Vp);
0392 }
0393 else {
0394 previousPoint.ParametersOnS1(Up,Vp);
0395 }
0396
0397 Standard_Real UV1=UV(1);
0398 Standard_Real UV2=UV(2);
0399
0400
0401 //Normalizing factor. If it is less than 1.0 then the range will be expanded.
0402 //This is no good for computation. Therefore, it is limited.
0403 //Do not limit this factor in case of highly anisotropic parametrization
0404 //(parametric space is considerably larger in one direction than another).
0405 const Standard_Boolean isHighlyAnisotropic = Max(tolu, tolv) > 1000. * Min(tolu, tolv);
0406 const Standard_Real deltau = mySRangeU.IsVoid() ? UM - Um
0407 : (isHighlyAnisotropic ? mySRangeU.Delta()
0408 : Max(mySRangeU.Delta(), 1.0));
0409 const Standard_Real deltav = mySRangeV.IsVoid() ? VM - Vm
0410 : (isHighlyAnisotropic ? mySRangeV.Delta()
0411 : Max(mySRangeV.Delta(), 1.0));
0412
0413 Up/=deltau; UV1/=deltau;
0414 Vp/=deltav; UV2/=deltav;
0415
0416 tolu/=deltau;
0417 tolv/=deltav;
0418
0419 Standard_Real tolu2=tolu+tolu;
0420 Standard_Real tolv2=tolv+tolv;
0421
0422
0423 Standard_Real dPreviousCurrent = (Up-UV1)*(Up-UV1)+(Vp-UV2)*(Vp-UV2);
0424 for (k = 1; k < (int)wd2.size(); k++) {
0425 if (wd2[k].etat > 0) {
0426 Utest = wd2[k].ustart;
0427 Vtest = wd2[k].vstart;
0428
0429 Utest/=deltau;
0430 Vtest/=deltav;
0431
0432 Standard_Real UV1mUtest=UV1-Utest;
0433 Standard_Real UV2mVtest=UV2-Vtest;
0434 if( (UV1mUtest<tolu2 && UV1mUtest>-tolu2)
0435 && (UV2mVtest<tolv2 && UV2mVtest>-tolv2)) {
0436 if(Index!=k) {
0437 //-- cout<<"* etat2 : ("<<k<<")"<<endl;
0438 wd2[k].etat=-wd2[k].etat; //-- mark the point as a crossing point
0439 }
0440 else { //-- Index == k
0441 //-- cout<<"* Arrive"<<endl;
0442 Arrive=Standard_True;
0443 }
0444 }
0445 else {
0446 Standard_Real UpmUtest = (Up-Utest);
0447 Standard_Real VpmVtest = (Vp-Vtest);
0448 Standard_Real dPreviousStart = (UpmUtest)*(UpmUtest)+(VpmVtest)*(VpmVtest);
0449 Standard_Real dCurrentStart = UV1mUtest * UV1mUtest + UV2mVtest * UV2mVtest;
0450
0451 Scal=(UpmUtest)*(UV1mUtest)+(VpmVtest)*(UV2mVtest);
0452 if( (Abs(UpmUtest)<tolu && Abs(VpmVtest)<tolv)) {
0453 if(Index != k ) {
0454 //-- cout<<"** etat2 : ("<<k<<")"<<endl;
0455 wd2[k].etat = -wd2[k].etat;
0456 }
0457 }
0458 else if(Scal<0 && (dPreviousStart+dCurrentStart < dPreviousCurrent)) {
0459 if (Index == k ) { // on a boucle.
0460 Arrive = Standard_True;
0461 //-- cout<<"** Arrive : k="<<k<<endl;
0462 }
0463 else {
0464 //-- cout<<"*** etat2 : ("<<k<<")"<<endl;
0465 wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point
0466 }
0467 }
0468 else if(k!=Index) {
0469 if(dPreviousStart < dPreviousCurrent*0.25) {
0470 wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point
0471 //-- cout<<"**** etat2 : ("<<k<<")"<<endl;
0472 }
0473 else {
0474 if(dCurrentStart < dPreviousCurrent*0.25) {
0475 //-- cout<<"***** etat2 : ("<<k<<")"<<endl;
0476 wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point
0477 }
0478 else {
0479 Standard_Real UMidUtest = 0.5*(UV1+Up)-Utest;
0480 Standard_Real VMidVtest = 0.5*(UV2+Vp)-Vtest;
0481 Standard_Real dMiddleStart = UMidUtest* UMidUtest+VMidVtest*VMidVtest;
0482
0483 if(dMiddleStart < dPreviousCurrent*0.5) {
0484 //-- cout<<"*********** etat2 : ("<<k<<")"<<endl;
0485 wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point
0486 }
0487 }
0488 }
0489 }
0490 }
0491 }
0492 }
0493
0494 // crossing test on crossing points.
0495
0496 Irang =0;
0497 for (i = 1; i < (int)wd1.size(); i++) {
0498 if (wd1[i].etat > 0 && wd1[i].etat < 11) { //test of crossing points
0499 Utest = wd1[i].ustart;
0500 Vtest = wd1[i].vstart;
0501 Utest/=deltau;
0502 Vtest/=deltav;
0503
0504 if (((Up-Utest) * (UV1-Utest) + (Vp-Vtest) * (UV2-Vtest) < 0) ||
0505 (Abs(UV1-Utest) < tolu && Abs(UV2-Vtest) < tolv))
0506 Irang = i;
0507 else if (nbMultiplicities[i] > 0) {
0508 N=0;
0509 for (k = 1; k < i; k++) N = N + nbMultiplicities[k];
0510 for (Standard_Integer j = N + 1; j <= N + nbMultiplicities[i]; j++) {
0511 Standard_Real Umultj = Umult(j)/deltau;
0512 Standard_Real Vmultj = Vmult(j)/deltav;
0513 if (((Up-Umultj)*(UV1-Umultj) +
0514 (Vp-Vmultj)*(UV2-Vmultj) < 0) ||
0515 (Abs(UV1-Umultj) < tolu &&
0516 Abs(UV2-Vmultj) < tolv)) {
0517 Irang=i;
0518 break;
0519 }
0520 }
0521 }
0522 }
0523 }
0524 return Arrive;
0525 }
0526
0527
0528 Standard_Boolean IntWalk_IWalking::TestArretAjout
0529 (TheIWFunction& sp,
0530 math_Vector& UV,
0531 Standard_Integer& Irang,
0532 IntSurf_PntOn2S& Psol)
0533
0534 // test of stop on added points
0535 // these are the points on the natural biorder that were not given at input
0536 // return : Psol, the added point.
0537 // Irang, index in the iterator of added points.
0538 // UV, parameter of the added point.
0539 //
0540 {
0541 Standard_Boolean Arrive = Standard_False;
0542 Standard_Real U1,V1;
0543 Standard_Real Up,Vp;
0544
0545 if (!reversed) {
0546 previousPoint.ParametersOnS2(Up,Vp);
0547 }
0548 else {
0549 previousPoint.ParametersOnS1(Up,Vp);
0550 }
0551
0552 Standard_Integer nbAjout = seqAjout.Length();
0553 for (Standard_Integer i = 1; i <= nbAjout; i++) {
0554 Irang = seqAjout.Value(i);
0555
0556 // add test Abs(Irang) <= lines.Length() for the case when
0557 // a closed line is opened by adding a 1 point on this same
0558 // line. Anyway there is a huge problem as 2 points will be
0559 // added on this line...
0560
0561 if (Abs(Irang) <= lines.Length()) {
0562
0563 const Handle(IntWalk_TheIWLine)& Line = lines.Value(Abs(Irang));
0564 if (Irang>0)
0565 Psol = Line->Value(Line->NbPoints());
0566 else
0567 Psol = Line->Value(1);
0568 if (!reversed) {
0569 Psol.ParametersOnS2(U1, V1);
0570 }
0571 else {
0572 Psol.ParametersOnS1(U1, V1);
0573 }
0574 if (((Up-U1) * (UV(1)-U1) +
0575 (Vp-V1) * (UV(2)-V1)) < 0 ||
0576 (Abs(UV(1)-U1) < tolerance(1) &&
0577 Abs(UV(2)-V1) < tolerance(2))) {
0578 //jag 940615 Irang= -Abs(Irang);
0579 Arrive = Standard_True;
0580 UV(1) = U1;
0581 UV(2) = V1;
0582 Standard_Real abidF[1], abidD[1][2];
0583 math_Vector bidF(abidF,1,1);
0584 math_Matrix bidD(abidD,1,1,1,2);
0585 sp.Values(UV,bidF,bidD);
0586 break;
0587 }
0588 }
0589 }
0590 return Arrive;
0591 }
0592
0593 void IntWalk_IWalking::FillPntsInHoles(TheIWFunction& sp,
0594 TColStd_SequenceOfInteger& CopySeqAlone,
0595 IntSurf_SequenceOfInteriorPoint& PntsInHoles)
0596 {
0597 math_Vector BornInf(1,2), BornSup(1,2);
0598 BornInf(1) = Um;
0599 BornSup(1) = UM;
0600 BornInf(2) = Vm;
0601 BornSup(2) = VM;
0602 PointLineLine.Clear();
0603 TColStd_SequenceOfInteger SeqToRemove;
0604 TColStd_MapOfInteger BadSolutions;
0605
0606 for (Standard_Integer i = 1; i < CopySeqAlone.Length(); i++)
0607 {
0608 Standard_Integer Irang1 = CopySeqAlone(i);
0609 if (Irang1 == 0)
0610 continue;
0611 Standard_Boolean ToRemove = Standard_False;
0612 IntSurf_PntOn2S PointAlone1, PointAlone2;
0613 const Handle(IntWalk_TheIWLine)& Line1 = lines.Value(Abs(Irang1));
0614 if (Irang1 > 0)
0615 PointAlone1 = Line1->Value(Line1->NbPoints());
0616 else
0617 PointAlone1 = Line1->Value(1);
0618 gp_Pnt2d P2d1 = PointAlone1.ValueOnSurface(reversed), P2d2;
0619 Standard_Real MinSqDist = RealLast();
0620 Standard_Integer MinRang = 0, MinIndex = 0;
0621 for (Standard_Integer j = i+1; j <= CopySeqAlone.Length(); j++)
0622 {
0623 Standard_Integer Irang2 = CopySeqAlone(j);
0624 if (Irang2 == 0 ||
0625 BadSolutions.Contains(Irang2))
0626 continue;
0627 const Handle(IntWalk_TheIWLine)& Line2 = lines.Value(Abs(Irang2));
0628 if (Irang2 > 0)
0629 PointAlone2 = Line2->Value(Line2->NbPoints());
0630 else
0631 PointAlone2 = Line2->Value(1);
0632 P2d2 = PointAlone2.ValueOnSurface(reversed);
0633 Standard_Real aSqDist = P2d1.SquareDistance(P2d2);
0634 if (aSqDist < MinSqDist)
0635 {
0636 MinSqDist = aSqDist;
0637 MinRang = Irang2;
0638 MinIndex = j;
0639 }
0640 }
0641 //processing points from Irang1 and MinRang
0642 if (MinRang == 0)
0643 {
0644 SeqToRemove.Append(Irang1);
0645 BadSolutions.Clear();
0646 continue;
0647 }
0648 //Ends of same line
0649 if (Abs(Irang1) == Abs(MinRang) &&
0650 lines.Value(Abs(Irang1))->NbPoints() == 2)
0651 {
0652 SeqToRemove.Append(Irang1);
0653 SeqToRemove.Append(MinRang);
0654 CopySeqAlone(i) = 0;
0655 CopySeqAlone(MinIndex) = 0;
0656 BadSolutions.Clear();
0657 continue;
0658 }
0659 ///////////////////
0660 const Handle(IntWalk_TheIWLine)& Line2 = lines.Value(Abs(MinRang));
0661 if (MinRang > 0)
0662 PointAlone2 = Line2->Value(Line2->NbPoints());
0663 else
0664 PointAlone2 = Line2->Value(1);
0665 gp_Pnt Pnt1 = PointAlone1.Value();
0666 gp_Pnt Pnt2 = PointAlone2.Value();
0667 P2d2 = PointAlone2.ValueOnSurface(reversed);
0668 Standard_Real MinSqDist3d = Pnt1.SquareDistance(Pnt2);
0669 if (MinSqDist3d <= epsilon ||
0670 (Abs(P2d1.X() - P2d2.X()) <= tolerance(1) &&
0671 Abs(P2d1.Y() - P2d2.Y()) <= tolerance(2))) //close points
0672 ToRemove = Standard_True;
0673 else //real curve
0674 {
0675 math_Vector UVap(1,2), UV(1,2);
0676 UVap(1) = (P2d1.X() + P2d2.X())/2;
0677 UVap(2) = (P2d1.Y() + P2d2.Y())/2;
0678 math_FunctionSetRoot Rsnld(sp, tolerance);
0679 Rsnld.Perform(sp, UVap, BornInf, BornSup);
0680 if (Rsnld.IsDone() &&
0681 Abs(sp.Root()) <= sp.Tolerance() &&
0682 !sp.IsTangent())
0683 {
0684 Rsnld.Root(UV);
0685 gp_Pnt2d Pmid(UV(1),UV(2));
0686 gp_Vec2d P1P2(P2d1, P2d2);
0687 gp_Vec2d P1Pmid(P2d1, Pmid);
0688 gp_Vec2d P2Pmid(P2d2, Pmid);
0689 Standard_Real ScalProd1 = P1P2 * P1Pmid;
0690 Standard_Real ScalProd2 = P1P2 * P2Pmid;
0691 Standard_Boolean IsPmidValid = (ScalProd1 > 0. && ScalProd2 < 0); //Pmid is in the middle
0692 if (IsPmidValid)
0693 {
0694 for (Standard_Integer iline = 1; iline <= lines.Length(); iline++)
0695 if (IsPointOnLine(Pmid,iline))
0696 {
0697 IsPmidValid = Standard_False;
0698 break;
0699 }
0700 }
0701 if (IsPmidValid)
0702 {
0703 IntSurf_InteriorPoint aPoint(sp.Point(), UV(1), UV(2),
0704 sp.Direction3d(),
0705 sp.Direction2d());
0706 PntsInHoles.Append(aPoint);
0707 TColStd_ListOfInteger LineLine;
0708 LineLine.Append(Irang1);
0709 LineLine.Append(MinRang);
0710 PointLineLine.Bind(PntsInHoles.Length(), LineLine);
0711 }
0712 else
0713 {
0714 BadSolutions.Add(MinRang);
0715 i--;
0716 continue;
0717 }
0718 }
0719 else
0720 {
0721 BadSolutions.Add(MinRang);
0722 i--;
0723 continue;
0724 }
0725 }
0726 CopySeqAlone(i) = 0;
0727 CopySeqAlone(MinIndex) = 0;
0728 if (ToRemove)
0729 {
0730 SeqToRemove.Append(Irang1);
0731 SeqToRemove.Append(MinRang);
0732 }
0733 BadSolutions.Clear();
0734 }
0735
0736 for (Standard_Integer i = 1; i <= SeqToRemove.Length(); i++)
0737 for (Standard_Integer j = 1; j <= seqAlone.Length(); j++)
0738 if (seqAlone(j) == SeqToRemove(i))
0739 {
0740 seqAlone.Remove(j);
0741 break;
0742 }
0743 }
0744
0745 void IntWalk_IWalking::TestArretCadre
0746 (const TColStd_SequenceOfReal& Umult,
0747 const TColStd_SequenceOfReal& Vmult,
0748 const Handle(IntWalk_TheIWLine)& Line,
0749 TheIWFunction& sp,
0750 math_Vector& UV,
0751 Standard_Integer& Irang)
0752
0753 // test of stop when located on border.
0754 // tried all tests of stop and arrived.
0755 // test of stop on all given departure points already marked and on the entire current line.
0756 // This line can be shortened if the stop point is found.
0757 // Abs(Irang) = index in the iterator of departure points or 0
0758 // if Irang <0 , it is necessary to add this point on the line (no Line->Cut)
0759 // UV = parameter of the departure point
0760 {
0761 Standard_Real Scal, Up, Vp, Uc, Vc;
0762 Standard_Integer N;
0763 Standard_Boolean Found = Standard_False;
0764
0765
0766 Irang =0;
0767 for (Standard_Integer i = 1; i < (int)wd1.size(); i++) {
0768 if (wd1[i].etat < 0) {
0769 N=0; // range in UVMult.
0770 if (nbMultiplicities[i] > 0) {
0771 for (Standard_Integer k = 1; k < i; k++)
0772 N+=nbMultiplicities[k];
0773 }
0774 if (!reversed) {
0775 Line->Value(1).ParametersOnS2(Up,Vp);
0776 }
0777 else {
0778 Line->Value(1).ParametersOnS1(Up,Vp);
0779 }
0780 Standard_Integer nbp= Line->NbPoints();
0781 for (Standard_Integer j = 2; j <= nbp; j++) {
0782 if (!reversed) {
0783 Line->Value(j).ParametersOnS2(Uc,Vc);
0784 }
0785 else {
0786 Line->Value(j).ParametersOnS1(Uc,Vc);
0787 }
0788
0789 gp_Vec2d aVec1 (Up-wd1[i].ustart, Vp-wd1[i].vstart),
0790 aVec2 (Uc-wd1[i].ustart, Vc-wd1[i].vstart);
0791 CutVectorByTolerances (aVec1, tolerance);
0792 CutVectorByTolerances (aVec2, tolerance);
0793
0794 Scal = aVec1 * aVec2;
0795
0796 // if a stop point is found: stop the line on this point.
0797 if (Scal < 0) {
0798 Line->Cut(j); nbp= Line->NbPoints();
0799 Irang = i;
0800 UV(1) = wd1[Irang].ustart;
0801 UV(2) = wd1[Irang].vstart;
0802 Found = Standard_True;
0803 }
0804 else if (Abs(Uc-wd1[i].ustart) < tolerance(1) &&
0805 Abs(Vc-wd1[i].vstart) < tolerance(2) ) {
0806 Line->Cut(j); nbp= Line->NbPoints();
0807 Irang=i;
0808 UV(1) = wd1[Irang].ustart;
0809 UV(2) = wd1[Irang].vstart;
0810 Found = Standard_True;
0811 }
0812 else if (nbMultiplicities[i] > 0) {
0813 for (Standard_Integer k = N+1; k <= N + nbMultiplicities[i]; k++) {
0814
0815 aVec1.SetCoord (Up-Umult(k), Vp-Vmult(k)),
0816 aVec2.SetCoord (Uc-Umult(k), Vc-Vmult(k));
0817 CutVectorByTolerances (aVec1, tolerance);
0818 CutVectorByTolerances (aVec2, tolerance);
0819
0820 Scal = aVec1 * aVec2;
0821
0822 if (Scal < 0) {
0823 Line->Cut(j); nbp= Line->NbPoints();
0824 Irang=i;
0825 UV(1) = wd1[Irang].ustart;
0826 UV(2) = wd1[Irang].vstart;
0827 Found = Standard_True;
0828 break;
0829 }
0830 else if (Abs(Uc-Umult(k)) < tolerance(1) &&
0831 Abs(Vc-Vmult(k)) < tolerance(2)) {
0832 Line->Cut(j); nbp= Line->NbPoints();
0833 Irang=i;
0834 UV(1) = wd1[Irang].ustart;
0835 UV(2) = wd1[Irang].vstart;
0836 Found = Standard_True;
0837 break;
0838 }
0839 }
0840 }
0841 if (Found) {
0842 Standard_Real abidF[1], abidD[1][2];
0843 math_Vector bidF(abidF,1,1);
0844 math_Matrix bidD(abidD,1,1,1,2);
0845 sp.Values(UV,bidF,bidD);
0846 Standard_Integer NBP = Line->NbPoints();
0847 Standard_Integer Indextg;
0848 Line->TangentVector(Indextg);
0849 if(Indextg > NBP) {
0850 if(j>3 && j<=NBP+1) {
0851 gp_Vec Dir3d = sp.Direction3d();
0852 gp_Vec Dir3d1 = gp_Vec(Line->Value(j-2).Value(),Line->Value(j-1).Value());
0853 Standard_Real dot = Dir3d.Dot(Dir3d1);
0854 if(dot<0.0) { // Normally this Function should not be used often !!!
0855 Dir3d.Reverse();
0856 //-- cout<<" IntWalk_IWalking_2.gxx REVERSE "<<endl;
0857 }
0858 Line->SetTangentVector(previousd3d,j-1);
0859 }
0860 #ifdef OCCT_DEBUG
0861 else {
0862 std::cout<<" IntWalk_IWalking_2.gxx : bizarrerie 30 10 97 "<<std::endl;
0863 }
0864 #endif
0865 }
0866
0867 return;
0868 }
0869 Up = Uc;
0870 Vp = Vc;
0871 }
0872
0873 // now the last point of the line and the last calculated point are compated.
0874 // there will be no need to "Cut"
0875
0876 gp_Vec2d aVec1 (Up-wd1[i].ustart, Vp-wd1[i].vstart),
0877 aVec2 (UV(1)-wd1[i].ustart, UV(2)-wd1[i].vstart);
0878 CutVectorByTolerances (aVec1, tolerance);
0879 CutVectorByTolerances (aVec2, tolerance);
0880
0881 Scal = aVec1 * aVec2;
0882
0883 if (Scal < 0) {
0884 Irang = i;
0885 UV(1) = wd1[Irang].ustart;
0886 UV(2) = wd1[Irang].vstart;
0887 Found = Standard_True;
0888 }
0889 else if (Abs(UV(1)-wd1[i].ustart) < tolerance(1) &&
0890 Abs(UV(2)-wd1[i].vstart) < tolerance(2)) {
0891 Irang=i;
0892 UV(1) = wd1[Irang].ustart;
0893 UV(2) = wd1[Irang].vstart;
0894 Found = Standard_True;
0895 }
0896 else if (nbMultiplicities[i] > 0) {
0897 for (Standard_Integer j = N+1; j <= N+nbMultiplicities[i]; j++) {
0898
0899 aVec1.SetCoord (Up-Umult(j), Vp-Vmult(j));
0900 aVec2.SetCoord (UV(1)-Umult(j), UV(2)-Vmult(j));
0901 CutVectorByTolerances (aVec1, tolerance);
0902 CutVectorByTolerances (aVec2, tolerance);
0903
0904 Scal = aVec1 * aVec2;
0905
0906 if (Scal < 0) {
0907 Irang=i;
0908 UV(1) = wd1[Irang].ustart;
0909 UV(2) = wd1[Irang].vstart;
0910 Found = Standard_True;
0911 break;
0912 }
0913 else if (Abs(UV(1)-Umult(j)) < tolerance(1) &&
0914 Abs(UV(2)-Vmult(j)) < tolerance(2)) {
0915 Irang=i;
0916 UV(1) = wd1[Irang].ustart;
0917 UV(2) = wd1[Irang].vstart;
0918 Found = Standard_True;
0919 break;
0920 }
0921 }
0922 }
0923 if (Found) {
0924 Irang = -Irang; // jag 941017
0925 Standard_Real abidF[1], abidD[1][2];
0926 math_Vector bidF(abidF,1,1);
0927 math_Matrix bidD(abidD,1,1,1,2);
0928 sp.Values(UV,bidF,bidD);
0929 return;
0930 }
0931 }
0932 }
0933 }
0934
0935