From: jgv Date: Fri, 30 Mar 2018 10:30:44 +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=refs%2Fheads%2FCR24694_28;p=occt-copy.git 0024694: Wrong processing of two surfaces (implicit and parametric) having tangential intersection: it is not found by intersector Multiple changes. --- diff --git a/src/BRepApprox/BRepApprox_TheZerImpFuncOfTheImpPrmSvSurfacesOfApprox.hxx b/src/BRepApprox/BRepApprox_TheZerImpFuncOfTheImpPrmSvSurfacesOfApprox.hxx index e863ce2a29..0b0dd78eda 100644 --- a/src/BRepApprox/BRepApprox_TheZerImpFuncOfTheImpPrmSvSurfacesOfApprox.hxx +++ b/src/BRepApprox/BRepApprox_TheZerImpFuncOfTheImpPrmSvSurfacesOfApprox.hxx @@ -81,10 +81,18 @@ public: Standard_EXPORT Standard_Boolean IsTangent(); + Standard_EXPORT Standard_Boolean IsTangentSmooth() ; + const gp_Vec& Direction3d(); const gp_Dir2d& Direction2d(); + Standard_EXPORT Standard_Boolean DerivativesAndNormalOnPSurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) ; + + Standard_EXPORT Standard_Boolean DerivativesAndNormalOnISurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) const; + + Standard_Real SquareTangentError() const; + const BRepAdaptor_Surface& PSurface() const; const IntSurf_Quadric& ISurface() const; @@ -114,6 +122,8 @@ private: Standard_Real tgdu; Standard_Real tgdv; gp_Vec gradient; + gp_Vec d1u_isurf; + gp_Vec d1v_isurf; Standard_Boolean derived; gp_Vec d1u; gp_Vec d1v; diff --git a/src/Contap/Contap_Contour.cxx b/src/Contap/Contap_Contour.cxx index 935bf5f859..0979d88b35 100644 --- a/src/Contap/Contap_Contour.cxx +++ b/src/Contap/Contap_Contour.cxx @@ -1499,7 +1499,8 @@ void Contap_Contour::Perform Standard_Boolean theToFillHoles = Standard_True; Contap_TheIWalking iwalk(Preci,Fleche,Pas,theToFillHoles); - 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.hxx b/src/Contap/Contap_SurfFunction.hxx index 9539a3bfbe..fe92dc7f5f 100644 --- a/src/Contap/Contap_SurfFunction.hxx +++ b/src/Contap/Contap_SurfFunction.hxx @@ -25,7 +25,9 @@ #include #include #include - +#include +class Adaptor3d_HSurface; +class StdFail_UndefinedDerivative; class gp_Pnt; class gp_Dir; class math_Matrix; @@ -85,10 +87,20 @@ public: Standard_EXPORT Standard_Boolean IsTangent(); + Standard_Boolean IsTangentSmooth() ; + const gp_Vec& Direction3d(); const gp_Dir2d& Direction2d(); + Standard_Boolean DerivativesAndNormalOnPSurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) ; + + Standard_Boolean DerivativesAndNormalOnISurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) const; + + Standard_Real SquareTangentError() const; + + const IntSurf_Quadric& ISurface() const; + Contap_TFunction FunctionType() const; const gp_Pnt& Eye() const; diff --git a/src/Contap/Contap_SurfFunction.lxx b/src/Contap/Contap_SurfFunction.lxx index 21120f78c7..208b4f5702 100644 --- a/src/Contap/Contap_SurfFunction.lxx +++ b/src/Contap/Contap_SurfFunction.lxx @@ -100,6 +100,42 @@ 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 const IntSurf_Quadric& Contap_SurfFunction::ISurface() const +{ + static IntSurf_Quadric aQuad; + return aQuad; +} + inline Contap_TFunction Contap_SurfFunction::FunctionType () const { return myType; diff --git a/src/Contap/Contap_TheIWLineOfTheIWalking.hxx b/src/Contap/Contap_TheIWLineOfTheIWalking.hxx index c23e4de10d..c28ce27189 100644 --- a/src/Contap/Contap_TheIWLineOfTheIWalking.hxx +++ b/src/Contap/Contap_TheIWLineOfTheIWalking.hxx @@ -56,6 +56,15 @@ public: //! Add a point in the line. void AddPoint (const IntSurf_PntOn2S& P); + //! Insert a point in the line. + void InsertBefore (const Standard_Integer Index, const IntSurf_PntOn2S& P) ; + + //! Allows or forbides purging of this WLine + void EnablePurging(const Standard_Boolean theIsEnabled); + + //! Returns TRUE if purging is allowed or forbiden for existing WLine + Standard_Boolean IsPurgingAllowed() const; + void AddStatusFirst (const Standard_Boolean Closed, const Standard_Boolean HasFirst); void AddStatusFirst (const Standard_Boolean Closed, const Standard_Boolean HasLast, const Standard_Integer Index, const IntSurf_PathPoint& P); @@ -76,6 +85,8 @@ public: void SetTangencyAtEnd (const Standard_Boolean IsTangent); + void SetTangency (const Standard_Boolean IsTangency) ; + //! Returns the number of points of the line (including first //! point and end point : see HasLastPoint and HasFirstPoint). Standard_Integer NbPoints() const; @@ -139,6 +150,8 @@ public: Standard_Boolean IsTangentAtBegining() const; Standard_Boolean IsTangentAtEnd() const; + + Standard_Boolean IsTangency() const; @@ -166,6 +179,8 @@ private: gp_Vec vcttg; Standard_Boolean istgtbeg; Standard_Boolean istgtend; + Standard_Boolean istangency; + Standard_Boolean myIsPurgerAllowed; }; diff --git a/src/Contap/Contap_TheIWalking.hxx b/src/Contap/Contap_TheIWalking.hxx index c264ee3a06..13e23e99ea 100644 --- a/src/Contap/Contap_TheIWalking.hxx +++ b/src/Contap/Contap_TheIWalking.hxx @@ -41,6 +41,7 @@ class Adaptor3d_HSurfaceTool; class Contap_SurfFunction; class Contap_TheIWLineOfTheIWalking; class math_FunctionSetRoot; +class IntSurf_Quadric; class Contap_TheIWalking { @@ -58,7 +59,9 @@ public: //! theToFillHoles is the flag defining whether possible holes //! between resulting curves are filled or not //! in case of Contap walking theToFillHoles is True - Standard_EXPORT Contap_TheIWalking(const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Step, + Standard_EXPORT Contap_TheIWalking(const Standard_Real Epsilon, + const Standard_Real Deflection, + const Standard_Real Step, const Standard_Boolean theToFillHoles = Standard_False); //! Deflection is the maximum deflection admitted between two @@ -72,11 +75,19 @@ public: //! Searches a set of polylines starting on a point of Pnts1 //! or Pnts2. //! Each point on a resulting polyline verifies F(u,v)=0 - Standard_EXPORT void Perform (const IntSurf_SequenceOfPathPoint& Pnts1, const IntSurf_SequenceOfInteriorPoint& Pnts2, Contap_SurfFunction& Func, const Handle(Adaptor3d_Surface)& S, const Standard_Boolean Reversed = Standard_False); + Standard_EXPORT void Perform (const IntSurf_SequenceOfPathPoint& Pnts1, + const IntSurf_SequenceOfInteriorPoint& Pnts2, + const IntSurf_SequenceOfInteriorPoint& Pnts3, + Contap_SurfFunction& Func, + const Handle(Adaptor3d_Surface)& S, + const Standard_Boolean Reversed = Standard_False) ; //! Searches a set of polylines starting on a point of Pnts1. //! Each point on a resulting polyline verifies F(u,v)=0 - Standard_EXPORT void Perform (const IntSurf_SequenceOfPathPoint& Pnts1, Contap_SurfFunction& Func, const Handle(Adaptor3d_Surface)& S, const Standard_Boolean Reversed = Standard_False); + Standard_EXPORT void Perform (const IntSurf_SequenceOfPathPoint& Pnts1, + Contap_SurfFunction& Func, + const Handle(Adaptor3d_Surface)& S, + const Standard_Boolean Reversed = Standard_False); //! Returns true if the calculus was successful. Standard_Boolean IsDone() const; @@ -107,25 +118,71 @@ public: protected: - Standard_EXPORT Standard_Boolean Cadrage (math_Vector& BornInf, math_Vector& BornSup, math_Vector& UVap, Standard_Real& Step, const Standard_Integer StepSign) const; + Standard_EXPORT Standard_Boolean Cadrage (math_Vector& BornInf, + math_Vector& BornSup, + math_Vector& UVap, + Standard_Real& Step, + const Standard_Integer StepSign) const; - Standard_EXPORT Standard_Boolean TestArretPassage (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, Contap_SurfFunction& Section, math_Vector& UV, Standard_Integer& Irang); + Standard_EXPORT Standard_Boolean TestArretPassage (const TColStd_SequenceOfReal& Umult, + const TColStd_SequenceOfReal& Vmult, + Contap_SurfFunction& Section, + math_Vector& UV, + Standard_Integer& Irang); - Standard_EXPORT Standard_Boolean TestArretPassage (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const math_Vector& UV, const Standard_Integer Index, Standard_Integer& Irang); + Standard_EXPORT Standard_Boolean TestArretPassage (const TColStd_SequenceOfReal& Umult, + const TColStd_SequenceOfReal& Vmult, + const math_Vector& UV, + const Standard_Integer Index, + Standard_Integer& Irang); - Standard_EXPORT Standard_Boolean TestArretAjout (Contap_SurfFunction& Section, math_Vector& UV, Standard_Integer& Irang, IntSurf_PntOn2S& PSol); + Standard_EXPORT Standard_Boolean TestArretPassageTang (const TColStd_SequenceOfReal& Umult, + const TColStd_SequenceOfReal& Vmult, + const math_Vector& UV, + const Standard_Integer Index, + Standard_Integer& Irang) ; + + Standard_EXPORT Standard_Boolean TestArretAjout (Contap_SurfFunction& Section, + math_Vector& UV, + Standard_Integer& Irang, + IntSurf_PntOn2S& PSol, + Standard_Boolean& OnPrevTangency) ; Standard_EXPORT void FillPntsInHoles (Contap_SurfFunction& Section, TColStd_SequenceOfInteger& CopySeqAlone, IntSurf_SequenceOfInteriorPoint& PntsInHoles); - Standard_EXPORT void TestArretCadre (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const Handle(Contap_TheIWLineOfTheIWalking)& Line, Contap_SurfFunction& Section, math_Vector& UV, Standard_Integer& Irang); + Standard_EXPORT void TestArretCadre (const TColStd_SequenceOfReal& Umult, + const TColStd_SequenceOfReal& Vmult, + const Handle(Contap_TheIWLineOfTheIWalking)& Line, + Contap_SurfFunction& Section, + math_Vector& UV, + Standard_Integer& Irang); - Standard_EXPORT IntWalk_StatusDeflection TestDeflection (Contap_SurfFunction& Section, const Standard_Boolean Finished, const math_Vector& UV, const IntWalk_StatusDeflection StatusPrecedent, Standard_Integer& NbDivision, Standard_Real& Step, const Standard_Integer StepSign); + Standard_EXPORT IntWalk_StatusDeflection TestDeflection (Contap_SurfFunction& Section, + const Standard_Boolean Finished, + const math_Vector& UV, + const IntWalk_StatusDeflection StatusPrecedent, + Standard_Integer& NbDivision, + Standard_Real& Step, + Standard_Real& StepInit, + const Standard_Integer StepSign, + const Standard_Integer CurNbPoints, + const Standard_Boolean ArretAjout, + const Standard_Boolean PrevStepWrong, + const Standard_Boolean OnPrevTangency) ; - Standard_EXPORT void ComputeOpenLine (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const IntSurf_SequenceOfPathPoint& Pnts1, Contap_SurfFunction& Section, Standard_Boolean& Rajout); + Standard_EXPORT void ComputeOpenLine (const TColStd_SequenceOfReal& Umult, + const TColStd_SequenceOfReal& Vmult, + const IntSurf_SequenceOfPathPoint& Pnts1, + Contap_SurfFunction& Section, + Standard_Boolean& Rajout); - Standard_EXPORT void OpenLine (const Standard_Integer N, const IntSurf_PntOn2S& Psol, const IntSurf_SequenceOfPathPoint& Pnts1, Contap_SurfFunction& Section, const Handle(Contap_TheIWLineOfTheIWalking)& Line); + Standard_EXPORT void OpenLine (const Standard_Integer N, + const IntSurf_PntOn2S& Psol, + const IntSurf_SequenceOfPathPoint& Pnts1, + Contap_SurfFunction& Section, + const Handle(Contap_TheIWLineOfTheIWalking)& Line); Standard_EXPORT Standard_Boolean IsValidEndPoint (const Standard_Integer IndOfPoint, const Standard_Integer IndOfLine); @@ -133,11 +190,61 @@ protected: Standard_EXPORT Standard_Boolean IsPointOnLine (const gp_Pnt2d& theP2d, const Standard_Integer Irang); - Standard_EXPORT void ComputeCloseLine (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const IntSurf_SequenceOfPathPoint& Pnts1, const IntSurf_SequenceOfInteriorPoint& Pnts2, Contap_SurfFunction& Section, Standard_Boolean& Rajout); + Standard_EXPORT void ComputeCloseLine (const TColStd_SequenceOfReal& Umult, + const TColStd_SequenceOfReal& Vmult, + const IntSurf_SequenceOfPathPoint& Pnts1, + const IntSurf_SequenceOfInteriorPoint& Pnts2, + const IntSurf_SequenceOfInteriorPoint& Pnts3, + Contap_SurfFunction& Section, + Standard_Boolean& Rajout); + + Standard_EXPORT void RecadreParam (Standard_Real& U, + const Standard_Real PrevU, + const IntSurf_Quadric& theQuad) const; + + Standard_EXPORT void AddPointInCurrentLine (const Standard_Integer N, + const IntSurf_PathPoint& PathPnt, + const IntSurf_Quadric& theQuad, + const Handle(Contap_TheIWLineOfTheIWalking)& CurrentLine) const; + + Standard_EXPORT void AddPointInCurrentLine (const Standard_Integer N, + const IntSurf_PathPoint& PathPnt, + const Handle(Contap_TheIWLineOfTheIWalking)& CurrentLine) const; + + Standard_EXPORT void DefineParams (const Standard_Integer Index, + TColStd_SequenceOfReal& Distances, + TColStd_SequenceOfReal& Params) const; + + Standard_EXPORT void DefineCurvatures (const Standard_Integer Index, + const TColStd_SequenceOfReal& Params, + TColStd_SequenceOfReal& Curvatures); + + Standard_EXPORT Standard_Integer InsertMiddlePoint (const Standard_Integer indline, + const Standard_Integer Index, + Contap_SurfFunction& Func, + TColStd_SequenceOfReal& Distances, + TColStd_SequenceOfReal& Params, + TColStd_SequenceOfReal& Curvatures); + + Standard_EXPORT void MakeWalkingPoint (const Standard_Integer Case, + const Standard_Real U, + const Standard_Real V, + Contap_SurfFunction& Section, + IntSurf_PntOn2S& Psol); + + Standard_EXPORT void FindExactCuspPoint (Contap_SurfFunction& Section, + IntSurf_PntOn2S& Psol, + const Standard_Integer PrevSignOfBcoeff, + const Standard_Integer SignOfBcoeff) ; - Standard_EXPORT void AddPointInCurrentLine (const Standard_Integer N, const IntSurf_PathPoint& PathPnt, const Handle(Contap_TheIWLineOfTheIWalking)& CurrentLine) const; + Standard_EXPORT void FindExactTangentPoint (const Standard_Real TolTang, Contap_SurfFunction& Section, IntSurf_PntOn2S& Psol) ; - Standard_EXPORT void MakeWalkingPoint (const Standard_Integer Case, const Standard_Real U, const Standard_Real V, Contap_SurfFunction& Section, IntSurf_PntOn2S& Psol); + Standard_EXPORT Standard_Boolean ComputeDirOfTangentialIntersection (Contap_SurfFunction& Section, + Standard_Integer& StepSign, + Standard_Boolean& IsDiscriminantNull, + Standard_Integer& SignOfBcoeff, + gp_Vec& NewD3d, + gp_Dir2d& NewD2d) ; //! Clears up internal containers Standard_EXPORT void Clear(); @@ -163,6 +270,7 @@ private: Standard_Boolean reversed; IntWalk_VectorOfWalkingData wd1; IntWalk_VectorOfWalkingData wd2; + IntWalk_VectorOfWalkingData wd3; IntWalk_VectorOfInteger nbMultiplicities; Bnd_Range mySRangeU; // Estimated U-range for section curve Bnd_Range mySRangeV; // Estimated V-range for section curve @@ -173,6 +281,7 @@ private: IntSurf_PntOn2S previousPoint; gp_Vec previousd3d; gp_Dir2d previousd2d; + Standard_Boolean IsTangentialIntersection; TColStd_SequenceOfInteger seqAjout; TColStd_SequenceOfInteger seqAlone; TColStd_DataMapOfIntegerListOfInteger PointLineLine; diff --git a/src/Contap/Contap_TheSearchInside.hxx b/src/Contap/Contap_TheSearchInside.hxx index 706a727b51..952ea35add 100644 --- a/src/Contap/Contap_TheSearchInside.hxx +++ b/src/Contap/Contap_TheSearchInside.hxx @@ -48,12 +48,16 @@ public: //! returns False. Standard_Integer NbPoints() const; + Standard_Integer NbTangentPoints() const; + //! Returns the point of range Index. //! The exception NotDone if raised if IsDone //! returns False. //! The exception OutOfRange if raised if //! Index <= 0 or Index > NbPoints. - const IntSurf_InteriorPoint& Value (const Standard_Integer Index) const; + const IntSurf_InteriorPoint& Value (const Standard_Integer Index) const; + + const IntSurf_InteriorPoint& TangentPoint (const Standard_Integer Index) const; @@ -70,6 +74,7 @@ private: Standard_Boolean done; IntSurf_SequenceOfInteriorPoint list; + IntSurf_SequenceOfInteriorPoint myTangentPoints; }; diff --git a/src/GeomInt/GeomInt_TheZerImpFuncOfTheImpPrmSvSurfacesOfWLApprox.hxx b/src/GeomInt/GeomInt_TheZerImpFuncOfTheImpPrmSvSurfacesOfWLApprox.hxx index 2ccdb87244..5868e5d16b 100644 --- a/src/GeomInt/GeomInt_TheZerImpFuncOfTheImpPrmSvSurfacesOfWLApprox.hxx +++ b/src/GeomInt/GeomInt_TheZerImpFuncOfTheImpPrmSvSurfacesOfWLApprox.hxx @@ -68,10 +68,18 @@ public: Standard_EXPORT Standard_Boolean IsTangent(); + Standard_EXPORT Standard_Boolean IsTangentSmooth() ; + const gp_Vec& Direction3d(); const gp_Dir2d& Direction2d(); + Standard_EXPORT Standard_Boolean DerivativesAndNormalOnPSurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) ; + + Standard_EXPORT Standard_Boolean DerivativesAndNormalOnISurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) const; + + Standard_Real SquareTangentError() const; + const Handle(Adaptor3d_Surface)& PSurface() const; const IntSurf_Quadric& ISurface() const; @@ -101,6 +109,8 @@ private: Standard_Real tgdu; Standard_Real tgdv; gp_Vec gradient; + gp_Vec d1u_isurf; + gp_Vec d1v_isurf; Standard_Boolean derived; gp_Vec d1u; gp_Vec d1v; diff --git a/src/IntImp/IntImp_ZerImpFunc.gxx b/src/IntImp/IntImp_ZerImpFunc.gxx index e2c47d78aa..1a66429bc5 100644 --- a/src/IntImp/IntImp_ZerImpFunc.gxx +++ b/src/IntImp/IntImp_ZerImpFunc.gxx @@ -116,7 +116,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); @@ -142,17 +142,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 !!!"<GetType() : Surf2->GetType(); + GeomAbs_SurfaceType aSType = reversed ? Surf1->GetType() : Surf2->GetType(); if (aSType == GeomAbs_BezierSurface || aSType == GeomAbs_BSplineSurface) { @@ -642,6 +642,7 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_Surface)& Surf // IntSurf_SequenceOfPathPoint seqpdep; IntSurf_SequenceOfInteriorPoint seqpins; + IntSurf_SequenceOfInteriorPoint seqptang; // NbPointRst = solrst.NbPoints(); TColStd_Array1OfInteger Destination(1,NbPointRst+1); Destination.Init(0); @@ -713,14 +714,21 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_Surface)& Surf for (Standard_Integer i=1; i <= NbPointIns; i++) { seqpins.Append(solins.Value(i)); } + NbPointsTang = solins.NbTangentPoints(); + for (Standard_Integer i = 1; i <= NbPointsTang; i++) + seqptang.Append(solins.TangentPoint(i)); } // NbPointDep=seqpdep.Length(); // if (NbPointDep || NbPointIns) { IntPatch_TheIWalking iwalk(TolTang, Fleche, aLocalPas); - iwalk.Perform(seqpdep, seqpins, Func, reversed ? Surf1 : Surf2, reversed); - + if (!reversed) { + iwalk.Perform(seqpdep,seqpins,seqptang,Func,Surf2); + } + else { + iwalk.Perform(seqpdep,seqpins,seqptang,Func,Surf1,Standard_True); + } if(!iwalk.IsDone()) { return; } @@ -884,6 +892,7 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_Surface)& Surf } // <-A wline = new IntPatch_WLine(thelin,Standard_False,trans1,trans2); + wline->EnablePurging(iwline->IsPurgingAllowed()); wline->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLImpPrm); #ifdef INTPATCH_IMPPRMINTERSECTION_DEBUG @@ -3284,4 +3293,4 @@ Standard_Boolean IsCoincide(IntPatch_TheSurfFunction& theFunc, } return Standard_True; -} \ No newline at end of file +} diff --git a/src/IntPatch/IntPatch_TheIWLineOfTheIWalking.hxx b/src/IntPatch/IntPatch_TheIWLineOfTheIWalking.hxx index ceca228e36..539d5a4c37 100644 --- a/src/IntPatch/IntPatch_TheIWLineOfTheIWalking.hxx +++ b/src/IntPatch/IntPatch_TheIWLineOfTheIWalking.hxx @@ -56,6 +56,15 @@ public: //! Add a point in the line. void AddPoint (const IntSurf_PntOn2S& P); + //! Insert a point in the line. + void InsertBefore (const Standard_Integer Index, const IntSurf_PntOn2S& P) ; + + //! Allows or forbides purging of this WLine + void EnablePurging(const Standard_Boolean theIsEnabled); + + //! Returns TRUE if purging is allowed or forbiden for existing WLine + Standard_Boolean IsPurgingAllowed() const; + void AddStatusFirst (const Standard_Boolean Closed, const Standard_Boolean HasFirst); void AddStatusFirst (const Standard_Boolean Closed, const Standard_Boolean HasLast, const Standard_Integer Index, const IntSurf_PathPoint& P); @@ -76,6 +85,8 @@ public: void SetTangencyAtEnd (const Standard_Boolean IsTangent); + void SetTangency (const Standard_Boolean IsTangency) ; + //! Returns the number of points of the line (including first //! point and end point : see HasLastPoint and HasFirstPoint). Standard_Integer NbPoints() const; @@ -139,6 +150,8 @@ public: Standard_Boolean IsTangentAtBegining() const; Standard_Boolean IsTangentAtEnd() const; + + Standard_Boolean IsTangency() const; @@ -166,6 +179,8 @@ private: gp_Vec vcttg; Standard_Boolean istgtbeg; Standard_Boolean istgtend; + Standard_Boolean istangency; + Standard_Boolean myIsPurgerAllowed; }; diff --git a/src/IntPatch/IntPatch_TheIWalking.hxx b/src/IntPatch/IntPatch_TheIWalking.hxx index c5b713d3bc..aac3d4ebba 100644 --- a/src/IntPatch/IntPatch_TheIWalking.hxx +++ b/src/IntPatch/IntPatch_TheIWalking.hxx @@ -32,6 +32,7 @@ #include #include #include +#include #include class IntSurf_PathPoint; @@ -60,7 +61,9 @@ public: //! theToFillHoles is the flag defining whether possible holes //! between resulting curves are filled or not //! in case of IntPatch walking theToFillHoles is False - Standard_EXPORT IntPatch_TheIWalking(const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Step, + Standard_EXPORT IntPatch_TheIWalking(const Standard_Real Epsilon, + const Standard_Real Deflection, + const Standard_Real Step, const Standard_Boolean theToFillHoles = Standard_False); //! Deflection is the maximum deflection admitted between two @@ -74,11 +77,19 @@ public: //! Searches a set of polylines starting on a point of Pnts1 //! or Pnts2. //! Each point on a resulting polyline verifies F(u,v)=0 - Standard_EXPORT void Perform (const IntSurf_SequenceOfPathPoint& Pnts1, const IntSurf_SequenceOfInteriorPoint& Pnts2, IntPatch_TheSurfFunction& Func, const Handle(Adaptor3d_Surface)& S, const Standard_Boolean Reversed = Standard_False); + Standard_EXPORT void Perform (const IntSurf_SequenceOfPathPoint& Pnts1, + const IntSurf_SequenceOfInteriorPoint& Pnts2, + const IntSurf_SequenceOfInteriorPoint& Pnts3, + IntPatch_TheSurfFunction& Func, + const Handle(Adaptor3d_Surface)& S, + const Standard_Boolean Reversed = Standard_False) ; //! Searches a set of polylines starting on a point of Pnts1. //! Each point on a resulting polyline verifies F(u,v)=0 - Standard_EXPORT void Perform (const IntSurf_SequenceOfPathPoint& Pnts1, IntPatch_TheSurfFunction& Func, const Handle(Adaptor3d_Surface)& S, const Standard_Boolean Reversed = Standard_False); + Standard_EXPORT void Perform (const IntSurf_SequenceOfPathPoint& Pnts1, + IntPatch_TheSurfFunction& Func, + const Handle(Adaptor3d_Surface)& S, + const Standard_Boolean Reversed = Standard_False); //! Returns true if the calculus was successful. Standard_Boolean IsDone() const; @@ -109,25 +120,71 @@ public: protected: - Standard_EXPORT Standard_Boolean Cadrage (math_Vector& BornInf, math_Vector& BornSup, math_Vector& UVap, Standard_Real& Step, const Standard_Integer StepSign) const; + Standard_EXPORT Standard_Boolean Cadrage (math_Vector& BornInf, + math_Vector& BornSup, + math_Vector& UVap, + Standard_Real& Step, + const Standard_Integer StepSign) const; - Standard_EXPORT Standard_Boolean TestArretPassage (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, IntPatch_TheSurfFunction& Section, math_Vector& UV, Standard_Integer& Irang); + Standard_EXPORT Standard_Boolean TestArretPassage (const TColStd_SequenceOfReal& Umult, + const TColStd_SequenceOfReal& Vmult, + IntPatch_TheSurfFunction& Section, + math_Vector& UV, + Standard_Integer& Irang); - Standard_EXPORT Standard_Boolean TestArretPassage (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const math_Vector& UV, const Standard_Integer Index, Standard_Integer& Irang); + Standard_EXPORT Standard_Boolean TestArretPassage (const TColStd_SequenceOfReal& Umult, + const TColStd_SequenceOfReal& Vmult, + const math_Vector& UV, + const Standard_Integer Index, + Standard_Integer& Irang); - Standard_EXPORT Standard_Boolean TestArretAjout (IntPatch_TheSurfFunction& Section, math_Vector& UV, Standard_Integer& Irang, IntSurf_PntOn2S& PSol); + Standard_EXPORT Standard_Boolean TestArretPassageTang (const TColStd_SequenceOfReal& Umult, + const TColStd_SequenceOfReal& Vmult, + const math_Vector& UV, + const Standard_Integer Index, + Standard_Integer& Irang) ; + + Standard_EXPORT Standard_Boolean TestArretAjout (IntPatch_TheSurfFunction& Section, + math_Vector& UV, + Standard_Integer& Irang, + IntSurf_PntOn2S& PSol, + Standard_Boolean& OnPrevTangency); Standard_EXPORT void FillPntsInHoles (IntPatch_TheSurfFunction& Section, TColStd_SequenceOfInteger& CopySeqAlone, IntSurf_SequenceOfInteriorPoint& PntsInHoles); - Standard_EXPORT void TestArretCadre (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const Handle(IntPatch_TheIWLineOfTheIWalking)& Line, IntPatch_TheSurfFunction& Section, math_Vector& UV, Standard_Integer& Irang); + Standard_EXPORT void TestArretCadre (const TColStd_SequenceOfReal& Umult, + const TColStd_SequenceOfReal& Vmult, + const Handle(IntPatch_TheIWLineOfTheIWalking)& Line, + IntPatch_TheSurfFunction& Section, + math_Vector& UV, + Standard_Integer& Irang); - Standard_EXPORT IntWalk_StatusDeflection TestDeflection (IntPatch_TheSurfFunction& Section, const Standard_Boolean Finished, const math_Vector& UV, const IntWalk_StatusDeflection StatusPrecedent, Standard_Integer& NbDivision, Standard_Real& Step, const Standard_Integer StepSign); + Standard_EXPORT IntWalk_StatusDeflection TestDeflection (IntPatch_TheSurfFunction& Section, + const Standard_Boolean Finished, + const math_Vector& UV, + const IntWalk_StatusDeflection StatusPrecedent, + Standard_Integer& NbDivision, + Standard_Real& Step, + Standard_Real& StepInit, + const Standard_Integer StepSign, + const Standard_Integer CurNbPoints, + const Standard_Boolean ArretAjout, + const Standard_Boolean PrevStepWrong, + const Standard_Boolean OnPrevTangency) ; - Standard_EXPORT void ComputeOpenLine (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const IntSurf_SequenceOfPathPoint& Pnts1, IntPatch_TheSurfFunction& Section, Standard_Boolean& Rajout); + Standard_EXPORT void ComputeOpenLine (const TColStd_SequenceOfReal& Umult, + const TColStd_SequenceOfReal& Vmult, + const IntSurf_SequenceOfPathPoint& Pnts1, + IntPatch_TheSurfFunction& Section, + Standard_Boolean& Rajout); - Standard_EXPORT void OpenLine (const Standard_Integer N, const IntSurf_PntOn2S& Psol, const IntSurf_SequenceOfPathPoint& Pnts1, IntPatch_TheSurfFunction& Section, const Handle(IntPatch_TheIWLineOfTheIWalking)& Line); + Standard_EXPORT void OpenLine (const Standard_Integer N, + const IntSurf_PntOn2S& Psol, + const IntSurf_SequenceOfPathPoint& Pnts1, + IntPatch_TheSurfFunction& Section, + const Handle(IntPatch_TheIWLineOfTheIWalking)& Line); Standard_EXPORT Standard_Boolean IsValidEndPoint (const Standard_Integer IndOfPoint, const Standard_Integer IndOfLine); @@ -135,11 +192,60 @@ protected: Standard_EXPORT Standard_Boolean IsPointOnLine (const gp_Pnt2d& theP2d, const Standard_Integer Irang); - Standard_EXPORT void ComputeCloseLine (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const IntSurf_SequenceOfPathPoint& Pnts1, const IntSurf_SequenceOfInteriorPoint& Pnts2, IntPatch_TheSurfFunction& Section, Standard_Boolean& Rajout); + Standard_EXPORT void ComputeCloseLine (const TColStd_SequenceOfReal& Umult, + const TColStd_SequenceOfReal& Vmult, + const IntSurf_SequenceOfPathPoint& Pnts1, + const IntSurf_SequenceOfInteriorPoint& Pnts2, + const IntSurf_SequenceOfInteriorPoint& Pnts3, + IntPatch_TheSurfFunction& Section, + Standard_Boolean& Rajout); + + Standard_EXPORT void RecadreParam (Standard_Real& U, + const Standard_Real PrevU, + const IntSurf_Quadric& theQuad) const; + + Standard_EXPORT void AddPointInCurrentLine (const Standard_Integer N, + const IntSurf_PathPoint& PathPnt, + const IntSurf_Quadric& theQuad, + const Handle(IntPatch_TheIWLineOfTheIWalking)& CurrentLine) const; + + Standard_EXPORT void DefineParams (const Standard_Integer indline, + TColStd_SequenceOfReal& Distances, + TColStd_SequenceOfReal& Params) const; + + Standard_EXPORT void DefineCurvatures (const Standard_Integer indline, + const TColStd_SequenceOfReal& Params, + TColStd_SequenceOfReal& Curvatures); + + Standard_EXPORT Standard_Integer InsertMiddlePoint (const Standard_Integer indline, + const Standard_Integer Index, + IntPatch_TheSurfFunction& Func, + TColStd_SequenceOfReal& Distances, + TColStd_SequenceOfReal& Params, + TColStd_SequenceOfReal& Curvatures); + + Standard_EXPORT void MakeWalkingPoint (const Standard_Integer Case, + const Standard_Real U, + const Standard_Real V, + IntPatch_TheSurfFunction& Section, + IntSurf_PntOn2S& Psol); + + Standard_EXPORT void FindExactCuspPoint (IntPatch_TheSurfFunction& Section, + IntSurf_PntOn2S& Psol, + const Standard_Integer + PrevSignOfBcoeff, + const Standard_Integer SignOfBcoeff) ; - Standard_EXPORT void AddPointInCurrentLine (const Standard_Integer N, const IntSurf_PathPoint& PathPnt, const Handle(IntPatch_TheIWLineOfTheIWalking)& CurrentLine) const; + Standard_EXPORT void FindExactTangentPoint (const Standard_Real TolTang, + IntPatch_TheSurfFunction& Section, + IntSurf_PntOn2S& Psol) ; - Standard_EXPORT void MakeWalkingPoint (const Standard_Integer Case, const Standard_Real U, const Standard_Real V, IntPatch_TheSurfFunction& Section, IntSurf_PntOn2S& Psol); + Standard_EXPORT Standard_Boolean ComputeDirOfTangentialIntersection (IntPatch_TheSurfFunction& Section, + Standard_Integer& StepSign, + Standard_Boolean& IsDiscriminantNull, + Standard_Integer& SignOfBcoeff, + gp_Vec& NewD3d, + gp_Dir2d& NewD2d) ; //! Clears up internal containers Standard_EXPORT void Clear(); @@ -166,6 +272,7 @@ private: Standard_Boolean reversed; IntWalk_VectorOfWalkingData wd1; IntWalk_VectorOfWalkingData wd2; + IntWalk_VectorOfWalkingData wd3; IntWalk_VectorOfInteger nbMultiplicities; Bnd_Range mySRangeU; // Estimated U-range for section curve Bnd_Range mySRangeV; // Estimated V-range for section curve @@ -176,6 +283,7 @@ private: IntSurf_PntOn2S previousPoint; gp_Vec previousd3d; gp_Dir2d previousd2d; + Standard_Boolean IsTangentialIntersection; TColStd_SequenceOfInteger seqAjout; TColStd_SequenceOfInteger seqAlone; TColStd_DataMapOfIntegerListOfInteger PointLineLine; diff --git a/src/IntPatch/IntPatch_TheSearchInside.hxx b/src/IntPatch/IntPatch_TheSearchInside.hxx index 1e9350151c..2403712516 100644 --- a/src/IntPatch/IntPatch_TheSearchInside.hxx +++ b/src/IntPatch/IntPatch_TheSearchInside.hxx @@ -47,12 +47,16 @@ public: //! returns False. Standard_Integer NbPoints() const; + Standard_Integer NbTangentPoints() const; + //! Returns the point of range Index. //! The exception NotDone if raised if IsDone //! returns False. //! The exception OutOfRange if raised if //! Index <= 0 or Index > NbPoints. - const IntSurf_InteriorPoint& Value (const Standard_Integer Index) const; + const IntSurf_InteriorPoint& Value (const Standard_Integer Index) const; + + const IntSurf_InteriorPoint& TangentPoint (const Standard_Integer Index) const; @@ -69,6 +73,7 @@ private: Standard_Boolean done; IntSurf_SequenceOfInteriorPoint list; + IntSurf_SequenceOfInteriorPoint myTangentPoints; }; diff --git a/src/IntPatch/IntPatch_TheSurfFunction.hxx b/src/IntPatch/IntPatch_TheSurfFunction.hxx index b76bee24af..632866e0b4 100644 --- a/src/IntPatch/IntPatch_TheSurfFunction.hxx +++ b/src/IntPatch/IntPatch_TheSurfFunction.hxx @@ -68,10 +68,18 @@ public: Standard_EXPORT Standard_Boolean IsTangent(); + Standard_EXPORT Standard_Boolean IsTangentSmooth() ; + const gp_Vec& Direction3d(); const gp_Dir2d& Direction2d(); + Standard_EXPORT Standard_Boolean DerivativesAndNormalOnPSurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) ; + + Standard_EXPORT Standard_Boolean DerivativesAndNormalOnISurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) const; + + Standard_Real SquareTangentError() const; + const Handle(Adaptor3d_Surface)& PSurface() const; const IntSurf_Quadric& ISurface() const; @@ -101,6 +109,8 @@ private: Standard_Real tgdu; Standard_Real tgdv; gp_Vec gradient; + gp_Vec d1u_isurf; + gp_Vec d1v_isurf; Standard_Boolean derived; gp_Vec d1u; gp_Vec d1v; diff --git a/src/IntStart/IntStart_SearchInside.gxx b/src/IntStart/IntStart_SearchInside.gxx index 53a2225cd0..81162ffca6 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; @@ -117,6 +123,12 @@ void IntStart_SearchInside::Perform (TheFunction& Func, //-- P I I I I I I I I //-- +#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; @@ -176,9 +188,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 +219,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 @@ -561,7 +779,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 224d257508..0e5a321ea8 100644 --- a/src/IntWalk/IntWalk_IWalking_3.gxx +++ b/src/IntWalk/IntWalk_IWalking_3.gxx @@ -15,6 +15,13 @@ #include #include +#include +#include + +//#ifdef DRAW +#include +//#endif + // modified by NIZHNY-MKK Thu Nov 2 15:07:26 2000.BEGIN static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd, @@ -63,13 +70,19 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, // end of conditions. { + //#ifdef DRAW + char* name = new char[100]; + //#endif + Standard_Integer I = 0, N = 0, SaveN = 0; 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 = 0.0, PasCu = 0.0, PasCv = 0.0; + Standard_Real PasC = 0.0, PasCu = 0.0, PasCv = 0.0, PasInit = 0.0; //PasSav; Standard_Boolean Arrive = false; // shows if the line ends Standard_Boolean Cadre = false; // shows if one is on border of the domain Standard_Boolean ArretAjout = false; //shows if one is on added point + Standard_Boolean PrevStepWrong = false; //shows was Rsnld successful or not + Standard_Boolean OnPrevTangency = false; //shows if one is on added point of tangent line IntSurf_PntOn2S Psol; Handle(IntWalk_TheIWLine) CurrentLine; // line under construction Standard_Boolean Tgtend = false; @@ -80,6 +93,9 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, // number of divisions of step for each section Standard_Integer StepSign = 0; + Standard_Integer StepSignTangent = 0; + Standard_Integer SignOfBcoeff = 0; + Standard_Integer PrevSignOfBcoeff = SignOfBcoeff; ThePointOfPath PathPnt; @@ -101,6 +117,9 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, TheIWFunction aFuncForDuplicate = Func; + //jgv + IntSurf_Quadric theQuad = (IntSurf_Quadric)(Func.ISurface()); + for (I = 1; I <= nbPath; I++) { //start point of the progression // if (wd1[I].etat > 11) { @@ -122,9 +141,27 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, CurrentLine->SetTangencyAtBegining(Standard_False); Tgtend = Standard_False; CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt); + IsTangentialIntersection = Standard_False; + SignOfBcoeff = PrevSignOfBcoeff = 0; + MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint); previousd3d = Func.Direction3d(); previousd2d = Func.Direction2d(); + //jgv + /* + Standard_Real u_i, v_i; + theQuad.Parameters(previousPoint.Value(), u_i, v_i); + previousPoint.SetValue(!reversed, u_i, v_i); + */ + ///// + CurrentLine->AddPoint(previousPoint); + //#ifdef DRAW + Standard_Integer aNbPoints = CurrentLine->NbPoints(); + gp_Pnt2d aPnt2d = previousPoint.ValueOnSurface(false); + sprintf(name, "op%d_%d", I, aNbPoints); + //DrawTrSurf::Set(name, aPnt2d); + //#endif + // modified by NIZHNY-MKK Fri Oct 27 12:34:32 2000.BEGIN if(movementdirectioninfo[I] !=0) { if(movementdirectioninfo[I] < 0) { @@ -164,13 +201,19 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy); } + PasInit = PasC; + //PasSav = PasC; + Arrive = Standard_False; ArretAjout = Standard_False; + PrevStepWrong = 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? @@ -185,19 +228,20 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, 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()) { + PrevStepWrong = Standard_True; + 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; seqAlone.Append(lines.Length() + 1); seqAjout.Append(lines.Length() + 1); @@ -212,7 +256,7 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, } else { if (Rajout) { - ArretAjout =TestArretAjout(Func, UVap, N, Psol); + ArretAjout =TestArretAjout(Func, UVap, N, Psol, OnPrevTangency); SaveN = N; if (ArretAjout) { // jag 940615 @@ -230,7 +274,7 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, previousPoint.ParametersOnS1(prevUp, prevVp); } Arrive = TestPassedSolutionWithNegativeState(wd1, Umult, Vmult, prevUp, prevVp, - nbMultiplicities, tolerance, Func, UVap, N); + nbMultiplicities, tolerance, Func, UVap, N); if(Arrive) { Cadre = Standard_False; } @@ -239,7 +283,6 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, 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(); @@ -248,8 +291,56 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, } } aStatus = TestDeflection(Func, Arrive, UVap, StatusPrecedent, - NbDivision,PasC,StepSign); + NbDivision,PasC,PasInit,StepSign, + CurrentLine->NbPoints(),ArretAjout,PrevStepWrong,OnPrevTangency); StatusPrecedent = aStatus; + + if (aStatus == IntWalk_ArretSurPoint && Func.IsTangent()) + { + PrevSignOfBcoeff = SignOfBcoeff; + gp_Vec newd3d; + gp_Dir2d newd2d; + Standard_Boolean IsDiscriminantNull; + if (ComputeDirOfTangentialIntersection(Func, StepSignTangent, + IsDiscriminantNull, SignOfBcoeff, + newd3d, newd2d) && + IsDiscriminantNull) + { + if (SignOfBcoeff == 0) //point of branching + aStatus = IntWalk_ArretSurPoint; + else + { + if (PrevSignOfBcoeff == 0 || + SignOfBcoeff == PrevSignOfBcoeff) + { + aStatus = IntWalk_OKtangent; + MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint); + previousd3d = newd3d; + previousd2d = newd2d; + //jgv + /* + Standard_Real u_i, v_i, prev_ui, prev_vi; + theQuad.Parameters(previousPoint.Value(), u_i, v_i); + IntSurf_PntOn2S LastPnt = CurrentLine->Value(CurrentLine->NbPoints()); + LastPnt.ParametersOnSurface(!reversed, prev_ui, prev_vi); + RecadreParam(u_i, prev_ui, theQuad); + previousPoint.SetValue(!reversed, u_i, v_i); + */ + ///// + 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)); + aStatus = IntWalk_ArretSurPoint; + } + } + } + } + if (aStatus == IntWalk_PasTropGrand) { Arrive = Standard_False; ArretAjout = Standard_False; @@ -325,7 +416,7 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, } CurrentLine->AddStatusLast(Standard_True, N, PathPnt); } - AddPointInCurrentLine(N,PathPnt,CurrentLine); + AddPointInCurrentLine(N,PathPnt,theQuad,CurrentLine); if ((etat1N != 1 && etat1N != 11)) { // modified by NIZHNY-MKK Fri Oct 27 12:43:05 2000.BEGIN // wd1[N].etat= - wd1[N].etat; @@ -358,13 +449,11 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, previousd2d = Func.Direction2d(); CurrentLine->AddPoint(previousPoint); } - else if (aStatus == IntWalk_PointConfondu) - { - aNbIter --; - } + PrevStepWrong = Standard_False; } } else { // no numerical solution + PrevStepWrong = Standard_True; PasC = PasC / 2.; PasCu = Abs(PasC*previousd2d.X()); PasCv = Abs(PasC*previousd2d.Y()); @@ -378,13 +467,11 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, seqAjout.Append(lines.Length() + 1); } } - - if(aNbIter < 0) - break; } // end of started line if (Arrive) { CurrentLine->SetTangencyAtEnd(Tgtend); + CurrentLine->SetTangency(IsTangentialIntersection); lines.Append(CurrentLine); // modified by NIZHNY-MKK Fri Oct 27 12:59:29 2000.BEGIN movementdirectioninfo[I]=0; diff --git a/src/IntWalk/IntWalk_IWalking_4.gxx b/src/IntWalk/IntWalk_IWalking_4.gxx index 8965974e8c..623e72ab9a 100644 --- a/src/IntWalk/IntWalk_IWalking_4.gxx +++ b/src/IntWalk/IntWalk_IWalking_4.gxx @@ -13,11 +13,15 @@ // 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 ) // *********** Processing of closed line ********************** @@ -52,6 +56,8 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, Standard_Boolean Arrive = false;// show if line ends Standard_Boolean Cadre = false; // show if on border of the domains Standard_Boolean ArretAjout = false; // show if on the added point + Standard_Boolean PrevStepWrong = false; //shows was Rsnld successful or not + Standard_Boolean OnPrevTangency = false; //shows if one is on added point of tangent line IntSurf_PntOn2S Psol; Handle(IntWalk_TheIWLine) CurrentLine; //line under construction ThePointOfPath PathPnt; @@ -60,6 +66,9 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, Standard_Boolean Tgtbeg = false, Tgtend = false; Standard_Integer StepSign = 0; + Standard_Integer StepSignTangent = 0; + Standard_Integer SignOfBcoeff = 0; + Standard_Integer PrevSignOfBcoeff = SignOfBcoeff; IntWalk_StatusDeflection aStatus = IntWalk_OK, StatusPrecedent; Standard_Integer NbDivision = 0; // number of divisions of step @@ -79,6 +88,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}; @@ -120,6 +130,9 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, TheIWFunction aFuncForDuplicate = Func; + //jgv + IntSurf_Quadric theQuad = (IntSurf_Quadric)(Func.ISurface()); + for (I = 1;I<=nbLoop;I++) { if (wd2[I].etat > 12) { // start point of closed line @@ -135,12 +148,29 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, 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; @@ -164,9 +194,11 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, Arrive = Standard_False; ArretAjout = Standard_False; + PrevStepWrong = 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? #ifdef CHRONO @@ -185,6 +217,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, } if (Rsnld.IsDone()) { if (Abs(Func.Root()) > Func.Tolerance()) { // no solution for the tolerance + PrevStepWrong = Standard_True; PasC = PasC/2.; PasCu = Abs(PasC*previousd2d.X()); PasCv = Abs(PasC*previousd2d.Y()); @@ -283,7 +316,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, } else { // modif jag 940615 if (Rajout) { // test on added points - ArretAjout =TestArretAjout(Func,Uvap,N,Psol); + ArretAjout =TestArretAjout(Func, Uvap, N, Psol, OnPrevTangency); SaveN = N; if (ArretAjout) { if (N >0) { @@ -317,7 +350,8 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, } } aStatus = TestDeflection(Func, Arrive,Uvap,StatusPrecedent, - NbDivision,PasC,StepSign); + NbDivision,PasC,PasSav,StepSign, + CurrentLine->NbPoints(),ArretAjout,PrevStepWrong,OnPrevTangency); if (isOnDegeneratedBorder && Tgtend) aStatus = IntWalk_ArretSurPoint; @@ -339,7 +373,19 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, if (Arrive) { // line s is open CurrentLine->AddStatusLast(Standard_False); //if (aStatus != IntWalk_ArretSurPointPrecedent) - CurrentLine->AddPoint(Psol); + if (aStatus != IntWalk_ArretSurPointPrecedent) { + //jgv + /* + Standard_Real u_i, v_i, prev_ui, prev_vi; + theQuad.Parameters(Psol.Value(), u_i, v_i); + IntSurf_PntOn2S LastPnt = CurrentLine->Value(CurrentLine->NbPoints()); + LastPnt.ParametersOnSurface(!reversed, prev_ui, prev_vi); + RecadreParam(u_i, prev_ui, theQuad); + Psol.SetValue(!reversed, u_i, v_i); + */ + ///// + CurrentLine->AddPoint(Psol); + } //Remove from and, if it is first found point, //from too @@ -456,7 +502,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, else if (Arrive) { if (wd2[I].etat > 12) { //line closed good case CurrentLine->AddStatusFirstLast(Standard_True, - Standard_False,Standard_False); + Standard_False,Standard_False); CurrentLine->AddPoint(CurrentLine->Value(1)); } else if ((N >0) && (Pnts1.Length() >= N)) @@ -464,40 +510,80 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, //point of stop given at input PathPnt = Pnts1.Value(N); CurrentLine->AddStatusLast(Standard_True,N,PathPnt); - AddPointInCurrentLine(N,PathPnt,CurrentLine); + AddPointInCurrentLine(N,PathPnt,theQuad,CurrentLine); } } - else if (aStatus == 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; - seqAlone.Append(N); - 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 (aStatus == IntWalk_ArretSurPoint) + { + if (Func.IsTangent()) + { + PrevSignOfBcoeff = SignOfBcoeff; + gp_Vec newd3d; + gp_Dir2d newd2d; + Standard_Boolean IsDiscriminantNull; + Standard_Boolean DirComputed = + ComputeDirOfTangentialIntersection(Func, StepSignTangent, + IsDiscriminantNull, SignOfBcoeff, + newd3d, newd2d); + if (DirComputed && IsDiscriminantNull) + { + if (SignOfBcoeff == 0) //point of branching + aStatus = IntWalk_ArretSurPoint; + else + { + if (PrevSignOfBcoeff == 0 || + SignOfBcoeff == PrevSignOfBcoeff) + { + aStatus = 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)); + //aStatus = IntWalk_ArretSurPoint; + } + } } - else { - CurrentLine->AddStatusLast(Standard_False); - IntSurf_PntOn2S newP; - newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2)); - CurrentLine->AddPoint(newP); + } //if (Func.IsTangent()) + if (aStatus == 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; - seqAlone.Append(lines.Length()+1); - seqAjout.Append(lines.Length()+1); + seqAlone.Append(N); + 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,theQuad,CurrentLine); + } + else { + CurrentLine->AddStatusLast(Standard_False); + IntSurf_PntOn2S newP; + newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2)); + CurrentLine->AddPoint(newP); + Rajout = Standard_True; + seqAlone.Append(lines.Length()+1); + seqAjout.Append(lines.Length()+1); + } } } } @@ -508,13 +594,11 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, previousd2d = Func.Direction2d(); CurrentLine->AddPoint(previousPoint); } - else if (aStatus == IntWalk_PointConfondu) - { - aNbIter --; - } - } - } + PrevStepWrong = Standard_False; + } //there is a solution + } //if (Rsnld.IsDone()) else { //no numerical solution NotDone + PrevStepWrong = Standard_True; PasC = PasC/2.; PasCu = Abs(PasC*previousd2d.X()); PasCv = Abs(PasC*previousd2d.Y()); @@ -556,17 +640,436 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, */ } } - - 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 + + //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) || + !IsDiscriminantNull) + continue; + if (SignOfBcoeff == 0) //point of branching or tangent zone + continue; + previousd3d = newd3d; + previousd2d = newd2d; + //here and are defined + + CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator()); + //jgv + /* + Standard_Real u_i, v_i; + theQuad.Parameters(previousPoint.Value(), u_i, v_i); + previousPoint.SetValue(!reversed, u_i, v_i); + */ + ///// + 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; + PrevStepWrong = 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 + PrevStepWrong = Standard_True; + 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); + } + Func.Values(Uvap, FuncVal, D); + } + 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 + } + } + aStatus = TestDeflection(Func, Arrive,Uvap,StatusPrecedent, + NbDivision,PasC,PasSav,StepSign, + CurrentLine->NbPoints(),ArretAjout,PrevStepWrong,OnPrevTangency); + StatusPrecedent = aStatus; + if (aStatus == 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 (aStatus != IntWalk_ArretSurPointPrecedent) { + //jgv + /* + Standard_Real u_i, v_i, prev_ui, prev_vi; + theQuad.Parameters(Psol.Value(), u_i, v_i); + IntSurf_PntOn2S LastPnt = CurrentLine->Value(CurrentLine->NbPoints()); + LastPnt.ParametersOnSurface(!reversed, prev_ui, prev_vi); + RecadreParam(u_i, prev_ui, theQuad); + Psol.SetValue(!reversed, u_i, v_i); + */ + ///// + 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 (aStatus == 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 ( aStatus == 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); + //jgv + /* + IntSurf_PntOn2S aFirstPoint = CurrentLine->Value(1); + Standard_Real u_i, v_i, prev_ui, prev_vi; + //theQuad.Parameters(aFirstPoint.Value(), u_i, v_i); + aFirstPoint.ParametersOnSurface(!reversed, u_i, v_i); + IntSurf_PntOn2S LastPnt = CurrentLine->Value(CurrentLine->NbPoints()); + LastPnt.ParametersOnSurface(!reversed, prev_ui, prev_vi); + RecadreParam(u_i, prev_ui, theQuad); + aFirstPoint.SetValue(!reversed, u_i, v_i); + */ + ///// + 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,theQuad,CurrentLine); + //AddPointInCurrentLine(N,PathPnt,CurrentLine); + } + } + else if (aStatus == IntWalk_ArretSurPoint && Func.IsTangent()) + { + PrevSignOfBcoeff = SignOfBcoeff; + gp_Vec aNewD3d; + gp_Dir2d aNewD2d; + Standard_Boolean aLocalIsDiscriminantNull; + if (ComputeDirOfTangentialIntersection(Func, StepSignTangent, + aLocalIsDiscriminantNull, SignOfBcoeff, + aNewD3d, aNewD2d) && + aLocalIsDiscriminantNull) + { + if (SignOfBcoeff == 0) //point of branching + { + //aStatus = IntWalk_ArretSurPoint; + } + else + { + if (PrevSignOfBcoeff == 0 || + SignOfBcoeff == PrevSignOfBcoeff) + { + aStatus = IntWalk_OKtangent; + MakeWalkingPoint(2, Uvap(1), Uvap(2), Func, previousPoint); + previousd3d = aNewD3d; + previousd2d = aNewD2d; + //jgv + /* + Standard_Real u_i, v_i, prev_ui, prev_vi; + theQuad.Parameters(previousPoint.Value(), u_i, v_i); + IntSurf_PntOn2S LastPnt = CurrentLine->Value(CurrentLine->NbPoints()); + LastPnt.ParametersOnSurface(!reversed, prev_ui, prev_vi); + RecadreParam(u_i, prev_ui, theQuad); + previousPoint.SetValue(!reversed, u_i, v_i); + */ + ///// + 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)); + //aStatus = IntWalk_ArretSurPoint; + } + } + } + if (aStatus == 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(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,theQuad,CurrentLine); + //AddPointInCurrentLine(Ipass,PathPnt,CurrentLine); + } + else { + CurrentLine->AddStatusLast(Standard_False); + IntSurf_PntOn2S newP; + newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2)); + //jgv + /* + Standard_Real u_i, v_i, prev_ui, prev_vi; + theQuad.Parameters(newP.Value(), u_i, v_i); + IntSurf_PntOn2S LastPnt = CurrentLine->Value(CurrentLine->NbPoints()); + LastPnt.ParametersOnSurface(!reversed, prev_ui, prev_vi); + RecadreParam(u_i, prev_ui, theQuad); + newP.SetValue(!reversed, u_i, v_i); + */ + ///// + CurrentLine->AddPoint(newP); + Rajout = Standard_True; + seqAjout.Append(lines.Length()+1); + } + } + } + } + else if (aStatus == IntWalk_OK) { + if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass); + previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2)); + //previousd3d = Func.Direction3d(); + //previousd2d = Func.Direction2d(); + //jgv + /* + Standard_Real u_i, v_i, prev_ui, prev_vi; + theQuad.Parameters(previousPoint.Value(), u_i, v_i); + IntSurf_PntOn2S LastPnt = CurrentLine->Value(CurrentLine->NbPoints()); + LastPnt.ParametersOnSurface(!reversed, prev_ui, prev_vi); + RecadreParam(u_i, prev_ui, theQuad); + previousPoint.SetValue(!reversed, u_i, v_i); + */ + ///// + CurrentLine->AddPoint(previousPoint); + } + PrevStepWrong = Standard_False; + } //there is a solution + } + else { //no numerical solution NotDone + PrevStepWrong = Standard_True; + 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); + CurrentLine->SetTangency(IsTangentialIntersection); + + 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 ebc381f547..1d875e2246 100644 --- a/src/IntWalk/IntWalk_IWalking_5.gxx +++ b/src/IntWalk/IntWalk_IWalking_5.gxx @@ -18,6 +18,7 @@ namespace { static const Standard_Real CosRef2D = 0.88; // correspond to 25 d static const Standard_Integer MaxDivision = 60; // max number of step division // because the angle is too great in 2d (U4) + static const Standard_Real TolDiffPnts = 4.*Precision::SquareConfusion(); } IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection @@ -27,7 +28,12 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection const IntWalk_StatusDeflection StatusPrecedent, Standard_Integer& NbDivision, Standard_Real& Step, - const Standard_Integer StepSign) + Standard_Real& StepInit, + const Standard_Integer StepSign, + const Standard_Integer CurNbPoints, + const Standard_Boolean ArretAjout, + const Standard_Boolean PrevStepWrong, + const Standard_Boolean OnPrevTangency) { // Check the step of advancement, AND recalculate this step : // @@ -75,14 +81,33 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection gp_Vec Corde(previousPoint.Value(), sp.Point()); const Standard_Real Norme = Corde.SquareMagnitude(); - - if ((Norme <= 4.0*Precision::SquareConfusion()) && - ((Duv <= Precision::SquarePConfusion()) || (StatusPrecedent != IntWalk_OK))) - { // the square is already taken in the constructor - aStatus = IntWalk_PointConfondu; - if (StatusPrecedent == IntWalk_PasTropGrand) +// if (Norme <= epsilon*epsilon) { +// if (Norme <= epsilon) { // the square is already taken in the constructor + Standard_Real TolNorm = Min(TolDiffPnts, epsilon); //epsilon; + if (CurNbPoints == 1 && ArretAjout && OnPrevTangency) + TolNorm = 1.e-10; + if (Norme <= TolNorm) { + if (CurNbPoints == 1 && !ArretAjout && !OnPrevTangency && + (Step > StepInit || StepInit - Step <= Precision::Confusion())) + //current tolerance is too big even for first step + epsilon = Norme / 4.; + else { - return IntWalk_ArretSurPointPrecedent; + if (Step > StepInit || + StepInit - Step <= Precision::Confusion()) + { + Standard_Real RefDist = Sqrt(Norme); + Standard_Real tolconf = Sqrt(TolNorm); + Standard_Real LocalResol = 0.; + if (RefDist > gp::Resolution()) + LocalResol = Step * tolconf / RefDist; + if (Step < 2*LocalResol) + Step = StepInit = pas = 2*LocalResol; + return IntWalk_PointConfondu; + } + aStatus = IntWalk_PointConfondu; + if (StatusPrecedent == IntWalk_PasTropGrand) + return IntWalk_ArretSurPointPrecedent; } } else @@ -119,12 +144,28 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection if ((Abs(Du) < aTolU) && (Abs(Dv) < aTolV)) { - //Thin shapes (for which Ulast-Ufirst or/and Vlast-Vfirst is quite small) - //exists (see bug #25820). In this case, step is quite small too. - //Nevertheless, it not always means that we mark time. Therefore, Du and Dv - //must consider step (aMinTolU and aMinTolV parameters). - - return IntWalk_ArretSurPointPrecedent; //confused point 2d + if (CurNbPoints == 1 && aStatus == IntWalk_OK && + !ArretAjout && !OnPrevTangency && + (Step > StepInit || StepInit - Step <= Precision::Confusion())) + { + //current tolerance is too big even for first step + tolerance(1) = Abs(Du)/2.; + tolerance(2) = Abs(Dv)/2.; + if (tolerance(1) <= gp::Resolution()) + tolerance(1) = tolerance(2); + if (tolerance(2) <= gp::Resolution()) + tolerance(2) = tolerance(1); + if (tolerance(1) <= gp::Resolution() && + tolerance(2) <= gp::Resolution()) + { + aStatus = IntWalk_PointConfondu; + if (StatusPrecedent == IntWalk_PasTropGrand) + aStatus = IntWalk_ArretSurPointPrecedent; + return aStatus; + } + } + else + return IntWalk_ArretSurPointPrecedent; //confused point 2d } Standard_Real Cosi = StepSign * (Du * previousd2d.X() + Dv * previousd2d.Y()); @@ -133,14 +174,23 @@ 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) - if ((NbDivision < MaxDivision) && (aStatus != IntWalk_PointConfondu) && - (StatusPrecedent!= IntWalk_PointConfondu)) + if ((NbDivision < MaxDivision) && + (aStatus != IntWalk_PointConfondu) && + (StatusPrecedent!= IntWalk_PointConfondu)) { Standard_Real Cosi2 = Cosi * Cosi / Duv; if (Cosi2 < CosRef2D || Cosi < 0 ) { @@ -194,9 +244,10 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection Standard_Real d2dx = Abs(previousd2d.X()); Standard_Real d2dy = Abs(previousd2d.Y()); + Standard_Real PrevStep = Step; if (d2dx < tolerance(1)) { - Step = StepV/d2dy; + Step = StepV/d2dy; } else if (d2dy < tolerance(2)) { @@ -206,6 +257,10 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection { Step = Min(StepU/d2dx,StepV/d2dy); } + if (Step <= PrevStep) //no chance for increasing of real step + aStatus = IntWalk_ArretSurPointPrecedent; + else if (PrevStepWrong) + return IntWalk_ArretSurPoint; //break of surface: end of C1-interval } else { @@ -306,5 +361,8 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection } } } - return aStatus; + else if (aStatus == IntWalk_PointConfondu) //finish + aStatus = IntWalk_ArretSurPointPrecedent; + + return aStatus; } diff --git a/src/IntWalk/IntWalk_IWalking_6.gxx b/src/IntWalk/IntWalk_IWalking_6.gxx index 4fa8f920d1..6932dda86a 100644 --- a/src/IntWalk/IntWalk_IWalking_6.gxx +++ b/src/IntWalk/IntWalk_IWalking_6.gxx @@ -12,24 +12,431 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#include +#include + +#include + +//Temporary +//#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 = "<Value(Index).ValueOnSurface(!reversed); + sprintf(name, "pp%d_%d", indline, Index); + DrawTrSurf::Set(name, curPnt2d); + } + */ + //#endif + } + + //if (aMaxCurvature / aMinCurvature >= aFactor) + if (aMaxCurvature >= aFactor * aMinCurvature) + lines(indline)->EnablePurging(Standard_False); +} + +Standard_Integer IntWalk_IWalking::InsertMiddlePoint(const Standard_Integer indline, + const Standard_Integer Index, + TheIWFunction& Func, + TColStd_SequenceOfReal& Distances, + TColStd_SequenceOfReal& Params, + TColStd_SequenceOfReal& Curvatures) +{ + const Standard_Real SqTol3d = Precision::Confusion()*Precision::Confusion(); + + IntSurf_Quadric theQuad = (IntSurf_Quadric)(Func.ISurface()); + + gp_Pnt2d PrevP2d = lines(indline)->Value(Index-1).ValueOnSurface(reversed); + gp_Pnt2d CurP2d = lines(indline)->Value(Index).ValueOnSurface(reversed); + gp_Pnt2d MidP2d((PrevP2d.XY() + CurP2d.XY())/2.); + + if (Abs(CurP2d.X() - MidP2d.X()) < tolerance(1) && + Abs(CurP2d.Y() - MidP2d.Y()) < tolerance(2)) + return 0; + + math_Vector BornInf(1, 2), BornSup(1, 2), UVap(1, 2); + BornInf(1) = Um; + BornSup(1) = UM; + BornInf(2) = Vm; + BornSup(2) = VM; + UVap(1) = MidP2d.X(); + UVap(2) = MidP2d.Y(); + + IntSurf_PntOn2S PointOnPSurf; + MakeWalkingPoint(11, UVap(1), UVap(2), Func, PointOnPSurf); + gp_Pnt MidPnt = PointOnPSurf.Value(); + gp_Pnt PrevPnt = lines(indline)->Value(Index-1).Value(); + gp_Pnt CurPnt = lines(indline)->Value(Index).Value(); + /* + Standard_Real SqDistMidPrev = MidPnt.SquareDistance(PrevPnt); + Standard_Real SqDistMidCur = MidPnt.SquareDistance(CurPnt); + */ + Standard_Real DistMidPrev = MidPnt.Distance(PrevPnt); + Standard_Real DistMidCur = MidPnt.Distance(CurPnt); + + math_FunctionSetRoot Rsnld(Func, tolerance); + Rsnld.Perform(Func,UVap,BornInf,BornSup); + if (Rsnld.IsDone() && Abs(Func.Root()) <= Func.Tolerance()) + Rsnld.Root(UVap); + + IntSurf_PntOn2S NewPoint; + MakeWalkingPoint(2, UVap(1), UVap(2), Func, NewPoint); + + gp_Pnt NewPnt = NewPoint.Value(); + Standard_Real SqDistNewPrev = NewPnt.SquareDistance(PrevPnt); + Standard_Real SqDistNewCur = NewPnt.SquareDistance(CurPnt); + if (SqDistNewPrev < SqTol3d || + SqDistNewCur < SqTol3d) + return 0; + + //Check for result point to lie near middle point + /* + Standard_Real SqDistMidRes = MidPnt.SquareDistance(NewPoint.Value()); + if (SqDistMidRes > SqDistMidPrev && + SqDistMidRes > SqDistMidCur) + cout< DistMidPrev && + DistMidRes > DistMidCur) + { + std::cout<Value(Index-1); + LastPnt.ParametersOnSurface(!reversed, prev_ui, prev_vi); + RecadreParam(u_i, prev_ui, theQuad); + NewPoint.SetValue(!reversed, u_i, v_i); + + lines(indline)->InsertBefore(Index, NewPoint); + + //Recompute , and + Distances.Remove(Index, Distances.Length()); + + //gp_Pnt PrevPnt = lines(indline)->Value(Index-1).Value(); + //gp_Pnt2d PrevP2d = lines(indline)->Value(Index-1).ValueOnSurface(reversed); + gp_Pnt2d PrevP2dOnQuad = lines(indline)->Value(Index-1).ValueOnSurface(!reversed); + + for (Standard_Integer i = Index; i <= lines(indline)->NbPoints(); i++) + { + gp_Pnt aCurPnt = lines(indline)->Value(i).Value(); + gp_Pnt2d aCurP2d = lines(indline)->Value(i).ValueOnSurface(reversed); + gp_Pnt2d CurP2dOnQuad = lines(indline)->Value(i).ValueOnSurface(!reversed); + Standard_Real dist3d = PrevPnt.Distance(aCurPnt); + Standard_Real dist2d = PrevP2d.Distance(aCurP2d); + Standard_Real dist2dOnQuad = PrevP2dOnQuad.Distance(CurP2dOnQuad); + + /* + if (dist3d < Precision::Confusion() || + (Abs(aCurP2d.X() - PrevP2d.X()) < tolerance(1) && + Abs(aCurP2d.Y() - PrevP2d.Y()) < tolerance(2))) + return Standard_False; + */ + + Standard_Real CurDist = Distances(Distances.Length()) + dist3d + dist2d + dist2dOnQuad; + Distances.Append(CurDist); + PrevPnt = aCurPnt; + PrevP2d = aCurP2d; + PrevP2dOnQuad = CurP2dOnQuad; + } + + Params.Clear(); + for (Standard_Integer i = 1; i < Distances.Length(); i++) + Params.Append(Distances(i) / Distances(Distances.Length())); + Params.Append(1.); + + DefineCurvatures(indline, Params, Curvatures); + + lines(indline)->EnablePurging(Standard_False); + + return 1; +} void IntWalk_IWalking::MakeWalkingPoint (const Standard_Integer Case, @@ -68,6 +475,110 @@ void IntWalk_IWalking::MakeWalkingPoint } } +Standard_Boolean + IntWalk_IWalking::ComputeDirOfTangentialIntersection(TheIWFunction& sp, + Standard_Integer& StepSignTangent, + Standard_Boolean& IsDiscriminantNull, + Standard_Integer& SignOfBcoeff, + gp_Vec& newd3d, + gp_Dir2d& newd2d) +{ + gp_Vec Pu, Pv; + Standard_Real B11, B22, B12; + if (!ComputeB11orB22(sp, IsDiscriminantNull, SignOfBcoeff, + Pu, Pv, B11, B22, B12)) + return Standard_False; + + if (IsDiscriminantNull) + { + if (SignOfBcoeff != 0) + { + gp_Vec NewPreviousD3d; + gp_Dir2d NewPreviousD2d; + if (Abs(B11) > TolB) + { +#ifdef DRAW + cout<<"B11 = "<