diff --git a/src/GCPnts/FILES b/src/GCPnts/FILES index f990131585..5dc21c935b 100755 --- a/src/GCPnts/FILES +++ b/src/GCPnts/FILES @@ -11,11 +11,11 @@ GCPnts_QuasiUniformDeflection.pxx GCPnts_QuasiUniformDeflection.hxx GCPnts_TangentialDeflection.cxx GCPnts_TangentialDeflection.hxx +GCPnts_TCurveTypes.hxx GCPnts_UniformAbscissa.cxx GCPnts_UniformAbscissa.pxx GCPnts_UniformAbscissa.hxx GCPnts_UniformDeflection.cxx -GCPnts_UniformDeflection.pxx GCPnts_UniformDeflection.hxx GCPnts_DistFunction.hxx GCPnts_DistFunction.cxx diff --git a/src/GCPnts/GCPnts_DistFunction.hxx b/src/GCPnts/GCPnts_DistFunction.hxx index 9885ed56cf..fc010e29fb 100644 --- a/src/GCPnts/GCPnts_DistFunction.hxx +++ b/src/GCPnts/GCPnts_DistFunction.hxx @@ -23,7 +23,7 @@ class gp_Pnt; //! Class to define function, which calculates square distance between point on curve //! C(u), U1 <= u <= U2 and line passing through points C(U1) and C(U2) -//! This function is used in any minimisation algorithm to define maximal deviation between curve and line, +//! This function is used in any minimization algorithm to define maximal deviation between curve and line, //! which required one variable function without derivative (for ex. math_BrentMinimum) class GCPnts_DistFunction : public math_Function { diff --git a/src/GCPnts/GCPnts_TCurveTypes.hxx b/src/GCPnts/GCPnts_TCurveTypes.hxx new file mode 100644 index 0000000000..eb21fe810b --- /dev/null +++ b/src/GCPnts/GCPnts_TCurveTypes.hxx @@ -0,0 +1,49 @@ +// Copyright (c) 2021 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. + +#ifndef _GCPnts_TCurveTypes_HeaderFile +#define _GCPnts_TCurveTypes_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include + +//! Auxiliary tool to resolve 2D/3D curve classes. +template struct GCPnts_TCurveTypes {}; + +//! Auxiliary tool to resolve 3D curve classes. +template<> struct GCPnts_TCurveTypes +{ + typedef gp_Pnt Point; + typedef Geom_BezierCurve BezierCurve; + typedef Geom_BSplineCurve BSplineCurve; + typedef GCPnts_DistFunction DistFunction; + typedef GCPnts_DistFunctionMV DistFunctionMV; +}; + +//! Auxiliary tool to resolve 2D curve classes. +template<> struct GCPnts_TCurveTypes +{ + typedef gp_Pnt2d Point; + typedef Geom2d_BezierCurve BezierCurve; + typedef Geom2d_BSplineCurve BSplineCurve; + typedef GCPnts_DistFunction2d DistFunction; + typedef GCPnts_DistFunction2dMV DistFunctionMV; +}; + +#endif // _GCPnts_TCurveTypes_HeaderFile diff --git a/src/GCPnts/GCPnts_TangentialDeflection.cxx b/src/GCPnts/GCPnts_TangentialDeflection.cxx index 7b74e20f2f..a14bc515fd 100644 --- a/src/GCPnts/GCPnts_TangentialDeflection.cxx +++ b/src/GCPnts/GCPnts_TangentialDeflection.cxx @@ -16,8 +16,8 @@ #include -#include -#include +#include + #include #include #include @@ -25,12 +25,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include #include #include @@ -42,27 +36,6 @@ namespace { static const Standard_Real Us3 = 0.3333333333333333333333333333; - //! Auxiliary tool to resolve 2D/3D curve classes. - template struct CurveTypes {}; - - //! Auxiliary tool to resolve 3D curve classes. - template<> struct CurveTypes - { - typedef Geom_BezierCurve BezierCurve; - typedef Geom_BSplineCurve BSplineCurve; - typedef GCPnts_DistFunction DistFunction; - typedef GCPnts_DistFunctionMV DistFunctionMV; - }; - - //! Auxiliary tool to resolve 2D curve classes. - template<> struct CurveTypes - { - typedef Geom2d_BezierCurve BezierCurve; - typedef Geom2d_BSplineCurve BSplineCurve; - typedef GCPnts_DistFunction2d DistFunction; - typedef GCPnts_DistFunction2dMV DistFunctionMV; - }; - inline static void D0 (const Adaptor3d_Curve& C, const Standard_Real U, gp_Pnt& P) { C.D0 (U, P); @@ -435,14 +408,14 @@ void GCPnts_TangentialDeflection::initialize (const TheCurve& theC, } case GeomAbs_BSplineCurve: { - Handle(typename CurveTypes::BSplineCurve) aBS = theC.BSpline(); + Handle(typename GCPnts_TCurveTypes::BSplineCurve) aBS = theC.BSpline(); if (aBS->NbPoles() == 2) PerformLinear (theC); else PerformCurve (theC); break; } case GeomAbs_BezierCurve: { - Handle(typename CurveTypes::BezierCurve) aBZ = theC.Bezier(); + Handle(typename GCPnts_TCurveTypes::BezierCurve) aBZ = theC.Bezier(); if (aBZ->NbPoles() == 2) PerformLinear (theC); else PerformCurve (theC); break; @@ -577,13 +550,13 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& theC) { case GeomAbs_BSplineCurve: { - Handle(typename CurveTypes::BSplineCurve) BS = theC.BSpline(); + Handle(typename GCPnts_TCurveTypes::BSplineCurve) BS = theC.BSpline(); NbPoints = Max(BS->Degree() + 1, NbPoints); break; } case GeomAbs_BezierCurve: { - Handle(typename CurveTypes::BezierCurve) BZ = theC.Bezier(); + Handle(typename GCPnts_TCurveTypes::BezierCurve) BZ = theC.Bezier(); NbPoints = Max(BZ->Degree() + 1, NbPoints); break; } @@ -963,7 +936,7 @@ void GCPnts_TangentialDeflection::EstimDefl (const TheCurve& theC, { const Standard_Real Du = (myLastU - myFirstu); // - typename CurveTypes::DistFunction aFunc (theC, theU1, theU2); + typename GCPnts_TCurveTypes::DistFunction aFunc (theC, theU1, theU2); // const Standard_Integer aNbIter = 100; const Standard_Real aRelTol = Max (1.e-3, 2. * myUTol / (Abs(theU1) + Abs(theU2))); @@ -986,7 +959,7 @@ void GCPnts_TangentialDeflection::EstimDefl (const TheCurve& theC, // Standard_Real aValue = 0.0; math_Vector aT (1, 1); - typename CurveTypes::DistFunctionMV aFuncMV(aFunc); + typename GCPnts_TCurveTypes::DistFunctionMV aFuncMV(aFunc); math_PSO aFinder (&aFuncMV, aLowBorder, aUppBorder, aSteps, aNbParticles); aFinder.Perform (aSteps, aValue, aT); diff --git a/src/GCPnts/GCPnts_UniformDeflection.cxx b/src/GCPnts/GCPnts_UniformDeflection.cxx index f43be1470b..85a8f45d2c 100644 --- a/src/GCPnts/GCPnts_UniformDeflection.cxx +++ b/src/GCPnts/GCPnts_UniformDeflection.cxx @@ -12,10 +12,11 @@ // 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 @@ -25,68 +26,357 @@ #include // 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) -{ - gp_Pnt aPoint ; - gp_Pnt2d a2dPoint = - C.Value(Parameter) ; - aPoint.SetX ( a2dPoint.X()) ; - aPoint.SetY ( a2dPoint.Y()) ; - aPoint.SetZ ( 0.0e0) ; - return aPoint ; -} -//======================================================================= -//function : Value -//purpose : -//======================================================================= -gp_Pnt GCPnts_UniformDeflection::Value - (const Standard_Integer Index) const -{ - StdFail_NotDone_Raise_if(!myDone, - "GCPnts_UniformAbscissa::Parameter()"); - return myPoints.Value(Index) ; +static gp_Pnt Value (const Adaptor2d_Curve2d& theC, + const Standard_Real theParameter) +{ + const gp_Pnt2d a2dPoint = theC.Value (theParameter); + return gp_Pnt (a2dPoint.X(), a2dPoint.Y(), 0.0); } + //======================================================================= //function : GCPnts_UniformDeflection -//purpose : +//purpose : //======================================================================= - -GCPnts_UniformDeflection::GCPnts_UniformDeflection () -: myDone(Standard_False), - myDeflection(0.0) +GCPnts_UniformDeflection::GCPnts_UniformDeflection() +: myDone (Standard_False), + myDeflection (0.0) { -} + // +} -#include -#include +//======================================================================= +//function : GCPnts_UniformDeflection +//purpose : +//======================================================================= +GCPnts_UniformDeflection::GCPnts_UniformDeflection (const Adaptor3d_Curve& theC, + const Standard_Real theDeflection, + const Standard_Real theU1, + const Standard_Real theU2, + const Standard_Boolean theWithControl) +: myDone (Standard_False), + myDeflection (theDeflection) +{ + Initialize (theC, theDeflection, theU1, theU2, theWithControl); +} -#define TheCurve Adaptor3d_Curve -#define Handle_TheBezierCurve Handle(Geom_BezierCurve) -#define Handle_TheBSplineCurve Handle(Geom_BSplineCurve) -#include "GCPnts_UniformDeflection.pxx" -#undef TheCurve -#undef Handle_TheBezierCurve -#undef Handle_TheBSplineCurve +//======================================================================= +//function : GCPnts_UniformDeflection +//purpose : +//======================================================================= +GCPnts_UniformDeflection::GCPnts_UniformDeflection (const Adaptor3d_Curve& theC, + const Standard_Real theDeflection, + const Standard_Boolean theWithControl) +: myDone (Standard_False), + myDeflection (theDeflection) +{ + Initialize (theC, theDeflection, theWithControl); +} -#include -#include -#define TheCurve Adaptor2d_Curve2d -#define Handle_TheBezierCurve Handle(Geom2d_BezierCurve) -#define Handle_TheBSplineCurve Handle(Geom2d_BSplineCurve) -#include "GCPnts_UniformDeflection.pxx" -#undef TheCurve -#undef Handle_TheBezierCurve -#undef Handle_TheBSplineCurve +//======================================================================= +//function : GCPnts_UniformDeflection +//purpose : +//======================================================================= +GCPnts_UniformDeflection::GCPnts_UniformDeflection (const Adaptor2d_Curve2d& theC, + const Standard_Real theDeflection, + const Standard_Real theU1, + const Standard_Real theU2, + const Standard_Boolean theWithControl) +: myDone (Standard_False), + myDeflection (theDeflection) +{ + Initialize (theC, theDeflection, theU1, theU2, theWithControl); +} + +//======================================================================= +//function : GCPnts_UniformDeflection +//purpose : +//======================================================================= +GCPnts_UniformDeflection::GCPnts_UniformDeflection (const Adaptor2d_Curve2d& theC, + const Standard_Real theDeflection, + const Standard_Boolean theWithControl) +: myDone (Standard_False), + myDeflection (theDeflection) +{ + Initialize (theC, theDeflection, theWithControl); +} + +//======================================================================= +//function : Initialize +//purpose : +//======================================================================= +void GCPnts_UniformDeflection::Initialize (const Adaptor3d_Curve& theC, + const Standard_Real theDeflection, + const Standard_Boolean theWithControl) +{ + Initialize (theC, theDeflection, theC.FirstParameter(), theC.LastParameter(), theWithControl); +} + +//======================================================================= +//function : Initialize +//purpose : +//======================================================================= +void GCPnts_UniformDeflection::Initialize (const Adaptor2d_Curve2d& theC, + const Standard_Real theDeflection, + const Standard_Boolean theWithControl) +{ + Initialize (theC, theDeflection, theC.FirstParameter(), theC.LastParameter(), theWithControl); +} + +//======================================================================= +//function : Initialize +//purpose : +//======================================================================= +void GCPnts_UniformDeflection::Initialize (const Adaptor3d_Curve& theC, + const Standard_Real theDeflection, + const Standard_Real theU1, + const Standard_Real theU2, + const Standard_Boolean theWithControl) +{ + initialize (theC, theDeflection, theU1, theU2, theWithControl); +} + +//======================================================================= +//function : Initialize +//purpose : +//======================================================================= +void GCPnts_UniformDeflection::Initialize (const Adaptor2d_Curve2d& theC, + const Standard_Real theDeflection, + const Standard_Real theU1, + const Standard_Real theU2, + const Standard_Boolean theWithControl) +{ + initialize (theC, theDeflection, theU1, theU2, theWithControl); +} + +//======================================================================= +//function : Value +//purpose : +//======================================================================= +gp_Pnt GCPnts_UniformDeflection::Value (const Standard_Integer theIndex) const +{ + StdFail_NotDone_Raise_if(!myDone, "GCPnts_UniformAbscissa::Parameter()"); + return myPoints.Value (theIndex); +} + +//! Control of the last points. +template +static void Controle (const TheCurve& theC, + TColStd_SequenceOfReal& theParameters, + TColgp_SequenceOfPnt& thePoints, + const Standard_Real theU2) +{ + const Standard_Integer aNbPnts = thePoints.Length(); + if (aNbPnts > 2) + { + const Standard_Real aUa = theParameters (aNbPnts - 2); + const Standard_Real aUb = theParameters (aNbPnts - 1); + if (theU2 - aUb < 0.33 * (theU2 - aUa)) + { + const Standard_Real aUc = (theU2 + aUa) * 0.5; + theParameters (aNbPnts - 1) = aUc; + thePoints (aNbPnts - 1) = Value (theC, aUc); + } + } +} + +//======================================================================= +//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) +{ + gp_Pnt aPoint; + Standard_Real anAngle = Max (1.0 - (theDeflection / theC.Circle().Radius()), 0.0); + anAngle = 2.0e0 * ACos (anAngle); + Standard_Integer aNbPoints = (Standard_Integer )((theU2 - theU1) / anAngle); + aNbPoints += 2; + anAngle = (theU2 - theU1) / (Standard_Real) (aNbPoints - 1); + Standard_Real aU = theU1; + for (Standard_Integer i = 1; i <= aNbPoints; ++i) + { + theParameters.Append (aU); + aPoint = Value (theC, aU); + thePoints.Append (aPoint); + aU += anAngle; + } + return Standard_True; +} + +//======================================================================= +//function : GetDefType +//purpose : +//======================================================================= +template +static GCPnts_DeflectionType GetDefType (const TheCurve& theC) +{ + if (theC.NbIntervals (GeomAbs_C2) > 1) + { + return GCPnts_DefComposite; + } + + switch (theC.GetType()) + { + case GeomAbs_Line: return GCPnts_Linear; + case GeomAbs_Circle: return GCPnts_Circular; + case GeomAbs_BSplineCurve: + { + Handle(typename GCPnts_TCurveTypes::BSplineCurve) aBSpline = theC.BSpline(); + return (aBSpline->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved; + } + case GeomAbs_BezierCurve: + { + Handle(typename GCPnts_TCurveTypes::BezierCurve) aBezier = theC.Bezier(); + return (aBezier->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 Standard_Boolean theWithControl) +{ + CPnts_UniformDeflection anIterator (theC, theDeflection, theU1, theU2, theEPSILON, theWithControl); + for (; anIterator.More(); anIterator.Next()) + { + theParameters.Append (anIterator.Value()); + thePoints.Append (anIterator.Point()); + } + return anIterator.IsAllDone(); +} +//======================================================================= +//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 Standard_Boolean theWithControl) +{ + 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, theWithControl)) + { + 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 : initialize +//purpose : +//======================================================================= +template +void GCPnts_UniformDeflection::initialize (const TheCurve& theC, + const Standard_Real theDeflection, + const Standard_Real theU1, + const Standard_Real theU2, + const Standard_Boolean theWithControl) +{ + const Standard_Real anEPSILON = theC.Resolution (Precision::Confusion()); + myDeflection = theDeflection; + myDone = Standard_False; + myParams.Clear(); + myPoints.Clear(); + + const Standard_Real aU1 = Min (theU1, theU2); + const Standard_Real aU2 = Max (theU1, theU2); + const GCPnts_DeflectionType aType = GetDefType (theC); + 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, theWithControl); + break; + case GCPnts_DefComposite: + myDone = PerformComposite (myParams, myPoints, theC, theDeflection, + aU1, aU2, anEPSILON, theWithControl); + break; + } + + // control of the last points + Controle (theC, myParams, myPoints, aU2); +} diff --git a/src/GCPnts/GCPnts_UniformDeflection.hxx b/src/GCPnts/GCPnts_UniformDeflection.hxx index f2518fd1e0..9420d81912 100644 --- a/src/GCPnts/GCPnts_UniformDeflection.hxx +++ b/src/GCPnts/GCPnts_UniformDeflection.hxx @@ -21,112 +21,125 @@ #include #include -class Standard_DomainError; -class Standard_ConstructionError; -class Standard_OutOfRange; -class StdFail_NotDone; class Adaptor3d_Curve; class Adaptor2d_Curve2d; class gp_Pnt; //! Provides an algorithm to compute a distribution of -//! points on a 'C2' continuous curve. The algorithm -//! respects a criterion of maximum deflection between +//! points on a 'C2' continuous curve. +//! The algorithm respects a criterion of maximum deflection between //! the curve and the polygon that results from the computed points. -//! Note: This algorithm is relatively time consuming. A -//! GCPnts_QuasiUniformDeflection algorithm is -//! quicker; it can also work with non-'C2' continuous -//! curves, but it generates more points in the distribution. -class GCPnts_UniformDeflection +//! Note: This algorithm is relatively time consuming. +//! A GCPnts_QuasiUniformDeflection algorithm is quicker; +//! it can also work with non-'C2' continuous curves, +//! but it generates more points in the distribution. +class GCPnts_UniformDeflection { 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_UniformDeflection(); + + //! Computes a uniform Deflection distribution of points on the curve. + //! @param theC [in] input 3D curve + //! @param theDeflection [in] target deflection + //! @param theWithControl [in] when TRUE, the algorithm controls the estimate deflection + Standard_EXPORT GCPnts_UniformDeflection (const Adaptor3d_Curve& theC, + const Standard_Real theDeflection, + const Standard_Boolean theWithControl = Standard_True); + + //! Computes a uniform Deflection distribution of points on the curve. + //! @param theC [in] input 2D curve + //! @param theDeflection [in] target deflection + //! @param theWithControl [in] when TRUE, the algorithm controls the estimate deflection + Standard_EXPORT GCPnts_UniformDeflection (const Adaptor2d_Curve2d& theC, + const Standard_Real theDeflection, + const Standard_Boolean theWithControl = Standard_True); + + //! Computes a Uniform Deflection distribution of points on a part of the curve. + //! @param theC [in] input 3D curve + //! @param theDeflection [in] target deflection + //! @param theU1 [in] first parameter on curve + //! @param theU2 [in] last parameter on curve + //! @param theWithControl [in] when TRUE, the algorithm controls the estimate deflection + Standard_EXPORT GCPnts_UniformDeflection (const Adaptor3d_Curve& theC, + const Standard_Real theDeflection, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Boolean theWithControl = Standard_True); - //! Computes a uniform Deflection distribution of points on - //! the Curve . - //! if is True,the algorithm controls the estimate - //! deflection - Standard_EXPORT GCPnts_UniformDeflection(const Adaptor3d_Curve& C, const Standard_Real Deflection, const Standard_Boolean WithControl = Standard_True); + //! Computes a Uniform Deflection distribution of points on a part of the curve. + //! @param theC [in] input 2D curve + //! @param theDeflection [in] target deflection + //! @param theU1 [in] first parameter on curve + //! @param theU2 [in] last parameter on curve + //! @param theWithControl [in] when TRUE, the algorithm controls the estimate deflection + Standard_EXPORT GCPnts_UniformDeflection (const Adaptor2d_Curve2d& theC, + const Standard_Real theDeflection, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Boolean theWithControl = Standard_True); + + //! Initialize the algorithms with 3D curve and deflection. + Standard_EXPORT void Initialize (const Adaptor3d_Curve& theC, + const Standard_Real theDeflection, + const Standard_Boolean theWithControl = Standard_True); + + //! Initialize the algorithms with 2D curve and deflection. + Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& theC, + const Standard_Real theDeflection, + const Standard_Boolean theWithControl = Standard_True); + + //! Initialize the algorithms with 3D curve, deflection, parameter range. + Standard_EXPORT void Initialize (const Adaptor3d_Curve& theC, + const Standard_Real theDeflection, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Boolean theWithControl = Standard_True); - //! Computes a uniform Deflection distribution of points on - //! the Curve . - //! if is True,the algorithm controls the estimate - //! deflection - Standard_EXPORT GCPnts_UniformDeflection(const Adaptor2d_Curve2d& C, const Standard_Real Deflection, const Standard_Boolean WithControl = Standard_True); - - //! Computes a Uniform Deflection distribution of points - //! on a part of the Curve . - //! if is True,the algorithm controls the estimate - //! deflection - Standard_EXPORT GCPnts_UniformDeflection(const Adaptor3d_Curve& C, const Standard_Real Deflection, const Standard_Real U1, const Standard_Real U2, const Standard_Boolean WithControl = Standard_True); - - //! Computes a Uniform Deflection distribution of points - //! on a part of the Curve . - //! if is True,the algorithm controls the estimate - //! deflection - Standard_EXPORT GCPnts_UniformDeflection(const Adaptor2d_Curve2d& C, const Standard_Real Deflection, const Standard_Real U1, const Standard_Real U2, const Standard_Boolean WithControl = Standard_True); - - //! Initialize the algorithms with , - Standard_EXPORT void Initialize (const Adaptor3d_Curve& C, const Standard_Real Deflection, const Standard_Boolean WithControl = Standard_True); - - //! Initialize the algorithms with , - Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& C, const Standard_Real Deflection, const Standard_Boolean WithControl = Standard_True); - - //! 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 Standard_Boolean WithControl = Standard_True); - - //! Initialize the algorithms with , , - //! , + //! Initialize the algorithms with curve, deflection, parameter range. //! This and the above methods 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, - //! where the maximum distance between C and the + //! - on the curve theC, or + //! - on the part of curve theC limited by the two parameter values theU1 and theU2, + //! where the maximum distance between theC and the //! polygon that results from the points of the - //! distribution is not greater than Deflection. + //! distribution 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. Intermediate - //! points of the distribution are built using - //! interpolations of segments of the curve limited at - //! the 2nd degree. The construction ensures, in a first - //! step, that the chordal deviation for this - //! interpolation of the curve is less than or equal to - //! Deflection. However, it does not ensure that the - //! chordal deviation for the curve itself is less than or - //! equal to Deflection. To do this a check is - //! necessary, which may generate (second step) - //! additional intermediate points. This check is time - //! consuming, and can be avoided by setting - //! WithControl to false. Note that by default - //! WithControl is true and check is performed. - //! 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. + //! 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 using + //! interpolations of segments of the curve limited at the 2nd degree. + //! The construction ensures, in a first step, + //! that the chordal deviation for this + //! interpolation of the curve is less than or equal to theDeflection. + //! However, it does not ensure that the chordal deviation + //! for the curve itself is less than or equal to theDeflection. + //! To do this a check is necessary, + //! which may generate (second step) additional intermediate points. + //! This check is time consuming, and can be avoided by setting theWithControl to false. + //! Note that by default theWithControl is true and check is performed. + //! 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 - //! - C is necessary, 'C2' continuous. This property is - //! not checked at construction time. - //! - The roles of U1 and U2 are inverted if U1 > U2. + //! - theC is necessary, 'C2' continuous. + //! This property is not checked at construction time. + //! - The roles of theU1 and theU2 are inverted if theU1 > theU2. + //! //! 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), + //! 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 Standard_Boolean WithControl = Standard_True); - + Standard_EXPORT void Initialize (const Adaptor2d_Curve2d& theC, + const Standard_Real theDeflection, + const Standard_Real theU1, const Standard_Real theU2, + const Standard_Boolean theWithControl = Standard_True); + //! Returns true if the computation was successful. //! IsDone is a protection against: //! - non-convergence of the algorithm @@ -189,6 +202,16 @@ public: return myDeflection; } +private: + + //! Initialize the algorithm. + template + void initialize (const TheCurve& theC, + const Standard_Real theDeflection, + const Standard_Real theU1, + const Standard_Real theU2, + const Standard_Boolean theWithControl); + private: Standard_Boolean myDone; Standard_Real myDeflection; diff --git a/src/GCPnts/GCPnts_UniformDeflection.pxx b/src/GCPnts/GCPnts_UniformDeflection.pxx deleted file mode 100644 index f50fb5c57c..0000000000 --- a/src/GCPnts/GCPnts_UniformDeflection.pxx +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -//======================================================================= -//function : Controle -//purpose : -//======================================================================= -static void Controle (const TheCurve& C, - TColStd_SequenceOfReal& Parameters, - TColgp_SequenceOfPnt& Points, - const Standard_Real U2) -{ - Standard_Integer nbp = Points.Length(); - - if (nbp > 2) - { - Standard_Real Ua = Parameters (nbp - 2); - Standard_Real Ub = Parameters (nbp - 1); - if (U2 - Ub < 0.33 * (U2 - Ua)) - { - Standard_Real Uc = (U2 + Ua) * 0.5; - Parameters (nbp - 1) = Uc; - Points (nbp - 1) = Value (C, Uc); - } - } -} - - -//======================================================================= -//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; -} - - -static GCPnts_DeflectionType GetDefType (const TheCurve& C) -{ - if (C.NbIntervals (GeomAbs_C2) > 1) - return GCPnts_DefComposite; - - switch (C.GetType()) - { - case GeomAbs_Line: return GCPnts_Linear; - case GeomAbs_Circle: return GCPnts_Circular; - case GeomAbs_BSplineCurve: - { - Handle_TheBSplineCurve aBSpline = C.BSpline(); - return (aBSpline->NbPoles() == 2) ? GCPnts_Linear : GCPnts_Curved; - } - case GeomAbs_BezierCurve: - { - Handle_TheBezierCurve aBezier = C.Bezier(); - return (aBezier->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 Standard_Boolean WithControl) -{ - CPnts_UniformDeflection Iterator (C, Deflection, U1, U2, EPSILON, WithControl); - for(; Iterator.More(); Iterator.Next()) - { - Parameters.Append (Iterator.Value()); - Points.Append (Iterator.Point()); - } - return Iterator.IsAllDone(); -} - - -//======================================================================= -//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 Standard_Boolean WithControl) -{ - 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, WithControl)) - { - 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_UniformDeflection -//purpose : -//======================================================================= -GCPnts_UniformDeflection::GCPnts_UniformDeflection (const TheCurve& C, - const Standard_Real Deflection, - const Standard_Real U1, - const Standard_Real U2, - const Standard_Boolean WithControl) -{ - Initialize (C, Deflection, U1, U2, WithControl); -} - - -//======================================================================= -//function : GCPnts_UniformDeflection -//purpose : -//======================================================================= -GCPnts_UniformDeflection::GCPnts_UniformDeflection (const TheCurve& C, - const Standard_Real Deflection, - const Standard_Boolean WithControl) -{ - Initialize(C, Deflection, WithControl); -} - - -//======================================================================= -//function : Initialize -//purpose : -//======================================================================= -void GCPnts_UniformDeflection::Initialize (const TheCurve& C, - const Standard_Real Deflection, - const Standard_Boolean WithControl) -{ - Initialize (C, Deflection, C.FirstParameter(), C.LastParameter(), WithControl); -} - - -//======================================================================= -//function : Initialize -//purpose : -//======================================================================= -void GCPnts_UniformDeflection::Initialize (const TheCurve& C, - const Standard_Real Deflection, - const Standard_Real theU1, - const Standard_Real theU2, - const Standard_Boolean WithControl) -{ - Standard_Real EPSILON = C.Resolution (Precision::Confusion()); - myDeflection = Deflection; - myDone = Standard_False; - myParams.Clear(); - myPoints.Clear(); - Standard_Real U1 = Min (theU1, theU2); - Standard_Real U2 = Max (theU1, theU2); - GCPnts_DeflectionType Type = GetDefType (C); - 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, WithControl); - break; - case GCPnts_DefComposite: - myDone = PerformComposite (myParams, myPoints, C, Deflection, - U1, U2, EPSILON, WithControl); - break; - } - - // controle des derniers points: - Controle (C, myParams, myPoints, U2); -}