Modeling - Refactor extrusion and revolution Utils to accept pre-computed curve values (#948)

Refactored Geom_ExtrusionUtils.pxx and Geom_RevolutionUtils.pxx to provide
Calculate* functions that accept pre-computed curve values (point, D1, D2, D3).
This follows the pattern established in Geom_OffsetSurfaceUtils.pxx.

Changes:
- Added CalculateD0/D1/D2/D3/DN functions to both Utils files that work with
  pre-computed curve data instead of requiring curve objects with methods
- Updated template functions D0/D1/D2/D3/DN to call the Calculate functions,
  eliminating code duplication within the Utils files
- Updated GeomGridEval_SurfaceOfExtrusion to use Geom_ExtrusionUtils::Calculate*
- Updated GeomGridEval_SurfaceOfRevolution to use Geom_RevolutionUtils::Calculate*
- Fixed bug in GeomGridEval_BSplineSurface::prepare() where out-of-bounds
  parameters were not properly stored after clamping by BSplCLib::LocateParameter()

This refactoring ensures a single source of truth for surface evaluation formulas,
fixing potential regression from commit 5870232236 where duplicated formulas in
GeomGridEval implementations could diverge from the canonical Utils implementations.
This commit is contained in:
Pasukhin Dmitry
2025-12-23 22:38:05 +00:00
committed by GitHub
parent 8491bf4cee
commit bb0d8200fa
5 changed files with 588 additions and 353 deletions

View File

@@ -21,16 +21,147 @@
//! @file Geom_ExtrusionUtils.pxx
//! @brief Shared utility functions for extrusion surface evaluation.
//!
//! This file provides template functions for evaluating points and derivatives
//! on linear extrusion surfaces. The functions are templated to work with both
//! Geom_Curve (for Geom_SurfaceOfLinearExtrusion) and Adaptor3d_Curve
//! (for GeomAdaptor_SurfaceOfLinearExtrusion).
//! This file provides both direct calculation functions (accepting pre-computed curve values)
//! and template functions for evaluating points and derivatives on linear extrusion surfaces.
//! The template functions work with both Geom_Curve (for Geom_SurfaceOfLinearExtrusion)
//! and Adaptor3d_Curve (for GeomAdaptor_SurfaceOfLinearExtrusion).
//!
//! Extrusion surface: P(U,V) = C(U) + V * Direction
namespace Geom_ExtrusionUtils
{
//! Calculates point on extrusion surface from pre-computed curve point.
//! @param theCurvePt Pre-computed curve point C(U)
//! @param theV Parameter along the extrusion direction
//! @param theDir Extrusion direction XYZ (must be normalized)
//! @param theP [out] Evaluated surface point
inline void CalculateD0(const gp_Pnt& theCurvePt,
const double theV,
const gp_XYZ& theDir,
gp_Pnt& theP)
{
theP.SetXYZ(theCurvePt.XYZ() + theV * theDir);
}
//! Calculates point and first derivatives on extrusion surface from pre-computed curve D1.
//! @param theCurvePt Pre-computed curve point C(U)
//! @param theCurveD1 Pre-computed curve first derivative C'(U)
//! @param theV Parameter along the extrusion direction
//! @param theDir Extrusion direction XYZ (must be normalized)
//! @param theP [out] Evaluated surface point
//! @param theD1U [out] First derivative with respect to U
//! @param theD1V [out] First derivative with respect to V
inline void CalculateD1(const gp_Pnt& theCurvePt,
const gp_Vec& theCurveD1,
const double theV,
const gp_XYZ& theDir,
gp_Pnt& theP,
gp_Vec& theD1U,
gp_Vec& theD1V)
{
theP.SetXYZ(theCurvePt.XYZ() + theV * theDir);
theD1U = theCurveD1;
theD1V.SetXYZ(theDir);
}
//! Calculates point, first and second derivatives on extrusion surface from pre-computed curve D2.
//! @param theCurvePt Pre-computed curve point C(U)
//! @param theCurveD1 Pre-computed curve first derivative C'(U)
//! @param theCurveD2 Pre-computed curve second derivative C''(U)
//! @param theV Parameter along the extrusion direction
//! @param theDir Extrusion direction XYZ (must be normalized)
//! @param theP [out] Evaluated surface point
//! @param theD1U [out] First derivative with respect to U
//! @param theD1V [out] First derivative with respect to V
//! @param theD2U [out] Second derivative with respect to U
//! @param theD2V [out] Second derivative with respect to V (always zero)
//! @param theD2UV [out] Mixed second derivative (always zero)
inline void CalculateD2(const gp_Pnt& theCurvePt,
const gp_Vec& theCurveD1,
const gp_Vec& theCurveD2,
const double theV,
const gp_XYZ& theDir,
gp_Pnt& theP,
gp_Vec& theD1U,
gp_Vec& theD1V,
gp_Vec& theD2U,
gp_Vec& theD2V,
gp_Vec& theD2UV)
{
theP.SetXYZ(theCurvePt.XYZ() + theV * theDir);
theD1U = theCurveD1;
theD1V.SetXYZ(theDir);
theD2U = theCurveD2;
theD2V.SetCoord(0.0, 0.0, 0.0);
theD2UV.SetCoord(0.0, 0.0, 0.0);
}
//! Calculates point and derivatives up to third order on extrusion surface from pre-computed curve
//! D3.
//! @param theCurvePt Pre-computed curve point C(U)
//! @param theCurveD1 Pre-computed curve first derivative C'(U)
//! @param theCurveD2 Pre-computed curve second derivative C''(U)
//! @param theCurveD3 Pre-computed curve third derivative C'''(U)
//! @param theV Parameter along the extrusion direction
//! @param theDir Extrusion direction XYZ (must be normalized)
//! @param theP [out] Evaluated surface point
//! @param theD1U [out] First derivative with respect to U
//! @param theD1V [out] First derivative with respect to V
//! @param theD2U [out] Second derivative with respect to U
//! @param theD2V [out] Second derivative with respect to V (always zero)
//! @param theD2UV [out] Mixed second derivative (always zero)
//! @param theD3U [out] Third derivative with respect to U
//! @param theD3V [out] Third derivative with respect to V (always zero)
//! @param theD3UUV [out] Mixed third derivative (UUV) (always zero)
//! @param theD3UVV [out] Mixed third derivative (UVV) (always zero)
inline void CalculateD3(const gp_Pnt& theCurvePt,
const gp_Vec& theCurveD1,
const gp_Vec& theCurveD2,
const gp_Vec& theCurveD3,
const double theV,
const gp_XYZ& theDir,
gp_Pnt& theP,
gp_Vec& theD1U,
gp_Vec& theD1V,
gp_Vec& theD2U,
gp_Vec& theD2V,
gp_Vec& theD2UV,
gp_Vec& theD3U,
gp_Vec& theD3V,
gp_Vec& theD3UUV,
gp_Vec& theD3UVV)
{
theP.SetXYZ(theCurvePt.XYZ() + theV * theDir);
theD1U = theCurveD1;
theD1V.SetXYZ(theDir);
theD2U = theCurveD2;
theD2V.SetCoord(0.0, 0.0, 0.0);
theD2UV.SetCoord(0.0, 0.0, 0.0);
theD3U = theCurveD3;
theD3V.SetCoord(0.0, 0.0, 0.0);
theD3UUV.SetCoord(0.0, 0.0, 0.0);
theD3UVV.SetCoord(0.0, 0.0, 0.0);
}
//! Calculates N-th derivative on extrusion surface from pre-computed curve derivative.
//! @param theCurveDN Pre-computed curve N-th derivative C^(theDerU)(U)
//! @param theDir Extrusion direction XYZ (must be normalized)
//! @param theDerU Derivative order with respect to U
//! @param theDerV Derivative order with respect to V
//! @return The derivative vector
inline gp_Vec CalculateDN(const gp_Vec& theCurveDN,
const gp_XYZ& theDir,
const int theDerU,
const int theDerV)
{
if (theDerV == 0)
return theCurveDN;
else if (theDerU == 0 && theDerV == 1)
return gp_Vec(theDir);
return gp_Vec(0.0, 0.0, 0.0);
}
//! Evaluates point on extrusion surface.
//! @tparam CurveType Type supporting D0(param, point) method
//! @param theU Parameter along the basis curve
@@ -45,8 +176,9 @@ inline void D0(const double theU,
const gp_XYZ& theDir,
gp_Pnt& theP)
{
theBasis.D0(theU, theP);
theP.SetXYZ(theP.XYZ() + theV * theDir);
gp_Pnt aCurvePt;
theBasis.D0(theU, aCurvePt);
CalculateD0(aCurvePt, theV, theDir, theP);
}
//! Evaluates point and first derivatives on extrusion surface.
@@ -67,9 +199,10 @@ inline void D1(const double theU,
gp_Vec& theD1U,
gp_Vec& theD1V)
{
theBasis.D1(theU, theP, theD1U);
theP.SetXYZ(theP.XYZ() + theV * theDir);
theD1V.SetXYZ(theDir);
gp_Pnt aCurvePt;
gp_Vec aCurveD1;
theBasis.D1(theU, aCurvePt, aCurveD1);
CalculateD1(aCurvePt, aCurveD1, theV, theDir, theP, theD1U, theD1V);
}
//! Evaluates point, first and second derivatives on extrusion surface.
@@ -96,11 +229,20 @@ inline void D2(const double theU,
gp_Vec& theD2V,
gp_Vec& theD2UV)
{
theBasis.D2(theU, theP, theD1U, theD2U);
theP.SetXYZ(theP.XYZ() + theV * theDir);
theD1V.SetXYZ(theDir);
theD2V.SetCoord(0.0, 0.0, 0.0);
theD2UV.SetCoord(0.0, 0.0, 0.0);
gp_Pnt aCurvePt;
gp_Vec aCurveD1, aCurveD2;
theBasis.D2(theU, aCurvePt, aCurveD1, aCurveD2);
CalculateD2(aCurvePt,
aCurveD1,
aCurveD2,
theV,
theDir,
theP,
theD1U,
theD1V,
theD2U,
theD2V,
theD2UV);
}
//! Evaluates point, first, second and third derivatives on extrusion surface.
@@ -135,14 +277,25 @@ inline void D3(const double theU,
gp_Vec& theD3UUV,
gp_Vec& theD3UVV)
{
theBasis.D3(theU, theP, theD1U, theD2U, theD3U);
theP.SetXYZ(theP.XYZ() + theV * theDir);
theD1V.SetXYZ(theDir);
theD2V.SetCoord(0.0, 0.0, 0.0);
theD2UV.SetCoord(0.0, 0.0, 0.0);
theD3V.SetCoord(0.0, 0.0, 0.0);
theD3UUV.SetCoord(0.0, 0.0, 0.0);
theD3UVV.SetCoord(0.0, 0.0, 0.0);
gp_Pnt aCurvePt;
gp_Vec aCurveD1, aCurveD2, aCurveD3;
theBasis.D3(theU, aCurvePt, aCurveD1, aCurveD2, aCurveD3);
CalculateD3(aCurvePt,
aCurveD1,
aCurveD2,
aCurveD3,
theV,
theDir,
theP,
theD1U,
theD1V,
theD2U,
theD2V,
theD2UV,
theD3U,
theD3V,
theD3UUV,
theD3UVV);
}
//! Evaluates N-th derivative on extrusion surface.
@@ -160,11 +313,8 @@ inline gp_Vec DN(const double theU,
const int theDerU,
const int theDerV)
{
if (theDerV == 0)
return theBasis.DN(theU, theDerU);
else if (theDerU == 0 && theDerV == 1)
return gp_Vec(theDir);
return gp_Vec(0.0, 0.0, 0.0);
gp_Vec aCurveDN = (theDerV == 0) ? theBasis.DN(theU, theDerU) : gp_Vec();
return CalculateDN(aCurveDN, theDir, theDerU, theDerV);
}
} // namespace Geom_ExtrusionUtils

View File

@@ -23,10 +23,10 @@
//! @file Geom_RevolutionUtils.pxx
//! @brief Shared utility functions for surface of revolution evaluation.
//!
//! This file provides template functions for evaluating points and derivatives
//! on surfaces of revolution. The functions are templated to work with both
//! Geom_Curve (for Geom_SurfaceOfRevolution) and Adaptor3d_Curve
//! (for GeomAdaptor_SurfaceOfRevolution).
//! This file provides both direct calculation functions (accepting pre-computed curve values)
//! and template functions for evaluating points and derivatives on surfaces of revolution.
//! The template functions work with both Geom_Curve (for Geom_SurfaceOfRevolution)
//! and Adaptor3d_Curve (for GeomAdaptor_SurfaceOfRevolution).
//!
//! Revolution surface: P(U,V) = Rotation(Axis, U) * BasisCurve(V)
//! where U is the rotation angle and V is the parameter along the basis curve.
@@ -34,6 +34,235 @@
namespace Geom_RevolutionUtils
{
//! Calculates point on surface of revolution from pre-computed curve point.
//! @param theCurvePt Pre-computed curve point C(V)
//! @param theU Rotation angle parameter
//! @param theAxis Rotation axis
//! @param theP [out] Evaluated surface point
inline void CalculateD0(const gp_Pnt& theCurvePt,
const double theU,
const gp_Ax1& theAxis,
gp_Pnt& theP)
{
theP = theCurvePt;
gp_Trsf aRotation;
aRotation.SetRotation(theAxis, theU);
theP.Transform(aRotation);
}
//! Calculates point and first derivatives on surface of revolution from pre-computed curve D1.
//! @param theCurvePt Pre-computed curve point C(V)
//! @param theCurveD1 Pre-computed curve first derivative C'(V)
//! @param theU Rotation angle parameter
//! @param theAxis Rotation axis
//! @param theP [out] Evaluated surface point
//! @param theD1U [out] First derivative with respect to U (rotation)
//! @param theD1V [out] First derivative with respect to V (along curve)
inline void CalculateD1(const gp_Pnt& theCurvePt,
const gp_Vec& theCurveD1,
const double theU,
const gp_Ax1& theAxis,
gp_Pnt& theP,
gp_Vec& theD1U,
gp_Vec& theD1V)
{
theP = theCurvePt;
// Vector from center of rotation to the point on rotated curve
gp_XYZ aCQ = theCurvePt.XYZ() - theAxis.Location().XYZ();
theD1U = gp_Vec(theAxis.Direction().XYZ().Crossed(aCQ));
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (theD1U.SquareMagnitude() < Precision::SquareConfusion())
{
theD1U.SetCoord(0.0, 0.0, 0.0);
}
gp_Trsf aRotation;
aRotation.SetRotation(theAxis, theU);
theP.Transform(aRotation);
theD1U.Transform(aRotation);
theD1V = theCurveD1;
theD1V.Transform(aRotation);
}
//! Calculates point, first and second derivatives on surface of revolution from pre-computed curve
//! D2.
//! @param theCurvePt Pre-computed curve point C(V)
//! @param theCurveD1 Pre-computed curve first derivative C'(V)
//! @param theCurveD2 Pre-computed curve second derivative C''(V)
//! @param theU Rotation angle parameter
//! @param theAxis Rotation axis
//! @param theP [out] Evaluated surface point
//! @param theD1U [out] First derivative with respect to U
//! @param theD1V [out] First derivative with respect to V
//! @param theD2U [out] Second derivative with respect to U
//! @param theD2V [out] Second derivative with respect to V
//! @param theD2UV [out] Mixed second derivative
inline void CalculateD2(const gp_Pnt& theCurvePt,
const gp_Vec& theCurveD1,
const gp_Vec& theCurveD2,
const double theU,
const gp_Ax1& theAxis,
gp_Pnt& theP,
gp_Vec& theD1U,
gp_Vec& theD1V,
gp_Vec& theD2U,
gp_Vec& theD2V,
gp_Vec& theD2UV)
{
theP = theCurvePt;
// Vector from center of rotation to the point on rotated curve
gp_XYZ aCQ = theCurvePt.XYZ() - theAxis.Location().XYZ();
const gp_XYZ& aDir = theAxis.Direction().XYZ();
theD1U = gp_Vec(aDir.Crossed(aCQ));
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (theD1U.SquareMagnitude() < Precision::SquareConfusion())
{
theD1U.SetCoord(0.0, 0.0, 0.0);
}
theD2U = gp_Vec(aDir.Dot(aCQ) * aDir - aCQ);
theD2UV = gp_Vec(aDir.Crossed(theCurveD1.XYZ()));
gp_Trsf aRotation;
aRotation.SetRotation(theAxis, theU);
theP.Transform(aRotation);
theD1U.Transform(aRotation);
theD1V = theCurveD1;
theD1V.Transform(aRotation);
theD2U.Transform(aRotation);
theD2V = theCurveD2;
theD2V.Transform(aRotation);
theD2UV.Transform(aRotation);
}
//! Calculates point and all derivatives up to third order on surface of revolution from
//! pre-computed curve D3.
//! @param theCurvePt Pre-computed curve point C(V)
//! @param theCurveD1 Pre-computed curve first derivative C'(V)
//! @param theCurveD2 Pre-computed curve second derivative C''(V)
//! @param theCurveD3 Pre-computed curve third derivative C'''(V)
//! @param theU Rotation angle parameter
//! @param theAxis Rotation axis
//! @param theP [out] Evaluated surface point
//! @param theD1U [out] First derivative with respect to U
//! @param theD1V [out] First derivative with respect to V
//! @param theD2U [out] Second derivative with respect to U
//! @param theD2V [out] Second derivative with respect to V
//! @param theD2UV [out] Mixed second derivative
//! @param theD3U [out] Third derivative with respect to U
//! @param theD3V [out] Third derivative with respect to V
//! @param theD3UUV [out] Mixed third derivative (UUV)
//! @param theD3UVV [out] Mixed third derivative (UVV)
inline void CalculateD3(const gp_Pnt& theCurvePt,
const gp_Vec& theCurveD1,
const gp_Vec& theCurveD2,
const gp_Vec& theCurveD3,
const double theU,
const gp_Ax1& theAxis,
gp_Pnt& theP,
gp_Vec& theD1U,
gp_Vec& theD1V,
gp_Vec& theD2U,
gp_Vec& theD2V,
gp_Vec& theD2UV,
gp_Vec& theD3U,
gp_Vec& theD3V,
gp_Vec& theD3UUV,
gp_Vec& theD3UVV)
{
theP = theCurvePt;
// Vector from center of rotation to the point on rotated curve
gp_XYZ aCQ = theCurvePt.XYZ() - theAxis.Location().XYZ();
const gp_XYZ& aDir = theAxis.Direction().XYZ();
theD1U = gp_Vec(aDir.Crossed(aCQ));
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (theD1U.SquareMagnitude() < Precision::SquareConfusion())
{
theD1U.SetCoord(0.0, 0.0, 0.0);
}
theD2U = gp_Vec(aDir.Dot(aCQ) * aDir - aCQ);
theD2UV = gp_Vec(aDir.Crossed(theCurveD1.XYZ()));
theD3U = -theD1U;
theD3UUV = gp_Vec(aDir.Dot(theCurveD1.XYZ()) * aDir - theCurveD1.XYZ());
theD3UVV = gp_Vec(aDir.Crossed(theCurveD2.XYZ()));
gp_Trsf aRotation;
aRotation.SetRotation(theAxis, theU);
theP.Transform(aRotation);
theD1U.Transform(aRotation);
theD1V = theCurveD1;
theD1V.Transform(aRotation);
theD2U.Transform(aRotation);
theD2V = theCurveD2;
theD2V.Transform(aRotation);
theD2UV.Transform(aRotation);
theD3U.Transform(aRotation);
theD3V = theCurveD3;
theD3V.Transform(aRotation);
theD3UUV.Transform(aRotation);
theD3UVV.Transform(aRotation);
}
//! Calculates N-th derivative on surface of revolution from pre-computed curve data.
//! For pure V derivatives (theDerU == 0): uses theCurveDN directly.
//! For mixed or pure U derivatives: uses theCurvePtOrDN as the base vector.
//! @param theCurvePtOrDN For theDerV == 0: curve point C(V); otherwise: curve derivative
//! C^(theDerV)(V)
//! @param theU Rotation angle parameter
//! @param theAxis Rotation axis
//! @param theDerU Derivative order with respect to U
//! @param theDerV Derivative order with respect to V
//! @return The derivative vector
inline gp_Vec CalculateDN(const gp_Vec& theCurvePtOrDN,
const double theU,
const gp_Ax1& theAxis,
const int theDerU,
const int theDerV)
{
// theDerV is part of the interface contract - caller provides different data based on its value
(void)theDerV;
gp_Trsf aRotation;
aRotation.SetRotation(theAxis, theU);
gp_Vec aResult;
if (theDerU == 0)
{
// Pure V derivative: just rotate the curve derivative
aResult = theCurvePtOrDN;
}
else
{
// For theDerV == 0: theCurvePtOrDN is (P - AxisLocation) as a vector
// For theDerV > 0: theCurvePtOrDN is the curve derivative
const gp_XYZ& aDir = theAxis.Direction().XYZ();
if (theDerU % 4 == 1)
{
aResult = gp_Vec(aDir.Crossed(theCurvePtOrDN.XYZ()));
}
else if (theDerU % 4 == 2)
{
aResult = gp_Vec(aDir.Dot(theCurvePtOrDN.XYZ()) * aDir - theCurvePtOrDN.XYZ());
}
else if (theDerU % 4 == 3)
{
aResult = gp_Vec(aDir.Crossed(theCurvePtOrDN.XYZ())) * (-1.0);
}
else
{
aResult = gp_Vec(theCurvePtOrDN.XYZ() - aDir.Dot(theCurvePtOrDN.XYZ()) * aDir);
}
}
aResult.Transform(aRotation);
return aResult;
}
//! Evaluates point on surface of revolution.
//! @tparam CurveType Type supporting D0(param, point) method
//! @param theU Rotation angle parameter
@@ -48,11 +277,9 @@ inline void D0(const double theU,
const gp_Ax1& theAxis,
gp_Pnt& theP)
{
theBasis.D0(theV, theP);
gp_Trsf aRotation;
aRotation.SetRotation(theAxis, theU);
theP.Transform(aRotation);
gp_Pnt aCurvePt;
theBasis.D0(theV, aCurvePt);
CalculateD0(aCurvePt, theU, theAxis, theP);
}
//! Evaluates point and first derivatives on surface of revolution.
@@ -73,23 +300,10 @@ inline void D1(const double theU,
gp_Vec& theD1U,
gp_Vec& theD1V)
{
theBasis.D1(theV, theP, theD1V);
// Vector from center of rotation to the point on rotated curve
gp_XYZ aCQ = theP.XYZ() - theAxis.Location().XYZ();
theD1U = gp_Vec(theAxis.Direction().XYZ().Crossed(aCQ));
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (theD1U.SquareMagnitude() < Precision::SquareConfusion())
{
theD1U.SetCoord(0.0, 0.0, 0.0);
}
gp_Trsf aRotation;
aRotation.SetRotation(theAxis, theU);
theP.Transform(aRotation);
theD1U.Transform(aRotation);
theD1V.Transform(aRotation);
gp_Pnt aCurvePt;
gp_Vec aCurveD1;
theBasis.D1(theV, aCurvePt, aCurveD1);
CalculateD1(aCurvePt, aCurveD1, theU, theAxis, theP, theD1U, theD1V);
}
//! Evaluates point, first and second derivatives on surface of revolution.
@@ -116,29 +330,20 @@ inline void D2(const double theU,
gp_Vec& theD2V,
gp_Vec& theD2UV)
{
theBasis.D2(theV, theP, theD1V, theD2V);
// Vector from center of rotation to the point on rotated curve
gp_XYZ aCQ = theP.XYZ() - theAxis.Location().XYZ();
const gp_XYZ& aDir = theAxis.Direction().XYZ();
theD1U = gp_Vec(aDir.Crossed(aCQ));
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (theD1U.SquareMagnitude() < Precision::SquareConfusion())
{
theD1U.SetCoord(0.0, 0.0, 0.0);
}
theD2U = gp_Vec(aDir.Dot(aCQ) * aDir - aCQ);
theD2UV = gp_Vec(aDir.Crossed(theD1V.XYZ()));
gp_Trsf aRotation;
aRotation.SetRotation(theAxis, theU);
theP.Transform(aRotation);
theD1U.Transform(aRotation);
theD1V.Transform(aRotation);
theD2U.Transform(aRotation);
theD2V.Transform(aRotation);
theD2UV.Transform(aRotation);
gp_Pnt aCurvePt;
gp_Vec aCurveD1, aCurveD2;
theBasis.D2(theV, aCurvePt, aCurveD1, aCurveD2);
CalculateD2(aCurvePt,
aCurveD1,
aCurveD2,
theU,
theAxis,
theP,
theD1U,
theD1V,
theD2U,
theD2V,
theD2UV);
}
//! Evaluates point and all derivatives up to third order on surface of revolution.
@@ -173,36 +378,25 @@ inline void D3(const double theU,
gp_Vec& theD3UUV,
gp_Vec& theD3UVV)
{
theBasis.D3(theV, theP, theD1V, theD2V, theD3V);
// Vector from center of rotation to the point on rotated curve
gp_XYZ aCQ = theP.XYZ() - theAxis.Location().XYZ();
const gp_XYZ& aDir = theAxis.Direction().XYZ();
theD1U = gp_Vec(aDir.Crossed(aCQ));
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (theD1U.SquareMagnitude() < Precision::SquareConfusion())
{
theD1U.SetCoord(0.0, 0.0, 0.0);
}
theD2U = gp_Vec(aDir.Dot(aCQ) * aDir - aCQ);
theD2UV = gp_Vec(aDir.Crossed(theD1V.XYZ()));
theD3U = -theD1U;
theD3UUV = gp_Vec(aDir.Dot(theD1V.XYZ()) * aDir - theD1V.XYZ());
theD3UVV = gp_Vec(aDir.Crossed(theD2V.XYZ()));
gp_Trsf aRotation;
aRotation.SetRotation(theAxis, theU);
theP.Transform(aRotation);
theD1U.Transform(aRotation);
theD1V.Transform(aRotation);
theD2U.Transform(aRotation);
theD2V.Transform(aRotation);
theD2UV.Transform(aRotation);
theD3U.Transform(aRotation);
theD3V.Transform(aRotation);
theD3UUV.Transform(aRotation);
theD3UVV.Transform(aRotation);
gp_Pnt aCurvePt;
gp_Vec aCurveD1, aCurveD2, aCurveD3;
theBasis.D3(theV, aCurvePt, aCurveD1, aCurveD2, aCurveD3);
CalculateD3(aCurvePt,
aCurveD1,
aCurveD2,
aCurveD3,
theU,
theAxis,
theP,
theD1U,
theD1V,
theD2U,
theD2V,
theD2UV,
theD3U,
theD3V,
theD3UUV,
theD3UVV);
}
//! Evaluates N-th derivative on surface of revolution.
@@ -222,49 +416,23 @@ inline gp_Vec DN(const double theU,
const int theDerU,
const int theDerV)
{
gp_Trsf aRotation;
aRotation.SetRotation(theAxis, theU);
gp_Pnt aP;
gp_Vec aDV;
gp_Vec aResult;
gp_Vec aCurvePtOrDN;
if (theDerU == 0)
{
aResult = theBasis.DN(theV, theDerV);
aCurvePtOrDN = theBasis.DN(theV, theDerV);
}
else if (theDerV == 0)
{
gp_Pnt aP;
theBasis.D0(theV, aP);
aCurvePtOrDN = gp_Vec(aP.XYZ() - theAxis.Location().XYZ());
}
else
{
if (theDerV == 0)
{
theBasis.D0(theV, aP);
aDV = gp_Vec(aP.XYZ() - theAxis.Location().XYZ());
}
else
{
aDV = theBasis.DN(theV, theDerV);
}
const gp_XYZ& aDir = theAxis.Direction().XYZ();
if (theDerU % 4 == 1)
{
aResult = gp_Vec(aDir.Crossed(aDV.XYZ()));
}
else if (theDerU % 4 == 2)
{
aResult = gp_Vec(aDir.Dot(aDV.XYZ()) * aDir - aDV.XYZ());
}
else if (theDerU % 4 == 3)
{
aResult = gp_Vec(aDir.Crossed(aDV.XYZ())) * (-1.0);
}
else
{
aResult = gp_Vec(aDV.XYZ() - aDir.Dot(aDV.XYZ()) * aDir);
}
aCurvePtOrDN = theBasis.DN(theV, theDerV);
}
aResult.Transform(aRotation);
return aResult;
return CalculateDN(aCurvePtOrDN, theU, theAxis, theDerU, theDerV);
}
} // namespace Geom_RevolutionUtils

View File

@@ -189,7 +189,7 @@ void GeomGridEval_BSplineSurface::prepare() const
const double aSpanMid = aSpanStart + aSpanHalfLen;
const double aLocalParam = (aParam - aSpanMid) / aSpanHalfLen;
myUParams.SetValue(i - 1, ParamWithSpan{myRawUParams.Value(i), aLocalParam, aSpanIdx});
myUParams.SetValue(i - 1, ParamWithSpan{aParam, aLocalParam, aSpanIdx});
}
// Process V parameters
@@ -207,7 +207,7 @@ void GeomGridEval_BSplineSurface::prepare() const
const double aSpanMid = aSpanStart + aSpanHalfLen;
const double aLocalParam = (aParam - aSpanMid) / aSpanHalfLen;
myVParams.SetValue(j - 1, ParamWithSpan{myRawVParams.Value(j), aLocalParam, aSpanIdx});
myVParams.SetValue(j - 1, ParamWithSpan{aParam, aLocalParam, aSpanIdx});
}
// Compute span ranges

View File

@@ -13,6 +13,8 @@
#include <GeomGridEval_SurfaceOfExtrusion.hxx>
#include <Geom_ExtrusionUtils.pxx>
//==================================================================================================
GeomGridEval_SurfaceOfExtrusion::GeomGridEval_SurfaceOfExtrusion(
@@ -77,11 +79,13 @@ NCollection_Array2<gp_Pnt> GeomGridEval_SurfaceOfExtrusion::EvaluateGrid() const
for (int i = 1; i <= aNbU; ++i)
{
const gp_XYZ& aCurvePt = aCurvePoints.Value(i).XYZ();
const gp_Pnt& aCurvePt = aCurvePoints.Value(i);
for (int j = 1; j <= aNbV; ++j)
{
const double aV = myVParams.Value(j);
aResult.SetValue(i, j, gp_Pnt(aCurvePt + aV * aDirXYZ));
gp_Pnt aP;
Geom_ExtrusionUtils::CalculateD0(aCurvePt, aV, aDirXYZ, aP);
aResult.SetValue(i, j, aP);
}
}
@@ -113,19 +117,25 @@ NCollection_Array2<GeomGridEval::SurfD1> GeomGridEval_SurfaceOfExtrusion::Evalua
// For extrusion: D1U = C'(u), D1V = Direction (constant)
const gp_XYZ aDirXYZ = myDirection.XYZ();
const gp_Vec aD1V(myDirection);
NCollection_Array2<GeomGridEval::SurfD1> aResult(1, aNbU, 1, aNbV);
for (int i = 1; i <= aNbU; ++i)
{
const GeomGridEval::CurveD1& aCurveData = aCurveD1.Value(i);
const gp_XYZ& aCurvePt = aCurveData.Point.XYZ();
const gp_Vec& aD1U = aCurveData.D1;
for (int j = 1; j <= aNbV; ++j)
{
const double aV = myVParams.Value(j);
aResult.ChangeValue(i, j) = {gp_Pnt(aCurvePt + aV * aDirXYZ), aD1U, aD1V};
const double aV = myVParams.Value(j);
gp_Pnt aP;
gp_Vec aD1U, aD1V;
Geom_ExtrusionUtils::CalculateD1(aCurveData.Point,
aCurveData.D1,
aV,
aDirXYZ,
aP,
aD1U,
aD1V);
aResult.ChangeValue(i, j) = {aP, aD1U, aD1V};
}
}
@@ -158,21 +168,29 @@ NCollection_Array2<GeomGridEval::SurfD2> GeomGridEval_SurfaceOfExtrusion::Evalua
// For extrusion: D1U = C'(u), D1V = Direction
// D2U = C''(u), D2V = 0, D2UV = 0
const gp_XYZ aDirXYZ = myDirection.XYZ();
const gp_Vec aD1V(myDirection);
const gp_Vec aZero(0.0, 0.0, 0.0);
NCollection_Array2<GeomGridEval::SurfD2> aResult(1, aNbU, 1, aNbV);
for (int i = 1; i <= aNbU; ++i)
{
const GeomGridEval::CurveD2& aCurveData = aCurveD2.Value(i);
const gp_XYZ& aCurvePt = aCurveData.Point.XYZ();
const gp_Vec& aD1U = aCurveData.D1;
const gp_Vec& aD2U = aCurveData.D2;
for (int j = 1; j <= aNbV; ++j)
{
const double aV = myVParams.Value(j);
aResult.ChangeValue(i, j) = {gp_Pnt(aCurvePt + aV * aDirXYZ), aD1U, aD1V, aD2U, aZero, aZero};
const double aV = myVParams.Value(j);
gp_Pnt aP;
gp_Vec aD1U, aD1V, aD2U, aD2V, aD2UV;
Geom_ExtrusionUtils::CalculateD2(aCurveData.Point,
aCurveData.D1,
aCurveData.D2,
aV,
aDirXYZ,
aP,
aD1U,
aD1V,
aD2U,
aD2V,
aD2UV);
aResult.ChangeValue(i, j) = {aP, aD1U, aD1V, aD2U, aD2V, aD2UV};
}
}
@@ -206,31 +224,34 @@ NCollection_Array2<GeomGridEval::SurfD3> GeomGridEval_SurfaceOfExtrusion::Evalua
// D2U = C''(u), D2V = 0, D2UV = 0
// D3U = C'''(u), D3V = 0, D3UUV = 0, D3UVV = 0
const gp_XYZ aDirXYZ = myDirection.XYZ();
const gp_Vec aD1V(myDirection);
const gp_Vec aZero(0.0, 0.0, 0.0);
NCollection_Array2<GeomGridEval::SurfD3> aResult(1, aNbU, 1, aNbV);
for (int i = 1; i <= aNbU; ++i)
{
const GeomGridEval::CurveD3& aCurveData = aCurveD3.Value(i);
const gp_XYZ& aCurvePt = aCurveData.Point.XYZ();
const gp_Vec& aD1U = aCurveData.D1;
const gp_Vec& aD2U = aCurveData.D2;
const gp_Vec& aD3U = aCurveData.D3;
for (int j = 1; j <= aNbV; ++j)
{
const double aV = myVParams.Value(j);
aResult.ChangeValue(i, j) = {gp_Pnt(aCurvePt + aV * aDirXYZ),
aD1U,
aD1V,
aD2U,
aZero,
aZero,
aD3U,
aZero,
aZero,
aZero};
const double aV = myVParams.Value(j);
gp_Pnt aP;
gp_Vec aD1U, aD1V, aD2U, aD2V, aD2UV, aD3U, aD3V, aD3UUV, aD3UVV;
Geom_ExtrusionUtils::CalculateD3(aCurveData.Point,
aCurveData.D1,
aCurveData.D2,
aCurveData.D3,
aV,
aDirXYZ,
aP,
aD1U,
aD1V,
aD2U,
aD2V,
aD2UV,
aD3U,
aD3V,
aD3UUV,
aD3UVV);
aResult.ChangeValue(i, j) = {aP, aD1U, aD1V, aD2U, aD2V, aD2UV, aD3U, aD3V, aD3UUV, aD3UVV};
}
}
@@ -253,49 +274,12 @@ NCollection_Array2<gp_Vec> GeomGridEval_SurfaceOfExtrusion::EvaluateGridDN(int t
NCollection_Array2<gp_Vec> aResult(1, aNbU, 1, aNbV);
// For extrusion surface:
// - DN with theNV >= 2: always zero (direction is constant)
// - DN with theNV == 1 and theNU == 0: Direction
// - DN with theNV == 0: curve derivative C^(theNU)(u)
if (theNV >= 2)
const gp_XYZ aDirXYZ = myDirection.XYZ();
// For theNV == 0: need curve derivative, otherwise use CalculateDN directly
if (theNV == 0)
{
// All higher V derivatives are zero
const gp_Vec aZero(0.0, 0.0, 0.0);
for (int i = 1; i <= aNbU; ++i)
{
for (int j = 1; j <= aNbV; ++j)
{
aResult.SetValue(i, j, aZero);
}
}
}
else if (theNV == 1 && theNU == 0)
{
// D0V = Direction
const gp_Vec aDir(myDirection);
for (int i = 1; i <= aNbU; ++i)
{
for (int j = 1; j <= aNbV; ++j)
{
aResult.SetValue(i, j, aDir);
}
}
}
else if (theNV == 1)
{
// Mixed derivatives with theNV == 1 are all zero (direction is constant)
const gp_Vec aZero(0.0, 0.0, 0.0);
for (int i = 1; i <= aNbU; ++i)
{
for (int j = 1; j <= aNbV; ++j)
{
aResult.SetValue(i, j, aZero);
}
}
}
else
{
// theNV == 0: pure U derivative = curve derivative
// Pure U derivative = curve derivative
GeomGridEval_Curve aCurveEval;
aCurveEval.Initialize(myBasisCurve);
aCurveEval.SetParams(myUParams);
@@ -304,7 +288,19 @@ NCollection_Array2<gp_Vec> GeomGridEval_SurfaceOfExtrusion::EvaluateGridDN(int t
for (int i = 1; i <= aNbU; ++i)
{
const gp_Vec& aDN = aCurveDN.Value(i);
const gp_Vec aDN = Geom_ExtrusionUtils::CalculateDN(aCurveDN.Value(i), aDirXYZ, theNU, theNV);
for (int j = 1; j <= aNbV; ++j)
{
aResult.SetValue(i, j, aDN);
}
}
}
else
{
// For theNV >= 1: result doesn't depend on curve, use CalculateDN with zero vector
const gp_Vec aDN = Geom_ExtrusionUtils::CalculateDN(gp_Vec(), aDirXYZ, theNU, theNV);
for (int i = 1; i <= aNbU; ++i)
{
for (int j = 1; j <= aNbV; ++j)
{
aResult.SetValue(i, j, aDN);

View File

@@ -13,8 +13,7 @@
#include <GeomGridEval_SurfaceOfRevolution.hxx>
#include <gp_Trsf.hxx>
#include <Precision.hxx>
#include <Geom_RevolutionUtils.pxx>
//==================================================================================================
@@ -79,13 +78,12 @@ NCollection_Array2<gp_Pnt> GeomGridEval_SurfaceOfRevolution::EvaluateGrid() cons
for (int i = 1; i <= aNbU; ++i)
{
gp_Trsf aRotation;
aRotation.SetRotation(myAxis, myUParams.Value(i));
const double aU = myUParams.Value(i);
for (int j = 1; j <= aNbV; ++j)
{
gp_Pnt aP = aCurvePoints.Value(j);
aP.Transform(aRotation);
gp_Pnt aP;
Geom_RevolutionUtils::CalculateD0(aCurvePoints.Value(j), aU, myAxis, aP);
aResult.SetValue(i, j, aP);
}
}
@@ -116,34 +114,25 @@ NCollection_Array2<GeomGridEval::SurfD1> GeomGridEval_SurfaceOfRevolution::Evalu
return NCollection_Array2<GeomGridEval::SurfD1>();
}
const gp_XYZ& aAxisDir = myAxisDirection.XYZ();
const gp_XYZ& aAxisLoc = myAxisLocation.XYZ();
NCollection_Array2<GeomGridEval::SurfD1> aResult(1, aNbU, 1, aNbV);
for (int i = 1; i <= aNbU; ++i)
{
gp_Trsf aRotation;
aRotation.SetRotation(myAxis, myUParams.Value(i));
const double aU = myUParams.Value(i);
for (int j = 1; j <= aNbV; ++j)
{
const GeomGridEval::CurveD1& aCurveData = aCurveD1.Value(j);
const gp_XYZ aCQ = aCurveData.Point.XYZ() - aAxisLoc;
// D1U (before rotation) = Axis Cross (P - AxisLoc)
gp_Vec aD1U(aAxisDir.Crossed(aCQ));
if (aD1U.SquareMagnitude() < Precision::SquareConfusion())
{
aD1U.SetCoord(0.0, 0.0, 0.0);
}
// Rotate point and vectors
gp_Pnt aP = aCurveData.Point;
aP.Transform(aRotation);
aD1U.Transform(aRotation);
gp_Vec aD1V = aCurveData.D1;
aD1V.Transform(aRotation);
gp_Pnt aP;
gp_Vec aD1U, aD1V;
Geom_RevolutionUtils::CalculateD1(aCurveData.Point,
aCurveData.D1,
aU,
myAxis,
aP,
aD1U,
aD1V);
aResult.ChangeValue(i, j) = {aP, aD1U, aD1V};
}
}
@@ -174,44 +163,29 @@ NCollection_Array2<GeomGridEval::SurfD2> GeomGridEval_SurfaceOfRevolution::Evalu
return NCollection_Array2<GeomGridEval::SurfD2>();
}
const gp_XYZ& aAxisDir = myAxisDirection.XYZ();
const gp_XYZ& aAxisLoc = myAxisLocation.XYZ();
NCollection_Array2<GeomGridEval::SurfD2> aResult(1, aNbU, 1, aNbV);
for (int i = 1; i <= aNbU; ++i)
{
gp_Trsf aRotation;
aRotation.SetRotation(myAxis, myUParams.Value(i));
const double aU = myUParams.Value(i);
for (int j = 1; j <= aNbV; ++j)
{
const GeomGridEval::CurveD2& aCurveData = aCurveD2.Value(j);
const gp_XYZ aCQ = aCurveData.Point.XYZ() - aAxisLoc;
// D1U (before rotation) = Axis Cross (P - AxisLoc)
gp_Vec aD1U(aAxisDir.Crossed(aCQ));
if (aD1U.SquareMagnitude() < Precision::SquareConfusion())
{
aD1U.SetCoord(0.0, 0.0, 0.0);
}
// D2U (before rotation) = (Axis Dot CQ) * Axis - CQ
gp_Vec aD2U(aAxisDir.Dot(aCQ) * aAxisDir - aCQ);
// D2UV (before rotation) = Axis Cross C'(v)
gp_Vec aD2UV(aAxisDir.Crossed(aCurveData.D1.XYZ()));
// Rotate point and all vectors
gp_Pnt aP = aCurveData.Point;
aP.Transform(aRotation);
aD1U.Transform(aRotation);
gp_Vec aD1V = aCurveData.D1;
aD1V.Transform(aRotation);
aD2U.Transform(aRotation);
gp_Vec aD2V = aCurveData.D2;
aD2V.Transform(aRotation);
aD2UV.Transform(aRotation);
gp_Pnt aP;
gp_Vec aD1U, aD1V, aD2U, aD2V, aD2UV;
Geom_RevolutionUtils::CalculateD2(aCurveData.Point,
aCurveData.D1,
aCurveData.D2,
aU,
myAxis,
aP,
aD1U,
aD1V,
aD2U,
aD2V,
aD2UV);
aResult.ChangeValue(i, j) = {aP, aD1U, aD1V, aD2U, aD2V, aD2UV};
}
}
@@ -242,58 +216,34 @@ NCollection_Array2<GeomGridEval::SurfD3> GeomGridEval_SurfaceOfRevolution::Evalu
return NCollection_Array2<GeomGridEval::SurfD3>();
}
const gp_XYZ& aAxisDir = myAxisDirection.XYZ();
const gp_XYZ& aAxisLoc = myAxisLocation.XYZ();
NCollection_Array2<GeomGridEval::SurfD3> aResult(1, aNbU, 1, aNbV);
for (int i = 1; i <= aNbU; ++i)
{
gp_Trsf aRotation;
aRotation.SetRotation(myAxis, myUParams.Value(i));
const double aU = myUParams.Value(i);
for (int j = 1; j <= aNbV; ++j)
{
const GeomGridEval::CurveD3& aCurveData = aCurveD3.Value(j);
const gp_XYZ aCQ = aCurveData.Point.XYZ() - aAxisLoc;
// D1U (before rotation) = Axis Cross (P - AxisLoc)
gp_Vec aD1U(aAxisDir.Crossed(aCQ));
if (aD1U.SquareMagnitude() < Precision::SquareConfusion())
{
aD1U.SetCoord(0.0, 0.0, 0.0);
}
// D2U (before rotation) = (Axis Dot CQ) * Axis - CQ
gp_Vec aD2U(aAxisDir.Dot(aCQ) * aAxisDir - aCQ);
// D2UV (before rotation) = Axis Cross C'(v)
gp_Vec aD2UV(aAxisDir.Crossed(aCurveData.D1.XYZ()));
// D3U (before rotation) = -D1U
gp_Vec aD3U = -aD1U;
// D3UUV (before rotation) = (Axis Dot D1V) * Axis - D1V
gp_Vec aD3UUV(aAxisDir.Dot(aCurveData.D1.XYZ()) * aAxisDir - aCurveData.D1.XYZ());
// D3UVV (before rotation) = Axis Cross D2V
gp_Vec aD3UVV(aAxisDir.Crossed(aCurveData.D2.XYZ()));
// Rotate point and all vectors
gp_Pnt aP = aCurveData.Point;
aP.Transform(aRotation);
aD1U.Transform(aRotation);
gp_Vec aD1V = aCurveData.D1;
aD1V.Transform(aRotation);
aD2U.Transform(aRotation);
gp_Vec aD2V = aCurveData.D2;
aD2V.Transform(aRotation);
aD2UV.Transform(aRotation);
aD3U.Transform(aRotation);
gp_Vec aD3V = aCurveData.D3;
aD3V.Transform(aRotation);
aD3UUV.Transform(aRotation);
aD3UVV.Transform(aRotation);
gp_Pnt aP;
gp_Vec aD1U, aD1V, aD2U, aD2V, aD2UV, aD3U, aD3V, aD3UUV, aD3UVV;
Geom_RevolutionUtils::CalculateD3(aCurveData.Point,
aCurveData.D1,
aCurveData.D2,
aCurveData.D3,
aU,
myAxis,
aP,
aD1U,
aD1V,
aD2U,
aD2V,
aD2UV,
aD3U,
aD3V,
aD3UUV,
aD3UVV);
aResult.ChangeValue(i, j) = {aP, aD1U, aD1V, aD2U, aD2V, aD2UV, aD3U, aD3V, aD3UUV, aD3UVV};
}
}
@@ -315,8 +265,6 @@ NCollection_Array2<gp_Vec> GeomGridEval_SurfaceOfRevolution::EvaluateGridDN(int
const int aNbU = myUParams.Size();
const int aNbV = myVParams.Size();
const gp_XYZ& aAxisDir = myAxisDirection.XYZ();
const gp_XYZ& aAxisLoc = myAxisLocation.XYZ();
NCollection_Array2<gp_Vec> aResult(1, aNbU, 1, aNbV);
// Get curve data
@@ -331,14 +279,12 @@ NCollection_Array2<gp_Vec> GeomGridEval_SurfaceOfRevolution::EvaluateGridDN(int
for (int i = 1; i <= aNbU; ++i)
{
gp_Trsf aRotation;
aRotation.SetRotation(myAxis, myUParams.Value(i));
const double aU = myUParams.Value(i);
for (int j = 1; j <= aNbV; ++j)
{
gp_Vec aDV = aCurveDN.Value(j);
aDV.Transform(aRotation);
aResult.SetValue(i, j, aDV);
gp_Vec aDN = Geom_RevolutionUtils::CalculateDN(aCurveDN.Value(j), aU, myAxis, theNU, theNV);
aResult.SetValue(i, j, aDN);
}
}
}
@@ -360,47 +306,22 @@ NCollection_Array2<gp_Vec> GeomGridEval_SurfaceOfRevolution::EvaluateGridDN(int
for (int i = 1; i <= aNbU; ++i)
{
gp_Trsf aRotation;
aRotation.SetRotation(myAxis, myUParams.Value(i));
const double aU = myUParams.Value(i);
for (int j = 1; j <= aNbV; ++j)
{
gp_Vec aDV;
gp_Vec aCurvePtOrDN;
if (theNV == 0)
{
// For pure U derivative, the "vector" is the position from axis
aDV = gp_Vec(aCurvePts.Value(j).XYZ() - aAxisLoc);
// For pure U derivative, pass (P - AxisLocation) as the base vector
aCurvePtOrDN = gp_Vec(aCurvePts.Value(j).XYZ() - myAxisLocation.XYZ());
}
else
{
aDV = aCurveDV.Value(j);
aCurvePtOrDN = aCurveDV.Value(j);
}
// Apply U derivative formula based on GeomEvaluator pattern:
// theNU % 4 == 1: Axis Cross DV
// theNU % 4 == 2: (Axis Dot DV) * Axis - DV
// theNU % 4 == 3: -(Axis Cross DV)
// theNU % 4 == 0: DV - (Axis Dot DV) * Axis
gp_Vec aDN;
const int aModU = theNU % 4;
if (aModU == 1)
{
aDN = gp_Vec(aAxisDir.Crossed(aDV.XYZ()));
}
else if (aModU == 2)
{
aDN = gp_Vec(aAxisDir.Dot(aDV.XYZ()) * aAxisDir - aDV.XYZ());
}
else if (aModU == 3)
{
aDN = gp_Vec(aAxisDir.Crossed(aDV.XYZ())) * (-1.0);
}
else // aModU == 0
{
aDN = gp_Vec(aDV.XYZ() - aAxisDir.Dot(aDV.XYZ()) * aAxisDir);
}
aDN.Transform(aRotation);
gp_Vec aDN = Geom_RevolutionUtils::CalculateDN(aCurvePtOrDN, aU, myAxis, theNU, theNV);
aResult.SetValue(i, j, aDN);
}
}