diff --git a/src/Contap/Contap_Contour.cxx b/src/Contap/Contap_Contour.cxx index ec9a8b01cb..fb2db73a9e 100644 --- a/src/Contap/Contap_Contour.cxx +++ b/src/Contap/Contap_Contour.cxx @@ -1491,7 +1491,8 @@ void Contap_Contour::Perform if (seqpdep.Length() != 0 || seqpins.Length() != 0) { Contap_TheIWalking iwalk(Preci,Fleche,Pas); - iwalk.Perform(seqpdep,seqpins,mySFunc ,Surf); + IntSurf_SequenceOfInteriorPoint seqptang; //dummy + iwalk.Perform(seqpdep,seqpins,seqptang,mySFunc ,Surf); if(!iwalk.IsDone()) { return; } diff --git a/src/Contap/Contap_SurfFunction.cdl b/src/Contap/Contap_SurfFunction.cdl index ac5b4504ca..b61f70a850 100644 --- a/src/Contap/Contap_SurfFunction.cdl +++ b/src/Contap/Contap_SurfFunction.cdl @@ -148,6 +148,12 @@ is returns Boolean from Standard is static; + IsTangentSmooth(me : in out) + + returns Boolean from Standard + ---C++: inline + is static; + Direction3d(me: in out) @@ -167,6 +173,52 @@ is is static; + Projection1(me: in out) + returns Real from Standard + ---C++: inline + is static; + + Projection2(me: in out) + returns Real from Standard + ---C++: inline + is static; + + Projection3(me: in out) + returns Real from Standard + ---C++: inline + is static; + + Projection4(me: in out) + returns Real from Standard + ---C++: inline + is static; + + DerivativesAndNormalOnPSurf(me: in out; D1U : out Vec from gp; + D1V : out Vec from gp; + Normal : out Vec from gp; + D2U : out Vec from gp; + D2V : out Vec from gp; + D2UV : out Vec from gp) + returns Boolean from Standard + ---C++: inline + is static; + + DerivativesAndNormalOnISurf(me; D1U : out Vec from gp; + D1V : out Vec from gp; + Normal : out Vec from gp; + D2U : out Vec from gp; + D2V : out Vec from gp; + D2UV : out Vec from gp) + returns Boolean from Standard + ---C++: inline + is static; + + SquareTangentError(me) + returns Real from Standard + ---C++: inline + is static; + + FunctionType(me) returns TFunction from Contap diff --git a/src/Contap/Contap_SurfFunction.lxx b/src/Contap/Contap_SurfFunction.lxx index bad8a0560c..21f04d1456 100644 --- a/src/Contap/Contap_SurfFunction.lxx +++ b/src/Contap/Contap_SurfFunction.lxx @@ -100,6 +100,56 @@ inline Standard_Real Contap_SurfFunction::Angle () const return myAng; } +inline Standard_Boolean Contap_SurfFunction::IsTangentSmooth() +{ + return Standard_False; +} + +inline Standard_Real Contap_SurfFunction::Projection1() +{ + return 1.; +} + +inline Standard_Real Contap_SurfFunction::Projection2() +{ + return 1.; +} + +inline Standard_Real Contap_SurfFunction::Projection3() +{ + return 1.; +} + +inline Standard_Real Contap_SurfFunction::Projection4() +{ + return 1.; +} + +inline Standard_Boolean Contap_SurfFunction::DerivativesAndNormalOnPSurf(gp_Vec&, + gp_Vec&, + gp_Vec&, + gp_Vec&, + gp_Vec&, + gp_Vec&) +{ + return Standard_False; +} + +inline Standard_Boolean Contap_SurfFunction::DerivativesAndNormalOnISurf(gp_Vec&, + gp_Vec&, + gp_Vec&, + gp_Vec&, + gp_Vec&, + gp_Vec&) const +{ + return Standard_False; +} + +inline Standard_Real Contap_SurfFunction::SquareTangentError() const +{ + return 0.; +} + inline Contap_TFunction Contap_SurfFunction::FunctionType () const { return myType; diff --git a/src/IntImp/IntImp_ZerImpFunc.cdl b/src/IntImp/IntImp_ZerImpFunc.cdl index 18b74e02fd..f816e0a910 100644 --- a/src/IntImp/IntImp_ZerImpFunc.cdl +++ b/src/IntImp/IntImp_ZerImpFunc.cdl @@ -141,6 +141,12 @@ is is static; + IsTangentSmooth(me : in out) + + returns Boolean from Standard + + is static; + Direction3d(me: in out) @@ -161,6 +167,45 @@ is raises UndefinedDerivative from StdFail is static; + Projection1(me: in out) + returns Real from Standard + is static; + + Projection2(me: in out) + returns Real from Standard + is static; + + Projection3(me: in out) + returns Real from Standard + is static; + + Projection4(me: in out) + returns Real from Standard + is static; + + DerivativesAndNormalOnPSurf(me: in out; D1U : out Vec from gp; + D1V : out Vec from gp; + Normal : out Vec from gp; + D2U : out Vec from gp; + D2V : out Vec from gp; + D2UV : out Vec from gp) + returns Boolean from Standard + is static; + + DerivativesAndNormalOnISurf(me; D1U : out Vec from gp; + D1V : out Vec from gp; + Normal : out Vec from gp; + D2U : out Vec from gp; + D2V : out Vec from gp; + D2UV : out Vec from gp) + returns Boolean from Standard + is static; + + SquareTangentError(me) + returns Real from Standard + ---C++: inline + + is static; PSurface(me) @@ -170,7 +215,6 @@ is is static; - ISurface(me) returns TheISurface @@ -195,11 +239,17 @@ fields tgdu : Real from Standard; tgdv : Real from Standard; gradient : Vec from gp; + d1u_isurf : Vec from gp; + d1v_isurf : Vec from gp; derived : Boolean from Standard; d1u : Vec from gp; d1v : Vec from gp; d3d : Vec from gp; d2d : Dir2d from gp; + Proj1 : Real from Standard; + Proj2 : Real from Standard; + Proj3 : Real from Standard; + Proj4 : Real from Standard; end ZerImpFunc; diff --git a/src/IntImp/IntImp_ZerImpFunc.gxx b/src/IntImp/IntImp_ZerImpFunc.gxx index ef6e231694..f128aa4103 100644 --- a/src/IntImp/IntImp_ZerImpFunc.gxx +++ b/src/IntImp/IntImp_ZerImpFunc.gxx @@ -92,7 +92,7 @@ Standard_Boolean IntImp_ZerImpFunc::Values(const math_Vector& X, v = X(2); ThePSurfaceTool::D1(SURF, u, v, pntsol, d1u, d1v); TheISurfaceTool::ValueAndGradient(FUNC, pntsol.X(), pntsol.Y(), pntsol.Z(), - valf, gradient); + valf, gradient, d1u_isurf, d1v_isurf); F(1) = valf; D(1,1) = d1u.Dot(gradient); D(1,2) = d1v.Dot(gradient); @@ -118,17 +118,247 @@ Standard_Boolean IntImp_ZerImpFunc::IsTangent() Standard_Real N2d1v = d1v.SquareMagnitude(); tangent =(tgdu * tgdu <= N2grad_EpsAng2 * N2d1v) && (tgdv * tgdv <= N2grad_EpsAng2 * N2d1u); + + if (tangent) + { +#ifdef DRAW + Standard_Real SumSquare = tgdu * tgdu + tgdv * tgdv; +#endif + gp_Vec NormSURF = d1u ^ d1v; + Proj1 = gradient * d1u; + Proj2 = gradient * d1v; + Proj3 = NormSURF * d1u_isurf; + Proj4 = NormSURF * d1v_isurf; +#ifdef DRAW + cout<<"Tangent !!!"<Classify(gp_Pnt2d(UVap(1),UVap(2)), + Maxtoler1toler2,Standard_False); //-- ,Standard_False pour ne pas recadrer on Periodic + if (situ == TopAbs_IN) { + myTangentPoints.Append(IntSurf_InteriorPoint(psol,UVap(1),UVap(2), + NullDir, NullDir2d)); +#ifdef DRAW + gp_Pnt2d p2dsol(UVap(1),UVap(2)); + sprintf(name, "tpp%d", myTangentPoints.Length()); + //DrawTrSurf::Set(name, p2dsol); + sprintf(name, "tp%d", myTangentPoints.Length()); + //DrawTrSurf::Set(name, psol); + cout< 0) { + Utest = wd3[k].ustart; + Vtest = wd3[k].vstart; + + Utest/=deltau; + Vtest/=deltav; + + Standard_Real UV1mUtest=UV1-Utest; + Standard_Real UV2mVtest=UV2-Vtest; + if( (UV1mUtest-tolu2) + && (UV2mVtest-tolv2)) { + if(Index!=k) { + //-- cout<<"* etat2 : ("< 0 && wd1[i].etat < 11) { //test of crossing points + Utest = wd1[i].ustart; + Vtest = wd1[i].vstart; + Utest/=deltau; + Vtest/=deltav; + + if (((Up-Utest) * (UV1-Utest) + (Vp-Vtest) * (UV2-Vtest) < 0) || + (Abs(UV1-Utest) < tolu && Abs(UV2-Vtest) < tolv)) + Irang = i; + else if (nbMultiplicities[i] > 0) { + N=0; + for (k = 1; k < i; k++) N = N + nbMultiplicities[k]; + for (Standard_Integer j = N + 1; j <= N + nbMultiplicities[i]; j++) { + Standard_Real Umultj = Umult(j)/deltau; + Standard_Real Vmultj = Vmult(j)/deltav; + if (((Up-Umultj)*(UV1-Umultj) + + (Vp-Vmultj)*(UV2-Vmultj) < 0) || + (Abs(UV1-Umultj) < tolu && + Abs(UV2-Vmultj) < tolv)) { + Irang=i; + break; + } + } + } + } + } + return Arrive; +} Standard_Boolean IntWalk_IWalking::TestArretAjout (TheIWFunction& sp, diff --git a/src/IntWalk/IntWalk_IWalking_3.gxx b/src/IntWalk/IntWalk_IWalking_3.gxx index 6bc7b7a133..da3f6e0636 100644 --- a/src/IntWalk/IntWalk_IWalking_3.gxx +++ b/src/IntWalk/IntWalk_IWalking_3.gxx @@ -14,6 +14,7 @@ #include #include +#include // modified by NIZHNY-MKK Thu Nov 2 15:07:26 2000.BEGIN @@ -66,7 +67,7 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, 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_Real PasC, PasCu, PasCv, PasSav; 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 @@ -74,12 +75,15 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, Handle(IntWalk_TheIWLine) CurrentLine; // line under construction Standard_Boolean Tgtend; + Standard_Real TolTang = 5.e-28; + IntWalk_StatusDeflection Status, StatusPrecedent; Standard_Integer NbDivision; // number of divisions of step for each section Standard_Integer StepSign; + Standard_Integer StepSignTangent; ThePointOfPath PathPnt; @@ -105,40 +109,50 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, // 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); + PathPnt = Pnts1.Value(I); +#ifdef DRAW + cout<<"PathPnt("<SetTangencyAtBegining(Standard_False); Tgtend = Standard_False; CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt); + PossibleCuspPoint = Standard_False; + IsTangentialIntersection = Standard_False; UVap(1) = wd1[I].ustart; UVap(2) = wd1[I].vstart; MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint); previousd3d = Func.Direction3d(); previousd2d = Func.Direction2d(); + //prevtg = Standard_False; + previousProj1 = Func.Projection1(); + previousProj2 = Func.Projection2(); + previousProj3 = Func.Projection3(); + previousProj4 = Func.Projection4(); 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); - } + 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); - } + 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 +// 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 @@ -146,300 +160,348 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, Standard_Real d2dx = Abs(previousd2d.X()); Standard_Real d2dy = Abs(previousd2d.Y()); if (d2dx < tolerance(1)) { - PasC = pas * (VM-Vm)/d2dy; + PasC = pas * (VM-Vm)/d2dy; } else if (d2dy < tolerance(2)) { - PasC = pas * (UM-Um)/d2dx; + PasC = pas * (UM-Um)/d2dx; } else { - PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy); + PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy); } + PasSav = PasC; + 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; + //Standard_Integer aNbIter = 10; + while (!Arrive) { // as one of stop tests is not checked - Cadre = Cadrage(BornInf,BornSup,UVap,PasC,StepSign); - // Border? + + Cadre = Cadrage(BornInf,BornSup,UVap,PasC,StepSign); + // Border? #ifdef CHRONO - Chronrsnld.Start(); + Chronrsnld.Start(); #endif - Rsnld.Perform(Func,UVap,BornInf,BornSup); + Rsnld.Perform(Func,UVap,BornInf,BornSup); #ifdef CHRONO - Chronrsnld.Stop(); + 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 + 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(); + 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; - } - } - // 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,CurrentLine->NbPoints()); + StatusPrecedent = Status; + + if (Status == IntWalk_ArretSurPoint && !PossibleCuspPoint && Func.IsTangent()) + { + if (ComputeDirOfTangentialIntersection(Func, StepSignTangent)) + { + MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint); + previousProj1 = previousProj2 = previousProj3 = previousProj4 = 0.; + CurrentLine->AddPoint(previousPoint); + Status = IntWalk_OKtangent; } } - 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)); - } + + 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 && + PossibleCuspPoint && + !Func.IsTangent()) //continue the line because no cusp point and no tangent point + { + Status = IntWalk_OK; + StatusPrecedent = IntWalk_OK; + PasC = PasSav; + PossibleCuspPoint = Standard_False; + + MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint); + previousd3d = Func.Direction3d(); + previousd2d = Func.Direction2d(); + //prevtg = Standard_False; + previousProj1 = Func.Projection1(); + previousProj2 = Func.Projection2(); + previousProj3 = Func.Projection3(); + previousProj4 = Func.Projection4(); + CurrentLine->AddPoint(previousPoint); } - 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; + 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 + 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); + 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; + } - 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; + 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); + //jgv + if (PossibleCuspPoint && + Func.IsTangent() && Func.SquareTangentError() > TolTang) + FindExactTangentPoint(TolTang, Func, Psol); + ///// CurrentLine->AddPoint(Psol); Rajout = Standard_True; seqAjout.Append(lines.Length() + 1); - } - else if (Status == IntWalk_OK) { + } + else if (Status == IntWalk_OK) { MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint); - previousd3d = Func.Direction3d(); - previousd2d = Func.Direction2d(); - CurrentLine->AddPoint(previousPoint); - } + previousd3d = Func.Direction3d(); + previousd2d = Func.Direction2d(); + //prevtg = Standard_False; + previousProj1 = Func.Projection1(); + previousProj2 = Func.Projection2(); + previousProj3 = Func.Projection3(); + previousProj4 = Func.Projection4(); + CurrentLine->AddPoint(previousPoint); + } else if (Status == IntWalk_PointConfondu) { - aNbIter --; + //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; + } + } + 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; + 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)); - } - } - } + //-- 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, diff --git a/src/IntWalk/IntWalk_IWalking_4.gxx b/src/IntWalk/IntWalk_IWalking_4.gxx index bddf8ff15c..e63248cec9 100644 --- a/src/IntWalk/IntWalk_IWalking_4.gxx +++ b/src/IntWalk/IntWalk_IWalking_4.gxx @@ -13,11 +13,13 @@ // commercial license or contractual agreement. #include +#include void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const ThePOPIterator& Pnts1, const ThePOLIterator& Pnts2, + const ThePOLIterator& Pnts3, TheIWFunction& Func, Standard_Boolean& Rajout ) // *********** Processing of closed line ********************** @@ -42,7 +44,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, // ******************************************************************** { - Standard_Integer I,N = 0; + Standard_Integer I, N = 0; Standard_Real aBornInf[2], aBornSup[2], aUVap[2]; math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2); math_Vector Uvap(aUVap,1,2);// parameters of current approach @@ -61,6 +63,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, Standard_Boolean Tgtbeg,Tgtend; Standard_Integer StepSign; + Standard_Integer StepSignTangent; IntWalk_StatusDeflection Status,StatusPrecedent; Standard_Integer NbDivision ; // number of divisions of step @@ -79,19 +82,38 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, Standard_Integer nbLoop = Pnts2.Length(); for (I = 1;I<=nbLoop;I++) { - if (wd2[I].etat > 12) - { // start point of closed line + if (wd2[I].etat > 12) { // start point of closed line + LoopPnt = Pnts2.Value(I); - previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt),reversed, - wd2[I].ustart,wd2[I].vstart); + gp_Pnt thePoint = ThePointOfLoopTool::Value3d(LoopPnt); + previousPoint.SetValue(thePoint,reversed, + wd2[I].ustart,wd2[I].vstart); previousd3d = ThePointOfLoopTool::Direction3d(LoopPnt); previousd2d = ThePointOfLoopTool::Direction2d(LoopPnt); - + + Standard_Real theU, theV; + ThePointOfLoopTool::Value2d(LoopPnt, theU, theV); + +#ifdef DRAW + cout<<"LoopPnt("<AddPoint(previousPoint); CurrentLine->SetTangentVector(previousd3d,1); Tgtbeg = Standard_False; Tgtend = Standard_False; + PossibleCuspPoint = Standard_False; + IsTangentialIntersection = Standard_False; Uvap(1) = wd2[I].ustart; Uvap(2) = wd2[I].vstart; @@ -102,13 +124,13 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, Standard_Real d2dx = Abs(previousd2d.X()); Standard_Real d2dy = Abs(previousd2d.Y()); if (d2dx < tolerance(1)) { - PasC = pas * (VM-Vm)/d2dy; + PasC = pas * (VM-Vm)/d2dy; } else if (d2dy < tolerance(2)) { - PasC = pas * (UM-Um)/d2dx; + PasC = pas * (UM-Um)/d2dx; } else { - PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy); + PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy); } PasSav = PasC; @@ -119,233 +141,549 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, StatusPrecedent = IntWalk_OK; Standard_Integer aNbIter = 10; while (!Arrive) { // as no test of stop is passed - Cadre=Cadrage(BornInf,BornSup,Uvap,PasC, StepSign); // border? + Cadre=Cadrage(BornInf,BornSup,Uvap,PasC, StepSign); // border? #ifdef CHRONO - Chronrsnld.Start(); + Chronrsnld.Start(); #endif - Rsnld.Perform(Func,Uvap,BornInf,BornSup); + Rsnld.Perform(Func,Uvap,BornInf,BornSup); #ifdef CHRONO - Chronrsnld.Stop(); + Chronrsnld.Stop(); #endif - if (Cadre) { // update of limits. - BornInf(1) = Um;BornSup(1) = UM;BornInf(2) = Vm;BornSup(2) = VM; - } - if (Rsnld.IsDone()) { - if (Abs(Func.Root()) > Func.Tolerance()) { // no solution for the tolerance - PasC = PasC/2.; - PasCu = Abs(PasC*previousd2d.X()); - PasCv = Abs(PasC*previousd2d.Y()); + if (Cadre) { // update of limits. + BornInf(1) = Um;BornSup(1) = UM;BornInf(2) = Vm;BornSup(2) = VM; + } + if (Rsnld.IsDone()) { + if (Abs(Func.Root()) > Func.Tolerance()) { // no solution for the tolerance + 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->AddStatusFirstLast(Standard_False, - Standard_False,Standard_False); - Rajout = Standard_True; + if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) { + if (CurrentLine->NbPoints()==1) break; + Arrive = Standard_True; + CurrentLine->AddStatusFirstLast(Standard_False, + Standard_False,Standard_False); + Rajout = Standard_True; seqAjout.Append(lines.Length()+1); - Tgtend = Standard_True; - } - } - else { // there is a solution - Rsnld.Root(Uvap); - Arrive = TestArretPassage(Umult,Vmult,Uvap,I,Ipass); - if (Arrive) {//reset proper parameter to test the arrow. - Psol = CurrentLine->Value(1); - if (!reversed) { - Psol.ParametersOnS2(Uvap(1),Uvap(2)); - } - else { - Psol.ParametersOnS1(Uvap(1),Uvap(2)); - } + Tgtend = Standard_True; + } + } + else { // there is a solution + Rsnld.Root(Uvap); + Arrive = TestArretPassage(Umult,Vmult,Uvap,I,Ipass); + if (Arrive) {//reset proper parameter to test the arrow. + Psol = CurrentLine->Value(1); + if (!reversed) { + Psol.ParametersOnS2(Uvap(1),Uvap(2)); + } + else { + Psol.ParametersOnS1(Uvap(1),Uvap(2)); + } Cadre=Standard_False; - //in case if there is a frame and arrival at the same time - } - else { // modif jag 940615 - if (Rajout) { // test on added points - ArretAjout =TestArretAjout(Func,Uvap,N,Psol); - if (ArretAjout) { - if (N >0) { - Tgtend = lines.Value(N)->IsTangentAtEnd(); - N = -N; - } - else { - Tgtend = lines.Value(-N)->IsTangentAtBegining(); - } - Arrive = (wd2[I].etat == 12); - } - } + //in case if there is a frame and arrival at the same time + } + else { // modif jag 940615 - if (!ArretAjout&& Cadre) { // test on already marked points - 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(); // jag 940616 - N = -N; - } - Arrive = (wd2[I].etat == 12); // the line is open - } - } - Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent, - NbDivision,PasC,StepSign); + if (Rajout) { // test on added points + ArretAjout =TestArretAjout(Func,Uvap,N,Psol); + if (ArretAjout) { + if (N >0) { + Tgtend = lines.Value(N)->IsTangentAtEnd(); + N = -N; + } + else { + Tgtend = lines.Value(-N)->IsTangentAtBegining(); + } + Arrive = (wd2[I].etat == 12); + } + } - StatusPrecedent = Status; - if (Status == IntWalk_PasTropGrand) {// division of the step - Arrive = Standard_False; - ArretAjout = Standard_False; - Tgtend = Standard_False; // jag 940616 - if (!reversed) { - previousPoint.ParametersOnS2(Uvap(1),Uvap(2)); - } - else { - previousPoint.ParametersOnS1(Uvap(1),Uvap(2)); - } - } - else if (ArretAjout || Cadre) { + if (!ArretAjout&& Cadre) { // test on already marked points + 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(); // jag 940616 + N = -N; + } + Arrive = (wd2[I].etat == 12); // the line is open + } + } + Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent, + NbDivision,PasC,StepSign,CurrentLine->NbPoints()); + StatusPrecedent = Status; + if (Status == IntWalk_PasTropGrand) {// division of the step + Arrive = Standard_False; + ArretAjout = Standard_False; + Tgtend = Standard_False; // jag 940616 + if (!reversed) { + previousPoint.ParametersOnS2(Uvap(1),Uvap(2)); + } + else { + previousPoint.ParametersOnS1(Uvap(1),Uvap(2)); + } + } + else if (ArretAjout || Cadre) { - if (Arrive) { // line s is open - CurrentLine->AddStatusLast(Standard_False); - if (Status != IntWalk_ArretSurPointPrecedent) { - CurrentLine->AddPoint(Psol); - } - if (Cadre && N==0) { - Rajout = Standard_True; - seqAjout.Append(lines.Length()+1); - } - - } - else { // open - wd2[I].etat = 12; // declare it open - Tgtbeg = Tgtend; - Tgtend = Standard_False; - ArretAjout = Standard_False; - StepSign = -1; + if (Arrive) { // line s is open + CurrentLine->AddStatusLast(Standard_False); + if (Status != IntWalk_ArretSurPointPrecedent) { + CurrentLine->AddPoint(Psol); + } + if (Cadre && N==0) { + Rajout = Standard_True; + seqAjout.Append(lines.Length()+1); + } + + } + else { // open + wd2[I].etat = 12; // declare it open + Tgtbeg = Tgtend; + Tgtend = Standard_False; + ArretAjout = Standard_False; + StepSign = -1; StatusPrecedent = IntWalk_OK; - PasC = PasSav; - if (Status == IntWalk_ArretSurPointPrecedent) { - OpenLine(0,Psol,Pnts1,Func,CurrentLine); - } - else { - OpenLine(-lines.Length()-1,Psol,Pnts1,Func,CurrentLine); - } - if (Cadre && N==0) { - Rajout = Standard_True; - seqAjout.Append(-lines.Length()-1); - } - } + PasC = PasSav; + PossibleCuspPoint = Standard_False; + if (Status == IntWalk_ArretSurPointPrecedent) { + OpenLine(0,Psol,Pnts1,Func,CurrentLine); + } + else { + OpenLine(-lines.Length()-1,Psol,Pnts1,Func,CurrentLine); + } + if (Cadre && N==0) { + Rajout = Standard_True; + seqAjout.Append(-lines.Length()-1); + } + } + } + else if (Status == IntWalk_ArretSurPointPrecedent && + PossibleCuspPoint && + !Func.IsTangent()) //continue the line because no cusp point and no tangent point + { + Status = IntWalk_OK; + StatusPrecedent = IntWalk_OK; + PasC = PasSav; + PossibleCuspPoint = Standard_False; + + if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass); + previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2)); + previousd3d = Func.Direction3d(); + previousd2d = Func.Direction2d(); + previousProj1 = Func.Projection1(); + previousProj2 = Func.Projection2(); + previousProj3 = Func.Projection3(); + previousProj4 = Func.Projection4(); + CurrentLine->AddPoint(previousPoint); } - else if ( Status == IntWalk_ArretSurPointPrecedent) { - if (CurrentLine->NbPoints() == 1) { //cancel the line - Arrive = Standard_False; - break; - } - if (wd2[I].etat >12) { //the line should become open - wd2[I].etat = 12; //declare it open - ArretAjout = Standard_False; - OpenLine(0,Psol,Pnts1,Func,CurrentLine); - StepSign = -1; + else if ( Status == IntWalk_ArretSurPointPrecedent) { + if (CurrentLine->NbPoints() == 1) { //cancel the line + Arrive = Standard_False; + break; + } + if (wd2[I].etat >12) { //the line should become open + wd2[I].etat = 12; //declare it open + ArretAjout = Standard_False; + OpenLine(0,Psol,Pnts1,Func,CurrentLine); + StepSign = -1; StatusPrecedent = IntWalk_OK; - Arrive = Standard_False; - PasC = PasSav; - Rajout = Standard_True; + Arrive = Standard_False; + PasC = PasSav; + Rajout = Standard_True; seqAjout.Append(-lines.Length()-1); - } - else { // line s is open - Arrive =Standard_True; - CurrentLine->AddStatusLast(Standard_False); - Rajout = Standard_True; + } + else { // line s is open + Arrive =Standard_True; + CurrentLine->AddStatusLast(Standard_False); + Rajout = Standard_True; seqAjout.Append(lines.Length()+1); - } - } - else if (Arrive) { - if (wd2[I].etat > 12) { //line closed good case - CurrentLine->AddStatusFirstLast(Standard_True, - Standard_False,Standard_False); - CurrentLine->AddPoint(CurrentLine->Value(1)); - } - else if (N >0) { //point of stop given at input - PathPnt = Pnts1.Value(N); - CurrentLine->AddStatusLast(Standard_True,N,PathPnt); + } + } + else if (Arrive) { + if (wd2[I].etat > 12) { //line closed good case + CurrentLine->AddStatusFirstLast(Standard_True, + Standard_False,Standard_False); + CurrentLine->AddPoint(CurrentLine->Value(1)); + } + else if (N >0) { //point of stop given at input + PathPnt = Pnts1.Value(N); + CurrentLine->AddStatusLast(Standard_True,N,PathPnt); AddPointInCurrentLine(N,PathPnt,CurrentLine); - } + } + } + else if (Status == IntWalk_ArretSurPoint && + !PossibleCuspPoint && Func.IsTangent()) + { + ComputeDirOfTangentialIntersection(Func, StepSignTangent); + MakeWalkingPoint(2, Uvap(1), Uvap(2), Func, previousPoint); + previousProj1 = previousProj2 = previousProj3 = previousProj4 = 0.; + CurrentLine->AddPoint(previousPoint); + Status = IntWalk_OKtangent; } - else if (Status == IntWalk_ArretSurPoint) { - if (wd2[I].etat >12) { //line should become open - wd2[I].etat = 12; //declare it open - Tgtbeg = Standard_True; - Tgtend = Standard_False; + else if (Status == IntWalk_ArretSurPoint) { + if (wd2[I].etat >12) { //line should become open + wd2[I].etat = 12; //declare it open + Tgtbeg = Standard_True; + Tgtend = Standard_False; N= -lines.Length()-1; Psol.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2)); - OpenLine(N,Psol,Pnts1,Func,CurrentLine); - StepSign = -1; - Rajout = Standard_True; + OpenLine(N,Psol,Pnts1,Func,CurrentLine); + StepSign = -1; + Rajout = Standard_True; seqAjout.Append(N); StatusPrecedent = IntWalk_OK; - Arrive = Standard_False; - PasC = PasSav; - } - else { - Arrive = Standard_True; - if (Ipass!=0) { //point of passage, point of stop - PathPnt = Pnts1.Value(Ipass); - CurrentLine->AddStatusLast(Standard_True,Ipass,PathPnt); + Arrive = Standard_False; + PasC = PasSav; + } + else { + Arrive = Standard_True; + if (Ipass!=0) { //point of passage, point of stop + PathPnt = Pnts1.Value(Ipass); + CurrentLine->AddStatusLast(Standard_True,Ipass,PathPnt); AddPointInCurrentLine(Ipass,PathPnt,CurrentLine); - } - else { + } + else { CurrentLine->AddStatusLast(Standard_False); - IntSurf_PntOn2S newP; - newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2)); + IntSurf_PntOn2S newP; + newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2)); CurrentLine->AddPoint(newP); - Rajout = Standard_True; - seqAjout.Append(lines.Length()+1); + Rajout = Standard_True; + seqAjout.Append(lines.Length()+1); } - } - } - else if (Status == IntWalk_OK) { - if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass); - previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2)); - previousd3d = Func.Direction3d(); - previousd2d = Func.Direction2d(); - CurrentLine->AddPoint(previousPoint); - } + } + } + else if (Status == IntWalk_OK) { + if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass); + previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2)); + previousd3d = Func.Direction3d(); + previousd2d = Func.Direction2d(); + previousProj1 = Func.Projection1(); + previousProj2 = Func.Projection2(); + previousProj3 = Func.Projection3(); + previousProj4 = Func.Projection4(); + CurrentLine->AddPoint(previousPoint); + } else if (Status == IntWalk_PointConfondu) { aNbIter --; } - } - } - else { //no numerical solution NotDone - PasC = PasC/2.; - PasCu = Abs(PasC*previousd2d.X()); - PasCv = Abs(PasC*previousd2d.Y()); + } + } + else { //no numerical solution NotDone + PasC = PasC/2.; + PasCu = Abs(PasC*previousd2d.X()); + PasCv = Abs(PasC*previousd2d.Y()); - if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) { + if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) { if (CurrentLine->NbPoints() == 1) break; // cancel the line - Arrive = Standard_True; - CurrentLine->AddStatusFirstLast(Standard_False,Standard_False, - Standard_False); - Tgtend = Standard_True; - Rajout = Standard_True; - seqAjout.Append(lines.Length()+1); - } - } - + Arrive = Standard_True; + CurrentLine->AddStatusFirstLast(Standard_False,Standard_False, + Standard_False); + Tgtend = Standard_True; + Rajout = Standard_True; + seqAjout.Append(lines.Length()+1); + } + } + if(aNbIter < 0) break; }// end of started line if (Arrive) { - CurrentLine->SetTangencyAtBegining(Tgtbeg); - CurrentLine->SetTangencyAtEnd(Tgtend); - - lines.Append(CurrentLine); - wd2[I].etat=-wd2[I].etat; //mark point as processed + CurrentLine->SetTangencyAtBegining(Tgtbeg); + CurrentLine->SetTangencyAtEnd(Tgtend); + + lines.Append(CurrentLine); + wd2[I].etat=-wd2[I].etat; //mark point as processed } } //end of processing of start point } //end of all start points + + //Process inner tangent points + IsTangentialIntersection = Standard_True; + StepSign = 1; + StepSignTangent = 1; + Standard_Integer nbTang = Pnts3.Length(); + for (I = 1; I <= nbTang; I++) { + if (wd3[I].etat > 12) { // start point of closed line + + LoopPnt = Pnts3.Value(I); + gp_Pnt thePoint = ThePointOfLoopTool::Value3d(LoopPnt); + previousPoint.SetValue(thePoint,reversed, + wd3[I].ustart, wd3[I].vstart); + Standard_Real theU, theV; + ThePointOfLoopTool::Value2d(LoopPnt, theU, theV); + IntSurf_PntOn2S PrevPointFromFunc; + MakeWalkingPoint(11, theU, theV, Func, PrevPointFromFunc); + ///// + if (!ComputeDirOfTangentialIntersection(Func, StepSignTangent)) + continue; + //here and are defined + + CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator()); + CurrentLine->AddPoint(previousPoint); + CurrentLine->SetTangentVector(previousd3d,1); + Tgtbeg = Standard_False; + Tgtend = Standard_False; + PossibleCuspPoint = Standard_False; + Uvap(1) = wd3[I].ustart; + Uvap(2) = wd3[I].vstart; + + StepSign = 1; + + // 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); + } + + PasSav = PasC; + + Arrive = Standard_False; + ArretAjout = Standard_False; + NbDivision = 0; + StatusPrecedent = IntWalk_OK; + while (!Arrive) { // as no test of stop is passed + 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) { // update of limits. + BornInf(1) = Um;BornSup(1) = UM;BornInf(2) = Vm;BornSup(2) = VM; + } + if (Rsnld.IsDone()) { + if (Abs(Func.Root()) > Func.Tolerance()) { // no solution for the tolerance + 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->AddStatusFirstLast(Standard_False, + Standard_False,Standard_False); + Rajout = Standard_True; + seqAjout.Append(lines.Length()+1); + Tgtend = Standard_True; + } + } + else { // there is a solution + Rsnld.Root(Uvap); + Arrive = TestArretPassageTang(Umult,Vmult,Uvap,I,Ipass); + if (Arrive) {//reset proper parameter to test the arrow. + Psol = CurrentLine->Value(1); + if (!reversed) { + Psol.ParametersOnS2(Uvap(1),Uvap(2)); + } + else { + Psol.ParametersOnS1(Uvap(1),Uvap(2)); + } + Cadre = Standard_False; + //in case if there is a frame and arrival at the same time + } + else { // modif jag 940615 + + if (Rajout) { // test on added points + ArretAjout = TestArretAjout(Func,Uvap,N,Psol); + if (ArretAjout) { + if (N >0) { + Tgtend = lines.Value(N)->IsTangentAtEnd(); + N = -N; + } + else { + Tgtend = lines.Value(-N)->IsTangentAtBegining(); + } + Arrive = (wd3[I].etat == 12); + } + } + + if (!ArretAjout&& Cadre) { // test on already marked points + 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(); // jag 940616 + N = -N; + } + Arrive = (wd3[I].etat == 12); // the line is open + } + } + Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent, + NbDivision,PasC,StepSign,CurrentLine->NbPoints()); + StatusPrecedent = Status; + if (Status == IntWalk_PasTropGrand) {// division of the step + Arrive = Standard_False; + ArretAjout = Standard_False; + Tgtend = Standard_False; // jag 940616 + if (!reversed) { + previousPoint.ParametersOnS2(Uvap(1),Uvap(2)); + } + else { + previousPoint.ParametersOnS1(Uvap(1),Uvap(2)); + } + } + else if (ArretAjout || Cadre) { + + if (Arrive) { // line s is open + CurrentLine->AddStatusLast(Standard_False); + if (Status != IntWalk_ArretSurPointPrecedent) { + CurrentLine->AddPoint(Psol); + } + if (Cadre && N==0) { + Rajout = Standard_True; + seqAjout.Append(lines.Length()+1); + } + + } + else { // open + wd3[I].etat = 12; // declare it open + Tgtbeg = Tgtend; + Tgtend = Standard_False; + ArretAjout = Standard_False; + StepSign = -1; + StatusPrecedent = IntWalk_OK; + PasC = PasSav; + if (Status == IntWalk_ArretSurPointPrecedent) { + OpenLine(0,Psol,Pnts1,Func,CurrentLine); + } + else { + OpenLine(-lines.Length()-1,Psol,Pnts1,Func,CurrentLine); + } + 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; + } + if (wd3[I].etat >12) { //the line should become open + wd3[I].etat = 12; //declare it open + ArretAjout = Standard_False; + OpenLine(0,Psol,Pnts1,Func,CurrentLine); + StepSign = -1; + StatusPrecedent = IntWalk_OK; + Arrive = Standard_False; + PasC = PasSav; + Rajout = Standard_True; + seqAjout.Append(-lines.Length()-1); + } + else { // line s is open + Arrive = Standard_True; + CurrentLine->AddStatusLast(Standard_False); + Rajout = Standard_True; + seqAjout.Append(lines.Length()+1); + } + } + else if (Arrive) { + if (wd3[I].etat > 12) { //line closed good case + CurrentLine->AddStatusFirstLast(Standard_True, + Standard_False,Standard_False); + CurrentLine->AddPoint(CurrentLine->Value(1)); + } + else if (N >0) { //point of stop given at input + PathPnt = Pnts1.Value(N); + CurrentLine->AddStatusLast(Standard_True,N,PathPnt); + AddPointInCurrentLine(N,PathPnt,CurrentLine); + } + } + else if (Status == IntWalk_ArretSurPoint && + !PossibleCuspPoint && Func.IsTangent()) + { + ComputeDirOfTangentialIntersection(Func, StepSignTangent); + MakeWalkingPoint(2, Uvap(1), Uvap(2), Func, previousPoint); + CurrentLine->AddPoint(previousPoint); + Status = IntWalk_OKtangent; + } + else if (Status == IntWalk_ArretSurPoint) { + if (wd3[I].etat >12) { //line should become open + wd3[I].etat = 12; //declare it open + Tgtbeg = Standard_True; + Tgtend = Standard_False; + N= -lines.Length()-1; + Psol.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2)); + OpenLine(N,Psol,Pnts1,Func,CurrentLine); + StepSign = -1; + Rajout = Standard_True; + seqAjout.Append(N); + StatusPrecedent = IntWalk_OK; + Arrive = Standard_False; + PasC = PasSav; + } + else { + Arrive = Standard_True; + if (Ipass!=0) { //point of passage, point of stop + PathPnt = Pnts1.Value(Ipass); + CurrentLine->AddStatusLast(Standard_True,Ipass,PathPnt); + AddPointInCurrentLine(Ipass,PathPnt,CurrentLine); + } + else { + CurrentLine->AddStatusLast(Standard_False); + IntSurf_PntOn2S newP; + newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2)); + CurrentLine->AddPoint(newP); + Rajout = Standard_True; + seqAjout.Append(lines.Length()+1); + } + } + } + else if (Status == IntWalk_OK) { + if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass); + previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2)); + //previousd3d = Func.Direction3d(); + //previousd2d = Func.Direction2d(); + CurrentLine->AddPoint(previousPoint); + } + } + } + else { //no numerical solution NotDone + 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; // cancel the line + Arrive = Standard_True; + CurrentLine->AddStatusFirstLast(Standard_False,Standard_False, + Standard_False); + Tgtend = Standard_True; + Rajout = Standard_True; + seqAjout.Append(lines.Length()+1); + } + } + }// end of started line + if (Arrive) { + CurrentLine->SetTangencyAtBegining(Tgtbeg); + CurrentLine->SetTangencyAtEnd(Tgtend); + + lines.Append(CurrentLine); + wd3[I].etat = -wd3[I].etat; //mark point as processed + } + } //end of processing of tangent point + } //end of all tangent points } diff --git a/src/IntWalk/IntWalk_IWalking_5.gxx b/src/IntWalk/IntWalk_IWalking_5.gxx index 98dce89f3e..a898e27763 100644 --- a/src/IntWalk/IntWalk_IWalking_5.gxx +++ b/src/IntWalk/IntWalk_IWalking_5.gxx @@ -20,6 +20,13 @@ namespace { // because the angle is too great in 2d (U4) } +static Standard_Real RealSign(const Standard_Real aValue) +{ + if (aValue >= 0.) + return 1.; + else return -1.; +} + IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection (TheIWFunction& sp, const Standard_Boolean Finished, @@ -27,7 +34,8 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection const IntWalk_StatusDeflection StatusPrecedent, Standard_Integer& NbDivision, Standard_Real& Step, - const Standard_Integer StepSign) + const Standard_Integer StepSign, + const Standard_Integer CurNbPoints) { // Check the step of advancement, AND recalculate this step : // @@ -58,83 +66,84 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection //-- if epsilon is great enough (1e-11). In this case one loops //-- without ever changing the values sent to Rsnld. //--------------------------------------------------------------------------------- - Standard_Real Paramu = 0.0, Paramv = 0.0; - - if (!reversed) { - previousPoint.ParametersOnS2(Paramu, Paramv); - } - else - { - previousPoint.ParametersOnS1(Paramu, Paramv); - } - - const Standard_Real Du = UV(1) - Paramu; - const Standard_Real Dv = UV(2) - Paramv; - const Standard_Real Duv = Du * Du + Dv * Dv; + Standard_Real Paramu, Paramv, StepU,StepV; + Standard_Real Cosi, Cosi2, Norme; gp_Vec Corde(previousPoint.Value(), sp.Point()); - const Standard_Real Norme = Corde.SquareMagnitude(), - aTol = epsilon*Precision::PConfusion(); - - //if ((++NbPointsConfondusConsecutifs < 10) && (Norme <= epsilon)) { // the square is already taken in the constructor - if ((Norme <= epsilon) && ((Duv <= aTol) || (StatusPrecedent != IntWalk_OK))) - { // the square is already taken in the constructor + Norme = Corde.SquareMagnitude(); +// if (Norme <= epsilon*epsilon) { +// if (Norme <= epsilon) { // the square is already taken in the constructor + if (Norme <= gp::Resolution()) { Status = IntWalk_PointConfondu; if (StatusPrecedent == IntWalk_PasTropGrand) { return IntWalk_ArretSurPointPrecedent; } } else { - Standard_Real Cosi = Corde * previousd3d; - Standard_Real Cosi2 = 0.0; - - if (Cosi*StepSign >= 0.) {// angle 3d <= pi/2 !!!! - const Standard_Real aDiv = previousd3d.SquareMagnitude()*Norme; - if(aDiv == 0) - return Status; - Cosi2 = Cosi * Cosi / aDiv; + Cosi = Corde * previousd3d; + if (Cosi*StepSign < 0.) { // angle 3d > pi/2 !!!! + Cosi2 = 0.; + } + else { + Cosi2 = Cosi * Cosi / previousd3d.SquareMagnitude() / Norme; } if (Cosi2 < CosRef3D) { //angle 3d too great Step = Step /2.0; - Standard_Real StepU = Abs(Step*previousd2d.X()), - StepV = Abs(Step*previousd2d.Y()); + StepU = Abs(Step*previousd2d.X()); + StepV = Abs(Step*previousd2d.Y()); if (StepU < tolerance(1) && StepV < tolerance(2)) - Status = IntWalk_ArretSurPointPrecedent; + Status = IntWalk_ArretSurPointPrecedent; else - Status = IntWalk_PasTropGrand; + Status = IntWalk_PasTropGrand; return Status; } } + if (!reversed) { + previousPoint.ParametersOnS2(Paramu, Paramv); + } + else { + previousPoint.ParametersOnS1(Paramu, Paramv); + } + Standard_Real Du = UV(1) - Paramu; + Standard_Real Dv = UV(2) - Paramv; + Standard_Real Duv = Du * Du + Dv * Dv; if (Abs(Du) < tolerance(1) && Abs(Dv) < tolerance(2)) return IntWalk_ArretSurPointPrecedent; //confused point 2d - - Standard_Real Cosi = StepSign * (Du * previousd2d.X() + Dv * previousd2d.Y()); - + Cosi = StepSign * (Du * previousd2d.X() + + Dv * previousd2d.Y()); if (Cosi < 0 && Status == IntWalk_PointConfondu) return IntWalk_ArretSurPointPrecedent; // leave as step back // with confused point - if (sp.IsTangent()) - return IntWalk_ArretSurPoint; + if (IsTangentialIntersection) + { + if (sp.IsTangentSmooth()) + return IntWalk_ArretSurPoint; + } + else + { + if (sp.IsTangent()) + return IntWalk_ArretSurPoint; + } //if during routing one has subdivided more than MaxDivision for each //previous step, bug on the square; do nothing (experience U4) - if ((NbDivision < MaxDivision) && (Status != IntWalk_PointConfondu) && - (StatusPrecedent!= IntWalk_PointConfondu)) - { - Standard_Real Cosi2 = Cosi * Cosi / Duv; + if (NbDivision < MaxDivision && + Status != IntWalk_PointConfondu && + StatusPrecedent!= IntWalk_PointConfondu ) { + Cosi2 = Cosi * Cosi / Duv; if (Cosi2 < CosRef2D || Cosi < 0 ) { Step = Step / 2.0; - Standard_Real StepU = Abs(Step*previousd2d.X()), - StepV = Abs(Step*previousd2d.Y()); + StepU = Abs(Step*previousd2d.X()); + StepV = Abs(Step*previousd2d.Y()); if (StepU < tolerance(1) && StepV < tolerance(2)) - Status = IntWalk_ArretSurPointPrecedent; + Status = IntWalk_ArretSurPointPrecedent; else - Status = IntWalk_PasTropGrand; + Status = IntWalk_PasTropGrand; NbDivision = NbDivision + 1; return Status; } @@ -143,149 +152,164 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection Cosi2 = Cosi * Cosi / sp.Direction3d().SquareMagnitude() / Norme; if (Cosi2 < CosRef3D ){ //angle 3d too great Step = Step / 2.; - Standard_Real StepU = Abs(Step*previousd2d.X()), - StepV = Abs(Step*previousd2d.Y()); + StepU = Abs(Step*previousd2d.X()); + StepV = Abs(Step*previousd2d.Y()); if (StepU < tolerance(1) && StepV < tolerance(2)) - Status = IntWalk_ArretSurPoint; + Status = IntWalk_ArretSurPoint; else - Status = IntWalk_PasTropGrand; + Status = IntWalk_PasTropGrand; return Status; } Cosi = Du * sp.Direction2d().X() + - Dv * sp.Direction2d().Y(); + Dv * sp.Direction2d().Y(); Cosi2 = Cosi * Cosi / Duv; if (Cosi2 < CosRef2D || - sp.Direction2d() * previousd2d < 0) { - //angle 2d too great or change the side + sp.Direction2d() * previousd2d < 0) { + //angle 2d too great or change the side + Step = Step / 2.; + StepU = Abs(Step*previousd2d.X()); + StepV = Abs(Step*previousd2d.Y()); + if (StepU < tolerance(1) && StepV < tolerance(2)) + Status = IntWalk_ArretSurPointPrecedent; + else + Status = IntWalk_PasTropGrand; + return Status; + } + //jgv: detect possible cusp points + //point is suspicious to be a cusp point + //if there are 2 or more changes of sign + if (!IsTangentialIntersection && CurNbPoints > 1) + { + Standard_Real ChangeSign [5]; + ChangeSign[1] = RealSign(previousProj1) * RealSign(sp.Projection1()); + ChangeSign[2] = RealSign(previousProj2) * RealSign(sp.Projection2()); + ChangeSign[3] = RealSign(previousProj3) * RealSign(sp.Projection3()); + ChangeSign[4] = RealSign(previousProj4) * RealSign(sp.Projection4()); + Standard_Real SumChange = ChangeSign[1]+ChangeSign[2]+ChangeSign[3]+ChangeSign[4]; + if (SumChange <= 0 || //at least 2 changes of sign + (StatusPrecedent == IntWalk_PasTropGrand && SumChange <= 2)) //1 change of sign + { + PossibleCuspPoint = Standard_True; + if (SumChange <= 0) + MakeWalkingPoint(1, UV(1), UV(2), sp, PointAfterPossibleCuspPoint); Step = Step / 2.; - Standard_Real StepU = Abs(Step*previousd2d.X()), - StepV = Abs(Step*previousd2d.Y()); + StepU = Abs(Step*previousd2d.X()); + StepV = Abs(Step*previousd2d.Y()); if (StepU < tolerance(1) && StepV < tolerance(2)) Status = IntWalk_ArretSurPointPrecedent; else Status = IntWalk_PasTropGrand; return Status; + } } + ////////////////////////////////// } if (!Finished) { - if (Status == IntWalk_PointConfondu) - { - Standard_Real StepU = Min(Abs(1.5 * Du),pas*(UM-Um)), - StepV = Min(Abs(1.5 * Dv),pas*(VM-Vm)); + + if (Status == IntWalk_PointConfondu) { + StepU = Min(Abs(1.5 * Du),pas*(UM-Um)); + StepV = Min(Abs(1.5 * Dv),pas*(VM-Vm)); Standard_Real d2dx = Abs(previousd2d.X()); Standard_Real d2dy = Abs(previousd2d.Y()); - if (d2dx < tolerance(1)) - { - Step = StepV/d2dy; + if (d2dx < tolerance(1)) { + Step = StepV/d2dy; } - else if (d2dy < tolerance(2)) - { - Step = StepU/d2dx; + else if (d2dy < tolerance(2)) { + Step = StepU/d2dx; } - else - { - Step = Min(StepU/d2dx,StepV/d2dy); + else { + Step = Min(StepU/d2dx,StepV/d2dy); } } - else - { - // estimate the current vector. - // if vector/2<=current vector<= vector it is considered that the criterion - // is observed. - // otherwise adjust the step depending on the previous step + else { +// estimate the current vector. +// if vector/2<=current vector<= vector it is considered that the criterion +// is observed. +// otherwise adjust the step depending on the previous step - /* - Standard_Real Dist = Sqrt(Norme)/3.; - TColgp_Array1OfPnt Poles(1,4); - gp_Pnt POnCurv,Milieu; - Poles(1) = previousPoint.Value(); - Poles(4) = sp.Point(); - Poles(2) = Poles(1).XYZ() + - StepSign * Dist* previousd3d.Normalized().XYZ(); - Poles(3) = Poles(4).XYZ() - - StepSign * Dist*sp.Direction3d().Normalized().XYZ(); - BzCLib::PntPole(0.5,Poles,POnCurv); - Milieu = (Poles(1).XYZ() + Poles(4).XYZ())*0.5; - // FlecheCourante = Milieu.Distance(POnCurv); - Standard_Real FlecheCourante = Milieu.SquareDistance(POnCurv); - */ +/* + Standard_Real Dist = Sqrt(Norme)/3.; + TColgp_Array1OfPnt Poles(1,4); + gp_Pnt POnCurv,Milieu; + Poles(1) = previousPoint.Value(); + Poles(4) = sp.Point(); + Poles(2) = Poles(1).XYZ() + + StepSign * Dist* previousd3d.Normalized().XYZ(); + Poles(3) = Poles(4).XYZ() - + StepSign * Dist*sp.Direction3d().Normalized().XYZ(); + BzCLib::PntPole(0.5,Poles,POnCurv); + Milieu = (Poles(1).XYZ() + Poles(4).XYZ())*0.5; +// FlecheCourante = Milieu.Distance(POnCurv); + Standard_Real FlecheCourante = Milieu.SquareDistance(POnCurv); +*/ - // Direct calculation : - // POnCurv=(((p1+p2)/2.+(p2+p3)/2.)/2. + ((p2+p3)/2.+(p3+P4)/2.)/2.)/2. - // either POnCurv = p1/8. + 3.p2/8. + 3.p3/8. + p4/8. - // Or p2 = p1 + lambda*d1 et p3 = p4 - lambda*d4 - // So POnCurv = (p1 + p4)/2. + 3.*(lambda d1 - lambda d4)/8. - // Calculate the deviation with (p1+p4)/2. . So it is just necessary to calculate - // the norm (square) of 3.*lambda (d1 - d4)/8. - // either the norm of : - // 3.*(Sqrt(Norme)/3.)*StepSign*(d1-d4)/8. - // which produces, takin the square : - // Norme * (d1-d4).SquareMagnitude()/64. + // Direct calculation : + // POnCurv=(((p1+p2)/2.+(p2+p3)/2.)/2. + ((p2+p3)/2.+(p3+P4)/2.)/2.)/2. + // either POnCurv = p1/8. + 3.p2/8. + 3.p3/8. + p4/8. + // Or p2 = p1 + lambda*d1 et p3 = p4 - lambda*d4 + // So POnCurv = (p1 + p4)/2. + 3.*(lambda d1 - lambda d4)/8. + // Calculate the deviation with (p1+p4)/2. . So it is just necessary to calculate + // the norm (square) of 3.*lambda (d1 - d4)/8. + // either the norm of : + // 3.*(Sqrt(Norme)/3.)*StepSign*(d1-d4)/8. + // which produces, takin the square : + // Norme * (d1-d4).SquareMagnitude()/64. Standard_Real FlecheCourante = (previousd3d.Normalized().XYZ()-sp.Direction3d().Normalized().XYZ()).SquareModulus()*Norme/64.; // if (FlecheCourante <= 0.5*fleche) { - if (FlecheCourante <= 0.25*fleche*fleche) - { - Standard_Real d2dx = Abs(sp.Direction2d().X()); - Standard_Real d2dy = Abs(sp.Direction2d().Y()); - - Standard_Real StepU = Min(Abs(1.5*Du),pas*(UM-Um)), - StepV = Min(Abs(1.5*Dv),pas*(VM-Vm)); + if (FlecheCourante <= 0.25*fleche*fleche) { - if (d2dx < tolerance(1)) - { - Step = StepV/d2dy; - } - else if (d2dy < tolerance(2)) - { - Step = StepU/d2dx; - } - else - { - Step = Min(StepU/d2dx,StepV/d2dy); - } + Standard_Real d2dx = Abs(sp.Direction2d().X()); + Standard_Real d2dy = Abs(sp.Direction2d().Y()); + + StepU = Min(Abs(1.5*Du),pas*(UM-Um)); + StepV = Min(Abs(1.5*Dv),pas*(VM-Vm)); + + if (d2dx < tolerance(1)) { + Step = StepV/d2dy; + } + else if (d2dy < tolerance(2)) { + Step = StepU/d2dx; + } + else { + Step = Min(StepU/d2dx,StepV/d2dy); + } + } - else - { - //if (FlecheCourante > fleche) { // step too great - if (FlecheCourante > fleche*fleche) - { // step too great - Step = Step /2.; - Standard_Real StepU = Abs(Step*previousd2d.X()), - StepV = Abs(Step*previousd2d.Y()); - + else { +// if (FlecheCourante > fleche) { // step too great + if (FlecheCourante > fleche*fleche) { // step too great + Step = Step /2.; + StepU = Abs(Step*previousd2d.X()); + StepV = Abs(Step*previousd2d.Y()); if (StepU < tolerance(1) && StepV < tolerance(2)) Status = IntWalk_ArretSurPointPrecedent; else Status = IntWalk_PasTropGrand; - } - else - { - Standard_Real d2dx = Abs(sp.Direction2d().X()); - Standard_Real d2dy = Abs(sp.Direction2d().Y()); - - Standard_Real StepU = Min(Abs(1.5*Du),pas*(UM-Um)), - StepV = Min(Abs(1.5*Dv),pas*(VM-Vm)); + } + else { + Standard_Real d2dx = Abs(sp.Direction2d().X()); + Standard_Real d2dy = Abs(sp.Direction2d().Y()); - if (d2dx < tolerance(1)) - { - Step = Min(Step,StepV/d2dy); - } - else if (d2dy < tolerance(2)) - { - Step = Min(Step,StepU/d2dx); - } - else - { - Step = Min(Step,Min(StepU/d2dx,StepV/d2dy)); - } - } + StepU = Min(Abs(1.5*Du),pas*(UM-Um)); + StepV = Min(Abs(1.5*Dv),pas*(VM-Vm)); + + if (d2dx < tolerance(1)) { + Step = Min(Step,StepV/d2dy); + } + else if (d2dy < tolerance(2)) { + Step = Min(Step,StepU/d2dx); + } + else { + Step = Min(Step,Min(StepU/d2dx,StepV/d2dy)); + } + } } } } diff --git a/src/IntWalk/IntWalk_IWalking_6.gxx b/src/IntWalk/IntWalk_IWalking_6.gxx index cbf903ac24..cfba8296ec 100644 --- a/src/IntWalk/IntWalk_IWalking_6.gxx +++ b/src/IntWalk/IntWalk_IWalking_6.gxx @@ -12,6 +12,10 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#include +#include + + #ifndef DEB #define No_Standard_RangeError #define No_Standard_OutOfRange @@ -39,7 +43,6 @@ void IntWalk_IWalking::MakeWalkingPoint IntSurf_PntOn2S& Psol ) { - // Case == 1 : make a WalkinkPoint. // Case == 2 : make a WalkinkPoint. // The computation of the tangency on is done @@ -60,16 +63,212 @@ void IntWalk_IWalking::MakeWalkingPoint UV(1) = U; UV(2) = V; sp.Values(UV, FF, DD); - MakeWalkingPoint(Case - 10, U, V, sp, Psol); + MakeWalkingPoint(Case - 10, U, V, sp, Psol); } else { Standard_ConstructionError::Raise(); } - - } +Standard_Boolean + IntWalk_IWalking::ComputeDirOfTangentialIntersection(TheIWFunction& sp, + Standard_Integer& StepSignTangent) +{ + gp_Vec Pu, Pv, Puu, Puv, Pvv; + gp_Vec Iu, Iv, Iuu, Iuv, Ivv; + gp_Vec NormalP, NormalI; + if (!sp.DerivativesAndNormalOnPSurf(Pu, Pv, NormalP, Puu, Pvv, Puv)) + return Standard_False; + if (!sp.DerivativesAndNormalOnISurf(Iu, Iv, NormalI, Iuu, Ivv, Iuv)) + return Standard_False; + + Standard_Real Lp, Mp, Np, Li, Mi, Ni; //second fundamental form coefficients + Lp = Puu * NormalP; + Mp = Puv * NormalP; + Np = Pvv * NormalP; + Li = Iuu * NormalI; + Mi = Iuv * NormalI; + Ni = Ivv * NormalI; + + gp_Vec Normal; + if (NormalP * NormalI < 0.) + NormalI.Reverse(); + Normal.SetXYZ(0.5*(NormalP.XYZ() + NormalI.XYZ())); + Normal.Normalize(); + + Standard_Real A11, A12, A21, A22; + Standard_Real NormIdotNorm = (Iu ^ Iv) * Normal; + A11 = ((Pu ^ Iv) * Normal) / NormIdotNorm; + A12 = ((Pv ^ Iv) * Normal) / NormIdotNorm; + A21 = ((Iu ^ Pu) * Normal) / NormIdotNorm; + A22 = ((Iu ^ Pv) * Normal) / NormIdotNorm; + + Standard_Real B11, B12, B22; + B11 = A11*A11*Li + 2*A11*A21*Mi + A21*A21*Ni - Lp; + B12 = A11*A12*Li + (A11*A22 + A21*A12)*Mi + A21*A22*Ni - Mp; + B22 = A12*A12*Li + 2*A12*A22*Mi + A22*A22*Ni - Np; + + Standard_Real Discriminant = B12*B12 - B11*B22; +#ifdef DRAW + cout<<"Discriminant = "< TolB) + { + Standard_Real CoefPu = -B12/B11; + NewPreviousD3d = CoefPu*Pu + Pv; + NewPreviousD3d.Normalize(); + NewPreviousD2d = gp_Dir2d(CoefPu, 1.); + } + else + { + Standard_Real CoefPv = -B12/B22; + NewPreviousD3d = Pu + CoefPv*Pv; + NewPreviousD3d.Normalize(); + NewPreviousD2d = gp_Dir2d(1., CoefPv); + } + + if (!IsTangentialIntersection) + { + IsTangentialIntersection = Standard_True; + if (NewPreviousD3d * previousd3d < 0) + StepSignTangent = -1; + else + StepSignTangent = 1; + } + previousd3d = StepSignTangent * NewPreviousD3d; + previousd2d = StepSignTangent * NewPreviousD2d; + } + } + + return Standard_True; +} + +void IntWalk_IWalking::FindExactTangentPoint(const Standard_Real TolTang, + TheIWFunction& sp, + IntSurf_PntOn2S& Psol) + +{ + IntSurf_PntOn2S TangentPoint = Psol; + + IntSurf_PntOn2S Pfirst, Plast; + + Standard_Real newU, newV; + IntSurf_PntOn2S newPoint; + + Standard_Real MinOffset = Sqrt(tolerance(1)*tolerance(1) + tolerance(2)*tolerance(2)); + + gp_Pnt2d prevP2d = previousPoint.ValueOnSurface(reversed); + gp_Pnt2d TangP2d = TangentPoint.ValueOnSurface(reversed); + gp_Pnt2d EndP2d = PointAfterPossibleCuspPoint.ValueOnSurface(reversed); + Handle(Geom2d_Line) Line1 = GCE2d_MakeLine(TangP2d, prevP2d); + Handle(Geom2d_Line) Line2 = GCE2d_MakeLine(TangP2d, EndP2d); + + Standard_Real Dist1 = prevP2d.Distance(TangP2d); + Standard_Real Dist2 = TangP2d.Distance(EndP2d); + Standard_Real Dist = (Dist1 < Dist2)? Dist1 : Dist2; + Standard_Real Offset = 0.01*Dist; + if (Offset < MinOffset) + Offset = MinOffset; + + Standard_Real TangentError = sp.SquareTangentError(); + + gp_Pnt2d DeltaUV1 = Line1->Value(Offset); + gp_Pnt2d DeltaUV2 = Line2->Value(Offset); + IntSurf_PntOn2S DeltaPnt1, DeltaPnt2; + + MakeWalkingPoint(11, DeltaUV1.X(), DeltaUV1.Y(), sp, DeltaPnt1); + Standard_Boolean IsTangentPoint = sp.IsTangent(); + Standard_Real DeltaError1 = sp.SquareTangentError(); + MakeWalkingPoint(11, DeltaUV2.X(), DeltaUV2.Y(), sp, DeltaPnt2); + IsTangentPoint = sp.IsTangent(); + Standard_Real DeltaError2 = sp.SquareTangentError(); + + if (DeltaError1 <= TangentError && TangentError <= DeltaError2) + { + Pfirst = previousPoint; + Plast = TangentPoint; + Dist = Dist1; + } + else if (DeltaError1 >= TangentError && TangentError >= DeltaError2) + { + Pfirst = TangentPoint; + Plast = PointAfterPossibleCuspPoint; + Dist = Dist2; + } + else + { + Pfirst = DeltaPnt1; + Plast = DeltaPnt2; + Dist = DeltaUV1.Distance(DeltaUV2); + } + + Standard_Real newError; + for (;;) + { + Standard_Real Ufirst, Vfirst, Ulast, Vlast; + Pfirst.ParametersOnSurface(reversed, Ufirst, Vfirst); + Plast.ParametersOnSurface(reversed, Ulast, Vlast); + + newU = 0.5*(Ufirst + Ulast); + newV = 0.5*(Vfirst + Vlast); + + if (Abs(newU - Ufirst) < tolerance(1) && + Abs(newV - Vfirst) < tolerance(2)) + break; + + MakeWalkingPoint(11, newU, newV, sp, newPoint); + + IsTangentPoint = sp.IsTangent(); + newError = sp.SquareTangentError(); + if (newError <= TolTang) + break; + + gp_Pnt2d newP2d(newU, newV); + Handle(Geom2d_Line) newLine = GCE2d_MakeLine(newP2d, Plast.ValueOnSurface(reversed)); + Dist *= 0.5; + Offset = 0.01*Dist; + + DeltaUV1 = newLine->Value(-Offset); + DeltaUV2 = newLine->Value(Offset); + + MakeWalkingPoint(11, DeltaUV1.X(), DeltaUV1.Y(), sp, DeltaPnt1); + IsTangentPoint = sp.IsTangent(); + DeltaError1 = sp.SquareTangentError(); + MakeWalkingPoint(11, DeltaUV2.X(), DeltaUV2.Y(), sp, DeltaPnt2); + IsTangentPoint = sp.IsTangent(); + DeltaError2 = sp.SquareTangentError(); + + if (DeltaError1 <= newError && newError <= DeltaError2) + Plast = newPoint; + else if (DeltaError1 >= newError && newError >= DeltaError2) + Pfirst = newPoint; + else + { + Pfirst = DeltaPnt1; + Plast = DeltaPnt2; + Dist = DeltaUV1.Distance(DeltaUV2); + } + } + + Psol = newPoint; +} void IntWalk_IWalking::OpenLine(const Standard_Integer N, const IntSurf_PntOn2S& Psol, @@ -94,8 +293,20 @@ void IntWalk_IWalking::OpenLine(const Standard_Integer N, previousPoint.ParametersOnS1(UV(1),UV(2)); } sp.Values(UV, FF, DD); - previousd3d = sp.Direction3d(); - previousd2d = sp.Direction2d(); + if (sp.IsTangent()) + { + Standard_Integer theSign = 1; + ComputeDirOfTangentialIntersection(sp, theSign); + } + else + { + previousd3d = sp.Direction3d(); + previousd2d = sp.Direction2d(); + previousProj1 = sp.Projection1(); + previousProj2 = sp.Projection2(); + previousProj3 = sp.Projection3(); + previousProj4 = sp.Projection4(); + } if (N>0) { //departure point given at input PathPnt = Pnts1.Value(N);