// Copyright (c) 1995-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include // modified by NIZHNY-MKK Thu Nov 2 15:07:26 2000.BEGIN static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd, const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const Standard_Real& prevUp, const Standard_Real& prevVp, const IntWalk_VectorOfInteger& nbMultiplicities, const math_Vector& tolerance, TheIWFunction& sp, math_Vector& UV, Standard_Integer& Irang); // modified by NIZHNY-MKK Thu Nov 2 15:07:39 2000.END void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const ThePOPIterator& Pnts1, TheIWFunction& Func, Standard_Boolean& Rajout) // Processing of open line. // // 1) for any starting point, which is not passing and not tangent and not yet processed, // calculation of the step of advancement = step depending on the arrow and the maximum step. // // 2) calculate a point of approach (this point is on the tangent to the section // of distance = no point in the interior) // // 3) conditions { // (all calculated points do not exceed a point in the // list of starting points) // or // (all points do not form an open line going // from one border of the domain to the other or from a point tangent // to border or from 2 tangent points : single cases) // // 1) framing of approached point on borders if necessary (there is // calculation of step) // 2) calculation of the point // 3) if the point is not found the step is divided // 4) stpo tests // 5) calculation of the step depending on the arrow and the max step, // (TestDeflection) // stop possible. // end of conditions. { Standard_Integer I, N; Standard_Real aBornInf[2], aBornSup[2], aUVap[2]; math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2), UVap(aUVap,1,2); Standard_Real PasC, PasCu, PasCv; Standard_Boolean Arrive; // shows if the line ends Standard_Boolean Cadre; // shows if one is on border of the domain Standard_Boolean ArretAjout; //shows if one is on added point IntSurf_PntOn2S Psol; Handle(IntWalk_TheIWLine) CurrentLine; // line under construction Standard_Boolean Tgtend; IntWalk_StatusDeflection Status, StatusPrecedent; Standard_Integer NbDivision; // number of divisions of step for each section Standard_Integer StepSign; ThePointOfPath PathPnt; BornInf(1) = Um; BornSup(1) = UM; BornInf(2) = Vm; BornSup(2) = VM; math_FunctionSetRoot Rsnld(Func, tolerance); Standard_Integer nbPath = Pnts1.Length(); // modified by NIZHNY-MKK Fri Oct 27 12:32:34 2000.BEGIN NCollection_LocalArray movementdirectioninfoarr (nbPath + 1); Standard_Integer* movementdirectioninfo = movementdirectioninfoarr; for (I = 0; I <= nbPath; I++) { movementdirectioninfo[I] = 0; } // modified by NIZHNY-MKK Fri Oct 27 12:32:38 2000.END for (I = 1; I <= nbPath; I++) { //start point of the progression // if (wd1[I].etat > 11) { // modified by NIZHNY-MKK Fri Oct 27 12:33:37 2000.BEGIN if ((wd1[I].etat > 11) || ((wd1[I].etat < -11) && (movementdirectioninfo[I]!=0))) { // modified by NIZHNY-MKK Fri Oct 27 12:33:43 2000.END PathPnt = Pnts1.Value(I); CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator()); CurrentLine->SetTangencyAtBegining(Standard_False); Tgtend = Standard_False; CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt); UVap(1) = wd1[I].ustart; UVap(2) = wd1[I].vstart; MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint); previousd3d = Func.Direction3d(); previousd2d = Func.Direction2d(); CurrentLine->AddPoint(previousPoint); // modified by NIZHNY-MKK Fri Oct 27 12:34:32 2000.BEGIN if(movementdirectioninfo[I] !=0) { if(movementdirectioninfo[I] < 0) { StepSign = -1; CurrentLine->SetTangentVector(previousd3d.Reversed(),1); } else { StepSign = 1; CurrentLine->SetTangentVector(previousd3d,1); } } else { Standard_Real tyutuyt=ThePointOfPathTool::Direction3d(PathPnt) * previousd3d; if( tyutuyt < 0) { StepSign = -1; CurrentLine->SetTangentVector(previousd3d.Reversed(),1); } else { StepSign = 1; CurrentLine->SetTangentVector(previousd3d,1); } } // modified by NIZHNY-MKK Fri Oct 27 12:34:37 2000.END // Modified by Sergey KHROMOV - Tue Nov 20 10:41:45 2001 Begin wd1[I].etat = - abs(wd1[I].etat); movementdirectioninfo[I] = (movementdirectioninfo[I]==0) ? StepSign : 0; // Modified by Sergey KHROMOV - Tue Nov 20 10:41:56 2001 End // first step of advancement Standard_Real d2dx = Abs(previousd2d.X()); Standard_Real d2dy = Abs(previousd2d.Y()); if (d2dx < tolerance(1)) { PasC = pas * (VM-Vm)/d2dy; } else if (d2dy < tolerance(2)) { PasC = pas * (UM-Um)/d2dx; } else { PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy); } Arrive = Standard_False; ArretAjout = Standard_False; NbDivision = 0; StatusPrecedent = IntWalk_OK; // modified by NIZHNY-MKK Fri Oct 27 12:39:37 2000 Standard_Integer IndexOfPathPointDoNotCheck=0; Standard_Integer aNbIter = 10; while (!Arrive) { // as one of stop tests is not checked Cadre = Cadrage(BornInf,BornSup,UVap,PasC,StepSign); // Border? #ifdef CHRONO Chronrsnld.Start(); #endif Rsnld.Perform(Func,UVap,BornInf,BornSup); #ifdef CHRONO Chronrsnld.Stop(); #endif if (Cadre) { BornInf(1) = Um; BornSup(1) = UM; BornInf(2) = Vm; BornSup(2) = VM; } if (Rsnld.IsDone()) { if (Abs(Func.Root()) > Func.Tolerance()) { PasC = PasC / 2.0; PasCu = Abs(PasC*previousd2d.X()); PasCv = Abs(PasC*previousd2d.Y()); if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) { if (CurrentLine->NbPoints() == 1) break; Arrive = Standard_True; CurrentLine->AddStatusLast(Standard_False); Tgtend = Standard_True; // check Rajout = Standard_True; seqAjout.Append(lines.Length() + 1); } } else { // test stop Rsnld.Root(UVap); Arrive = TestArretPassage(Umult, Vmult, Func, UVap, N); if (Arrive) { Cadre = Standard_False; //in case if there is a frame and arrive at the same time } else { if (Rajout) { ArretAjout =TestArretAjout(Func, UVap, N, Psol); if (ArretAjout) { // jag 940615 Tgtend = lines.Value(N)->IsTangentAtEnd(); N = -N; } } // modified by NIZHNY-MKK Thu Nov 2 15:09:08 2000.BEGIN if(!(Rajout && ArretAjout)) { Standard_Real prevUp, prevVp; if (!reversed) { previousPoint.ParametersOnS2(prevUp, prevVp); } else { previousPoint.ParametersOnS1(prevUp, prevVp); } Arrive = TestPassedSolutionWithNegativeState(wd1, Umult, Vmult, prevUp, prevVp, nbMultiplicities, tolerance, Func, UVap, N); if(Arrive) { Cadre = Standard_False; } } // modified by NIZHNY-MKK Thu Nov 2 15:09:13 2000.END if (!ArretAjout && Cadre) { if (CurrentLine->NbPoints() == 1) break; // cancel the line TestArretCadre(Umult, Vmult, CurrentLine, Func, UVap, N); // if (N == 0) { if (N <= 0) { // jag 941017 MakeWalkingPoint(2, UVap(1), UVap(2), Func, Psol); Tgtend = Func.IsTangent(); N = -N; } } } Status = TestDeflection(Func, Arrive, UVap, StatusPrecedent, NbDivision,PasC,StepSign); StatusPrecedent = Status; if (Status == IntWalk_PasTropGrand) { Arrive = Standard_False; ArretAjout = Standard_False; Tgtend = Standard_False; // jag 940615 if (!reversed) { previousPoint.ParametersOnS2(UVap(1), UVap(2)); } else { previousPoint.ParametersOnS1(UVap(1), UVap(2)); } } else if (ArretAjout || Cadre) { Arrive = Standard_True; CurrentLine->AddStatusLast(Standard_False); if (Status != IntWalk_ArretSurPointPrecedent) { CurrentLine->AddPoint(Psol); } if (Cadre && N==0) { Rajout = Standard_True; seqAjout.Append(lines.Length()+1); } } else if (Status == IntWalk_ArretSurPointPrecedent) { if (CurrentLine->NbPoints() == 1) { //cancel the line Arrive = Standard_False; break; } Arrive = Standard_True; Rajout = Standard_True; seqAjout.Append(lines.Length() + 1); CurrentLine->AddStatusLast(Standard_False); Tgtend = Standard_True; // check } else if (Arrive) { if (CurrentLine->NbPoints() == 1 && // cancel the line (N == I || Status == IntWalk_PointConfondu) ) { // if N == I the main uv is probably lost // or the point is a point of accumulation // if point is confused the start data is bad Arrive = Standard_False; break; } // necessairily N > 0 jag 940617 // point of stop given at input PathPnt = Pnts1.Value(N); Standard_Integer etat1N=wd1[N].etat; // modified by NIZHNY-MKK Thu Nov 2 15:09:51 2000.BEGIN // if (etat1N < 11) { // passing point that is a stop if (Abs(etat1N) < 11) { // passing point that is a stop // modified by NIZHNY-MKK Thu Nov 2 15:12:11 2000.END if (Status == IntWalk_ArretSurPoint) { CurrentLine->AddStatusLast(Standard_False); Tgtend = Standard_True; // need check } else { Arrive = Standard_False; } CurrentLine->AddIndexPassing(N); } else { // point of stop given at input if (etat1N == 11) { Tgtend = Standard_True; } CurrentLine->AddStatusLast(Standard_True, N, PathPnt); } AddPointInCurrentLine(N,PathPnt,CurrentLine); if ((etat1N != 1 && etat1N != 11)) { // modified by NIZHNY-MKK Fri Oct 27 12:43:05 2000.BEGIN // wd1[N].etat= - wd1[N].etat; wd1[N].etat = - Abs(etat1N); movementdirectioninfo[N] = (movementdirectioninfo[N]==0) ? StepSign : 0; if(Arrive && movementdirectioninfo[N]!=0) { IndexOfPathPointDoNotCheck = N; } if(Arrive) { Rajout = Standard_True; seqAjout.Append(lines.Length() + 1); } // modified by NIZHNY-MKK Fri Oct 27 12:45:33 2000.END } } else if (Status == IntWalk_ArretSurPoint) { Arrive = Standard_True; CurrentLine->AddStatusLast(Standard_False); Tgtend = Standard_True; MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol); CurrentLine->AddPoint(Psol); Rajout = Standard_True; seqAjout.Append(lines.Length() + 1); } else if (Status == IntWalk_OK) { MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint); previousd3d = Func.Direction3d(); previousd2d = Func.Direction2d(); CurrentLine->AddPoint(previousPoint); } else if (Status == IntWalk_PointConfondu) { aNbIter --; } } } else { // no numerical solution PasC = PasC / 2.; PasCu = Abs(PasC*previousd2d.X()); PasCv = Abs(PasC*previousd2d.Y()); if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) { if (CurrentLine->NbPoints()==1) break; Arrive = Standard_True; CurrentLine->AddStatusLast(Standard_False); Tgtend = Standard_True; // need check Rajout = Standard_True; seqAjout.Append(lines.Length() + 1); } } if(aNbIter < 0) break; } // end of started line if (Arrive) { CurrentLine->SetTangencyAtEnd(Tgtend); lines.Append(CurrentLine); // modified by NIZHNY-MKK Fri Oct 27 12:59:29 2000.BEGIN movementdirectioninfo[I]=0; if(wd1[I].etat > 0) // modified by NIZHNY-MKK Fri Oct 27 12:59:42 2000.END wd1[I].etat=-wd1[I].etat; //-- lbr le 5 juin 97 (Pb ds Contap) for(Standard_Integer av=1; av<=nbPath; av++) { // modified by NIZHNY-MKK Fri Oct 27 13:00:22 2000.BEGIN // if (wd1[av].etat > 11) { if ((wd1[av].etat > 11) || ((av!=I) && (av!=IndexOfPathPointDoNotCheck) && (wd1[av].etat < -11) && (movementdirectioninfo[av]!=0))) { // modified by NIZHNY-MKK Fri Oct 27 13:00:26 2000.END Standard_Real Uav=wd1[av].ustart; Standard_Real Vav=wd1[av].vstart; Standard_Real Uavp,Vavp; const IntSurf_PntOn2S &avP=CurrentLine->Value(CurrentLine->NbPoints()); if (!reversed) { avP.ParametersOnS2(Uavp,Vavp); } else { avP.ParametersOnS1(Uavp,Vavp); } Uav-=Uavp; Vav-=Vavp; Uav*=0.001; Vav*=0.001; if(Abs(Uav)AddStatusLast(Standard_True, av, Pnts1.Value(av)); //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<Value(1); if (!reversed) { avPP.ParametersOnS2(Uavp,Vavp); } else { avPP.ParametersOnS1(Uavp,Vavp); } Uav=wd1[av].ustart; Vav=wd1[av].vstart; Uav-=Uavp; Vav-=Vavp; Uav*=0.001; Vav*=0.001; if(Abs(Uav)AddStatusFirst(Standard_False, Standard_True, av, Pnts1.Value(av)); } } } } } //end of point processing } //end of all points } // modified by NIZHNY-MKK Thu Nov 2 15:07:53 2000.BEGIN static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd, const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const Standard_Real& prevUp, const Standard_Real& prevVp, const IntWalk_VectorOfInteger& nbMultiplicities, const math_Vector& tolerance, TheIWFunction& sp, math_Vector& UV, Standard_Integer& Irang) { Standard_Boolean Arrive = Standard_False; Standard_Real Dup, Dvp, Utest,Vtest; Standard_Real tolu = tolerance(1); Standard_Real tolv = tolerance(2); Standard_Integer i, j, k, N; for (i = 1; i < (int)wd.size(); i++) { if (wd[i].etat < -11) { // debug jag see with isg Utest = wd[i].ustart; Vtest = wd[i].vstart; Dup = prevUp - Utest; Dvp = prevVp - Vtest; if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) { Standard_Real UV1mUtest = UV(1)-Utest; Standard_Real UV2mVtest = UV(2)-Vtest; if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) || ( Abs(UV1mUtest) < tolu && Abs(UV2mVtest) < tolv)) { Irang=i; Arrive = Standard_True; UV(1) = Utest; UV(2) = Vtest; } else if (nbMultiplicities[i] > 0) { N=0; for (k = 1; k < i; k++) { N+=nbMultiplicities[k]; } for (j = N + 1; j <= N + nbMultiplicities[i]; j++) { if (((prevUp-Umult(j))*(UV(1)-Umult(j)) + (prevVp-Vmult(j))*(UV(2)-Vmult(j)) < 0) || (Abs(UV(1)-Umult(j)) < tolu && Abs(UV(2)-Vmult(j)) < tolv)) { Irang=i; Arrive = Standard_True; UV(1) = Utest; UV(2) = Vtest; break; } } } if (Arrive) { Standard_Real abidF[1], abidD[1][2]; math_Vector bidF(abidF,1,1); math_Matrix bidD(abidD,1,1,1,2); sp.Values(UV,bidF,bidD); break; } } } } return Arrive; } // modified by NIZHNY-MKK Thu Nov 2 15:07:58 2000.END