1// Copyright (c) 1995-1999 Matra Datavision 2// Copyright (c) 1999-2014 OPEN CASCADE SAS 3// 4// This file is part of Open CASCADE Technology software library. 5// 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 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. 11// 12// Alternatively, this file may be used under the terms of Open CASCADE 13// commercial license or contractual agreement. 14 15#include <NCollection_IncAllocator.hxx> 16#include <NCollection_LocalArray.hxx> 17 18 19// modified by NIZHNY-MKK Thu Nov 2 15:07:26 2000.BEGIN 20static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd, 21 const TColStd_SequenceOfReal& Umult, 22 const TColStd_SequenceOfReal& Vmult, 23 const Standard_Real& prevUp, 24 const Standard_Real& prevVp, 25 const IntWalk_VectorOfInteger& nbMultiplicities, 26 const math_Vector& tolerance, 27 TheIWFunction& sp, 28 math_Vector& UV, 29 Standard_Integer& Irang); 30// modified by NIZHNY-MKK Thu Nov 2 15:07:39 2000.END 31 32 33void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, 34 const TColStd_SequenceOfReal& Vmult, 35 const ThePOPIterator& Pnts1, 36 TheIWFunction& Func, 37 Standard_Boolean& Rajout) 38 39// Processing of open line. 40// 41// 1) for any starting point, which is not passing and not tangent and not yet processed, 42// calculation of the step of advancement = step depending on the arrow and the maximum step. 43// 44// 2) calculate a point of approach (this point is on the tangent to the section 45// of distance = no point in the interior) 46// 47// 3) conditions { 48// (all calculated points do not exceed a point in the 49// list of starting points) 50// or 51// (all points do not form an open line going 52// from one border of the domain to the other or from a point tangent 53// to border or from 2 tangent points : single cases) 54// 55// 1) framing of approached point on borders if necessary (there is 56// calculation of step) 57// 2) calculation of the point 58// 3) if the point is not found the step is divided 59// 4) stop tests 60// 5) calculation of the step depending on the arrow and the max step, 61// (TestDeflection) 62// stop possible. 63// end of conditions. 64 65{ 66 Standard_Integer I = 0, N = 0, SaveN = 0; 67 Standard_Real aBornInf[2] = {}, aBornSup[2] = {}, aUVap[2] = {}; 68 math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2), UVap(aUVap,1,2); 69 Standard_Real PasC = 0.0, PasCu = 0.0, PasCv = 0.0; 70 Standard_Boolean Arrive = false; // shows if the line ends 71 Standard_Boolean Cadre = false; // shows if one is on border of the domain 72 Standard_Boolean ArretAjout = false; //shows if one is on added point 73 IntSurf_PntOn2S Psol; 74 Handle(IntWalk_TheIWLine) CurrentLine; // line under construction 75 Standard_Boolean Tgtend = false; 76 77 IntWalk_StatusDeflection aStatus = IntWalk_OK, StatusPrecedent = IntWalk_OK; 78 79 Standard_Integer NbDivision = 0; 80 // number of divisions of step for each section 81 82 Standard_Integer StepSign = 0; 83 84 ThePointOfPath PathPnt; 85 86 BornInf(1) = Um; 87 BornSup(1) = UM; 88 BornInf(2) = Vm; 89 BornSup(2) = VM; 90 91 math_FunctionSetRoot Rsnld(Func, tolerance); 92 Standard_Integer nbPath = Pnts1.Length(); 93 94 // modified by NIZHNY-MKK Fri Oct 27 12:32:34 2000.BEGIN 95 NCollection_LocalArray<Standard_Integer> movementdirectioninfoarr (nbPath + 1); 96 Standard_Integer* movementdirectioninfo = movementdirectioninfoarr; 97 for (I = 0; I <= nbPath; I++) { 98 movementdirectioninfo[I] = 0; 99 } 100 // modified by NIZHNY-MKK Fri Oct 27 12:32:38 2000.END 101 102 TheIWFunction aFuncForDuplicate = Func; 103 104 for (I = 1; I <= nbPath; I++) { 105 //start point of the progression 106 // if (wd1[I].etat > 11) { 107 // modified by NIZHNY-MKK Fri Oct 27 12:33:37 2000.BEGIN 108 if ((wd1[I].etat > 11) || ((wd1[I].etat < -11) && (movementdirectioninfo[I]!=0))) { 109 // modified by NIZHNY-MKK Fri Oct 27 12:33:43 2000.END 110 PathPnt = Pnts1.Value(I); 111 UVap(1) = wd1[I].ustart; 112 UVap(2) = wd1[I].vstart; 113 MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint); 114 115 if (IsPointOnLine(previousPoint, BornInf, BornSup, Rsnld, aFuncForDuplicate)) 116 { 117 wd1[I].etat = -Abs(wd1[I].etat); //mark point as processed 118 continue; 119 } 120 121 CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator()); 122 CurrentLine->SetTangencyAtBegining(Standard_False); 123 Tgtend = Standard_False; 124 CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt); 125 previousd3d = Func.Direction3d(); 126 previousd2d = Func.Direction2d(); 127 CurrentLine->AddPoint(previousPoint); 128 // modified by NIZHNY-MKK Fri Oct 27 12:34:32 2000.BEGIN 129 if(movementdirectioninfo[I] !=0) { 130 if(movementdirectioninfo[I] < 0) { 131 StepSign = -1; 132 CurrentLine->SetTangentVector(previousd3d.Reversed(),1); 133 } else { 134 StepSign = 1; 135 CurrentLine->SetTangentVector(previousd3d,1); 136 } 137 } else { 138 Standard_Real tyutuyt=ThePointOfPathTool::Direction3d(PathPnt) * previousd3d; 139 if( tyutuyt < 0) { 140 StepSign = -1; 141 CurrentLine->SetTangentVector(previousd3d.Reversed(),1); 142 } 143 else { 144 StepSign = 1; 145 CurrentLine->SetTangentVector(previousd3d,1); 146 } 147 } 148 // modified by NIZHNY-MKK Fri Oct 27 12:34:37 2000.END 149 150 // Modified by Sergey KHROMOV - Tue Nov 20 10:41:45 2001 Begin 151 wd1[I].etat = -Abs(wd1[I].etat); 152 movementdirectioninfo[I] = (movementdirectioninfo[I]==0) ? StepSign : 0; 153// Modified by Sergey KHROMOV - Tue Nov 20 10:41:56 2001 End 154 // first step of advancement 155 Standard_Real d2dx = Abs(previousd2d.X()); 156 Standard_Real d2dy = Abs(previousd2d.Y()); 157 if (d2dx < tolerance(1)) { 158 PasC = pas * (VM-Vm)/d2dy; 159 } 160 else if (d2dy < tolerance(2)) { 161 PasC = pas * (UM-Um)/d2dx; 162 } 163 else { 164 PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy); 165 } 166 167 Arrive = Standard_False; 168 ArretAjout = Standard_False; 169 NbDivision = 0; 170 StatusPrecedent = IntWalk_OK; 171 // modified by NIZHNY-MKK Fri Oct 27 12:39:37 2000 172 Standard_Integer IndexOfPathPointDoNotCheck=0; 173 Standard_Integer aNbIter = 10; 174 while (!Arrive) { // as one of stop tests is not checked 175 Cadre = Cadrage(BornInf,BornSup,UVap,PasC,StepSign); 176 // Border? 177 178#ifdef CHRONO 179 Chronrsnld.Start(); 180#endif 181 182 Rsnld.Perform(Func,UVap,BornInf,BornSup); 183 184#ifdef CHRONO 185 Chronrsnld.Stop(); 186#endif 187 188 if (Cadre) { 189 BornInf(1) = Um; BornSup(1) = UM; BornInf(2) = Vm; BornSup(2) = VM; 190 } 191 if (Rsnld.IsDone()) { 192 if (Abs(Func.Root()) > Func.Tolerance()) { 193 PasC = PasC / 2.0; 194 PasCu = Abs(PasC*previousd2d.X()); 195 PasCv = Abs(PasC*previousd2d.Y()); 196 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) { 197 if (CurrentLine->NbPoints() == 1) break; 198 Arrive = Standard_True; 199 CurrentLine->AddStatusLast(Standard_False); 200 Tgtend = Standard_True; // check 201 Rajout = Standard_True; 202 seqAlone.Append(lines.Length() + 1); 203 seqAjout.Append(lines.Length() + 1); 204 } 205 } 206 else { // test stop 207 Rsnld.Root(UVap); 208 Arrive = TestArretPassage(Umult, Vmult, Func, UVap, N); 209 if (Arrive) { 210 Cadre = Standard_False; 211 //in case if there is a frame and arrive at the same time 212 } 213 else { 214 if (Rajout) { 215 ArretAjout =TestArretAjout(Func, UVap, N, Psol); 216 SaveN = N; 217 if (ArretAjout) { 218 // jag 940615 219 Tgtend = lines.Value(N)->IsTangentAtEnd(); 220 N = -N; 221 } 222 } 223 // modified by NIZHNY-MKK Thu Nov 2 15:09:08 2000.BEGIN 224 if(!(Rajout && ArretAjout)) { 225 Standard_Real prevUp, prevVp; 226 if (!reversed) { 227 previousPoint.ParametersOnS2(prevUp, prevVp); 228 } 229 else { 230 previousPoint.ParametersOnS1(prevUp, prevVp); 231 } 232 Arrive = TestPassedSolutionWithNegativeState(wd1, Umult, Vmult, prevUp, prevVp, 233 nbMultiplicities, tolerance, Func, UVap, N); 234 if(Arrive) { 235 Cadre = Standard_False; 236 } 237 } 238 // modified by NIZHNY-MKK Thu Nov 2 15:09:13 2000.END 239 if (!ArretAjout && Cadre) { 240 if (CurrentLine->NbPoints() == 1) break; // cancel the line 241 TestArretCadre(Umult, Vmult, CurrentLine, Func, UVap, N); 242 // if (N == 0) { 243 if (N <= 0) { // jag 941017 244 MakeWalkingPoint(2, UVap(1), UVap(2), Func, Psol); 245 Tgtend = Func.IsTangent(); 246 N = -N; 247 } 248 } 249 } 250 aStatus = TestDeflection(Func, Arrive, UVap, StatusPrecedent, 251 NbDivision,PasC,StepSign); 252 StatusPrecedent = aStatus; 253 if (aStatus == IntWalk_PasTropGrand) { 254 Arrive = Standard_False; 255 ArretAjout = Standard_False; 256 Tgtend = Standard_False; // jag 940615 257 if (!reversed) { 258 previousPoint.ParametersOnS2(UVap(1), UVap(2)); 259 } 260 else { 261 previousPoint.ParametersOnS1(UVap(1), UVap(2)); 262 } 263 } 264 else if (ArretAjout || Cadre) { 265 Arrive = Standard_True; 266 CurrentLine->AddStatusLast(Standard_False); 267 //if (aStatus != IntWalk_ArretSurPointPrecedent) 268 CurrentLine->AddPoint(Psol); 269 //Remove <SaveN> from <seqAlone> 270 for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++) 271 if (seqAlone(iseq) == SaveN) 272 { 273 seqAlone.Remove(iseq); 274 break; 275 } 276 277 if (Cadre && N==0) { 278 Rajout = Standard_True; 279 seqAjout.Append(lines.Length()+1); 280 } 281 } 282 else if (aStatus == IntWalk_ArretSurPointPrecedent) { 283 if (CurrentLine->NbPoints() == 1) { //cancel the line 284 Arrive = Standard_False; 285 break; 286 } 287 Arrive = Standard_True; 288 Rajout = Standard_True; 289 //AddAlonePoint(); 290 seqAlone.Append(lines.Length() + 1); 291 seqAjout.Append(lines.Length() + 1); 292 CurrentLine->AddStatusLast(Standard_False); 293 Tgtend = Standard_True; // check 294 } 295 else if (Arrive) { 296 if (CurrentLine->NbPoints() == 1 && // cancel the line 297 (N == I || aStatus == IntWalk_PointConfondu) ) { 298 // if N == I the main uv is probably lost 299 // or the point is a point of accumulation 300 // if point is confused the start data is bad 301 Arrive = Standard_False; 302 break; 303 } 304 // necessairily N > 0 jag 940617 305 // point of stop given at input 306 PathPnt = Pnts1.Value(N); 307 308 Standard_Integer etat1N=wd1[N].etat; 309 // modified by NIZHNY-MKK Thu Nov 2 15:09:51 2000.BEGIN 310 // if (etat1N < 11) { // passing point that is a stop 311 if (Abs(etat1N) < 11) { // passing point that is a stop 312 // modified by NIZHNY-MKK Thu Nov 2 15:12:11 2000.END 313 if (aStatus == IntWalk_ArretSurPoint) { 314 CurrentLine->AddStatusLast(Standard_False); 315 Tgtend = Standard_True; // need check 316 } 317 else { 318 Arrive = Standard_False; 319 } 320 CurrentLine->AddIndexPassing(N); 321 } 322 else { // point of stop given at input 323 if (etat1N == 11) { 324 Tgtend = Standard_True; 325 } 326 CurrentLine->AddStatusLast(Standard_True, N, PathPnt); 327 } 328 AddPointInCurrentLine(N,PathPnt,CurrentLine); 329 if ((etat1N != 1 && etat1N != 11)) { 330 // modified by NIZHNY-MKK Fri Oct 27 12:43:05 2000.BEGIN 331 // wd1[N].etat= - wd1[N].etat; 332 wd1[N].etat = - Abs(etat1N); 333 movementdirectioninfo[N] = (movementdirectioninfo[N]==0) ? StepSign : 0; 334 if(Arrive && movementdirectioninfo[N]!=0) { 335 IndexOfPathPointDoNotCheck = N; 336 } 337 338 if(Arrive) { 339 Rajout = Standard_True; 340 seqAjout.Append(lines.Length() + 1); 341 } 342 // modified by NIZHNY-MKK Fri Oct 27 12:45:33 2000.END 343 } 344 } 345 else if (aStatus == IntWalk_ArretSurPoint) { 346 Arrive = Standard_True; 347 CurrentLine->AddStatusLast(Standard_False); 348 Tgtend = Standard_True; 349 MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol); 350 CurrentLine->AddPoint(Psol); 351 Rajout = Standard_True; 352 seqAlone.Append(lines.Length() + 1); 353 seqAjout.Append(lines.Length() + 1); 354 } 355 else if (aStatus == IntWalk_OK) { 356 MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint); 357 previousd3d = Func.Direction3d(); 358 previousd2d = Func.Direction2d(); 359 CurrentLine->AddPoint(previousPoint); 360 } 361 else if (aStatus == IntWalk_PointConfondu) 362 { 363 aNbIter --; 364 } 365 } 366 } 367 else { // no numerical solution 368 PasC = PasC / 2.; 369 PasCu = Abs(PasC*previousd2d.X()); 370 PasCv = Abs(PasC*previousd2d.Y()); 371 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) { 372 if (CurrentLine->NbPoints()==1) break; 373 Arrive = Standard_True; 374 CurrentLine->AddStatusLast(Standard_False); 375 Tgtend = Standard_True; // need check 376 Rajout = Standard_True; 377 seqAlone.Append(lines.Length() + 1); 378 seqAjout.Append(lines.Length() + 1); 379 } 380 } 381 382 if(aNbIter < 0) 383 break; 384 } // end of started line 385 386 if (Arrive) { 387 CurrentLine->SetTangencyAtEnd(Tgtend); 388 lines.Append(CurrentLine); 389 // modified by NIZHNY-MKK Fri Oct 27 12:59:29 2000.BEGIN 390 movementdirectioninfo[I]=0; 391 if(wd1[I].etat > 0) 392 // modified by NIZHNY-MKK Fri Oct 27 12:59:42 2000.END 393 wd1[I].etat=-wd1[I].etat; 394 395 //-- lbr le 5 juin 97 (Pb ds Contap) 396 for(Standard_Integer av=1; av<=nbPath; av++) { 397 // modified by NIZHNY-MKK Fri Oct 27 13:00:22 2000.BEGIN 398 // if (wd1[av].etat > 11) { 399 if ((wd1[av].etat > 11) || 400 ((av!=I) && 401 (av!=IndexOfPathPointDoNotCheck) && 402 (wd1[av].etat < -11) && 403 (movementdirectioninfo[av]!=0))) 404 { 405 // modified by NIZHNY-MKK Fri Oct 27 13:00:26 2000.END 406 Standard_Real Uav=wd1[av].ustart; 407 Standard_Real Vav=wd1[av].vstart; 408 Standard_Real Uavp,Vavp; 409 const IntSurf_PntOn2S &avP=CurrentLine->Value(CurrentLine->NbPoints()); 410 if (!reversed) { 411 avP.ParametersOnS2(Uavp,Vavp); 412 } 413 else { 414 avP.ParametersOnS1(Uavp,Vavp); 415 } 416 Uav-=Uavp; 417 Vav-=Vavp; 418 Uav*=0.001; Vav*=0.001; 419 if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) { 420 // modified by NIZHNY-MKK Fri Oct 27 13:01:38 2000.BEGIN 421 // wd1[av].etat=-wd1[av].etat; 422 if(wd1[av].etat < 0) { 423 movementdirectioninfo[av] = 0; 424 } else { 425 wd1[av].etat=-wd1[av].etat; 426 movementdirectioninfo[av] = StepSign; 427 } 428 // modified by NIZHNY-MKK Fri Oct 27 13:01:42 2000.END 429 CurrentLine->AddStatusLast(Standard_True, av, Pnts1.Value(av)); 430 //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl; 431 } 432 433 const IntSurf_PntOn2S &avPP=CurrentLine->Value(1); 434 if (!reversed) { 435 avPP.ParametersOnS2(Uavp,Vavp); 436 } 437 else { 438 avPP.ParametersOnS1(Uavp,Vavp); 439 } 440 Uav=wd1[av].ustart; 441 Vav=wd1[av].vstart; 442 Uav-=Uavp; 443 Vav-=Vavp; 444 Uav*=0.001; Vav*=0.001; 445 if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) { 446 // modified by NIZHNY-MKK Fri Oct 27 13:02:49 2000.BEGIN 447 // wd1[av].etat=-wd1[av].etat; 448 if(wd1[av].etat < 0) { 449 movementdirectioninfo[av] = 0; 450 } else { 451 wd1[av].etat=-wd1[av].etat; 452 movementdirectioninfo[av] = -StepSign; 453 } 454 // modified by NIZHNY-MKK Fri Oct 27 13:02:52 2000.END 455 //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl; 456 CurrentLine->AddStatusFirst(Standard_False, Standard_True, av, Pnts1.Value(av)); 457 } 458 } 459 } 460 } 461 } //end of point processing 462 } //end of all points 463} 464 465// modified by NIZHNY-MKK Thu Nov 2 15:07:53 2000.BEGIN 466static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd, 467 const TColStd_SequenceOfReal& Umult, 468 const TColStd_SequenceOfReal& Vmult, 469 const Standard_Real& prevUp, 470 const Standard_Real& prevVp, 471 const IntWalk_VectorOfInteger& nbMultiplicities, 472 const math_Vector& tolerance, 473 TheIWFunction& sp, 474 math_Vector& UV, 475 Standard_Integer& Irang) { 476 Standard_Boolean Arrive = Standard_False; 477 Standard_Real Dup, Dvp, Utest,Vtest; 478 Standard_Real tolu = tolerance(1); 479 Standard_Real tolv = tolerance(2); 480 Standard_Integer i, j, k, N; 481 for (i = 1; i < (int)wd.size(); i++) { 482 if (wd[i].etat < -11) { 483 484 // debug jag see with isg 485 486 Utest = wd[i].ustart; 487 Vtest = wd[i].vstart; 488 Dup = prevUp - Utest; 489 Dvp = prevVp - Vtest; 490 if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) { 491 Standard_Real UV1mUtest = UV(1)-Utest; 492 Standard_Real UV2mVtest = UV(2)-Vtest; 493 if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) || 494 ( Abs(UV1mUtest) < tolu 495 && Abs(UV2mVtest) < tolv)) { 496 Irang=i; 497 Arrive = Standard_True; 498 UV(1) = Utest; 499 UV(2) = Vtest; 500 } 501 else if (nbMultiplicities[i] > 0) { 502 N=0; 503 for (k = 1; k < i; k++) { 504 N+=nbMultiplicities[k]; 505 } 506 for (j = N + 1; j <= N + nbMultiplicities[i]; j++) { 507 if (((prevUp-Umult(j))*(UV(1)-Umult(j)) + 508 (prevVp-Vmult(j))*(UV(2)-Vmult(j)) < 0) || 509 (Abs(UV(1)-Umult(j)) < tolu && 510 Abs(UV(2)-Vmult(j)) < tolv)) { 511 Irang=i; 512 Arrive = Standard_True; 513 UV(1) = Utest; 514 UV(2) = Vtest; 515 break; 516 } 517 } 518 } 519 if (Arrive) { 520 Standard_Real abidF[1], abidD[1][2]; 521 math_Vector bidF(abidF,1,1); 522 math_Matrix bidD(abidD,1,1,1,2); 523 sp.Values(UV,bidF,bidD); 524 break; 525 } 526 } 527 } 528 } 529 return Arrive; 530} 531// modified by NIZHNY-MKK Thu Nov 2 15:07:58 2000.END 532