From ca8e8f2120cf79eddccfc04b6e19b77a9cd2eab9 Mon Sep 17 00:00:00 2001 From: jgv Date: Thu, 6 Mar 2014 17:58:44 +0400 Subject: [PATCH] 0024694: Wrong processing of two surfaces (implicit and parametric) having tangential intersection: it is not found by intersector --- src/Contap/Contap_ContourGen_2.gxx | 7 +- src/Contap/Contap_SurfFunction.cdl | 53 ++- src/Contap/Contap_SurfFunction.lxx | 52 ++- src/IntImp/IntImp_ISurfaceTool.cdl | 13 +- src/IntImp/IntImp_ZerImpFunc.cdl | 55 ++- src/IntImp/IntImp_ZerImpFunc.gxx | 224 ++++++++++++- src/IntImp/IntImp_ZerImpFunc.lxx | 9 +- src/IntPatch/IntPatch_ImpPrmIntersection.cxx | 336 ++++++++++++------- src/IntStart/IntStart_SearchInside.cdl | 42 ++- src/IntStart/IntStart_SearchInside.gxx | 69 +++- src/IntStart/IntStart_SearchInside.lxx | 17 +- src/IntSurf/IntSurf_PntOn2S.cdl | 22 +- src/IntSurf/IntSurf_PntOn2S.cxx | 27 +- src/IntSurf/IntSurf_QuadricTool.cdl | 22 +- src/IntSurf/IntSurf_QuadricTool.cxx | 38 ++- src/IntSurf/IntSurf_QuadricTool.lxx | 16 +- src/IntWalk/IntWalk.cdl | 2 +- src/IntWalk/IntWalk_IWalking.cdl | 39 ++- src/IntWalk/IntWalk_IWalking_1.gxx | 27 +- src/IntWalk/IntWalk_IWalking_2.gxx | 252 ++++++++++++++ src/IntWalk/IntWalk_IWalking_3.gxx | 53 ++- src/IntWalk/IntWalk_IWalking_4.gxx | 324 +++++++++++++++++- src/IntWalk/IntWalk_IWalking_5.gxx | 55 ++- src/IntWalk/IntWalk_IWalking_6.gxx | 211 +++++++++++- 24 files changed, 1743 insertions(+), 222 deletions(-) diff --git a/src/Contap/Contap_ContourGen_2.gxx b/src/Contap/Contap_ContourGen_2.gxx index 1168dc42f3..741633a257 100644 --- a/src/Contap/Contap_ContourGen_2.gxx +++ b/src/Contap/Contap_ContourGen_2.gxx @@ -5,8 +5,8 @@ // // This file is part of Open CASCADE Technology software library. // -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. @@ -1338,7 +1338,8 @@ void Contap_ContourGen::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 bf8a8e7ec5..d771abc5f8 100644 --- a/src/Contap/Contap_SurfFunction.cdl +++ b/src/Contap/Contap_SurfFunction.cdl @@ -5,8 +5,8 @@ -- -- This file is part of Open CASCADE Technology software library. -- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published +-- This library is free software; you can redistribute it and / or modify it +-- under the terms of the GNU Lesser General Public version 2.1 as published -- by the Free Software Foundation, with special exception defined in the file -- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -- distribution for complete text of the license and disclaimer of any warranty. @@ -152,6 +152,12 @@ is returns Boolean from Standard is static; + IsTangentSmooth(me : in out) + + returns Boolean from Standard + ---C++: inline + is static; + Direction3d(me: in out) @@ -171,6 +177,49 @@ 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 Dir from gp; + D2U : out Vec from gp; + D2V : out Vec from gp; + D2UV : out Vec from gp) + ---C++: inline + is static; + + DerivativesAndNormalOnISurf(me; D1U : out Vec from gp; + D1V : out Vec from gp; + Normal : out Dir from gp; + D2U : out Vec from gp; + D2V : out Vec from gp; + D2UV : out Vec from gp) + ---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 9f2e61a726..59549b6f68 100644 --- a/src/Contap/Contap_SurfFunction.lxx +++ b/src/Contap/Contap_SurfFunction.lxx @@ -5,8 +5,8 @@ // // This file is part of Open CASCADE Technology software library. // -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. @@ -100,6 +100,54 @@ 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 void Contap_SurfFunction::DerivativesAndNormalOnPSurf(gp_Vec&, + gp_Vec&, + gp_Dir&, + gp_Vec&, + gp_Vec&, + gp_Vec&) +{ +} + +inline void Contap_SurfFunction::DerivativesAndNormalOnISurf(gp_Vec&, + gp_Vec&, + gp_Dir&, + gp_Vec&, + gp_Vec&, + gp_Vec&) const +{ +} + +inline Standard_Real Contap_SurfFunction::SquareTangentError() const +{ + return 0.; +} + inline Contap_TFunction Contap_SurfFunction::FunctionType () const { return myType; diff --git a/src/IntImp/IntImp_ISurfaceTool.cdl b/src/IntImp/IntImp_ISurfaceTool.cdl index cb704050cd..22f57de898 100644 --- a/src/IntImp/IntImp_ISurfaceTool.cdl +++ b/src/IntImp/IntImp_ISurfaceTool.cdl @@ -5,8 +5,8 @@ -- -- This file is part of Open CASCADE Technology software library. -- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published +-- This library is free software; you can redistribute it and / or modify it +-- under the terms of the GNU Lesser General Public version 2.1 as published -- by the Free Software Foundation, with special exception defined in the file -- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -- distribution for complete text of the license and disclaimer of any warranty. @@ -21,7 +21,9 @@ deferred generic class ISurfaceTool from IntImp -- implicit surface. -uses Vec from gp +uses + Vec from gp, + Pnt from gp is @@ -43,11 +45,14 @@ is ValueAndGradient(myclass; Is: ImplicitSurface; X, Y, Z: Real from Standard; - Val: out Real from Standard; Grad: out Vec from gp); + Val: out Real from Standard; + Grad: out Vec from gp; + D1U_ISurf, D1V_ISurf: out Vec from gp); ---Purpose: Returns the value and the gradient. + Tolerance(myclass; Is: ImplicitSurface ) ---Purpose: returns the tolerance of the zero of the implicit function diff --git a/src/IntImp/IntImp_ZerImpFunc.cdl b/src/IntImp/IntImp_ZerImpFunc.cdl index 5f6d3d0939..97978b08c0 100644 --- a/src/IntImp/IntImp_ZerImpFunc.cdl +++ b/src/IntImp/IntImp_ZerImpFunc.cdl @@ -5,8 +5,8 @@ -- -- This file is part of Open CASCADE Technology software library. -- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published +-- This library is free software; you can redistribute it and / or modify it +-- under the terms of the GNU Lesser General Public version 2.1 as published -- by the Free Software Foundation, with special exception defined in the file -- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -- distribution for complete text of the license and disclaimer of any warranty. @@ -31,6 +31,7 @@ uses Vector from math, Matrix from math, Pnt from gp, Vec from gp, + Dir from gp, Dir2d from gp raises UndefinedDerivative from StdFail @@ -141,6 +142,12 @@ is is static; + IsTangentSmooth(me : in out) + + returns Boolean from Standard + + is static; + Direction3d(me: in out) @@ -161,6 +168,43 @@ 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 Dir from gp; + D2U : out Vec from gp; + D2V : out Vec from gp; + D2UV : out Vec from gp) + is static; + + DerivativesAndNormalOnISurf(me; D1U : out Vec from gp; + D1V : out Vec from gp; + Normal : out Dir from gp; + D2U : out Vec from gp; + D2V : out Vec from gp; + D2UV : out Vec from gp) + is static; + + SquareTangentError(me) + returns Real from Standard + ---C++: inline + + is static; PSurface(me) @@ -170,7 +214,6 @@ is is static; - ISurface(me) returns TheISurface @@ -195,11 +238,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 d805625a0b..e719b42962 100644 --- a/src/IntImp/IntImp_ZerImpFunc.gxx +++ b/src/IntImp/IntImp_ZerImpFunc.gxx @@ -3,8 +3,8 @@ // // This file is part of Open CASCADE Technology software library. // -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. @@ -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,233 @@ 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 bb790e68e9..3008fa838c 100644 --- a/src/IntWalk/IntWalk_IWalking_3.gxx +++ b/src/IntWalk/IntWalk_IWalking_3.gxx @@ -3,8 +3,8 @@ // // This file is part of Open CASCADE Technology software library. // -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. @@ -14,6 +14,7 @@ #include #include +#include // modified by NIZHNY-MKK Thu Nov 2 15:07:26 2000.BEGIN @@ -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,16 +109,26 @@ 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) { @@ -238,8 +252,18 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, } } Status = TestDeflection(Func, Arrive, UVap, StatusPrecedent, - NbDivision,PasC,StepSign); + NbDivision,PasC,StepSign,CurrentLine->NbPoints()); StatusPrecedent = Status; + + 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; + } + if (Status == IntWalk_PasTropGrand) { Arrive = Standard_False; ArretAjout = Standard_False; @@ -324,18 +348,28 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, } } else if (Status == IntWalk_ArretSurPoint) { - Arrive = Standard_True; - CurrentLine->AddStatusLast(Standard_False); - Tgtend = Standard_True; + Arrive = Standard_True; + CurrentLine->AddStatusLast(Standard_False); + Tgtend = Standard_True; MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol); - CurrentLine->AddPoint(Psol); - Rajout = Standard_True; + //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) { 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); } } @@ -434,6 +468,7 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, } //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 6dfbf6cbb5..569c24c85d 100644 --- a/src/IntWalk/IntWalk_IWalking_4.gxx +++ b/src/IntWalk/IntWalk_IWalking_4.gxx @@ -3,8 +3,8 @@ // // This file is part of Open CASCADE Technology software library. // -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. @@ -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 @@ -77,21 +80,33 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, math_FunctionSetRoot Rsnld(Func,tolerance); Standard_Integer nbLoop = Pnts2.Length(); - + for (I = 1;I<=nbLoop;I++) { if (wd2[I].etat > 12) { // start point of closed line LoopPnt = Pnts2.Value(I); - previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt),reversed, + 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); + IntSurf_PntOn2S PrevPointFromFunc; + MakeWalkingPoint(11, theU, theV, Func, PrevPointFromFunc); + previousProj1 = Func.Projection1(); + previousProj2 = Func.Projection2(); + previousProj3 = Func.Projection3(); + previousProj4 = Func.Projection4(); + ///// CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator()); CurrentLine->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; @@ -191,7 +206,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, } } Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent, - NbDivision,PasC,StepSign); + NbDivision,PasC,StepSign,CurrentLine->NbPoints()); StatusPrecedent = Status; if (Status == IntWalk_PasTropGrand) {// division of the step Arrive = Standard_False; @@ -273,6 +288,15 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, 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 @@ -310,6 +334,10 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, 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); } } @@ -339,6 +367,288 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, } } //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); + ///// + ComputeDirOfTangentialIntersection(Func, StepSignTangent); + //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 fa7e62e888..cdf7297801 100644 --- a/src/IntWalk/IntWalk_IWalking_5.gxx +++ b/src/IntWalk/IntWalk_IWalking_5.gxx @@ -3,8 +3,8 @@ // // This file is part of Open CASCADE Technology software library. // -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. @@ -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 : // @@ -117,9 +125,16 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection 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) @@ -168,6 +183,34 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection 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.; + 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) { diff --git a/src/IntWalk/IntWalk_IWalking_6.gxx b/src/IntWalk/IntWalk_IWalking_6.gxx index cbf903ac24..a9647766aa 100644 --- a/src/IntWalk/IntWalk_IWalking_6.gxx +++ b/src/IntWalk/IntWalk_IWalking_6.gxx @@ -3,8 +3,8 @@ // // This file is part of Open CASCADE Technology software library. // -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published +// This library is free software; you can redistribute it and / or modify it +// under the terms of the GNU Lesser General Public version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. @@ -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 @@ -65,11 +68,201 @@ void IntWalk_IWalking::MakeWalkingPoint else { Standard_ConstructionError::Raise(); } +} + +void IntWalk_IWalking::ComputeDirOfTangentialIntersection(TheIWFunction& sp, + Standard_Integer& StepSignTangent) +{ + gp_Vec Pu, Pv, Puu, Puv, Pvv; + gp_Vec Iu, Iv, Iuu, Iuv, Ivv; + gp_Dir NormalP, NormalI; + + sp.DerivativesAndNormalOnPSurf(Pu, Pv, NormalP, Puu, Pvv, Puv); + sp.DerivativesAndNormalOnISurf(Iu, Iv, NormalI, Iuu, Ivv, Iuv); + + 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; + } + } } +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 +287,16 @@ 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(); + } if (N>0) { //departure point given at input PathPnt = Pnts1.Value(N); -- 2.39.5