1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-24 13:50:49 +03:00

0026838: Using GeomEvaluators for calculation of values of curves

1. Implemented evaluators for 2D and 3D offset curves
2. Removed obsolete namespace CSLib_Offset

Update of UDLIST (adding no-cdl-pack Geom2dEvaluator)

Update TKG2d/CMakeLists.txt after rebase

Correction compilation in debug mode
This commit is contained in:
azv
2015-11-06 08:49:50 +03:00
committed by bugmaster
parent badc9305ae
commit d660a72aca
22 changed files with 1693 additions and 2084 deletions

View File

@@ -16,7 +16,6 @@
// modified by Edward AGAPOV (eap) Jan 28 2002 --- DN(), occ143(BUC60654)
#include <CSLib_Offset.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_Circle.hxx>
@@ -42,28 +41,9 @@
#include <Standard_RangeError.hxx>
#include <Standard_Type.hxx>
typedef Geom2d_OffsetCurve OffsetCurve;
typedef Geom2d_Curve Curve;
typedef gp_Dir2d Dir2d;
typedef gp_Pnt2d Pnt2d;
typedef gp_Vec2d Vec2d;
typedef gp_Trsf2d Trsf2d;
typedef gp_XY XY;
//ordre de derivation maximum pour la recherche de la premiere
//derivee non nulle
static const int maxDerivOrder = 3;
static const Standard_Real MinStep = 1e-7;
static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();
static gp_Vec2d dummyDerivative; // used as empty value for unused derivatives in AdjustDerivative
// Recalculate derivatives in the singular point
// Returns true if the direction of derivatives is changed
static Standard_Boolean AdjustDerivative(const Handle(Geom2d_Curve)& theCurve, Standard_Integer theMaxDerivative,
Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2 = dummyDerivative,
gp_Vec2d& theD3 = dummyDerivative, gp_Vec2d& theD4 = dummyDerivative);
//=======================================================================
//function : Copy
@@ -73,7 +53,7 @@ static Standard_Boolean AdjustDerivative(const Handle(Geom2d_Curve)& theCurve, S
Handle(Geom2d_Geometry) Geom2d_OffsetCurve::Copy () const
{
Handle(Geom2d_OffsetCurve) C;
C = new OffsetCurve (basisCurve, offsetValue);
C = new Geom2d_OffsetCurve (basisCurve, offsetValue);
return C;
}
@@ -177,6 +157,7 @@ void Geom2d_OffsetCurve::SetBasisCurve (const Handle(Geom2d_Curve)& C,
basisCurve = aCheckingCurve;
}
myEvaluator = new Geom2dEvaluator_OffsetCurve(basisCurve, offsetValue);
}
//=======================================================================
@@ -184,7 +165,11 @@ void Geom2d_OffsetCurve::SetBasisCurve (const Handle(Geom2d_Curve)& C,
//purpose :
//=======================================================================
void Geom2d_OffsetCurve::SetOffsetValue (const Standard_Real D) { offsetValue = D; }
void Geom2d_OffsetCurve::SetOffsetValue (const Standard_Real D)
{
offsetValue = D;
myEvaluator->SetOffsetValue(offsetValue);
}
//=======================================================================
//function : BasisCurve
@@ -223,37 +208,18 @@ GeomAbs_Shape Geom2d_OffsetCurve::Continuity () const
//=======================================================================
void Geom2d_OffsetCurve::D0 (const Standard_Real theU,
Pnt2d& theP) const
{
Vec2d vD1;
basisCurve->D1 (theU, theP, vD1);
Standard_Boolean IsDirectionChange = Standard_False;
if(vD1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 1, theU, vD1);
CSLib_Offset::D0(theP, vD1, offsetValue, IsDirectionChange, theP);
gp_Pnt2d& theP) const
{
myEvaluator->D0(theU, theP);
}
//=======================================================================
//function : D1
//purpose :
//=======================================================================
void Geom2d_OffsetCurve::D1 (const Standard_Real theU, Pnt2d& theP, Vec2d& theV1) const
void Geom2d_OffsetCurve::D1 (const Standard_Real theU, gp_Pnt2d& theP, gp_Vec2d& theV1) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
Vec2d V2;
basisCurve->D2 (theU, theP, theV1, V2);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 2, theU, theV1, V2);
CSLib_Offset::D1(theP, theV1, V2, offsetValue, IsDirectionChange, theP, theV1);
myEvaluator->D1(theU, theP, theV1);
}
//=======================================================================
@@ -262,25 +228,10 @@ void Geom2d_OffsetCurve::D1 (const Standard_Real theU, Pnt2d& theP, Vec2d& theV1
//=======================================================================
void Geom2d_OffsetCurve::D2 (const Standard_Real theU,
Pnt2d& theP,
Vec2d& theV1, Vec2d& theV2) const
gp_Pnt2d& theP,
gp_Vec2d& theV1, gp_Vec2d& theV2) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
Vec2d V3;
basisCurve->D3 (theU, theP, theV1, theV2, V3);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 3, theU, theV1, theV2, V3);
CSLib_Offset::D2(theP, theV1, theV2, V3, offsetValue, IsDirectionChange, theP, theV1, theV2);
myEvaluator->D2(theU, theP, theV1, theV2);
}
@@ -290,32 +241,10 @@ void Geom2d_OffsetCurve::D2 (const Standard_Real theU,
//=======================================================================
void Geom2d_OffsetCurve::D3 (const Standard_Real theU,
Pnt2d& theP,
Vec2d& theV1, Vec2d& theV2, Vec2d& theV3) const
gp_Pnt2d& theP,
gp_Vec2d& theV1, gp_Vec2d& theV2, gp_Vec2d& theV3) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
//P"'(u) = p"'(u) + (Offset / R) * (D3Ndir - (3.0 * Dr/R**2 ) * D2Ndir -
// (3.0 * D2r / R2) * DNdir) + (3.0 * Dr * Dr / R4) * DNdir -
// (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
// (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
basisCurve->D3 (theU, theP, theV1, theV2, theV3);
Vec2d V4 = basisCurve->DN (theU, 4);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 4, theU, theV1, theV2, theV3, V4);
CSLib_Offset::D3(theP, theV1, theV2, theV3, V4, offsetValue, IsDirectionChange,
theP, theV1, theV2, theV3);
myEvaluator->D3(theU, theP, theV1, theV2, theV3);
}
//=======================================================================
@@ -323,10 +252,10 @@ void Geom2d_OffsetCurve::D3 (const Standard_Real theU,
//purpose :
//=======================================================================
Vec2d Geom2d_OffsetCurve::DN (const Standard_Real U,
const Standard_Integer N) const
gp_Vec2d Geom2d_OffsetCurve::DN (const Standard_Real U,
const Standard_Integer N) const
{
Standard_RangeError_Raise_if (N < 1, "Exception: Geom2d_OffsetCurve::DN(). N<1.");
Standard_RangeError_Raise_if (N < 1, "Exception: Geom2d_OffsetCurve::DN(). N<1.");
gp_Vec2d VN, VBidon;
gp_Pnt2d PBidon;
@@ -342,88 +271,6 @@ Standard_RangeError_Raise_if (N < 1, "Exception: Geom2d_OffsetCurve::DN(). N<1."
return VN;
}
//=======================================================================
//function : Value
//purpose :
//=======================================================================
void Geom2d_OffsetCurve::Value (const Standard_Real theU,
Pnt2d& theP, Pnt2d& thePbasis,
Vec2d& theV1basis ) const
{
basisCurve->D1(theU, thePbasis, theV1basis);
D0(theU,theP);
}
//=======================================================================
//function : D1
//purpose :
//=======================================================================
void Geom2d_OffsetCurve::D1 (const Standard_Real U,
Pnt2d& P, Pnt2d& Pbasis,
Vec2d& V1, Vec2d& V1basis,
Vec2d& V2basis ) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
basisCurve->D2 (U, Pbasis, V1basis, V2basis);
V1 = V1basis;
Vec2d V2 = V2basis;
Standard_Integer Index = 2;
while (V1.Magnitude() <= gp::Resolution() && Index <= maxDerivOrder) {
V1 = basisCurve->DN (U, Index);
Index++;
}
if (Index != 2) {
V2 = basisCurve->DN (U, Index);
}
CSLib_Offset::D1(P, V1, V2, offsetValue, Standard_False, P, V1);
}
//=======================================================================
//function : D2
//purpose :
//=======================================================================
void Geom2d_OffsetCurve::D2 (const Standard_Real U,
Pnt2d& P, Pnt2d& Pbasis,
Vec2d& V1, Vec2d& V2,
Vec2d& V1basis, Vec2d& V2basis,
Vec2d& V3basis ) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
basisCurve->D3 (U, Pbasis, V1basis, V2basis, V3basis);
Standard_Integer Index = 2;
V1 = V1basis;
V2 = V2basis;
Vec2d V3 = V3basis;
while (V1.Magnitude() <= gp::Resolution() && Index <= maxDerivOrder) {
V1 = basisCurve->DN (U, Index);
Index++;
}
if (Index != 2) {
V2 = basisCurve->DN (U, Index);
V3 = basisCurve->DN (U, Index + 1);
}
CSLib_Offset::D2(P, V1, V2, V3, offsetValue, Standard_False, P, V1, V2);
}
//=======================================================================
//function : FirstParameter
//purpose :
@@ -450,7 +297,8 @@ Standard_Real Geom2d_OffsetCurve::LastParameter () const
//purpose :
//=======================================================================
Standard_Real Geom2d_OffsetCurve::Offset () const { return offsetValue; }
Standard_Real Geom2d_OffsetCurve::Offset () const
{ return offsetValue; }
//=======================================================================
//function : IsClosed
@@ -501,10 +349,12 @@ Standard_Real Geom2d_OffsetCurve::Period() const
//purpose :
//=======================================================================
void Geom2d_OffsetCurve::Transform (const Trsf2d& T)
void Geom2d_OffsetCurve::Transform (const gp_Trsf2d& T)
{
basisCurve->Transform (T);
offsetValue *= Abs(T.ScaleFactor());
myEvaluator->SetOffsetValue(offsetValue);
}
@@ -537,57 +387,3 @@ GeomAbs_Shape Geom2d_OffsetCurve::GetBasisCurveContinuity() const
{
return myBasisCurveContinuity;
}
// ============= Auxiliary functions ===================
Standard_Boolean AdjustDerivative(const Handle(Geom2d_Curve)& theCurve, Standard_Integer theMaxDerivative,
Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2,
gp_Vec2d& theD3, gp_Vec2d& theD4)
{
static const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False;
const Standard_Real anUinfium = theCurve->FirstParameter();
const Standard_Real anUsupremum = theCurve->LastParameter();
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum - anUinfium;
const Standard_Real aDelta = Max(du * DivisionFactor, MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
Vec2d V;
do
{
V = theCurve->DN(theU, ++anIndex);
}
while((V.SquareMagnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
Pnt2d P1, P2;
theCurve->D0(Min(theU, u),P1);
theCurve->D0(Max(theU, u),P2);
Vec2d V1(P1,P2);
IsDirectionChange = V.Dot(V1) < 0.0;
Standard_Real aSign = IsDirectionChange ? -1.0 : 1.0;
theD1 = V * aSign;
gp_Vec2d* aDeriv[3] = {&theD2, &theD3, &theD4};
for (Standard_Integer i = 1; i < theMaxDerivative; i++)
*(aDeriv[i-1]) = theCurve->DN(theU, anIndex + i) * aSign;
return IsDirectionChange;
}

View File

@@ -25,6 +25,8 @@
#include <Geom2d_Curve.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_Integer.hxx>
#include <Geom2dEvaluator_OffsetCurve.hxx>
class Geom2d_Curve;
class Standard_ConstructionError;
class Standard_RangeError;
@@ -204,28 +206,15 @@ public:
//! raised if it is not possible to compute a unique offset direction.
Standard_EXPORT gp_Vec2d DN (const Standard_Real U, const Standard_Integer N) const Standard_OVERRIDE;
//! Warning! this should not be called
//! if the basis curve is not at least C1. Nevertheless
//! if used on portion where the curve is C1, it is OK
Standard_EXPORT void Value (const Standard_Real U, gp_Pnt2d& P, gp_Pnt2d& Pbasis, gp_Vec2d& V1basis) const;
//! Warning! this should not be called
//! if the continuity of the basis curve is not C1.
//! Nevertheless, it's OK to use it on portion
//! where the curve is C1
Standard_EXPORT void D1 (const Standard_Real U, gp_Pnt2d& P, gp_Pnt2d& Pbasis, gp_Vec2d& V1, gp_Vec2d& V1basis, gp_Vec2d& V2basis) const;
//! Warning! this should not be called
//! if the continuity of the basis curve is not C3.
//! Nevertheless, it's OK to use it on portion
//! where the curve is C3
Standard_EXPORT void D2 (const Standard_Real U, gp_Pnt2d& P, gp_Pnt2d& Pbasis, gp_Vec2d& V1, gp_Vec2d& V2, gp_Vec2d& V1basis, gp_Vec2d& V2basis, gp_Vec2d& V3basis) const;
Standard_EXPORT Standard_Real FirstParameter() const Standard_OVERRIDE;
//! Returns the value of the first or last parameter of this
//! Returns the value of the first parameter of this
//! offset curve. The first parameter corresponds to the
//! start point of the curve. The last parameter
//! start point of the curve.
//! Note: the first and last parameters of this offset curve
//! are also the ones of its basis curve.
Standard_EXPORT Standard_Real FirstParameter() const Standard_OVERRIDE;
//! Returns the value of the last parameter of this
//! offset curve. The last parameter
//! corresponds to the end point.
//! Note: the first and last parameters of this offset curve
//! are also the ones of its basis curve.
@@ -312,7 +301,7 @@ private:
Handle(Geom2d_Curve) basisCurve;
Standard_Real offsetValue;
GeomAbs_Shape myBasisCurveContinuity;
Handle(Geom2dEvaluator_OffsetCurve) myEvaluator;
};