mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-05 14:39:41 +08:00
462 lines
14 KiB
C
462 lines
14 KiB
C
/* $NoKeywords: $ */
|
|
/*
|
|
//
|
|
// Copyright (c) 1993-2012 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>.
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
*/
|
|
|
|
#if !defined(ON_EVALUATE_NURBS_INC_)
|
|
#define ON_EVALUATE_NURBS_INC_
|
|
|
|
ON_DECL
|
|
bool ON_IncreaseBezierDegree(
|
|
int, // dimension
|
|
bool, // true if Bezier is rational
|
|
int, // order (>=2)
|
|
int, // cv_stride (>=dim+1)
|
|
double* // cv[(order+1)*cv_stride] array
|
|
);
|
|
|
|
ON_DECL
|
|
bool ON_RemoveBezierSingAt0( // input bezier is rational with 0/0 at start
|
|
int, // dimension
|
|
int, // order (>=2)
|
|
int, // cv_stride (>=dim+1)
|
|
double* // cv[order*cv_stride] array
|
|
);
|
|
|
|
ON_DECL
|
|
bool ON_RemoveBezierSingAt1( // input bezier is rational with 0/0 at end
|
|
int, // dimension
|
|
int, // order (>=2)
|
|
int, // cv_stride (>=dim+1)
|
|
double* // cv[order*cv_stride] array
|
|
);
|
|
|
|
ON_DECL
|
|
double ON_EvaluateBernsteinBasis( // returns (i choose d)*(1-t)^(d-i)*t^i
|
|
int, // degree,
|
|
int, // 0 <= i <= degree
|
|
double // t
|
|
);
|
|
|
|
ON_DECL
|
|
void ON_EvaluatedeCasteljau(
|
|
int, // dim
|
|
int, // order
|
|
int, // side <= 0 return left side of bezier in cv array
|
|
// > 0 return right side of bezier in cv array
|
|
int, // cv_stride
|
|
double*, // cv
|
|
double // t 0 <= t <= 1
|
|
);
|
|
|
|
ON_DECL
|
|
bool ON_EvaluateBezier(
|
|
int, // dimension
|
|
bool, // true if Bezier is rational
|
|
int, // order (>=2)
|
|
int, // cv_stride >= (is_rat)?dim+1:dim
|
|
const double*, // cv[order*cv_stride] array
|
|
double, double, // t0,t1 = domain of bezier
|
|
int, // number of derivatives to compute (>=0)
|
|
double, // evaluation parameter
|
|
int, // v_stride (>=dimension)
|
|
double* // v[(der_count+1)*v_stride] array
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Evaluate B-spline basis functions
|
|
|
|
Parameters:
|
|
order - [in]
|
|
order >= 1
|
|
d = degree = order - 1
|
|
knot - [in]
|
|
array of length 2*d.
|
|
Generally, knot[0] <= ... <= knot[d-1] < knot[d] <= ... <= knot[2*d-1].
|
|
These are the knots that are active for the span being evaluated.
|
|
t - [in]
|
|
Evaluation parameter.
|
|
Typically knot[d-1] <= t <= knot[d].
|
|
In general t may be outside the interval knot[d-1],knot[d]. This can happen
|
|
when some type of extrapolation is being used and is almost always a bad
|
|
idea in practical situations.
|
|
|
|
N - [out]
|
|
double array with capacity order*order.
|
|
The returned values are:
|
|
|
|
If "N" were declared as double N[order][order], then
|
|
|
|
k
|
|
N[d-k][i] = N (t) = value of i-th degree k basis function at t.
|
|
i
|
|
where 0 <= k <= d and k <= i <= d.
|
|
|
|
In particular, N[0], ..., N[d] - values of degree d basis functions.
|
|
The "lower left" triangle is not initialized.
|
|
|
|
Actually, the above is true when knot[d-1] <= t < knot[d]. Otherwise, the
|
|
value returned is the value of the polynomial that agrees with N_i^k on the
|
|
half open domain [ knot[d-1], knot[d] )
|
|
|
|
COMMENTS:
|
|
If a degree d NURBS has n control points, then the OpenNURBS knot vector
|
|
for the entire NURBS curve has length d+n-1. The knot[] paramter to this
|
|
function points to the 2*d knots active for the span being evaluated.
|
|
|
|
Most literature, including DeBoor and The NURBS Book,
|
|
duplicate the Opennurbs start and end knot values and have knot vectors
|
|
of length d+n+1. The extra two knot values are completely superfluous
|
|
when degree >= 1.
|
|
|
|
Assume C is a B-spline of degree d (order=d+1) with n control vertices
|
|
(n>=d+1) and knot[] is its knot vector. Then
|
|
|
|
C(t) = Sum( 0 <= i < n, N_{i}(t) * C_{i} )
|
|
|
|
where N_{i} are the degree d b-spline basis functions and C_{i} are the control
|
|
vertices. The knot[] array length d+n-1 and satisfies
|
|
|
|
knot[0] <= ... <= knot[d-1] < knot[d]
|
|
knot[n-2] < knot[n-1] <= ... <= knot[n+d-2]
|
|
knot[i] < knot[d+i] for 0 <= i < n-1
|
|
knot[i] <= knot[i+1] for 0 <= i < n+d-2
|
|
|
|
The domain of C is [ knot[d-1], knot[n-1] ].
|
|
|
|
The support of N_{i} is [ knot[i-1], knot[i+d] ).
|
|
|
|
If d-1 <= k < n-1 and knot[k] <= t < knot[k+1], then
|
|
N_{i}(t) = 0 if i <= k-d
|
|
= 0 if i >= k+2
|
|
= B[i-k+d-1] if k-d+1 <= i <= k+1, where B[] is computed by the call
|
|
ON_EvaluateNurbsBasis( d+1, knot+k-d+1, t, B );
|
|
|
|
If 0 <= j < n-d, 0 <= m <= d, knot[j+d-1] <= t < knot[j+d], and B[] is
|
|
computed by the call
|
|
ON_EvaluateNurbsBasis( d+1, knot+j, t, B ),
|
|
then
|
|
N_{j+m}(t) = B[m].
|
|
*/
|
|
ON_DECL
|
|
bool ON_EvaluateNurbsBasis(
|
|
int order,
|
|
const double* knot,
|
|
double t,
|
|
double* N
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Calculate derivatives of B-spline basis functions.
|
|
INPUT:
|
|
order - [in]
|
|
order >= 1
|
|
d = degree = order - 1
|
|
knot - [in]
|
|
array of length 2*d.
|
|
Generally, knot[0] <= ... <= knot[d-1] < knot[d] <= ... <= knot[2*d-1].
|
|
These are the knots that are active for the span being evaluated.
|
|
der_count - [in]
|
|
1 <= der_count < order
|
|
Number of derivatives.
|
|
Note all B-spline basis derivatives with der_coutn >= order are identically zero.
|
|
|
|
N - [in]
|
|
The input value of N[] should be the results of the call
|
|
ON_EvaluateNurbsBasis( order, knot, t, N );
|
|
|
|
N - [out]
|
|
If "N" were declared as double N[order][order], then
|
|
|
|
d
|
|
N[d-k][i] = k-th derivative of N (t)
|
|
i
|
|
|
|
where 0 <= k <= d and 0 <= i <= d.
|
|
|
|
In particular,
|
|
N[0], ..., N[d] - values of degree d basis functions.
|
|
N[order], ..., N[order_d] - values of first derivative.
|
|
*/
|
|
ON_DECL
|
|
bool ON_EvaluateNurbsBasisDerivatives(
|
|
int order,
|
|
const double* knot,
|
|
int der_count,
|
|
double* N
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Evaluate a NURBS curve span.
|
|
Parameters:
|
|
dim - [in]
|
|
dimension (> 0).
|
|
is_rat - [in]
|
|
true or false.
|
|
order - [in]
|
|
order=degree+1 (order>=2)
|
|
knot - [in] NURBS knot vector.
|
|
NURBS knot vector with 2*(order-1) knots, knot[order-2] != knot[order-1]
|
|
cv_stride - [in]
|
|
cv - [in]
|
|
For 0 <= i < order the i-th control vertex is
|
|
|
|
cv[n],...,cv[n+(is_rat?dim:dim+1)],
|
|
|
|
where n = i*cv_stride. If is_rat is true the cv is
|
|
in homogeneous form.
|
|
der_count - [in]
|
|
number of derivatives to evaluate (>=0)
|
|
t - [in]
|
|
evaluation parameter
|
|
v_stride - [in]
|
|
v - [out]
|
|
An array of length v_stride*(der_count+1). The evaluation
|
|
results are returned in this array.
|
|
|
|
P = v[0],...,v[m_dim-1]
|
|
Dt = v[v_stride],...
|
|
Dtt = v[2*v_stride],...
|
|
...
|
|
|
|
In general, Dt^i returned in v[n],...,v[n+m_dim-1], where
|
|
|
|
n = v_stride*i.
|
|
|
|
Returns:
|
|
True if successful.
|
|
See Also:
|
|
ON_NurbsCurve::Evaluate
|
|
ON_EvaluateNurbsSurfaceSpan
|
|
ON_EvaluateNurbsCageSpan
|
|
*/
|
|
ON_DECL
|
|
bool ON_EvaluateNurbsSpan(
|
|
int dim,
|
|
bool is_rat,
|
|
int order,
|
|
const double* knot,
|
|
int cv_stride,
|
|
const double* cv,
|
|
int der_count,
|
|
double t,
|
|
int v_stride,
|
|
double* v
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Evaluate a NURBS surface bispan.
|
|
Parameters:
|
|
dim - [in] >0
|
|
is_rat - [in] true of false
|
|
order0 - [in] >= 2
|
|
order1 - [in] >= 2
|
|
knot0 - [in]
|
|
NURBS knot vector with 2*(order0-1) knots, knot0[order0-2] != knot0[order0-1]
|
|
knot1 - [in]
|
|
NURBS knot vector with 2*(order1-1) knots, knot1[order1-2] != knot1[order1-1]
|
|
cv_stride0 - [in]
|
|
cv_stride1 - [in]
|
|
cv - [in]
|
|
For 0 <= i < order0 and 0 <= j < order1, the (i,j) control vertex is
|
|
|
|
cv[n],...,cv[n+(is_rat?dim:dim+1)],
|
|
|
|
where n = i*cv_stride0 + j*cv_stride1. If is_rat is true the cv is
|
|
in homogeneous form.
|
|
|
|
der_count - [in] (>=0)
|
|
s - [in]
|
|
t - [in] (s,t) is the evaluation parameter
|
|
v_stride - [in] (>=dim)
|
|
v - [out] An array of length v_stride*(der_count+1)*(der_count+2)/2.
|
|
The evaluation results are stored in this array.
|
|
|
|
P = v[0],...,v[m_dim-1]
|
|
Ds = v[v_stride],...
|
|
Dt = v[2*v_stride],...
|
|
Dss = v[3*v_stride],...
|
|
Dst = v[4*v_stride],...
|
|
Dtt = v[5*v_stride],...
|
|
|
|
In general, Ds^i Dt^j is returned in v[n],...,v[n+m_dim-1], where
|
|
|
|
n = v_stride*( (i+j)*(i+j+1)/2 + j).
|
|
|
|
Returns:
|
|
True if succcessful.
|
|
See Also:
|
|
ON_NurbsSurface::Evaluate
|
|
ON_EvaluateNurbsSpan
|
|
ON_EvaluateNurbsCageSpan
|
|
*/
|
|
ON_DECL
|
|
bool ON_EvaluateNurbsSurfaceSpan(
|
|
int dim,
|
|
bool is_rat,
|
|
int order0,
|
|
int order1,
|
|
const double* knot0,
|
|
const double* knot1,
|
|
int cv_stride0,
|
|
int cv_stride1,
|
|
const double* cv,
|
|
int der_count,
|
|
double s,
|
|
double t,
|
|
int v_stride,
|
|
double* v
|
|
);
|
|
|
|
|
|
|
|
/*
|
|
Description:
|
|
Evaluate a NURBS cage trispan.
|
|
Parameters:
|
|
dim - [in] >0
|
|
is_rat - [in] true of false
|
|
order0 - [in] >= 2
|
|
order1 - [in] >= 2
|
|
order2 - [in] >= 2
|
|
knot0 - [in]
|
|
NURBS knot vector with 2*(order0-1) knots, knot0[order0-2] != knot0[order0-1]
|
|
knot1 - [in]
|
|
NURBS knot vector with 2*(order1-1) knots, knot1[order1-2] != knot1[order1-1]
|
|
knot2 - [in]
|
|
NURBS knot vector with 2*(order1-1) knots, knot2[order2-2] != knot2[order2-1]
|
|
cv_stride0 - [in]
|
|
cv_stride1 - [in]
|
|
cv_stride2 - [in]
|
|
cv - [in]
|
|
For 0 <= i < order0, 0 <= j < order1, and 0 <= k < order2,
|
|
the (i,j,k)-th control vertex is
|
|
|
|
cv[n],...,cv[n+(is_rat?dim:dim+1)],
|
|
|
|
where n = i*cv_stride0 + j*cv_stride1 *k*cv_stride2.
|
|
If is_rat is true the cv is in homogeneous form.
|
|
|
|
der_count - [in] (>=0)
|
|
r - [in]
|
|
s - [in]
|
|
t - [in] (r,s,t) is the evaluation parameter
|
|
v_stride - [in] (>=dim)
|
|
v - [out] An array of length v_stride*(der_count+1)*(der_count+2)*(der_count+3)/6.
|
|
The evaluation results are stored in this array.
|
|
|
|
P = v[0],...,v[m_dim-1]
|
|
Dr = v[v_stride],...
|
|
Ds = v[2*v_stride],...
|
|
Dt = v[3*v_stride],...
|
|
Drr = v[4*v_stride],...
|
|
Drs = v[5*v_stride],...
|
|
Drt = v[6*v_stride],...
|
|
Dss = v[7*v_stride],...
|
|
Dst = v[8*v_stride],...
|
|
Dtt = v[9*v_stride],...
|
|
|
|
In general, Dr^i Ds^j Dt^k is returned in v[n],...,v[n+dim-1], where
|
|
|
|
d = (i+j+k)
|
|
n = v_stride*( d*(d+1)*(d+2)/6 + (j+k)*(j+k+1)/2 + k)
|
|
|
|
Returns:
|
|
True if succcessful.
|
|
See Also:
|
|
ON_NurbsCage::Evaluate
|
|
ON_EvaluateNurbsSpan
|
|
ON_EvaluateNurbsSurfaceSpan
|
|
*/
|
|
ON_DECL
|
|
bool ON_EvaluateNurbsCageSpan(
|
|
int dim,
|
|
bool is_rat,
|
|
int order0, int order1, int order2,
|
|
const double* knot0,
|
|
const double* knot1,
|
|
const double* knot2,
|
|
int cv_stride0, int cv_stride1, int cv_stride2,
|
|
const double* cv,
|
|
int der_count,
|
|
double t0, double t1, double t2,
|
|
int v_stride,
|
|
double* v
|
|
);
|
|
|
|
|
|
ON_DECL
|
|
bool ON_EvaluateNurbsDeBoor( // for expert users only - no support available
|
|
int, // cv_dim ( dim+1 for rational cvs )
|
|
int, // order (>=2)
|
|
int, // cv_stride (>=cv_dim)
|
|
double*, // cv array - values changed to result of applying De Boor's algorithm
|
|
const double*, // knot array
|
|
int, // side,
|
|
// -1 return left side of B-spline span in cv array
|
|
// +1 return right side of B-spline span in cv array
|
|
// -2 return left side of B-spline span in cv array
|
|
// Ignore values of knots[0,...,order-3] and assume
|
|
// left end of span has a fully multiple knot with
|
|
// value "mult_k".
|
|
// +2 return right side of B-spline span in cv array
|
|
// Ignore values of knots[order,...,2*order-2] and
|
|
// assume right end of span has a fully multiple
|
|
// knot with value "mult_k".
|
|
double, // mult_k - used when side is +2 or -2. See above for usage.
|
|
double // t
|
|
// If side < 0, then the cv's for the portion of the NURB span to
|
|
// the LEFT of t are computed. If side > 0, then the cv's for the
|
|
// portion the span to the RIGHT of t are computed. The following
|
|
// table summarizes the restrictions on t:
|
|
//
|
|
// value of side condition t must satisfy
|
|
// -2 mult_k < t and mult_k < knots[order-1]
|
|
// -1 knots[order-2] < t
|
|
// +1 t < knots[order-1]
|
|
// +2 t < mult_k and knots[order-2] < mult_k
|
|
);
|
|
|
|
|
|
ON_DECL
|
|
bool ON_EvaluateNurbsBlossom(int, // cvdim,
|
|
int, // order,
|
|
int, // cv_stride,
|
|
const double*, //CV, size cv_stride*order
|
|
const double*, //knot, nondecreasing, size 2*(order-1)
|
|
// knot[order-2] != knot[order-1]
|
|
const double*, //t, input parameters size order-1
|
|
double* // P
|
|
|
|
// DeBoor algorithm with different input at each step.
|
|
// returns false for bad input.
|
|
);
|
|
|
|
|
|
ON_DECL
|
|
void ON_ConvertNurbSpanToBezier(
|
|
int, // cvdim (dim+1 for rational curves)
|
|
int, // order,
|
|
int, // cvstride (>=cvdim)
|
|
double*, // cv array - input has NURBS cvs, output has Bezier cvs
|
|
const double*, // (2*order-2) knots for the NURBS span
|
|
double, // t0, NURBS span parameter of start point
|
|
double // t1, NURBS span parameter of end point
|
|
);
|
|
#endif
|