GCPnts_QuasiUniformAbscissa.cxx
GCPnts_QuasiUniformAbscissa.hxx
GCPnts_QuasiUniformDeflection.cxx
-GCPnts_QuasiUniformDeflection.pxx
GCPnts_QuasiUniformDeflection.hxx
GCPnts_TangentialDeflection.cxx
GCPnts_TangentialDeflection.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_QuasiUniformDeflection.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Pnt2d.hxx>
+
+#include <GCPnts_DeflectionType.hxx>
+#include <GCPnts_TCurveTypes.hxx>
#include <gp_Vec.hxx>
#include <gp_Vec2d.hxx>
-#include <Standard_ConstructionError.hxx>
-#include <Standard_DomainError.hxx>
-#include <Standard_NotImplemented.hxx>
-#include <Standard_OutOfRange.hxx>
#include <StdFail_NotDone.hxx>
static const Standard_Integer MyMaxQuasiFleshe = 2000;
// mask the return of a Adaptor2d_Curve2d as a gp_Pnt
-static gp_Pnt Value(const Adaptor3d_Curve & C,
- const Standard_Real Parameter)
+static gp_Pnt Value (const Adaptor3d_Curve& theC,
+ const Standard_Real theParameter)
{
- return C.Value(Parameter) ;
+ return theC.Value (theParameter);
}
-static gp_Pnt Value(const Adaptor2d_Curve2d & C,
- const Standard_Real Parameter)
+
+static gp_Pnt Value (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theParameter)
{
- gp_Pnt aPoint ;
- gp_Pnt2d a2dPoint(C.Value(Parameter));
- aPoint.SetCoord(a2dPoint.X(),a2dPoint.Y(),0.);
- return aPoint ;
+ gp_Pnt aPoint;
+ gp_Pnt2d a2dPoint (theC.Value (theParameter));
+ aPoint.SetCoord (a2dPoint.X(), a2dPoint.Y(), 0.0);
+ return aPoint;
}
-static void D1(const Adaptor3d_Curve & C,
- const Standard_Real Parameter,
- gp_Pnt& P,
- gp_Vec& V)
+static void D1 (const Adaptor3d_Curve& theC,
+ const Standard_Real theParameter,
+ gp_Pnt& theP,
+ gp_Vec& theV)
{
- C.D1(Parameter,P,V);
+ theC.D1 (theParameter, theP, theV);
}
-static void D1(const Adaptor2d_Curve2d & C,
- const Standard_Real Parameter,
- gp_Pnt& P,
- gp_Vec& V)
+static void D1 (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theParameter,
+ gp_Pnt& theP,
+ gp_Vec& theV)
{
gp_Pnt2d a2dPoint;
gp_Vec2d a2dVec;
- C.D1(Parameter,a2dPoint,a2dVec);
- P.SetCoord(a2dPoint.X(),a2dPoint.Y(),0.);
- V.SetCoord(a2dVec.X(),a2dVec.Y(),0.);
+ theC.D1 (theParameter, a2dPoint, a2dVec);
+ theP.SetCoord (a2dPoint.X(), a2dPoint.Y(), 0.0);
+ theV.SetCoord (a2dVec.X(), a2dVec.Y(), 0.0);
}
+//=======================================================================
+//function : QuasiFleche
+//purpose :
+//=======================================================================
+template<class TheCurve>
+static void QuasiFleche (const TheCurve& theC,
+ const Standard_Real theDeflection2,
+ const Standard_Real theUdeb,
+ const gp_Pnt& thePdeb,
+ const gp_Vec& theVdeb,
+ const Standard_Real theUfin,
+ const gp_Pnt& thePfin,
+ const gp_Vec& theVfin,
+ const Standard_Integer theNbmin,
+ const Standard_Real theEps,
+ TColStd_SequenceOfReal& theParameters,
+ TColgp_SequenceOfPnt& thePoints,
+ Standard_Integer& theNbCalls)
+{
+ ++theNbCalls;
+ if (theNbCalls >= MyMaxQuasiFleshe)
+ {
+ return;
+ }
+
+ const Standard_Integer aPtslength = thePoints.Length();
+ if (theNbCalls > 100 && aPtslength < 2)
+ {
+ return;
+ }
+
+ Standard_Real aUdelta = theUfin - theUdeb;
+ gp_Pnt aPdelta;
+ gp_Vec aVdelta;
+ if (theNbmin > 2)
+ {
+ aUdelta /= (theNbmin - 1);
+ D1 (theC, theUdeb + aUdelta, aPdelta, aVdelta);
+ }
+ else
+ {
+ aPdelta = thePfin;
+ aVdelta = theVfin;
+ }
+
+ const Standard_Real aNorme = gp_Vec (thePdeb, aPdelta).SquareMagnitude();
+ Standard_Real aFleche = 0.0;
+ Standard_Boolean isFlecheOk = Standard_False;
+ if (aNorme > theEps)
+ {
+ // Evaluation de la fleche par interpolation . Voir IntWalk_IWalking_5.gxx
+ Standard_Real N1 = theVdeb.SquareMagnitude();
+ Standard_Real N2 = aVdelta.SquareMagnitude();
+ if (N1 > theEps && N2 > theEps)
+ {
+ Standard_Real aNormediff = (theVdeb.Normalized().XYZ() - aVdelta.Normalized().XYZ()).SquareModulus();
+ if (aNormediff > theEps)
+ {
+ aFleche = aNormediff * aNorme / 64.0;
+ isFlecheOk = Standard_True;
+ }
+ }
+ }
+ if (!isFlecheOk)
+ {
+ gp_Pnt aPmid ((thePdeb.XYZ() + aPdelta.XYZ()) * 0.5);
+ gp_Pnt aPverif (Value (theC, theUdeb + aUdelta * 0.5));
+ aFleche = aPmid.SquareDistance (aPverif);
+ }
+
+ if (aFleche < theDeflection2)
+ {
+ theParameters.Append (theUdeb + aUdelta);
+ thePoints.Append (aPdelta);
+ }
+ else
+ {
+ QuasiFleche (theC, theDeflection2, theUdeb, thePdeb,
+ theVdeb,
+ theUdeb + aUdelta, aPdelta,
+ aVdelta,
+ 3,
+ theEps,
+ theParameters, thePoints, theNbCalls);
+ }
+
+ if (theNbmin > 2)
+ {
+ QuasiFleche (theC, theDeflection2, theUdeb + aUdelta, aPdelta,
+ aVdelta,
+ theUfin, thePfin,
+ theVfin,
+ theNbmin - (thePoints.Length() - aPtslength),
+ theEps,
+ theParameters, thePoints, theNbCalls);
+ }
+ --theNbCalls;
+}
//=======================================================================
-//function : Value
-//purpose :
+//function : QuasiFleche
+//purpose :
//=======================================================================
+template<class TheCurve>
+static void QuasiFleche (const TheCurve& theC,
+ const Standard_Real theDeflection2,
+ const Standard_Real theUdeb,
+ const gp_Pnt& thePdeb,
+ const Standard_Real theUfin,
+ const gp_Pnt& thePfin,
+ const Standard_Integer theNbmin,
+ TColStd_SequenceOfReal& theParameters,
+ TColgp_SequenceOfPnt& thePoints,
+ Standard_Integer& theNbCalls)
+{
+ ++theNbCalls;
+ if (theNbCalls >= MyMaxQuasiFleshe)
+ {
+ return;
+ }
+ const Standard_Integer aPtslength = thePoints.Length();
+ if (theNbCalls > 100 && aPtslength < 2)
+ {
+ return;
+ }
+
+ Standard_Real aUdelta = theUfin - theUdeb;
+ gp_Pnt aPdelta;
+ if (theNbmin > 2)
+ {
+ aUdelta /= (theNbmin - 1);
+ aPdelta = Value (theC, theUdeb + aUdelta);
+ }
+ else
+ {
+ aPdelta = thePfin;
+ }
+
+ const gp_Pnt aPmid ((thePdeb.XYZ() + aPdelta.XYZ()) * 0.5);
+ const gp_Pnt aPverif (Value (theC, theUdeb + aUdelta * 0.5));
+ const Standard_Real aFleche = aPmid.SquareDistance (aPverif);
+ if (aFleche < theDeflection2)
+ {
+ theParameters.Append (theUdeb + aUdelta);
+ thePoints.Append (aPdelta);
+ }
+ else
+ {
+ QuasiFleche (theC, theDeflection2, theUdeb, thePdeb,
+ theUdeb + aUdelta * 0.5, aPverif,
+ 2,
+ theParameters, thePoints, theNbCalls);
-gp_Pnt GCPnts_QuasiUniformDeflection::Value
- (const Standard_Integer Index) const
-{
- StdFail_NotDone_Raise_if(!myDone,
- "GCPnts_QuasiUniformAbscissa::Parameter()");
- return myPoints.Value(Index) ;
+ QuasiFleche (theC, theDeflection2, theUdeb + aUdelta * 0.5, aPverif,
+ theUdeb + aUdelta, aPdelta,
+ 2,
+ theParameters, thePoints, theNbCalls);
+ }
+
+ if (theNbmin > 2)
+ {
+ QuasiFleche (theC, theDeflection2, theUdeb + aUdelta, aPdelta,
+ theUfin, thePfin,
+ theNbmin - (thePoints.Length() - aPtslength),
+ theParameters, thePoints, theNbCalls);
+ }
+ --theNbCalls;
}
+
+
//=======================================================================
-//function : GCPnts_QuasiUniformDeflection
-//purpose :
+//function : PerformLinear
+//purpose :
+//=======================================================================
+template<class TheCurve>
+static Standard_Boolean PerformLinear (const TheCurve& theC,
+ TColStd_SequenceOfReal& theParameters,
+ TColgp_SequenceOfPnt& thePoints,
+ const Standard_Real theU1,
+ const Standard_Real theU2)
+{
+ theParameters.Append (theU1);
+ gp_Pnt aPoint = Value (theC, theU1);
+ thePoints.Append (aPoint);
+
+ theParameters.Append (theU2);
+ aPoint = Value (theC, theU2);
+ thePoints.Append (aPoint);
+ return Standard_True;
+}
+
//=======================================================================
+//function : PerformCircular
+//purpose :
+//=======================================================================
+template<class TheCurve>
+static Standard_Boolean PerformCircular (const TheCurve& theC,
+ TColStd_SequenceOfReal& theParameters,
+ TColgp_SequenceOfPnt& thePoints,
+ const Standard_Real theDeflection,
+ const Standard_Real theU1,
+ const Standard_Real theU2)
+{
+ Standard_Real anAngle = Max (1.0 - (theDeflection / theC.Circle().Radius()), 0.0);
+ anAngle = 2.0 * ACos (anAngle);
+ Standard_Integer aNbPoints = (Standard_Integer )((theU2 - theU1) / anAngle);
+ aNbPoints += 2;
+ anAngle = (theU2 - theU1) / (Standard_Real) (aNbPoints - 1);
+ Standard_Real U = theU1;
+ for (Standard_Integer i = 1; i <= aNbPoints; ++i)
+ {
+ theParameters.Append (U);
+ const gp_Pnt aPoint = Value (theC, U);
+ thePoints.Append (aPoint);
+ U += anAngle;
+ }
+ return Standard_True;
+}
-GCPnts_QuasiUniformDeflection::GCPnts_QuasiUniformDeflection ()
-: myDone(Standard_False),
- myDeflection(0.0),
- myCont(GeomAbs_C1)
+//=======================================================================
+//function : GetDefType
+//purpose :
+//=======================================================================
+template<class TheCurve>
+static GCPnts_DeflectionType GetDefType (const TheCurve& theC)
{
-}
+ if (theC.NbIntervals (GeomAbs_C1) > 1)
+ {
+ return GCPnts_DefComposite;
+ }
-#include <Geom_BezierCurve.hxx>
-#include <Geom_BSplineCurve.hxx>
+ // pour forcer les decoupages aux cassures.
+ // G1 devrait marcher, mais donne des exceptions...
+ switch (theC.GetType())
+ {
+ case GeomAbs_Line: return GCPnts_Linear;
+ case GeomAbs_Circle: return GCPnts_Circular;
+ case GeomAbs_BSplineCurve:
+ {
+ Handle(typename GCPnts_TCurveTypes<TheCurve>::BSplineCurve) aBS = theC.BSpline();
+ return (aBS->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved;
+ }
+ case GeomAbs_BezierCurve:
+ {
+ Handle(typename GCPnts_TCurveTypes<TheCurve>::BezierCurve) aBZ = theC.Bezier();
+ return (aBZ->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved;
+ }
+ default: return GCPnts_Curved;
+ }
+}
-#define TheCurve Adaptor3d_Curve
-#define Handle_TheBezierCurve Handle(Geom_BezierCurve)
-#define Handle_TheBSplineCurve Handle(Geom_BSplineCurve)
+//=======================================================================
+//function : PerformCurve
+//purpose :
+//=======================================================================
+template<class TheCurve>
+static Standard_Boolean PerformCurve (TColStd_SequenceOfReal& theParameters,
+ TColgp_SequenceOfPnt& thePoints,
+ const TheCurve& theC,
+ const Standard_Real theDeflection,
+ const Standard_Real theU1,
+ const Standard_Real theU2,
+ const Standard_Real theEPSILON,
+ const GeomAbs_Shape theContinuity)
+{
+ Standard_Integer aNbmin = 2;
+ Standard_Integer aNbCallQF = 0;
-#include "GCPnts_QuasiUniformDeflection.pxx"
+ gp_Pnt aPdeb;
+ if (theContinuity <= GeomAbs_G1)
+ {
+ aPdeb = Value (theC, theU1);
+ theParameters.Append (theU1);
+ thePoints.Append (aPdeb);
-#undef TheCurve
-#undef Handle_TheBezierCurve
-#undef Handle_TheBSplineCurve
+ gp_Pnt aPfin (Value (theC, theU2));
+ QuasiFleche (theC, theDeflection * theDeflection,
+ theU1, aPdeb,
+ theU2, aPfin,
+ aNbmin,
+ theParameters, thePoints, aNbCallQF);
+ }
+ else
+ {
+ gp_Pnt aPfin;
+ gp_Vec aDdeb, aDfin;
+ D1 (theC, theU1, aPdeb, aDdeb);
+ theParameters.Append (theU1);
+ thePoints.Append (aPdeb);
-#include <Geom2d_BezierCurve.hxx>
-#include <Geom2d_BSplineCurve.hxx>
+ const Standard_Real aDecreasedU2 = theU2 - Epsilon (theU2) * 10.0;
+ D1 (theC, aDecreasedU2, aPfin, aDfin);
+ QuasiFleche (theC, theDeflection * theDeflection,
+ theU1, aPdeb,
+ aDdeb,
+ theU2, aPfin,
+ aDfin,
+ aNbmin,
+ theEPSILON * theEPSILON,
+ theParameters, thePoints, aNbCallQF);
+ }
+ // cout << "Nb de pts: " << Points.Length()<< endl;
+ return Standard_True;
+}
-#define TheCurve Adaptor2d_Curve2d
-#define Handle_TheBezierCurve Handle(Geom2d_BezierCurve)
-#define Handle_TheBSplineCurve Handle(Geom2d_BSplineCurve)
+//=======================================================================
+//function : PerformComposite
+//purpose :
+//=======================================================================
+template<class TheCurve>
+static Standard_Boolean PerformComposite (TColStd_SequenceOfReal& theParameters,
+ TColgp_SequenceOfPnt& thePoints,
+ const TheCurve& theC,
+ const Standard_Real theDeflection,
+ const Standard_Real theU1,
+ const Standard_Real theU2,
+ const Standard_Real theEPSILON,
+ const GeomAbs_Shape theContinuity)
+{
+ //
+ // coherence avec Intervals
+ //
+ const Standard_Integer aNbIntervals = theC.NbIntervals (GeomAbs_C2);
+ Standard_Integer aPIndex = 0;
+ TColStd_Array1OfReal aTI (1, aNbIntervals + 1);
+ theC.Intervals (aTI, GeomAbs_C2);
+ BSplCLib::Hunt (aTI, theU1, aPIndex);
-#include "GCPnts_QuasiUniformDeflection.pxx"
+ // iterate by continuous segments
+ Standard_Real aUa = theU1;
+ for (Standard_Integer anIndex = aPIndex;;)
+ {
+ Standard_Real aUb = anIndex + 1 <= aTI.Upper()
+ ? Min (theU2, aTI (anIndex + 1))
+ : theU2;
+ if (!PerformCurve (theParameters, thePoints, theC, theDeflection,
+ aUa, aUb, theEPSILON, theContinuity))
+ {
+ return Standard_False;
+ }
+ ++anIndex;
+ if (anIndex > aNbIntervals || theU2 < aTI (anIndex))
+ {
+ return Standard_True;
+ }
+ // remove last point to avoid duplication
+ theParameters.Remove (theParameters.Length());
+ thePoints.Remove (thePoints.Length());
+ aUa = aUb;
+ }
+}
+//=======================================================================
+//function : Value
+//purpose :
+//=======================================================================
+gp_Pnt GCPnts_QuasiUniformDeflection::Value (const Standard_Integer theIndex) const
+{
+ StdFail_NotDone_Raise_if(!myDone, "GCPnts_QuasiUniformAbscissa::Parameter()");
+ return myPoints.Value (theIndex);
+}
+//=======================================================================
+//function : GCPnts_QuasiUniformDeflection
+//purpose :
+//=======================================================================
+GCPnts_QuasiUniformDeflection::GCPnts_QuasiUniformDeflection()
+: myDone (Standard_False),
+ myDeflection (0.0),
+ myCont (GeomAbs_C1)
+{
+ //
+}
+//=======================================================================
+//function : GCPnts_QuasiUniformDeflection
+//purpose :
+//=======================================================================
+GCPnts_QuasiUniformDeflection::GCPnts_QuasiUniformDeflection (const Adaptor3d_Curve& theC,
+ const Standard_Real theDeflection,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const GeomAbs_Shape theContinuity)
+: myDone (Standard_False),
+ myDeflection (theDeflection),
+ myCont (GeomAbs_C1)
+{
+ Initialize (theC, theDeflection, theU1, theU2, theContinuity);
+}
+
+//=======================================================================
+//function : GCPnts_QuasiUniformDeflection
+//purpose :
+//=======================================================================
+GCPnts_QuasiUniformDeflection::GCPnts_QuasiUniformDeflection (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theDeflection,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const GeomAbs_Shape theContinuity)
+: myDone (Standard_False),
+ myDeflection (theDeflection),
+ myCont (GeomAbs_C1)
+{
+ Initialize (theC, theDeflection, theU1, theU2, theContinuity);
+}
+
+//=======================================================================
+//function : GCPnts_QuasiUniformDeflection
+//purpose :
+//=======================================================================
+GCPnts_QuasiUniformDeflection::GCPnts_QuasiUniformDeflection (const Adaptor3d_Curve& theC,
+ const Standard_Real theDeflection,
+ const GeomAbs_Shape theContinuity)
+: myDone (Standard_False),
+ myDeflection (theDeflection),
+ myCont (GeomAbs_C1)
+{
+ Initialize (theC, theDeflection, theContinuity);
+}
+
+//=======================================================================
+//function : GCPnts_QuasiUniformDeflection
+//purpose :
+//=======================================================================
+GCPnts_QuasiUniformDeflection::GCPnts_QuasiUniformDeflection (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theDeflection,
+ const GeomAbs_Shape theContinuity)
+: myDone (Standard_False),
+ myDeflection (theDeflection),
+ myCont (GeomAbs_C1)
+{
+ Initialize (theC, theDeflection, theContinuity);
+}
+
+//=======================================================================
+//function : Initialize
+//purpose :
+//=======================================================================
+void GCPnts_QuasiUniformDeflection::Initialize (const Adaptor3d_Curve& theC,
+ const Standard_Real theDeflection,
+ const GeomAbs_Shape theContinuity)
+{
+ Initialize (theC, theDeflection, theC.FirstParameter(), theC.LastParameter(), theContinuity);
+}
+
+//=======================================================================
+//function : Initialize
+//purpose :
+//=======================================================================
+void GCPnts_QuasiUniformDeflection::Initialize (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theDeflection,
+ const GeomAbs_Shape theContinuity)
+{
+ Initialize (theC, theDeflection, theC.FirstParameter(), theC.LastParameter(), theContinuity);
+}
+
+//=======================================================================
+//function : Initialize
+//purpose :
+//=======================================================================
+void GCPnts_QuasiUniformDeflection::Initialize (const Adaptor3d_Curve& theC,
+ const Standard_Real theDeflection,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const GeomAbs_Shape theContinuity)
+{
+ initialize (theC, theDeflection, theU1, theU2, theContinuity);
+}
+
+//=======================================================================
+//function : Initialize
+//purpose :
+//=======================================================================
+void GCPnts_QuasiUniformDeflection::Initialize (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theDeflection,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const GeomAbs_Shape theContinuity)
+{
+ initialize (theC, theDeflection, theU1, theU2, theContinuity);
+}
+
+//=======================================================================
+//function : initialize
+//purpose :
+//=======================================================================
+template<class TheCurve>
+void GCPnts_QuasiUniformDeflection::initialize (const TheCurve& theC,
+ const Standard_Real theDeflection,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const GeomAbs_Shape theContinuity)
+{
+ myCont = (theContinuity > GeomAbs_G1) ? GeomAbs_C1 : GeomAbs_C0;
+ myDeflection = theDeflection;
+ myDone = Standard_False;
+ myParams.Clear();
+ myPoints.Clear();
+
+ const Standard_Real anEPSILON = Min (theC.Resolution (Precision::Confusion()), 1.e50);
+ const GCPnts_DeflectionType aType = GetDefType (theC);
+ const Standard_Real aU1 = Min (theU1, theU2);
+ const Standard_Real aU2 = Max (theU1, theU2);
+ if (aType == GCPnts_Curved
+ || aType == GCPnts_DefComposite)
+ {
+ if (theC.GetType() == GeomAbs_BSplineCurve
+ || theC.GetType() == GeomAbs_BezierCurve)
+ {
+ const Standard_Real aMaxPar = Max (Abs (theC.FirstParameter()), Abs (theC.LastParameter()));
+ if (anEPSILON < Epsilon (aMaxPar))
+ {
+ return;
+ }
+ }
+ }
+
+ switch (aType)
+ {
+ case GCPnts_Linear:
+ {
+ myDone = PerformLinear (theC, myParams, myPoints, aU1, aU2);
+ break;
+ }
+ case GCPnts_Circular:
+ {
+ myDone = PerformCircular (theC, myParams, myPoints, theDeflection, aU1, aU2);
+ break;
+ }
+ case GCPnts_Curved:
+ {
+ myDone = PerformCurve (myParams, myPoints, theC, theDeflection,
+ aU1, aU2, anEPSILON, myCont);
+ break;
+ }
+ case GCPnts_DefComposite:
+ {
+ myDone = PerformComposite (myParams, myPoints, theC, theDeflection,
+ aU1, aU2, anEPSILON, myCont);
+ break;
+ }
+ }
+}
#include <TColgp_SequenceOfPnt.hxx>
#include <GeomAbs_Shape.hxx>
-class Standard_DomainError;
-class Standard_ConstructionError;
-class Standard_OutOfRange;
-class StdFail_NotDone;
class Adaptor3d_Curve;
class Adaptor2d_Curve2d;
class gp_Pnt;
-//! This class computes a distribution of points on a
-//! curve. The points may respect the deflection. The algorithm
-//! is not based on the classical prediction (with second
-//! derivative of curve), but either on the evaluation of
-//! the distance between the mid point and the point of
-//! mid parameter of the two points, or the distance
-//! between the mid point and the point at parameter 0.5
-//! on the cubic interpolation of the two points and their
-//! tangents.
-//! Note: this algorithm is faster than a
-//! GCPnts_UniformDeflection algorithm, and is
-//! able to work with non-"C2" continuous curves.
+//! This class computes a distribution of points on a curve.
+//! The points may respect the deflection.
+//! The algorithm is not based on the classical prediction (with second derivative of curve),
+//! but either on the evaluation of the distance between the mid point
+//! and the point of mid parameter of the two points,
+//! or the distance between the mid point and the point at parameter 0.5
+//! on the cubic interpolation of the two points and their tangents.
+//!
+//! Note: this algorithm is faster than a GCPnts_UniformDeflection algorithm,
+//! and is able to work with non-"C2" continuous curves.
//! However, it generates more points in the distribution.
class GCPnts_QuasiUniformDeflection
{
DEFINE_STANDARD_ALLOC
-
- //! Constructs an empty algorithm. To define the problem
- //! to be solved, use the function Initialize.
+ //! Constructs an empty algorithm.
+ //! To define the problem to be solved, use the function Initialize().
Standard_EXPORT GCPnts_QuasiUniformDeflection();
-
- //! Computes a QuasiUniform Deflection distribution
- //! of points on the Curve <C>.
- Standard_EXPORT GCPnts_QuasiUniformDeflection(const Adaptor3d_Curve& C, const Standard_Real Deflection, const GeomAbs_Shape Continuity = GeomAbs_C1);
-
- //! Computes a QuasiUniform Deflection distribution
- //! of points on the Curve <C>.
- Standard_EXPORT GCPnts_QuasiUniformDeflection(const Adaptor2d_Curve2d& C, const Standard_Real Deflection, const GeomAbs_Shape Continuity = GeomAbs_C1);
-
- //! Computes a QuasiUniform Deflection distribution
- //! of points on a part of the Curve <C>.
- Standard_EXPORT GCPnts_QuasiUniformDeflection(const Adaptor3d_Curve& C, const Standard_Real Deflection, const Standard_Real U1, const Standard_Real U2, const GeomAbs_Shape Continuity = GeomAbs_C1);
-
- //! Computes a QuasiUniform Deflection distribution
- //! of points on a part of the Curve <C>.
+
+ //! Computes a QuasiUniform Deflection distribution of points on the Curve.
+ Standard_EXPORT GCPnts_QuasiUniformDeflection (const Adaptor3d_Curve& theC,
+ const Standard_Real theDeflection,
+ const GeomAbs_Shape theContinuity = GeomAbs_C1);
+
+ //! Computes a QuasiUniform Deflection distribution of points on the Curve.
+ Standard_EXPORT GCPnts_QuasiUniformDeflection (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theDeflection,
+ const GeomAbs_Shape theContinuity = GeomAbs_C1);
+
+ //! Computes a QuasiUniform Deflection distribution of points on a part of the Curve.
+ Standard_EXPORT GCPnts_QuasiUniformDeflection (const Adaptor3d_Curve& theC,
+ const Standard_Real theDeflection,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const GeomAbs_Shape theContinuity = GeomAbs_C1);
+
+ //! Computes a QuasiUniform Deflection distribution of points on a part of the Curve.
//! This and the above algorithms compute a distribution of points:
- //! - on the curve C, or
- //! - on the part of curve C limited by the two
- //! parameter values U1 and U2,
+ //! - on the curve theC, or
+ //! - on the part of curve theC limited by the two parameter values theU1 and theU2,
//! where the deflection resulting from the distributed
- //! points is not greater than Deflection.
+ //! points is not greater than theDeflection.
+ //!
//! The first point of the distribution is either the origin of
- //! curve C or the point of parameter U1. The last point
- //! of the distribution is either the end point of curve C or
- //! the point of parameter U2.
+ //! curve theC or the point of parameter theU1.
+ //! The last point of the distribution is either the end point
+ //! of curve theC or the point of parameter theU2.
+ //!
//! Intermediate points of the distribution are built such
- //! that the deflection is not greater than Deflection.
+ //! that the deflection is not greater than theDeflection.
//! Using the following evaluation of the deflection:
//! if Pi and Pj are two consecutive points of the
- //! distribution, respectively of parameter ui and uj on
- //! the curve, the deflection is the distance between:
- //! - the mid-point of Pi and Pj (the center of the
- //! chord joining these two points)
+ //! distribution, respectively of parameter ui and uj on the curve,
+ //! the deflection is the distance between:
+ //! - the mid-point of Pi and Pj (the center of the chord joining these two points)
//! - and the point of mid-parameter of these two
- //! points (the point of parameter [(ui+uj) / 2 ] on curve C).
- //! Continuity, defaulted to GeomAbs_C1, gives the
- //! degree of continuity of the curve C. (Note that C is an
- //! Adaptor3d_Curve or an Adaptor2d_Curve2d
- //! object, and does not know the degree of continuity of
- //! the underlying curve).
- //! Use the function IsDone to verify that the
- //! computation was successful, the function NbPoints
- //! to obtain the number of points of the computed
- //! distribution, and the function Parameter to read the
- //! parameter of each point.
+ //! points (the point of parameter [(ui+uj) / 2] on curve theC).
+ //! theContinuity, defaulted to GeomAbs_C1, gives the degree of continuity of the curve theC.
+ //! (Note that C is an Adaptor3d_Curve or an Adaptor2d_Curve2d object,
+ //! and does not know the degree of continuity of the underlying curve).
+ //! Use the function IsDone() to verify that the computation was successful,
+ //! the function NbPoints() to obtain the number of points of the computed distribution,
+ //! and the function Parameter() to read the parameter of each point.
+ //!
//! Warning
- //! - The roles of U1 and U2 are inverted if U1 > U2.
- //! - Derivative functions on the curve are called
- //! according to Continuity. An error may occur if
- //! Continuity is greater than the real degree of
- //! continuity of the curve.
+ //! - The roles of theU1 and theU2 are inverted if theU1 > theU2.
+ //! - Derivative functions on the curve are called according to theContinuity.
+ //! An error may occur if theContinuity is greater than
+ //! the real degree of continuity of the curve.
+ //!
//! Warning
- //! C is an adapted curve, i.e. an object which is an
- //! interface between:
+ //! theC is an adapted curve, i.e. an object which is an interface between:
//! - the services provided by either a 2D curve from
- //! the package Geom2d (in the case of an
- //! Adaptor2d_Curve2d curve) or a 3D curve from
- //! the package Geom (in the case of an
- //! Adaptor3d_Curve curve),
- //! - and those required on the curve by the
- //! computation algorithm.
- Standard_EXPORT GCPnts_QuasiUniformDeflection(const Adaptor2d_Curve2d& C, const Standard_Real Deflection, const Standard_Real U1, const Standard_Real U2, const GeomAbs_Shape Continuity = GeomAbs_C1);
-
- //! Initialize the algorithms with <C>, <Deflection>
- Standard_EXPORT void Initialize (const Adaptor3d_Curve& C, const Standard_Real Deflection, const GeomAbs_Shape Continuity = GeomAbs_C1);
-
- //! Initialize the algorithms with <C>, <Deflection>
- Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& C, const Standard_Real Deflection, const GeomAbs_Shape Continuity = GeomAbs_C1);
-
- //! Initialize the algorithms with <C>, <Deflection>,
- //! <U1>,<U2>
- Standard_EXPORT void Initialize (const Adaptor3d_Curve& C, const Standard_Real Deflection, const Standard_Real U1, const Standard_Real U2, const GeomAbs_Shape Continuity = GeomAbs_C1);
-
- //! Initialize the algorithms with <C>, <Deflection>,
- //! -- <U1>,<U2>
+ //! the package Geom2d (in the case of an Adaptor2d_Curve2d curve)
+ //! or a 3D curve from the package Geom (in the case of an Adaptor3d_Curve curve),
+ //! - and those required on the curve by the computation algorithm.
+ Standard_EXPORT GCPnts_QuasiUniformDeflection (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theDeflection,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const GeomAbs_Shape theContinuity = GeomAbs_C1);
+
+ //! Initialize the algorithms with 3D curve and deflection.
+ Standard_EXPORT void Initialize (const Adaptor3d_Curve& theC,
+ const Standard_Real theDeflection,
+ const GeomAbs_Shape theContinuity = GeomAbs_C1);
+
+ //! Initialize the algorithms with 2D curve and deflection.
+ Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theDeflection,
+ const GeomAbs_Shape theContinuity = GeomAbs_C1);
+
+ //! Initialize the algorithms with 3D curve, deflection and parameter range.
+ Standard_EXPORT void Initialize (const Adaptor3d_Curve& theC,
+ const Standard_Real theDeflection,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const GeomAbs_Shape theContinuity = GeomAbs_C1);
+
+ //! Initialize the algorithms with theC, theDeflection, theU1, theU2.
//! This and the above algorithms initialize (or reinitialize)
//! this algorithm and compute a distribution of points:
- //! - on the curve C, or
- //! - on the part of curve C limited by the two
- //! parameter values U1 and U2,
+ //! - on the curve theC, or
+ //! - on the part of curve theC limited by the two parameter values theU1 and theU2,
//! where the deflection resulting from the distributed
- //! points is not greater than Deflection.
+ //! points is not greater than theDeflection.
+ //!
//! The first point of the distribution is either the origin
- //! of curve C or the point of parameter U1. The last
- //! point of the distribution is either the end point of
- //! curve C or the point of parameter U2.
+ //! of curve theC or the point of parameter theU1.
+ //! The last point of the distribution is either the end point of
+ //! curve theC or the point of parameter theU2.
+ //!
//! Intermediate points of the distribution are built in
- //! such a way that the deflection is not greater than
- //! Deflection. Using the following evaluation of the deflection:
- //! if Pi and Pj are two consecutive points of the
- //! distribution, respectively of parameter ui and uj
- //! on the curve, the deflection is the distance between:
- //! - the mid-point of Pi and Pj (the center of the
- //! chord joining these two points)
+ //! such a way that the deflection is not greater than theDeflection.
+ //! Using the following evaluation of the deflection:
+ //! if Pi and Pj are two consecutive points of the distribution,
+ //! respectively of parameter ui and uj on the curve,
+ //! the deflection is the distance between:
+ //! - the mid-point of Pi and Pj (the center of the chord joining these two points)
//! - and the point of mid-parameter of these two
- //! points (the point of parameter [(ui+uj) / 2 ] on curve C).
- //! Continuity, defaulted to GeomAbs_C1, gives the
- //! degree of continuity of the curve C. (Note that C is
- //! an Adaptor3d_Curve or an
- //! Adaptor2d_Curve2d object, and does not know
- //! the degree of continuity of the underlying curve).
- //! Use the function IsDone to verify that the
- //! computation was successful, the function NbPoints
- //! to obtain the number of points of the computed
- //! distribution, and the function Parameter to read
- //! the parameter of each point.
+ //! points (the point of parameter [(ui+uj) / 2] on curve theC).
+ //! theContinuity, defaulted to GeomAbs_C1, gives the degree of continuity of the curve theC.
+ //! (Note that C is an Adaptor3d_Curve or an Adaptor2d_Curve2d object,
+ //! and does not know the degree of continuity of the underlying curve).
+ //! Use the function IsDone to verify that the computation was successful,
+ //! the function NbPoints() to obtain the number of points of the computed distribution,
+ //! and the function Parameter() to read the parameter of each point.
+ //!
//! Warning
- //! - The roles of U1 and U2 are inverted if U1 > U2.
- //! - Derivative functions on the curve are called
- //! according to Continuity. An error may occur if
- //! Continuity is greater than the real degree of
- //! continuity of the curve.
+ //! - The roles of theU1 and theU2 are inverted if theU1 > theU2.
+ //! - Derivative functions on the curve are called according to theContinuity.
+ //! An error may occur if theContinuity is greater than
+ //! the real degree of continuity of the curve.
+ //!
//! Warning
- //! C is an adapted curve, i.e. an object which is an
- //! interface between:
+ //! theC is an adapted curve, i.e. an object which is an interface between:
//! - the services provided by either a 2D curve from
- //! the package Geom2d (in the case of an
- //! Adaptor2d_Curve2d curve) or a 3D curve from
- //! the package Geom (in the case of an Adaptor3d_Curve curve),
- //! and those required on the curve by the computation algorithm.
- Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& C, const Standard_Real Deflection, const Standard_Real U1, const Standard_Real U2, const GeomAbs_Shape Continuity = GeomAbs_C1);
-
+ //! the package Geom2d (in the case of an Adaptor2d_Curve2d curve)
+ //! or a 3D curve from the package Geom (in the case of an Adaptor3d_Curve curve),
+ //! and those required on the curve by the computation algorithm.
+ Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& theC,
+ const Standard_Real theDeflection,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const GeomAbs_Shape theContinuity = GeomAbs_C1);
//! Returns true if the computation was successful.
//! IsDone is a protection against:
return myDeflection;
}
+private:
+
+ //! Initializes algorithm.
+ template<class TheCurve>
+ void initialize (const TheCurve& theC,
+ const Standard_Real theDeflection,
+ const Standard_Real theU1, const Standard_Real theU2,
+ const GeomAbs_Shape theContinuity);
+
private:
Standard_Boolean myDone;
Standard_Real myDeflection;
+++ /dev/null
-// 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 <StdFail_NotDone.hxx>
-#include <Standard_DomainError.hxx>
-#include <Standard_OutOfRange.hxx>
-#include <Standard_ConstructionError.hxx>
-#include <Standard_NotImplemented.hxx>
-#include <GCPnts_DeflectionType.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <TColStd_SequenceOfReal.hxx>
-#include <BSplCLib.hxx>
-#include <gp_Circ.hxx>
-#include <gp_Circ2d.hxx>
-#include <Precision.hxx>
-
-
-static void QuasiFleche(const TheCurve&,
- const Standard_Real,
- const Standard_Real,
- const gp_Pnt&,
- const gp_Vec&,
- const Standard_Real,
- const gp_Pnt&,
- const gp_Vec&,
- const Standard_Integer,
- const Standard_Real,
- TColStd_SequenceOfReal&,
- TColgp_SequenceOfPnt&,
- Standard_Integer&);
-
-static void QuasiFleche(const TheCurve&,
- const Standard_Real,
- const Standard_Real,
- const gp_Pnt&,
- const Standard_Real,
- const gp_Pnt&,
- const Standard_Integer,
- TColStd_SequenceOfReal&,
- TColgp_SequenceOfPnt&,
- Standard_Integer&);
-
-
-//=======================================================================
-//function : PerformLinear
-//purpose :
-//=======================================================================
-static Standard_Boolean PerformLinear (const TheCurve& C,
- TColStd_SequenceOfReal& Parameters,
- TColgp_SequenceOfPnt& Points,
- const Standard_Real U1,
- const Standard_Real U2)
-{
- gp_Pnt aPoint;
- Parameters.Append (U1);
- aPoint = Value (C, U1);
- Points.Append (aPoint);
-
- Parameters.Append (U2);
- aPoint = Value (C, U2);
- Points.Append (aPoint);
- return Standard_True;
-}
-
-
-//=======================================================================
-//function : PerformCircular
-//purpose :
-//=======================================================================
-static Standard_Boolean PerformCircular (const TheCurve& C,
- TColStd_SequenceOfReal& Parameters,
- TColgp_SequenceOfPnt& Points,
- const Standard_Real Deflection,
- const Standard_Real U1,
- const Standard_Real U2)
-
-{
- gp_Pnt aPoint;
- Standard_Real Angle = Max (1.0e0 - (Deflection / C.Circle().Radius()), 0.0e0);
- Angle = 2.0e0 * ACos (Angle);
- Standard_Integer NbPoints = (Standard_Integer )((U2 - U1) / Angle);
- NbPoints += 2;
- Angle = (U2 - U1) / (Standard_Real) (NbPoints - 1);
- Standard_Real U = U1;
- for (Standard_Integer i = 1; i <= NbPoints; ++i)
- {
- Parameters.Append (U);
- aPoint = Value (C,U);
- Points.Append (aPoint);
- U += Angle;
- }
- return Standard_True;
-}
-
-
-//=======================================================================
-//function : GetDefType
-//purpose :
-//=======================================================================
-static GCPnts_DeflectionType GetDefType (const TheCurve& C)
-{
- if (C.NbIntervals(GeomAbs_C1) > 1)
- return GCPnts_DefComposite;
- // pour forcer les decoupages aux cassures. G1 devrait marcher,
- // mais donne des exceptions...
-
- switch (C.GetType())
- {
- case GeomAbs_Line: return GCPnts_Linear;
- case GeomAbs_Circle: return GCPnts_Circular;
- case GeomAbs_BSplineCurve:
- {
- Handle_TheBSplineCurve BS = C.BSpline();
- return (BS->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved;
- }
- case GeomAbs_BezierCurve:
- {
- Handle_TheBezierCurve BZ = C.Bezier();
- return (BZ->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved;
- }
- default: return GCPnts_Curved;
- }
-}
-
-
-//=======================================================================
-//function : PerformCurve
-//purpose :
-//=======================================================================
-static Standard_Boolean PerformCurve (TColStd_SequenceOfReal& Parameters,
- TColgp_SequenceOfPnt& Points,
- const TheCurve& C,
- const Standard_Real Deflection,
- const Standard_Real U1,
- const Standard_Real U2,
- const Standard_Real EPSILON,
- const GeomAbs_Shape Continuity)
-{
- Standard_Integer Nbmin = 2;
- Standard_Integer aNbCallQF = 0;
-
- gp_Pnt Pdeb;
- if (Continuity <= GeomAbs_G1)
- {
-
- Pdeb = Value (C, U1);
- Parameters.Append (U1);
- Points.Append (Pdeb);
-
- gp_Pnt Pfin (Value (C, U2));
- QuasiFleche (C, Deflection * Deflection,
- U1, Pdeb,
- U2, Pfin,
- Nbmin,
- Parameters, Points, aNbCallQF);
- }
- else
- {
- gp_Pnt Pfin;
- gp_Vec Ddeb, Dfin;
- D1 (C, U1, Pdeb, Ddeb);
- Parameters.Append (U1);
- Points.Append (Pdeb);
-
- Standard_Real aDecreasedU2 = U2 - Epsilon(U2) * 10.;
- D1 (C, aDecreasedU2, Pfin, Dfin);
- QuasiFleche (C, Deflection * Deflection,
- U1, Pdeb,
- Ddeb,
- U2, Pfin,
- Dfin,
- Nbmin,
- EPSILON * EPSILON,
- Parameters, Points, aNbCallQF);
- }
-// cout << "Nb de pts: " << Points.Length()<< endl;
- return Standard_True;
-}
-
-
-//=======================================================================
-//function : PerformComposite
-//purpose :
-//=======================================================================
-static Standard_Boolean PerformComposite (TColStd_SequenceOfReal& Parameters,
- TColgp_SequenceOfPnt& Points,
- const TheCurve& C,
- const Standard_Real Deflection,
- const Standard_Real U1,
- const Standard_Real U2,
- const Standard_Real EPSILON,
- const GeomAbs_Shape Continuity)
-{
-//
-// coherence avec Intervals
-//
- Standard_Integer NbIntervals = C.NbIntervals (GeomAbs_C2);
- Standard_Integer PIndex;
- TColStd_Array1OfReal TI (1, NbIntervals + 1);
- C.Intervals (TI, GeomAbs_C2);
- BSplCLib::Hunt (TI, U1, PIndex);
-
- // iterate by continuous segments
- Standard_Real Ua = U1;
- for (Standard_Integer Index = PIndex;;)
- {
- Standard_Real Ub = Index + 1 <= TI.Upper()
- ? Min (U2, TI (Index + 1))
- : U2;
- if (!PerformCurve (Parameters, Points, C, Deflection,
- Ua, Ub, EPSILON, Continuity))
- return Standard_False;
-
- ++Index;
- if (Index > NbIntervals || U2 < TI (Index))
- return Standard_True;
-
- // remove last point to avoid duplication
- Parameters.Remove (Parameters.Length());
- Points.Remove (Points.Length());
-
- Ua = Ub;
- }
-}
-
-
-//=======================================================================
-//function : GCPnts_QuasiUniformDeflection
-//purpose :
-//=======================================================================
-GCPnts_QuasiUniformDeflection::GCPnts_QuasiUniformDeflection
- (const TheCurve& C,
- const Standard_Real Deflection,
- const Standard_Real U1,
- const Standard_Real U2,
- const GeomAbs_Shape Continuity)
-{
- Initialize (C, Deflection, U1, U2, Continuity);
-}
-
-
-//=======================================================================
-//function : GCPnts_QuasiUniformDeflection
-//purpose :
-//=======================================================================
-GCPnts_QuasiUniformDeflection::GCPnts_QuasiUniformDeflection
- (const TheCurve& C,
- const Standard_Real Deflection,
- const GeomAbs_Shape Continuity)
-{
- Initialize (C, Deflection, Continuity);
-}
-
-
-//=======================================================================
-//function : Initialize
-//purpose :
-//=======================================================================
-void GCPnts_QuasiUniformDeflection::Initialize (const TheCurve& C,
- const Standard_Real Deflection,
- const GeomAbs_Shape Continuity)
-{
- Initialize (C, Deflection, C.FirstParameter(),
- C.LastParameter(), Continuity);
-}
-
-
-//=======================================================================
-//function : Initialize
-//purpose :
-//=======================================================================
-
-void GCPnts_QuasiUniformDeflection::Initialize
- (const TheCurve& C,
- const Standard_Real Deflection,
- const Standard_Real theU1,
- const Standard_Real theU2,
- const GeomAbs_Shape Continuity)
-{
- myCont = (Continuity > GeomAbs_G1) ? GeomAbs_C1 : GeomAbs_C0;
- Standard_Real EPSILON = C.Resolution (Precision::Confusion());
- EPSILON = Min (EPSILON, 1.e50);
- myDeflection = Deflection;
- myDone = Standard_False;
- myParams.Clear();
- myPoints.Clear();
- GCPnts_DeflectionType Type = GetDefType (C);
-
- Standard_Real U1 = Min (theU1, theU2);
- Standard_Real U2 = Max (theU1, theU2);
-
- if (Type == GCPnts_Curved || Type == GCPnts_DefComposite)
- {
- if (C.GetType() == GeomAbs_BSplineCurve || C.GetType() == GeomAbs_BezierCurve)
- {
- Standard_Real maxpar = Max (Abs (C.FirstParameter()), Abs (C.LastParameter()));
- if (EPSILON < Epsilon (maxpar)) return;
- }
- }
-
- switch (Type)
- {
- case GCPnts_Linear:
- myDone = PerformLinear (C, myParams, myPoints, U1, U2);
- break;
- case GCPnts_Circular:
- myDone = PerformCircular (C, myParams, myPoints, Deflection, U1, U2);
- break;
- case GCPnts_Curved:
- myDone = PerformCurve (myParams, myPoints, C, Deflection,
- U1, U2, EPSILON, myCont);
- break;
- case GCPnts_DefComposite:
- myDone = PerformComposite (myParams, myPoints, C, Deflection,
- U1, U2, EPSILON, myCont);
- break;
- }
-}
-
-
-//=======================================================================
-//function : QuasiFleche
-//purpose :
-//=======================================================================
-void QuasiFleche (const TheCurve& C,
- const Standard_Real Deflection2,
- const Standard_Real Udeb,
- const gp_Pnt& Pdeb,
- const gp_Vec& Vdeb,
- const Standard_Real Ufin,
- const gp_Pnt& Pfin,
- const gp_Vec& Vfin,
- const Standard_Integer Nbmin,
- const Standard_Real Eps,
- TColStd_SequenceOfReal& Parameters,
- TColgp_SequenceOfPnt& Points,
- Standard_Integer& theNbCalls)
-{
- theNbCalls++;
- if (theNbCalls >= MyMaxQuasiFleshe)
- {
- return;
- }
- Standard_Integer Ptslength = Points.Length();
- if (theNbCalls > 100 && Ptslength < 2)
- {
- return;
- }
- Standard_Real Udelta = Ufin - Udeb;
- gp_Pnt Pdelta;
- gp_Vec Vdelta;
- if (Nbmin > 2)
- {
- Udelta /= (Nbmin - 1);
- D1 (C, Udeb + Udelta, Pdelta, Vdelta);
- }
- else
- {
- Pdelta = Pfin;
- Vdelta = Vfin;
- }
-
- Standard_Real Norme = gp_Vec (Pdeb, Pdelta).SquareMagnitude();
- Standard_Real theFleche = 0;
- Standard_Boolean flecheok = Standard_False;
- if (Norme > Eps)
- {
- // Evaluation de la fleche par interpolation . Voir IntWalk_IWalking_5.gxx
- Standard_Real N1 = Vdeb.SquareMagnitude();
- Standard_Real N2 = Vdelta.SquareMagnitude();
- if (N1 > Eps && N2 > Eps)
- {
- Standard_Real Normediff = (Vdeb.Normalized().XYZ() - Vdelta.Normalized().XYZ()).SquareModulus();
- if (Normediff > Eps)
- {
- theFleche = Normediff * Norme / 64.;
- flecheok = Standard_True;
- }
- }
- }
- if (!flecheok)
- {
- gp_Pnt Pmid ((Pdeb.XYZ() + Pdelta.XYZ()) * 0.5);
- gp_Pnt Pverif (Value(C, Udeb + Udelta * 0.5));
- theFleche = Pmid.SquareDistance (Pverif);
- }
-
- if (theFleche < Deflection2)
- {
- Parameters.Append (Udeb + Udelta);
- Points.Append (Pdelta);
- }
- else
- {
- QuasiFleche (C, Deflection2, Udeb, Pdeb,
- Vdeb,
- Udeb + Udelta, Pdelta,
- Vdelta,
- 3,
- Eps,
- Parameters, Points, theNbCalls);
- }
-
- if (Nbmin > 2)
- {
- QuasiFleche (C, Deflection2, Udeb + Udelta, Pdelta,
- Vdelta,
- Ufin, Pfin,
- Vfin,
- Nbmin - (Points.Length() - Ptslength),
- Eps,
- Parameters, Points, theNbCalls);
- }
- theNbCalls--;
-}
-
-
-//=======================================================================
-//function : QuasiFleche
-//purpose :
-//=======================================================================
-void QuasiFleche (const TheCurve& C,
- const Standard_Real Deflection2,
- const Standard_Real Udeb,
- const gp_Pnt& Pdeb,
- const Standard_Real Ufin,
- const gp_Pnt& Pfin,
- const Standard_Integer Nbmin,
- TColStd_SequenceOfReal& Parameters,
- TColgp_SequenceOfPnt& Points,
- Standard_Integer& theNbCalls)
-{
- theNbCalls++;
- if (theNbCalls >= MyMaxQuasiFleshe)
- {
- return;
- }
- Standard_Integer Ptslength = Points.Length();
- if (theNbCalls > 100 && Ptslength < 2)
- {
- return;
- }
- Standard_Real Udelta = Ufin - Udeb;
- gp_Pnt Pdelta;
- if (Nbmin > 2)
- {
- Udelta /= (Nbmin-1);
- Pdelta = Value (C, Udeb + Udelta);
- }
- else
- {
- Pdelta = Pfin;
- }
-
- gp_Pnt Pmid ((Pdeb.XYZ() + Pdelta.XYZ()) * 0.5);
- gp_Pnt Pverif (Value (C, Udeb + Udelta * 0.5));
- Standard_Real theFleche = Pmid.SquareDistance (Pverif);
-
- if (theFleche < Deflection2)
- {
- Parameters.Append(Udeb + Udelta);
- Points.Append (Pdelta);
- }
- else
- {
- QuasiFleche (C, Deflection2, Udeb, Pdeb,
- Udeb + Udelta * 0.5, Pverif,
- 2,
- Parameters, Points, theNbCalls);
-
- QuasiFleche (C, Deflection2, Udeb + Udelta * 0.5, Pverif,
- Udeb + Udelta, Pdelta,
- 2,
- Parameters, Points, theNbCalls);
- }
-
- if (Nbmin > 2)
- {
- QuasiFleche (C, Deflection2, Udeb + Udelta, Pdelta,
- Ufin, Pfin,
- Nbmin - (Points.Length() - Ptslength),
- Parameters, Points, theNbCalls);
- }
- theNbCalls--;
-}