diff --git a/src/GCPnts/FILES b/src/GCPnts/FILES index c6edf27d61..13a6ee2d6e 100755 --- a/src/GCPnts/FILES +++ b/src/GCPnts/FILES @@ -5,7 +5,6 @@ GCPnts_DeflectionType.hxx GCPnts_QuasiUniformAbscissa.cxx GCPnts_QuasiUniformAbscissa.hxx GCPnts_QuasiUniformDeflection.cxx -GCPnts_QuasiUniformDeflection.pxx GCPnts_QuasiUniformDeflection.hxx GCPnts_TangentialDeflection.cxx GCPnts_TangentialDeflection.hxx diff --git a/src/GCPnts/GCPnts_QuasiUniformDeflection.cxx b/src/GCPnts/GCPnts_QuasiUniformDeflection.cxx index f600e2dfbb..fd357bfbc6 100644 --- a/src/GCPnts/GCPnts_QuasiUniformDeflection.cxx +++ b/src/GCPnts/GCPnts_QuasiUniformDeflection.cxx @@ -12,106 +12,590 @@ // 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 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) ; -} -static gp_Pnt Value(const Adaptor2d_Curve2d & C, - const Standard_Real Parameter) -{ - gp_Pnt aPoint ; - gp_Pnt2d a2dPoint(C.Value(Parameter)); - aPoint.SetCoord(a2dPoint.X(),a2dPoint.Y(),0.); - return aPoint ; + return theC.Value (theParameter); } -static void D1(const Adaptor3d_Curve & C, - const Standard_Real Parameter, - gp_Pnt& P, - gp_Vec& V) +static gp_Pnt Value (const Adaptor2d_Curve2d& theC, + const Standard_Real theParameter) { - C.D1(Parameter,P,V); + gp_Pnt aPoint; + gp_Pnt2d a2dPoint (theC.Value (theParameter)); + aPoint.SetCoord (a2dPoint.X(), a2dPoint.Y(), 0.0); + return aPoint; } -static void D1(const Adaptor2d_Curve2d & 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) +{ + theC.D1 (theParameter, theP, theV); +} + +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 +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 : QuasiFleche +//purpose : +//======================================================================= +template +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); + + 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 : PerformLinear +//purpose : +//======================================================================= +template +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 +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; +} + +//======================================================================= +//function : GetDefType +//purpose : +//======================================================================= +template +static GCPnts_DeflectionType GetDefType (const TheCurve& theC) +{ + if (theC.NbIntervals (GeomAbs_C1) > 1) + { + return GCPnts_DefComposite; + } + + // 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::BSplineCurve) aBS = theC.BSpline(); + return (aBS->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved; + } + case GeomAbs_BezierCurve: + { + Handle(typename GCPnts_TCurveTypes::BezierCurve) aBZ = theC.Bezier(); + return (aBZ->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved; + } + default: return GCPnts_Curved; + } +} + +//======================================================================= +//function : PerformCurve +//purpose : +//======================================================================= +template +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; + + gp_Pnt aPdeb; + if (theContinuity <= GeomAbs_G1) + { + aPdeb = Value (theC, theU1); + theParameters.Append (theU1); + thePoints.Append (aPdeb); + + 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); + + 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; +} + +//======================================================================= +//function : PerformComposite +//purpose : +//======================================================================= +template +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); + + // 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 : +//purpose : //======================================================================= - -gp_Pnt GCPnts_QuasiUniformDeflection::Value - (const Standard_Integer Index) const -{ - StdFail_NotDone_Raise_if(!myDone, - "GCPnts_QuasiUniformAbscissa::Parameter()"); - return myPoints.Value(Index) ; +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 : +//purpose : //======================================================================= - -GCPnts_QuasiUniformDeflection::GCPnts_QuasiUniformDeflection () -: myDone(Standard_False), - myDeflection(0.0), - myCont(GeomAbs_C1) +GCPnts_QuasiUniformDeflection::GCPnts_QuasiUniformDeflection() +: myDone (Standard_False), + myDeflection (0.0), + myCont (GeomAbs_C1) { -} + // +} -#include -#include +//======================================================================= +//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); +} -#define TheCurve Adaptor3d_Curve -#define Handle_TheBezierCurve Handle(Geom_BezierCurve) -#define Handle_TheBSplineCurve Handle(Geom_BSplineCurve) +//======================================================================= +//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); +} -#include "GCPnts_QuasiUniformDeflection.pxx" +//======================================================================= +//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); +} -#undef TheCurve -#undef Handle_TheBezierCurve -#undef Handle_TheBSplineCurve +//======================================================================= +//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); +} -#include -#include - -#define TheCurve Adaptor2d_Curve2d -#define Handle_TheBezierCurve Handle(Geom2d_BezierCurve) -#define Handle_TheBSplineCurve Handle(Geom2d_BSplineCurve) - -#include "GCPnts_QuasiUniformDeflection.pxx" +//======================================================================= +//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 +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; + } + } +} diff --git a/src/GCPnts/GCPnts_QuasiUniformDeflection.hxx b/src/GCPnts/GCPnts_QuasiUniformDeflection.hxx index 375d748141..c61d8b40b9 100644 --- a/src/GCPnts/GCPnts_QuasiUniformDeflection.hxx +++ b/src/GCPnts/GCPnts_QuasiUniformDeflection.hxx @@ -22,26 +22,20 @@ #include #include -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 { @@ -49,132 +43,132 @@ public: 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 . - 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 . - 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 . - 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 . + + //! 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 , - Standard_EXPORT void Initialize (const Adaptor3d_Curve& C, const Standard_Real Deflection, const GeomAbs_Shape Continuity = GeomAbs_C1); - - //! Initialize the algorithms with , - Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& C, const Standard_Real Deflection, const GeomAbs_Shape Continuity = GeomAbs_C1); - - //! Initialize the algorithms with , , - //! , - 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 , , - //! -- , + //! 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: @@ -238,6 +232,15 @@ public: return myDeflection; } +private: + + //! Initializes algorithm. + template + 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; diff --git a/src/GCPnts/GCPnts_QuasiUniformDeflection.pxx b/src/GCPnts/GCPnts_QuasiUniformDeflection.pxx deleted file mode 100644 index aff5f87a79..0000000000 --- a/src/GCPnts/GCPnts_QuasiUniformDeflection.pxx +++ /dev/null @@ -1,496 +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 - - -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--; -}