Warning, /include/opencascade/IntWalk_IWalking_3.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 #include <NCollection_IncAllocator.hxx>
0016 #include <NCollection_LocalArray.hxx>
0017
0018
0019 // modified by NIZHNY-MKK Thu Nov 2 15:07:26 2000.BEGIN
0020 static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd,
0021 const TColStd_SequenceOfReal& Umult,
0022 const TColStd_SequenceOfReal& Vmult,
0023 const Standard_Real& prevUp,
0024 const Standard_Real& prevVp,
0025 const IntWalk_VectorOfInteger& nbMultiplicities,
0026 const math_Vector& tolerance,
0027 TheIWFunction& sp,
0028 math_Vector& UV,
0029 Standard_Integer& Irang);
0030 // modified by NIZHNY-MKK Thu Nov 2 15:07:39 2000.END
0031
0032
0033 void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
0034 const TColStd_SequenceOfReal& Vmult,
0035 const ThePOPIterator& Pnts1,
0036 TheIWFunction& Func,
0037 Standard_Boolean& Rajout)
0038
0039 // Processing of open line.
0040 //
0041 // 1) for any starting point, which is not passing and not tangent and not yet processed,
0042 // calculation of the step of advancement = step depending on the arrow and the maximum step.
0043 //
0044 // 2) calculate a point of approach (this point is on the tangent to the section
0045 // of distance = no point in the interior)
0046 //
0047 // 3) conditions {
0048 // (all calculated points do not exceed a point in the
0049 // list of starting points)
0050 // or
0051 // (all points do not form an open line going
0052 // from one border of the domain to the other or from a point tangent
0053 // to border or from 2 tangent points : single cases)
0054 //
0055 // 1) framing of approached point on borders if necessary (there is
0056 // calculation of step)
0057 // 2) calculation of the point
0058 // 3) if the point is not found the step is divided
0059 // 4) stop tests
0060 // 5) calculation of the step depending on the arrow and the max step,
0061 // (TestDeflection)
0062 // stop possible.
0063 // end of conditions.
0064
0065 {
0066 Standard_Integer I = 0, N = 0, SaveN = 0;
0067 Standard_Real aBornInf[2] = {}, aBornSup[2] = {}, aUVap[2] = {};
0068 math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2), UVap(aUVap,1,2);
0069 Standard_Real PasC = 0.0, PasCu = 0.0, PasCv = 0.0;
0070 Standard_Boolean Arrive = false; // shows if the line ends
0071 Standard_Boolean Cadre = false; // shows if one is on border of the domain
0072 Standard_Boolean ArretAjout = false; //shows if one is on added point
0073 IntSurf_PntOn2S Psol;
0074 Handle(IntWalk_TheIWLine) CurrentLine; // line under construction
0075 Standard_Boolean Tgtend = false;
0076
0077 IntWalk_StatusDeflection aStatus = IntWalk_OK, StatusPrecedent = IntWalk_OK;
0078
0079 Standard_Integer NbDivision = 0;
0080 // number of divisions of step for each section
0081
0082 Standard_Integer StepSign = 0;
0083
0084 ThePointOfPath PathPnt;
0085
0086 BornInf(1) = Um;
0087 BornSup(1) = UM;
0088 BornInf(2) = Vm;
0089 BornSup(2) = VM;
0090
0091 math_FunctionSetRoot Rsnld(Func, tolerance);
0092 Standard_Integer nbPath = Pnts1.Length();
0093
0094 // modified by NIZHNY-MKK Fri Oct 27 12:32:34 2000.BEGIN
0095 NCollection_LocalArray<Standard_Integer> movementdirectioninfoarr (nbPath + 1);
0096 Standard_Integer* movementdirectioninfo = movementdirectioninfoarr;
0097 for (I = 0; I <= nbPath; I++) {
0098 movementdirectioninfo[I] = 0;
0099 }
0100 // modified by NIZHNY-MKK Fri Oct 27 12:32:38 2000.END
0101
0102 TheIWFunction aFuncForDuplicate = Func;
0103
0104 for (I = 1; I <= nbPath; I++) {
0105 //start point of the progression
0106 // if (wd1[I].etat > 11) {
0107 // modified by NIZHNY-MKK Fri Oct 27 12:33:37 2000.BEGIN
0108 if ((wd1[I].etat > 11) || ((wd1[I].etat < -11) && (movementdirectioninfo[I]!=0))) {
0109 // modified by NIZHNY-MKK Fri Oct 27 12:33:43 2000.END
0110 PathPnt = Pnts1.Value(I);
0111 UVap(1) = wd1[I].ustart;
0112 UVap(2) = wd1[I].vstart;
0113 MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint);
0114
0115 if (IsPointOnLine(previousPoint, BornInf, BornSup, Rsnld, aFuncForDuplicate))
0116 {
0117 wd1[I].etat = -Abs(wd1[I].etat); //mark point as processed
0118 continue;
0119 }
0120
0121 CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
0122 CurrentLine->SetTangencyAtBegining(Standard_False);
0123 Tgtend = Standard_False;
0124 CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt);
0125 previousd3d = Func.Direction3d();
0126 previousd2d = Func.Direction2d();
0127 CurrentLine->AddPoint(previousPoint);
0128 // modified by NIZHNY-MKK Fri Oct 27 12:34:32 2000.BEGIN
0129 if(movementdirectioninfo[I] !=0) {
0130 if(movementdirectioninfo[I] < 0) {
0131 StepSign = -1;
0132 CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
0133 } else {
0134 StepSign = 1;
0135 CurrentLine->SetTangentVector(previousd3d,1);
0136 }
0137 } else {
0138 Standard_Real tyutuyt=ThePointOfPathTool::Direction3d(PathPnt) * previousd3d;
0139 if( tyutuyt < 0) {
0140 StepSign = -1;
0141 CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
0142 }
0143 else {
0144 StepSign = 1;
0145 CurrentLine->SetTangentVector(previousd3d,1);
0146 }
0147 }
0148 // modified by NIZHNY-MKK Fri Oct 27 12:34:37 2000.END
0149
0150 // Modified by Sergey KHROMOV - Tue Nov 20 10:41:45 2001 Begin
0151 wd1[I].etat = -Abs(wd1[I].etat);
0152 movementdirectioninfo[I] = (movementdirectioninfo[I]==0) ? StepSign : 0;
0153 // Modified by Sergey KHROMOV - Tue Nov 20 10:41:56 2001 End
0154 // first step of advancement
0155 Standard_Real d2dx = Abs(previousd2d.X());
0156 Standard_Real d2dy = Abs(previousd2d.Y());
0157 if (d2dx < tolerance(1)) {
0158 PasC = pas * (VM-Vm)/d2dy;
0159 }
0160 else if (d2dy < tolerance(2)) {
0161 PasC = pas * (UM-Um)/d2dx;
0162 }
0163 else {
0164 PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
0165 }
0166
0167 Arrive = Standard_False;
0168 ArretAjout = Standard_False;
0169 NbDivision = 0;
0170 StatusPrecedent = IntWalk_OK;
0171 // modified by NIZHNY-MKK Fri Oct 27 12:39:37 2000
0172 Standard_Integer IndexOfPathPointDoNotCheck=0;
0173 Standard_Integer aNbIter = 10;
0174 while (!Arrive) { // as one of stop tests is not checked
0175 Cadre = Cadrage(BornInf,BornSup,UVap,PasC,StepSign);
0176 // Border?
0177
0178 #ifdef CHRONO
0179 Chronrsnld.Start();
0180 #endif
0181
0182 Rsnld.Perform(Func,UVap,BornInf,BornSup);
0183
0184 #ifdef CHRONO
0185 Chronrsnld.Stop();
0186 #endif
0187
0188 if (Cadre) {
0189 BornInf(1) = Um; BornSup(1) = UM; BornInf(2) = Vm; BornSup(2) = VM;
0190 }
0191 if (Rsnld.IsDone()) {
0192 if (Abs(Func.Root()) > Func.Tolerance()) {
0193 PasC = PasC / 2.0;
0194 PasCu = Abs(PasC*previousd2d.X());
0195 PasCv = Abs(PasC*previousd2d.Y());
0196 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
0197 if (CurrentLine->NbPoints() == 1) break;
0198 Arrive = Standard_True;
0199 CurrentLine->AddStatusLast(Standard_False);
0200 Tgtend = Standard_True; // check
0201 Rajout = Standard_True;
0202 seqAlone.Append(lines.Length() + 1);
0203 seqAjout.Append(lines.Length() + 1);
0204 }
0205 }
0206 else { // test stop
0207 Rsnld.Root(UVap);
0208 Arrive = TestArretPassage(Umult, Vmult, Func, UVap, N);
0209 if (Arrive) {
0210 Cadre = Standard_False;
0211 //in case if there is a frame and arrive at the same time
0212 }
0213 else {
0214 if (Rajout) {
0215 ArretAjout =TestArretAjout(Func, UVap, N, Psol);
0216 SaveN = N;
0217 if (ArretAjout) {
0218 // jag 940615
0219 Tgtend = lines.Value(N)->IsTangentAtEnd();
0220 N = -N;
0221 }
0222 }
0223 // modified by NIZHNY-MKK Thu Nov 2 15:09:08 2000.BEGIN
0224 if(!(Rajout && ArretAjout)) {
0225 Standard_Real prevUp, prevVp;
0226 if (!reversed) {
0227 previousPoint.ParametersOnS2(prevUp, prevVp);
0228 }
0229 else {
0230 previousPoint.ParametersOnS1(prevUp, prevVp);
0231 }
0232 Arrive = TestPassedSolutionWithNegativeState(wd1, Umult, Vmult, prevUp, prevVp,
0233 nbMultiplicities, tolerance, Func, UVap, N);
0234 if(Arrive) {
0235 Cadre = Standard_False;
0236 }
0237 }
0238 // modified by NIZHNY-MKK Thu Nov 2 15:09:13 2000.END
0239 if (!ArretAjout && Cadre) {
0240 if (CurrentLine->NbPoints() == 1) break; // cancel the line
0241 TestArretCadre(Umult, Vmult, CurrentLine, Func, UVap, N);
0242 // if (N == 0) {
0243 if (N <= 0) { // jag 941017
0244 MakeWalkingPoint(2, UVap(1), UVap(2), Func, Psol);
0245 Tgtend = Func.IsTangent();
0246 N = -N;
0247 }
0248 }
0249 }
0250 aStatus = TestDeflection(Func, Arrive, UVap, StatusPrecedent,
0251 NbDivision,PasC,StepSign);
0252 StatusPrecedent = aStatus;
0253 if (aStatus == IntWalk_PasTropGrand) {
0254 Arrive = Standard_False;
0255 ArretAjout = Standard_False;
0256 Tgtend = Standard_False; // jag 940615
0257 if (!reversed) {
0258 previousPoint.ParametersOnS2(UVap(1), UVap(2));
0259 }
0260 else {
0261 previousPoint.ParametersOnS1(UVap(1), UVap(2));
0262 }
0263 }
0264 else if (ArretAjout || Cadre) {
0265 Arrive = Standard_True;
0266 CurrentLine->AddStatusLast(Standard_False);
0267 //if (aStatus != IntWalk_ArretSurPointPrecedent)
0268 CurrentLine->AddPoint(Psol);
0269 //Remove <SaveN> from <seqAlone>
0270 for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
0271 if (seqAlone(iseq) == SaveN)
0272 {
0273 seqAlone.Remove(iseq);
0274 break;
0275 }
0276
0277 if (Cadre && N==0) {
0278 Rajout = Standard_True;
0279 seqAjout.Append(lines.Length()+1);
0280 }
0281 }
0282 else if (aStatus == IntWalk_ArretSurPointPrecedent) {
0283 if (CurrentLine->NbPoints() == 1) { //cancel the line
0284 Arrive = Standard_False;
0285 break;
0286 }
0287 Arrive = Standard_True;
0288 Rajout = Standard_True;
0289 //AddAlonePoint();
0290 seqAlone.Append(lines.Length() + 1);
0291 seqAjout.Append(lines.Length() + 1);
0292 CurrentLine->AddStatusLast(Standard_False);
0293 Tgtend = Standard_True; // check
0294 }
0295 else if (Arrive) {
0296 if (CurrentLine->NbPoints() == 1 && // cancel the line
0297 (N == I || aStatus == IntWalk_PointConfondu) ) {
0298 // if N == I the main uv is probably lost
0299 // or the point is a point of accumulation
0300 // if point is confused the start data is bad
0301 Arrive = Standard_False;
0302 break;
0303 }
0304 // necessairily N > 0 jag 940617
0305 // point of stop given at input
0306 PathPnt = Pnts1.Value(N);
0307
0308 Standard_Integer etat1N=wd1[N].etat;
0309 // modified by NIZHNY-MKK Thu Nov 2 15:09:51 2000.BEGIN
0310 // if (etat1N < 11) { // passing point that is a stop
0311 if (Abs(etat1N) < 11) { // passing point that is a stop
0312 // modified by NIZHNY-MKK Thu Nov 2 15:12:11 2000.END
0313 if (aStatus == IntWalk_ArretSurPoint) {
0314 CurrentLine->AddStatusLast(Standard_False);
0315 Tgtend = Standard_True; // need check
0316 }
0317 else {
0318 Arrive = Standard_False;
0319 }
0320 CurrentLine->AddIndexPassing(N);
0321 }
0322 else { // point of stop given at input
0323 if (etat1N == 11) {
0324 Tgtend = Standard_True;
0325 }
0326 CurrentLine->AddStatusLast(Standard_True, N, PathPnt);
0327 }
0328 AddPointInCurrentLine(N,PathPnt,CurrentLine);
0329 if ((etat1N != 1 && etat1N != 11)) {
0330 // modified by NIZHNY-MKK Fri Oct 27 12:43:05 2000.BEGIN
0331 // wd1[N].etat= - wd1[N].etat;
0332 wd1[N].etat = - Abs(etat1N);
0333 movementdirectioninfo[N] = (movementdirectioninfo[N]==0) ? StepSign : 0;
0334 if(Arrive && movementdirectioninfo[N]!=0) {
0335 IndexOfPathPointDoNotCheck = N;
0336 }
0337
0338 if(Arrive) {
0339 Rajout = Standard_True;
0340 seqAjout.Append(lines.Length() + 1);
0341 }
0342 // modified by NIZHNY-MKK Fri Oct 27 12:45:33 2000.END
0343 }
0344 }
0345 else if (aStatus == IntWalk_ArretSurPoint) {
0346 Arrive = Standard_True;
0347 CurrentLine->AddStatusLast(Standard_False);
0348 Tgtend = Standard_True;
0349 MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol);
0350 CurrentLine->AddPoint(Psol);
0351 Rajout = Standard_True;
0352 seqAlone.Append(lines.Length() + 1);
0353 seqAjout.Append(lines.Length() + 1);
0354 }
0355 else if (aStatus == IntWalk_OK) {
0356 MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint);
0357 previousd3d = Func.Direction3d();
0358 previousd2d = Func.Direction2d();
0359 CurrentLine->AddPoint(previousPoint);
0360 }
0361 else if (aStatus == IntWalk_PointConfondu)
0362 {
0363 aNbIter --;
0364 }
0365 }
0366 }
0367 else { // no numerical solution
0368 PasC = PasC / 2.;
0369 PasCu = Abs(PasC*previousd2d.X());
0370 PasCv = Abs(PasC*previousd2d.Y());
0371 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
0372 if (CurrentLine->NbPoints()==1) break;
0373 Arrive = Standard_True;
0374 CurrentLine->AddStatusLast(Standard_False);
0375 Tgtend = Standard_True; // need check
0376 Rajout = Standard_True;
0377 seqAlone.Append(lines.Length() + 1);
0378 seqAjout.Append(lines.Length() + 1);
0379 }
0380 }
0381
0382 if(aNbIter < 0)
0383 break;
0384 } // end of started line
0385
0386 if (Arrive) {
0387 CurrentLine->SetTangencyAtEnd(Tgtend);
0388 lines.Append(CurrentLine);
0389 // modified by NIZHNY-MKK Fri Oct 27 12:59:29 2000.BEGIN
0390 movementdirectioninfo[I]=0;
0391 if(wd1[I].etat > 0)
0392 // modified by NIZHNY-MKK Fri Oct 27 12:59:42 2000.END
0393 wd1[I].etat=-wd1[I].etat;
0394
0395 //-- lbr le 5 juin 97 (Pb ds Contap)
0396 for(Standard_Integer av=1; av<=nbPath; av++) {
0397 // modified by NIZHNY-MKK Fri Oct 27 13:00:22 2000.BEGIN
0398 // if (wd1[av].etat > 11) {
0399 if ((wd1[av].etat > 11) ||
0400 ((av!=I) &&
0401 (av!=IndexOfPathPointDoNotCheck) &&
0402 (wd1[av].etat < -11) &&
0403 (movementdirectioninfo[av]!=0)))
0404 {
0405 // modified by NIZHNY-MKK Fri Oct 27 13:00:26 2000.END
0406 Standard_Real Uav=wd1[av].ustart;
0407 Standard_Real Vav=wd1[av].vstart;
0408 Standard_Real Uavp,Vavp;
0409 const IntSurf_PntOn2S &avP=CurrentLine->Value(CurrentLine->NbPoints());
0410 if (!reversed) {
0411 avP.ParametersOnS2(Uavp,Vavp);
0412 }
0413 else {
0414 avP.ParametersOnS1(Uavp,Vavp);
0415 }
0416 Uav-=Uavp;
0417 Vav-=Vavp;
0418 Uav*=0.001; Vav*=0.001;
0419 if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) {
0420 // modified by NIZHNY-MKK Fri Oct 27 13:01:38 2000.BEGIN
0421 // wd1[av].etat=-wd1[av].etat;
0422 if(wd1[av].etat < 0) {
0423 movementdirectioninfo[av] = 0;
0424 } else {
0425 wd1[av].etat=-wd1[av].etat;
0426 movementdirectioninfo[av] = StepSign;
0427 }
0428 // modified by NIZHNY-MKK Fri Oct 27 13:01:42 2000.END
0429 CurrentLine->AddStatusLast(Standard_True, av, Pnts1.Value(av));
0430 //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
0431 }
0432
0433 const IntSurf_PntOn2S &avPP=CurrentLine->Value(1);
0434 if (!reversed) {
0435 avPP.ParametersOnS2(Uavp,Vavp);
0436 }
0437 else {
0438 avPP.ParametersOnS1(Uavp,Vavp);
0439 }
0440 Uav=wd1[av].ustart;
0441 Vav=wd1[av].vstart;
0442 Uav-=Uavp;
0443 Vav-=Vavp;
0444 Uav*=0.001; Vav*=0.001;
0445 if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) {
0446 // modified by NIZHNY-MKK Fri Oct 27 13:02:49 2000.BEGIN
0447 // wd1[av].etat=-wd1[av].etat;
0448 if(wd1[av].etat < 0) {
0449 movementdirectioninfo[av] = 0;
0450 } else {
0451 wd1[av].etat=-wd1[av].etat;
0452 movementdirectioninfo[av] = -StepSign;
0453 }
0454 // modified by NIZHNY-MKK Fri Oct 27 13:02:52 2000.END
0455 //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
0456 CurrentLine->AddStatusFirst(Standard_False, Standard_True, av, Pnts1.Value(av));
0457 }
0458 }
0459 }
0460 }
0461 } //end of point processing
0462 } //end of all points
0463 }
0464
0465 // modified by NIZHNY-MKK Thu Nov 2 15:07:53 2000.BEGIN
0466 static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd,
0467 const TColStd_SequenceOfReal& Umult,
0468 const TColStd_SequenceOfReal& Vmult,
0469 const Standard_Real& prevUp,
0470 const Standard_Real& prevVp,
0471 const IntWalk_VectorOfInteger& nbMultiplicities,
0472 const math_Vector& tolerance,
0473 TheIWFunction& sp,
0474 math_Vector& UV,
0475 Standard_Integer& Irang) {
0476 Standard_Boolean Arrive = Standard_False;
0477 Standard_Real Dup, Dvp, Utest,Vtest;
0478 Standard_Real tolu = tolerance(1);
0479 Standard_Real tolv = tolerance(2);
0480 Standard_Integer i, j, k, N;
0481 for (i = 1; i < (int)wd.size(); i++) {
0482 if (wd[i].etat < -11) {
0483
0484 // debug jag see with isg
0485
0486 Utest = wd[i].ustart;
0487 Vtest = wd[i].vstart;
0488 Dup = prevUp - Utest;
0489 Dvp = prevVp - Vtest;
0490 if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) {
0491 Standard_Real UV1mUtest = UV(1)-Utest;
0492 Standard_Real UV2mVtest = UV(2)-Vtest;
0493 if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) ||
0494 ( Abs(UV1mUtest) < tolu
0495 && Abs(UV2mVtest) < tolv)) {
0496 Irang=i;
0497 Arrive = Standard_True;
0498 UV(1) = Utest;
0499 UV(2) = Vtest;
0500 }
0501 else if (nbMultiplicities[i] > 0) {
0502 N=0;
0503 for (k = 1; k < i; k++) {
0504 N+=nbMultiplicities[k];
0505 }
0506 for (j = N + 1; j <= N + nbMultiplicities[i]; j++) {
0507 if (((prevUp-Umult(j))*(UV(1)-Umult(j)) +
0508 (prevVp-Vmult(j))*(UV(2)-Vmult(j)) < 0) ||
0509 (Abs(UV(1)-Umult(j)) < tolu &&
0510 Abs(UV(2)-Vmult(j)) < tolv)) {
0511 Irang=i;
0512 Arrive = Standard_True;
0513 UV(1) = Utest;
0514 UV(2) = Vtest;
0515 break;
0516 }
0517 }
0518 }
0519 if (Arrive) {
0520 Standard_Real abidF[1], abidD[1][2];
0521 math_Vector bidF(abidF,1,1);
0522 math_Matrix bidD(abidD,1,1,1,2);
0523 sp.Values(UV,bidF,bidD);
0524 break;
0525 }
0526 }
0527 }
0528 }
0529 return Arrive;
0530 }
0531 // modified by NIZHNY-MKK Thu Nov 2 15:07:58 2000.END