From: jgv Date: Wed, 3 Jun 2015 15:21:57 +0000 (+0300) Subject: 0024694: Wrong processing of two surfaces (implicit and parametric) having tangential... X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=1d8d784527a06e6e7cfe53a2ffb1aa22eebae09b;p=occt-copy.git 0024694: Wrong processing of two surfaces (implicit and parametric) having tangential intersection: it is not found by intersector --- 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..10279499fa 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,32 @@ is 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..bccf6ccaa5 100644 --- a/src/Contap/Contap_SurfFunction.lxx +++ b/src/Contap/Contap_SurfFunction.lxx @@ -100,6 +100,36 @@ inline Standard_Real Contap_SurfFunction::Angle () const return myAng; } +inline Standard_Boolean Contap_SurfFunction::IsTangentSmooth() +{ + return Standard_False; +} + +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..f9e23ac93a 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,29 @@ is raises UndefinedDerivative from StdFail 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 +199,6 @@ is is static; - ISurface(me) returns TheISurface @@ -195,6 +223,8 @@ 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; diff --git a/src/IntImp/IntImp_ZerImpFunc.gxx b/src/IntImp/IntImp_ZerImpFunc.gxx index aba25b3410..0ae63ca55f 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,133 @@ Standard_Boolean IntImp_ZerImpFunc::IsTangent() Standard_Real N2d1v = d1v.SquareMagnitude(); tangent =(tgdu * tgdu <= N2grad_EpsAng2 * N2d1v) && (tgdv * tgdv <= N2grad_EpsAng2 * N2d1u); + +#ifdef DRAW + if (tangent) + { + Standard_Real SumSquare = tgdu * tgdu + tgdv * tgdv; + gp_Vec NormSURF = d1u ^ d1v; + cout<<"Tangent !!!"< NbTangentPoints. + + returns InteriorPoint from IntSurf + ---C++: return const& + ---C++: inline + + raises NotDone from StdFail, + OutOfRange from Standard + + is static; + fields - done : Boolean from Standard; - list : SequenceOfInteriorPoint from IntSurf; + done : Boolean from Standard; + list : SequenceOfInteriorPoint from IntSurf; + myTangentPoints : SequenceOfInteriorPoint from IntSurf; end SearchInside; diff --git a/src/IntStart/IntStart_SearchInside.gxx b/src/IntStart/IntStart_SearchInside.gxx index 53a2225cd0..bee9328cc3 100644 --- a/src/IntStart/IntStart_SearchInside.gxx +++ b/src/IntStart/IntStart_SearchInside.gxx @@ -25,6 +25,11 @@ #include +#ifdef DRAW +#include +#endif + + IntStart_SearchInside::IntStart_SearchInside (): done(Standard_False) {} @@ -49,6 +54,7 @@ void IntStart_SearchInside::Perform (TheFunction& Func, done = Standard_False; list.Clear(); + myTangentPoints.Clear(); Standard_Real aBinf[2], aBsup[2], aUVap[2], atoler[2]; math_Vector Binf(aBinf,1,2), Bsup(aBsup,1,2), UVap(aUVap,1,2), toler(atoler,1,2); gp_Pnt psol; @@ -118,6 +124,13 @@ void IntStart_SearchInside::Perform (TheFunction& Func, //-- +#ifdef DRAW + char* name = new char[100]; +#endif + + gp_Vec NullDir(0.,0.,0.); + gp_Vec2d NullDir2d(0.,0.); + for (i=1; i <= Nbsample+12; i++) { gp_Pnt2d s2d; gp_Pnt s3d; @@ -176,9 +189,9 @@ void IntStart_SearchInside::Perform (TheFunction& Func, Rsnld.Perform(Func,UVap,Binf,Bsup); if (Rsnld.IsDone()) { if (Abs(Func.Root()) <= Tol) { + psol = Func.Point(); + Rsnld.Root(UVap); if (!Func.IsTangent()) { - psol = Func.Point(); - Rsnld.Root(UVap); // On regarde si le point trouve est bien un nouveau point. j = 1; nbpt = list.Length(); @@ -207,9 +220,54 @@ void IntStart_SearchInside::Perform (TheFunction& Func, list.Append(IntSurf_InteriorPoint(psol,UVap(1),UVap(2), Func.Direction3d(), Func.Direction2d())); +#ifdef DRAW + gp_Pnt2d p2dsol(UVap(1),UVap(2)); + sprintf(name, "pp%d", list.Length()); + DrawTrSurf::Set(name, p2dsol); + sprintf(name, "p%d", list.Length()); + DrawTrSurf::Set(name, psol); +#endif } } - } + }//if (!Func.IsTangent()) + else //tangent point + { + Standard_Boolean IsNewTangentPoint = Standard_True; + for (j = 1; j <= myTangentPoints.Length(); j++) + { + const IntSurf_InteriorPoint& IPj = myTangentPoints(j); + const gp_Pnt& Pj = IPj.Value(); + if ( (Abs(Pj.X()-psol.X()) <= Epsilon) + && (Abs(Pj.Y()-psol.Y()) <= Epsilon) + && (Abs(Pj.Z()-psol.Z()) <= Epsilon) + && (Abs(UVap(1)-IPj.UParameter()) <= toler1) + && (Abs(UVap(2)-IPj.VParameter()) <= toler2) ) + { + IsNewTangentPoint = Standard_False; + break; + } + } + + if (IsNewTangentPoint) + { + situ = T->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, math_Vector& UV, Standard_Integer& Irang, - IntSurf_PntOn2S& Psol) + IntSurf_PntOn2S& Psol, + Standard_Boolean& OnPrevTangency) // test of stop on added points // these are the points on the natural biorder that were not given at input @@ -559,7 +777,8 @@ Standard_Boolean IntWalk_IWalking::TestArretAjout (Abs(UV(1)-U1) < tolerance(1) && Abs(UV(2)-V1) < tolerance(2))) { //jag 940615 Irang= -Abs(Irang); - Arrive = Standard_True; + Arrive = Standard_True; + OnPrevTangency = Line->IsTangency(); UV(1) = U1; UV(2) = V1; Standard_Real abidF[1], abidD[1][2]; diff --git a/src/IntWalk/IntWalk_IWalking_3.gxx b/src/IntWalk/IntWalk_IWalking_3.gxx index 6bc7b7a133..68a34fc3f0 100644 --- a/src/IntWalk/IntWalk_IWalking_3.gxx +++ b/src/IntWalk/IntWalk_IWalking_3.gxx @@ -66,10 +66,11 @@ 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 + Standard_Boolean OnPrevTangency; //shows if one is on added point of tangent line IntSurf_PntOn2S Psol; Handle(IntWalk_TheIWLine) CurrentLine; // line under construction Standard_Boolean Tgtend; @@ -80,6 +81,9 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, // number of divisions of step for each section Standard_Integer StepSign; + Standard_Integer StepSignTangent; + Standard_Integer SignOfBcoeff = 0; + Standard_Integer PrevSignOfBcoeff = SignOfBcoeff; ThePointOfPath PathPnt; @@ -105,11 +109,16 @@ 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); + IsTangentialIntersection = Standard_False; + SignOfBcoeff = PrevSignOfBcoeff = 0; UVap(1) = wd1[I].ustart; UVap(2) = wd1[I].vstart; MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint); @@ -118,27 +127,27 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, 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 +155,357 @@ 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; + OnPrevTangency = 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(); - 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(); + 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, OnPrevTangency); + 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, + CurrentLine->NbPoints(),ArretAjout,OnPrevTangency); + StatusPrecedent = Status; + + if (Status == IntWalk_ArretSurPoint && Func.IsTangent()) + { + PrevSignOfBcoeff = SignOfBcoeff; + gp_Vec newd3d; + gp_Dir2d newd2d; + Standard_Boolean IsDiscriminantNull; + if (ComputeDirOfTangentialIntersection(Func, StepSignTangent, + IsDiscriminantNull, SignOfBcoeff, + newd3d, newd2d)) + { + if (SignOfBcoeff == 0) //point of branching + Status = IntWalk_ArretSurPoint; + else + { + if (PrevSignOfBcoeff == 0 || + SignOfBcoeff == PrevSignOfBcoeff) + { + Status = IntWalk_OKtangent; + MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint); + previousd3d = newd3d; + previousd2d = newd2d; + CurrentLine->AddPoint(previousPoint); + } + else //change of sign of Bcoeff + { + MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol); + FindExactCuspPoint(Func, Psol, + PrevSignOfBcoeff, SignOfBcoeff); + Psol.ParametersOnSurface(reversed, UVap(1), UVap(2)); + Status = IntWalk_ArretSurPoint; + } } } } - 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); - } + + 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 && + !Func.IsTangent()) //continue the line because no tangent point + { + Status = IntWalk_OK; + StatusPrecedent = IntWalk_OK; + PasC = PasSav; + MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint); + previousd3d = Func.Direction3d(); + previousd2d = Func.Direction2d(); + CurrentLine->AddPoint(previousPoint); } - 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); - - 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; - } + 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; + 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) { + } + 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(); + 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; - - //-- 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"<SetTangencyAtEnd(Tgtend); + CurrentLine->SetTangency(IsTangentialIntersection); + 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; - const IntSurf_PntOn2S &avPP=CurrentLine->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 635ed1c674..bcf30c4993 100644 --- a/src/IntWalk/IntWalk_IWalking_4.gxx +++ b/src/IntWalk/IntWalk_IWalking_4.gxx @@ -13,13 +13,17 @@ // commercial license or contractual agreement. #include +#include +#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 ) + Standard_Boolean& Rajout ) // *********** Processing of closed line ********************** // // for any interior non-processed point @@ -41,7 +45,9 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, // // ******************************************************************** { - Standard_Integer I,N = 0; + //const Standard_Real GlobalValTol = 1.e-12; + + 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 @@ -52,6 +58,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, Standard_Boolean Arrive;// show if line ends Standard_Boolean Cadre; // show if on border of the domains Standard_Boolean ArretAjout; // show if on the added point + Standard_Boolean OnPrevTangency; //shows if one is on added point of tangent line IntSurf_PntOn2S Psol; Handle(IntWalk_TheIWLine) CurrentLine; //line under construction ThePointOfPath PathPnt; @@ -60,6 +67,9 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, Standard_Boolean Tgtbeg,Tgtend; Standard_Integer StepSign; + Standard_Integer StepSignTangent; + Standard_Integer SignOfBcoeff = 0; + Standard_Integer PrevSignOfBcoeff = SignOfBcoeff; IntWalk_StatusDeflection Status = IntWalk_OK, StatusPrecedent; Standard_Integer NbDivision ; // number of divisions of step @@ -79,6 +89,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, // Check borders for degeneracy: math_Matrix D(1,1,1,2); + math_Vector FuncVal(1,1); const Standard_Integer aNbSamplePnt = 10; Standard_Boolean isLeftDegeneratedBorder[2] = {Standard_True, Standard_True}; Standard_Boolean isRightDegeneratedBorder[2] = {Standard_True, Standard_True}; @@ -119,19 +130,30 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, } 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); - + +#ifdef DRAW + Standard_Real theU, theV; + ThePointOfLoopTool::Value2d(LoopPnt, theU, theV); + cout<<"LoopPnt("<AddPoint(previousPoint); CurrentLine->SetTangentVector(previousd3d,1); Tgtbeg = Standard_False; Tgtend = Standard_False; + IsTangentialIntersection = Standard_False; + SignOfBcoeff = PrevSignOfBcoeff = 0; Uvap(1) = wd2[I].ustart; Uvap(2) = wd2[I].vstart; @@ -142,54 +164,54 @@ 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; Arrive = Standard_False; ArretAjout = Standard_False; + OnPrevTangency = Standard_False; NbDivision = 0; 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); #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 (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 (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 + Tgtend = Standard_True; + } + } + else { // there is a solution Rsnld.Root(Uvap); // Avoid unitialized memory access. @@ -231,199 +253,629 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, } } - 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)); - } + 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 + //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, OnPrevTangency); + if (ArretAjout) { + if (N >0) { + Tgtend = lines.Value(N)->IsTangentAtEnd(); + N = -N; + } + else { + Tgtend = lines.Value(-N)->IsTangentAtBegining(); + } + Arrive = (wd2[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 = (wd2[I].etat == 12); // the line is open + } + } + Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent, + NbDivision,PasC,StepSign, + CurrentLine->NbPoints(),ArretAjout,OnPrevTangency); + 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; + 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 && + !Func.IsTangent()) //continue the line because no tangent point + { + Status = IntWalk_OK; + StatusPrecedent = IntWalk_OK; + PasC = PasSav; + + 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 { // 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 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; + 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 (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) + { + if (Func.IsTangent()) + { + PrevSignOfBcoeff = SignOfBcoeff; + gp_Vec newd3d; + gp_Dir2d newd2d; + Standard_Boolean IsDiscriminantNull; + ComputeDirOfTangentialIntersection(Func, StepSignTangent, + IsDiscriminantNull, SignOfBcoeff, + newd3d, newd2d); + if (!IsDiscriminantNull) //we have gone from tangent line + { + //take line from prevprevP to prevP + //project current solution onto this line + //direction of projection is direction to find null Discriminant again + //and then repeat + gp_Pnt2d prevprevP = CurrentLine->Value(CurrentLine->NbPoints()-1).ValueOnSurface(reversed); + gp_Pnt2d prevP = previousPoint.ValueOnSurface(reversed); + gp_Lin2d prevLine = gce_MakeLin2d(prevprevP, prevP); + //project + gp_Pnt2d CurSol(Uvap(1),Uvap(2)); + gp_XY LinLoc = prevLine.Location().XY(); + gp_XY LinDir = prevLine.Direction().XY(); + Standard_Real Parameter = (CurSol.XY() - LinLoc) * LinDir; + gp_Pnt2d ProjCurSol( LinLoc + Parameter * LinDir ); + Uvap(1) = ProjCurSol.X(); + Uvap(2) = ProjCurSol.Y(); + Func.Values(Uvap, FuncVal, D); + ///////// + ComputeDirOfTangentialIntersection(Func, StepSignTangent, + IsDiscriminantNull, SignOfBcoeff, + newd3d, newd2d); + } + if (SignOfBcoeff == 0) //point of branching + Status = IntWalk_ArretSurPoint; + else + { + if (PrevSignOfBcoeff == 0 || + SignOfBcoeff == PrevSignOfBcoeff) + { + Status = IntWalk_OKtangent; + MakeWalkingPoint(2, Uvap(1), Uvap(2), Func, previousPoint); + previousd3d = newd3d; + previousd2d = newd2d; + CurrentLine->AddPoint(previousPoint); } - else { - Tgtend = lines.Value(-N)->IsTangentAtBegining(); + else //change of sign of Bcoeff + { + MakeWalkingPoint(1, Uvap(1), Uvap(2), Func, Psol); + FindExactCuspPoint(Func, Psol, + PrevSignOfBcoeff, SignOfBcoeff); + Psol.ParametersOnSurface(reversed, Uvap(1), Uvap(2)); + //Status = IntWalk_ArretSurPoint; } - Arrive = (wd2[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; + 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; + SignOfBcoeff = PrevSignOfBcoeff = 0; + 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); + } } - Arrive = (wd2[I].etat == 12); // the line is open } } - Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent, - NbDivision,PasC,StepSign); - - 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 (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_PointConfondu) + { + aNbIter --; } - else if (ArretAjout || Cadre) { + } + } + 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); + } + } + + if(aNbIter < 0) + break; + }// end of started line + if (Arrive) { + CurrentLine->SetTangencyAtBegining(Tgtbeg); + CurrentLine->SetTangencyAtEnd(Tgtend); + CurrentLine->SetTangency(IsTangentialIntersection); + + lines.Append(CurrentLine); + wd2[I].etat=-wd2[I].etat; //mark point as processed + } + } //end of processing of start point + } //end of all start points - 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); - } + //Process inner tangent points + IsTangentialIntersection = Standard_True; + StepSign = 1; + StepSignTangent = 1; + SignOfBcoeff = 0; + PrevSignOfBcoeff = SignOfBcoeff; + 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); + ///// + gp_Vec newd3d; + gp_Dir2d newd2d; + Standard_Boolean IsDiscriminantNull; + if (!ComputeDirOfTangentialIntersection(Func, StepSignTangent, + IsDiscriminantNull, SignOfBcoeff, + newd3d, newd2d)) + continue; + previousd3d = newd3d; + previousd2d = newd2d; + //here and are defined + + CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator()); + CurrentLine->AddPoint(previousPoint); + CurrentLine->SetTangentVector(previousd3d,1); + Tgtbeg = Standard_False; + Tgtend = Standard_False; + SignOfBcoeff = PrevSignOfBcoeff = 0; + 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; + OnPrevTangency = 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 + + //Standard_Boolean ExactStartSolution = Standard_False; + /* + for (Standard_Integer ind = 1; ind <= 2; ind++) + { + if (Uvap(ind) <= BornInf(ind)) Uvap(ind) = BornInf(ind); + else if (Uvap(ind) > BornSup(ind)) Uvap(ind) = BornSup(ind); + } + Func.Values(Uvap, FuncVal, D); + */ + //if (FuncVal(1) >= GlobalValTol) + 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 + math_Vector NewUv(1,2), OldUv(1,2); + Rsnld.Root(NewUv); + gp_Pnt2d prevPnt2d, NewPnt2d(NewUv(1),NewUv(2)), Pnt2dap(Uvap(1),Uvap(2)); + prevPnt2d = previousPoint.ValueOnSurface(reversed); + gp_Vec2d PrevToAp(prevPnt2d, Pnt2dap); + gp_Vec2d PrevToNew(prevPnt2d, NewPnt2d); + if (PrevToAp * PrevToNew < 0. || + PrevToNew.Magnitude()/2. > PrevToAp.Magnitude()) //solution is bad + { + for (Standard_Integer ind = 1; ind <= 2; ind++) + { + if (Uvap(ind) <= BornInf(ind)) Uvap(ind) = BornInf(ind); + else if (Uvap(ind) > BornSup(ind)) Uvap(ind) = BornSup(ind); } - 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); - } - } + Func.Values(Uvap, FuncVal, D); } - 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 + Uvap = NewUv; + + 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, OnPrevTangency); + 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(),ArretAjout,OnPrevTangency); + 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; - Arrive = Standard_False; - PasC = PasSav; - Rajout = Standard_True; + 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; + } + 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 (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 && Func.IsTangent()) + { + PrevSignOfBcoeff = SignOfBcoeff; + gp_Vec newd3d; + gp_Dir2d newd2d; + Standard_Boolean IsDiscriminantNull; + ComputeDirOfTangentialIntersection(Func, StepSignTangent, + IsDiscriminantNull, SignOfBcoeff, + newd3d, newd2d); + if (SignOfBcoeff == 0) //point of branching + { + //Status = IntWalk_ArretSurPoint; } - } - 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; - 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 + { + if (PrevSignOfBcoeff == 0 || + SignOfBcoeff == PrevSignOfBcoeff) + { + Status = IntWalk_OKtangent; + MakeWalkingPoint(2, Uvap(1), Uvap(2), Func, previousPoint); + previousd3d = newd3d; + previousd2d = newd2d; + CurrentLine->AddPoint(previousPoint); } - else { - CurrentLine->AddStatusLast(Standard_False); - IntSurf_PntOn2S newP; - newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2)); - CurrentLine->AddPoint(newP); + else //change of sign of Bcoeff + { + MakeWalkingPoint(1, Uvap(1), Uvap(2), Func, Psol); + FindExactCuspPoint(Func, Psol, + PrevSignOfBcoeff, SignOfBcoeff); + Psol.ParametersOnSurface(reversed, Uvap(1), Uvap(2)); + //Status = IntWalk_ArretSurPoint; + } + } + 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; + SignOfBcoeff = PrevSignOfBcoeff = 0; Rajout = Standard_True; - seqAjout.Append(lines.Length()+1); + 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 if (Status == IntWalk_PointConfondu) - { - aNbIter --; - } - } - } - 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)) { + 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); - } - } - - if(aNbIter < 0) - break; + 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); - wd2[I].etat=-wd2[I].etat; //mark point as processed + CurrentLine->SetTangencyAtBegining(Tgtbeg); + CurrentLine->SetTangencyAtEnd(Tgtend); + CurrentLine->SetTangency(IsTangentialIntersection); + + lines.Append(CurrentLine); + wd3[I].etat = -wd3[I].etat; //mark point as processed } - } //end of processing of start point - } //end of all start points + } //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..c5c8910800 100644 --- a/src/IntWalk/IntWalk_IWalking_5.gxx +++ b/src/IntWalk/IntWalk_IWalking_5.gxx @@ -20,6 +20,7 @@ namespace { // because the angle is too great in 2d (U4) } + IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection (TheIWFunction& sp, const Standard_Boolean Finished, @@ -27,7 +28,10 @@ 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, + const Standard_Boolean ArretAjout, + const Standard_Boolean OnPrevTangency) { // Check the step of advancement, AND recalculate this step : // @@ -58,83 +62,90 @@ 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 = 0., Paramv = 0., StepU = 0., StepV = 0.; + Standard_Real Cosi = 0., Cosi2 = 0., Norme = 0.; 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 + Standard_Real TolNorm = gp::Resolution(); + if (CurNbPoints == 1 && ArretAjout && OnPrevTangency) + TolNorm = 1.e-10; + if (Norme <= TolNorm) { 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 (Abs(Du) < tolerance(1) && Abs(Dv) < tolerance(2)) + 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; + Standard_Real TolDu = tolerance(1), TolDv = tolerance(2); + if (CurNbPoints == 1 && ArretAjout && OnPrevTangency) + TolDu = TolDv = 1.e-7; + if (Abs(Du) < TolDu && Abs(Dv) < TolDv) 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 +154,136 @@ 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 - Step = Step / 2.; - Standard_Real 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; + 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; } } 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) { + + Standard_Real d2dx = Abs(sp.Direction2d().X()); + Standard_Real d2dy = Abs(sp.Direction2d().Y()); - if (d2dx < tolerance(1)) - { - Step = StepV/d2dy; - } - else if (d2dy < tolerance(2)) - { - Step = StepU/d2dx; - } - else - { - 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 = 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()); + + 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)); - } - } + 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 5bf7f34958..62271321e2 100644 --- a/src/IntWalk/IntWalk_IWalking_6.gxx +++ b/src/IntWalk/IntWalk_IWalking_6.gxx @@ -12,12 +12,112 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#include +#include + + #ifndef OCCT_DEBUG #define No_Standard_RangeError #define No_Standard_OutOfRange #endif +const Standard_Real TolDiscr = 1.e-8; +const Standard_Real TolB = 1.e-5; + +static Standard_Integer RealSign(const Standard_Real aValue) +{ + if (aValue >= 0.) + return 1; + else return -1; +} + +static Standard_Boolean ComputeB11orB22(TheIWFunction& sp, + Standard_Boolean& IsDiscriminantNull, + Standard_Integer& SignOfBcoeff, + gp_Vec& Pu, + gp_Vec& Pv, + Standard_Real& B11, + Standard_Real& B22, + Standard_Real& B12) +{ + gp_Vec 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; + + if (Abs(Discriminant) < TolDiscr) + { + IsDiscriminantNull = Standard_True; + if (Abs(B11) <= TolB && Abs(B22) <= TolB) + { +#ifdef DRAW + cout<<"Possible branching"< TolB) + { +#ifdef DRAW + cout<<"B11 = "<