GCPnts_AbscissaPoint.cxx
-GCPnts_AbscissaPoint.pxx
GCPnts_AbscissaPoint.hxx
GCPnts_AbscissaType.hxx
GCPnts_DeflectionType.hxx
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-
-#include <Adaptor2d_Curve2d.hxx>
-#include <Adaptor3d_Curve.hxx>
#include <GCPnts_AbscissaPoint.hxx>
+
+#include <GCPnts_AbscissaType.hxx>
+#include <GCPnts_TCurveTypes.hxx>
#include <Standard_ConstructionError.hxx>
-#include <StdFail_NotDone.hxx>
+
+//! Dimension independent used to implement GCPnts_AbscissaPoint
+//! compute the type and the length ratio if GCPnts_LengthParametrized.
+template<class TheCurve>
+static GCPnts_AbscissaType computeType (const TheCurve& theC,
+ Standard_Real& theRatio)
+{
+ if (theC.NbIntervals (GeomAbs_CN) > 1)
+ {
+ return GCPnts_AbsComposite;
+ }
+
+ switch (theC.GetType())
+ {
+ case GeomAbs_Line:
+ {
+ theRatio = 1.0;
+ return GCPnts_LengthParametrized;
+ }
+ case GeomAbs_Circle:
+ {
+ theRatio = theC.Circle().Radius();
+ return GCPnts_LengthParametrized;
+ }
+ case GeomAbs_BezierCurve:
+ {
+ Handle(typename GCPnts_TCurveTypes<TheCurve>::BezierCurve) aBz = theC.Bezier();
+ if (aBz->NbPoles() == 2
+ && !aBz->IsRational())
+ {
+ theRatio = aBz->DN (0, 1).Magnitude();
+ return GCPnts_LengthParametrized;
+ }
+ return GCPnts_Parametrized;
+ }
+ case GeomAbs_BSplineCurve:
+ {
+ Handle(typename GCPnts_TCurveTypes<TheCurve>::BSplineCurve) aBs = theC.BSpline();
+ if (aBs->NbPoles() == 2
+ && !aBs->IsRational())
+ {
+ theRatio = aBs->DN (aBs->FirstParameter(), 1).Magnitude();
+ return GCPnts_LengthParametrized;
+ }
+ return GCPnts_Parametrized;
+ }
+ default:
+ {
+ return GCPnts_Parametrized;
+ }
+ }
+}
+
+//! Compute a point at distance theAbscis from parameter theU0 using theUi as initial guess
+template<class TheCurve>
+static void Compute (CPnts_AbscissaPoint& theComputer,
+ const TheCurve& theC,
+ Standard_Real& theAbscis,
+ Standard_Real& theU0,
+ Standard_Real& theUi,
+ const Standard_Real theEPSILON)
+{
+ // test for easy solution
+ if (Abs (theAbscis) <= Precision::Confusion())
+ {
+ theComputer.SetParameter (theU0);
+ return;
+ }
+
+ Standard_Real aRatio = 1.0;
+ const GCPnts_AbscissaType aType = computeType (theC, aRatio);
+ switch (aType)
+ {
+ case GCPnts_LengthParametrized:
+ {
+ theComputer.SetParameter (theU0 + theAbscis / aRatio);
+ return;
+ }
+ case GCPnts_Parametrized:
+ {
+ theComputer.Init (theC);
+ theComputer.Perform (theAbscis, theU0, theUi, theEPSILON);
+ return;
+ }
+ case GCPnts_AbsComposite:
+ {
+ const Standard_Integer aNbIntervals = theC.NbIntervals (GeomAbs_CN);
+ TColStd_Array1OfReal aTI (1, aNbIntervals + 1);
+ theC.Intervals (aTI, GeomAbs_CN);
+ Standard_Real aL = 0.0, aSign = 1.0;
+ Standard_Integer anIndex = 1;
+ BSplCLib::Hunt (aTI, theU0, anIndex);
+ Standard_Integer aDirection = 1;
+ if (theAbscis < 0)
+ {
+ aDirection = 0;
+ theAbscis = -theAbscis;
+ aSign = -1.0;
+ }
+
+ while (anIndex >= 1
+ && anIndex <= aNbIntervals)
+ {
+ aL = CPnts_AbscissaPoint::Length (theC, theU0, aTI (anIndex + aDirection));
+ if (Abs (aL - theAbscis) <= Precision::Confusion())
+ {
+ theComputer.SetParameter (aTI (anIndex + aDirection));
+ return;
+ }
+
+ if (aL > theAbscis)
+ {
+ if (theUi < aTI (anIndex)
+ || theUi > aTI (anIndex + 1))
+ {
+ theUi = (theAbscis / aL) * (aTI (anIndex + 1) - theU0);
+ if (aDirection)
+ {
+ theUi = theU0 + theUi;
+ }
+ else
+ {
+ theUi = theU0 - theUi;
+ }
+ }
+ theComputer.Init (theC, aTI (anIndex), aTI (anIndex + 1));
+ theComputer.Perform (aSign * theAbscis, theU0, theUi, theEPSILON);
+ return;
+ }
+ else
+ {
+ theU0 = aTI (anIndex + aDirection);
+ theAbscis -= aL;
+ }
+ if (aDirection)
+ {
+ ++anIndex;
+ }
+ else
+ {
+ --anIndex;
+ }
+ }
+
+ // Push a little bit outside the limits (hairy !!!)
+ theUi = theU0 + 0.1;
+ theComputer.Init (theC, theU0, theU0 + 0.2);
+ theComputer.Perform (aSign * theAbscis, theU0, theUi, theEPSILON);
+ return;
+ }
+ break;
+ }
+}
+
+//! Introduced by rbv for curvilinear parametrization
+//! performs more appropriate tolerance management.
+template<class TheCurve>
+static void AdvCompute (CPnts_AbscissaPoint& theComputer,
+ const TheCurve& theC,
+ Standard_Real& theAbscis,
+ Standard_Real& theU0,
+ Standard_Real& theUi,
+ const Standard_Real theEPSILON)
+{
+ Standard_Real aRatio = 1.0;
+ const GCPnts_AbscissaType aType = computeType (theC, aRatio);
+ switch (aType)
+ {
+ case GCPnts_LengthParametrized:
+ {
+ theComputer.SetParameter (theU0 + theAbscis / aRatio);
+ return;
+ }
+ case GCPnts_Parametrized:
+ {
+ // theComputer.Init (theC);
+ theComputer.Init (theC, theEPSILON); //rbv's modification
+ theComputer.AdvPerform (theAbscis, theU0, theUi, theEPSILON);
+ return;
+ }
+ case GCPnts_AbsComposite:
+ {
+ const Standard_Integer aNbIntervals = theC.NbIntervals (GeomAbs_CN);
+ TColStd_Array1OfReal aTI (1, aNbIntervals + 1);
+ theC.Intervals (aTI, GeomAbs_CN);
+ Standard_Real aL = 0.0, aSign = 1.0;
+ Standard_Integer anIndex = 1;
+ BSplCLib::Hunt (aTI, theU0, anIndex);
+
+ Standard_Integer aDirection = 1;
+ if (theAbscis < 0)
+ {
+ aDirection = 0;
+ theAbscis = -theAbscis;
+ aSign = -1.0;
+ }
+
+ if (anIndex == 0 && aDirection > 0)
+ {
+ aL = CPnts_AbscissaPoint::Length (theC, theU0, aTI (anIndex + aDirection), theEPSILON);
+ if (Abs (aL - theAbscis) <= /*Precision::Confusion()*/theEPSILON)
+ {
+ theComputer.SetParameter (aTI (anIndex + aDirection));
+ return;
+ }
+
+ if (aL > theAbscis)
+ {
+ if (theUi > aTI (anIndex + 1))
+ {
+ theUi = (theAbscis / aL) * (aTI (anIndex + 1) - theU0);
+ theUi = theU0 + theUi;
+ }
+ theComputer.Init (theC, theU0, aTI (anIndex + 1), theEPSILON);
+ theComputer.AdvPerform (aSign * theAbscis, theU0, theUi, theEPSILON);
+ return;
+ }
+ else
+ {
+ theU0 = aTI (anIndex + aDirection);
+ theAbscis -= aL;
+ }
+ ++anIndex;
+ }
+
+ while (anIndex >= 1
+ && anIndex <= aNbIntervals)
+ {
+ aL = CPnts_AbscissaPoint::Length (theC, theU0, aTI (anIndex + aDirection), theEPSILON);
+ if (Abs (aL - theAbscis) <= Precision::PConfusion())
+ {
+ theComputer.SetParameter (aTI (anIndex + aDirection));
+ return;
+ }
+
+ if (aL > theAbscis)
+ {
+ if (theUi < aTI (anIndex)
+ || theUi > aTI (anIndex + 1))
+ {
+ theUi = (theAbscis / aL) * (aTI (anIndex + 1) - theU0);
+ if (aDirection)
+ {
+ theUi = theU0 + theUi;
+ }
+ else
+ {
+ theUi = theU0 - theUi;
+ }
+ }
+ theComputer.Init (theC, aTI (anIndex), aTI (anIndex + 1), theEPSILON);
+ theComputer.AdvPerform (aSign * theAbscis, theU0, theUi, theEPSILON);
+ return;
+ }
+ else
+ {
+ theU0 = aTI (anIndex + aDirection);
+ theAbscis -= aL;
+ }
+ if (aDirection)
+ {
+ ++anIndex;
+ }
+ else
+ {
+ --anIndex;
+ }
+ }
+
+ // Push a little bit outside the limits (hairy !!!)
+ const Standard_Boolean isNonPeriodic = !theC.IsPeriodic();
+ theUi = theU0 + aSign * 0.1;
+ Standard_Real aU1 = theU0 + aSign * 0.2;
+ if (isNonPeriodic)
+ {
+ if (aSign > 0)
+ {
+ theUi = Min (theUi, theC.LastParameter());
+ aU1 = Min (aU1, theC.LastParameter());
+ }
+ else
+ {
+ theUi = Max (theUi, theC.FirstParameter());
+ aU1 = Max (aU1, theC.FirstParameter());
+ }
+ }
+
+ theComputer.Init (theC, theU0, aU1, theEPSILON);
+ theComputer.AdvPerform (aSign * theAbscis, theU0, theUi, theEPSILON);
+ return;
+ }
+ break;
+ }
+}
//=======================================================================
//function : GCPnts_AbscissaPoint
-//purpose :
+//purpose :
//=======================================================================
GCPnts_AbscissaPoint::GCPnts_AbscissaPoint()
{
+ //
+}
+
+//=======================================================================
+//function : Length
+//purpose :
+//=======================================================================
+Standard_Real GCPnts_AbscissaPoint::Length (const Adaptor3d_Curve& theC)
+{
+ return GCPnts_AbscissaPoint::Length (theC, theC.FirstParameter(), theC.LastParameter());
+}
+
+//=======================================================================
+//function : Length
+//purpose :
+//=======================================================================
+Standard_Real GCPnts_AbscissaPoint::Length (const Adaptor2d_Curve2d& theC)
+{
+ return GCPnts_AbscissaPoint::Length (theC, theC.FirstParameter(), theC.LastParameter());
+}
+
+//=======================================================================
+//function : Length
+//purpose :
+//=======================================================================
+Standard_Real GCPnts_AbscissaPoint::Length (const Adaptor3d_Curve& theC,
+ const Standard_Real theTol)
+{
+ return GCPnts_AbscissaPoint::Length (theC, theC.FirstParameter(), theC.LastParameter(), theTol);
+}
+
+//=======================================================================
+//function : Length
+//purpose :
+//=======================================================================
+Standard_Real GCPnts_AbscissaPoint::Length (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theTol)
+{
+ return GCPnts_AbscissaPoint::Length (theC, theC.FirstParameter(), theC.LastParameter(), theTol);
+}
+
+//=======================================================================
+//function : Length
+//purpose :
+//=======================================================================
+Standard_Real GCPnts_AbscissaPoint::Length (const Adaptor3d_Curve& theC,
+ const Standard_Real theU1, const Standard_Real theU2)
+{
+ return length (theC, theU1, theU2, NULL);
+}
+
+//=======================================================================
+//function : Length
+//purpose :
+//=======================================================================
+Standard_Real GCPnts_AbscissaPoint::Length (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theU1, const Standard_Real theU2)
+{
+ return length (theC, theU1, theU2, NULL);
+}
+
+//=======================================================================
+//function : Length
+//purpose :
+//=======================================================================
+Standard_Real GCPnts_AbscissaPoint::Length (const Adaptor3d_Curve& theC,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const Standard_Real theTol)
+{
+ return length (theC, theU1, theU2, &theTol);
+}
+
+//=======================================================================
+//function : Length
+//purpose :
+//=======================================================================
+Standard_Real GCPnts_AbscissaPoint::Length (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const Standard_Real theTol)
+{
+ return length (theC, theU1, theU2, &theTol);
+}
+
+//=======================================================================
+//function : length
+//purpose :
+//=======================================================================
+template<class TheCurve>
+Standard_Real GCPnts_AbscissaPoint::length (const TheCurve& theC,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const Standard_Real* theTol)
+{
+ Standard_Real aRatio = 1.0;
+ const GCPnts_AbscissaType aType = computeType (theC, aRatio);
+ switch (aType)
+ {
+ case GCPnts_LengthParametrized:
+ {
+ return Abs (theU2 - theU1) * aRatio;
+ }
+ case GCPnts_Parametrized:
+ {
+ return theTol != NULL
+ ? CPnts_AbscissaPoint::Length (theC, theU1, theU2, *theTol)
+ : CPnts_AbscissaPoint::Length (theC, theU1, theU2);
+ }
+ case GCPnts_AbsComposite:
+ {
+ const Standard_Integer aNbIntervals = theC.NbIntervals (GeomAbs_CN);
+ TColStd_Array1OfReal aTI (1, aNbIntervals + 1);
+ theC.Intervals (aTI, GeomAbs_CN);
+ const Standard_Real aUU1 = Min (theU1, theU2);
+ const Standard_Real aUU2 = Max (theU1, theU2);
+ Standard_Real aL = 0.0;
+ for (Standard_Integer anIndex = 1; anIndex <= aNbIntervals; ++anIndex)
+ {
+ if (aTI (anIndex) > aUU2) { break; }
+ if (aTI (anIndex + 1) < aUU1) { continue; }
+ if (theTol != NULL)
+ {
+ aL += CPnts_AbscissaPoint::Length (theC,
+ Max (aTI (anIndex), aUU1),
+ Min (aTI (anIndex + 1), aUU2),
+ *theTol);
+ }
+ else
+ {
+ aL += CPnts_AbscissaPoint::Length (theC,
+ Max (aTI (anIndex), aUU1),
+ Min (aTI (anIndex + 1), aUU2));
+ }
+ }
+ return aL;
+ }
+ }
+ return RealLast();
+}
+
+//=======================================================================
+//function : compute
+//purpose :
+//=======================================================================
+template<class TheCurve>
+void GCPnts_AbscissaPoint::compute (const TheCurve& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0)
+{
+ const Standard_Real aL = GCPnts_AbscissaPoint::Length (theC);
+ if (aL < Precision::Confusion())
+ {
+ throw Standard_ConstructionError();
+ }
+
+ Standard_Real anAbscis = theAbscissa;
+ Standard_Real aUU0 = theU0;
+ Standard_Real aUUi = theU0 + (anAbscis / aL) * (theC.LastParameter() - theC.FirstParameter());
+ Compute (myComputer, theC, anAbscis, aUU0, aUUi,
+ theC.Resolution (Precision::Confusion()));
+}
+
+//=======================================================================
+//function : GCPnts_AbscissaPoint
+//purpose :
+//=======================================================================
+GCPnts_AbscissaPoint::GCPnts_AbscissaPoint (const Adaptor3d_Curve& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0)
+{
+ compute (theC, theAbscissa, theU0);
}
-#include <Geom_BezierCurve.hxx>
-#include <Geom_BSplineCurve.hxx>
+//=======================================================================
+//function : GCPnts_AbscissaPoint
+//purpose :
+//=======================================================================
+GCPnts_AbscissaPoint::GCPnts_AbscissaPoint (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0)
+{
+ compute (theC, theAbscissa, theU0);
+}
+
+//=======================================================================
+//function : advCompute
+//purpose :
+//=======================================================================
+template<class TheCurve>
+void GCPnts_AbscissaPoint::advCompute (const Standard_Real theTol,
+ const TheCurve& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0)
+{
+ const Standard_Real aL = GCPnts_AbscissaPoint::Length (theC, theTol);
+ /*if (aL < Precision::Confusion())
+ {
+ throw Standard_ConstructionError ("GCPnts_AbscissaPoint::GCPnts_AbscissaPoint");
+ }*/
+ Standard_Real anAbscis = theAbscissa;
+ Standard_Real aUU0 = theU0;
+ Standard_Real aUUi = 0.0;
+ if (aL >= Precision::Confusion())
+ {
+ aUUi= theU0 + (anAbscis / aL) * (theC.LastParameter() - theC.FirstParameter());
+ }
+ else
+ {
+ aUUi = theU0;
+ }
+ AdvCompute (myComputer, theC, anAbscis, aUU0, aUUi, theTol);
+}
-#define TheCurve Adaptor3d_Curve
-#define Handle_TheBezierCurve Handle(Geom_BezierCurve)
-#define Handle_TheBSplineCurve Handle(Geom_BSplineCurve)
+//=======================================================================
+//function : GCPnts_AbscissaPoint
+//purpose :
+//=======================================================================
+GCPnts_AbscissaPoint::GCPnts_AbscissaPoint (const Standard_Real theTol,
+ const Adaptor3d_Curve& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0)
+{
+ advCompute (theTol, theC, theAbscissa, theU0);
+}
-#include "GCPnts_AbscissaPoint.pxx"
+//=======================================================================
+//function : GCPnts_AbscissaPoint
+//purpose :
+//=======================================================================
+GCPnts_AbscissaPoint::GCPnts_AbscissaPoint (const Standard_Real theTol,
+ const Adaptor2d_Curve2d& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0)
+{
+ advCompute (theTol, theC, theAbscissa, theU0);
+}
-#undef TheCurve
-#undef Handle_TheBezierCurve
-#undef Handle_TheBSplineCurve
+//=======================================================================
+//function : GCPnts_AbscissaPoint
+//purpose :
+//=======================================================================
+GCPnts_AbscissaPoint::GCPnts_AbscissaPoint (const Adaptor3d_Curve& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0, const Standard_Real theUi)
+{
+ Standard_Real anAbscis = theAbscissa, aUU0 = theU0, aUUi = theUi;
+ Compute (myComputer, theC, anAbscis, aUU0, aUUi, theC.Resolution (Precision::Confusion()));
+}
-#include <Geom2d_BezierCurve.hxx>
-#include <Geom2d_BSplineCurve.hxx>
+//=======================================================================
+//function : GCPnts_AbscissaPoint
+//purpose :
+//=======================================================================
+GCPnts_AbscissaPoint::GCPnts_AbscissaPoint (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0, const Standard_Real theUi)
+{
+ Standard_Real anAbscis = theAbscissa, aUU0 = theU0, aUUi = theUi;
+ Compute (myComputer, theC, anAbscis, aUU0, aUUi, theC.Resolution (Precision::Confusion()));
+}
-#define TheCurve Adaptor2d_Curve2d
-#define Handle_TheBezierCurve Handle(Geom2d_BezierCurve)
-#define Handle_TheBSplineCurve Handle(Geom2d_BSplineCurve)
+//=======================================================================
+//function : GCPnts_AbscissaPoint
+//purpose :
+//=======================================================================
+GCPnts_AbscissaPoint::GCPnts_AbscissaPoint (const Adaptor3d_Curve& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0, const Standard_Real theUi,
+ const Standard_Real theTol)
+{
+ Standard_Real anAbscis = theAbscissa, aUU0 = theU0, aUUi = theUi;
+ AdvCompute (myComputer, theC, anAbscis, aUU0, aUUi, theTol);
+}
-#include "GCPnts_AbscissaPoint.pxx"
+//=======================================================================
+//function : GCPnts_AbscissaPoint
+//purpose :
+//=======================================================================
+GCPnts_AbscissaPoint::GCPnts_AbscissaPoint (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0, const Standard_Real theUi,
+ const Standard_Real theTol)
+{
+ Standard_Real anAbscis = theAbscissa, aUU0 = theU0, aUUi = theUi;
+ AdvCompute (myComputer, theC, anAbscis, aUU0, aUUi, theTol);
+}
#include <CPnts_AbscissaPoint.hxx>
-class StdFail_NotDone;
-class Standard_ConstructionError;
class Adaptor3d_Curve;
class Adaptor2d_Curve2d;
//! Provides an algorithm to compute a point on a curve
-//! situated at a given distance from another point on the
-//! curve, the distance being measured along the curve
-//! (curvilinear abscissa on the curve).
+//! situated at a given distance from another point on the curve,
+//! the distance being measured along the curve (curvilinear abscissa on the curve).
//! This algorithm is also used to compute the length of a curve.
//! An AbscissaPoint object provides a framework for:
//! - defining the point to compute
//! - implementing the construction algorithm
//! - consulting the result.
-class GCPnts_AbscissaPoint
+class GCPnts_AbscissaPoint
{
public:
DEFINE_STANDARD_ALLOC
+ //! Computes the length of the 3D Curve.
+ Standard_EXPORT static Standard_Real Length (const Adaptor3d_Curve& theC);
- //! Computes the length of the Curve <C>.
- Standard_EXPORT static Standard_Real Length (const Adaptor3d_Curve& C);
+ //! Computes the length of the 2D Curve.
+ Standard_EXPORT static Standard_Real Length (const Adaptor2d_Curve2d& theC);
- //! Computes the length of the Curve <C>.
- Standard_EXPORT static Standard_Real Length (const Adaptor2d_Curve2d& C);
+ //! Computes the length of the 3D Curve with the given tolerance.
+ Standard_EXPORT static Standard_Real Length (const Adaptor3d_Curve& theC,
+ const Standard_Real theTol);
- //! Computes the length of the Curve <C> with the given tolerance.
- Standard_EXPORT static Standard_Real Length (const Adaptor3d_Curve& C, const Standard_Real Tol);
+ //! Computes the length of the 2D Curve with the given tolerance.
+ Standard_EXPORT static Standard_Real Length (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theTol);
- //! Computes the length of the Curve <C> with the given tolerance.
- Standard_EXPORT static Standard_Real Length (const Adaptor2d_Curve2d& C, const Standard_Real Tol);
+ //! Computes the length of the 3D Curve.
+ Standard_EXPORT static Standard_Real Length (const Adaptor3d_Curve& theC,
+ const Standard_Real theU1, const Standard_Real theU2);
- //! Computes the length of the Curve <C>.
- Standard_EXPORT static Standard_Real Length (const Adaptor3d_Curve& C, const Standard_Real U1, const Standard_Real U2);
-
- //! Computes the length of the Curve <C>.
- Standard_EXPORT static Standard_Real Length (const Adaptor2d_Curve2d& C, const Standard_Real U1, const Standard_Real U2);
-
- //! Computes the length of the Curve <C> with the given tolerance.
- Standard_EXPORT static Standard_Real Length (const Adaptor3d_Curve& C, const Standard_Real U1, const Standard_Real U2, const Standard_Real Tol);
-
- //! Computes the length of the Curve <C> with the given tolerance.
- //! Constructs an empty algorithm. This function is used
- //! only for initializing a framework to compute the length
- //! of a curve (or a series of curves).
- //! Warning
- //! The function IsDone will return the value false after the use of this function.
- Standard_EXPORT static Standard_Real Length (const Adaptor2d_Curve2d& C, const Standard_Real U1, const Standard_Real U2, const Standard_Real Tol);
+ //! Computes the length of the 2D Curve.
+ Standard_EXPORT static Standard_Real Length (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theU1, const Standard_Real theU2);
+ //! Computes the length of the 3D Curve with the given tolerance.
+ Standard_EXPORT static Standard_Real Length (const Adaptor3d_Curve& theC,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const Standard_Real theTol);
+
+ //! Computes the length of the Curve with the given tolerance.
+ Standard_EXPORT static Standard_Real Length (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const Standard_Real theTol);
+
+public:
+
+ //! Empty constructor.
Standard_EXPORT GCPnts_AbscissaPoint();
-
- //! the algorithm computes a point on a curve <Curve> at the
- //! distance <Abscissa> from the point of parameter <U0>.
- Standard_EXPORT GCPnts_AbscissaPoint(const Adaptor3d_Curve& C, const Standard_Real Abscissa, const Standard_Real U0);
-
- //! the algorithm computes a point on a curve <Curve> at
- //! the distance <Abscissa> from the point of parameter
- //! <U0> with the given tolerance.
- Standard_EXPORT GCPnts_AbscissaPoint(const Standard_Real Tol, const Adaptor3d_Curve& C, const Standard_Real Abscissa, const Standard_Real U0);
-
- //! the algorithm computes a point on a curve <Curve> at
- //! the distance <Abscissa> from the point of parameter
- //! <U0> with the given tolerance.
- Standard_EXPORT GCPnts_AbscissaPoint(const Standard_Real Tol, const Adaptor2d_Curve2d& C, const Standard_Real Abscissa, const Standard_Real U0);
-
- //! the algorithm computes a point on a curve <Curve> at the
- //! distance <Abscissa> from the point of parameter <U0>.
- Standard_EXPORT GCPnts_AbscissaPoint(const Adaptor2d_Curve2d& C, const Standard_Real Abscissa, const Standard_Real U0);
-
- //! the algorithm computes a point on a curve <Curve> at the
- //! distance <Abscissa> from the point of parameter <U0>.
- //! <Ui> is the starting value used in the iterative process
- //! which find the solution, it must be close to the final
- //! solution
- Standard_EXPORT GCPnts_AbscissaPoint(const Adaptor3d_Curve& C, const Standard_Real Abscissa, const Standard_Real U0, const Standard_Real Ui);
-
- //! the algorithm computes a point on a curve <Curve> at the
- //! distance <Abscissa> from the point of parameter <U0>.
- //! <Ui> is the starting value used in the iterative process
- //! which find the solution, it must be closed to the final
- //! solution
- Standard_EXPORT GCPnts_AbscissaPoint(const Adaptor2d_Curve2d& C, const Standard_Real Abscissa, const Standard_Real U0, const Standard_Real Ui);
-
- //! the algorithm computes a point on a curve <Curve> at the
- //! distance <Abscissa> from the point of parameter <U0>.
- //! <Ui> is the starting value used in the iterative process
- //! which find the solution, it must be close to the final
- //! solution
- Standard_EXPORT GCPnts_AbscissaPoint(const Adaptor3d_Curve& C, const Standard_Real Abscissa, const Standard_Real U0, const Standard_Real Ui, const Standard_Real Tol);
-
- //! the algorithm computes a point on a curve <Curve> at the
- //! distance <Abscissa> from the point of parameter <U0>.
- //! <Ui> is the starting value used in the iterative process
- //! which find the solution, it must be close to the final
- //! solution
- Standard_EXPORT GCPnts_AbscissaPoint(const Adaptor2d_Curve2d& C, const Standard_Real Abscissa, const Standard_Real U0, const Standard_Real Ui, const Standard_Real Tol);
-
+
+ //! The algorithm computes a point on a curve at the
+ //! distance theAbscissa from the point of parameter theU0.
+ Standard_EXPORT GCPnts_AbscissaPoint (const Adaptor3d_Curve& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0);
+
+ //! The algorithm computes a point on a curve at
+ //! the distance theAbscissa from the point of parameter
+ //! theU0 with the given tolerance.
+ Standard_EXPORT GCPnts_AbscissaPoint (const Standard_Real theTol,
+ const Adaptor3d_Curve& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0);
+
+ //! The algorithm computes a point on a curve at
+ //! the distance theAbscissa from the point of parameter
+ //! theU0 with the given tolerance.
+ Standard_EXPORT GCPnts_AbscissaPoint (const Standard_Real theTol,
+ const Adaptor2d_Curve2d& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0);
+
+ //! The algorithm computes a point on a curve at the
+ //! distance theAbscissa from the point of parameter theU0.
+ Standard_EXPORT GCPnts_AbscissaPoint (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0);
+
+ //! The algorithm computes a point on a curve at the
+ //! distance theAbscissa from the point of parameter theU0.
+ //! theUi is the starting value used in the iterative process
+ //! which find the solution, it must be close to the final solution.
+ Standard_EXPORT GCPnts_AbscissaPoint (const Adaptor3d_Curve& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0, const Standard_Real theUi);
+
+ //! The algorithm computes a point on a curve at the
+ //! distance theAbscissa from the point of parameter theU0.
+ //! theUi is the starting value used in the iterative process
+ //! which find the solution, it must be closed to the final solution
+ Standard_EXPORT GCPnts_AbscissaPoint (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0, const Standard_Real theUi);
+
+ //! The algorithm computes a point on a curve at the
+ //! distance theAbscissa from the point of parameter theU0.
+ //! theUi is the starting value used in the iterative process
+ //! which find the solution, it must be close to the final solution
+ Standard_EXPORT GCPnts_AbscissaPoint (const Adaptor3d_Curve& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0, const Standard_Real theUi,
+ const Standard_Real theTol);
+
+ //! The algorithm computes a point on a curve at the
+ //! distance theAbscissa from the point of parameter theU0.
+ //! theUi is the starting value used in the iterative process
+ //! which find the solution, it must be close to the final solution
+ Standard_EXPORT GCPnts_AbscissaPoint (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0, const Standard_Real theUi,
+ const Standard_Real theTol);
+
//! True if the computation was successful, False otherwise.
//! IsDone is a protection against:
//! - non-convergence of the algorithm
return myComputer.Parameter ();
}
+private:
+
+ //! Computes the length of the Curve with the optional tolerance.
+ template<class TheCurve>
+ static Standard_Real length (const TheCurve& theC,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const Standard_Real* theTol);
+
+ //! Performs algorithm from the point of parameter.
+ template<class TheCurve>
+ void compute (const TheCurve& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0);
+
+ //! Performs algorithm from the point of parameter with the given tolerance.
+ template<class TheCurve>
+ void advCompute (const Standard_Real theTol,
+ const TheCurve& theC,
+ const Standard_Real theAbscissa,
+ const Standard_Real theU0);
+
private:
CPnts_AbscissaPoint myComputer;
};
+++ /dev/null
-// Created on: 1995-05-05
-// Created by: Modelistation
-// 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.
-
-// Dimension independent used to implement GCPnts_AbscissaPoint
-
-// compute the type
-// and the length ratio if GCPnts_LengthParametrized
-#include <GCPnts_AbscissaType.hxx>
-#include <gp_Vec.hxx>
-#include <gp_Vec2d.hxx>
-#include <gp_Circ.hxx>
-#include <gp_Circ2d.hxx>
-#include <Precision.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <BSplCLib.hxx>
-
-static GCPnts_AbscissaType computeType( const TheCurve& C,
- Standard_Real& Ratio)
-{
- GCPnts_AbscissaType LocalType ;
-
- if (C.NbIntervals(GeomAbs_CN) > 1)
- return GCPnts_AbsComposite;
-
- switch (C.GetType()) {
-
- case GeomAbs_Line:
- Ratio = 1.0e0 ;
- return GCPnts_LengthParametrized;
-
- case GeomAbs_Circle:
- Ratio = C.Circle().Radius();
- return GCPnts_LengthParametrized;
-
- case GeomAbs_BezierCurve:
- {
- Handle_TheBezierCurve Bz = C.Bezier();
- if ((Bz->NbPoles() == 2) && !(Bz->IsRational())) {
- Ratio = Bz->DN(0,1).Magnitude();
- LocalType = GCPnts_LengthParametrized;
- }
- else
- LocalType = GCPnts_Parametrized;
- return LocalType ;
- }
- case GeomAbs_BSplineCurve:
- {
- Handle_TheBSplineCurve Bs = C.BSpline();
- if ((Bs->NbPoles() == 2) && !(Bs->IsRational())) {
- Ratio = Bs->DN(Bs->FirstParameter(),1).Magnitude();
- LocalType = GCPnts_LengthParametrized;
- }
- else
- LocalType = GCPnts_Parametrized;
- return LocalType ;
- }
- default:
- return GCPnts_Parametrized;
-
- }
-}
-
-// compute a point at distance Abscis from parameter U0
-// using Ui as initial guess
-
-static void Compute(CPnts_AbscissaPoint& theComputer,
- const TheCurve& C,
- Standard_Real& Abscis,
- Standard_Real& U0,
- Standard_Real& Ui,
- const Standard_Real EPSILON)
-{
- // test for easy solution
- if (Abs(Abscis) <= Precision::Confusion()) {
- theComputer.SetParameter(U0);
- return;
- }
-
- Standard_Real Ratio = 1.;
- GCPnts_AbscissaType Type = computeType(C,Ratio);
-
- switch (Type) {
- case GCPnts_LengthParametrized :
- theComputer.SetParameter(U0 + Abscis / Ratio);
- return;
-
- case GCPnts_Parametrized :
- theComputer.Init(C);
- theComputer.Perform(Abscis, U0, Ui, EPSILON);
- return;
-
- case GCPnts_AbsComposite :
- {
- Standard_Integer NbIntervals = C.NbIntervals(GeomAbs_CN);
- TColStd_Array1OfReal TI(1,NbIntervals+1);
- C.Intervals(TI,GeomAbs_CN);
- Standard_Real L = 0.0, sign = 1.;
- Standard_Integer Index = 1;
- BSplCLib::Hunt(TI,U0,Index);
- Standard_Integer Direction = 1;
- if (Abscis < 0) {
- Direction = 0;
- Abscis = -Abscis;
- sign = -1.;
- }
-
- while ((Index >= 1) && (Index <= NbIntervals)) {
-
- L = CPnts_AbscissaPoint::Length(C, U0, TI(Index+Direction));
- if (Abs(L - Abscis) <= Precision::Confusion()) {
- theComputer.SetParameter(TI(Index+Direction));
- return;
- }
- if(L > Abscis) {
- if ((Ui < TI(Index)) || (Ui > TI(Index+1))) {
- Ui = (Abscis / L) * (TI(Index+1) - U0);
- if (Direction)
- Ui = U0 + Ui;
- else
- Ui = U0 - Ui;
- }
- theComputer.Init(C,TI(Index),TI(Index+1));
- theComputer.Perform(sign*Abscis, U0, Ui, EPSILON);
- return;
- }
- else {
- U0 = TI(Index+Direction);
- Abscis -= L;
- }
- if (Direction)
- Index++;
- else
- Index--;
- }
-
- // Push a little bit outside the limits (hairy !!!)
- Ui = U0 + 0.1;
- theComputer.Init(C,U0,U0+0.2);
- theComputer.Perform(sign*Abscis, U0, Ui, EPSILON);
- return;
- }
- break;
- }
-
-}
-
-// introduced by rbv for curvilinear parametrization
-// performs more appropriate tolerance management
-
-static void AdvCompute(CPnts_AbscissaPoint& theComputer,
- const TheCurve& C,
- Standard_Real& Abscis,
- Standard_Real& U0,
- Standard_Real& Ui,
- const Standard_Real EPSILON)
-{
- Standard_Real Ratio = 1.0;
- GCPnts_AbscissaType Type = computeType(C,Ratio);
-
- switch (Type) {
- case GCPnts_LengthParametrized :
- theComputer.SetParameter(U0 + Abscis / Ratio);
- return;
-
- case GCPnts_Parametrized :
-// theComputer.Init(C);
- theComputer.Init(C, EPSILON); //rbv's modification
-//
- theComputer.AdvPerform(Abscis, U0, Ui, EPSILON);
- return;
-
- case GCPnts_AbsComposite :
- {
- Standard_Integer NbIntervals = C.NbIntervals(GeomAbs_CN);
- TColStd_Array1OfReal TI(1,NbIntervals+1);
- C.Intervals(TI,GeomAbs_CN);
- Standard_Real L = 0.0, sign = 1.;
- Standard_Integer Index = 1;
- BSplCLib::Hunt(TI,U0,Index);
-
- Standard_Integer Direction = 1;
- if (Abscis < 0) {
- Direction = 0;
- Abscis = -Abscis;
- sign = -1.;
- }
-
- if(Index == 0 && Direction > 0) {
- L = CPnts_AbscissaPoint::Length(C, U0, TI(Index+Direction), EPSILON);
- if (Abs(L - Abscis) <= /*Precision::Confusion()*/EPSILON) {
- theComputer.SetParameter(TI(Index+Direction));
- return;
- }
- if(L > Abscis) {
- if ( Ui > TI(Index+1) ) {
- Ui = (Abscis / L) * (TI(Index+1) - U0);
- Ui = U0 + Ui;
- }
- theComputer.Init(C,U0,TI(Index+1), EPSILON);
- theComputer.AdvPerform(sign*Abscis, U0, Ui, EPSILON);
- return;
- }
- else {
- U0 = TI(Index+Direction);
- Abscis -= L;
- }
- Index++;
- }
-
-
- while ((Index >= 1) && (Index <= NbIntervals)) {
-
- L = CPnts_AbscissaPoint::Length(C, U0, TI(Index+Direction), EPSILON);
- if (Abs(L - Abscis) <= Precision::PConfusion()) {
- theComputer.SetParameter(TI(Index+Direction));
- return;
- }
- if(L > Abscis) {
- if ((Ui < TI(Index)) || (Ui > TI(Index+1))) {
- Ui = (Abscis / L) * (TI(Index+1) - U0);
- if (Direction)
- Ui = U0 + Ui;
- else
- Ui = U0 - Ui;
- }
- theComputer.Init(C,TI(Index),TI(Index+1), EPSILON);
- theComputer.AdvPerform(sign*Abscis, U0, Ui, EPSILON);
- return;
- }
- else {
- U0 = TI(Index+Direction);
- Abscis -= L;
- }
- if (Direction) {
- Index++;
-
- }
- else {
- Index--;
-
- }
- }
-
- // Push a little bit outside the limits (hairy !!!)
-
- Standard_Boolean nonperiodic = !C.IsPeriodic();
- Ui = U0 + sign*0.1;
- Standard_Real U1 = U0 + sign*.2;
- if(nonperiodic) {
- if(sign > 0) {
- Ui = Min(Ui,C.LastParameter());
- U1 = Min(U1, C.LastParameter());
- }
- else {
- Ui = Max(Ui,C.FirstParameter());
- U1 = Max(U1, C.FirstParameter());
- }
- }
-
- theComputer.Init(C, U0, U1, EPSILON);
- theComputer.AdvPerform(sign*Abscis, U0, Ui, EPSILON);
- return;
- }
- break;
- }
-
-}
-
-//=======================================================================
-//function : Length
-//purpose :
-//=======================================================================
-
-Standard_Real GCPnts_AbscissaPoint::Length(const TheCurve& C)
-{
- return GCPnts_AbscissaPoint::Length(C,C.FirstParameter(),
- C.LastParameter());
-}
-
-//=======================================================================
-//function : Length
-//purpose :
-//=======================================================================
-
-Standard_Real GCPnts_AbscissaPoint::Length(const TheCurve& C,
- const Standard_Real Tol)
-{
- return GCPnts_AbscissaPoint::Length(C,C.FirstParameter(),
- C.LastParameter(),Tol);
-}
-
-
-//=======================================================================
-//function : Length
-//purpose :
-//=======================================================================
-
-Standard_Real GCPnts_AbscissaPoint::Length(const TheCurve& C,
- const Standard_Real U1,
- const Standard_Real U2)
-{
- Standard_Real Ratio = 1.0;
- GCPnts_AbscissaType Type = computeType(C,Ratio);
- switch (Type) {
-
- case GCPnts_LengthParametrized:
- return Abs(U2-U1) * Ratio;
-
- case GCPnts_Parametrized:
- return CPnts_AbscissaPoint::Length(C, U1, U2);
-
- case GCPnts_AbsComposite:
- {
- Standard_Integer NbIntervals = C.NbIntervals(GeomAbs_CN);
- TColStd_Array1OfReal TI(1,NbIntervals+1);
- C.Intervals(TI,GeomAbs_CN);
- Standard_Real UU1 = Min(U1, U2);
- Standard_Real UU2 = Max(U1, U2);
- Standard_Real L = 0.0;
- for(Standard_Integer Index = 1; Index <= NbIntervals; Index++) {
- if (TI(Index) > UU2) break;
- if (TI(Index+1) < UU1) continue;
- L += CPnts_AbscissaPoint::Length(C,
- Max(TI(Index),UU1),
- Min(TI(Index+1),UU2));
- }
- return L;
- }
- }
- return RealLast();
-}
-
-//=======================================================================
-//function : Length
-//purpose :
-//=======================================================================
-
-Standard_Real GCPnts_AbscissaPoint::Length(const TheCurve& C,
- const Standard_Real U1,
- const Standard_Real U2,
- const Standard_Real Tol)
-{
- Standard_Real Ratio = 1.0;
- GCPnts_AbscissaType Type = computeType(C,Ratio);
- switch (Type) {
-
- case GCPnts_LengthParametrized:
- return Abs(U2-U1) * Ratio;
-
- case GCPnts_Parametrized:
- return CPnts_AbscissaPoint::Length(C, U1, U2, Tol);
-
- case GCPnts_AbsComposite:
- {
- Standard_Integer NbIntervals = C.NbIntervals(GeomAbs_CN);
- TColStd_Array1OfReal TI(1,NbIntervals+1);
- C.Intervals(TI,GeomAbs_CN);
- Standard_Real UU1 = Min(U1, U2);
- Standard_Real UU2 = Max(U1, U2);
- Standard_Real L = 0.0;
- for(Standard_Integer Index = 1; Index <= NbIntervals; Index++) {
- if (TI(Index) > UU2) break;
- if (TI(Index+1) < UU1) continue;
- L += CPnts_AbscissaPoint::Length(C,
- Max(TI(Index),UU1),
- Min(TI(Index+1),UU2),
- Tol);
- }
- return L;
- }
- }
- return RealLast();
-}
-
-
-//=======================================================================
-//function : GCPnts_AbscissaPoint
-//purpose :
-//=======================================================================
-
-GCPnts_AbscissaPoint::GCPnts_AbscissaPoint
- (const TheCurve& C,
- const Standard_Real Abscissa,
- const Standard_Real U0)
-{
- Standard_Real L = GCPnts_AbscissaPoint::Length(C);
- if (L < Precision::Confusion()) {
- throw Standard_ConstructionError();
- }
- Standard_Real Abscis = Abscissa;
- Standard_Real UU0 = U0;
- Standard_Real UUi = U0 +
- (Abscis / L) * (C.LastParameter() - C.FirstParameter());
- Compute(myComputer, C, Abscis, UU0, UUi,
- C.Resolution(Precision::Confusion()));
-}
-
-//=======================================================================
-//function : GCPnts_AbscissaPoint
-//purpose : rbv for curvilinear parametrization
-//=======================================================================
-
-GCPnts_AbscissaPoint::GCPnts_AbscissaPoint
- (const Standard_Real Tol,
- const TheCurve& C,
- const Standard_Real Abscissa,
- const Standard_Real U0)
-{
- Standard_Real L = GCPnts_AbscissaPoint::Length(C, Tol);
-/* if (L < Precision::Confusion()) {
- cout<<"FirstParameter = "<<C.FirstParameter()<<endl;
- cout<<"LastParameter = "<<C.LastParameter()<<endl;
- throw Standard_ConstructionError("GCPnts_AbscissaPoint::GCPnts_AbscissaPoint");
- }
-*/
- Standard_Real Abscis = Abscissa;
- Standard_Real UU0 = U0;
- Standard_Real UUi;
- if (L >= Precision::Confusion())
- UUi= U0 +
- (Abscis / L) * (C.LastParameter() - C.FirstParameter());
- else UUi = U0;
-
- AdvCompute(myComputer, C, Abscis, UU0, UUi, Tol);
-}
-
-//=======================================================================
-//function : GCPnts_AbscissaPoint
-//purpose :
-//=======================================================================
-
-GCPnts_AbscissaPoint::GCPnts_AbscissaPoint
- (const TheCurve& C,
- const Standard_Real Abscissa,
- const Standard_Real U0,
- const Standard_Real Ui)
-{
- Standard_Real Abscis = Abscissa;
- Standard_Real UU0 = U0;
- Standard_Real UUi = Ui;
- Compute(myComputer, C, Abscis, UU0, UUi,
- C.Resolution(Precision::Confusion()));
-}
-
-//=======================================================================
-//function : GCPnts_AbscissaPoint
-//purpose : rbv for curvilinear parametrization
-//=======================================================================
-
-GCPnts_AbscissaPoint::GCPnts_AbscissaPoint
- (const TheCurve& C,
- const Standard_Real Abscissa,
- const Standard_Real U0,
- const Standard_Real Ui,
- const Standard_Real Tol)
-{
- Standard_Real Abscis = Abscissa;
- Standard_Real UU0 = U0;
- Standard_Real UUi = Ui;
- AdvCompute(myComputer, C, Abscis, UU0, UUi, Tol);
-}