Files
opennurbs/opennurbs_evaluate_nurbs.h
2019-04-09 10:11:17 -07:00

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