mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-02 12:37:02 +08:00
465 lines
17 KiB
C++
465 lines
17 KiB
C++
//
|
|
// Copyright (c) 1993-2022 Robert McNeel & Associates. All rights reserved.
|
|
// OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
|
|
// McNeel & Associates.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
|
|
// ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
|
|
// MERCHANTABILITY ARE HEREBY DISCLAIMED.
|
|
//
|
|
// For complete openNURBS copyright information see <http://www.opennurbs.org>.
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// Definition of curve proxy object
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
#if !defined(OPENNURBS_CURVEPROXY_INC_)
|
|
#define OPENNURBS_CURVEPROXY_INC_
|
|
|
|
/*
|
|
Description:
|
|
An ON_CurveProxy is a reference to an ON_Curve.
|
|
One may specify a subdomain of the referenced curve
|
|
and apply a affine reparameterization, possibly reversing
|
|
the orientation. The underlying curve cannot be modified through
|
|
the curve proxy.
|
|
Details:
|
|
The reference to the "real_curve" is const, so most functions
|
|
which modify an ON_Curve will fail when passed an ON_CurveProxy.
|
|
*/
|
|
class ON_CurveProxy;
|
|
class ON_CLASS ON_CurveProxy : public ON_Curve
|
|
{
|
|
ON_OBJECT_DECLARE(ON_CurveProxy);
|
|
|
|
public:
|
|
ON_CurveProxy() ON_NOEXCEPT;
|
|
virtual ~ON_CurveProxy();
|
|
ON_CurveProxy( const ON_CurveProxy& );
|
|
ON_CurveProxy& operator=(const ON_CurveProxy&);
|
|
|
|
#if defined(ON_HAS_RVALUEREF)
|
|
// rvalue copy constructor
|
|
ON_CurveProxy( ON_CurveProxy&& ) ON_NOEXCEPT;
|
|
|
|
// The rvalue assignment operator calls ON_Object::operator=(ON_Object&&)
|
|
// which could throw exceptions. See the implementation of
|
|
// ON_Object::operator=(ON_Object&&) for details.
|
|
ON_CurveProxy& operator=( ON_CurveProxy&& );
|
|
#endif
|
|
|
|
public:
|
|
// virtual ON_Object::DestroyRuntimeCache override
|
|
void DestroyRuntimeCache( bool bDelete = true ) override;
|
|
|
|
|
|
|
|
ON_CurveProxy( const ON_Curve* );
|
|
ON_CurveProxy( const ON_Curve*, ON_Interval );
|
|
|
|
// virtual ON_Object::SizeOf override
|
|
unsigned int SizeOf() const override;
|
|
|
|
// virtual ON_Object::DataCRC override
|
|
ON__UINT32 DataCRC(ON__UINT32 current_remainder) const override;
|
|
|
|
/*
|
|
Description:
|
|
Sets the curve geometry that "this" is a proxy for.
|
|
Sets proxy domain to proxy_curve->Domain().
|
|
Parameters:
|
|
real_curve - [in]
|
|
*/
|
|
void SetProxyCurve( const ON_Curve* real_curve );
|
|
|
|
/*
|
|
Description:
|
|
Sets the curve geometry that "this" is a proxy for.
|
|
Sets proxy domain to proxy_curve->Domain().
|
|
Parameters:
|
|
real_curve - [in]
|
|
real_curve_subdomain - [in] increasing sub interval of
|
|
real_curve->Domain(). This interval defines the
|
|
portion the "real" curve geometry that "this" proxy
|
|
uses.
|
|
bReversed - [in] true if the parameterization of "this" proxy
|
|
as a curve is reversed from the underlying "real" curve
|
|
geometry.
|
|
*/
|
|
void SetProxyCurve( const ON_Curve* real_curve,
|
|
ON_Interval real_curve_subdomain
|
|
);
|
|
|
|
/*
|
|
Returns:
|
|
"Real" curve geometry that "this" is a proxy for.
|
|
*/
|
|
const ON_Curve* ProxyCurve() const;
|
|
|
|
/*
|
|
Description:
|
|
Sets portion of the "real" curve that this proxy represents.
|
|
Does NOT change the domain of "this" curve.
|
|
Parameters:
|
|
proxy_curve_subdomain - [in] increasing sub interval of
|
|
ProxyCurve()->Domain(). This interval defines the
|
|
portion the curve geometry that "this" proxy uses.
|
|
Remarks:
|
|
This function is poorly named. It does NOT set the proxy
|
|
curve's domain. It does set the interval of the "real"
|
|
curve for which "this" is a proxy.
|
|
*/
|
|
bool SetProxyCurveDomain( ON_Interval proxy_curve_subdomain );
|
|
|
|
|
|
/*
|
|
Returns:
|
|
Sub interval of the "real" curve's domain that "this" uses.
|
|
This interval is not necessarily the same as "this" curve's
|
|
domain.
|
|
Remarks:
|
|
This function is poorly named. It does NOT get the proxy
|
|
curve's domain. It does get the evaluation interval
|
|
of the "real" curve for which "this" is a proxy.
|
|
*/
|
|
ON_Interval ProxyCurveDomain() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if "this" as a curve is reversed from the "real" curve
|
|
geometry.
|
|
*/
|
|
bool ProxyCurveIsReversed() const;
|
|
|
|
protected:
|
|
// Used by CRhinoPolyEdgeSegment::Create() to restore the
|
|
// value of ON_CurveProxy::m_bReversed.
|
|
void SetProxyCurveIsReversed(bool bReversed);
|
|
|
|
public:
|
|
/*
|
|
Parameters:
|
|
t - [in] parameter for "this" curve
|
|
Returns:
|
|
Corresponding parameter in m_real_curve's domain.
|
|
*/
|
|
double RealCurveParameter( double t ) const;
|
|
|
|
/*
|
|
Parameters:
|
|
real_curve_parameter - [in] m_real_curve parameter
|
|
Returns:
|
|
Corresponding parameter for "this" curve
|
|
*/
|
|
double ThisCurveParameter( double real_curve_parameter ) const;
|
|
|
|
private:
|
|
// "real" curve geometry that "this" is a proxy for.
|
|
const ON_Curve* m_real_curve;
|
|
// If true, the parameterization of "this" proxy is
|
|
// the reverse of the m_curve parameterization.
|
|
bool m_bReversed;
|
|
|
|
// The m_real_curve_domain interval is always increasing and included in
|
|
// m_real_curve->Domain(). The m_real_curve_domain interval defines the portion
|
|
// of m_real_curve that "this" proxy uses and it can be a proper
|
|
// sub-interval of m_real_curve->Domain().
|
|
ON_Interval m_real_curve_domain;
|
|
|
|
// The evaluation domain of this curve. If "t" is a parameter for
|
|
// "this" and "r" is a parameter for m_real_curve, then when m_bReversed==false
|
|
// we have
|
|
// t = m_this_domain.ParameterAt(m_real_curve_domain.NormalizedParameterAt(r))
|
|
// r = m_real_curve_domain.ParameterAt(m_this_domain.NormalizedParameterAt(t))
|
|
// and when m_bReversed==true we have
|
|
// t = m_this_domain.ParameterAt(1 - m_real_curve_domain.NormalizedParameterAt(r))
|
|
// r = m_real_curve_domain.ParameterAt(1 - m_this_domain.NormalizedParameterAt(t))
|
|
ON_Interval m_this_domain;
|
|
|
|
ON_Interval RealCurveInterval( const ON_Interval* sub_domain ) const;
|
|
|
|
|
|
public:
|
|
/*
|
|
Description:
|
|
Get a duplicate of the curve.
|
|
Returns:
|
|
A duplicate of the curve.
|
|
Remarks:
|
|
The caller must delete the returned curve.
|
|
For non-ON_CurveProxy objects, this simply duplicates the curve using
|
|
ON_Object::Duplicate.
|
|
For ON_CurveProxy objects, this duplicates the actual proxy curve
|
|
geometry and, if necessary, trims and reverse the result to that
|
|
the returned curve's parameterization and locus match the proxy curve's.
|
|
*/
|
|
ON_Curve* DuplicateCurve() const override;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// ON_Object overrides
|
|
|
|
bool IsValid( class ON_TextLog* text_log = nullptr ) const override;
|
|
|
|
void Dump( ON_TextLog& ) const override; // for debugging
|
|
|
|
bool Write( // returns false - nothing serialized
|
|
ON_BinaryArchive& // open binary file
|
|
) const override;
|
|
|
|
bool Read( // returns false - nothing serialized
|
|
ON_BinaryArchive& // open binary file
|
|
) override;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// ON_Geometry overrides
|
|
|
|
int Dimension() const override;
|
|
|
|
// virtual ON_Geometry GetBBox override
|
|
bool GetBBox( double* boxmin, double* boxmax, bool bGrowBox = false ) const override;
|
|
|
|
bool Transform(
|
|
const ON_Xform&
|
|
) override;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// ON_Curve overrides
|
|
|
|
// Returns:
|
|
// domain of the curve.
|
|
// Remarks:
|
|
// If m_bReverse is true, this returns the reverse
|
|
// of m_domain.
|
|
ON_Interval Domain() const override;
|
|
|
|
/* virtual ON_Curve::SetDomain() override */
|
|
bool SetDomain(
|
|
double t0,
|
|
double t1
|
|
) override;
|
|
|
|
bool SetDomain( ON_Interval domain );
|
|
|
|
int SpanCount() const override; // number of smooth spans in curve
|
|
|
|
bool GetSpanVector(
|
|
double*
|
|
) const override;
|
|
|
|
int Degree( // returns maximum algebraic degree of any span
|
|
// ( or a good estimate if curve spans are not algebraic )
|
|
) const override;
|
|
|
|
// (optional - override if curve is piecewise smooth)
|
|
bool GetParameterTolerance( // returns tminus < tplus: parameters tminus <= s <= tplus
|
|
double, // t = parameter in domain
|
|
double*, // tminus
|
|
double* // tplus
|
|
) const override;
|
|
|
|
bool IsLinear( // true if curve locus is a line segment between
|
|
// between specified points
|
|
double = ON_ZERO_TOLERANCE // tolerance to use when checking linearity
|
|
) const override;
|
|
|
|
// virtual override of ON_Curve::IsPolyline
|
|
int IsPolyline(
|
|
ON_SimpleArray<ON_3dPoint>* pline_points = nullptr,
|
|
ON_SimpleArray<double>* pline_t = nullptr
|
|
) const override;
|
|
|
|
bool IsArc( // ON_Arc.m_angle > 0 if curve locus is an arc between
|
|
// specified points
|
|
const ON_Plane* = nullptr, // if not nullptr, test is performed in this plane
|
|
ON_Arc* = nullptr, // if not nullptr and true is returned, then arc parameters
|
|
// are filled in
|
|
double = ON_ZERO_TOLERANCE // tolerance to use when checking
|
|
) const override;
|
|
|
|
bool IsPlanar(
|
|
ON_Plane* = nullptr, // if not nullptr and true is returned, then plane parameters
|
|
// are filled in
|
|
double = ON_ZERO_TOLERANCE // tolerance to use when checking
|
|
) const override;
|
|
|
|
bool IsInPlane(
|
|
const ON_Plane&, // plane to test
|
|
double = ON_ZERO_TOLERANCE // tolerance to use when checking
|
|
) const override;
|
|
|
|
bool IsClosed( // true if curve is closed (either curve has
|
|
void // clamped end knots and euclidean location of start
|
|
) const override; // CV = euclidean location of end CV, or curve is
|
|
// periodic.)
|
|
|
|
bool IsPeriodic( // true if curve is a single periodic segment
|
|
void
|
|
) const override;
|
|
|
|
/*
|
|
Description:
|
|
Search for a derivatitive, tangent, or curvature discontinuity.
|
|
Parameters:
|
|
c - [in] type of continity to test for. If ON::continuity::C1_continuous
|
|
t0 - [in] search begins at t0
|
|
t1 - [in] (t0 < t1) search ends at t1
|
|
t - [out] if a discontinuity is found, the *t reports the
|
|
parameter at the discontinuity.
|
|
hint - [in/out] if GetNextDiscontinuity will be called repeatedly,
|
|
passing a "hint" with initial value *hint=0 will increase the speed
|
|
of the search.
|
|
dtype - [out] if not nullptr, *dtype reports the kind of discontinuity
|
|
found at *t. A value of 1 means the first derivative or unit tangent
|
|
was discontinuous. A value of 2 means the second derivative or
|
|
curvature was discontinuous.
|
|
cos_angle_tolerance - [in] default = cos(1 degree) Used only when
|
|
c is ON::continuity::G1_continuous or ON::continuity::G2_continuous. If the cosine
|
|
of the angle between two tangent vectors
|
|
is <= cos_angle_tolerance, then a G1 discontinuity is reported.
|
|
curvature_tolerance - [in] (default = ON_SQRT_EPSILON) Used only when
|
|
c is ON::continuity::G2_continuous or ON::continuity::Gsmooth_continuous.
|
|
ON::continuity::G2_continuous:
|
|
If K0 and K1 are curvatures evaluated
|
|
from above and below and |K0 - K1| > curvature_tolerance,
|
|
then a curvature discontinuity is reported.
|
|
ON::continuity::Gsmooth_continuous:
|
|
If K0 and K1 are curvatures evaluated from above and below
|
|
and the angle between K0 and K1 is at least twice angle tolerance
|
|
or ||K0| - |K1|| > (max(|K0|,|K1|) > curvature_tolerance,
|
|
then a curvature discontinuity is reported.
|
|
Returns:
|
|
true if a discontinuity was found on the interior of the interval (t0,t1).
|
|
Remarks:
|
|
Overrides ON_Curve::GetNextDiscontinuity.
|
|
*/
|
|
bool GetNextDiscontinuity(
|
|
ON::continuity c,
|
|
double t0,
|
|
double t1,
|
|
double* t,
|
|
int* hint=nullptr,
|
|
int* dtype=nullptr,
|
|
double cos_angle_tolerance=ON_DEFAULT_ANGLE_TOLERANCE_COSINE,
|
|
double curvature_tolerance=ON_SQRT_EPSILON
|
|
) const override;
|
|
|
|
/*
|
|
Description:
|
|
Test continuity at a curve parameter value.
|
|
Parameters:
|
|
c - [in] continuity to test for
|
|
t - [in] parameter to test
|
|
hint - [in] evaluation hint
|
|
point_tolerance - [in] if the distance between two points is
|
|
greater than point_tolerance, then the curve is not C0.
|
|
d1_tolerance - [in] if the difference between two first derivatives is
|
|
greater than d1_tolerance, then the curve is not C1.
|
|
d2_tolerance - [in] if the difference between two second derivatives is
|
|
greater than d2_tolerance, then the curve is not C2.
|
|
cos_angle_tolerance - [in] default = cos(1 degree) Used only when
|
|
c is ON::continuity::G1_continuous or ON::continuity::G2_continuous. If the cosine
|
|
of the angle between two tangent vectors
|
|
is <= cos_angle_tolerance, then a G1 discontinuity is reported.
|
|
curvature_tolerance - [in] (default = ON_SQRT_EPSILON) Used only when
|
|
c is ON::continuity::G2_continuous or ON::continuity::Gsmooth_continuous.
|
|
ON::continuity::G2_continuous:
|
|
If K0 and K1 are curvatures evaluated
|
|
from above and below and |K0 - K1| > curvature_tolerance,
|
|
then a curvature discontinuity is reported.
|
|
ON::continuity::Gsmooth_continuous:
|
|
If K0 and K1 are curvatures evaluated from above and below
|
|
and the angle between K0 and K1 is at least twice angle tolerance
|
|
or ||K0| - |K1|| > (max(|K0|,|K1|) > curvature_tolerance,
|
|
then a curvature discontinuity is reported.
|
|
Returns:
|
|
true if the curve has at least the c type continuity at the parameter t.
|
|
Remarks:
|
|
Overrides ON_Curve::IsContinuous.
|
|
*/
|
|
bool IsContinuous(
|
|
ON::continuity c,
|
|
double t,
|
|
int* hint = nullptr,
|
|
double point_tolerance=ON_ZERO_TOLERANCE,
|
|
double d1_tolerance=ON_ZERO_TOLERANCE,
|
|
double d2_tolerance=ON_ZERO_TOLERANCE,
|
|
double cos_angle_tolerance=ON_DEFAULT_ANGLE_TOLERANCE_COSINE,
|
|
double curvature_tolerance=ON_SQRT_EPSILON
|
|
) const override;
|
|
|
|
bool Reverse() override; // reverse parameterizatrion
|
|
// Domain changes from [a,b] to [-b,-a]
|
|
|
|
bool Evaluate( // returns false if unable to evaluate
|
|
double, // evaluation parameter
|
|
int, // number of derivatives (>=0)
|
|
int, // array stride (>=Dimension())
|
|
double*, // array of length stride*(ndir+1)
|
|
int = 0, // optional - determines which side to evaluate from
|
|
// 0 = default
|
|
// < 0 to evaluate from below,
|
|
// > 0 to evaluate from above
|
|
int* = 0 // optional - evaluation hint (int) used to speed
|
|
// repeated evaluations
|
|
) const override;
|
|
|
|
|
|
// override of virtual ON_Curve::Trim
|
|
bool Trim(
|
|
const ON_Interval& domain
|
|
) override;
|
|
|
|
// override of virtual ON_Curve::Split
|
|
bool Split(
|
|
double t,
|
|
ON_Curve*& left_side,
|
|
ON_Curve*& right_side
|
|
) const override;
|
|
|
|
int GetNurbForm( // returns 0: unable to create NURBS representation
|
|
// with desired accuracy.
|
|
// 1: success - returned NURBS parameterization
|
|
// matches the curve's to wthe desired accuracy
|
|
// 2: success - returned NURBS point locus matches
|
|
// the curve's to the desired accuracy but, on
|
|
// the interior of the curve's domain, the
|
|
// curve's parameterization and the NURBS
|
|
// parameterization may not match to the
|
|
// desired accuracy.
|
|
ON_NurbsCurve&,
|
|
double = 0.0,
|
|
const ON_Interval* = nullptr // OPTIONAL subdomain of ON_CurveProxy::Domain()
|
|
) const override;
|
|
|
|
int HasNurbForm( // returns 0: unable to create NURBS representation
|
|
// with desired accuracy.
|
|
// 1: success - returned NURBS parameterization
|
|
// matches the curve's to wthe desired accuracy
|
|
// 2: success - returned NURBS point locus matches
|
|
// the curve's to the desired accuracy but, on
|
|
// the interior of the curve's domain, the
|
|
// curve's parameterization and the NURBS
|
|
// parameterization may not match to the
|
|
// desired accuracy.
|
|
) const override;
|
|
|
|
// virtual ON_Curve::GetCurveParameterFromNurbFormParameter override
|
|
bool GetCurveParameterFromNurbFormParameter(
|
|
double, // nurbs_t
|
|
double* // curve_t
|
|
) const override;
|
|
|
|
// virtual ON_Curve::GetNurbFormParameterFromCurveParameter override
|
|
bool GetNurbFormParameterFromCurveParameter(
|
|
double, // curve_t
|
|
double* // nurbs_t
|
|
) const override;
|
|
};
|
|
|
|
|
|
#endif
|