mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-08-07 22:07:33 +08:00
Modeling Data - Integrate EvalRep descriptors and dispatch for Geom/Geom2d (#1089)
Introduce EvalRep descriptors for selected Geom and Geom2d curve/surface classes and add inline EvalRep utilities for evaluation dispatch with fallback to native paths. - add per-class Set/Get/Clear EvalRepresentation API and storage - support full, derivative-bounded and mapped descriptors - validate mapped parameter transforms in SetEvalRepresentation() - migrate Geom_OffsetSurface equivalent-surface path to EvalRep - clone EvalRep descriptors in copy constructors and Copy() paths - update adaptors to use EvalRep in supported branches - keep EvalRep invalidation in geometry mutators and fix regressions
This commit is contained in:
@@ -23,6 +23,8 @@ set(OCCT_Geom2d_FILES
|
||||
Geom2d_Direction.hxx
|
||||
Geom2d_Ellipse.cxx
|
||||
Geom2d_Ellipse.hxx
|
||||
Geom2d_EvalRepCurveDesc.hxx
|
||||
Geom2d_EvalRepUtils.pxx
|
||||
Geom2d_Geometry.cxx
|
||||
Geom2d_Geometry.hxx
|
||||
Geom2d_Hyperbola.cxx
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
#include <BSplCLib.hxx>
|
||||
#include <Geom2d_BSplineCurve.hxx>
|
||||
#include "Geom2d_EvalRepCurveDesc.hxx"
|
||||
#include "Geom2d_EvalRepUtils.pxx"
|
||||
#include <Geom2d_Geometry.hxx>
|
||||
#include <Geom2d_UndefinedDerivative.hxx>
|
||||
#include <gp.hxx>
|
||||
@@ -39,12 +41,22 @@
|
||||
#include <Standard_NoSuchObject.hxx>
|
||||
#include <Standard_NotImplemented.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <Standard_ProgramError.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Geom2d_BSplineCurve, Geom2d_BoundedCurve)
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Geom2d_BSplineCurve::SetEvalRepresentation(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc)
|
||||
{
|
||||
Geom2d_EvalRepUtils::ValidateCurveDesc(theDesc, this);
|
||||
myEvalRep = theDesc;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
static void CheckCurveData(const NCollection_Array1<gp_Pnt2d>& CPoles,
|
||||
const NCollection_Array1<double>& CKnots,
|
||||
const NCollection_Array1<int>& CMults,
|
||||
@@ -102,6 +114,7 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve(const Geom2d_BSplineCurve& theOther)
|
||||
myKnots(theOther.myKnots),
|
||||
myFlatKnots(theOther.myFlatKnots),
|
||||
myMults(theOther.myMults),
|
||||
myEvalRep(Geom2d_EvalRepUtils::CloneCurveDesc(theOther.myEvalRep)),
|
||||
myDeg(theOther.myDeg),
|
||||
myPeriodic(theOther.myPeriodic),
|
||||
myRational(theOther.myRational),
|
||||
|
||||
@@ -29,6 +29,11 @@
|
||||
class gp_Trsf2d;
|
||||
class Geom2d_Geometry;
|
||||
|
||||
namespace Geom2d_EvalRepCurveDesc
|
||||
{
|
||||
class Base;
|
||||
}
|
||||
|
||||
//! Describes a BSpline curve.
|
||||
//! A BSpline curve can be:
|
||||
//! - uniform or non-uniform,
|
||||
@@ -189,6 +194,20 @@ public:
|
||||
//! Copy constructor for optimized copying without validation.
|
||||
Standard_EXPORT Geom2d_BSplineCurve(const Geom2d_BSplineCurve& theOther);
|
||||
|
||||
//! Returns true if an evaluation representation is attached.
|
||||
bool HasEvalRepresentation() const { return !myEvalRep.IsNull(); }
|
||||
|
||||
//! Returns the current evaluation representation descriptor (may be null).
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& EvalRepresentation() const { return myEvalRep; }
|
||||
|
||||
//! Sets a new evaluation representation.
|
||||
//! Validates descriptor data and ensures no circular references.
|
||||
Standard_EXPORT void SetEvalRepresentation(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc);
|
||||
|
||||
//! Removes the evaluation representation.
|
||||
void ClearEvalRepresentation() { myEvalRep.Nullify(); }
|
||||
|
||||
//! Increases the degree of this BSpline curve to
|
||||
//! Degree. As a result, the poles, weights and
|
||||
//! multiplicities tables are modified; the knots table is
|
||||
@@ -848,18 +867,19 @@ protected:
|
||||
void updateKnots();
|
||||
|
||||
private:
|
||||
NCollection_Array1<gp_Pnt2d> myPoles;
|
||||
NCollection_Array1<double> myWeights;
|
||||
NCollection_Array1<double> myKnots;
|
||||
NCollection_Array1<double> myFlatKnots;
|
||||
NCollection_Array1<int> myMults;
|
||||
int myDeg = 0;
|
||||
bool myPeriodic = false;
|
||||
bool myRational = false;
|
||||
GeomAbs_BSplKnotDistribution myKnotSet = GeomAbs_NonUniform;
|
||||
GeomAbs_Shape mySmooth = GeomAbs_C0;
|
||||
double myMaxDerivInv = 0.0;
|
||||
bool myMaxDerivInvOk = false;
|
||||
NCollection_Array1<gp_Pnt2d> myPoles;
|
||||
NCollection_Array1<double> myWeights;
|
||||
NCollection_Array1<double> myKnots;
|
||||
NCollection_Array1<double> myFlatKnots;
|
||||
NCollection_Array1<int> myMults;
|
||||
occ::handle<Geom2d_EvalRepCurveDesc::Base> myEvalRep;
|
||||
int myDeg = 0;
|
||||
bool myPeriodic = false;
|
||||
bool myRational = false;
|
||||
GeomAbs_BSplKnotDistribution myKnotSet = GeomAbs_NonUniform;
|
||||
GeomAbs_Shape mySmooth = GeomAbs_C0;
|
||||
double myMaxDerivInv = 0.0;
|
||||
bool myMaxDerivInvOk = false;
|
||||
};
|
||||
|
||||
#endif // _Geom2d_BSplineCurve_HeaderFile
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#include <BSplCLib.hxx>
|
||||
#include <Geom2d_BSplineCurve.hxx>
|
||||
#include "Geom2d_EvalRepCurveDesc.hxx"
|
||||
#include "Geom2d_EvalRepUtils.pxx"
|
||||
#include <Geom2d_UndefinedDerivative.hxx>
|
||||
#include <gp.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
@@ -160,6 +162,13 @@ int Geom2d_BSplineCurve::Degree() const
|
||||
|
||||
std::optional<gp_Pnt2d> Geom2d_BSplineCurve::EvalD0(const double U) const
|
||||
{
|
||||
if (const std::optional<gp_Pnt2d> aEvalRepResult =
|
||||
Geom2d_EvalRepUtils::TryEvalCurveD0(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
gp_Pnt2d P;
|
||||
int aSpanIndex = 0;
|
||||
double aNewU(U);
|
||||
@@ -176,6 +185,13 @@ std::optional<gp_Pnt2d> Geom2d_BSplineCurve::EvalD0(const double U) const
|
||||
|
||||
std::optional<Geom2d_Curve::ResD1> Geom2d_BSplineCurve::EvalD1(const double U) const
|
||||
{
|
||||
if (const std::optional<Geom2d_Curve::ResD1> aEvalRepResult =
|
||||
Geom2d_EvalRepUtils::TryEvalCurveD1(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom2d_Curve::ResD1> aResult{std::in_place};
|
||||
int aSpanIndex = 0;
|
||||
double aNewU(U);
|
||||
@@ -201,6 +217,13 @@ std::optional<Geom2d_Curve::ResD1> Geom2d_BSplineCurve::EvalD1(const double U) c
|
||||
|
||||
std::optional<Geom2d_Curve::ResD2> Geom2d_BSplineCurve::EvalD2(const double U) const
|
||||
{
|
||||
if (const std::optional<Geom2d_Curve::ResD2> aEvalRepResult =
|
||||
Geom2d_EvalRepUtils::TryEvalCurveD2(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom2d_Curve::ResD2> aResult{std::in_place};
|
||||
int aSpanIndex = 0;
|
||||
double aNewU(U);
|
||||
@@ -227,6 +250,13 @@ std::optional<Geom2d_Curve::ResD2> Geom2d_BSplineCurve::EvalD2(const double U) c
|
||||
|
||||
std::optional<Geom2d_Curve::ResD3> Geom2d_BSplineCurve::EvalD3(const double U) const
|
||||
{
|
||||
if (const std::optional<Geom2d_Curve::ResD3> aEvalRepResult =
|
||||
Geom2d_EvalRepUtils::TryEvalCurveD3(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom2d_Curve::ResD3> aResult{std::in_place};
|
||||
int aSpanIndex = 0;
|
||||
double aNewU(U);
|
||||
@@ -256,6 +286,14 @@ std::optional<gp_Vec2d> Geom2d_BSplineCurve::EvalDN(const double U, const int N)
|
||||
{
|
||||
if (N < 1)
|
||||
return std::nullopt;
|
||||
|
||||
if (const std::optional<gp_Vec2d> aEvalRepResult =
|
||||
Geom2d_EvalRepUtils::TryEvalCurveDN(myEvalRep, U, N);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
gp_Vec2d V;
|
||||
BSplCLib::DN(U, N, 0, myDeg, myPeriodic, myPoles, Weights(), myFlatKnots, BSplCLib::NoMults(), V);
|
||||
return V;
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
// Suppressed Swaps, added Init, removed typedefs
|
||||
|
||||
#include <Geom2d_BezierCurve.hxx>
|
||||
#include "Geom2d_EvalRepCurveDesc.hxx"
|
||||
#include "Geom2d_EvalRepUtils.pxx"
|
||||
#include <Geom2d_Geometry.hxx>
|
||||
#include <gp.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
@@ -33,6 +35,7 @@
|
||||
#include <Standard_ConstructionError.hxx>
|
||||
#include <Standard_DimensionError.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <Standard_ProgramError.hxx>
|
||||
#include <Standard_RangeError.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
@@ -43,6 +46,15 @@ IMPLEMENT_STANDARD_RTTIEXT(Geom2d_BezierCurve, Geom2d_BoundedCurve)
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Geom2d_BezierCurve::SetEvalRepresentation(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc)
|
||||
{
|
||||
Geom2d_EvalRepUtils::ValidateCurveDesc(theDesc, this);
|
||||
myEvalRep = theDesc;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
static bool Rational(const NCollection_Array1<double>& W)
|
||||
{
|
||||
int i, n = W.Length();
|
||||
@@ -105,6 +117,7 @@ Geom2d_BezierCurve::Geom2d_BezierCurve(const Geom2d_BezierCurve& theOther)
|
||||
: myPoles(theOther.myPoles),
|
||||
myWeights(theOther.myRational ? NCollection_Array1<double>(theOther.myWeights)
|
||||
: BSplCLib::UnitWeights(theOther.myPoles.Length())),
|
||||
myEvalRep(Geom2d_EvalRepUtils::CloneCurveDesc(theOther.myEvalRep)),
|
||||
myRational(theOther.myRational),
|
||||
myClosed(theOther.myClosed),
|
||||
myMaxDerivInvOk(false)
|
||||
@@ -446,6 +459,13 @@ int Geom2d_BezierCurve::Degree() const
|
||||
|
||||
std::optional<gp_Pnt2d> Geom2d_BezierCurve::EvalD0(const double U) const
|
||||
{
|
||||
if (const std::optional<gp_Pnt2d> aEvalRepResult =
|
||||
Geom2d_EvalRepUtils::TryEvalCurveD0(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
gp_Pnt2d P;
|
||||
BSplCLib::D0(U, Poles(), Weights(), P);
|
||||
return P;
|
||||
@@ -455,6 +475,13 @@ std::optional<gp_Pnt2d> Geom2d_BezierCurve::EvalD0(const double U) const
|
||||
|
||||
std::optional<Geom2d_Curve::ResD1> Geom2d_BezierCurve::EvalD1(const double U) const
|
||||
{
|
||||
if (const std::optional<Geom2d_Curve::ResD1> aEvalRepResult =
|
||||
Geom2d_EvalRepUtils::TryEvalCurveD1(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom2d_Curve::ResD1> aResult{std::in_place};
|
||||
BSplCLib::D1(U, Poles(), Weights(), aResult->Point, aResult->D1);
|
||||
return aResult;
|
||||
@@ -464,6 +491,13 @@ std::optional<Geom2d_Curve::ResD1> Geom2d_BezierCurve::EvalD1(const double U) co
|
||||
|
||||
std::optional<Geom2d_Curve::ResD2> Geom2d_BezierCurve::EvalD2(const double U) const
|
||||
{
|
||||
if (const std::optional<Geom2d_Curve::ResD2> aEvalRepResult =
|
||||
Geom2d_EvalRepUtils::TryEvalCurveD2(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom2d_Curve::ResD2> aResult{std::in_place};
|
||||
BSplCLib::D2(U, Poles(), Weights(), aResult->Point, aResult->D1, aResult->D2);
|
||||
return aResult;
|
||||
@@ -473,6 +507,13 @@ std::optional<Geom2d_Curve::ResD2> Geom2d_BezierCurve::EvalD2(const double U) co
|
||||
|
||||
std::optional<Geom2d_Curve::ResD3> Geom2d_BezierCurve::EvalD3(const double U) const
|
||||
{
|
||||
if (const std::optional<Geom2d_Curve::ResD3> aEvalRepResult =
|
||||
Geom2d_EvalRepUtils::TryEvalCurveD3(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom2d_Curve::ResD3> aResult{std::in_place};
|
||||
BSplCLib::D3(U, Poles(), Weights(), aResult->Point, aResult->D1, aResult->D2, aResult->D3);
|
||||
return aResult;
|
||||
@@ -484,6 +525,14 @@ std::optional<gp_Vec2d> Geom2d_BezierCurve::EvalDN(const double U, const int N)
|
||||
{
|
||||
if (N < 1)
|
||||
return std::nullopt;
|
||||
|
||||
if (const std::optional<gp_Vec2d> aEvalRepResult =
|
||||
Geom2d_EvalRepUtils::TryEvalCurveDN(myEvalRep, U, N);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
gp_Vec2d V;
|
||||
|
||||
BSplCLib::DN(U, N, 0, Degree(), false, myPoles, Weights(), Knots(), &Multiplicities(), V);
|
||||
@@ -576,6 +625,7 @@ void Geom2d_BezierCurve::Transform(const gp_Trsf2d& T)
|
||||
|
||||
for (int i = 1; i <= nbpoles; i++)
|
||||
myPoles(i).Transform(T);
|
||||
ClearEvalRepresentation();
|
||||
myMaxDerivInvOk = false;
|
||||
}
|
||||
|
||||
@@ -635,6 +685,7 @@ void Geom2d_BezierCurve::init(const NCollection_Array1<gp_Pnt2d>& thePoles,
|
||||
|
||||
myMaxDerivInv = 0.0;
|
||||
myMaxDerivInvOk = false;
|
||||
ClearEvalRepresentation();
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
class gp_Trsf2d;
|
||||
class Geom2d_Geometry;
|
||||
|
||||
namespace Geom2d_EvalRepCurveDesc
|
||||
{
|
||||
class Base;
|
||||
}
|
||||
|
||||
//! Describes a rational or non-rational Bezier curve
|
||||
//! - a non-rational Bezier curve is defined by a table
|
||||
//! of poles (also called control points),
|
||||
@@ -104,6 +109,20 @@ public:
|
||||
//! Copy constructor for optimized copying without validation.
|
||||
Standard_EXPORT Geom2d_BezierCurve(const Geom2d_BezierCurve& theOther);
|
||||
|
||||
//! Returns true if an evaluation representation is attached.
|
||||
bool HasEvalRepresentation() const { return !myEvalRep.IsNull(); }
|
||||
|
||||
//! Returns the current evaluation representation descriptor (may be null).
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& EvalRepresentation() const { return myEvalRep; }
|
||||
|
||||
//! Sets a new evaluation representation.
|
||||
//! Validates descriptor data and ensures no circular references.
|
||||
Standard_EXPORT void SetEvalRepresentation(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc);
|
||||
|
||||
//! Removes the evaluation representation.
|
||||
void ClearEvalRepresentation() { myEvalRep.Nullify(); }
|
||||
|
||||
//! Increases the degree of a bezier curve. Degree is the new
|
||||
//! degree of <me>.
|
||||
//! raises ConstructionError if Degree is greater than MaxDegree or lower than 2
|
||||
@@ -321,12 +340,13 @@ protected:
|
||||
const NCollection_Array1<double>* theWeights);
|
||||
|
||||
private:
|
||||
NCollection_Array1<gp_Pnt2d> myPoles;
|
||||
NCollection_Array1<double> myWeights;
|
||||
bool myRational = false;
|
||||
bool myClosed = false;
|
||||
double myMaxDerivInv = 0.0;
|
||||
bool myMaxDerivInvOk = false;
|
||||
NCollection_Array1<gp_Pnt2d> myPoles;
|
||||
NCollection_Array1<double> myWeights;
|
||||
occ::handle<Geom2d_EvalRepCurveDesc::Base> myEvalRep;
|
||||
bool myRational = false;
|
||||
bool myClosed = false;
|
||||
double myMaxDerivInv = 0.0;
|
||||
bool myMaxDerivInvOk = false;
|
||||
};
|
||||
|
||||
#endif // _Geom2d_BezierCurve_HeaderFile
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
// Copyright (c) 2025 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 _Geom2d_EvalRepCurveDesc_HeaderFile
|
||||
#define _Geom2d_EvalRepCurveDesc_HeaderFile
|
||||
|
||||
#include <Geom2d_Curve.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
|
||||
namespace Geom2d_EvalRepCurveDesc
|
||||
{
|
||||
//! 1D affine parameter map: uRep = Scale * u + Offset.
|
||||
struct Map1d
|
||||
{
|
||||
double Scale = 1.0;
|
||||
double Offset = 0.0;
|
||||
|
||||
bool IsIdentity() const
|
||||
{
|
||||
return std::abs(Scale - 1.0) < Precision::Confusion()
|
||||
&& std::abs(Offset) < Precision::Confusion();
|
||||
}
|
||||
|
||||
bool IsValid() const { return std::abs(Scale) > Precision::Confusion(); }
|
||||
|
||||
double Map(const double theU) const { return Scale * theU + Offset; }
|
||||
};
|
||||
|
||||
//! 1D parameter domain interval.
|
||||
struct Domain1d
|
||||
{
|
||||
double First = 0.0;
|
||||
double Last = 1.0;
|
||||
|
||||
bool Contains(const double theU) const
|
||||
{
|
||||
return (theU >= First - Precision::Confusion()) && (theU <= Last + Precision::Confusion());
|
||||
}
|
||||
};
|
||||
|
||||
//! Abstract base descriptor for 2D curve evaluation representation.
|
||||
//! Holds the representation handle and a Kind tag for switch-based dispatch.
|
||||
class Base : public Standard_Transient
|
||||
{
|
||||
public:
|
||||
//! Descriptor kind for switch-based dispatch (no RTTI needed).
|
||||
enum class Kind
|
||||
{
|
||||
Full, //!< fully equivalent, no derivative limit, no domain, no map
|
||||
DerivBounded, //!< full domain + identity map, limited to MaxDerivOrder
|
||||
Mapped //!< has MaxDerivOrder + optional Domain + ParamMap
|
||||
};
|
||||
|
||||
occ::handle<Geom2d_Curve> Representation; //!< geometry used for evaluation
|
||||
|
||||
//! Returns the descriptor kind.
|
||||
virtual Kind GetKind() const = 0;
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(Base, Standard_Transient)
|
||||
|
||||
protected:
|
||||
Base() = default;
|
||||
};
|
||||
|
||||
//! Fully equivalent descriptor: no derivative limit, no domain, no map.
|
||||
//! Fastest evaluation path - direct delegation to Representation.
|
||||
class Full : public Base
|
||||
{
|
||||
public:
|
||||
Kind GetKind() const override { return Kind::Full; }
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(Full, Base)
|
||||
};
|
||||
|
||||
//! Derivative-bounded descriptor: full domain, identity map, limited to MaxDerivOrder.
|
||||
class DerivBounded : public Base
|
||||
{
|
||||
public:
|
||||
std::size_t MaxDerivOrder = 3; //!< max supported derivative order
|
||||
|
||||
Kind GetKind() const override { return Kind::DerivBounded; }
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(DerivBounded, Base)
|
||||
};
|
||||
|
||||
//! Mapped descriptor for 2D curve evaluation representation.
|
||||
//! Adds optional bounded domain and affine parameter map.
|
||||
class Mapped : public Base
|
||||
{
|
||||
public:
|
||||
std::size_t MaxDerivOrder = 3; //!< max supported derivative order
|
||||
std::optional<Domain1d> Domain; //!< nullopt = full domain
|
||||
Map1d ParamMap; //!< affine parameter transform
|
||||
|
||||
Kind GetKind() const override { return Kind::Mapped; }
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(Mapped, Base)
|
||||
};
|
||||
} // namespace Geom2d_EvalRepCurveDesc
|
||||
|
||||
#endif // _Geom2d_EvalRepCurveDesc_HeaderFile
|
||||
@@ -0,0 +1,417 @@
|
||||
// Copyright (c) 2025 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 _Geom2d_EvalRepUtils_HeaderFile
|
||||
#define _Geom2d_EvalRepUtils_HeaderFile
|
||||
|
||||
#include "Geom2d_EvalRepCurveDesc.hxx"
|
||||
|
||||
#include <Geom2d_Curve.hxx>
|
||||
|
||||
#include <Standard_ProgramError.hxx>
|
||||
|
||||
#include <cmath>
|
||||
#include <optional>
|
||||
|
||||
namespace Geom2d_EvalRepUtils
|
||||
{
|
||||
occ::handle<Geom2d_EvalRepCurveDesc::Base> CloneCurveDesc(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc);
|
||||
|
||||
std::optional<gp_Pnt2d> TryEvalCurveD0(const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU);
|
||||
std::optional<Geom2d_Curve::ResD1> TryEvalCurveD1(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU);
|
||||
std::optional<Geom2d_Curve::ResD2> TryEvalCurveD2(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU);
|
||||
std::optional<Geom2d_Curve::ResD3> TryEvalCurveD3(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU);
|
||||
std::optional<gp_Vec2d> TryEvalCurveDN(const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU,
|
||||
const int theN);
|
||||
std::optional<gp_Pnt2d> TryEvalCurveD0Mapped(const Geom2d_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU);
|
||||
std::optional<Geom2d_Curve::ResD1> TryEvalCurveD1Mapped(
|
||||
const Geom2d_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU);
|
||||
std::optional<Geom2d_Curve::ResD2> TryEvalCurveD2Mapped(
|
||||
const Geom2d_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU);
|
||||
std::optional<Geom2d_Curve::ResD3> TryEvalCurveD3Mapped(
|
||||
const Geom2d_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU);
|
||||
std::optional<gp_Vec2d> TryEvalCurveDNMapped(const Geom2d_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU,
|
||||
const int theN);
|
||||
void ValidateCurveDesc(const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc,
|
||||
const Geom2d_Curve* theOwner);
|
||||
} // namespace Geom2d_EvalRepUtils
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline void Geom2d_EvalRepUtils::ValidateCurveDesc(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc,
|
||||
const Geom2d_Curve* theOwner)
|
||||
{
|
||||
if (theDesc.IsNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (theDesc->Representation.IsNull())
|
||||
{
|
||||
throw Standard_ProgramError("SetEvalRepresentation: null Representation");
|
||||
}
|
||||
if (theDesc->GetKind() == Geom2d_EvalRepCurveDesc::Base::Kind::Mapped)
|
||||
{
|
||||
const auto* aMapped = static_cast<const Geom2d_EvalRepCurveDesc::Mapped*>(theDesc.get());
|
||||
if (!aMapped->ParamMap.IsValid())
|
||||
{
|
||||
throw Standard_ProgramError("SetEvalRepresentation: invalid parameter map");
|
||||
}
|
||||
}
|
||||
// Only direct self-reference is detected here; indirect cycles (A->B->A) are not
|
||||
// checked because EvalRepresentation() is not available on the Geom2d_Curve base class.
|
||||
if (theDesc->Representation.get() == theOwner)
|
||||
{
|
||||
throw Standard_ProgramError("SetEvalRepresentation: invalid descriptor chain");
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline occ::handle<Geom2d_EvalRepCurveDesc::Base> Geom2d_EvalRepUtils::CloneCurveDesc(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc)
|
||||
{
|
||||
if (theDesc.IsNull() || theDesc->Representation.IsNull())
|
||||
{
|
||||
return occ::handle<Geom2d_EvalRepCurveDesc::Base>();
|
||||
}
|
||||
|
||||
const occ::handle<Geom2d_Curve> aRepCopy =
|
||||
occ::down_cast<Geom2d_Curve>(theDesc->Representation->Copy());
|
||||
if (aRepCopy.IsNull())
|
||||
{
|
||||
return occ::handle<Geom2d_EvalRepCurveDesc::Base>();
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::Full: {
|
||||
occ::handle<Geom2d_EvalRepCurveDesc::Full> aClone = new Geom2d_EvalRepCurveDesc::Full();
|
||||
aClone->Representation = aRepCopy;
|
||||
return aClone;
|
||||
}
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::DerivBounded: {
|
||||
const auto* aSrc = static_cast<const Geom2d_EvalRepCurveDesc::DerivBounded*>(theDesc.get());
|
||||
occ::handle<Geom2d_EvalRepCurveDesc::DerivBounded> aClone =
|
||||
new Geom2d_EvalRepCurveDesc::DerivBounded();
|
||||
aClone->Representation = aRepCopy;
|
||||
aClone->MaxDerivOrder = aSrc->MaxDerivOrder;
|
||||
return aClone;
|
||||
}
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::Mapped: {
|
||||
const auto* aSrc = static_cast<const Geom2d_EvalRepCurveDesc::Mapped*>(theDesc.get());
|
||||
occ::handle<Geom2d_EvalRepCurveDesc::Mapped> aClone = new Geom2d_EvalRepCurveDesc::Mapped();
|
||||
aClone->Representation = aRepCopy;
|
||||
aClone->MaxDerivOrder = aSrc->MaxDerivOrder;
|
||||
aClone->Domain = aSrc->Domain;
|
||||
aClone->ParamMap = aSrc->ParamMap;
|
||||
return aClone;
|
||||
}
|
||||
}
|
||||
return occ::handle<Geom2d_EvalRepCurveDesc::Base>();
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<gp_Pnt2d> Geom2d_EvalRepUtils::TryEvalCurveD0(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
if (theDesc.IsNull())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::Full:
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::DerivBounded:
|
||||
return theDesc->Representation->EvalD0(theU);
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::Mapped:
|
||||
return TryEvalCurveD0Mapped(
|
||||
*static_cast<const Geom2d_EvalRepCurveDesc::Mapped*>(theDesc.get()),
|
||||
theU);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom2d_Curve::ResD1> Geom2d_EvalRepUtils::TryEvalCurveD1(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
if (theDesc.IsNull())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::Full:
|
||||
return theDesc->Representation->EvalD1(theU);
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::DerivBounded: {
|
||||
const auto* aBounded =
|
||||
static_cast<const Geom2d_EvalRepCurveDesc::DerivBounded*>(theDesc.get());
|
||||
if (aBounded->MaxDerivOrder < 1)
|
||||
return std::nullopt;
|
||||
return theDesc->Representation->EvalD1(theU);
|
||||
}
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::Mapped: {
|
||||
const auto* aMapped = static_cast<const Geom2d_EvalRepCurveDesc::Mapped*>(theDesc.get());
|
||||
if (aMapped->MaxDerivOrder < 1)
|
||||
return std::nullopt;
|
||||
return TryEvalCurveD1Mapped(*aMapped, theU);
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom2d_Curve::ResD2> Geom2d_EvalRepUtils::TryEvalCurveD2(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
if (theDesc.IsNull())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::Full:
|
||||
return theDesc->Representation->EvalD2(theU);
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::DerivBounded: {
|
||||
const auto* aBounded =
|
||||
static_cast<const Geom2d_EvalRepCurveDesc::DerivBounded*>(theDesc.get());
|
||||
if (aBounded->MaxDerivOrder < 2)
|
||||
return std::nullopt;
|
||||
return theDesc->Representation->EvalD2(theU);
|
||||
}
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::Mapped: {
|
||||
const auto* aMapped = static_cast<const Geom2d_EvalRepCurveDesc::Mapped*>(theDesc.get());
|
||||
if (aMapped->MaxDerivOrder < 2)
|
||||
return std::nullopt;
|
||||
return TryEvalCurveD2Mapped(*aMapped, theU);
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom2d_Curve::ResD3> Geom2d_EvalRepUtils::TryEvalCurveD3(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
if (theDesc.IsNull())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::Full:
|
||||
return theDesc->Representation->EvalD3(theU);
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::DerivBounded: {
|
||||
const auto* aBounded =
|
||||
static_cast<const Geom2d_EvalRepCurveDesc::DerivBounded*>(theDesc.get());
|
||||
if (aBounded->MaxDerivOrder < 3)
|
||||
return std::nullopt;
|
||||
return theDesc->Representation->EvalD3(theU);
|
||||
}
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::Mapped: {
|
||||
const auto* aMapped = static_cast<const Geom2d_EvalRepCurveDesc::Mapped*>(theDesc.get());
|
||||
if (aMapped->MaxDerivOrder < 3)
|
||||
return std::nullopt;
|
||||
return TryEvalCurveD3Mapped(*aMapped, theU);
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<gp_Vec2d> Geom2d_EvalRepUtils::TryEvalCurveDN(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU,
|
||||
const int theN)
|
||||
{
|
||||
if (theDesc.IsNull() || theN < 1)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::Full:
|
||||
return theDesc->Representation->EvalDN(theU, theN);
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::DerivBounded: {
|
||||
const auto* aBounded =
|
||||
static_cast<const Geom2d_EvalRepCurveDesc::DerivBounded*>(theDesc.get());
|
||||
if (aBounded->MaxDerivOrder < static_cast<std::size_t>(theN))
|
||||
return std::nullopt;
|
||||
return theDesc->Representation->EvalDN(theU, theN);
|
||||
}
|
||||
case Geom2d_EvalRepCurveDesc::Base::Kind::Mapped: {
|
||||
const auto* aMapped = static_cast<const Geom2d_EvalRepCurveDesc::Mapped*>(theDesc.get());
|
||||
if (aMapped->MaxDerivOrder < static_cast<std::size_t>(theN))
|
||||
return std::nullopt;
|
||||
return TryEvalCurveDNMapped(*aMapped, theU, theN);
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<gp_Pnt2d> Geom2d_EvalRepUtils::TryEvalCurveD0Mapped(
|
||||
const Geom2d_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
const double aURep = theDesc.ParamMap.Map(theU);
|
||||
|
||||
if (theDesc.Domain.has_value() && !theDesc.Domain->Contains(aURep))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return theDesc.Representation->EvalD0(aURep);
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom2d_Curve::ResD1> Geom2d_EvalRepUtils::TryEvalCurveD1Mapped(
|
||||
const Geom2d_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
const double aURep = theDesc.ParamMap.Map(theU);
|
||||
|
||||
if (theDesc.Domain.has_value() && !theDesc.Domain->Contains(aURep))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const std::optional<Geom2d_Curve::ResD1> aRepRes = theDesc.Representation->EvalD1(aURep);
|
||||
if (!aRepRes)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const double aScale = theDesc.ParamMap.Scale;
|
||||
Geom2d_Curve::ResD1 aRes;
|
||||
aRes.Point = aRepRes->Point;
|
||||
aRes.D1 = aRepRes->D1 * aScale;
|
||||
return aRes;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom2d_Curve::ResD2> Geom2d_EvalRepUtils::TryEvalCurveD2Mapped(
|
||||
const Geom2d_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
const double aURep = theDesc.ParamMap.Map(theU);
|
||||
|
||||
if (theDesc.Domain.has_value() && !theDesc.Domain->Contains(aURep))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const std::optional<Geom2d_Curve::ResD2> aRepRes = theDesc.Representation->EvalD2(aURep);
|
||||
if (!aRepRes)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const double aScale = theDesc.ParamMap.Scale;
|
||||
const double aScale2 = aScale * aScale;
|
||||
|
||||
Geom2d_Curve::ResD2 aRes;
|
||||
aRes.Point = aRepRes->Point;
|
||||
aRes.D1 = aRepRes->D1 * aScale;
|
||||
aRes.D2 = aRepRes->D2 * aScale2;
|
||||
return aRes;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom2d_Curve::ResD3> Geom2d_EvalRepUtils::TryEvalCurveD3Mapped(
|
||||
const Geom2d_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
const double aURep = theDesc.ParamMap.Map(theU);
|
||||
|
||||
if (theDesc.Domain.has_value() && !theDesc.Domain->Contains(aURep))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const std::optional<Geom2d_Curve::ResD3> aRepRes = theDesc.Representation->EvalD3(aURep);
|
||||
if (!aRepRes)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const double aScale = theDesc.ParamMap.Scale;
|
||||
const double aScale2 = aScale * aScale;
|
||||
const double aScale3 = aScale2 * aScale;
|
||||
|
||||
Geom2d_Curve::ResD3 aRes;
|
||||
aRes.Point = aRepRes->Point;
|
||||
aRes.D1 = aRepRes->D1 * aScale;
|
||||
aRes.D2 = aRepRes->D2 * aScale2;
|
||||
aRes.D3 = aRepRes->D3 * aScale3;
|
||||
return aRes;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<gp_Vec2d> Geom2d_EvalRepUtils::TryEvalCurveDNMapped(
|
||||
const Geom2d_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU,
|
||||
const int theN)
|
||||
{
|
||||
const double aURep = theDesc.ParamMap.Map(theU);
|
||||
|
||||
if (theDesc.Domain.has_value() && !theDesc.Domain->Contains(aURep))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const std::optional<gp_Vec2d> aRepVec = theDesc.Representation->EvalDN(aURep, theN);
|
||||
if (!aRepVec)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const double aScaleN = std::pow(theDesc.ParamMap.Scale, theN);
|
||||
return (*aRepVec) * aScaleN;
|
||||
}
|
||||
|
||||
#endif // _Geom2d_EvalRepUtils_HeaderFile
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <Geom2d_BezierCurve.hxx>
|
||||
#include <Geom2d_BSplineCurve.hxx>
|
||||
#include <Geom2d_Curve.hxx>
|
||||
#include "Geom2d_EvalRepCurveDesc.hxx"
|
||||
#include "Geom2d_EvalRepUtils.pxx"
|
||||
#include <Geom2d_Geometry.hxx>
|
||||
#include <Geom2d_OffsetCurve.hxx>
|
||||
#include <Geom2d_OffsetCurveUtils.pxx>
|
||||
@@ -33,6 +35,7 @@
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_ConstructionError.hxx>
|
||||
#include <Standard_NotImplemented.hxx>
|
||||
#include <Standard_ProgramError.hxx>
|
||||
#include <Standard_RangeError.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
@@ -42,6 +45,15 @@ static const double MyAngularToleranceForG1 = Precision::Angular();
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
void Geom2d_OffsetCurve::SetEvalRepresentation(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc)
|
||||
{
|
||||
Geom2d_EvalRepUtils::ValidateCurveDesc(theDesc, this);
|
||||
myEvalRep = theDesc;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
occ::handle<Geom2d_Geometry> Geom2d_OffsetCurve::Copy() const
|
||||
{
|
||||
return new Geom2d_OffsetCurve(*this);
|
||||
@@ -64,17 +76,19 @@ Geom2d_OffsetCurve::Geom2d_OffsetCurve(const occ::handle<Geom2d_Curve>& theCurve
|
||||
//==================================================================================================
|
||||
|
||||
Geom2d_OffsetCurve::Geom2d_OffsetCurve(const Geom2d_OffsetCurve& theOther)
|
||||
: offsetValue(theOther.offsetValue),
|
||||
: basisCurve(occ::down_cast<Geom2d_Curve>(theOther.basisCurve->Copy())),
|
||||
myEvalRep(Geom2d_EvalRepUtils::CloneCurveDesc(theOther.myEvalRep)),
|
||||
offsetValue(theOther.offsetValue),
|
||||
myBasisCurveContinuity(theOther.myBasisCurveContinuity)
|
||||
{
|
||||
// Deep copy basis curve without validation
|
||||
basisCurve = occ::down_cast<Geom2d_Curve>(theOther.basisCurve->Copy());
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
void Geom2d_OffsetCurve::Reverse()
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
basisCurve->Reverse();
|
||||
offsetValue = -offsetValue;
|
||||
}
|
||||
@@ -90,6 +104,7 @@ double Geom2d_OffsetCurve::ReversedParameter(const double U) const
|
||||
|
||||
void Geom2d_OffsetCurve::SetBasisCurve(const occ::handle<Geom2d_Curve>& C, const bool isNotCheckC0)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
const double aUf = C->FirstParameter(), aUl = C->LastParameter();
|
||||
occ::handle<Geom2d_Curve> aCheckingCurve = C;
|
||||
bool isTrimmed = false;
|
||||
@@ -149,6 +164,7 @@ void Geom2d_OffsetCurve::SetBasisCurve(const occ::handle<Geom2d_Curve>& C, const
|
||||
|
||||
void Geom2d_OffsetCurve::SetOffsetValue(const double D)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
offsetValue = D;
|
||||
}
|
||||
|
||||
@@ -196,6 +212,13 @@ GeomAbs_Shape Geom2d_OffsetCurve::Continuity() const
|
||||
|
||||
std::optional<gp_Pnt2d> Geom2d_OffsetCurve::EvalD0(const double theU) const
|
||||
{
|
||||
if (const std::optional<gp_Pnt2d> aEvalRepResult =
|
||||
Geom2d_EvalRepUtils::TryEvalCurveD0(myEvalRep, theU);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom2d_Curve::ResD1> aBasisD1 = basisCurve->EvalD1(theU);
|
||||
if (!aBasisD1)
|
||||
return std::nullopt;
|
||||
@@ -209,6 +232,13 @@ std::optional<gp_Pnt2d> Geom2d_OffsetCurve::EvalD0(const double theU) const
|
||||
|
||||
std::optional<Geom2d_Curve::ResD1> Geom2d_OffsetCurve::EvalD1(const double theU) const
|
||||
{
|
||||
if (const std::optional<Geom2d_Curve::ResD1> aEvalRepResult =
|
||||
Geom2d_EvalRepUtils::TryEvalCurveD1(myEvalRep, theU);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom2d_Curve::ResD2> aBasisD2 = basisCurve->EvalD2(theU);
|
||||
if (!aBasisD2)
|
||||
return std::nullopt;
|
||||
@@ -223,6 +253,13 @@ std::optional<Geom2d_Curve::ResD1> Geom2d_OffsetCurve::EvalD1(const double theU)
|
||||
|
||||
std::optional<Geom2d_Curve::ResD2> Geom2d_OffsetCurve::EvalD2(const double theU) const
|
||||
{
|
||||
if (const std::optional<Geom2d_Curve::ResD2> aEvalRepResult =
|
||||
Geom2d_EvalRepUtils::TryEvalCurveD2(myEvalRep, theU);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom2d_Curve::ResD3> aBasisD3 = basisCurve->EvalD3(theU);
|
||||
if (!aBasisD3)
|
||||
return std::nullopt;
|
||||
@@ -251,6 +288,13 @@ std::optional<Geom2d_Curve::ResD2> Geom2d_OffsetCurve::EvalD2(const double theU)
|
||||
|
||||
std::optional<Geom2d_Curve::ResD3> Geom2d_OffsetCurve::EvalD3(const double theU) const
|
||||
{
|
||||
if (const std::optional<Geom2d_Curve::ResD3> aEvalRepResult =
|
||||
Geom2d_EvalRepUtils::TryEvalCurveD3(myEvalRep, theU);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom2d_Curve::ResD3> aBasisD3 = basisCurve->EvalD3(theU);
|
||||
if (!aBasisD3)
|
||||
return std::nullopt;
|
||||
@@ -290,6 +334,12 @@ std::optional<gp_Vec2d> Geom2d_OffsetCurve::EvalDN(const double U, const int N)
|
||||
{
|
||||
if (N < 1)
|
||||
return std::nullopt;
|
||||
if (const std::optional<gp_Vec2d> aEvalRepResult =
|
||||
Geom2d_EvalRepUtils::TryEvalCurveDN(myEvalRep, U, N);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
switch (N)
|
||||
{
|
||||
case 1: {
|
||||
@@ -366,6 +416,7 @@ double Geom2d_OffsetCurve::Period() const
|
||||
|
||||
void Geom2d_OffsetCurve::Transform(const gp_Trsf2d& T)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
basisCurve->Transform(T);
|
||||
offsetValue *= std::abs(T.ScaleFactor());
|
||||
}
|
||||
|
||||
@@ -26,6 +26,11 @@
|
||||
class gp_Trsf2d;
|
||||
class Geom2d_Geometry;
|
||||
|
||||
namespace Geom2d_EvalRepCurveDesc
|
||||
{
|
||||
class Base;
|
||||
}
|
||||
|
||||
//! This class implements the basis services for the creation,
|
||||
//! edition, modification and evaluation of planar offset curve.
|
||||
//! The offset curve is obtained by offsetting by distance along
|
||||
@@ -94,6 +99,20 @@ public:
|
||||
//! Copy constructor for optimized copying without validation.
|
||||
Standard_EXPORT Geom2d_OffsetCurve(const Geom2d_OffsetCurve& theOther);
|
||||
|
||||
//! Returns true if an evaluation representation is attached.
|
||||
bool HasEvalRepresentation() const { return !myEvalRep.IsNull(); }
|
||||
|
||||
//! Returns the current evaluation representation descriptor (may be null).
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& EvalRepresentation() const { return myEvalRep; }
|
||||
|
||||
//! Sets a new evaluation representation.
|
||||
//! Validates descriptor data and ensures no circular references.
|
||||
Standard_EXPORT void SetEvalRepresentation(
|
||||
const occ::handle<Geom2d_EvalRepCurveDesc::Base>& theDesc);
|
||||
|
||||
//! Removes the evaluation representation.
|
||||
void ClearEvalRepresentation() { myEvalRep.Nullify(); }
|
||||
|
||||
//! Changes the direction of parametrization of <me>.
|
||||
//! As a result:
|
||||
//! - the basis curve is reversed,
|
||||
@@ -275,9 +294,10 @@ public:
|
||||
DEFINE_STANDARD_RTTIEXT(Geom2d_OffsetCurve, Geom2d_Curve)
|
||||
|
||||
private:
|
||||
occ::handle<Geom2d_Curve> basisCurve;
|
||||
double offsetValue;
|
||||
GeomAbs_Shape myBasisCurveContinuity;
|
||||
occ::handle<Geom2d_Curve> basisCurve;
|
||||
occ::handle<Geom2d_EvalRepCurveDesc::Base> myEvalRep;
|
||||
double offsetValue;
|
||||
GeomAbs_Shape myBasisCurveContinuity;
|
||||
};
|
||||
|
||||
#endif // _Geom2d_OffsetCurve_HeaderFile
|
||||
|
||||
@@ -61,6 +61,29 @@ static const double PosTol = Precision::PConfusion() / 2;
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Geom2dAdaptor_Curve, Adaptor2d_Curve2d)
|
||||
|
||||
namespace
|
||||
{
|
||||
bool hasEvalRep(const Geom2dAdaptor_Curve::CurveDataVariant& theData)
|
||||
{
|
||||
if (const Geom2dAdaptor_Curve::BezierData* aBezierData =
|
||||
std::get_if<Geom2dAdaptor_Curve::BezierData>(&theData))
|
||||
{
|
||||
return !aBezierData->EvalRep.IsNull();
|
||||
}
|
||||
if (const Geom2dAdaptor_Curve::BSplineData* aBSplineData =
|
||||
std::get_if<Geom2dAdaptor_Curve::BSplineData>(&theData))
|
||||
{
|
||||
return !aBSplineData->EvalRep.IsNull();
|
||||
}
|
||||
if (const Geom2dAdaptor_Curve::OffsetData* anOffsetData =
|
||||
std::get_if<Geom2dAdaptor_Curve::OffsetData>(&theData))
|
||||
{
|
||||
return !anOffsetData->EvalRep.IsNull();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
occ::handle<Adaptor2d_Curve2d> Geom2dAdaptor_Curve::ShallowCopy() const
|
||||
@@ -82,17 +105,24 @@ occ::handle<Adaptor2d_Curve2d> Geom2dAdaptor_Curve::ShallowCopy() const
|
||||
occ::down_cast<Geom2dAdaptor_Curve>(anOffsetData->BasisAdaptor->ShallowCopy());
|
||||
}
|
||||
aNewData.Offset = anOffsetData->Offset;
|
||||
aNewData.EvalRep = anOffsetData->EvalRep;
|
||||
aCopy->myCurveData = std::move(aNewData);
|
||||
}
|
||||
else if (const auto* aBSplineData = std::get_if<BSplineData>(&myCurveData))
|
||||
{
|
||||
BSplineData aNewData;
|
||||
aNewData.Curve = aBSplineData->Curve;
|
||||
aNewData.EvalRep = aBSplineData->EvalRep;
|
||||
aCopy->myCurveData = std::move(aNewData);
|
||||
}
|
||||
else if (std::holds_alternative<BezierData>(myCurveData))
|
||||
{
|
||||
aCopy->myCurveData = BezierData{};
|
||||
const BezierData& aBezierData = std::get<BezierData>(myCurveData);
|
||||
BezierData aNewData;
|
||||
aNewData.Curve = aBezierData.Curve;
|
||||
aNewData.EvalRep = aBezierData.EvalRep;
|
||||
// Cache is not copied - will be rebuilt on demand.
|
||||
aCopy->myCurveData = std::move(aNewData);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -276,14 +306,18 @@ void Geom2dAdaptor_Curve::load(const occ::handle<Geom2d_Curve>& C,
|
||||
else if (TheType == STANDARD_TYPE(Geom2d_BezierCurve))
|
||||
{
|
||||
myTypeCurve = GeomAbs_BezierCurve;
|
||||
myCurveData = BezierData{};
|
||||
BezierData aBezierData;
|
||||
aBezierData.Curve = occ::down_cast<Geom2d_BezierCurve>(myCurve);
|
||||
aBezierData.EvalRep = aBezierData.Curve->EvalRepresentation();
|
||||
myCurveData = std::move(aBezierData);
|
||||
}
|
||||
else if (TheType == STANDARD_TYPE(Geom2d_BSplineCurve))
|
||||
{
|
||||
myTypeCurve = GeomAbs_BSplineCurve;
|
||||
BSplineData aBSplineData;
|
||||
aBSplineData.Curve = occ::down_cast<Geom2d_BSplineCurve>(myCurve);
|
||||
myCurveData = std::move(aBSplineData);
|
||||
aBSplineData.Curve = occ::down_cast<Geom2d_BSplineCurve>(myCurve);
|
||||
aBSplineData.EvalRep = aBSplineData.Curve->EvalRepresentation();
|
||||
myCurveData = std::move(aBSplineData);
|
||||
}
|
||||
else if (TheType == STANDARD_TYPE(Geom2d_OffsetCurve))
|
||||
{
|
||||
@@ -295,6 +329,7 @@ void Geom2dAdaptor_Curve::load(const occ::handle<Geom2d_Curve>& C,
|
||||
OffsetData anOffsetData;
|
||||
anOffsetData.BasisAdaptor = new Geom2dAdaptor_Curve(aBaseCurve, UFirst, ULast);
|
||||
anOffsetData.Offset = anOffsetCurve->Offset();
|
||||
anOffsetData.EvalRep = anOffsetCurve->EvalRepresentation();
|
||||
myCurveData = std::move(anOffsetData);
|
||||
}
|
||||
else
|
||||
@@ -682,6 +717,10 @@ std::optional<gp_Pnt2d> Geom2dAdaptor_Curve::EvalD0(double U) const
|
||||
return P;
|
||||
|
||||
case GeomAbs_BezierCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD0(U);
|
||||
}
|
||||
auto& aBezierData = std::get<BezierData>(myCurveData);
|
||||
if (aBezierData.Cache.IsNull())
|
||||
RebuildCache(U);
|
||||
@@ -690,6 +729,10 @@ std::optional<gp_Pnt2d> Geom2dAdaptor_Curve::EvalD0(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_BSplineCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD0(U);
|
||||
}
|
||||
int aStart = 0, aFinish = 0;
|
||||
const BSplineData& aBSplineData = std::get<BSplineData>(myCurveData);
|
||||
if (IsBoundary(U, aStart, aFinish))
|
||||
@@ -706,6 +749,10 @@ std::optional<gp_Pnt2d> Geom2dAdaptor_Curve::EvalD0(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD0(U);
|
||||
}
|
||||
const auto& anOffsetData = std::get<OffsetData>(myCurveData);
|
||||
if (!Geom2d_OffsetCurveUtils::EvaluateD0(U,
|
||||
anOffsetData.BasisAdaptor.get(),
|
||||
@@ -761,6 +808,10 @@ std::optional<Geom2d_Curve::ResD1> Geom2dAdaptor_Curve::EvalD1(double U) const
|
||||
return aResult;
|
||||
|
||||
case GeomAbs_BezierCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD1(U);
|
||||
}
|
||||
auto& aBezierData = std::get<BezierData>(myCurveData);
|
||||
if (aBezierData.Cache.IsNull())
|
||||
RebuildCache(U);
|
||||
@@ -769,6 +820,10 @@ std::optional<Geom2d_Curve::ResD1> Geom2dAdaptor_Curve::EvalD1(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_BSplineCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD1(U);
|
||||
}
|
||||
int aStart = 0, aFinish = 0;
|
||||
const BSplineData& aBSplineData = std::get<BSplineData>(myCurveData);
|
||||
if (IsBoundary(U, aStart, aFinish))
|
||||
@@ -785,6 +840,10 @@ std::optional<Geom2d_Curve::ResD1> Geom2dAdaptor_Curve::EvalD1(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD1(U);
|
||||
}
|
||||
const auto& anOffsetData = std::get<OffsetData>(myCurveData);
|
||||
if (!Geom2d_OffsetCurveUtils::EvaluateD1(U,
|
||||
anOffsetData.BasisAdaptor.get(),
|
||||
@@ -843,6 +902,10 @@ std::optional<Geom2d_Curve::ResD2> Geom2dAdaptor_Curve::EvalD2(double U) const
|
||||
return aResult;
|
||||
|
||||
case GeomAbs_BezierCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD2(U);
|
||||
}
|
||||
auto& aBezierData = std::get<BezierData>(myCurveData);
|
||||
if (aBezierData.Cache.IsNull())
|
||||
RebuildCache(U);
|
||||
@@ -851,6 +914,10 @@ std::optional<Geom2d_Curve::ResD2> Geom2dAdaptor_Curve::EvalD2(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_BSplineCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD2(U);
|
||||
}
|
||||
int aStart = 0, aFinish = 0;
|
||||
const BSplineData& aBSplineData = std::get<BSplineData>(myCurveData);
|
||||
if (IsBoundary(U, aStart, aFinish))
|
||||
@@ -867,6 +934,10 @@ std::optional<Geom2d_Curve::ResD2> Geom2dAdaptor_Curve::EvalD2(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD2(U);
|
||||
}
|
||||
const auto& anOffsetData = std::get<OffsetData>(myCurveData);
|
||||
if (!Geom2d_OffsetCurveUtils::EvaluateD2(U,
|
||||
anOffsetData.BasisAdaptor.get(),
|
||||
@@ -948,6 +1019,10 @@ std::optional<Geom2d_Curve::ResD3> Geom2dAdaptor_Curve::EvalD3(double U) const
|
||||
return aResult;
|
||||
|
||||
case GeomAbs_BezierCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD3(U);
|
||||
}
|
||||
auto& aBezierData = std::get<BezierData>(myCurveData);
|
||||
if (aBezierData.Cache.IsNull())
|
||||
RebuildCache(U);
|
||||
@@ -956,6 +1031,10 @@ std::optional<Geom2d_Curve::ResD3> Geom2dAdaptor_Curve::EvalD3(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_BSplineCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD3(U);
|
||||
}
|
||||
int aStart = 0, aFinish = 0;
|
||||
const BSplineData& aBSplineData = std::get<BSplineData>(myCurveData);
|
||||
if (IsBoundary(U, aStart, aFinish))
|
||||
@@ -973,6 +1052,10 @@ std::optional<Geom2d_Curve::ResD3> Geom2dAdaptor_Curve::EvalD3(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD3(U);
|
||||
}
|
||||
const auto& anOffsetData = std::get<OffsetData>(myCurveData);
|
||||
if (!Geom2d_OffsetCurveUtils::EvaluateD3(U,
|
||||
anOffsetData.BasisAdaptor.get(),
|
||||
@@ -1027,6 +1110,10 @@ std::optional<gp_Vec2d> Geom2dAdaptor_Curve::EvalDN(double U, int N) const
|
||||
return myCurve->EvalDN(U, N);
|
||||
|
||||
case GeomAbs_BSplineCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalDN(U, N);
|
||||
}
|
||||
int aStart = 0, aFinish = 0;
|
||||
if (IsBoundary(U, aStart, aFinish))
|
||||
{
|
||||
@@ -1037,6 +1124,10 @@ std::optional<gp_Vec2d> Geom2dAdaptor_Curve::EvalDN(double U, int N) const
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalDN(U, N);
|
||||
}
|
||||
const auto& anOffsetData = std::get<OffsetData>(myCurveData);
|
||||
gp_Vec2d aDN;
|
||||
if (!Geom2d_OffsetCurveUtils::EvaluateDN(U,
|
||||
|
||||
@@ -38,6 +38,11 @@ class gp_Vec2d;
|
||||
class Geom2d_BezierCurve;
|
||||
class Geom2d_BSplineCurve;
|
||||
|
||||
namespace Geom2d_EvalRepCurveDesc
|
||||
{
|
||||
class Base;
|
||||
}
|
||||
|
||||
//! An interface between the services provided by any
|
||||
//! curve from the package Geom2d and those required
|
||||
//! of the curve by algorithms which use it.
|
||||
@@ -52,21 +57,25 @@ public:
|
||||
//! Internal structure for 2D offset curve evaluation data.
|
||||
struct OffsetData
|
||||
{
|
||||
occ::handle<Geom2dAdaptor_Curve> BasisAdaptor; //!< Adaptor for basis curve
|
||||
double Offset = 0.0; //!< Offset distance
|
||||
occ::handle<Geom2dAdaptor_Curve> BasisAdaptor; //!< Adaptor for basis curve
|
||||
double Offset = 0.0; //!< Offset distance
|
||||
occ::handle<Geom2d_EvalRepCurveDesc::Base> EvalRep; //!< Eval representation descriptor
|
||||
};
|
||||
|
||||
//! Internal structure for Bezier curve evaluation data.
|
||||
struct BezierData
|
||||
{
|
||||
mutable occ::handle<BSplCLib_Cache> Cache; //!< Cached data for evaluation
|
||||
occ::handle<Geom2d_BezierCurve> Curve; //!< Bezier curve to prevent downcasts
|
||||
mutable occ::handle<BSplCLib_Cache> Cache; //!< Cached data for evaluation
|
||||
occ::handle<Geom2d_EvalRepCurveDesc::Base> EvalRep; //!< Eval representation descriptor
|
||||
};
|
||||
|
||||
//! Internal structure for BSpline curve evaluation data.
|
||||
struct BSplineData
|
||||
{
|
||||
occ::handle<Geom2d_BSplineCurve> Curve; //!< BSpline curve to prevent downcasts
|
||||
mutable occ::handle<BSplCLib_Cache> Cache; //!< Cached data for evaluation
|
||||
occ::handle<Geom2d_BSplineCurve> Curve; //!< BSpline curve to prevent downcasts
|
||||
mutable occ::handle<BSplCLib_Cache> Cache; //!< Cached data for evaluation
|
||||
occ::handle<Geom2d_EvalRepCurveDesc::Base> EvalRep; //!< Eval representation descriptor
|
||||
};
|
||||
|
||||
//! Variant type for 2D curve-specific evaluation data.
|
||||
|
||||
@@ -41,6 +41,9 @@ set(OCCT_Geom_FILES
|
||||
Geom_ElementarySurface.hxx
|
||||
Geom_Ellipse.cxx
|
||||
Geom_Ellipse.hxx
|
||||
Geom_EvalRepCurveDesc.hxx
|
||||
Geom_EvalRepSurfaceDesc.hxx
|
||||
Geom_EvalRepUtils.pxx
|
||||
Geom_Geometry.cxx
|
||||
Geom_Geometry.hxx
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include <BSplCLib.hxx>
|
||||
#include <ElCLib.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include "Geom_EvalRepCurveDesc.hxx"
|
||||
#include "Geom_EvalRepUtils.pxx"
|
||||
#include <Geom_Geometry.hxx>
|
||||
#include <Geom_UndefinedDerivative.hxx>
|
||||
#include <gp.hxx>
|
||||
@@ -41,6 +43,7 @@
|
||||
#include <Standard_NoSuchObject.hxx>
|
||||
#include <Standard_NotImplemented.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <Standard_ProgramError.hxx>
|
||||
#include <Standard_Real.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
@@ -48,6 +51,15 @@ IMPLEMENT_STANDARD_RTTIEXT(Geom_BSplineCurve, Geom_BoundedCurve)
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Geom_BSplineCurve::SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc)
|
||||
{
|
||||
Geom_EvalRepUtils::ValidateCurveDesc(theDesc, this);
|
||||
myEvalRep = theDesc;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
static void CheckCurveData(const NCollection_Array1<gp_Pnt>& CPoles,
|
||||
const NCollection_Array1<double>& CKnots,
|
||||
const NCollection_Array1<int>& CMults,
|
||||
@@ -105,6 +117,7 @@ Geom_BSplineCurve::Geom_BSplineCurve(const Geom_BSplineCurve& theOther)
|
||||
myKnots(theOther.myKnots),
|
||||
myFlatKnots(theOther.myFlatKnots),
|
||||
myMults(theOther.myMults),
|
||||
myEvalRep(Geom_EvalRepUtils::CloneCurveDesc(theOther.myEvalRep)),
|
||||
myDeg(theOther.myDeg),
|
||||
myPeriodic(theOther.myPeriodic),
|
||||
myRational(theOther.myRational),
|
||||
@@ -220,6 +233,8 @@ void Geom_BSplineCurve::IncreaseDegree(const int Degree)
|
||||
if (Degree == myDeg)
|
||||
return;
|
||||
|
||||
ClearEvalRepresentation();
|
||||
|
||||
if (Degree < myDeg || Degree > Geom_BSplineCurve::MaxDegree())
|
||||
{
|
||||
throw Standard_ConstructionError("BSpline curve: IncreaseDegree: bad degree value");
|
||||
@@ -336,6 +351,8 @@ void Geom_BSplineCurve::InsertKnots(const NCollection_Array1<double>& Knots,
|
||||
if (nbpoles == myPoles.Length())
|
||||
return;
|
||||
|
||||
ClearEvalRepresentation();
|
||||
|
||||
NCollection_Array1<gp_Pnt> npoles(1, nbpoles);
|
||||
NCollection_Array1<double> nknots(1, nbknots);
|
||||
NCollection_Array1<int> nmults(1, nbknots);
|
||||
@@ -423,6 +440,8 @@ bool Geom_BSplineCurve::RemoveKnot(const int Index, const int M, const double To
|
||||
return false;
|
||||
}
|
||||
|
||||
ClearEvalRepresentation();
|
||||
|
||||
if (IsRational())
|
||||
myWeights = std::move(nweights);
|
||||
else
|
||||
@@ -440,6 +459,7 @@ bool Geom_BSplineCurve::RemoveKnot(const int Index, const int M, const double To
|
||||
|
||||
void Geom_BSplineCurve::Reverse()
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
BSplCLib::Reverse(myKnots);
|
||||
BSplCLib::Reverse(myMults);
|
||||
int last;
|
||||
@@ -467,6 +487,8 @@ void Geom_BSplineCurve::Segment(const double U1, const double U2, const double t
|
||||
if (U2 < U1)
|
||||
throw Standard_DomainError("Geom_BSplineCurve::Segment");
|
||||
|
||||
ClearEvalRepresentation();
|
||||
|
||||
double NewU1, NewU2;
|
||||
double U, DU = 0, aDDU = 0;
|
||||
int index;
|
||||
@@ -660,6 +682,7 @@ void Geom_BSplineCurve::SetKnot(const int Index, const double K)
|
||||
}
|
||||
if (K != myKnots.Value(Index))
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
myKnots.SetValue(Index, K);
|
||||
myMaxDerivInvOk = false;
|
||||
updateKnots();
|
||||
@@ -671,6 +694,7 @@ void Geom_BSplineCurve::SetKnot(const int Index, const double K)
|
||||
void Geom_BSplineCurve::SetKnots(const NCollection_Array1<double>& K)
|
||||
{
|
||||
CheckCurveData(myPoles, K, myMults, myDeg, myPeriodic);
|
||||
ClearEvalRepresentation();
|
||||
myKnots = K;
|
||||
myMaxDerivInvOk = false;
|
||||
updateKnots();
|
||||
@@ -688,6 +712,7 @@ void Geom_BSplineCurve::SetKnot(const int Index, const double K, const int M)
|
||||
|
||||
void Geom_BSplineCurve::SetPeriodic()
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
int first = FirstUKnotIndex();
|
||||
int last = LastUKnotIndex();
|
||||
|
||||
@@ -724,6 +749,8 @@ void Geom_BSplineCurve::SetOrigin(const int Index)
|
||||
if (!myPeriodic)
|
||||
throw Standard_NoSuchObject("Geom_BSplineCurve::SetOrigin");
|
||||
|
||||
ClearEvalRepresentation();
|
||||
|
||||
int i, k;
|
||||
int first = FirstUKnotIndex();
|
||||
int last = LastUKnotIndex();
|
||||
@@ -819,6 +846,7 @@ void Geom_BSplineCurve::SetOrigin(const double U, const double Tol)
|
||||
|
||||
if (std::abs(U - u) > Tol)
|
||||
{ // On reparametre la courbe
|
||||
ClearEvalRepresentation();
|
||||
double delta = U - u;
|
||||
uf += delta;
|
||||
ul += delta;
|
||||
@@ -859,6 +887,7 @@ void Geom_BSplineCurve::SetNotPeriodic()
|
||||
{
|
||||
if (myPeriodic)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
int NbKnots, NbPoles;
|
||||
BSplCLib::PrepareUnperiodize(myDeg, myMults, NbKnots, NbPoles);
|
||||
|
||||
@@ -903,6 +932,7 @@ void Geom_BSplineCurve::SetPole(const int Index, const gp_Pnt& P)
|
||||
{
|
||||
if (Index < 1 || Index > myPoles.Length())
|
||||
throw Standard_OutOfRange("BSpline curve: SetPole: index and #pole mismatch");
|
||||
ClearEvalRepresentation();
|
||||
myPoles.SetValue(Index, P);
|
||||
myMaxDerivInvOk = false;
|
||||
}
|
||||
@@ -925,6 +955,8 @@ void Geom_BSplineCurve::SetWeight(const int Index, const double W)
|
||||
if (W <= gp::Resolution())
|
||||
throw Standard_ConstructionError("BSpline curve: SetWeight: Weight too small");
|
||||
|
||||
ClearEvalRepresentation();
|
||||
|
||||
bool rat = IsRational() || (std::abs(W - 1.) > gp::Resolution());
|
||||
|
||||
if (rat)
|
||||
@@ -980,6 +1012,7 @@ void Geom_BSplineCurve::MovePoint(const double U,
|
||||
npoles);
|
||||
if (FirstModifiedPole)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
myPoles = std::move(npoles);
|
||||
myMaxDerivInvOk = false;
|
||||
}
|
||||
@@ -1027,6 +1060,7 @@ void Geom_BSplineCurve::MovePointAndTangent(const double U,
|
||||
ErrorStatus);
|
||||
if (!ErrorStatus)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
myPoles = std::move(new_poles);
|
||||
myMaxDerivInvOk = false;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,11 @@
|
||||
class gp_Trsf;
|
||||
class Geom_Geometry;
|
||||
|
||||
namespace Geom_EvalRepCurveDesc
|
||||
{
|
||||
class Base;
|
||||
}
|
||||
|
||||
//! Definition of the B_spline curve.
|
||||
//! A B-spline curve can be
|
||||
//! Uniform or non-uniform
|
||||
@@ -166,6 +171,20 @@ public:
|
||||
//! @param[in] theOther the BSpline curve to copy from
|
||||
Standard_EXPORT Geom_BSplineCurve(const Geom_BSplineCurve& theOther);
|
||||
|
||||
//! Returns true if an evaluation representation is attached.
|
||||
bool HasEvalRepresentation() const { return !myEvalRep.IsNull(); }
|
||||
|
||||
//! Returns the current evaluation representation descriptor (may be null).
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& EvalRepresentation() const { return myEvalRep; }
|
||||
|
||||
//! Sets a new evaluation representation.
|
||||
//! Validates descriptor data and ensures no circular references.
|
||||
Standard_EXPORT void SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc);
|
||||
|
||||
//! Removes the evaluation representation.
|
||||
void ClearEvalRepresentation() { myEvalRep.Nullify(); }
|
||||
|
||||
//! Increases the degree of this BSpline curve to
|
||||
//! Degree. As a result, the poles, weights and
|
||||
//! multiplicities tables are modified; the knots table is
|
||||
@@ -817,18 +836,19 @@ protected:
|
||||
void updateKnots();
|
||||
|
||||
private:
|
||||
NCollection_Array1<gp_Pnt> myPoles;
|
||||
NCollection_Array1<double> myWeights;
|
||||
NCollection_Array1<double> myKnots;
|
||||
NCollection_Array1<double> myFlatKnots;
|
||||
NCollection_Array1<int> myMults;
|
||||
int myDeg = 0;
|
||||
bool myPeriodic = false;
|
||||
bool myRational = false;
|
||||
GeomAbs_BSplKnotDistribution myKnotSet = GeomAbs_NonUniform;
|
||||
GeomAbs_Shape mySmooth = GeomAbs_C0;
|
||||
double myMaxDerivInv = 0.0;
|
||||
bool myMaxDerivInvOk = false;
|
||||
NCollection_Array1<gp_Pnt> myPoles;
|
||||
NCollection_Array1<double> myWeights;
|
||||
NCollection_Array1<double> myKnots;
|
||||
NCollection_Array1<double> myFlatKnots;
|
||||
NCollection_Array1<int> myMults;
|
||||
occ::handle<Geom_EvalRepCurveDesc::Base> myEvalRep;
|
||||
int myDeg = 0;
|
||||
bool myPeriodic = false;
|
||||
bool myRational = false;
|
||||
GeomAbs_BSplKnotDistribution myKnotSet = GeomAbs_NonUniform;
|
||||
GeomAbs_Shape mySmooth = GeomAbs_C0;
|
||||
double myMaxDerivInv = 0.0;
|
||||
bool myMaxDerivInvOk = false;
|
||||
};
|
||||
|
||||
#endif // _Geom_BSplineCurve_HeaderFile
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#include <BSplCLib.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include "Geom_EvalRepCurveDesc.hxx"
|
||||
#include "Geom_EvalRepUtils.pxx"
|
||||
#include <Geom_UndefinedDerivative.hxx>
|
||||
#include <gp.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
@@ -160,6 +162,12 @@ int Geom_BSplineCurve::Degree() const
|
||||
|
||||
std::optional<gp_Pnt> Geom_BSplineCurve::EvalD0(const double U) const
|
||||
{
|
||||
if (const std::optional<gp_Pnt> aEvalRepResult = Geom_EvalRepUtils::TryEvalCurveD0(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
gp_Pnt P;
|
||||
int aSpanIndex = 0;
|
||||
double aNewU(U);
|
||||
@@ -176,6 +184,13 @@ std::optional<gp_Pnt> Geom_BSplineCurve::EvalD0(const double U) const
|
||||
|
||||
std::optional<Geom_Curve::ResD1> Geom_BSplineCurve::EvalD1(const double U) const
|
||||
{
|
||||
if (const std::optional<Geom_Curve::ResD1> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalCurveD1(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD1> aResult{std::in_place};
|
||||
int aSpanIndex = 0;
|
||||
double aNewU(U);
|
||||
@@ -201,6 +216,13 @@ std::optional<Geom_Curve::ResD1> Geom_BSplineCurve::EvalD1(const double U) const
|
||||
|
||||
std::optional<Geom_Curve::ResD2> Geom_BSplineCurve::EvalD2(const double U) const
|
||||
{
|
||||
if (const std::optional<Geom_Curve::ResD2> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalCurveD2(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD2> aResult{std::in_place};
|
||||
int aSpanIndex = 0;
|
||||
double aNewU(U);
|
||||
@@ -227,6 +249,13 @@ std::optional<Geom_Curve::ResD2> Geom_BSplineCurve::EvalD2(const double U) const
|
||||
|
||||
std::optional<Geom_Curve::ResD3> Geom_BSplineCurve::EvalD3(const double U) const
|
||||
{
|
||||
if (const std::optional<Geom_Curve::ResD3> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalCurveD3(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD3> aResult{std::in_place};
|
||||
int aSpanIndex = 0;
|
||||
double aNewU(U);
|
||||
@@ -256,6 +285,14 @@ std::optional<gp_Vec> Geom_BSplineCurve::EvalDN(const double U, const int N) con
|
||||
{
|
||||
if (N < 1)
|
||||
return std::nullopt;
|
||||
|
||||
if (const std::optional<gp_Vec> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalCurveDN(myEvalRep, U, N);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
gp_Vec V;
|
||||
BSplCLib::DN(U, N, 0, myDeg, myPeriodic, myPoles, Weights(), myFlatKnots, BSplCLib::NoMults(), V);
|
||||
return V;
|
||||
@@ -605,6 +642,7 @@ bool Geom_BSplineCurve::IsRational() const
|
||||
|
||||
void Geom_BSplineCurve::Transform(const gp_Trsf& T)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
for (int I = 1; I <= myPoles.Length(); I++)
|
||||
myPoles.ChangeValue(I).Transform(T);
|
||||
myMaxDerivInvOk = false;
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <BSplCLib.hxx>
|
||||
#include <BSplSLib.hxx>
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
#include "Geom_EvalRepSurfaceDesc.hxx"
|
||||
#include "Geom_EvalRepUtils.pxx"
|
||||
#include <Geom_Geometry.hxx>
|
||||
#include <Geom_UndefinedDerivative.hxx>
|
||||
#include <gp.hxx>
|
||||
@@ -34,12 +36,22 @@
|
||||
#include <Standard_DomainError.hxx>
|
||||
#include <Standard_NotImplemented.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <Standard_ProgramError.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Geom_BSplineSurface, Geom_BoundedSurface)
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Geom_BSplineSurface::SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc)
|
||||
{
|
||||
Geom_EvalRepUtils::ValidateSurfaceDesc(theDesc, this);
|
||||
myEvalRep = theDesc;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
static void CheckSurfaceData(const NCollection_Array2<gp_Pnt>& SPoles,
|
||||
const NCollection_Array1<double>& SUKnots,
|
||||
const NCollection_Array1<double>& SVKnots,
|
||||
@@ -142,6 +154,7 @@ Geom_BSplineSurface::Geom_BSplineSurface(const Geom_BSplineSurface& theOther)
|
||||
myVFlatKnots(theOther.myVFlatKnots),
|
||||
myUMults(theOther.myUMults),
|
||||
myVMults(theOther.myVMults),
|
||||
myEvalRep(Geom_EvalRepUtils::CloneSurfaceDesc(theOther.myEvalRep)),
|
||||
myUDeg(theOther.myUDeg),
|
||||
myVDeg(theOther.myVDeg),
|
||||
myUPeriodic(theOther.myUPeriodic),
|
||||
@@ -293,6 +306,7 @@ Geom_BSplineSurface::Geom_BSplineSurface(const NCollection_Array2<gp_Pnt>& Poles
|
||||
|
||||
void Geom_BSplineSurface::ExchangeUV()
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
int LC = myPoles.LowerCol();
|
||||
int UC = myPoles.UpperCol();
|
||||
int LR = myPoles.LowerRow();
|
||||
@@ -345,6 +359,8 @@ void Geom_BSplineSurface::IncreaseDegree(const int UDegree, const int VDegree)
|
||||
if (UDegree < myUDeg || UDegree > Geom_BSplineSurface::MaxDegree())
|
||||
throw Standard_ConstructionError("Geom_BSplineSurface::IncreaseDegree: bad U degree value");
|
||||
|
||||
ClearEvalRepresentation();
|
||||
|
||||
int FromK1 = FirstUKnotIndex();
|
||||
int ToK2 = LastUKnotIndex();
|
||||
|
||||
@@ -406,6 +422,8 @@ void Geom_BSplineSurface::IncreaseDegree(const int UDegree, const int VDegree)
|
||||
if (VDegree < myVDeg || VDegree > Geom_BSplineSurface::MaxDegree())
|
||||
throw Standard_ConstructionError("Geom_BSplineSurface::IncreaseDegree: bad V degree value");
|
||||
|
||||
ClearEvalRepresentation();
|
||||
|
||||
int FromK1 = FirstVKnotIndex();
|
||||
int ToK2 = LastVKnotIndex();
|
||||
|
||||
@@ -518,6 +536,7 @@ void Geom_BSplineSurface::segment(const double U1,
|
||||
const bool SegmentInU,
|
||||
const bool SegmentInV)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
double deltaU = U2 - U1;
|
||||
if (myUPeriodic)
|
||||
{
|
||||
@@ -876,6 +895,7 @@ void Geom_BSplineSurface::SetUKnot(const int UIndex, const double K)
|
||||
|
||||
if (K != myUKnots.Value(NewIndex))
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
myUKnots.SetValue(NewIndex, K);
|
||||
myMaxDerivInvOk = false;
|
||||
updateUKnots();
|
||||
@@ -908,6 +928,7 @@ void Geom_BSplineSurface::SetUKnots(const NCollection_Array1<double>& UK)
|
||||
}
|
||||
}
|
||||
double K1 = UK(Lower);
|
||||
ClearEvalRepresentation();
|
||||
for (int i = Lower; i <= Upper; i++)
|
||||
{
|
||||
myUKnots.SetValue(i, UK(i));
|
||||
@@ -965,6 +986,7 @@ void Geom_BSplineSurface::SetVKnot(const int VIndex, const double K)
|
||||
|
||||
if (K != myVKnots.Value(NewIndex))
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
myVKnots.SetValue(NewIndex, K);
|
||||
myMaxDerivInvOk = false;
|
||||
updateVKnots();
|
||||
@@ -997,6 +1019,7 @@ void Geom_BSplineSurface::SetVKnots(const NCollection_Array1<double>& VK)
|
||||
}
|
||||
}
|
||||
double K1 = VK(Lower);
|
||||
ClearEvalRepresentation();
|
||||
for (int i = Lower; i <= Upper; i++)
|
||||
{
|
||||
myVKnots.SetValue(i, VK(i));
|
||||
@@ -1226,6 +1249,7 @@ void Geom_BSplineSurface::SetWeight(const int UIndex, const int VIndex, const do
|
||||
{
|
||||
throw Standard_OutOfRange("Geom_BSplineSurface::SetWeight: Index and #pole mismatch");
|
||||
}
|
||||
ClearEvalRepresentation();
|
||||
if (!myURational && !myVRational)
|
||||
{
|
||||
// Make an owned copy of the unit weights view before modifying.
|
||||
@@ -1252,6 +1276,7 @@ void Geom_BSplineSurface::SetWeightCol(const int VIndex,
|
||||
{
|
||||
throw Standard_ConstructionError("Geom_BSplineSurface::SetWeightCol: invalid array dimension");
|
||||
}
|
||||
ClearEvalRepresentation();
|
||||
if (!myURational && !myVRational)
|
||||
{
|
||||
// Make an owned copy of the unit weights view before modifying.
|
||||
@@ -1289,6 +1314,7 @@ void Geom_BSplineSurface::SetWeightRow(const int UIndex,
|
||||
|
||||
throw Standard_ConstructionError("Geom_BSplineSurface::SetWeightRow: invalid array dimension");
|
||||
}
|
||||
ClearEvalRepresentation();
|
||||
if (!myURational && !myVRational)
|
||||
{
|
||||
// Make an owned copy of the unit weights view before modifying.
|
||||
|
||||
@@ -31,6 +31,11 @@ class Geom_Curve;
|
||||
class gp_Trsf;
|
||||
class Geom_Geometry;
|
||||
|
||||
namespace Geom_EvalRepSurfaceDesc
|
||||
{
|
||||
class Base;
|
||||
}
|
||||
|
||||
//! Describes a BSpline surface.
|
||||
//! In each parametric direction, a BSpline surface can be:
|
||||
//! - uniform or non-uniform,
|
||||
@@ -220,6 +225,20 @@ public:
|
||||
//! @param[in] theOther the BSpline surface to copy from
|
||||
Standard_EXPORT Geom_BSplineSurface(const Geom_BSplineSurface& theOther);
|
||||
|
||||
//! Returns true if an evaluation representation is attached.
|
||||
bool HasEvalRepresentation() const { return !myEvalRep.IsNull(); }
|
||||
|
||||
//! Returns the current evaluation representation descriptor (may be null).
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& EvalRepresentation() const { return myEvalRep; }
|
||||
|
||||
//! Sets a new evaluation representation.
|
||||
//! Validates descriptor data and ensures no circular references.
|
||||
Standard_EXPORT void SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc);
|
||||
|
||||
//! Removes the evaluation representation.
|
||||
void ClearEvalRepresentation() { myEvalRep.Nullify(); }
|
||||
|
||||
//! Exchanges the u and v parametric directions on
|
||||
//! this BSpline surface.
|
||||
//! As a consequence:
|
||||
@@ -1280,27 +1299,28 @@ protected:
|
||||
void updateVKnots();
|
||||
|
||||
private:
|
||||
NCollection_Array2<gp_Pnt> myPoles;
|
||||
NCollection_Array2<double> myWeights;
|
||||
NCollection_Array1<double> myUKnots;
|
||||
NCollection_Array1<double> myVKnots;
|
||||
NCollection_Array1<double> myUFlatKnots;
|
||||
NCollection_Array1<double> myVFlatKnots;
|
||||
NCollection_Array1<int> myUMults;
|
||||
NCollection_Array1<int> myVMults;
|
||||
int myUDeg = 0;
|
||||
int myVDeg = 0;
|
||||
bool myUPeriodic = false;
|
||||
bool myVPeriodic = false;
|
||||
bool myURational = false;
|
||||
bool myVRational = false;
|
||||
GeomAbs_BSplKnotDistribution myUKnotSet = GeomAbs_NonUniform;
|
||||
GeomAbs_BSplKnotDistribution myVKnotSet = GeomAbs_NonUniform;
|
||||
GeomAbs_Shape myUSmooth = GeomAbs_C0;
|
||||
GeomAbs_Shape myVSmooth = GeomAbs_C0;
|
||||
double myUMaxDerivInv = 0.0;
|
||||
double myVMaxDerivInv = 0.0;
|
||||
bool myMaxDerivInvOk = false;
|
||||
NCollection_Array2<gp_Pnt> myPoles;
|
||||
NCollection_Array2<double> myWeights;
|
||||
NCollection_Array1<double> myUKnots;
|
||||
NCollection_Array1<double> myVKnots;
|
||||
NCollection_Array1<double> myUFlatKnots;
|
||||
NCollection_Array1<double> myVFlatKnots;
|
||||
NCollection_Array1<int> myUMults;
|
||||
NCollection_Array1<int> myVMults;
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::Base> myEvalRep;
|
||||
int myUDeg = 0;
|
||||
int myVDeg = 0;
|
||||
bool myUPeriodic = false;
|
||||
bool myVPeriodic = false;
|
||||
bool myURational = false;
|
||||
bool myVRational = false;
|
||||
GeomAbs_BSplKnotDistribution myUKnotSet = GeomAbs_NonUniform;
|
||||
GeomAbs_BSplKnotDistribution myVKnotSet = GeomAbs_NonUniform;
|
||||
GeomAbs_Shape myUSmooth = GeomAbs_C0;
|
||||
GeomAbs_Shape myVSmooth = GeomAbs_C0;
|
||||
double myUMaxDerivInv = 0.0;
|
||||
double myVMaxDerivInv = 0.0;
|
||||
bool myMaxDerivInvOk = false;
|
||||
};
|
||||
|
||||
#endif // _Geom_BSplineSurface_HeaderFile
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
#include <Geom_Curve.hxx>
|
||||
#include "Geom_EvalRepSurfaceDesc.hxx"
|
||||
#include "Geom_EvalRepUtils.pxx"
|
||||
#include <Geom_UndefinedDerivative.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Trsf.hxx>
|
||||
@@ -108,6 +110,13 @@ bool Geom_BSplineSurface::IsCNv(const int N) const
|
||||
|
||||
std::optional<gp_Pnt> Geom_BSplineSurface::EvalD0(const double U, const double V) const
|
||||
{
|
||||
if (const std::optional<gp_Pnt> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD0(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
double aNewU = U;
|
||||
double aNewV = V;
|
||||
PeriodicNormalization(aNewU, aNewV);
|
||||
@@ -137,6 +146,13 @@ std::optional<gp_Pnt> Geom_BSplineSurface::EvalD0(const double U, const double V
|
||||
|
||||
std::optional<Geom_Surface::ResD1> Geom_BSplineSurface::EvalD1(const double U, const double V) const
|
||||
{
|
||||
if (const std::optional<Geom_Surface::ResD1> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD1(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
double aNewU = U;
|
||||
double aNewV = V;
|
||||
PeriodicNormalization(aNewU, aNewV);
|
||||
@@ -176,6 +192,13 @@ std::optional<Geom_Surface::ResD1> Geom_BSplineSurface::EvalD1(const double U, c
|
||||
|
||||
std::optional<Geom_Surface::ResD2> Geom_BSplineSurface::EvalD2(const double U, const double V) const
|
||||
{
|
||||
if (const std::optional<Geom_Surface::ResD2> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD2(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
double aNewU = U;
|
||||
double aNewV = V;
|
||||
PeriodicNormalization(aNewU, aNewV);
|
||||
@@ -218,6 +241,13 @@ std::optional<Geom_Surface::ResD2> Geom_BSplineSurface::EvalD2(const double U, c
|
||||
|
||||
std::optional<Geom_Surface::ResD3> Geom_BSplineSurface::EvalD3(const double U, const double V) const
|
||||
{
|
||||
if (const std::optional<Geom_Surface::ResD3> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD3(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Surface::ResD3> aResult{std::in_place};
|
||||
BSplSLib::D3(U,
|
||||
V,
|
||||
@@ -257,6 +287,14 @@ std::optional<gp_Vec> Geom_BSplineSurface::EvalDN(const double U,
|
||||
{
|
||||
if (Nu + Nv < 1 || Nu < 0 || Nv < 0)
|
||||
return std::nullopt;
|
||||
|
||||
if (const std::optional<gp_Vec> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceDN(myEvalRep, U, V, Nu, Nv);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
gp_Vec Vn;
|
||||
BSplSLib::DN(U,
|
||||
V,
|
||||
@@ -888,6 +926,7 @@ const NCollection_Array2<double>* Geom_BSplineSurface::Weights() const
|
||||
|
||||
void Geom_BSplineSurface::Transform(const gp_Trsf& T)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
for (int j = myPoles.LowerCol(); j <= myPoles.UpperCol(); j++)
|
||||
{
|
||||
for (int i = myPoles.LowerRow(); i <= myPoles.UpperRow(); i++)
|
||||
@@ -902,6 +941,7 @@ void Geom_BSplineSurface::Transform(const gp_Trsf& T)
|
||||
|
||||
void Geom_BSplineSurface::SetUPeriodic()
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
int first = FirstUKnotIndex();
|
||||
int last = LastUKnotIndex();
|
||||
|
||||
@@ -940,6 +980,7 @@ void Geom_BSplineSurface::SetUPeriodic()
|
||||
|
||||
void Geom_BSplineSurface::SetVPeriodic()
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
int first = FirstVKnotIndex();
|
||||
int last = LastVKnotIndex();
|
||||
|
||||
@@ -981,6 +1022,8 @@ void Geom_BSplineSurface::SetUOrigin(const int Index)
|
||||
if (!myUPeriodic)
|
||||
throw Standard_NoSuchObject("Geom_BSplineSurface::SetUOrigin: surface is not U periodic");
|
||||
|
||||
ClearEvalRepresentation();
|
||||
|
||||
int i, j, k;
|
||||
int first = FirstUKnotIndex();
|
||||
int last = LastUKnotIndex();
|
||||
@@ -1079,6 +1122,8 @@ void Geom_BSplineSurface::SetVOrigin(const int Index)
|
||||
if (!myVPeriodic)
|
||||
throw Standard_NoSuchObject("Geom_BSplineSurface::SetVOrigin: surface is not V periodic");
|
||||
|
||||
ClearEvalRepresentation();
|
||||
|
||||
int i, j, k;
|
||||
int first = FirstVKnotIndex();
|
||||
int last = LastVKnotIndex();
|
||||
@@ -1176,6 +1221,7 @@ void Geom_BSplineSurface::SetUNotPeriodic()
|
||||
{
|
||||
if (myUPeriodic)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
int NbKnots, NbPoles;
|
||||
BSplCLib::PrepareUnperiodize(myUDeg, myUMults, NbKnots, NbPoles);
|
||||
|
||||
@@ -1231,6 +1277,7 @@ void Geom_BSplineSurface::SetVNotPeriodic()
|
||||
{
|
||||
if (myVPeriodic)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
int NbKnots, NbPoles;
|
||||
BSplCLib::PrepareUnperiodize(myVDeg, myVMults, NbKnots, NbPoles);
|
||||
|
||||
@@ -1482,6 +1529,7 @@ void Geom_BSplineSurface::LocateV(const double V,
|
||||
|
||||
void Geom_BSplineSurface::UReverse()
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
BSplCLib::Reverse(myUMults);
|
||||
BSplCLib::Reverse(myUKnots);
|
||||
int last;
|
||||
@@ -1506,6 +1554,7 @@ double Geom_BSplineSurface::UReversedParameter(const double U) const
|
||||
|
||||
void Geom_BSplineSurface::VReverse()
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
BSplCLib::Reverse(myVMults);
|
||||
BSplCLib::Reverse(myVKnots);
|
||||
int last;
|
||||
@@ -1540,6 +1589,7 @@ void Geom_BSplineSurface::SetPoleCol(const int VIndex, const NCollection_Array1<
|
||||
throw Standard_ConstructionError("Geom_BSplineSurface::SetPoleCol: invalid array dimension");
|
||||
}
|
||||
|
||||
ClearEvalRepresentation();
|
||||
for (int I = CPoles.Lower(); I <= CPoles.Upper(); I++)
|
||||
{
|
||||
myPoles(I + myPoles.LowerRow() - 1, VIndex + myPoles.LowerCol() - 1) = CPoles(I);
|
||||
@@ -1571,6 +1621,7 @@ void Geom_BSplineSurface::SetPoleRow(const int UIndex, const NCollection_Array1<
|
||||
throw Standard_ConstructionError("Geom_BSplineSurface::SetPoleRow: invalid array dimension");
|
||||
}
|
||||
|
||||
ClearEvalRepresentation();
|
||||
for (int I = CPoles.Lower(); I <= CPoles.Upper(); I++)
|
||||
{
|
||||
myPoles(UIndex + myPoles.LowerRow() - 1, I + myPoles.LowerCol() - 1) = CPoles(I);
|
||||
@@ -1592,6 +1643,7 @@ void Geom_BSplineSurface::SetPoleRow(const int UIndex,
|
||||
|
||||
void Geom_BSplineSurface::SetPole(const int UIndex, const int VIndex, const gp_Pnt& P)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
myPoles.SetValue(UIndex + myPoles.LowerRow() - 1, VIndex + myPoles.LowerCol() - 1, P);
|
||||
myMaxDerivInvOk = false;
|
||||
}
|
||||
@@ -1654,6 +1706,7 @@ void Geom_BSplineSurface::MovePoint(const double U,
|
||||
npoles);
|
||||
if (UFirstModifiedPole)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
myPoles = std::move(npoles);
|
||||
}
|
||||
myMaxDerivInvOk = false;
|
||||
@@ -1778,6 +1831,8 @@ void Geom_BSplineSurface::InsertUKnots(const NCollection_Array1<double>& Knots,
|
||||
if (nbpoles == myPoles.ColLength())
|
||||
return;
|
||||
|
||||
ClearEvalRepresentation();
|
||||
|
||||
NCollection_Array2<gp_Pnt> npoles(1, nbpoles, 1, myPoles.RowLength());
|
||||
NCollection_Array1<double> nknots(1, nbknots);
|
||||
NCollection_Array1<int> nmults(1, nbknots);
|
||||
@@ -1853,6 +1908,8 @@ void Geom_BSplineSurface::InsertVKnots(const NCollection_Array1<double>& Knots,
|
||||
if (nbpoles == myPoles.RowLength())
|
||||
return;
|
||||
|
||||
ClearEvalRepresentation();
|
||||
|
||||
NCollection_Array2<gp_Pnt> npoles(1, myPoles.ColLength(), 1, nbpoles);
|
||||
NCollection_Array1<double> nknots(1, nbknots);
|
||||
NCollection_Array1<int> nmults(1, nbknots);
|
||||
@@ -1970,6 +2027,7 @@ bool Geom_BSplineSurface::RemoveUKnot(const int Index, const int M, const double
|
||||
myWeights = BSplSLib::UnitWeights(npoles.ColLength(), npoles.RowLength());
|
||||
}
|
||||
|
||||
ClearEvalRepresentation();
|
||||
myPoles = std::move(npoles);
|
||||
myUKnots = std::move(nknots);
|
||||
myUMults = std::move(nmults);
|
||||
@@ -2046,9 +2104,11 @@ bool Geom_BSplineSurface::RemoveVKnot(const int Index, const int M, const double
|
||||
myWeights = BSplSLib::UnitWeights(npoles.ColLength(), npoles.RowLength());
|
||||
}
|
||||
|
||||
myPoles = std::move(npoles);
|
||||
myVKnots = std::move(nknots);
|
||||
myVMults = std::move(nmults);
|
||||
ClearEvalRepresentation();
|
||||
myPoles = std::move(npoles);
|
||||
myVKnots = std::move(nknots);
|
||||
myVMults = std::move(nmults);
|
||||
|
||||
myMaxDerivInvOk = false;
|
||||
updateVKnots();
|
||||
return true;
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
// Suppressed Swaps, added Init, removed typedefs
|
||||
|
||||
#include <Geom_BezierCurve.hxx>
|
||||
#include "Geom_EvalRepCurveDesc.hxx"
|
||||
#include "Geom_EvalRepUtils.pxx"
|
||||
#include <Geom_Geometry.hxx>
|
||||
#include <gp.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
@@ -35,6 +37,7 @@
|
||||
#include <Standard_ConstructionError.hxx>
|
||||
#include <Standard_DimensionError.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <Standard_ProgramError.hxx>
|
||||
#include <Standard_RangeError.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
@@ -45,6 +48,15 @@ IMPLEMENT_STANDARD_RTTIEXT(Geom_BezierCurve, Geom_BoundedCurve)
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Geom_BezierCurve::SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc)
|
||||
{
|
||||
Geom_EvalRepUtils::ValidateCurveDesc(theDesc, this);
|
||||
myEvalRep = theDesc;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
static bool Rational(const NCollection_Array1<double>& W)
|
||||
{
|
||||
int i, n = W.Length();
|
||||
@@ -64,6 +76,7 @@ Geom_BezierCurve::Geom_BezierCurve(const Geom_BezierCurve& theOther)
|
||||
: myPoles(theOther.myPoles),
|
||||
myWeights(theOther.myRational ? NCollection_Array1<double>(theOther.myWeights)
|
||||
: BSplCLib::UnitWeights(theOther.myPoles.Length())),
|
||||
myEvalRep(Geom_EvalRepUtils::CloneCurveDesc(theOther.myEvalRep)),
|
||||
myRational(theOther.myRational),
|
||||
myClosed(theOther.myClosed),
|
||||
myMaxDerivInvOk(false)
|
||||
@@ -473,6 +486,12 @@ int Geom_BezierCurve::Degree() const
|
||||
|
||||
std::optional<gp_Pnt> Geom_BezierCurve::EvalD0(const double U) const
|
||||
{
|
||||
if (const std::optional<gp_Pnt> aEvalRepResult = Geom_EvalRepUtils::TryEvalCurveD0(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
gp_Pnt P;
|
||||
BSplCLib::D0(U, Poles(), Weights(), P);
|
||||
return P;
|
||||
@@ -482,6 +501,13 @@ std::optional<gp_Pnt> Geom_BezierCurve::EvalD0(const double U) const
|
||||
|
||||
std::optional<Geom_Curve::ResD1> Geom_BezierCurve::EvalD1(const double U) const
|
||||
{
|
||||
if (const std::optional<Geom_Curve::ResD1> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalCurveD1(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD1> aResult{std::in_place};
|
||||
BSplCLib::D1(U, Poles(), Weights(), aResult->Point, aResult->D1);
|
||||
return aResult;
|
||||
@@ -491,6 +517,13 @@ std::optional<Geom_Curve::ResD1> Geom_BezierCurve::EvalD1(const double U) const
|
||||
|
||||
std::optional<Geom_Curve::ResD2> Geom_BezierCurve::EvalD2(const double U) const
|
||||
{
|
||||
if (const std::optional<Geom_Curve::ResD2> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalCurveD2(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD2> aResult{std::in_place};
|
||||
BSplCLib::D2(U, Poles(), Weights(), aResult->Point, aResult->D1, aResult->D2);
|
||||
return aResult;
|
||||
@@ -500,6 +533,13 @@ std::optional<Geom_Curve::ResD2> Geom_BezierCurve::EvalD2(const double U) const
|
||||
|
||||
std::optional<Geom_Curve::ResD3> Geom_BezierCurve::EvalD3(const double U) const
|
||||
{
|
||||
if (const std::optional<Geom_Curve::ResD3> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalCurveD3(myEvalRep, U);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD3> aResult{std::in_place};
|
||||
BSplCLib::D3(U, Poles(), Weights(), aResult->Point, aResult->D1, aResult->D2, aResult->D3);
|
||||
return aResult;
|
||||
@@ -511,6 +551,14 @@ std::optional<gp_Vec> Geom_BezierCurve::EvalDN(const double U, const int N) cons
|
||||
{
|
||||
if (N < 1)
|
||||
return std::nullopt;
|
||||
|
||||
if (const std::optional<gp_Vec> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalCurveDN(myEvalRep, U, N);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
gp_Vec V;
|
||||
|
||||
const int aDeg = myPoles.Size() - 1;
|
||||
@@ -616,6 +664,7 @@ void Geom_BezierCurve::Transform(const gp_Trsf& T)
|
||||
|
||||
for (int i = 1; i <= nbpoles; i++)
|
||||
myPoles(i).Transform(T);
|
||||
ClearEvalRepresentation();
|
||||
myMaxDerivInvOk = false;
|
||||
}
|
||||
|
||||
@@ -677,6 +726,7 @@ void Geom_BezierCurve::init(const NCollection_Array1<gp_Pnt>& thePoles,
|
||||
|
||||
myMaxDerivInv = 0.0;
|
||||
myMaxDerivInvOk = false;
|
||||
ClearEvalRepresentation();
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
class gp_Trsf;
|
||||
class Geom_Geometry;
|
||||
|
||||
namespace Geom_EvalRepCurveDesc
|
||||
{
|
||||
class Base;
|
||||
}
|
||||
|
||||
//! Describes a rational or non-rational Bezier curve
|
||||
//! - a non-rational Bezier curve is defined by a table of
|
||||
//! poles (also called control points),
|
||||
@@ -101,6 +106,20 @@ public:
|
||||
//! @param[in] theOther the Bezier curve to copy from
|
||||
Standard_EXPORT Geom_BezierCurve(const Geom_BezierCurve& theOther);
|
||||
|
||||
//! Returns true if an evaluation representation is attached.
|
||||
bool HasEvalRepresentation() const { return !myEvalRep.IsNull(); }
|
||||
|
||||
//! Returns the current evaluation representation descriptor (may be null).
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& EvalRepresentation() const { return myEvalRep; }
|
||||
|
||||
//! Sets a new evaluation representation.
|
||||
//! Validates descriptor data and ensures no circular references.
|
||||
Standard_EXPORT void SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc);
|
||||
|
||||
//! Removes the evaluation representation.
|
||||
void ClearEvalRepresentation() { myEvalRep.Nullify(); }
|
||||
|
||||
//! Increases the degree of a bezier curve. Degree is the new
|
||||
//! degree of <me>. Raises ConstructionError
|
||||
//! if Degree is greater than MaxDegree or lower than 2
|
||||
@@ -338,12 +357,13 @@ protected:
|
||||
const NCollection_Array1<double>* theWeights);
|
||||
|
||||
private:
|
||||
NCollection_Array1<gp_Pnt> myPoles;
|
||||
NCollection_Array1<double> myWeights;
|
||||
bool myRational = false;
|
||||
bool myClosed = false;
|
||||
double myMaxDerivInv = 0.0;
|
||||
bool myMaxDerivInvOk = false;
|
||||
NCollection_Array1<gp_Pnt> myPoles;
|
||||
NCollection_Array1<double> myWeights;
|
||||
occ::handle<Geom_EvalRepCurveDesc::Base> myEvalRep;
|
||||
bool myRational = false;
|
||||
bool myClosed = false;
|
||||
double myMaxDerivInv = 0.0;
|
||||
bool myMaxDerivInvOk = false;
|
||||
};
|
||||
|
||||
#endif // _Geom_BezierCurve_HeaderFile
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <BSplCLib.hxx>
|
||||
#include <Geom_BezierCurve.hxx>
|
||||
#include <Geom_BezierSurface.hxx>
|
||||
#include "Geom_EvalRepSurfaceDesc.hxx"
|
||||
#include "Geom_EvalRepUtils.pxx"
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <Geom_Geometry.hxx>
|
||||
#include <gp.hxx>
|
||||
@@ -40,6 +42,7 @@
|
||||
#include <Standard_ConstructionError.hxx>
|
||||
#include <Standard_DimensionError.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <Standard_ProgramError.hxx>
|
||||
#include <Standard_RangeError.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
@@ -47,6 +50,15 @@
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Geom_BezierSurface, Geom_BoundedSurface)
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Geom_BezierSurface::SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc)
|
||||
{
|
||||
Geom_EvalRepUtils::ValidateSurfaceDesc(theDesc, this);
|
||||
myEvalRep = theDesc;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : Rational
|
||||
// purpose : check rationality of an array of weights
|
||||
@@ -363,6 +375,7 @@ Geom_BezierSurface::Geom_BezierSurface(const Geom_BezierSurface& theOther)
|
||||
(theOther.myURational || theOther.myVRational)
|
||||
? NCollection_Array2<double>(theOther.myWeights)
|
||||
: BSplSLib::UnitWeights(theOther.myPoles.ColLength(), theOther.myPoles.RowLength())),
|
||||
myEvalRep(Geom_EvalRepUtils::CloneSurfaceDesc(theOther.myEvalRep)),
|
||||
myURational(theOther.myURational),
|
||||
myVRational(theOther.myVRational),
|
||||
myUMaxDerivInv(theOther.myUMaxDerivInv),
|
||||
@@ -1253,6 +1266,7 @@ void Geom_BezierSurface::UReverse()
|
||||
}
|
||||
}
|
||||
}
|
||||
ClearEvalRepresentation();
|
||||
myMaxDerivInvOk = false;
|
||||
}
|
||||
|
||||
@@ -1299,6 +1313,7 @@ void Geom_BezierSurface::VReverse()
|
||||
}
|
||||
}
|
||||
}
|
||||
ClearEvalRepresentation();
|
||||
myMaxDerivInvOk = false;
|
||||
}
|
||||
|
||||
@@ -1330,6 +1345,13 @@ GeomAbs_Shape Geom_BezierSurface::Continuity() const
|
||||
|
||||
std::optional<gp_Pnt> Geom_BezierSurface::EvalD0(const double U, const double V) const
|
||||
{
|
||||
if (const std::optional<gp_Pnt> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD0(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
gp_Pnt P;
|
||||
if (myURational || myVRational)
|
||||
{
|
||||
@@ -1378,6 +1400,13 @@ std::optional<gp_Pnt> Geom_BezierSurface::EvalD0(const double U, const double V)
|
||||
|
||||
std::optional<Geom_Surface::ResD1> Geom_BezierSurface::EvalD1(const double U, const double V) const
|
||||
{
|
||||
if (const std::optional<Geom_Surface::ResD1> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD1(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Surface::ResD1> aResult{std::in_place};
|
||||
if (myURational || myVRational)
|
||||
{
|
||||
@@ -1430,6 +1459,13 @@ std::optional<Geom_Surface::ResD1> Geom_BezierSurface::EvalD1(const double U, co
|
||||
|
||||
std::optional<Geom_Surface::ResD2> Geom_BezierSurface::EvalD2(const double U, const double V) const
|
||||
{
|
||||
if (const std::optional<Geom_Surface::ResD2> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD2(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Surface::ResD2> aResult{std::in_place};
|
||||
if (myURational || myVRational)
|
||||
{
|
||||
@@ -1490,6 +1526,13 @@ std::optional<Geom_Surface::ResD2> Geom_BezierSurface::EvalD2(const double U, co
|
||||
|
||||
std::optional<Geom_Surface::ResD3> Geom_BezierSurface::EvalD3(const double U, const double V) const
|
||||
{
|
||||
if (const std::optional<Geom_Surface::ResD3> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD3(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Surface::ResD3> aResult{std::in_place};
|
||||
if (myURational || myVRational)
|
||||
{
|
||||
@@ -1559,6 +1602,13 @@ std::optional<gp_Vec> Geom_BezierSurface::EvalDN(const double U,
|
||||
const int Nu,
|
||||
const int Nv) const
|
||||
{
|
||||
if (const std::optional<gp_Vec> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceDN(myEvalRep, U, V, Nu, Nv);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
if (Nu + Nv < 1 || Nu < 0 || Nv < 0)
|
||||
return std::nullopt;
|
||||
gp_Vec Derivative;
|
||||
@@ -1805,6 +1855,7 @@ void Geom_BezierSurface::Transform(const gp_Trsf& T)
|
||||
myPoles(I, J).Transform(T);
|
||||
}
|
||||
}
|
||||
ClearEvalRepresentation();
|
||||
myMaxDerivInvOk = false;
|
||||
}
|
||||
|
||||
@@ -1941,6 +1992,7 @@ void Geom_BezierSurface::init(const NCollection_Array2<gp_Pnt>& thePoles,
|
||||
}
|
||||
|
||||
myMaxDerivInvOk = false;
|
||||
ClearEvalRepresentation();
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
@@ -30,6 +30,11 @@ class Geom_Curve;
|
||||
class gp_Trsf;
|
||||
class Geom_Geometry;
|
||||
|
||||
namespace Geom_EvalRepSurfaceDesc
|
||||
{
|
||||
class Base;
|
||||
}
|
||||
|
||||
//! Describes a rational or non-rational Bezier surface.
|
||||
//! - A non-rational Bezier surface is defined by a table
|
||||
//! of poles (also known as control points).
|
||||
@@ -121,6 +126,20 @@ public:
|
||||
//! @param[in] theOther the Bezier surface to copy from
|
||||
Standard_EXPORT Geom_BezierSurface(const Geom_BezierSurface& theOther);
|
||||
|
||||
//! Returns true if an evaluation representation is attached.
|
||||
bool HasEvalRepresentation() const { return !myEvalRep.IsNull(); }
|
||||
|
||||
//! Returns the current evaluation representation descriptor (may be null).
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& EvalRepresentation() const { return myEvalRep; }
|
||||
|
||||
//! Sets a new evaluation representation.
|
||||
//! Validates descriptor data and ensures no circular references.
|
||||
Standard_EXPORT void SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc);
|
||||
|
||||
//! Removes the evaluation representation.
|
||||
void ClearEvalRepresentation() { myEvalRep.Nullify(); }
|
||||
|
||||
//! ---Purpose
|
||||
//! Creates a rational Bezier surface with a set of poles and a
|
||||
//! set of weights.
|
||||
@@ -614,13 +633,14 @@ protected:
|
||||
const NCollection_Array2<double>* theWeights);
|
||||
|
||||
private:
|
||||
NCollection_Array2<gp_Pnt> myPoles;
|
||||
NCollection_Array2<double> myWeights;
|
||||
bool myURational = false;
|
||||
bool myVRational = false;
|
||||
double myUMaxDerivInv = 0.0;
|
||||
double myVMaxDerivInv = 0.0;
|
||||
bool myMaxDerivInvOk = false;
|
||||
NCollection_Array2<gp_Pnt> myPoles;
|
||||
NCollection_Array2<double> myWeights;
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::Base> myEvalRep;
|
||||
bool myURational = false;
|
||||
bool myVRational = false;
|
||||
double myUMaxDerivInv = 0.0;
|
||||
double myVMaxDerivInv = 0.0;
|
||||
bool myMaxDerivInvOk = false;
|
||||
};
|
||||
|
||||
#endif // _Geom_BezierSurface_HeaderFile
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
// Copyright (c) 2025 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 _Geom_EvalRepCurveDesc_HeaderFile
|
||||
#define _Geom_EvalRepCurveDesc_HeaderFile
|
||||
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
|
||||
namespace Geom_EvalRepCurveDesc
|
||||
{
|
||||
//! 1D affine parameter map: uRep = Scale * u + Offset.
|
||||
struct Map1d
|
||||
{
|
||||
double Scale = 1.0;
|
||||
double Offset = 0.0;
|
||||
|
||||
bool IsIdentity() const
|
||||
{
|
||||
return std::abs(Scale - 1.0) < Precision::Confusion()
|
||||
&& std::abs(Offset) < Precision::Confusion();
|
||||
}
|
||||
|
||||
bool IsValid() const { return std::abs(Scale) > Precision::Confusion(); }
|
||||
|
||||
double Map(const double theU) const { return Scale * theU + Offset; }
|
||||
};
|
||||
|
||||
//! 1D parameter domain interval.
|
||||
struct Domain1d
|
||||
{
|
||||
double First = 0.0;
|
||||
double Last = 1.0;
|
||||
|
||||
bool Contains(const double theU) const
|
||||
{
|
||||
return (theU >= First - Precision::Confusion()) && (theU <= Last + Precision::Confusion());
|
||||
}
|
||||
};
|
||||
|
||||
//! Abstract base descriptor for curve evaluation representation.
|
||||
//! Holds the representation handle and a Kind tag for switch-based dispatch.
|
||||
class Base : public Standard_Transient
|
||||
{
|
||||
public:
|
||||
//! Descriptor kind for switch-based dispatch (no RTTI needed).
|
||||
enum class Kind
|
||||
{
|
||||
Full, //!< fully equivalent, no derivative limit, no domain, no map
|
||||
DerivBounded, //!< full domain + identity map, limited to MaxDerivOrder
|
||||
Mapped //!< has MaxDerivOrder + optional Domain + ParamMap
|
||||
};
|
||||
|
||||
occ::handle<Geom_Curve> Representation; //!< geometry used for evaluation
|
||||
|
||||
//! Returns the descriptor kind.
|
||||
virtual Kind GetKind() const = 0;
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(Base, Standard_Transient)
|
||||
|
||||
protected:
|
||||
Base() = default;
|
||||
};
|
||||
|
||||
//! Fully equivalent descriptor: no derivative limit, no domain, no map.
|
||||
//! Fastest evaluation path - direct delegation to Representation.
|
||||
class Full : public Base
|
||||
{
|
||||
public:
|
||||
Kind GetKind() const override { return Kind::Full; }
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(Full, Base)
|
||||
};
|
||||
|
||||
//! Derivative-bounded descriptor: full domain, identity map, limited to MaxDerivOrder.
|
||||
class DerivBounded : public Base
|
||||
{
|
||||
public:
|
||||
std::size_t MaxDerivOrder = 3; //!< max supported derivative order
|
||||
|
||||
Kind GetKind() const override { return Kind::DerivBounded; }
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(DerivBounded, Base)
|
||||
};
|
||||
|
||||
//! Mapped descriptor for curve evaluation representation.
|
||||
//! Adds optional bounded domain and affine parameter map.
|
||||
//! Evaluation requires: domain check -> map parameter -> evaluate -> scale derivatives.
|
||||
class Mapped : public Base
|
||||
{
|
||||
public:
|
||||
std::size_t MaxDerivOrder = 3; //!< max supported derivative order
|
||||
std::optional<Domain1d> Domain; //!< nullopt = full domain
|
||||
Map1d ParamMap; //!< affine parameter transform
|
||||
|
||||
Kind GetKind() const override { return Kind::Mapped; }
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(Mapped, Base)
|
||||
};
|
||||
} // namespace Geom_EvalRepCurveDesc
|
||||
|
||||
#endif // _Geom_EvalRepCurveDesc_HeaderFile
|
||||
@@ -0,0 +1,143 @@
|
||||
// Copyright (c) 2025 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 _Geom_EvalRepSurfaceDesc_HeaderFile
|
||||
#define _Geom_EvalRepSurfaceDesc_HeaderFile
|
||||
|
||||
#include <Geom_Surface.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
|
||||
namespace Geom_EvalRepSurfaceDesc
|
||||
{
|
||||
//! 2D diagonal affine parameter map with optional UV swap.
|
||||
//! Without swap: uRep = ScaleU*u + OffsetU, vRep = ScaleV*v + OffsetV.
|
||||
//! With swap: uRep = ScaleU*v + OffsetU, vRep = ScaleV*u + OffsetV.
|
||||
struct Map2d
|
||||
{
|
||||
double ScaleU = 1.0;
|
||||
double OffsetU = 0.0;
|
||||
double ScaleV = 1.0;
|
||||
double OffsetV = 0.0;
|
||||
bool SwapUV = false;
|
||||
|
||||
bool IsIdentity() const
|
||||
{
|
||||
return std::abs(ScaleU - 1.0) < Precision::Confusion()
|
||||
&& std::abs(ScaleV - 1.0) < Precision::Confusion()
|
||||
&& std::abs(OffsetU) < Precision::Confusion()
|
||||
&& std::abs(OffsetV) < Precision::Confusion() && !SwapUV;
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return std::abs(ScaleU) > Precision::Confusion() && std::abs(ScaleV) > Precision::Confusion();
|
||||
}
|
||||
|
||||
void Map(const double theU, const double theV, double& theURep, double& theVRep) const
|
||||
{
|
||||
if (SwapUV)
|
||||
{
|
||||
theURep = ScaleU * theV + OffsetU;
|
||||
theVRep = ScaleV * theU + OffsetV;
|
||||
}
|
||||
else
|
||||
{
|
||||
theURep = ScaleU * theU + OffsetU;
|
||||
theVRep = ScaleV * theV + OffsetV;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//! 2D parameter domain.
|
||||
struct Domain2d
|
||||
{
|
||||
double UFirst = 0.0;
|
||||
double ULast = 1.0;
|
||||
double VFirst = 0.0;
|
||||
double VLast = 1.0;
|
||||
|
||||
bool Contains(const double theU, const double theV) const
|
||||
{
|
||||
return (theU >= UFirst - Precision::Confusion()) && (theU <= ULast + Precision::Confusion())
|
||||
&& (theV >= VFirst - Precision::Confusion()) && (theV <= VLast + Precision::Confusion());
|
||||
}
|
||||
};
|
||||
|
||||
//! Abstract base descriptor for surface evaluation representation.
|
||||
//! Holds the representation handle and a Kind tag for switch-based dispatch.
|
||||
class Base : public Standard_Transient
|
||||
{
|
||||
public:
|
||||
//! Descriptor kind for switch-based dispatch (no RTTI needed).
|
||||
enum class Kind
|
||||
{
|
||||
Full, //!< fully equivalent, no derivative limit, no domain, no map
|
||||
DerivBounded, //!< full domain + identity map, limited to MaxDerivOrder
|
||||
Mapped //!< has MaxDerivOrder + optional Domain + ParamMap
|
||||
};
|
||||
|
||||
occ::handle<Geom_Surface> Representation; //!< geometry used for evaluation
|
||||
|
||||
//! Returns the descriptor kind.
|
||||
virtual Kind GetKind() const = 0;
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(Base, Standard_Transient)
|
||||
|
||||
protected:
|
||||
Base() = default;
|
||||
};
|
||||
|
||||
//! Fully equivalent descriptor: no derivative limit, no domain, no map.
|
||||
//! Fastest evaluation path - direct delegation to Representation.
|
||||
class Full : public Base
|
||||
{
|
||||
public:
|
||||
Kind GetKind() const override { return Kind::Full; }
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(Full, Base)
|
||||
};
|
||||
|
||||
//! Derivative-bounded descriptor: full domain, identity map, limited to MaxDerivOrder.
|
||||
class DerivBounded : public Base
|
||||
{
|
||||
public:
|
||||
std::size_t MaxDerivOrder = 3; //!< max supported derivative order
|
||||
|
||||
Kind GetKind() const override { return Kind::DerivBounded; }
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(DerivBounded, Base)
|
||||
};
|
||||
|
||||
//! Mapped descriptor for surface evaluation representation.
|
||||
//! Adds optional bounded domain and diagonal affine parameter map with optional UV swap.
|
||||
//! Evaluation requires: domain check -> map parameters -> evaluate -> scale derivatives.
|
||||
//! Future subclasses can support multi-region descriptors with per-patch UV domains and maps.
|
||||
class Mapped : public Base
|
||||
{
|
||||
public:
|
||||
std::size_t MaxDerivOrder = 3; //!< max supported derivative order
|
||||
std::optional<Domain2d> Domain; //!< nullopt = full domain
|
||||
Map2d ParamMap; //!< affine parameter transform
|
||||
|
||||
Kind GetKind() const override { return Kind::Mapped; }
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(Mapped, Base)
|
||||
};
|
||||
} // namespace Geom_EvalRepSurfaceDesc
|
||||
|
||||
#endif // _Geom_EvalRepSurfaceDesc_HeaderFile
|
||||
@@ -0,0 +1,900 @@
|
||||
// Copyright (c) 2025 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 _Geom_EvalRepUtils_HeaderFile
|
||||
#define _Geom_EvalRepUtils_HeaderFile
|
||||
|
||||
#include "Geom_EvalRepCurveDesc.hxx"
|
||||
#include "Geom_EvalRepSurfaceDesc.hxx"
|
||||
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <Geom_Surface.hxx>
|
||||
|
||||
#include <Standard_ProgramError.hxx>
|
||||
|
||||
#include <cmath>
|
||||
#include <optional>
|
||||
|
||||
//! Internal helper namespace for EvalRep dispatch and validation.
|
||||
namespace Geom_EvalRepUtils
|
||||
{
|
||||
occ::handle<Geom_EvalRepCurveDesc::Base> CloneCurveDesc(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc);
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::Base> CloneSurfaceDesc(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc);
|
||||
|
||||
std::optional<gp_Pnt> TryEvalCurveD0(const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU);
|
||||
std::optional<Geom_Curve::ResD1> TryEvalCurveD1(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU);
|
||||
std::optional<Geom_Curve::ResD2> TryEvalCurveD2(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU);
|
||||
std::optional<Geom_Curve::ResD3> TryEvalCurveD3(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU);
|
||||
std::optional<gp_Vec> TryEvalCurveDN(const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU,
|
||||
const int theN);
|
||||
|
||||
std::optional<gp_Pnt> TryEvalSurfaceD0(const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc,
|
||||
const double theU,
|
||||
const double theV);
|
||||
std::optional<Geom_Surface::ResD1> TryEvalSurfaceD1(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc,
|
||||
const double theU,
|
||||
const double theV);
|
||||
std::optional<Geom_Surface::ResD2> TryEvalSurfaceD2(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc,
|
||||
const double theU,
|
||||
const double theV);
|
||||
std::optional<Geom_Surface::ResD3> TryEvalSurfaceD3(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc,
|
||||
const double theU,
|
||||
const double theV);
|
||||
std::optional<gp_Vec> TryEvalSurfaceDN(const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc,
|
||||
const double theU,
|
||||
const double theV,
|
||||
const int theNu,
|
||||
const int theNv);
|
||||
|
||||
std::optional<gp_Pnt> TryEvalCurveD0Mapped(const Geom_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU);
|
||||
std::optional<Geom_Curve::ResD1> TryEvalCurveD1Mapped(const Geom_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU);
|
||||
std::optional<Geom_Curve::ResD2> TryEvalCurveD2Mapped(const Geom_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU);
|
||||
std::optional<Geom_Curve::ResD3> TryEvalCurveD3Mapped(const Geom_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU);
|
||||
std::optional<gp_Vec> TryEvalCurveDNMapped(const Geom_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU,
|
||||
const int theN);
|
||||
|
||||
std::optional<gp_Pnt> TryEvalSurfaceD0Mapped(const Geom_EvalRepSurfaceDesc::Mapped& theDesc,
|
||||
const double theU,
|
||||
const double theV);
|
||||
std::optional<Geom_Surface::ResD1> TryEvalSurfaceD1Mapped(
|
||||
const Geom_EvalRepSurfaceDesc::Mapped& theDesc,
|
||||
const double theU,
|
||||
const double theV);
|
||||
std::optional<Geom_Surface::ResD2> TryEvalSurfaceD2Mapped(
|
||||
const Geom_EvalRepSurfaceDesc::Mapped& theDesc,
|
||||
const double theU,
|
||||
const double theV);
|
||||
std::optional<Geom_Surface::ResD3> TryEvalSurfaceD3Mapped(
|
||||
const Geom_EvalRepSurfaceDesc::Mapped& theDesc,
|
||||
const double theU,
|
||||
const double theV);
|
||||
std::optional<gp_Vec> TryEvalSurfaceDNMapped(const Geom_EvalRepSurfaceDesc::Mapped& theDesc,
|
||||
const double theU,
|
||||
const double theV,
|
||||
const int theNu,
|
||||
const int theNv);
|
||||
void ValidateCurveDesc(const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc,
|
||||
const Geom_Curve* theOwner);
|
||||
void ValidateSurfaceDesc(const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc,
|
||||
const Geom_Surface* theOwner);
|
||||
} // namespace Geom_EvalRepUtils
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline void Geom_EvalRepUtils::ValidateCurveDesc(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc,
|
||||
const Geom_Curve* theOwner)
|
||||
{
|
||||
if (theDesc.IsNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (theDesc->Representation.IsNull())
|
||||
{
|
||||
throw Standard_ProgramError("SetEvalRepresentation: null Representation");
|
||||
}
|
||||
if (theDesc->GetKind() == Geom_EvalRepCurveDesc::Base::Kind::Mapped)
|
||||
{
|
||||
const auto* aMapped = static_cast<const Geom_EvalRepCurveDesc::Mapped*>(theDesc.get());
|
||||
if (!aMapped->ParamMap.IsValid())
|
||||
{
|
||||
throw Standard_ProgramError("SetEvalRepresentation: invalid parameter map");
|
||||
}
|
||||
}
|
||||
// Only direct self-reference is detected here; indirect cycles (A->B->A) are not
|
||||
// checked because EvalRepresentation() is not available on the Geom_Curve base class.
|
||||
if (theDesc->Representation.get() == theOwner)
|
||||
{
|
||||
throw Standard_ProgramError("SetEvalRepresentation: invalid descriptor chain");
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline void Geom_EvalRepUtils::ValidateSurfaceDesc(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc,
|
||||
const Geom_Surface* theOwner)
|
||||
{
|
||||
if (theDesc.IsNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (theDesc->Representation.IsNull())
|
||||
{
|
||||
throw Standard_ProgramError("SetEvalRepresentation: null Representation");
|
||||
}
|
||||
if (theDesc->GetKind() == Geom_EvalRepSurfaceDesc::Base::Kind::Mapped)
|
||||
{
|
||||
const auto* aMapped = static_cast<const Geom_EvalRepSurfaceDesc::Mapped*>(theDesc.get());
|
||||
if (!aMapped->ParamMap.IsValid())
|
||||
{
|
||||
throw Standard_ProgramError("SetEvalRepresentation: invalid parameter map");
|
||||
}
|
||||
}
|
||||
// Only direct self-reference is detected here; indirect cycles (A->B->A) are not
|
||||
// checked because EvalRepresentation() is not available on the Geom_Surface base class.
|
||||
if (theDesc->Representation.get() == theOwner)
|
||||
{
|
||||
throw Standard_ProgramError("SetEvalRepresentation: invalid descriptor chain");
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline occ::handle<Geom_EvalRepCurveDesc::Base> Geom_EvalRepUtils::CloneCurveDesc(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc)
|
||||
{
|
||||
if (theDesc.IsNull() || theDesc->Representation.IsNull())
|
||||
{
|
||||
return occ::handle<Geom_EvalRepCurveDesc::Base>();
|
||||
}
|
||||
|
||||
const occ::handle<Geom_Curve> aRepCopy =
|
||||
occ::down_cast<Geom_Curve>(theDesc->Representation->Copy());
|
||||
if (aRepCopy.IsNull())
|
||||
{
|
||||
return occ::handle<Geom_EvalRepCurveDesc::Base>();
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::Full: {
|
||||
occ::handle<Geom_EvalRepCurveDesc::Full> aClone = new Geom_EvalRepCurveDesc::Full();
|
||||
aClone->Representation = aRepCopy;
|
||||
return aClone;
|
||||
}
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::DerivBounded: {
|
||||
const auto* aSrc = static_cast<const Geom_EvalRepCurveDesc::DerivBounded*>(theDesc.get());
|
||||
occ::handle<Geom_EvalRepCurveDesc::DerivBounded> aClone =
|
||||
new Geom_EvalRepCurveDesc::DerivBounded();
|
||||
aClone->Representation = aRepCopy;
|
||||
aClone->MaxDerivOrder = aSrc->MaxDerivOrder;
|
||||
return aClone;
|
||||
}
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::Mapped: {
|
||||
const auto* aSrc = static_cast<const Geom_EvalRepCurveDesc::Mapped*>(theDesc.get());
|
||||
occ::handle<Geom_EvalRepCurveDesc::Mapped> aClone = new Geom_EvalRepCurveDesc::Mapped();
|
||||
aClone->Representation = aRepCopy;
|
||||
aClone->MaxDerivOrder = aSrc->MaxDerivOrder;
|
||||
aClone->Domain = aSrc->Domain;
|
||||
aClone->ParamMap = aSrc->ParamMap;
|
||||
return aClone;
|
||||
}
|
||||
}
|
||||
return occ::handle<Geom_EvalRepCurveDesc::Base>();
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline occ::handle<Geom_EvalRepSurfaceDesc::Base> Geom_EvalRepUtils::CloneSurfaceDesc(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc)
|
||||
{
|
||||
if (theDesc.IsNull() || theDesc->Representation.IsNull())
|
||||
{
|
||||
return occ::handle<Geom_EvalRepSurfaceDesc::Base>();
|
||||
}
|
||||
|
||||
const occ::handle<Geom_Surface> aRepCopy =
|
||||
occ::down_cast<Geom_Surface>(theDesc->Representation->Copy());
|
||||
if (aRepCopy.IsNull())
|
||||
{
|
||||
return occ::handle<Geom_EvalRepSurfaceDesc::Base>();
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::Full: {
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::Full> aClone = new Geom_EvalRepSurfaceDesc::Full();
|
||||
aClone->Representation = aRepCopy;
|
||||
return aClone;
|
||||
}
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::DerivBounded: {
|
||||
const auto* aSrc = static_cast<const Geom_EvalRepSurfaceDesc::DerivBounded*>(theDesc.get());
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::DerivBounded> aClone =
|
||||
new Geom_EvalRepSurfaceDesc::DerivBounded();
|
||||
aClone->Representation = aRepCopy;
|
||||
aClone->MaxDerivOrder = aSrc->MaxDerivOrder;
|
||||
return aClone;
|
||||
}
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::Mapped: {
|
||||
const auto* aSrc = static_cast<const Geom_EvalRepSurfaceDesc::Mapped*>(theDesc.get());
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::Mapped> aClone = new Geom_EvalRepSurfaceDesc::Mapped();
|
||||
aClone->Representation = aRepCopy;
|
||||
aClone->MaxDerivOrder = aSrc->MaxDerivOrder;
|
||||
aClone->Domain = aSrc->Domain;
|
||||
aClone->ParamMap = aSrc->ParamMap;
|
||||
return aClone;
|
||||
}
|
||||
}
|
||||
return occ::handle<Geom_EvalRepSurfaceDesc::Base>();
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<gp_Pnt> Geom_EvalRepUtils::TryEvalCurveD0(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
if (theDesc.IsNull())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::Full:
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::DerivBounded:
|
||||
return theDesc->Representation->EvalD0(theU);
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::Mapped:
|
||||
return TryEvalCurveD0Mapped(*static_cast<const Geom_EvalRepCurveDesc::Mapped*>(theDesc.get()),
|
||||
theU);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom_Curve::ResD1> Geom_EvalRepUtils::TryEvalCurveD1(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
if (theDesc.IsNull())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::Full:
|
||||
return theDesc->Representation->EvalD1(theU);
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::DerivBounded: {
|
||||
const auto* aBounded = static_cast<const Geom_EvalRepCurveDesc::DerivBounded*>(theDesc.get());
|
||||
if (aBounded->MaxDerivOrder < 1)
|
||||
return std::nullopt;
|
||||
return theDesc->Representation->EvalD1(theU);
|
||||
}
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::Mapped: {
|
||||
const auto* aMapped = static_cast<const Geom_EvalRepCurveDesc::Mapped*>(theDesc.get());
|
||||
if (aMapped->MaxDerivOrder < 1)
|
||||
return std::nullopt;
|
||||
return TryEvalCurveD1Mapped(*aMapped, theU);
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom_Curve::ResD2> Geom_EvalRepUtils::TryEvalCurveD2(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
if (theDesc.IsNull())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::Full:
|
||||
return theDesc->Representation->EvalD2(theU);
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::DerivBounded: {
|
||||
const auto* aBounded = static_cast<const Geom_EvalRepCurveDesc::DerivBounded*>(theDesc.get());
|
||||
if (aBounded->MaxDerivOrder < 2)
|
||||
return std::nullopt;
|
||||
return theDesc->Representation->EvalD2(theU);
|
||||
}
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::Mapped: {
|
||||
const auto* aMapped = static_cast<const Geom_EvalRepCurveDesc::Mapped*>(theDesc.get());
|
||||
if (aMapped->MaxDerivOrder < 2)
|
||||
return std::nullopt;
|
||||
return TryEvalCurveD2Mapped(*aMapped, theU);
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom_Curve::ResD3> Geom_EvalRepUtils::TryEvalCurveD3(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
if (theDesc.IsNull())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::Full:
|
||||
return theDesc->Representation->EvalD3(theU);
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::DerivBounded: {
|
||||
const auto* aBounded = static_cast<const Geom_EvalRepCurveDesc::DerivBounded*>(theDesc.get());
|
||||
if (aBounded->MaxDerivOrder < 3)
|
||||
return std::nullopt;
|
||||
return theDesc->Representation->EvalD3(theU);
|
||||
}
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::Mapped: {
|
||||
const auto* aMapped = static_cast<const Geom_EvalRepCurveDesc::Mapped*>(theDesc.get());
|
||||
if (aMapped->MaxDerivOrder < 3)
|
||||
return std::nullopt;
|
||||
return TryEvalCurveD3Mapped(*aMapped, theU);
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<gp_Vec> Geom_EvalRepUtils::TryEvalCurveDN(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc,
|
||||
const double theU,
|
||||
const int theN)
|
||||
{
|
||||
if (theDesc.IsNull() || theN < 1)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::Full:
|
||||
return theDesc->Representation->EvalDN(theU, theN);
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::DerivBounded: {
|
||||
const auto* aBounded = static_cast<const Geom_EvalRepCurveDesc::DerivBounded*>(theDesc.get());
|
||||
if (aBounded->MaxDerivOrder < static_cast<std::size_t>(theN))
|
||||
return std::nullopt;
|
||||
return theDesc->Representation->EvalDN(theU, theN);
|
||||
}
|
||||
case Geom_EvalRepCurveDesc::Base::Kind::Mapped: {
|
||||
const auto* aMapped = static_cast<const Geom_EvalRepCurveDesc::Mapped*>(theDesc.get());
|
||||
if (aMapped->MaxDerivOrder < static_cast<std::size_t>(theN))
|
||||
return std::nullopt;
|
||||
return TryEvalCurveDNMapped(*aMapped, theU, theN);
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<gp_Pnt> Geom_EvalRepUtils::TryEvalSurfaceD0(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc,
|
||||
const double theU,
|
||||
const double theV)
|
||||
{
|
||||
if (theDesc.IsNull())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::Full:
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::DerivBounded:
|
||||
return theDesc->Representation->EvalD0(theU, theV);
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::Mapped:
|
||||
return TryEvalSurfaceD0Mapped(
|
||||
*static_cast<const Geom_EvalRepSurfaceDesc::Mapped*>(theDesc.get()),
|
||||
theU,
|
||||
theV);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom_Surface::ResD1> Geom_EvalRepUtils::TryEvalSurfaceD1(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc,
|
||||
const double theU,
|
||||
const double theV)
|
||||
{
|
||||
if (theDesc.IsNull())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::Full:
|
||||
return theDesc->Representation->EvalD1(theU, theV);
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::DerivBounded: {
|
||||
const auto* aBounded =
|
||||
static_cast<const Geom_EvalRepSurfaceDesc::DerivBounded*>(theDesc.get());
|
||||
if (aBounded->MaxDerivOrder < 1)
|
||||
return std::nullopt;
|
||||
return theDesc->Representation->EvalD1(theU, theV);
|
||||
}
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::Mapped: {
|
||||
const auto* aMapped = static_cast<const Geom_EvalRepSurfaceDesc::Mapped*>(theDesc.get());
|
||||
if (aMapped->MaxDerivOrder < 1)
|
||||
return std::nullopt;
|
||||
return TryEvalSurfaceD1Mapped(*aMapped, theU, theV);
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom_Surface::ResD2> Geom_EvalRepUtils::TryEvalSurfaceD2(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc,
|
||||
const double theU,
|
||||
const double theV)
|
||||
{
|
||||
if (theDesc.IsNull())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::Full:
|
||||
return theDesc->Representation->EvalD2(theU, theV);
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::DerivBounded: {
|
||||
const auto* aBounded =
|
||||
static_cast<const Geom_EvalRepSurfaceDesc::DerivBounded*>(theDesc.get());
|
||||
if (aBounded->MaxDerivOrder < 2)
|
||||
return std::nullopt;
|
||||
return theDesc->Representation->EvalD2(theU, theV);
|
||||
}
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::Mapped: {
|
||||
const auto* aMapped = static_cast<const Geom_EvalRepSurfaceDesc::Mapped*>(theDesc.get());
|
||||
if (aMapped->MaxDerivOrder < 2)
|
||||
return std::nullopt;
|
||||
return TryEvalSurfaceD2Mapped(*aMapped, theU, theV);
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom_Surface::ResD3> Geom_EvalRepUtils::TryEvalSurfaceD3(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc,
|
||||
const double theU,
|
||||
const double theV)
|
||||
{
|
||||
if (theDesc.IsNull())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::Full:
|
||||
return theDesc->Representation->EvalD3(theU, theV);
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::DerivBounded: {
|
||||
const auto* aBounded =
|
||||
static_cast<const Geom_EvalRepSurfaceDesc::DerivBounded*>(theDesc.get());
|
||||
if (aBounded->MaxDerivOrder < 3)
|
||||
return std::nullopt;
|
||||
return theDesc->Representation->EvalD3(theU, theV);
|
||||
}
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::Mapped: {
|
||||
const auto* aMapped = static_cast<const Geom_EvalRepSurfaceDesc::Mapped*>(theDesc.get());
|
||||
if (aMapped->MaxDerivOrder < 3)
|
||||
return std::nullopt;
|
||||
return TryEvalSurfaceD3Mapped(*aMapped, theU, theV);
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<gp_Vec> Geom_EvalRepUtils::TryEvalSurfaceDN(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc,
|
||||
const double theU,
|
||||
const double theV,
|
||||
const int theNu,
|
||||
const int theNv)
|
||||
{
|
||||
const int aTotalOrder = theNu + theNv;
|
||||
if (theDesc.IsNull() || theNu < 0 || theNv < 0 || aTotalOrder < 1)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (theDesc->GetKind())
|
||||
{
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::Full:
|
||||
return theDesc->Representation->EvalDN(theU, theV, theNu, theNv);
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::DerivBounded: {
|
||||
const auto* aBounded =
|
||||
static_cast<const Geom_EvalRepSurfaceDesc::DerivBounded*>(theDesc.get());
|
||||
if (aBounded->MaxDerivOrder < static_cast<std::size_t>(aTotalOrder))
|
||||
return std::nullopt;
|
||||
return theDesc->Representation->EvalDN(theU, theV, theNu, theNv);
|
||||
}
|
||||
case Geom_EvalRepSurfaceDesc::Base::Kind::Mapped: {
|
||||
const auto* aMapped = static_cast<const Geom_EvalRepSurfaceDesc::Mapped*>(theDesc.get());
|
||||
if (aMapped->MaxDerivOrder < static_cast<std::size_t>(aTotalOrder))
|
||||
return std::nullopt;
|
||||
return TryEvalSurfaceDNMapped(*aMapped, theU, theV, theNu, theNv);
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<gp_Pnt> Geom_EvalRepUtils::TryEvalCurveD0Mapped(
|
||||
const Geom_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
const double aURep = theDesc.ParamMap.Map(theU);
|
||||
|
||||
if (theDesc.Domain.has_value() && !theDesc.Domain->Contains(aURep))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return theDesc.Representation->EvalD0(aURep);
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom_Curve::ResD1> Geom_EvalRepUtils::TryEvalCurveD1Mapped(
|
||||
const Geom_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
const double aURep = theDesc.ParamMap.Map(theU);
|
||||
|
||||
if (theDesc.Domain.has_value() && !theDesc.Domain->Contains(aURep))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const std::optional<Geom_Curve::ResD1> aRepRes = theDesc.Representation->EvalD1(aURep);
|
||||
if (!aRepRes)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const double aScale = theDesc.ParamMap.Scale;
|
||||
Geom_Curve::ResD1 aRes;
|
||||
aRes.Point = aRepRes->Point;
|
||||
aRes.D1 = aRepRes->D1 * aScale;
|
||||
return aRes;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom_Curve::ResD2> Geom_EvalRepUtils::TryEvalCurveD2Mapped(
|
||||
const Geom_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
const double aURep = theDesc.ParamMap.Map(theU);
|
||||
|
||||
if (theDesc.Domain.has_value() && !theDesc.Domain->Contains(aURep))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const std::optional<Geom_Curve::ResD2> aRepRes = theDesc.Representation->EvalD2(aURep);
|
||||
if (!aRepRes)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const double aScale = theDesc.ParamMap.Scale;
|
||||
const double aScale2 = aScale * aScale;
|
||||
|
||||
Geom_Curve::ResD2 aRes;
|
||||
aRes.Point = aRepRes->Point;
|
||||
aRes.D1 = aRepRes->D1 * aScale;
|
||||
aRes.D2 = aRepRes->D2 * aScale2;
|
||||
return aRes;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom_Curve::ResD3> Geom_EvalRepUtils::TryEvalCurveD3Mapped(
|
||||
const Geom_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU)
|
||||
{
|
||||
const double aURep = theDesc.ParamMap.Map(theU);
|
||||
|
||||
if (theDesc.Domain.has_value() && !theDesc.Domain->Contains(aURep))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const std::optional<Geom_Curve::ResD3> aRepRes = theDesc.Representation->EvalD3(aURep);
|
||||
if (!aRepRes)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const double aScale = theDesc.ParamMap.Scale;
|
||||
const double aScale2 = aScale * aScale;
|
||||
const double aScale3 = aScale2 * aScale;
|
||||
|
||||
Geom_Curve::ResD3 aRes;
|
||||
aRes.Point = aRepRes->Point;
|
||||
aRes.D1 = aRepRes->D1 * aScale;
|
||||
aRes.D2 = aRepRes->D2 * aScale2;
|
||||
aRes.D3 = aRepRes->D3 * aScale3;
|
||||
return aRes;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<gp_Vec> Geom_EvalRepUtils::TryEvalCurveDNMapped(
|
||||
const Geom_EvalRepCurveDesc::Mapped& theDesc,
|
||||
const double theU,
|
||||
const int theN)
|
||||
{
|
||||
const double aURep = theDesc.ParamMap.Map(theU);
|
||||
|
||||
if (theDesc.Domain.has_value() && !theDesc.Domain->Contains(aURep))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const std::optional<gp_Vec> aRepVec = theDesc.Representation->EvalDN(aURep, theN);
|
||||
if (!aRepVec)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const double aScaleN = std::pow(theDesc.ParamMap.Scale, theN);
|
||||
return (*aRepVec) * aScaleN;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<gp_Pnt> Geom_EvalRepUtils::TryEvalSurfaceD0Mapped(
|
||||
const Geom_EvalRepSurfaceDesc::Mapped& theDesc,
|
||||
const double theU,
|
||||
const double theV)
|
||||
{
|
||||
double aURep = 0.0;
|
||||
double aVRep = 0.0;
|
||||
theDesc.ParamMap.Map(theU, theV, aURep, aVRep);
|
||||
|
||||
if (theDesc.Domain.has_value() && !theDesc.Domain->Contains(aURep, aVRep))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return theDesc.Representation->EvalD0(aURep, aVRep);
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom_Surface::ResD1> Geom_EvalRepUtils::TryEvalSurfaceD1Mapped(
|
||||
const Geom_EvalRepSurfaceDesc::Mapped& theDesc,
|
||||
const double theU,
|
||||
const double theV)
|
||||
{
|
||||
double aURep = 0.0;
|
||||
double aVRep = 0.0;
|
||||
theDesc.ParamMap.Map(theU, theV, aURep, aVRep);
|
||||
|
||||
if (theDesc.Domain.has_value() && !theDesc.Domain->Contains(aURep, aVRep))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const std::optional<Geom_Surface::ResD1> aRepRes = theDesc.Representation->EvalD1(aURep, aVRep);
|
||||
if (!aRepRes)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
Geom_Surface::ResD1 aRes;
|
||||
aRes.Point = aRepRes->Point;
|
||||
|
||||
if (theDesc.ParamMap.SwapUV)
|
||||
{
|
||||
aRes.D1U = aRepRes->D1V * theDesc.ParamMap.ScaleV;
|
||||
aRes.D1V = aRepRes->D1U * theDesc.ParamMap.ScaleU;
|
||||
}
|
||||
else
|
||||
{
|
||||
aRes.D1U = aRepRes->D1U * theDesc.ParamMap.ScaleU;
|
||||
aRes.D1V = aRepRes->D1V * theDesc.ParamMap.ScaleV;
|
||||
}
|
||||
|
||||
return aRes;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom_Surface::ResD2> Geom_EvalRepUtils::TryEvalSurfaceD2Mapped(
|
||||
const Geom_EvalRepSurfaceDesc::Mapped& theDesc,
|
||||
const double theU,
|
||||
const double theV)
|
||||
{
|
||||
double aURep = 0.0;
|
||||
double aVRep = 0.0;
|
||||
theDesc.ParamMap.Map(theU, theV, aURep, aVRep);
|
||||
|
||||
if (theDesc.Domain.has_value() && !theDesc.Domain->Contains(aURep, aVRep))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const std::optional<Geom_Surface::ResD2> aRepRes = theDesc.Representation->EvalD2(aURep, aVRep);
|
||||
if (!aRepRes)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
Geom_Surface::ResD2 aRes;
|
||||
aRes.Point = aRepRes->Point;
|
||||
|
||||
const double aSu = theDesc.ParamMap.ScaleU;
|
||||
const double aSv = theDesc.ParamMap.ScaleV;
|
||||
const double aSu2 = aSu * aSu;
|
||||
const double aSv2 = aSv * aSv;
|
||||
const double aSuSv = aSu * aSv;
|
||||
|
||||
if (theDesc.ParamMap.SwapUV)
|
||||
{
|
||||
aRes.D1U = aRepRes->D1V * aSv;
|
||||
aRes.D1V = aRepRes->D1U * aSu;
|
||||
aRes.D2U = aRepRes->D2V * aSv2;
|
||||
aRes.D2V = aRepRes->D2U * aSu2;
|
||||
aRes.D2UV = aRepRes->D2UV * aSuSv;
|
||||
}
|
||||
else
|
||||
{
|
||||
aRes.D1U = aRepRes->D1U * aSu;
|
||||
aRes.D1V = aRepRes->D1V * aSv;
|
||||
aRes.D2U = aRepRes->D2U * aSu2;
|
||||
aRes.D2V = aRepRes->D2V * aSv2;
|
||||
aRes.D2UV = aRepRes->D2UV * aSuSv;
|
||||
}
|
||||
|
||||
return aRes;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<Geom_Surface::ResD3> Geom_EvalRepUtils::TryEvalSurfaceD3Mapped(
|
||||
const Geom_EvalRepSurfaceDesc::Mapped& theDesc,
|
||||
const double theU,
|
||||
const double theV)
|
||||
{
|
||||
double aURep = 0.0;
|
||||
double aVRep = 0.0;
|
||||
theDesc.ParamMap.Map(theU, theV, aURep, aVRep);
|
||||
|
||||
if (theDesc.Domain.has_value() && !theDesc.Domain->Contains(aURep, aVRep))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const std::optional<Geom_Surface::ResD3> aRepRes = theDesc.Representation->EvalD3(aURep, aVRep);
|
||||
if (!aRepRes)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
Geom_Surface::ResD3 aRes;
|
||||
aRes.Point = aRepRes->Point;
|
||||
|
||||
const double aSu = theDesc.ParamMap.ScaleU;
|
||||
const double aSv = theDesc.ParamMap.ScaleV;
|
||||
|
||||
if (theDesc.ParamMap.SwapUV)
|
||||
{
|
||||
aRes.D1U = aRepRes->D1V * aSv;
|
||||
aRes.D1V = aRepRes->D1U * aSu;
|
||||
aRes.D2U = aRepRes->D2V * (aSv * aSv);
|
||||
aRes.D2V = aRepRes->D2U * (aSu * aSu);
|
||||
aRes.D2UV = aRepRes->D2UV * (aSu * aSv);
|
||||
aRes.D3U = aRepRes->D3V * (aSv * aSv * aSv);
|
||||
aRes.D3V = aRepRes->D3U * (aSu * aSu * aSu);
|
||||
aRes.D3UUV = aRepRes->D3UVV * (aSv * aSv * aSu);
|
||||
aRes.D3UVV = aRepRes->D3UUV * (aSu * aSu * aSv);
|
||||
}
|
||||
else
|
||||
{
|
||||
aRes.D1U = aRepRes->D1U * aSu;
|
||||
aRes.D1V = aRepRes->D1V * aSv;
|
||||
aRes.D2U = aRepRes->D2U * (aSu * aSu);
|
||||
aRes.D2V = aRepRes->D2V * (aSv * aSv);
|
||||
aRes.D2UV = aRepRes->D2UV * (aSu * aSv);
|
||||
aRes.D3U = aRepRes->D3U * (aSu * aSu * aSu);
|
||||
aRes.D3V = aRepRes->D3V * (aSv * aSv * aSv);
|
||||
aRes.D3UUV = aRepRes->D3UUV * (aSu * aSu * aSv);
|
||||
aRes.D3UVV = aRepRes->D3UVV * (aSu * aSv * aSv);
|
||||
}
|
||||
|
||||
return aRes;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline std::optional<gp_Vec> Geom_EvalRepUtils::TryEvalSurfaceDNMapped(
|
||||
const Geom_EvalRepSurfaceDesc::Mapped& theDesc,
|
||||
const double theU,
|
||||
const double theV,
|
||||
const int theNu,
|
||||
const int theNv)
|
||||
{
|
||||
double aURep = 0.0;
|
||||
double aVRep = 0.0;
|
||||
theDesc.ParamMap.Map(theU, theV, aURep, aVRep);
|
||||
|
||||
if (theDesc.Domain.has_value() && !theDesc.Domain->Contains(aURep, aVRep))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
int aNuRep = theNu;
|
||||
int aNvRep = theNv;
|
||||
|
||||
if (theDesc.ParamMap.SwapUV)
|
||||
{
|
||||
aNuRep = theNv;
|
||||
aNvRep = theNu;
|
||||
}
|
||||
|
||||
const std::optional<gp_Vec> aRepVec =
|
||||
theDesc.Representation->EvalDN(aURep, aVRep, aNuRep, aNvRep);
|
||||
if (!aRepVec)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const double aScale =
|
||||
std::pow(theDesc.ParamMap.ScaleU, aNuRep) * std::pow(theDesc.ParamMap.ScaleV, aNvRep);
|
||||
|
||||
return (*aRepVec) * aScale;
|
||||
}
|
||||
|
||||
#endif // _Geom_EvalRepUtils_HeaderFile
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <Geom_BezierCurve.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <Geom_Curve.hxx>
|
||||
#include "Geom_EvalRepCurveDesc.hxx"
|
||||
#include "Geom_EvalRepUtils.pxx"
|
||||
#include <Geom_Geometry.hxx>
|
||||
#include <Geom_OffsetCurve.hxx>
|
||||
#include <Geom_OffsetCurveUtils.pxx>
|
||||
@@ -35,6 +37,7 @@
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_ConstructionError.hxx>
|
||||
#include <Standard_NotImplemented.hxx>
|
||||
#include <Standard_ProgramError.hxx>
|
||||
#include <Standard_RangeError.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
@@ -44,6 +47,15 @@ static const double MyAngularToleranceForG1 = Precision::Angular();
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
void Geom_OffsetCurve::SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc)
|
||||
{
|
||||
Geom_EvalRepUtils::ValidateCurveDesc(theDesc, this);
|
||||
myEvalRep = theDesc;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
occ::handle<Geom_Geometry> Geom_OffsetCurve::Copy() const
|
||||
{
|
||||
return new Geom_OffsetCurve(*this);
|
||||
@@ -57,6 +69,7 @@ occ::handle<Geom_Geometry> Geom_OffsetCurve::Copy() const
|
||||
|
||||
Geom_OffsetCurve::Geom_OffsetCurve(const Geom_OffsetCurve& theOther)
|
||||
: basisCurve(occ::down_cast<Geom_Curve>(theOther.basisCurve->Copy())),
|
||||
myEvalRep(Geom_EvalRepUtils::CloneCurveDesc(theOther.myEvalRep)),
|
||||
direction(theOther.direction),
|
||||
offsetValue(theOther.offsetValue),
|
||||
myBasisCurveContinuity(theOther.myBasisCurveContinuity)
|
||||
@@ -80,6 +93,7 @@ Geom_OffsetCurve::Geom_OffsetCurve(const occ::handle<Geom_Curve>& theCurve,
|
||||
|
||||
void Geom_OffsetCurve::Reverse()
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
basisCurve->Reverse();
|
||||
offsetValue = -offsetValue;
|
||||
}
|
||||
@@ -102,6 +116,7 @@ const gp_Dir& Geom_OffsetCurve::Direction() const
|
||||
|
||||
void Geom_OffsetCurve::SetDirection(const gp_Dir& V)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
direction = V;
|
||||
}
|
||||
|
||||
@@ -109,6 +124,7 @@ void Geom_OffsetCurve::SetDirection(const gp_Dir& V)
|
||||
|
||||
void Geom_OffsetCurve::SetOffsetValue(const double D)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
offsetValue = D;
|
||||
}
|
||||
|
||||
@@ -130,6 +146,7 @@ double Geom_OffsetCurve::Period() const
|
||||
|
||||
void Geom_OffsetCurve::SetBasisCurve(const occ::handle<Geom_Curve>& C, const bool isNotCheckC0)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
const double aUf = C->FirstParameter(), aUl = C->LastParameter();
|
||||
occ::handle<Geom_Curve> aCheckingCurve = occ::down_cast<Geom_Curve>(C->Copy());
|
||||
bool isTrimmed = false;
|
||||
@@ -242,6 +259,13 @@ GeomAbs_Shape Geom_OffsetCurve::Continuity() const
|
||||
|
||||
std::optional<gp_Pnt> Geom_OffsetCurve::EvalD0(const double theU) const
|
||||
{
|
||||
if (const std::optional<gp_Pnt> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalCurveD0(myEvalRep, theU);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD1> aBasisD1 = basisCurve->EvalD1(theU);
|
||||
if (!aBasisD1)
|
||||
return std::nullopt;
|
||||
@@ -255,6 +279,13 @@ std::optional<gp_Pnt> Geom_OffsetCurve::EvalD0(const double theU) const
|
||||
|
||||
std::optional<Geom_Curve::ResD1> Geom_OffsetCurve::EvalD1(const double theU) const
|
||||
{
|
||||
if (const std::optional<Geom_Curve::ResD1> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalCurveD1(myEvalRep, theU);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD2> aBasisD2 = basisCurve->EvalD2(theU);
|
||||
if (!aBasisD2)
|
||||
return std::nullopt;
|
||||
@@ -269,6 +300,13 @@ std::optional<Geom_Curve::ResD1> Geom_OffsetCurve::EvalD1(const double theU) con
|
||||
|
||||
std::optional<Geom_Curve::ResD2> Geom_OffsetCurve::EvalD2(const double theU) const
|
||||
{
|
||||
if (const std::optional<Geom_Curve::ResD2> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalCurveD2(myEvalRep, theU);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD3> aBasisD3 = basisCurve->EvalD3(theU);
|
||||
if (!aBasisD3)
|
||||
return std::nullopt;
|
||||
@@ -303,6 +341,13 @@ std::optional<Geom_Curve::ResD2> Geom_OffsetCurve::EvalD2(const double theU) con
|
||||
|
||||
std::optional<Geom_Curve::ResD3> Geom_OffsetCurve::EvalD3(const double theU) const
|
||||
{
|
||||
if (const std::optional<Geom_Curve::ResD3> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalCurveD3(myEvalRep, theU);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD3> aBasisD3 = basisCurve->EvalD3(theU);
|
||||
if (!aBasisD3)
|
||||
return std::nullopt;
|
||||
@@ -343,6 +388,12 @@ std::optional<gp_Vec> Geom_OffsetCurve::EvalDN(const double U, const int N) cons
|
||||
{
|
||||
if (N < 1)
|
||||
return std::nullopt;
|
||||
if (const std::optional<gp_Vec> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalCurveDN(myEvalRep, U, N);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
switch (N)
|
||||
{
|
||||
case 1: {
|
||||
@@ -405,6 +456,7 @@ bool Geom_OffsetCurve::IsCN(const int N) const
|
||||
|
||||
void Geom_OffsetCurve::Transform(const gp_Trsf& T)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
basisCurve->Transform(T);
|
||||
direction.Transform(T);
|
||||
offsetValue *= T.ScaleFactor();
|
||||
|
||||
@@ -27,6 +27,11 @@
|
||||
class gp_Trsf;
|
||||
class Geom_Geometry;
|
||||
|
||||
namespace Geom_EvalRepCurveDesc
|
||||
{
|
||||
class Base;
|
||||
}
|
||||
|
||||
//! This class implements the basis services for an offset curve
|
||||
//! in 3D space. The Offset curve in this package can be a self
|
||||
//! intersecting curve even if the basis curve does not
|
||||
@@ -98,6 +103,20 @@ public:
|
||||
//! @param[in] theOther the offset curve to copy from
|
||||
Standard_EXPORT Geom_OffsetCurve(const Geom_OffsetCurve& theOther);
|
||||
|
||||
//! Returns true if an evaluation representation is attached.
|
||||
bool HasEvalRepresentation() const { return !myEvalRep.IsNull(); }
|
||||
|
||||
//! Returns the current evaluation representation descriptor (may be null).
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& EvalRepresentation() const { return myEvalRep; }
|
||||
|
||||
//! Sets a new evaluation representation.
|
||||
//! Validates descriptor data and ensures no circular references.
|
||||
Standard_EXPORT void SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepCurveDesc::Base>& theDesc);
|
||||
|
||||
//! Removes the evaluation representation.
|
||||
void ClearEvalRepresentation() { myEvalRep.Nullify(); }
|
||||
|
||||
//! Changes the orientation of this offset curve.
|
||||
//! As a result:
|
||||
//! - the basis curve is reversed,
|
||||
@@ -273,10 +292,11 @@ public:
|
||||
DEFINE_STANDARD_RTTIEXT(Geom_OffsetCurve, Geom_Curve)
|
||||
|
||||
private:
|
||||
occ::handle<Geom_Curve> basisCurve;
|
||||
gp_Dir direction;
|
||||
double offsetValue;
|
||||
GeomAbs_Shape myBasisCurveContinuity;
|
||||
occ::handle<Geom_Curve> basisCurve;
|
||||
occ::handle<Geom_EvalRepCurveDesc::Base> myEvalRep;
|
||||
gp_Dir direction;
|
||||
double offsetValue;
|
||||
GeomAbs_Shape myBasisCurveContinuity;
|
||||
};
|
||||
|
||||
#endif // _Geom_OffsetCurve_HeaderFile
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <Geom_CylindricalSurface.hxx>
|
||||
#include <Geom_ElementarySurface.hxx>
|
||||
#include "Geom_EvalRepSurfaceDesc.hxx"
|
||||
#include "Geom_EvalRepUtils.pxx"
|
||||
#include <Geom_Ellipse.hxx>
|
||||
#include <Geom_Geometry.hxx>
|
||||
#include <Geom_OffsetCurve.hxx>
|
||||
@@ -53,6 +55,7 @@
|
||||
#include <Standard_ConstructionError.hxx>
|
||||
#include <Standard_NotImplemented.hxx>
|
||||
#include <Standard_NumericError.hxx>
|
||||
#include <Standard_ProgramError.hxx>
|
||||
#include <Standard_RangeError.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
@@ -64,6 +67,44 @@ IMPLEMENT_STANDARD_RTTIEXT(Geom_OffsetSurface, Geom_Surface)
|
||||
|
||||
static const double MyAngularToleranceForG1 = Precision::Angular();
|
||||
|
||||
namespace
|
||||
{
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::Base> makeFullSurfaceRep(
|
||||
const occ::handle<Geom_Surface>& theSurface)
|
||||
{
|
||||
if (theSurface.IsNull())
|
||||
{
|
||||
return occ::handle<Geom_EvalRepSurfaceDesc::Base>();
|
||||
}
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::Full> aDesc = new Geom_EvalRepSurfaceDesc::Full();
|
||||
aDesc->Representation = theSurface;
|
||||
return aDesc;
|
||||
}
|
||||
|
||||
occ::handle<Geom_Surface> directRepSurface(const Geom_OffsetSurface& theSurface)
|
||||
{
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& aDesc = theSurface.EvalRepresentation();
|
||||
if (aDesc.IsNull())
|
||||
{
|
||||
return occ::handle<Geom_Surface>();
|
||||
}
|
||||
if (aDesc->GetKind() != Geom_EvalRepSurfaceDesc::Base::Kind::Full)
|
||||
{
|
||||
return occ::handle<Geom_Surface>();
|
||||
}
|
||||
return aDesc->Representation;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Geom_OffsetSurface::SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc)
|
||||
{
|
||||
Geom_EvalRepUtils::ValidateSurfaceDesc(theDesc, this);
|
||||
myEvalRep = theDesc;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
occ::handle<Geom_Geometry> Geom_OffsetSurface::Copy() const
|
||||
@@ -79,15 +120,13 @@ occ::handle<Geom_Geometry> Geom_OffsetSurface::Copy() const
|
||||
|
||||
Geom_OffsetSurface::Geom_OffsetSurface(const Geom_OffsetSurface& theOther)
|
||||
: basisSurf(occ::down_cast<Geom_Surface>(theOther.basisSurf->Copy())),
|
||||
equivSurf(theOther.equivSurf.IsNull()
|
||||
? occ::handle<Geom_Surface>()
|
||||
: occ::down_cast<Geom_Surface>(theOther.equivSurf->Copy())),
|
||||
myEvalRep(Geom_EvalRepUtils::CloneSurfaceDesc(theOther.myEvalRep)),
|
||||
offsetValue(theOther.offsetValue),
|
||||
myOscSurf(theOther.myOscSurf ? std::make_unique<Geom_OsculatingSurface>(*theOther.myOscSurf)
|
||||
: nullptr),
|
||||
myBasisSurfContinuity(theOther.myBasisSurfContinuity)
|
||||
{
|
||||
// Deep copy without validation - source surface is already validated
|
||||
// Deep copy without validation - source surface is already validated.
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@@ -109,6 +148,7 @@ Geom_OffsetSurface::Geom_OffsetSurface(const occ::handle<Geom_Surface>& theSurf,
|
||||
void Geom_OffsetSurface::SetBasisSurface(const occ::handle<Geom_Surface>& S,
|
||||
const bool isNotCheckC0)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
double aUf, aUl, aVf, aVl;
|
||||
S->Bounds(aUf, aUl, aVf, aVl);
|
||||
|
||||
@@ -215,7 +255,8 @@ void Geom_OffsetSurface::SetBasisSurface(const occ::handle<Geom_Surface>& S,
|
||||
basisSurf = aCheckingSurf;
|
||||
}
|
||||
|
||||
equivSurf = Surface();
|
||||
const occ::handle<Geom_Surface> aSurfaceRep = Surface();
|
||||
SetEvalRepresentation(makeFullSurfaceRep(aSurfaceRep));
|
||||
|
||||
if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))
|
||||
|| aCheckingSurf->IsKind(STANDARD_TYPE(Geom_BezierSurface)))
|
||||
@@ -233,18 +274,18 @@ void Geom_OffsetSurface::SetBasisSurface(const occ::handle<Geom_Surface>& S,
|
||||
|
||||
void Geom_OffsetSurface::SetOffsetValue(const double D)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
offsetValue = D;
|
||||
equivSurf = Surface();
|
||||
SetEvalRepresentation(makeFullSurfaceRep(Surface()));
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Geom_OffsetSurface::UReverse()
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
basisSurf->UReverse();
|
||||
offsetValue = -offsetValue;
|
||||
if (!equivSurf.IsNull())
|
||||
equivSurf->UReverse();
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@@ -258,10 +299,9 @@ double Geom_OffsetSurface::UReversedParameter(const double U) const
|
||||
|
||||
void Geom_OffsetSurface::VReverse()
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
basisSurf->VReverse();
|
||||
offsetValue = -offsetValue;
|
||||
if (!equivSurf.IsNull())
|
||||
equivSurf->VReverse();
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@@ -306,9 +346,11 @@ std::optional<gp_Pnt> Geom_OffsetSurface::EvalD0(const double U, const double V)
|
||||
return std::nullopt;
|
||||
}
|
||||
#endif
|
||||
if (!equivSurf.IsNull())
|
||||
if (const std::optional<gp_Pnt> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD0(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return equivSurf->EvalD0(U, V);
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
gp_Pnt aP;
|
||||
@@ -329,9 +371,11 @@ std::optional<Geom_Surface::ResD1> Geom_OffsetSurface::EvalD1(const double U, co
|
||||
return std::nullopt;
|
||||
}
|
||||
#endif
|
||||
if (!equivSurf.IsNull())
|
||||
if (const std::optional<Geom_Surface::ResD1> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD1(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return equivSurf->EvalD1(U, V);
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
Geom_Surface::ResD1 aResult;
|
||||
@@ -360,9 +404,11 @@ std::optional<Geom_Surface::ResD2> Geom_OffsetSurface::EvalD2(const double U, co
|
||||
return std::nullopt;
|
||||
}
|
||||
#endif
|
||||
if (!equivSurf.IsNull())
|
||||
if (const std::optional<Geom_Surface::ResD2> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD2(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return equivSurf->EvalD2(U, V);
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
Geom_Surface::ResD2 aResult;
|
||||
@@ -393,9 +439,11 @@ std::optional<Geom_Surface::ResD3> Geom_OffsetSurface::EvalD3(const double U, co
|
||||
return std::nullopt;
|
||||
}
|
||||
#endif
|
||||
if (!equivSurf.IsNull())
|
||||
if (const std::optional<Geom_Surface::ResD3> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD3(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return equivSurf->EvalD3(U, V);
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
Geom_Surface::ResD3 aResult;
|
||||
@@ -435,9 +483,11 @@ std::optional<gp_Vec> Geom_OffsetSurface::EvalDN(const double U,
|
||||
return std::nullopt;
|
||||
}
|
||||
#endif
|
||||
if (!equivSurf.IsNull())
|
||||
if (const std::optional<gp_Vec> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceDN(myEvalRep, U, V, Nu, Nv);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return equivSurf->EvalDN(U, V, Nu, Nv);
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
gp_Vec aResult;
|
||||
@@ -565,7 +615,8 @@ void Geom_OffsetSurface_VIsoEvaluator::Evaluate(int*, /*Dimension*/
|
||||
|
||||
occ::handle<Geom_Curve> Geom_OffsetSurface::UIso(const double UU) const
|
||||
{
|
||||
if (equivSurf.IsNull())
|
||||
const occ::handle<Geom_Surface> anEquivSurface = directRepSurface(*this);
|
||||
if (anEquivSurface.IsNull())
|
||||
{
|
||||
GeomAdaptor_Surface aGAsurf(basisSurf);
|
||||
if (aGAsurf.GetType() == GeomAbs_SurfaceOfExtrusion)
|
||||
@@ -608,15 +659,15 @@ occ::handle<Geom_Curve> Geom_OffsetSurface::UIso(const double UU) const
|
||||
occ::handle<Geom_BSplineCurve> C = new Geom_BSplineCurve(Poles, Knots, Mults, Approx.Degree());
|
||||
return C;
|
||||
}
|
||||
else
|
||||
return equivSurf->UIso(UU);
|
||||
return anEquivSurface->UIso(UU);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
occ::handle<Geom_Curve> Geom_OffsetSurface::VIso(const double VV) const
|
||||
{
|
||||
if (equivSurf.IsNull())
|
||||
const occ::handle<Geom_Surface> anEquivSurface = directRepSurface(*this);
|
||||
if (anEquivSurface.IsNull())
|
||||
{
|
||||
const int Num1 = 0, Num2 = 0, Num3 = 1;
|
||||
occ::handle<NCollection_HArray1<double>> T1, T2, T3 = new NCollection_HArray1<double>(1, Num3);
|
||||
@@ -644,8 +695,7 @@ occ::handle<Geom_Curve> Geom_OffsetSurface::VIso(const double VV) const
|
||||
occ::handle<Geom_BSplineCurve> C = new Geom_BSplineCurve(Poles, Knots, Mults, Approx.Degree());
|
||||
return C;
|
||||
}
|
||||
else
|
||||
return equivSurf->VIso(VV);
|
||||
return anEquivSurface->VIso(VV);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@@ -799,9 +849,9 @@ bool Geom_OffsetSurface::IsVClosed() const
|
||||
|
||||
void Geom_OffsetSurface::Transform(const gp_Trsf& T)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
basisSurf->Transform(T);
|
||||
offsetValue *= T.ScaleFactor();
|
||||
equivSurf.Nullify();
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@@ -809,8 +859,11 @@ void Geom_OffsetSurface::Transform(const gp_Trsf& T)
|
||||
void Geom_OffsetSurface::TransformParameters(double& U, double& V, const gp_Trsf& T) const
|
||||
{
|
||||
basisSurf->TransformParameters(U, V, T);
|
||||
if (!equivSurf.IsNull())
|
||||
equivSurf->TransformParameters(U, V, T);
|
||||
const occ::handle<Geom_Surface> anEquivSurface = directRepSurface(*this);
|
||||
if (!anEquivSurface.IsNull())
|
||||
{
|
||||
anEquivSurface->TransformParameters(U, V, T);
|
||||
}
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@@ -972,12 +1025,14 @@ bool Geom_OffsetSurface::VOsculatingSurface(const double U,
|
||||
|
||||
void Geom_OffsetSurface::DumpJson(Standard_OStream& theOStream, int theDepth) const
|
||||
{
|
||||
const occ::handle<Geom_Surface> anEquivSurface = directRepSurface(*this);
|
||||
|
||||
OCCT_DUMP_TRANSIENT_CLASS_BEGIN(theOStream)
|
||||
|
||||
OCCT_DUMP_BASE_CLASS(theOStream, theDepth, Geom_Surface)
|
||||
|
||||
OCCT_DUMP_FIELD_VALUES_DUMPED(theOStream, theDepth, basisSurf.get())
|
||||
OCCT_DUMP_FIELD_VALUES_DUMPED(theOStream, theDepth, equivSurf.get())
|
||||
OCCT_DUMP_FIELD_VALUES_DUMPED(theOStream, theDepth, anEquivSurface.get())
|
||||
|
||||
OCCT_DUMP_FIELD_VALUE_NUMERICAL(theOStream, offsetValue)
|
||||
OCCT_DUMP_FIELD_VALUE_NUMERICAL(theOStream, myBasisSurfContinuity)
|
||||
|
||||
@@ -32,6 +32,11 @@ class gp_Trsf;
|
||||
class gp_GTrsf2d;
|
||||
class Geom_Geometry;
|
||||
|
||||
namespace Geom_EvalRepSurfaceDesc
|
||||
{
|
||||
class Base;
|
||||
}
|
||||
|
||||
//! Describes an offset surface in 3D space.
|
||||
//! An offset surface is defined by:
|
||||
//! - the basis surface to which it is parallel, and
|
||||
@@ -86,6 +91,20 @@ public:
|
||||
const double Offset,
|
||||
const bool isNotCheckC0 = false);
|
||||
|
||||
//! Returns true if an evaluation representation is attached.
|
||||
bool HasEvalRepresentation() const { return !myEvalRep.IsNull(); }
|
||||
|
||||
//! Returns the current evaluation representation descriptor (may be null).
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& EvalRepresentation() const { return myEvalRep; }
|
||||
|
||||
//! Sets a new evaluation representation.
|
||||
//! Validates descriptor data and ensures no circular references.
|
||||
Standard_EXPORT void SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc);
|
||||
|
||||
//! Removes the evaluation representation.
|
||||
void ClearEvalRepresentation() { myEvalRep.Nullify(); }
|
||||
|
||||
//! Raised if S is not at least C1.
|
||||
//! Warnings :
|
||||
//! No check is done to verify that a unique normal direction is
|
||||
@@ -354,11 +373,11 @@ public:
|
||||
DEFINE_STANDARD_RTTIEXT(Geom_OffsetSurface, Geom_Surface)
|
||||
|
||||
private:
|
||||
occ::handle<Geom_Surface> basisSurf;
|
||||
occ::handle<Geom_Surface> equivSurf;
|
||||
double offsetValue;
|
||||
std::unique_ptr<Geom_OsculatingSurface> myOscSurf;
|
||||
GeomAbs_Shape myBasisSurfContinuity;
|
||||
occ::handle<Geom_Surface> basisSurf;
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::Base> myEvalRep;
|
||||
double offsetValue;
|
||||
std::unique_ptr<Geom_OsculatingSurface> myOscSurf;
|
||||
GeomAbs_Shape myBasisSurfContinuity;
|
||||
};
|
||||
|
||||
#endif // _Geom_OffsetSurface_HeaderFile
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <BSplSLib.hxx>
|
||||
#include <Geom_BezierCurve.hxx>
|
||||
#include <Geom_Curve.hxx>
|
||||
#include "Geom_EvalRepSurfaceDesc.hxx"
|
||||
#include "Geom_EvalRepUtils.pxx"
|
||||
#include "Geom_ExtrusionUtils.pxx"
|
||||
#include <Geom_Geometry.hxx>
|
||||
#include <Geom_Line.hxx>
|
||||
@@ -32,6 +34,7 @@
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_XYZ.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_ProgramError.hxx>
|
||||
#include <Standard_RangeError.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
@@ -55,12 +58,21 @@ typedef gp_XYZ XYZ;
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Geom_SurfaceOfLinearExtrusion::SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc)
|
||||
{
|
||||
Geom_EvalRepUtils::ValidateSurfaceDesc(theDesc, this);
|
||||
myEvalRep = theDesc;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
occ::handle<Geom_Geometry> Geom_SurfaceOfLinearExtrusion::Copy() const
|
||||
{
|
||||
|
||||
occ::handle<Geom_SurfaceOfLinearExtrusion> Sr;
|
||||
Sr = new SurfaceOfLinearExtrusion(basisCurve, direction);
|
||||
return Sr;
|
||||
occ::handle<Geom_SurfaceOfLinearExtrusion> aCopy =
|
||||
new SurfaceOfLinearExtrusion(basisCurve, direction);
|
||||
aCopy->myEvalRep = Geom_EvalRepUtils::CloneSurfaceDesc(myEvalRep);
|
||||
return aCopy;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@@ -77,7 +89,7 @@ Geom_SurfaceOfLinearExtrusion::Geom_SurfaceOfLinearExtrusion(const occ::handle<G
|
||||
|
||||
void Geom_SurfaceOfLinearExtrusion::UReverse()
|
||||
{
|
||||
|
||||
ClearEvalRepresentation();
|
||||
basisCurve->Reverse();
|
||||
}
|
||||
|
||||
@@ -93,6 +105,7 @@ double Geom_SurfaceOfLinearExtrusion::UReversedParameter(const double U) const
|
||||
|
||||
void Geom_SurfaceOfLinearExtrusion::VReverse()
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
direction.Reverse();
|
||||
}
|
||||
|
||||
@@ -108,6 +121,7 @@ double Geom_SurfaceOfLinearExtrusion::VReversedParameter(const double V) const
|
||||
|
||||
void Geom_SurfaceOfLinearExtrusion::SetDirection(const Dir& V)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
direction = V;
|
||||
}
|
||||
|
||||
@@ -115,6 +129,7 @@ void Geom_SurfaceOfLinearExtrusion::SetDirection(const Dir& V)
|
||||
|
||||
void Geom_SurfaceOfLinearExtrusion::SetBasisCurve(const occ::handle<Geom_Curve>& C)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
smooth = C->Continuity();
|
||||
basisCurve = occ::down_cast<Geom_Curve>(C->Copy());
|
||||
}
|
||||
@@ -134,6 +149,13 @@ void Geom_SurfaceOfLinearExtrusion::Bounds(double& U1, double& U2, double& V1, d
|
||||
|
||||
std::optional<gp_Pnt> Geom_SurfaceOfLinearExtrusion::EvalD0(const double U, const double V) const
|
||||
{
|
||||
if (const std::optional<gp_Pnt> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD0(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<gp_Pnt> aBasisD0 = basisCurve->EvalD0(U);
|
||||
if (!aBasisD0)
|
||||
return std::nullopt;
|
||||
@@ -147,6 +169,13 @@ std::optional<gp_Pnt> Geom_SurfaceOfLinearExtrusion::EvalD0(const double U, cons
|
||||
std::optional<Geom_Surface::ResD1> Geom_SurfaceOfLinearExtrusion::EvalD1(const double U,
|
||||
const double V) const
|
||||
{
|
||||
if (const std::optional<Geom_Surface::ResD1> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD1(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD1> aBasisD1 = basisCurve->EvalD1(U);
|
||||
if (!aBasisD1)
|
||||
return std::nullopt;
|
||||
@@ -166,6 +195,13 @@ std::optional<Geom_Surface::ResD1> Geom_SurfaceOfLinearExtrusion::EvalD1(const d
|
||||
std::optional<Geom_Surface::ResD2> Geom_SurfaceOfLinearExtrusion::EvalD2(const double U,
|
||||
const double V) const
|
||||
{
|
||||
if (const std::optional<Geom_Surface::ResD2> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD2(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD2> aBasisD2 = basisCurve->EvalD2(U);
|
||||
if (!aBasisD2)
|
||||
return std::nullopt;
|
||||
@@ -189,6 +225,13 @@ std::optional<Geom_Surface::ResD2> Geom_SurfaceOfLinearExtrusion::EvalD2(const d
|
||||
std::optional<Geom_Surface::ResD3> Geom_SurfaceOfLinearExtrusion::EvalD3(const double U,
|
||||
const double V) const
|
||||
{
|
||||
if (const std::optional<Geom_Surface::ResD3> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD3(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD3> aBasisD3 = basisCurve->EvalD3(U);
|
||||
if (!aBasisD3)
|
||||
return std::nullopt;
|
||||
@@ -215,12 +258,20 @@ std::optional<Geom_Surface::ResD3> Geom_SurfaceOfLinearExtrusion::EvalD3(const d
|
||||
//=================================================================================================
|
||||
|
||||
std::optional<gp_Vec> Geom_SurfaceOfLinearExtrusion::EvalDN(const double U,
|
||||
const double,
|
||||
const int Nu,
|
||||
const int Nv) const
|
||||
const double V,
|
||||
const int Nu,
|
||||
const int Nv) const
|
||||
{
|
||||
if (Nu + Nv < 1 || Nu < 0 || Nv < 0)
|
||||
return std::nullopt;
|
||||
|
||||
if (const std::optional<gp_Vec> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceDN(myEvalRep, U, V, Nu, Nv);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
if (Nv == 0)
|
||||
{
|
||||
std::optional<gp_Vec> aDN = basisCurve->EvalDN(U, Nu);
|
||||
@@ -278,6 +329,7 @@ bool Geom_SurfaceOfLinearExtrusion::IsCNv(const int) const
|
||||
|
||||
void Geom_SurfaceOfLinearExtrusion::Transform(const Trsf& T)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
direction.Transform(T);
|
||||
basisCurve->Transform(T);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,11 @@ class gp_Trsf;
|
||||
class gp_GTrsf2d;
|
||||
class Geom_Geometry;
|
||||
|
||||
namespace Geom_EvalRepSurfaceDesc
|
||||
{
|
||||
class Base;
|
||||
}
|
||||
|
||||
//! Describes a surface of linear extrusion ("extruded
|
||||
//! surface"), e.g. a generalized cylinder. Such a surface
|
||||
//! is obtained by sweeping a curve (called the "extruded
|
||||
@@ -72,6 +77,20 @@ public:
|
||||
//! line.
|
||||
Standard_EXPORT Geom_SurfaceOfLinearExtrusion(const occ::handle<Geom_Curve>& C, const gp_Dir& V);
|
||||
|
||||
//! Returns true if an evaluation representation is attached.
|
||||
bool HasEvalRepresentation() const { return !myEvalRep.IsNull(); }
|
||||
|
||||
//! Returns the current evaluation representation descriptor (may be null).
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& EvalRepresentation() const { return myEvalRep; }
|
||||
|
||||
//! Sets a new evaluation representation.
|
||||
//! Validates descriptor data and ensures no circular references.
|
||||
Standard_EXPORT void SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc);
|
||||
|
||||
//! Removes the evaluation representation.
|
||||
void ClearEvalRepresentation() { myEvalRep.Nullify(); }
|
||||
|
||||
//! Assigns V as the "direction of extrusion" for this
|
||||
//! surface of linear extrusion.
|
||||
Standard_EXPORT void SetDirection(const gp_Dir& V);
|
||||
@@ -235,6 +254,9 @@ public:
|
||||
Standard_EXPORT void DumpJson(Standard_OStream& theOStream, int theDepth = -1) const final;
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(Geom_SurfaceOfLinearExtrusion, Geom_SweptSurface)
|
||||
|
||||
private:
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::Base> myEvalRep;
|
||||
};
|
||||
|
||||
#endif // _Geom_SurfaceOfLinearExtrusion_HeaderFile
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <Geom_Circle.hxx>
|
||||
#include <Geom_Curve.hxx>
|
||||
#include "Geom_EvalRepSurfaceDesc.hxx"
|
||||
#include "Geom_EvalRepUtils.pxx"
|
||||
#include <Geom_Geometry.hxx>
|
||||
#include "Geom_RevolutionUtils.pxx"
|
||||
#include <Geom_SurfaceOfRevolution.hxx>
|
||||
@@ -36,6 +38,7 @@
|
||||
#include <gp_XYZ.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_NotImplemented.hxx>
|
||||
#include <Standard_ProgramError.hxx>
|
||||
#include <Standard_RangeError.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
@@ -62,10 +65,20 @@ typedef gp_XYZ XYZ;
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void Geom_SurfaceOfRevolution::SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc)
|
||||
{
|
||||
Geom_EvalRepUtils::ValidateSurfaceDesc(theDesc, this);
|
||||
myEvalRep = theDesc;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
occ::handle<Geom_Geometry> Geom_SurfaceOfRevolution::Copy() const
|
||||
{
|
||||
|
||||
return new Geom_SurfaceOfRevolution(basisCurve, Axis());
|
||||
occ::handle<Geom_SurfaceOfRevolution> aCopy = new Geom_SurfaceOfRevolution(basisCurve, Axis());
|
||||
aCopy->myEvalRep = Geom_EvalRepUtils::CloneSurfaceDesc(myEvalRep);
|
||||
return aCopy;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@@ -81,6 +94,7 @@ Geom_SurfaceOfRevolution::Geom_SurfaceOfRevolution(const occ::handle<Geom_Curve>
|
||||
|
||||
void Geom_SurfaceOfRevolution::UReverse()
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
direction.Reverse();
|
||||
}
|
||||
|
||||
@@ -96,7 +110,7 @@ double Geom_SurfaceOfRevolution::UReversedParameter(const double U) const
|
||||
|
||||
void Geom_SurfaceOfRevolution::VReverse()
|
||||
{
|
||||
|
||||
ClearEvalRepresentation();
|
||||
basisCurve->Reverse();
|
||||
}
|
||||
|
||||
@@ -176,6 +190,7 @@ bool Geom_SurfaceOfRevolution::IsVPeriodic() const
|
||||
|
||||
void Geom_SurfaceOfRevolution::SetAxis(const Ax1& A1)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
direction = A1.Direction();
|
||||
loc = A1.Location();
|
||||
}
|
||||
@@ -184,6 +199,7 @@ void Geom_SurfaceOfRevolution::SetAxis(const Ax1& A1)
|
||||
|
||||
void Geom_SurfaceOfRevolution::SetDirection(const Dir& V)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
direction = V;
|
||||
}
|
||||
|
||||
@@ -191,6 +207,7 @@ void Geom_SurfaceOfRevolution::SetDirection(const Dir& V)
|
||||
|
||||
void Geom_SurfaceOfRevolution::SetBasisCurve(const occ::handle<Geom_Curve>& C)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
basisCurve = occ::down_cast<Geom_Curve>(C->Copy());
|
||||
smooth = C->Continuity();
|
||||
}
|
||||
@@ -199,6 +216,7 @@ void Geom_SurfaceOfRevolution::SetBasisCurve(const occ::handle<Geom_Curve>& C)
|
||||
|
||||
void Geom_SurfaceOfRevolution::SetLocation(const Pnt& P)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
loc = P;
|
||||
}
|
||||
|
||||
@@ -217,6 +235,13 @@ void Geom_SurfaceOfRevolution::Bounds(double& U1, double& U2, double& V1, double
|
||||
|
||||
std::optional<gp_Pnt> Geom_SurfaceOfRevolution::EvalD0(const double U, const double V) const
|
||||
{
|
||||
if (const std::optional<gp_Pnt> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD0(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<gp_Pnt> aBasisD0 = basisCurve->EvalD0(V);
|
||||
if (!aBasisD0)
|
||||
return std::nullopt;
|
||||
@@ -230,6 +255,13 @@ std::optional<gp_Pnt> Geom_SurfaceOfRevolution::EvalD0(const double U, const dou
|
||||
std::optional<Geom_Surface::ResD1> Geom_SurfaceOfRevolution::EvalD1(const double U,
|
||||
const double V) const
|
||||
{
|
||||
if (const std::optional<Geom_Surface::ResD1> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD1(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD1> aBasisD1 = basisCurve->EvalD1(V);
|
||||
if (!aBasisD1)
|
||||
return std::nullopt;
|
||||
@@ -249,6 +281,13 @@ std::optional<Geom_Surface::ResD1> Geom_SurfaceOfRevolution::EvalD1(const double
|
||||
std::optional<Geom_Surface::ResD2> Geom_SurfaceOfRevolution::EvalD2(const double U,
|
||||
const double V) const
|
||||
{
|
||||
if (const std::optional<Geom_Surface::ResD2> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD2(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD2> aBasisD2 = basisCurve->EvalD2(V);
|
||||
if (!aBasisD2)
|
||||
return std::nullopt;
|
||||
@@ -272,6 +311,13 @@ std::optional<Geom_Surface::ResD2> Geom_SurfaceOfRevolution::EvalD2(const double
|
||||
std::optional<Geom_Surface::ResD3> Geom_SurfaceOfRevolution::EvalD3(const double U,
|
||||
const double V) const
|
||||
{
|
||||
if (const std::optional<Geom_Surface::ResD3> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceD3(myEvalRep, U, V);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
|
||||
std::optional<Geom_Curve::ResD3> aBasisD3 = basisCurve->EvalD3(V);
|
||||
if (!aBasisD3)
|
||||
return std::nullopt;
|
||||
@@ -304,6 +350,12 @@ std::optional<gp_Vec> Geom_SurfaceOfRevolution::EvalDN(const double U,
|
||||
{
|
||||
if (Nu + Nv < 1 || Nu < 0 || Nv < 0)
|
||||
return std::nullopt;
|
||||
if (const std::optional<gp_Vec> aEvalRepResult =
|
||||
Geom_EvalRepUtils::TryEvalSurfaceDN(myEvalRep, U, V, Nu, Nv);
|
||||
aEvalRepResult.has_value())
|
||||
{
|
||||
return aEvalRepResult;
|
||||
}
|
||||
gp_Vec aCurvePtOrDN;
|
||||
if (Nu == 0)
|
||||
{
|
||||
@@ -384,6 +436,7 @@ occ::handle<Geom_Curve> Geom_SurfaceOfRevolution::VIso(const double V) const
|
||||
|
||||
void Geom_SurfaceOfRevolution::Transform(const Trsf& T)
|
||||
{
|
||||
ClearEvalRepresentation();
|
||||
loc.Transform(T);
|
||||
direction.Transform(T);
|
||||
basisCurve->Transform(T);
|
||||
|
||||
@@ -30,6 +30,11 @@ class gp_Trsf;
|
||||
class gp_GTrsf2d;
|
||||
class Geom_Geometry;
|
||||
|
||||
namespace Geom_EvalRepSurfaceDesc
|
||||
{
|
||||
class Base;
|
||||
}
|
||||
|
||||
//! Describes a surface of revolution (revolved surface).
|
||||
//! Such a surface is obtained by rotating a curve (called
|
||||
//! the "meridian") through a complete revolution about
|
||||
@@ -91,6 +96,20 @@ public:
|
||||
//! self-intersects.
|
||||
Standard_EXPORT Geom_SurfaceOfRevolution(const occ::handle<Geom_Curve>& C, const gp_Ax1& A1);
|
||||
|
||||
//! Returns true if an evaluation representation is attached.
|
||||
bool HasEvalRepresentation() const { return !myEvalRep.IsNull(); }
|
||||
|
||||
//! Returns the current evaluation representation descriptor (may be null).
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& EvalRepresentation() const { return myEvalRep; }
|
||||
|
||||
//! Sets a new evaluation representation.
|
||||
//! Validates descriptor data and ensures no circular references.
|
||||
Standard_EXPORT void SetEvalRepresentation(
|
||||
const occ::handle<Geom_EvalRepSurfaceDesc::Base>& theDesc);
|
||||
|
||||
//! Removes the evaluation representation.
|
||||
void ClearEvalRepresentation() { myEvalRep.Nullify(); }
|
||||
|
||||
//! Changes the axis of revolution.
|
||||
//! Warnings :
|
||||
//! It is not checked that the axis is in the plane of the
|
||||
@@ -286,7 +305,8 @@ public:
|
||||
DEFINE_STANDARD_RTTIEXT(Geom_SurfaceOfRevolution, Geom_SweptSurface)
|
||||
|
||||
private:
|
||||
gp_Pnt loc;
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::Base> myEvalRep;
|
||||
gp_Pnt loc;
|
||||
};
|
||||
|
||||
#endif // _Geom_SurfaceOfRevolution_HeaderFile
|
||||
|
||||
@@ -61,6 +61,29 @@ static const double PosTol = Precision::PConfusion() / 2;
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(GeomAdaptor_Curve, Adaptor3d_Curve)
|
||||
|
||||
namespace
|
||||
{
|
||||
bool hasEvalRep(const GeomAdaptor_Curve::CurveDataVariant& theData)
|
||||
{
|
||||
if (const GeomAdaptor_Curve::BezierData* aBezierData =
|
||||
std::get_if<GeomAdaptor_Curve::BezierData>(&theData))
|
||||
{
|
||||
return !aBezierData->EvalRep.IsNull();
|
||||
}
|
||||
if (const GeomAdaptor_Curve::BSplineData* aBSplineData =
|
||||
std::get_if<GeomAdaptor_Curve::BSplineData>(&theData))
|
||||
{
|
||||
return !aBSplineData->EvalRep.IsNull();
|
||||
}
|
||||
if (const GeomAdaptor_Curve::OffsetData* anOffsetData =
|
||||
std::get_if<GeomAdaptor_Curve::OffsetData>(&theData))
|
||||
{
|
||||
return !anOffsetData->EvalRep.IsNull();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
occ::handle<Adaptor3d_Curve> GeomAdaptor_Curve::ShallowCopy() const
|
||||
@@ -80,17 +103,24 @@ occ::handle<Adaptor3d_Curve> GeomAdaptor_Curve::ShallowCopy() const
|
||||
occ::down_cast<GeomAdaptor_Curve>(anOffsetData->BasisAdaptor->ShallowCopy());
|
||||
aCopyData.Offset = anOffsetData->Offset;
|
||||
aCopyData.Direction = anOffsetData->Direction;
|
||||
aCopyData.EvalRep = anOffsetData->EvalRep;
|
||||
aCopy->myCurveData = std::move(aCopyData);
|
||||
}
|
||||
else if (const auto* aBSplineData = std::get_if<BSplineData>(&myCurveData))
|
||||
{
|
||||
BSplineData aCopyData;
|
||||
aCopyData.Curve = aBSplineData->Curve;
|
||||
aCopyData.EvalRep = aBSplineData->EvalRep;
|
||||
aCopy->myCurveData = std::move(aCopyData);
|
||||
}
|
||||
else if (std::holds_alternative<BezierData>(myCurveData))
|
||||
{
|
||||
aCopy->myCurveData = BezierData{};
|
||||
const BezierData& aBezierData = std::get<BezierData>(myCurveData);
|
||||
BezierData aCopyData;
|
||||
aCopyData.Curve = aBezierData.Curve;
|
||||
aCopyData.EvalRep = aBezierData.EvalRep;
|
||||
// Cache is not copied - will be rebuilt on demand.
|
||||
aCopy->myCurveData = std::move(aCopyData);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -243,14 +273,18 @@ void GeomAdaptor_Curve::load(const occ::handle<Geom_Curve>& C,
|
||||
else if (TheType == STANDARD_TYPE(Geom_BezierCurve))
|
||||
{
|
||||
myTypeCurve = GeomAbs_BezierCurve;
|
||||
myCurveData = BezierData{};
|
||||
BezierData aBezierData;
|
||||
aBezierData.Curve = occ::down_cast<Geom_BezierCurve>(C);
|
||||
aBezierData.EvalRep = aBezierData.Curve->EvalRepresentation();
|
||||
myCurveData = std::move(aBezierData);
|
||||
}
|
||||
else if (TheType == STANDARD_TYPE(Geom_BSplineCurve))
|
||||
{
|
||||
myTypeCurve = GeomAbs_BSplineCurve;
|
||||
BSplineData aBSplineData;
|
||||
aBSplineData.Curve = occ::down_cast<Geom_BSplineCurve>(C);
|
||||
myCurveData = std::move(aBSplineData);
|
||||
aBSplineData.Curve = occ::down_cast<Geom_BSplineCurve>(C);
|
||||
aBSplineData.EvalRep = aBSplineData.Curve->EvalRepresentation();
|
||||
myCurveData = std::move(aBSplineData);
|
||||
}
|
||||
else if (TheType == STANDARD_TYPE(Geom_OffsetCurve))
|
||||
{
|
||||
@@ -260,6 +294,7 @@ void GeomAdaptor_Curve::load(const occ::handle<Geom_Curve>& C,
|
||||
anOffsetData.BasisAdaptor = new GeomAdaptor_Curve(anOffsetCurve->BasisCurve());
|
||||
anOffsetData.Offset = anOffsetCurve->Offset();
|
||||
anOffsetData.Direction = anOffsetCurve->Direction();
|
||||
anOffsetData.EvalRep = anOffsetCurve->EvalRepresentation();
|
||||
myCurveData = std::move(anOffsetData);
|
||||
}
|
||||
else
|
||||
@@ -656,6 +691,10 @@ std::optional<gp_Pnt> GeomAdaptor_Curve::EvalD0(double U) const
|
||||
return P;
|
||||
|
||||
case GeomAbs_BezierCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD0(U);
|
||||
}
|
||||
auto& aCache = std::get<BezierData>(myCurveData).Cache;
|
||||
if (aCache.IsNull())
|
||||
RebuildCache(U);
|
||||
@@ -664,6 +703,10 @@ std::optional<gp_Pnt> GeomAdaptor_Curve::EvalD0(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_BSplineCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD0(U);
|
||||
}
|
||||
int aStart = 0, aFinish = 0;
|
||||
auto& aBSplData = std::get<BSplineData>(myCurveData);
|
||||
if (IsBoundary(U, aStart, aFinish))
|
||||
@@ -680,6 +723,10 @@ std::optional<gp_Pnt> GeomAdaptor_Curve::EvalD0(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD0(U);
|
||||
}
|
||||
const auto& anOffsetData = std::get<OffsetData>(myCurveData);
|
||||
if (!Geom_OffsetCurveUtils::EvaluateD0(U,
|
||||
anOffsetData.BasisAdaptor.get(),
|
||||
@@ -736,6 +783,10 @@ std::optional<Geom_Curve::ResD1> GeomAdaptor_Curve::EvalD1(double U) const
|
||||
return aResult;
|
||||
|
||||
case GeomAbs_BezierCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD1(U);
|
||||
}
|
||||
auto& aCache = std::get<BezierData>(myCurveData).Cache;
|
||||
if (aCache.IsNull())
|
||||
RebuildCache(U);
|
||||
@@ -744,6 +795,10 @@ std::optional<Geom_Curve::ResD1> GeomAdaptor_Curve::EvalD1(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_BSplineCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD1(U);
|
||||
}
|
||||
int aStart = 0, aFinish = 0;
|
||||
auto& aBSplData = std::get<BSplineData>(myCurveData);
|
||||
if (IsBoundary(U, aStart, aFinish))
|
||||
@@ -760,6 +815,10 @@ std::optional<Geom_Curve::ResD1> GeomAdaptor_Curve::EvalD1(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD1(U);
|
||||
}
|
||||
const auto& anOffsetData = std::get<OffsetData>(myCurveData);
|
||||
if (!Geom_OffsetCurveUtils::EvaluateD1(U,
|
||||
anOffsetData.BasisAdaptor.get(),
|
||||
@@ -819,6 +878,10 @@ std::optional<Geom_Curve::ResD2> GeomAdaptor_Curve::EvalD2(double U) const
|
||||
return aResult;
|
||||
|
||||
case GeomAbs_BezierCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD2(U);
|
||||
}
|
||||
auto& aCache = std::get<BezierData>(myCurveData).Cache;
|
||||
if (aCache.IsNull())
|
||||
RebuildCache(U);
|
||||
@@ -827,6 +890,10 @@ std::optional<Geom_Curve::ResD2> GeomAdaptor_Curve::EvalD2(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_BSplineCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD2(U);
|
||||
}
|
||||
int aStart = 0, aFinish = 0;
|
||||
auto& aBSplData = std::get<BSplineData>(myCurveData);
|
||||
if (IsBoundary(U, aStart, aFinish))
|
||||
@@ -843,6 +910,10 @@ std::optional<Geom_Curve::ResD2> GeomAdaptor_Curve::EvalD2(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD2(U);
|
||||
}
|
||||
const auto& anOffsetData = std::get<OffsetData>(myCurveData);
|
||||
if (!Geom_OffsetCurveUtils::EvaluateD2(U,
|
||||
anOffsetData.BasisAdaptor.get(),
|
||||
@@ -921,6 +992,10 @@ std::optional<Geom_Curve::ResD3> GeomAdaptor_Curve::EvalD3(double U) const
|
||||
return aResult;
|
||||
|
||||
case GeomAbs_BezierCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD3(U);
|
||||
}
|
||||
auto& aCache = std::get<BezierData>(myCurveData).Cache;
|
||||
if (aCache.IsNull())
|
||||
RebuildCache(U);
|
||||
@@ -929,6 +1004,10 @@ std::optional<Geom_Curve::ResD3> GeomAdaptor_Curve::EvalD3(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_BSplineCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD3(U);
|
||||
}
|
||||
int aStart = 0, aFinish = 0;
|
||||
auto& aBSplData = std::get<BSplineData>(myCurveData);
|
||||
if (IsBoundary(U, aStart, aFinish))
|
||||
@@ -946,6 +1025,10 @@ std::optional<Geom_Curve::ResD3> GeomAdaptor_Curve::EvalD3(double U) const
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalD3(U);
|
||||
}
|
||||
const auto& anOffsetData = std::get<OffsetData>(myCurveData);
|
||||
if (!Geom_OffsetCurveUtils::EvaluateD3(U,
|
||||
anOffsetData.BasisAdaptor.get(),
|
||||
@@ -1001,6 +1084,10 @@ std::optional<gp_Vec> GeomAdaptor_Curve::EvalDN(double U, int N) const
|
||||
return myCurve->EvalDN(U, N);
|
||||
|
||||
case GeomAbs_BSplineCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalDN(U, N);
|
||||
}
|
||||
int aStart = 0, aFinish = 0;
|
||||
if (IsBoundary(U, aStart, aFinish))
|
||||
{
|
||||
@@ -1011,6 +1098,10 @@ std::optional<gp_Vec> GeomAdaptor_Curve::EvalDN(double U, int N) const
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetCurve: {
|
||||
if (hasEvalRep(myCurveData))
|
||||
{
|
||||
return myCurve->EvalDN(U, N);
|
||||
}
|
||||
const auto& anOffsetData = std::get<OffsetData>(myCurveData);
|
||||
gp_Vec aDN;
|
||||
if (!Geom_OffsetCurveUtils::EvaluateDN(U,
|
||||
|
||||
@@ -34,6 +34,12 @@
|
||||
#include <variant>
|
||||
|
||||
class Geom_BSplineCurve;
|
||||
class Geom_BezierCurve;
|
||||
|
||||
namespace Geom_EvalRepCurveDesc
|
||||
{
|
||||
class Base;
|
||||
}
|
||||
|
||||
//! This class provides an interface between the services provided by any
|
||||
//! curve from the package Geom and those required of the curve by algorithms which use it.
|
||||
@@ -49,22 +55,26 @@ public:
|
||||
//! Internal structure for offset curve evaluation data.
|
||||
struct OffsetData
|
||||
{
|
||||
occ::handle<GeomAdaptor_Curve> BasisAdaptor; //!< Adaptor for basis curve
|
||||
double Offset = 0.0; //!< Offset distance
|
||||
gp_Dir Direction; //!< Offset direction
|
||||
occ::handle<GeomAdaptor_Curve> BasisAdaptor; //!< Adaptor for basis curve
|
||||
double Offset = 0.0; //!< Offset distance
|
||||
gp_Dir Direction; //!< Offset direction
|
||||
occ::handle<Geom_EvalRepCurveDesc::Base> EvalRep; //!< Eval representation descriptor
|
||||
};
|
||||
|
||||
//! Internal structure for Bezier curve cache data.
|
||||
struct BezierData
|
||||
{
|
||||
mutable occ::handle<BSplCLib_Cache> Cache; //!< Cached data for evaluation
|
||||
occ::handle<Geom_BezierCurve> Curve; //!< Bezier curve to prevent downcasts
|
||||
mutable occ::handle<BSplCLib_Cache> Cache; //!< Cached data for evaluation
|
||||
occ::handle<Geom_EvalRepCurveDesc::Base> EvalRep; //!< Eval representation descriptor
|
||||
};
|
||||
|
||||
//! Internal structure for BSpline curve cache data.
|
||||
struct BSplineData
|
||||
{
|
||||
occ::handle<Geom_BSplineCurve> Curve; //!< BSpline curve to prevent downcasts
|
||||
mutable occ::handle<BSplCLib_Cache> Cache; //!< Cached data for evaluation
|
||||
occ::handle<Geom_BSplineCurve> Curve; //!< BSpline curve to prevent downcasts
|
||||
mutable occ::handle<BSplCLib_Cache> Cache; //!< Cached data for evaluation
|
||||
occ::handle<Geom_EvalRepCurveDesc::Base> EvalRep; //!< Eval representation descriptor
|
||||
};
|
||||
|
||||
//! Variant type for curve-specific evaluation data.
|
||||
|
||||
@@ -75,6 +75,35 @@ IMPLEMENT_STANDARD_RTTIEXT(GeomAdaptor_Surface, Adaptor3d_Surface)
|
||||
|
||||
namespace
|
||||
{
|
||||
bool hasEvalRep(const GeomAdaptor_Surface::SurfaceDataVariant& theData)
|
||||
{
|
||||
if (const GeomAdaptor_Surface::BezierData* aBezierData =
|
||||
std::get_if<GeomAdaptor_Surface::BezierData>(&theData))
|
||||
{
|
||||
return !aBezierData->EvalRep.IsNull();
|
||||
}
|
||||
if (const GeomAdaptor_Surface::BSplineData* aBSplineData =
|
||||
std::get_if<GeomAdaptor_Surface::BSplineData>(&theData))
|
||||
{
|
||||
return !aBSplineData->EvalRep.IsNull();
|
||||
}
|
||||
if (const GeomAdaptor_Surface::ExtrusionData* anExtrusionData =
|
||||
std::get_if<GeomAdaptor_Surface::ExtrusionData>(&theData))
|
||||
{
|
||||
return !anExtrusionData->EvalRep.IsNull();
|
||||
}
|
||||
if (const GeomAdaptor_Surface::RevolutionData* aRevolutionData =
|
||||
std::get_if<GeomAdaptor_Surface::RevolutionData>(&theData))
|
||||
{
|
||||
return !aRevolutionData->EvalRep.IsNull();
|
||||
}
|
||||
if (const GeomAdaptor_Surface::OffsetData* anOffsetData =
|
||||
std::get_if<GeomAdaptor_Surface::OffsetData>(&theData))
|
||||
{
|
||||
return !anOffsetData->EvalRep.IsNull();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
@@ -320,6 +349,7 @@ occ::handle<Adaptor3d_Surface> GeomAdaptor_Surface::ShallowCopy() const
|
||||
GeomAdaptor_Surface::ExtrusionData aNewData;
|
||||
aNewData.BasisCurve = anExtrusionData->BasisCurve->ShallowCopy();
|
||||
aNewData.Direction = anExtrusionData->Direction;
|
||||
aNewData.EvalRep = anExtrusionData->EvalRep;
|
||||
aCopy->mySurfaceData = aNewData;
|
||||
}
|
||||
else if (auto* aRevolutionData = std::get_if<GeomAdaptor_Surface::RevolutionData>(&mySurfaceData))
|
||||
@@ -327,6 +357,7 @@ occ::handle<Adaptor3d_Surface> GeomAdaptor_Surface::ShallowCopy() const
|
||||
GeomAdaptor_Surface::RevolutionData aNewData;
|
||||
aNewData.BasisCurve = aRevolutionData->BasisCurve->ShallowCopy();
|
||||
aNewData.Axis = aRevolutionData->Axis;
|
||||
aNewData.EvalRep = aRevolutionData->EvalRep;
|
||||
aCopy->mySurfaceData = aNewData;
|
||||
}
|
||||
else if (auto* anOffsetData = std::get_if<GeomAdaptor_Surface::OffsetData>(&mySurfaceData))
|
||||
@@ -341,15 +372,24 @@ occ::handle<Adaptor3d_Surface> GeomAdaptor_Surface::ShallowCopy() const
|
||||
}
|
||||
aNewData.OffsetSurface = anOffsetData->OffsetSurface; // Shared handle to original surface
|
||||
aNewData.Offset = anOffsetData->Offset;
|
||||
aNewData.EvalRep = anOffsetData->EvalRep;
|
||||
aCopy->mySurfaceData = std::move(aNewData);
|
||||
}
|
||||
else if (auto* aBSplineData = std::get_if<GeomAdaptor_Surface::BSplineData>(&mySurfaceData))
|
||||
{
|
||||
GeomAdaptor_Surface::BSplineData aNewData;
|
||||
aNewData.Surface = aBSplineData->Surface;
|
||||
aNewData.EvalRep = aBSplineData->EvalRep;
|
||||
// Cache is not copied - will be rebuilt on demand
|
||||
aCopy->mySurfaceData = aNewData;
|
||||
}
|
||||
else if (auto* aBezierData = std::get_if<GeomAdaptor_Surface::BezierData>(&mySurfaceData))
|
||||
{
|
||||
GeomAdaptor_Surface::BezierData aNewData;
|
||||
aNewData.Surface = aBezierData->Surface;
|
||||
aNewData.EvalRep = aBezierData->EvalRep;
|
||||
aCopy->mySurfaceData = aNewData;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Elementary surface types (gp_Pln, gp_Cylinder, etc.) are value types - direct copy
|
||||
@@ -424,6 +464,7 @@ void GeomAdaptor_Surface::load(const occ::handle<Geom_Surface>& S,
|
||||
GeomAdaptor_Surface::RevolutionData aRevData;
|
||||
aRevData.BasisCurve = new GeomAdaptor_Curve(aRevSurf->BasisCurve());
|
||||
aRevData.Axis = aRevSurf->Axis();
|
||||
aRevData.EvalRep = aRevSurf->EvalRepresentation();
|
||||
mySurfaceData = aRevData;
|
||||
}
|
||||
else if (TheType == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))
|
||||
@@ -435,18 +476,23 @@ void GeomAdaptor_Surface::load(const occ::handle<Geom_Surface>& S,
|
||||
GeomAdaptor_Surface::ExtrusionData anExtData;
|
||||
anExtData.BasisCurve = new GeomAdaptor_Curve(anExtSurf->BasisCurve());
|
||||
anExtData.Direction = anExtSurf->Direction().XYZ();
|
||||
anExtData.EvalRep = anExtSurf->EvalRepresentation();
|
||||
mySurfaceData = anExtData;
|
||||
}
|
||||
else if (TheType == STANDARD_TYPE(Geom_BezierSurface))
|
||||
{
|
||||
mySurfaceType = GeomAbs_BezierSurface;
|
||||
mySurfaceData = GeomAdaptor_Surface::BezierData{};
|
||||
GeomAdaptor_Surface::BezierData aBezierData;
|
||||
aBezierData.Surface = occ::down_cast<Geom_BezierSurface>(mySurface);
|
||||
aBezierData.EvalRep = aBezierData.Surface->EvalRepresentation();
|
||||
mySurfaceData = std::move(aBezierData);
|
||||
}
|
||||
else if (TheType == STANDARD_TYPE(Geom_BSplineSurface))
|
||||
{
|
||||
mySurfaceType = GeomAbs_BSplineSurface;
|
||||
GeomAdaptor_Surface::BSplineData aBSplineData;
|
||||
aBSplineData.Surface = occ::down_cast<Geom_BSplineSurface>(mySurface);
|
||||
aBSplineData.EvalRep = aBSplineData.Surface->EvalRepresentation();
|
||||
mySurfaceData = aBSplineData;
|
||||
}
|
||||
else if (TheType == STANDARD_TYPE(Geom_OffsetSurface))
|
||||
@@ -464,6 +510,7 @@ void GeomAdaptor_Surface::load(const occ::handle<Geom_Surface>& S,
|
||||
myTolV);
|
||||
anOffsetData.OffsetSurface = anOffSurf;
|
||||
anOffsetData.Offset = anOffSurf->Offset();
|
||||
anOffsetData.EvalRep = anOffSurf->EvalRepresentation();
|
||||
// Check if equivalent canonical surface exists for faster evaluation
|
||||
occ::handle<Geom_Surface> anEquivSurf = anOffSurf->Surface();
|
||||
if (!anEquivSurf.IsNull())
|
||||
@@ -1015,6 +1062,10 @@ std::optional<gp_Pnt> GeomAdaptor_Surface::EvalD0(double U, double V) const
|
||||
return P;
|
||||
|
||||
case GeomAbs_BezierSurface: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD0(U, V);
|
||||
}
|
||||
auto& aCache = std::get<BezierData>(mySurfaceData).Cache;
|
||||
if (aCache.IsNull())
|
||||
RebuildCache(U, V);
|
||||
@@ -1022,6 +1073,10 @@ std::optional<gp_Pnt> GeomAdaptor_Surface::EvalD0(double U, double V) const
|
||||
return P;
|
||||
}
|
||||
case GeomAbs_BSplineSurface: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD0(U, V);
|
||||
}
|
||||
auto& aCache = std::get<BSplineData>(mySurfaceData).Cache;
|
||||
if (aCache.IsNull() || !aCache->IsCacheValid(U, V))
|
||||
RebuildCache(U, V);
|
||||
@@ -1030,6 +1085,10 @@ std::optional<gp_Pnt> GeomAdaptor_Surface::EvalD0(double U, double V) const
|
||||
}
|
||||
|
||||
case GeomAbs_SurfaceOfExtrusion: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD0(U, V);
|
||||
}
|
||||
const auto& anExtData = std::get<GeomAdaptor_Surface::ExtrusionData>(mySurfaceData);
|
||||
if (!Geom_ExtrusionUtils::D0(U, V, *anExtData.BasisCurve, anExtData.Direction, P))
|
||||
return std::nullopt;
|
||||
@@ -1037,6 +1096,10 @@ std::optional<gp_Pnt> GeomAdaptor_Surface::EvalD0(double U, double V) const
|
||||
}
|
||||
|
||||
case GeomAbs_SurfaceOfRevolution: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD0(U, V);
|
||||
}
|
||||
const auto& aRevData = std::get<GeomAdaptor_Surface::RevolutionData>(mySurfaceData);
|
||||
if (!Geom_RevolutionUtils::D0(U, V, *aRevData.BasisCurve, aRevData.Axis, P))
|
||||
return std::nullopt;
|
||||
@@ -1044,6 +1107,10 @@ std::optional<gp_Pnt> GeomAdaptor_Surface::EvalD0(double U, double V) const
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetSurface: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD0(U, V);
|
||||
}
|
||||
const auto& anOffData = std::get<GeomAdaptor_Surface::OffsetData>(mySurfaceData);
|
||||
if (!offsetD0(U, V, anOffData, P))
|
||||
return std::nullopt;
|
||||
@@ -1123,6 +1190,10 @@ std::optional<Geom_Surface::ResD1> GeomAdaptor_Surface::EvalD1(double U, double
|
||||
return aResult;
|
||||
|
||||
case GeomAbs_BezierSurface: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD1(U, V);
|
||||
}
|
||||
auto& aCache = std::get<BezierData>(mySurfaceData).Cache;
|
||||
if (aCache.IsNull())
|
||||
RebuildCache(U, V);
|
||||
@@ -1130,6 +1201,10 @@ std::optional<Geom_Surface::ResD1> GeomAdaptor_Surface::EvalD1(double U, double
|
||||
return aResult;
|
||||
}
|
||||
case GeomAbs_BSplineSurface: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD1(U, V);
|
||||
}
|
||||
auto& aBSplData = std::get<BSplineData>(mySurfaceData);
|
||||
const auto& aBSpl = aBSplData.Surface;
|
||||
if ((USide != 0 || VSide != 0) && IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide))
|
||||
@@ -1144,6 +1219,10 @@ std::optional<Geom_Surface::ResD1> GeomAdaptor_Surface::EvalD1(double U, double
|
||||
}
|
||||
|
||||
case GeomAbs_SurfaceOfExtrusion: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD1(U, V);
|
||||
}
|
||||
const auto& anExtData = std::get<GeomAdaptor_Surface::ExtrusionData>(mySurfaceData);
|
||||
if (!Geom_ExtrusionUtils::D1(u,
|
||||
v,
|
||||
@@ -1157,6 +1236,10 @@ std::optional<Geom_Surface::ResD1> GeomAdaptor_Surface::EvalD1(double U, double
|
||||
}
|
||||
|
||||
case GeomAbs_SurfaceOfRevolution: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD1(U, V);
|
||||
}
|
||||
const auto& aRevData = std::get<GeomAdaptor_Surface::RevolutionData>(mySurfaceData);
|
||||
if (!Geom_RevolutionUtils::D1(u,
|
||||
v,
|
||||
@@ -1170,6 +1253,10 @@ std::optional<Geom_Surface::ResD1> GeomAdaptor_Surface::EvalD1(double U, double
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetSurface: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD1(U, V);
|
||||
}
|
||||
const auto& anOffData = std::get<GeomAdaptor_Surface::OffsetData>(mySurfaceData);
|
||||
if (!offsetD1(u, v, anOffData, aResult.Point, aResult.D1U, aResult.D1V))
|
||||
return std::nullopt;
|
||||
@@ -1285,6 +1372,10 @@ std::optional<Geom_Surface::ResD2> GeomAdaptor_Surface::EvalD2(double U, double
|
||||
return aResult;
|
||||
|
||||
case GeomAbs_BezierSurface: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD2(U, V);
|
||||
}
|
||||
auto& aCache = std::get<BezierData>(mySurfaceData).Cache;
|
||||
if (aCache.IsNull())
|
||||
RebuildCache(U, V);
|
||||
@@ -1293,6 +1384,10 @@ std::optional<Geom_Surface::ResD2> GeomAdaptor_Surface::EvalD2(double U, double
|
||||
return aResult;
|
||||
}
|
||||
case GeomAbs_BSplineSurface: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD2(U, V);
|
||||
}
|
||||
auto& aBSplData = std::get<BSplineData>(mySurfaceData);
|
||||
const auto& aBSpl = aBSplData.Surface;
|
||||
if ((USide != 0 || VSide != 0) && IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide))
|
||||
@@ -1325,6 +1420,10 @@ std::optional<Geom_Surface::ResD2> GeomAdaptor_Surface::EvalD2(double U, double
|
||||
}
|
||||
|
||||
case GeomAbs_SurfaceOfExtrusion: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD2(U, V);
|
||||
}
|
||||
const auto& anExtData = std::get<GeomAdaptor_Surface::ExtrusionData>(mySurfaceData);
|
||||
if (!Geom_ExtrusionUtils::D2(u,
|
||||
v,
|
||||
@@ -1341,6 +1440,10 @@ std::optional<Geom_Surface::ResD2> GeomAdaptor_Surface::EvalD2(double U, double
|
||||
}
|
||||
|
||||
case GeomAbs_SurfaceOfRevolution: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD2(U, V);
|
||||
}
|
||||
const auto& aRevData = std::get<GeomAdaptor_Surface::RevolutionData>(mySurfaceData);
|
||||
if (!Geom_RevolutionUtils::D2(u,
|
||||
v,
|
||||
@@ -1357,6 +1460,10 @@ std::optional<Geom_Surface::ResD2> GeomAdaptor_Surface::EvalD2(double U, double
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetSurface: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD2(U, V);
|
||||
}
|
||||
const auto& anOffData = std::get<GeomAdaptor_Surface::OffsetData>(mySurfaceData);
|
||||
if (!offsetD2(u,
|
||||
v,
|
||||
@@ -1508,6 +1615,10 @@ std::optional<Geom_Surface::ResD3> GeomAdaptor_Surface::EvalD3(double U, double
|
||||
return aResult;
|
||||
|
||||
case GeomAbs_BSplineSurface: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD3(U, V);
|
||||
}
|
||||
const auto& aBSpl = std::get<BSplineData>(mySurfaceData).Surface;
|
||||
if ((USide == 0) && (VSide == 0))
|
||||
{
|
||||
@@ -1547,6 +1658,10 @@ std::optional<Geom_Surface::ResD3> GeomAdaptor_Surface::EvalD3(double U, double
|
||||
}
|
||||
|
||||
case GeomAbs_SurfaceOfExtrusion: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD3(U, V);
|
||||
}
|
||||
const auto& anExtData = std::get<GeomAdaptor_Surface::ExtrusionData>(mySurfaceData);
|
||||
if (!Geom_ExtrusionUtils::D3(u,
|
||||
v,
|
||||
@@ -1567,6 +1682,10 @@ std::optional<Geom_Surface::ResD3> GeomAdaptor_Surface::EvalD3(double U, double
|
||||
}
|
||||
|
||||
case GeomAbs_SurfaceOfRevolution: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD3(U, V);
|
||||
}
|
||||
const auto& aRevData = std::get<GeomAdaptor_Surface::RevolutionData>(mySurfaceData);
|
||||
if (!Geom_RevolutionUtils::D3(u,
|
||||
v,
|
||||
@@ -1587,6 +1706,10 @@ std::optional<Geom_Surface::ResD3> GeomAdaptor_Surface::EvalD3(double U, double
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetSurface: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalD3(U, V);
|
||||
}
|
||||
const auto& anOffData = std::get<GeomAdaptor_Surface::OffsetData>(mySurfaceData);
|
||||
if (!offsetD3(u,
|
||||
v,
|
||||
@@ -1650,6 +1773,10 @@ std::optional<gp_Vec> GeomAdaptor_Surface::EvalDN(double U, double V, int Nu, in
|
||||
switch (mySurfaceType)
|
||||
{
|
||||
case GeomAbs_BSplineSurface: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalDN(U, V, Nu, Nv);
|
||||
}
|
||||
const auto& aBSpl = std::get<BSplineData>(mySurfaceData).Surface;
|
||||
if ((USide == 0) && (VSide == 0))
|
||||
return aBSpl->EvalDN(u, v, Nu, Nv);
|
||||
@@ -1663,6 +1790,10 @@ std::optional<gp_Vec> GeomAdaptor_Surface::EvalDN(double U, double V, int Nu, in
|
||||
}
|
||||
|
||||
case GeomAbs_SurfaceOfExtrusion: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalDN(U, V, Nu, Nv);
|
||||
}
|
||||
const auto& anExtData = std::get<GeomAdaptor_Surface::ExtrusionData>(mySurfaceData);
|
||||
gp_Vec aDN;
|
||||
if (!Geom_ExtrusionUtils::DN(u, *anExtData.BasisCurve, anExtData.Direction, Nu, Nv, aDN))
|
||||
@@ -1671,6 +1802,10 @@ std::optional<gp_Vec> GeomAdaptor_Surface::EvalDN(double U, double V, int Nu, in
|
||||
}
|
||||
|
||||
case GeomAbs_SurfaceOfRevolution: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalDN(U, V, Nu, Nv);
|
||||
}
|
||||
const auto& aRevData = std::get<GeomAdaptor_Surface::RevolutionData>(mySurfaceData);
|
||||
gp_Vec aDN;
|
||||
if (!Geom_RevolutionUtils::DN(u, v, *aRevData.BasisCurve, aRevData.Axis, Nu, Nv, aDN))
|
||||
@@ -1679,6 +1814,10 @@ std::optional<gp_Vec> GeomAdaptor_Surface::EvalDN(double U, double V, int Nu, in
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetSurface: {
|
||||
if (hasEvalRep(mySurfaceData))
|
||||
{
|
||||
return mySurface->EvalDN(U, V, Nu, Nv);
|
||||
}
|
||||
const auto& anOffData = std::get<GeomAdaptor_Surface::OffsetData>(mySurfaceData);
|
||||
gp_Vec aDN;
|
||||
if (!offsetDN(u, v, anOffData, Nu, Nv, aDN))
|
||||
|
||||
@@ -37,6 +37,12 @@
|
||||
|
||||
class GeomAdaptor_Curve;
|
||||
class Geom_OffsetSurface;
|
||||
class Geom_BezierSurface;
|
||||
|
||||
namespace Geom_EvalRepSurfaceDesc
|
||||
{
|
||||
class Base;
|
||||
}
|
||||
|
||||
//! An interface between the services provided by any
|
||||
//! surface from the package Geom and those required
|
||||
@@ -53,15 +59,17 @@ public:
|
||||
//! Internal structure for extrusion surface evaluation data.
|
||||
struct ExtrusionData
|
||||
{
|
||||
occ::handle<Adaptor3d_Curve> BasisCurve; //!< Adaptor for basis curve
|
||||
gp_XYZ Direction; //!< Extrusion direction XYZ (normalized)
|
||||
occ::handle<Adaptor3d_Curve> BasisCurve; //!< Adaptor for basis curve
|
||||
gp_XYZ Direction; //!< Extrusion direction XYZ (normalized)
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::Base> EvalRep; //!< Eval representation descriptor
|
||||
};
|
||||
|
||||
//! Internal structure for revolution surface evaluation data.
|
||||
struct RevolutionData
|
||||
{
|
||||
occ::handle<Adaptor3d_Curve> BasisCurve; //!< Adaptor for basis curve
|
||||
gp_Ax1 Axis; //!< Revolution axis
|
||||
occ::handle<Adaptor3d_Curve> BasisCurve; //!< Adaptor for basis curve
|
||||
gp_Ax1 Axis; //!< Revolution axis
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::Base> EvalRep; //!< Eval representation descriptor
|
||||
};
|
||||
|
||||
//! Internal structure for offset surface evaluation data.
|
||||
@@ -73,19 +81,23 @@ public:
|
||||
occ::handle<Geom_OffsetSurface>
|
||||
OffsetSurface; //!< Original offset surface for osculating queries
|
||||
double Offset = 0.0; //!< Offset distance
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::Base> EvalRep; //!< Eval representation descriptor
|
||||
};
|
||||
|
||||
//! Internal structure for Bezier surface cache data.
|
||||
struct BezierData
|
||||
{
|
||||
mutable occ::handle<BSplSLib_Cache> Cache; //!< Cached data for evaluation
|
||||
occ::handle<Geom_BezierSurface> Surface; //!< Bezier surface to prevent downcasts
|
||||
mutable occ::handle<BSplSLib_Cache> Cache; //!< Cached data for evaluation
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::Base> EvalRep; //!< Eval representation descriptor
|
||||
};
|
||||
|
||||
//! Internal structure for BSpline surface cache data.
|
||||
struct BSplineData
|
||||
{
|
||||
occ::handle<Geom_BSplineSurface> Surface; //!< BSpline surface to prevent downcasts
|
||||
mutable occ::handle<BSplSLib_Cache> Cache; //!< Cached data for evaluation
|
||||
occ::handle<Geom_BSplineSurface> Surface; //!< BSpline surface to prevent downcasts
|
||||
mutable occ::handle<BSplSLib_Cache> Cache; //!< Cached data for evaluation
|
||||
occ::handle<Geom_EvalRepSurfaceDesc::Base> EvalRep; //!< Eval representation descriptor
|
||||
};
|
||||
|
||||
//! Variant type for surface-specific evaluation data.
|
||||
|
||||
Reference in New Issue
Block a user