/* $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 . // //////////////////////////////////////////////////////////////// */ #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