From 9e7cc3ad597b7fb6634f5c2022fd4b5261eee0ba Mon Sep 17 00:00:00 2001 From: kgv Date: Sat, 10 Apr 2021 17:44:18 +0300 Subject: [PATCH] 0032297: Coding Rules - merge GCPnts_UniformAbscissa.pxx into GCPnts_UniformAbscissa.cxx --- src/GCPnts/FILES | 1 - src/GCPnts/GCPnts_UniformAbscissa.cxx | 595 ++++++++++++++++++++++++-- src/GCPnts/GCPnts_UniformAbscissa.hxx | 276 ++++++++---- src/GCPnts/GCPnts_UniformAbscissa.pxx | 477 --------------------- 4 files changed, 757 insertions(+), 592 deletions(-) delete mode 100644 src/GCPnts/GCPnts_UniformAbscissa.pxx diff --git a/src/GCPnts/FILES b/src/GCPnts/FILES index 13a6ee2d6e..8f98e2faeb 100755 --- a/src/GCPnts/FILES +++ b/src/GCPnts/FILES @@ -10,7 +10,6 @@ GCPnts_TangentialDeflection.cxx GCPnts_TangentialDeflection.hxx GCPnts_TCurveTypes.hxx GCPnts_UniformAbscissa.cxx -GCPnts_UniformAbscissa.pxx GCPnts_UniformAbscissa.hxx GCPnts_UniformDeflection.cxx GCPnts_UniformDeflection.hxx diff --git a/src/GCPnts/GCPnts_UniformAbscissa.cxx b/src/GCPnts/GCPnts_UniformAbscissa.cxx index 75c50752e1..5651350375 100644 --- a/src/GCPnts/GCPnts_UniformAbscissa.cxx +++ b/src/GCPnts/GCPnts_UniformAbscissa.cxx @@ -12,47 +12,586 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include -#include -#include -#include #include -#include -#include + +#include +#include +#include +#include + +//======================================================================= +//function : GetParameterLengthRatio +//purpose : +//======================================================================= +template +static Standard_Real GetParameterLengthRatio (const TheCurve& theC) +{ + switch (theC.GetType()) + { + case GeomAbs_Circle: + { + return theC.Circle().Radius(); + } + case GeomAbs_Line: + { + return 1.0; + } + case GeomAbs_BezierCurve: + case GeomAbs_BSplineCurve: + { + if (!theC.IsRational()) + { + return theC.DN (0.0, 1).Magnitude(); + } + return RealLast(); + } + default: + { + return RealLast(); + } + } +} + +//======================================================================= +//function : GetAbsType +//purpose : +//======================================================================= +template +static GCPnts_AbscissaType GetAbsType (const TheCurve& theC) +{ + if (theC.NbIntervals (GeomAbs_C1) > 1) + { + return GCPnts_AbsComposite; + } + + switch (theC.GetType()) + { + case GeomAbs_Line: + case GeomAbs_Circle: + { + return GCPnts_LengthParametrized; + } + case GeomAbs_BezierCurve: + { + Handle(typename GCPnts_TCurveTypes::BezierCurve) aBZ = theC.Bezier(); + if (aBZ->NbPoles() == 2 && !aBZ->IsRational()) + { + return GCPnts_LengthParametrized; + } + return GCPnts_Parametrized; + } + case GeomAbs_BSplineCurve: + { + Handle(typename GCPnts_TCurveTypes::BSplineCurve) aBS = theC.BSpline(); + if (aBS->NbPoles() == 2 && !aBS->IsRational()) + { + return GCPnts_LengthParametrized; + } + return GCPnts_Parametrized; + } + default: + { + return GCPnts_Parametrized; + } + } +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +template +static Standard_Boolean Perform (TColStd_Array1OfReal& theParameters, + const TheCurve& theC, + const Standard_Real theAbscissa, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theTotalLength, + Standard_Integer& theNbPoints, + const Standard_Real theEPSILON) +{ + Standard_Boolean isLocalDone = Standard_True; + Standard_Real aUU1 = Min (theU1, theU2), aUU2 = Max (theU1, theU2); + theNbPoints = 0; + + // this initialization avoids the computation of the Length of the curve + Standard_Real aDelta = (theAbscissa / theTotalLength) * (aUU2 - aUU1); + Standard_Integer anIndex = 1; + theParameters.SetValue (anIndex, aUU1); + for (Standard_Boolean isNotDone = Standard_True; isNotDone; ) + { + Standard_Real aUi = theParameters.Value (anIndex) + aDelta; + if (aUi > aUU2) + { + // MSV 21.04.2004: OCC5739 (GCPnts_UniformAbscissa gives incorrect distribution of points) + // if (aUU2 - theParameters.Value (anIndex) > 0.01 * aDelta) { Index += 1; } + // theParameters.SetValue (anIndex, aUU2); + // isNotDone = Standard_False; + // break; + aUi = aUU2; + } + GCPnts_AbscissaPoint anAbscissaFinder (theC, theAbscissa, + theParameters.Value (anIndex), + aUi, + theEPSILON); + if (anAbscissaFinder.IsDone()) + { + anIndex += 1; + aUi = anAbscissaFinder.Parameter(); + if (Abs (aUi - aUU2) <= theEPSILON) + { + theParameters.SetValue (anIndex, aUU2); + isNotDone = Standard_False; + } + else if (aUi < aUU2) + { + theParameters.SetValue (anIndex, aUi); + } + else + { + theParameters.SetValue (anIndex, aUU2); + isNotDone = Standard_False; + } + isNotDone = isNotDone && (anIndex + 1 <= theParameters.Length()); + } + else + { + isLocalDone = Standard_False; + isNotDone = Standard_True; + aDelta -= aDelta / 10; + if (aDelta <= Precision::PConfusion()) + { + break; + } + } + } + theNbPoints = anIndex; + return isLocalDone; +} + +//======================================================================= +//function : PerformLengthParametrized +//purpose : +//======================================================================= +template +static Standard_Boolean PerformLengthParametrized (TColStd_Array1OfReal& theParameters, + const TheCurve& theC, + const Standard_Real theAbscissa, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theTotalLength, + Standard_Integer& theNbPoints, + const Standard_Real theEPSILON) +{ + Standard_Real aUU1 = Min (theU1, theU2); + Standard_Real aUU2 = Max (theU1, theU2); + + // Ratio is defined as dl = Ratio * du + // for a circle of gp Ratio is equal to the radius of the circle. + // for a line of gp ratio is equal to 1.0 + const Standard_Real aRatio = GetParameterLengthRatio (theC); + if (theAbscissa < 0.0e0) + { + aUU2 = Min (theU1, theU2); + aUU1 = Max (theU1, theU2); + } + + const Standard_Real aDelta = (theAbscissa / theTotalLength) * (aUU2 - aUU1); + Standard_Integer anIndex = 1; + theNbPoints = 0; + theParameters.SetValue (anIndex, aUU1); + for (Standard_Boolean isNotDone = Standard_True; isNotDone;) + { + anIndex += 1; + const Standard_Real aUi = theParameters.Value (anIndex - 1) + aDelta; + if (Abs (aUi - aUU2) <= theEPSILON) + { + theParameters.SetValue (anIndex, aUU2); + isNotDone = Standard_False; + } + else if (aUi < aUU2) + { + theParameters.SetValue (anIndex, aUi); + } + else + { + isNotDone = Standard_False; + if (Abs (theParameters.Value (anIndex - 1) - aUU2) * aRatio / theAbscissa < 0.1) + { + theParameters.SetValue (anIndex - 1, aUU2); + anIndex -= 1; + } + else + { + theParameters.SetValue (anIndex, aUU2); + } + } + isNotDone = (anIndex + 1 <= theParameters.Length()) && isNotDone; + } + + theNbPoints = anIndex; + return Standard_True; +} //======================================================================= //function : GCPnts_UniformAbscissa -//purpose : +//purpose : //======================================================================= - -GCPnts_UniformAbscissa::GCPnts_UniformAbscissa () - :myDone(Standard_False), - myNbPoints(0), - myAbscissa(0.) +GCPnts_UniformAbscissa::GCPnts_UniformAbscissa() +: myDone (Standard_False), + myNbPoints (0), + myAbscissa (0.0) { -} + // +} -#include -#include +//======================================================================= +//function : GCPnts_UniformAbscissa +//purpose : +//======================================================================= +GCPnts_UniformAbscissa::GCPnts_UniformAbscissa (const Adaptor3d_Curve& theC, + const Standard_Real theAbscissa, + const Standard_Real theTol) +: myDone (Standard_False), + myNbPoints (0), + myAbscissa (0.0) +{ + Initialize (theC, theAbscissa, theTol); +} -#define TheCurve Adaptor3d_Curve -#define Handle_TheBezierCurve Handle(Geom_BezierCurve) -#define Handle_TheBSplineCurve Handle(Geom_BSplineCurve) +//======================================================================= +//function : GCPnts_UniformAbscissa +//purpose : +//======================================================================= +GCPnts_UniformAbscissa::GCPnts_UniformAbscissa (const Adaptor2d_Curve2d& theC, + const Standard_Real theAbscissa, + const Standard_Real theTol) +: myDone (Standard_False), + myNbPoints (0), + myAbscissa (0.0) +{ + Initialize (theC, theAbscissa, theTol); +} -#include "GCPnts_UniformAbscissa.pxx" +//======================================================================= +//function : GCPnts_UniformAbscissa +//purpose : +//======================================================================= +GCPnts_UniformAbscissa::GCPnts_UniformAbscissa (const Adaptor3d_Curve& theC, + const Standard_Real theAbscissa, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theTol) +: myDone (Standard_False), + myNbPoints (0), + myAbscissa (0.0) +{ + Initialize (theC, theAbscissa, theU1, theU2, theTol); +} -#undef TheCurve -#undef Handle_TheBezierCurve -#undef Handle_TheBSplineCurve +//======================================================================= +//function : GCPnts_UniformAbscissa +//purpose : +//======================================================================= +GCPnts_UniformAbscissa::GCPnts_UniformAbscissa (const Adaptor2d_Curve2d& theC, + const Standard_Real theAbscissa, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theTol) +: myDone (Standard_False), + myNbPoints (0), + myAbscissa (0.0) +{ + Initialize (theC, theAbscissa, theU1, theU2, theTol); +} -#include -#include +//======================================================================= +//function : GCPnts_UniformAbscissa +//purpose : +//======================================================================= +GCPnts_UniformAbscissa::GCPnts_UniformAbscissa (const Adaptor3d_Curve& theC, + const Standard_Integer theNbPoints, + const Standard_Real theTol) +: myDone (Standard_False), + myNbPoints (0), + myAbscissa (0.0) +{ + Initialize (theC, theNbPoints, theTol); +} -#define TheCurve Adaptor2d_Curve2d -#define Handle_TheBezierCurve Handle(Geom2d_BezierCurve) -#define Handle_TheBSplineCurve Handle(Geom2d_BSplineCurve) +//======================================================================= +//function : GCPnts_UniformAbscissa +//purpose : +//======================================================================= +GCPnts_UniformAbscissa::GCPnts_UniformAbscissa (const Adaptor2d_Curve2d& theC, + const Standard_Integer theNbPoints, + const Standard_Real theTol) +: myDone (Standard_False), + myNbPoints (0), + myAbscissa (0.0) +{ + Initialize (theC, theNbPoints, theTol); +} -#include "GCPnts_UniformAbscissa.pxx" +//======================================================================= +//function : GCPnts_UniformAbscissa +//purpose : +//======================================================================= +GCPnts_UniformAbscissa::GCPnts_UniformAbscissa (const Adaptor3d_Curve& theC, + const Standard_Integer theNbPoints, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theTol) +: myDone (Standard_False), + myNbPoints (0), + myAbscissa (0.0) +{ + Initialize (theC, theNbPoints, theU1, theU2, theTol); +} +//======================================================================= +//function : GCPnts_UniformAbscissa +//purpose : +//======================================================================= +GCPnts_UniformAbscissa::GCPnts_UniformAbscissa (const Adaptor2d_Curve2d& theC, + const Standard_Integer theNbPoints, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theTol) +: myDone (Standard_False), + myNbPoints (0), + myAbscissa (0.0) +{ + Initialize (theC, theNbPoints, theU1, theU2, theTol); +} +//======================================================================= +//function : Initialize +//purpose : +//======================================================================= +void GCPnts_UniformAbscissa::Initialize (const Adaptor3d_Curve& theC, + const Standard_Real theAbscissa, + const Standard_Real theTol) +{ + Initialize (theC, theAbscissa, theC.FirstParameter(), theC.LastParameter(), theTol); +} +//======================================================================= +//function : Initialize +//purpose : +//======================================================================= +void GCPnts_UniformAbscissa::Initialize (const Adaptor2d_Curve2d& theC, + const Standard_Real theAbscissa, + const Standard_Real theTol) +{ + Initialize (theC, theAbscissa, theC.FirstParameter(), theC.LastParameter(), theTol); +} + +//======================================================================= +//function : Initialize +//purpose : +//======================================================================= +void GCPnts_UniformAbscissa::Initialize (const Adaptor3d_Curve& theC, + const Standard_Real theAbscissa, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theTol) +{ + initialize (theC, theAbscissa, theU1, theU2, theTol); +} + +//======================================================================= +//function : Initialize +//purpose : +//======================================================================= +void GCPnts_UniformAbscissa::Initialize (const Adaptor2d_Curve2d& theC, + const Standard_Real theAbscissa, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theTol) +{ + initialize (theC, theAbscissa, theU1, theU2, theTol); +} + +//======================================================================= +//function : initialize +//purpose : +//======================================================================= +template +void GCPnts_UniformAbscissa::initialize (const TheCurve& theC, + const Standard_Real theAbscissa, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theTol) +{ + myAbscissa = theAbscissa; + myNbPoints = 0; + myDone = Standard_False; + + const Standard_Real anEPSILON = theC.Resolution (Max (theTol, Precision::Confusion())); + const Standard_Real aL = GCPnts_AbscissaPoint::Length (theC, theU1, theU2, anEPSILON); + if (aL <= Precision::Confusion()) + { + return; + } + + // compute the total Length here so that we can guess + // the number of points instead of letting the constructor + // of CPnts_AbscissaPoint do that and lose the information + const Standard_Real aSizeR = aL / Abs (theAbscissa) + 5; + if (aSizeR >= IntegerLast()) // modified by Igor Motchalov 23/04/2001 + { + return; + } + + const Standard_Integer aSize = (Standard_Integer )aSizeR; + if (!myParams.IsNull()) + { + if (myParams->Length() < aSize) + { + myParams.Nullify(); + myParams = new TColStd_HArray1OfReal (1, aSize); + } + } + else + { + myParams = new TColStd_HArray1OfReal (1, aSize); + } + + const GCPnts_AbscissaType aType = GetAbsType (theC); + switch (aType) + { + case GCPnts_LengthParametrized: + { + myDone = PerformLengthParametrized (myParams->ChangeArray1(), + theC, + theAbscissa, + theU1, theU2, + aL, + myNbPoints, + anEPSILON); + break; + } + case GCPnts_Parametrized: + case GCPnts_AbsComposite: + { + myDone = Perform (myParams->ChangeArray1(), + theC, + theAbscissa, + theU1, theU2, + aL, + myNbPoints, + anEPSILON); + break; + } + } +} + +//======================================================================= +//function : Initialize +//purpose : +//======================================================================= +void GCPnts_UniformAbscissa::Initialize (const Adaptor3d_Curve& theC, + const Standard_Integer theNbPoints, + const Standard_Real theTol) +{ + Initialize (theC, theNbPoints, theC.FirstParameter(), theC.LastParameter(), theTol); +} + +//======================================================================= +//function : Initialize +//purpose : +//======================================================================= +void GCPnts_UniformAbscissa::Initialize (const Adaptor2d_Curve2d& theC, + const Standard_Integer theNbPoints, + const Standard_Real theTol) +{ + Initialize (theC, theNbPoints, theC.FirstParameter(), theC.LastParameter(), theTol); +} + +//======================================================================= +//function : Initialize +//purpose : +//======================================================================= +void GCPnts_UniformAbscissa::Initialize (const Adaptor3d_Curve& theC, + const Standard_Integer theNbPoints, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theTol) +{ + initialize (theC, theNbPoints, theU1, theU2, theTol); +} + +//======================================================================= +//function : Initialize +//purpose : +//======================================================================= +void GCPnts_UniformAbscissa::Initialize (const Adaptor2d_Curve2d& theC, + const Standard_Integer theNbPoints, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theTol) +{ + initialize (theC, theNbPoints, theU1, theU2, theTol); +} + +//======================================================================= +//function : initialize +//purpose : +//======================================================================= +template +void GCPnts_UniformAbscissa::initialize (const TheCurve& theC, + const Standard_Integer theNbPoints, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theTol) +{ + Standard_ConstructionError_Raise_if (theNbPoints <= 1, "GCPnts_UniformAbscissa::Initialize() - number of points should be >= 2"); + myNbPoints = 0; + myDone = Standard_False; + + const Standard_Real anEPSILON = theC.Resolution (Max (theTol, Precision::Confusion())); + // although very similar to Initialize with Abscissa this avoid + // the computation of the total length of the curve twice + const Standard_Real aL = GCPnts_AbscissaPoint::Length (theC, theU1, theU2, anEPSILON); + if (aL <= Precision::Confusion()) + { + return; + } + + const Standard_Real anAbscissa = myAbscissa = aL / (theNbPoints - 1); + + // compute the total Length here so that we can guess + // the number of points instead of letting the constructor + // of CPnts_AbscissaPoint do that and lose the information + const Standard_Integer aSize = theNbPoints + 5; + if (!myParams.IsNull()) + { + if (myParams->Length() < aSize) + { + myParams.Nullify(); + myParams = new TColStd_HArray1OfReal (1, aSize); + } + } + else + { + myParams = new TColStd_HArray1OfReal (1, aSize); + } + + myNbPoints = 0; + const GCPnts_AbscissaType aType = GetAbsType (theC); + switch (aType) + { + case GCPnts_LengthParametrized: + { + myDone = PerformLengthParametrized (myParams->ChangeArray1(), + theC, + anAbscissa, + theU1, theU2, + aL, + myNbPoints, + anEPSILON); + break; + } + case GCPnts_Parametrized: + case GCPnts_AbsComposite: + { + myDone = Perform (myParams->ChangeArray1(), + theC, + anAbscissa, + theU1, theU2, + aL, + myNbPoints, + anEPSILON); + break; + } + } +} diff --git a/src/GCPnts/GCPnts_UniformAbscissa.hxx b/src/GCPnts/GCPnts_UniformAbscissa.hxx index 62b56936af..4ff80abb5b 100644 --- a/src/GCPnts/GCPnts_UniformAbscissa.hxx +++ b/src/GCPnts/GCPnts_UniformAbscissa.hxx @@ -20,101 +20,190 @@ #include #include -class Standard_DomainError; -class Standard_ConstructionError; -class Standard_OutOfRange; -class StdFail_NotDone; class Adaptor3d_Curve; class Adaptor2d_Curve2d; //! This class allows to compute a uniform distribution of points -//! on a curve (ie the points will all be equally distant). +//! on a curve (i.e. the points will all be equally distant). class GCPnts_UniformAbscissa { public: DEFINE_STANDARD_ALLOC - //! creation of a indefinite UniformAbscissa Standard_EXPORT GCPnts_UniformAbscissa(); - - //! Computes a uniform abscissa distribution of points on - //! the Curve . Parameter Toler is equal Precision::Confusion by default. - //! It Is used for more precise calculation of curve length - Standard_EXPORT GCPnts_UniformAbscissa(const Adaptor3d_Curve& C, const Standard_Real Abscissa, const Standard_Real Toler = -1); - - //! Computes a Uniform abscissa distribution of points - //! on a part of the Curve . Parameter Toler is equal Precision::Confusion by default. - //! It Is used for more precise calculation of curve length - Standard_EXPORT GCPnts_UniformAbscissa(const Adaptor3d_Curve& C, const Standard_Real Abscissa, const Standard_Real U1, const Standard_Real U2, const Standard_Real Toler = -1); - - //! Computes a uniform abscissa distribution of points on - //! the Curve . - //! defines the nomber of desired points. - //! Parameter Toler is equal Precision::Confusion by default. - //! It Is used for more precise calculation of curve length - Standard_EXPORT GCPnts_UniformAbscissa(const Adaptor3d_Curve& C, const Standard_Integer NbPoints, const Standard_Real Toler = -1); - - //! Computes a Uniform abscissa distribution of points - //! on a part of the Curve . - //! Parameter Toler is equal Precision::Confusion by default. - //! It Is used for more precise calculation of curve length - Standard_EXPORT GCPnts_UniformAbscissa(const Adaptor3d_Curve& C, const Standard_Integer NbPoints, const Standard_Real U1, const Standard_Real U2, const Standard_Real Toler = -1); - - //! Initialize the algorithms with , , - Standard_EXPORT void Initialize (const Adaptor3d_Curve& C, const Standard_Real Abscissa, const Standard_Real Toler = -1); - - //! Initialize the algorithms with , , , - //! , - Standard_EXPORT void Initialize (const Adaptor3d_Curve& C, const Standard_Real Abscissa, const Standard_Real U1, const Standard_Real U2, const Standard_Real Toler = -1); - - //! Initialize the algorithms with , , and - Standard_EXPORT void Initialize (const Adaptor3d_Curve& C, const Standard_Integer NbPoints, const Standard_Real Toler = -1); - - //! Initialize the algorithms with , , , - //! , . - Standard_EXPORT void Initialize (const Adaptor3d_Curve& C, const Standard_Integer NbPoints, const Standard_Real U1, const Standard_Real U2, const Standard_Real Toler = -1); - - //! Computes a uniform abscissa distribution of points on - //! the Curve2d . - //! Parameter Toler is equal Precision::Confusion by default. - //! It Is used for more precise calculation of curve length - Standard_EXPORT GCPnts_UniformAbscissa(const Adaptor2d_Curve2d& C, const Standard_Real Abscissa, const Standard_Real Toler = -1); - - //! Computes a Uniform abscissa distribution of points - //! on a part of the Curve2d . - //! Parameter Toler is equal Precision::Confusion by default. - //! It Is used for more precise calculation of curve length - Standard_EXPORT GCPnts_UniformAbscissa(const Adaptor2d_Curve2d& C, const Standard_Real Abscissa, const Standard_Real U1, const Standard_Real U2, const Standard_Real Toler = -1); - - //! Computes a uniform abscissa distribution of points on - //! the Curve2d . - //! defines the nomber of desired points. - //! Parameter Toler is equal Precision::Confusion by default. - //! It Is used for more precise calculation of curve length - Standard_EXPORT GCPnts_UniformAbscissa(const Adaptor2d_Curve2d& C, const Standard_Integer NbPoints, const Standard_Real Toler = -1); - - //! Computes a Uniform abscissa distribution of points - //! on a part of the Curve2d . - //! Parameter Toler is equal Precision::Confusion by default. - //! It Is used for more precise calculation of curve length - Standard_EXPORT GCPnts_UniformAbscissa(const Adaptor2d_Curve2d& C, const Standard_Integer NbPoints, const Standard_Real U1, const Standard_Real U2, const Standard_Real Toler = -1); - - //! Initialize the algorithms with , , - Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& C, const Standard_Real Abscissa, const Standard_Real Toler = -1); - - //! Initialize the algorithms with , , , - //! , - Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& C, const Standard_Real Abscissa, const Standard_Real U1, const Standard_Real U2, const Standard_Real Toler = -1); - - //! Initialize the algorithms with , , and - Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& C, const Standard_Integer NbPoints, const Standard_Real Toler = -1); - - //! Initialize the algorithms with , , , - //! , . - Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& C, const Standard_Integer NbPoints, const Standard_Real U1, const Standard_Real U2, const Standard_Real Toler = -1); - + + //! Computes a uniform abscissa distribution of points on the 3D curve. + //! @param theC [in] input curve + //! @param theAbscissa [in] abscissa (distance between two consecutive points) + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT GCPnts_UniformAbscissa (const Adaptor3d_Curve& theC, + const Standard_Real theAbscissa, + const Standard_Real theToler = -1); + + //! Computes a Uniform abscissa distribution of points on a part of the 3D Curve. + //! @param theC [in] input curve + //! @param theAbscissa [in] abscissa (distance between two consecutive points) + //! @param theU1 [in] first parameter on curve + //! @param theU2 [in] last parameter on curve + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT GCPnts_UniformAbscissa (const Adaptor3d_Curve& theC, + const Standard_Real theAbscissa, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theToler = -1); + + //! Computes a uniform abscissa distribution of points on the 3D Curve. + //! @param theC [in] input curve + //! @param theNbPoints [in] defines the number of desired points + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT GCPnts_UniformAbscissa (const Adaptor3d_Curve& theC, + const Standard_Integer theNbPoints, + const Standard_Real theToler = -1); + + //! Computes a Uniform abscissa distribution of points on a part of the 3D Curve. + //! @param theC [in] input curve + //! @param theNbPoints [in] defines the number of desired points + //! @param theU1 [in] first parameter on curve + //! @param theU2 [in] last parameter on curve + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT GCPnts_UniformAbscissa (const Adaptor3d_Curve& theC, + const Standard_Integer theNbPoints, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theToler = -1); + + //! Initialize the algorithms with 3D curve, Abscissa, and Tolerance. + //! @param theC [in] input curve + //! @param theAbscissa [in] abscissa (distance between two consecutive points) + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT void Initialize (const Adaptor3d_Curve& theC, + const Standard_Real theAbscissa, + const Standard_Real theToler = -1); + + //! Initialize the algorithms with 3D curve, Abscissa, Tolerance, and parameter range. + //! @param theC [in] input curve + //! @param theAbscissa [in] abscissa (distance between two consecutive points) + //! @param theU1 [in] first parameter on curve + //! @param theU2 [in] last parameter on curve + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT void Initialize (const Adaptor3d_Curve& theC, + const Standard_Real theAbscissa, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theToler = -1); + + //! Initialize the algorithms with 3D curve, number of points, and Tolerance. + //! @param theC [in] input curve + //! @param theNbPoints [in] defines the number of desired points + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT void Initialize (const Adaptor3d_Curve& theC, + const Standard_Integer theNbPoints, + const Standard_Real theToler = -1); + + //! Initialize the algorithms with 3D curve, number of points, Tolerance, and parameter range. + //! @param theC [in] input curve + //! @param theNbPoints [in] defines the number of desired points + //! @param theU1 [in] first parameter on curve + //! @param theU2 [in] last parameter on curve + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT void Initialize (const Adaptor3d_Curve& theC, + const Standard_Integer theNbPoints, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theToler = -1); + +public: + + //! Computes a uniform abscissa distribution of points on the 2D curve. + //! @param theC [in] input curve + //! @param theAbscissa [in] abscissa (distance between two consecutive points) + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT GCPnts_UniformAbscissa (const Adaptor2d_Curve2d& theC, + const Standard_Real theAbscissa, + const Standard_Real theToler = -1); + + //! Computes a Uniform abscissa distribution of points on a part of the 2D Curve. + //! @param theC [in] input curve + //! @param theAbscissa [in] abscissa (distance between two consecutive points) + //! @param theU1 [in] first parameter on curve + //! @param theU2 [in] last parameter on curve + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT GCPnts_UniformAbscissa (const Adaptor2d_Curve2d& theC, + const Standard_Real theAbscissa, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theToler = -1); + + //! Computes a uniform abscissa distribution of points on the 2D Curve. + //! @param theC [in] input curve + //! @param theNbPoints [in] defines the number of desired points + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT GCPnts_UniformAbscissa (const Adaptor2d_Curve2d& theC, + const Standard_Integer theNbPoints, + const Standard_Real theToler = -1); + + //! Computes a Uniform abscissa distribution of points on a part of the 2D Curve. + //! @param theC [in] input curve + //! @param theNbPoints [in] defines the number of desired points + //! @param theU1 [in] first parameter on curve + //! @param theU2 [in] last parameter on curve + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT GCPnts_UniformAbscissa (const Adaptor2d_Curve2d& theC, + const Standard_Integer theNbPoints, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theToler = -1); + + //! Initialize the algorithms with 2D curve, Abscissa, and Tolerance. + //! @param theC [in] input curve + //! @param theAbscissa [in] abscissa (distance between two consecutive points) + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& theC, + const Standard_Real theAbscissa, + const Standard_Real theToler = -1); + + //! Initialize the algorithms with 2D curve, Abscissa, Tolerance, and parameter range. + //! @param theC [in] input curve + //! @param theAbscissa [in] abscissa (distance between two consecutive points) + //! @param theU1 [in] first parameter on curve + //! @param theU2 [in] last parameter on curve + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& theC, + const Standard_Real theAbscissa, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theToler = -1); + + //! Initialize the algorithms with 2D curve, number of points, and Tolerance. + //! @param theC [in] input curve + //! @param theNbPoints [in] defines the number of desired points + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& theC, + const Standard_Integer theNbPoints, + const Standard_Real theToler = -1); + + //! Initialize the algorithms with 2D curve, number of points, Tolerance, and parameter range. + //! @param theC [in] input curve + //! @param theNbPoints [in] defines the number of desired points + //! @param theU1 [in] first parameter on curve + //! @param theU2 [in] last parameter on curve + //! @param theToler [in] used for more precise calculation of curve length + //! (Precision::Confusion() by default) + Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& theC, + const Standard_Integer theNbPoints, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theToler = -1); + Standard_Boolean IsDone () const { return myDone; @@ -132,15 +221,30 @@ public: StdFail_NotDone_Raise_if (!myDone, "GCPnts_UniformAbscissa::Parameter()"); return myParams->Value (Index); } - - //! returne the current abscissa - //! ie the distance between two consecutive points + + //! Returns the current abscissa, i.e. the distance between two consecutive points. Standard_Real Abscissa () const { StdFail_NotDone_Raise_if (!myDone, "GCPnts_UniformAbscissa::Abscissa()"); return myAbscissa; } +private: + + //! Initializes algorithm. + template + void initialize (const TheCurve& theC, + const Standard_Real theAbscissa, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theTol); + + //! Initializes algorithm. + template + void initialize (const TheCurve& theC, + const Standard_Integer theNbPoints, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Real theTol); + private: Standard_Boolean myDone; Standard_Integer myNbPoints; diff --git a/src/GCPnts/GCPnts_UniformAbscissa.pxx b/src/GCPnts/GCPnts_UniformAbscissa.pxx deleted file mode 100644 index 6a505f7ebc..0000000000 --- a/src/GCPnts/GCPnts_UniformAbscissa.pxx +++ /dev/null @@ -1,477 +0,0 @@ -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static Standard_Real GetParameterLengthRatio(const TheCurve& C) -{ - switch (C.GetType()) { - - case GeomAbs_Circle : - return C.Circle().Radius(); - - case GeomAbs_Line : - return 1.; - - case GeomAbs_BezierCurve : - case GeomAbs_BSplineCurve : - { - if (!C.IsRational()) - return C.DN(0., 1).Magnitude(); - else - return RealLast(); - } - - default : - return RealLast(); - - } -} - - -static GCPnts_AbscissaType GetAbsType(const TheCurve& C) -{ - if (C.NbIntervals(GeomAbs_C1) > 1) - return GCPnts_AbsComposite; - - switch (C.GetType()) { - - case GeomAbs_Line: - case GeomAbs_Circle: - return GCPnts_LengthParametrized; - case GeomAbs_BezierCurve: - { - Handle_TheBezierCurve BZ = C.Bezier(); - if (BZ->NbPoles() == 2 && !BZ->IsRational()) - return GCPnts_LengthParametrized; - else - return GCPnts_Parametrized; - } - case GeomAbs_BSplineCurve: - { - Handle_TheBSplineCurve BS = C.BSpline() ; - if (BS->NbPoles() == 2 && !BS->IsRational()) - return GCPnts_LengthParametrized; - else - return GCPnts_Parametrized; - } - default: - return GCPnts_Parametrized ; - } -} - -static Standard_Boolean Perform(Handle(TColStd_HArray1OfReal)& HParameters, - const TheCurve& C, - const Standard_Real Abscissa, - const Standard_Real U1, - const Standard_Real U2, - const Standard_Real TotalLength, - Standard_Integer &NbPoints, - const Standard_Real EPSILON) -{ - Standard_Boolean NotDone = Standard_True; - Standard_Boolean LocalDone = Standard_True; -// Standard_Boolean Forward = Standard_True ; - Standard_Real UU1 = Min(U1, U2), UU2 = Max(U1, U2) ; - Standard_Integer Index ; -// Standard_Real UCurrent, Delta, Ui; - Standard_Real Delta, Ui; - NbPoints = 0 ; - -// -// this initialization avoids the computation of the Length -// of the curve - - Delta = (Abscissa/TotalLength) * (UU2 - UU1) ; - Index = 1 ; - HParameters->SetValue(Index,UU1) ; - while (NotDone) { - Ui = HParameters->Value(Index) + Delta; - if (Ui > UU2) { - // MSV 21.04.2004: OCC5739 (GCPnts_UniformAbscissa gives incorrect - // distribution of points) -// if (UU2 - HParameters->Value(Index) > 0.01*Delta) { -// Index += 1; -// } -// HParameters->SetValue(Index, UU2); -// NotDone = Standard_False; -// break; - Ui = UU2; - } - GCPnts_AbscissaPoint AbscissaFinder(C, - Abscissa, - HParameters->Value(Index), - Ui, - EPSILON) ; - if (AbscissaFinder.IsDone()) { - Index += 1 ; - Ui = AbscissaFinder.Parameter(); - if (Abs(Ui-UU2) <= EPSILON) { - HParameters->SetValue(Index, UU2); - NotDone = Standard_False; - } - else if (Ui < UU2) { - HParameters->SetValue(Index, Ui); - } - else { - HParameters->SetValue(Index, UU2); - NotDone = Standard_False; - } - NotDone = NotDone && (Index + 1 <= HParameters->Length()) ; - } - else { - - LocalDone = Standard_False ; - NotDone = Standard_True ; - Delta -= Delta/10; - if (Delta <= Precision::PConfusion()) break; - } - } - NbPoints = Index ; - return (LocalDone) ; -} - - -static Standard_Boolean -PerformLengthParametrized( Handle(TColStd_HArray1OfReal)& HParameters, - const TheCurve& C, - const Standard_Real Abscissa, - const Standard_Real U1, - const Standard_Real U2, - const Standard_Real TotalLength, - Standard_Integer &NbPoints, - const Standard_Real EPSILON) -{ - Standard_Boolean NotDone = Standard_True; -// Standard_Boolean LocalDone = Standard_True; - Standard_Real UU1 = Min(U1, U2); -// Standard_Real UCurrent; - Standard_Real Delta, Ui; - Standard_Real UU2 = Max(U1, U2); - Standard_Integer Index ; - -// Ratio is defined as dl = Ratio * du -// for a circle of gp Ratio is equal to the radius of the circle. -// for a line of gp ratio is equal to 1.0 - Standard_Real Ratio = GetParameterLengthRatio(C); - - - if (Abscissa < 0.0e0) { - UU2 = Min(U1, U2); - UU1 = Max(U1, U2); - } - Delta = (Abscissa/TotalLength) * (UU2 - UU1) ; - Index = 1 ; - NbPoints = 0 ; - HParameters->SetValue(Index,UU1) ; - while (NotDone) { - Index += 1 ; - Ui = HParameters->Value(Index-1) + Delta; - if (Abs(Ui-UU2) <= EPSILON) { - HParameters->SetValue(Index, UU2); - NotDone = Standard_False; - } - else if (Ui < UU2) { - HParameters->SetValue(Index, Ui); - } - else { - NotDone = Standard_False; - if (Abs(HParameters->Value(Index-1) - UU2)*Ratio/Abscissa < 0.1) { - HParameters->SetValue(Index-1, UU2); - Index -= 1; - } - else - HParameters->SetValue(Index, UU2); - } - NotDone = (Index+1 <= HParameters->Length()) && NotDone ; - } - - NbPoints = Index ; - return Standard_True ; -} - - -//======================================================================= -//function : Initialize -//purpose : -//======================================================================= - -void GCPnts_UniformAbscissa::Initialize (const TheCurve& C, - const Standard_Real Abscissa, - const Standard_Real Tol) -{ - Initialize(C, Abscissa, C.FirstParameter(), - C.LastParameter(), Tol); -} - -//======================================================================= -//function : GCPnts_UniformAbscissa -//purpose : -//======================================================================= - -GCPnts_UniformAbscissa::GCPnts_UniformAbscissa (const TheCurve& C, - const Standard_Real Abscissa, - const Standard_Real Tol) -{ - Initialize(C, Abscissa, Tol); -} - -//======================================================================= -//function : GCPnts_UniformAbscissa -//purpose : -//======================================================================= - -GCPnts_UniformAbscissa::GCPnts_UniformAbscissa (const TheCurve& C, - const Standard_Real Abscissa, - const Standard_Real U1, - const Standard_Real U2, - const Standard_Real Tol) -{ - Initialize(C, Abscissa, U1, U2, Tol); -} - -//======================================================================= -//function : GCPnts_UniformAbscissa -//purpose : -//======================================================================= - -GCPnts_UniformAbscissa::GCPnts_UniformAbscissa(const TheCurve& C, - const Standard_Integer NbPoints, - const Standard_Real Tol) -{ - Initialize(C, NbPoints, Tol); -} - -//======================================================================= -//function : GCPnts_UniformAbscissa -//purpose : -//======================================================================= - -GCPnts_UniformAbscissa::GCPnts_UniformAbscissa(const TheCurve& C, - const Standard_Integer NbPoints, - const Standard_Real U1, - const Standard_Real U2, - const Standard_Real Tol) -{ - Initialize(C, NbPoints, U1, U2, Tol); -} - -//======================================================================= -//function : Initialize -//purpose : -//======================================================================= - -void GCPnts_UniformAbscissa::Initialize(const TheCurve& C, - const Standard_Real Abscissa, - const Standard_Real U1, - const Standard_Real U2, - const Standard_Real Tol) -{ - Standard_Real L ; - myAbscissa = Abscissa; - myNbPoints = 0 ; - myDone = Standard_False; - Standard_Real EPSILON; - - if(Tol < Precision::Confusion()) - EPSILON = C.Resolution(Precision::Confusion()); - else - EPSILON = C.Resolution(Tol); - - L = GCPnts_AbscissaPoint::Length(C, U1, U2, EPSILON); - if (L <= Precision::Confusion()) { - return; - } - Standard_Integer size ; - -// -// compute the total Length here so that we can -// guess the number of points instead of letting the -// constructor of CPnts_AbscissaPoint do that and lose -// the information -// -// - -// modified by Igor Motchalov 23/04/2001 -// size = (Standard_Integer )( (L/Abs(Abscissa)) + 5 ); - Standard_Real sizeR=L/Abs(Abscissa) + 5; - if (sizeR < IntegerLast()) { - size=(Standard_Integer) sizeR; - } else { - return; - } - - if (!myParams.IsNull()) { - if (myParams->Length() < size) { - myParams.Nullify() ; - myParams = new - TColStd_HArray1OfReal(1,size) ; - } - } - else { - myParams = new - TColStd_HArray1OfReal(1,size) ; - } - -// Standard_Real EPSILON = C.Resolution(Precision::Confusion()); - GCPnts_AbscissaType Type = GetAbsType(C); - switch (Type) { - case GCPnts_LengthParametrized : - myDone = PerformLengthParametrized(myParams, - C, - Abscissa, - U1, - U2, - L, - myNbPoints, - EPSILON); - break; - case GCPnts_Parametrized: - case GCPnts_AbsComposite: - myDone = Perform(myParams, - C, - Abscissa, - U1, - U2, - L, - myNbPoints, - EPSILON); - break; - } -} - - -//======================================================================= -//function : Initialize -//purpose : -//======================================================================= - -void GCPnts_UniformAbscissa::Initialize(const TheCurve& C, - const Standard_Integer NbPoints, - const Standard_Real Tol) -{ - Initialize(C, NbPoints, C.FirstParameter(), - C.LastParameter(), Tol); -} - - -//======================================================================= -//function : Initialize -//purpose : -//======================================================================= - -void GCPnts_UniformAbscissa::Initialize(const TheCurve& C, - const Standard_Integer NbPoints, - const Standard_Real U1, - const Standard_Real U2, - const Standard_Real Tol) -{ - Standard_ConstructionError_Raise_if (NbPoints <= 1, - "GCPnts_UniformAbscissa::Initialize() - number of points should be >= 2"); - Standard_Real Abscissa ; - myNbPoints = 0 ; - myDone = Standard_False; - Standard_Real EPSILON; - - if(Tol < Precision::Confusion()) - EPSILON = C.Resolution(Precision::Confusion()); - else - EPSILON = C.Resolution(Tol); - -// -// although very similar to Initialize with Abscissa this avoid -// the computation of the total length of the curve twice -// - Standard_Real L = GCPnts_AbscissaPoint::Length(C, U1, U2, EPSILON) ; - - if (L <= Precision::Confusion()) { - return; - } - - Abscissa = - myAbscissa = L / (NbPoints - 1); - - Standard_Integer size ; - -// -// compute the total Length here so that we can -// guess the number of points instead of letting the -// constructor of CPnts_AbscissaPoint do that and lose -// the information -// -// - - size = NbPoints + 5 ; - - - if (!myParams.IsNull()) { - if (myParams->Length() < size) { - myParams.Nullify() ; - myParams = new - TColStd_HArray1OfReal(1,size) ; - } - } - else { - myParams = new - TColStd_HArray1OfReal(1,size) ; - } - - - myNbPoints = 0 ; - GCPnts_AbscissaType Type = GetAbsType(C); - switch (Type) { - case GCPnts_LengthParametrized: - myDone = PerformLengthParametrized(myParams, - C, - Abscissa, - U1, - U2, - L, - myNbPoints, - EPSILON); - break; - case GCPnts_Parametrized: - case GCPnts_AbsComposite: - myDone = Perform(myParams, - C, - Abscissa, - U1, - U2, - L, - myNbPoints, - EPSILON); - break; - } -} - - - - - -