opennurbs_evaluate_nurbs.h
1 /* $NoKeywords: $ */
2 /*
3 //
4 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
5 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
6 // McNeel & Associates.
7 //
8 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
9 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
10 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
11 //
12 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
13 //
14 ////////////////////////////////////////////////////////////////
15 */
16 
17 #if !defined(ON_EVALUATE_NURBS_INC_)
18 #define ON_EVALUATE_NURBS_INC_
19 
20 ON_DECL
21 bool ON_IncreaseBezierDegree(
22  int, // dimension
23  bool, // true if Bezier is rational
24  int, // order (>=2)
25  int, // cv_stride (>=dim+1)
26  double* // cv[(order+1)*cv_stride] array
27  );
28 
29 ON_DECL
30 bool ON_RemoveBezierSingAt0( // input bezier is rational with 0/0 at start
31  int, // dimension
32  int, // order (>=2)
33  int, // cv_stride (>=dim+1)
34  double* // cv[order*cv_stride] array
35  );
36 
37 ON_DECL
38 bool ON_RemoveBezierSingAt1( // input bezier is rational with 0/0 at end
39  int, // dimension
40  int, // order (>=2)
41  int, // cv_stride (>=dim+1)
42  double* // cv[order*cv_stride] array
43  );
44 
45 ON_DECL
46 double ON_EvaluateBernsteinBasis( // returns (i choose d)*(1-t)^(d-i)*t^i
47  int, // degree,
48  int, // 0 <= i <= degree
49  double // t
50  );
51 
52 ON_DECL
53 void ON_EvaluatedeCasteljau(
54  int, // dim
55  int, // order
56  int, // side <= 0 return left side of bezier in cv array
57  // > 0 return right side of bezier in cv array
58  int, // cv_stride
59  double*, // cv
60  double // t 0 <= t <= 1
61  );
62 
63 ON_DECL
64 bool ON_EvaluateBezier(
65  int, // dimension
66  bool, // true if Bezier is rational
67  int, // order (>=2)
68  int, // cv_stride >= (is_rat)?dim+1:dim
69  const double*, // cv[order*cv_stride] array
70  double, double, // t0,t1 = domain of bezier
71  int, // number of derivatives to compute (>=0)
72  double, // evaluation parameter
73  int, // v_stride (>=dimension)
74  double* // v[(der_count+1)*v_stride] array
75  );
76 
77 /*
78 Description:
79  Evaluate B-spline basis functions
80 
81 Parameters:
82  order - [in]
83  order >= 1
84  d = degree = order - 1
85  knot - [in]
86  array of length 2*d.
87  Generally, knot[0] <= ... <= knot[d-1] < knot[d] <= ... <= knot[2*d-1].
88  These are the knots that are active for the span being evaluated.
89  t - [in]
90  Evaluation parameter.
91  Typically knot[d-1] <= t <= knot[d].
92  In general t may be outside the interval knot[d-1],knot[d]. This can happen
93  when some type of extrapolation is being used and is almost always a bad
94  idea in practical situations.
95 
96  N - [out]
97  double array with capacity order*order.
98  The returned values are:
99 
100  If "N" were declared as double N[order][order], then
101 
102  k
103  N[d-k][i] = N (t) = value of i-th degree k basis function at t.
104  i
105  where 0 <= k <= d and k <= i <= d.
106 
107  In particular, N[0], ..., N[d] - values of degree d basis functions.
108  The "lower left" triangle is not initialized.
109 
110  Actually, the above is true when knot[d-1] <= t < knot[d]. Otherwise, the
111  value returned is the value of the polynomial that agrees with N_i^k on the
112  half open domain [ knot[d-1], knot[d] )
113 
114 COMMENTS:
115  If a degree d NURBS has n control points, then the OpenNURBS knot vector
116  for the entire NURBS curve has length d+n-1. The knot[] paramter to this
117  function points to the 2*d knots active for the span being evaluated.
118 
119  Most literature, including DeBoor and The NURBS Book,
120  duplicate the Opennurbs start and end knot values and have knot vectors
121  of length d+n+1. The extra two knot values are completely superfluous
122  when degree >= 1.
123 
124  Assume C is a B-spline of degree d (order=d+1) with n control vertices
125  (n>=d+1) and knot[] is its knot vector. Then
126 
127  C(t) = Sum( 0 <= i < n, N_{i}(t) * C_{i} )
128 
129  where N_{i} are the degree d b-spline basis functions and C_{i} are the control
130  vertices. The knot[] array length d+n-1 and satisfies
131 
132  knot[0] <= ... <= knot[d-1] < knot[d]
133  knot[n-2] < knot[n-1] <= ... <= knot[n+d-2]
134  knot[i] < knot[d+i] for 0 <= i < n-1
135  knot[i] <= knot[i+1] for 0 <= i < n+d-2
136 
137  The domain of C is [ knot[d-1], knot[n-1] ].
138 
139  The support of N_{i} is [ knot[i-1], knot[i+d] ).
140 
141  If d-1 <= k < n-1 and knot[k] <= t < knot[k+1], then
142  N_{i}(t) = 0 if i <= k-d
143  = 0 if i >= k+2
144  = B[i-k+d-1] if k-d+1 <= i <= k+1, where B[] is computed by the call
145  ON_EvaluateNurbsBasis( d+1, knot+k-d+1, t, B );
146 
147  If 0 <= j < n-d, 0 <= m <= d, knot[j+d-1] <= t < knot[j+d], and B[] is
148  computed by the call
149  ON_EvaluateNurbsBasis( d+1, knot+j, t, B ),
150  then
151  N_{j+m}(t) = B[m].
152 */
153 ON_DECL
154 bool ON_EvaluateNurbsBasis(
155  int order,
156  const double* knot,
157  double t,
158  double* N
159  );
160 
161 /*
162 Description:
163  Calculate derivatives of B-spline basis functions.
164 INPUT:
165  order - [in]
166  order >= 1
167  d = degree = order - 1
168  knot - [in]
169  array of length 2*d.
170  Generally, knot[0] <= ... <= knot[d-1] < knot[d] <= ... <= knot[2*d-1].
171  These are the knots that are active for the span being evaluated.
172  der_count - [in]
173  1 <= der_count < order
174  Number of derivatives.
175  Note all B-spline basis derivatives with der_coutn >= order are identically zero.
176 
177  N - [in]
178  The input value of N[] should be the results of the call
179  ON_EvaluateNurbsBasis( order, knot, t, N );
180 
181  N - [out]
182  If "N" were declared as double N[order][order], then
183 
184  d
185  N[d-k][i] = k-th derivative of N (t)
186  i
187 
188  where 0 <= k <= d and 0 <= i <= d.
189 
190  In particular,
191  N[0], ..., N[d] - values of degree d basis functions.
192  N[order], ..., N[order_d] - values of first derivative.
193 */
194 ON_DECL
195 bool ON_EvaluateNurbsBasisDerivatives(
196  int order,
197  const double* knot,
198  int der_count,
199  double* N
200  );
201 
202 /*
203 Description:
204  Evaluate a NURBS curve span.
205 Parameters:
206  dim - [in]
207  dimension (> 0).
208  is_rat - [in]
209  true or false.
210  order - [in]
211  order=degree+1 (order>=2)
212  knot - [in] NURBS knot vector.
213  NURBS knot vector with 2*(order-1) knots, knot[order-2] != knot[order-1]
214  cv_stride - [in]
215  cv - [in]
216  For 0 <= i < order the i-th control vertex is
217 
218  cv[n],...,cv[n+(is_rat?dim:dim+1)],
219 
220  where n = i*cv_stride. If is_rat is true the cv is
221  in homogeneous form.
222  der_count - [in]
223  number of derivatives to evaluate (>=0)
224  t - [in]
225  evaluation parameter
226  v_stride - [in]
227  v - [out]
228  An array of length v_stride*(der_count+1). The evaluation
229  results are returned in this array.
230 
231  P = v[0],...,v[m_dim-1]
232  Dt = v[v_stride],...
233  Dtt = v[2*v_stride],...
234  ...
235 
236  In general, Dt^i returned in v[n],...,v[n+m_dim-1], where
237 
238  n = v_stride*i.
239 
240 Returns:
241  True if successful.
242 See Also:
243  ON_NurbsCurve::Evaluate
244  ON_EvaluateNurbsSurfaceSpan
245  ON_EvaluateNurbsCageSpan
246 */
247 ON_DECL
248 bool ON_EvaluateNurbsSpan(
249  int dim,
250  bool is_rat,
251  int order,
252  const double* knot,
253  int cv_stride,
254  const double* cv,
255  int der_count,
256  double t,
257  int v_stride,
258  double* v
259  );
260 
261 /*
262 Description:
263  Evaluate a NURBS surface bispan.
264 Parameters:
265  dim - [in] >0
266  is_rat - [in] true of false
267  order0 - [in] >= 2
268  order1 - [in] >= 2
269  knot0 - [in]
270  NURBS knot vector with 2*(order0-1) knots, knot0[order0-2] != knot0[order0-1]
271  knot1 - [in]
272  NURBS knot vector with 2*(order1-1) knots, knot1[order1-2] != knot1[order1-1]
273  cv_stride0 - [in]
274  cv_stride1 - [in]
275  cv - [in]
276  For 0 <= i < order0 and 0 <= j < order1, the (i,j) control vertex is
277 
278  cv[n],...,cv[n+(is_rat?dim:dim+1)],
279 
280  where n = i*cv_stride0 + j*cv_stride1. If is_rat is true the cv is
281  in homogeneous form.
282 
283  der_count - [in] (>=0)
284  s - [in]
285  t - [in] (s,t) is the evaluation parameter
286  v_stride - [in] (>=dim)
287  v - [out] An array of length v_stride*(der_count+1)*(der_count+2)/2.
288  The evaluation results are stored in this array.
289 
290  P = v[0],...,v[m_dim-1]
291  Ds = v[v_stride],...
292  Dt = v[2*v_stride],...
293  Dss = v[3*v_stride],...
294  Dst = v[4*v_stride],...
295  Dtt = v[5*v_stride],...
296 
297  In general, Ds^i Dt^j is returned in v[n],...,v[n+m_dim-1], where
298 
299  n = v_stride*( (i+j)*(i+j+1)/2 + j).
300 
301 Returns:
302  True if succcessful.
303 See Also:
304  ON_NurbsSurface::Evaluate
305  ON_EvaluateNurbsSpan
306  ON_EvaluateNurbsCageSpan
307 */
308 ON_DECL
309 bool ON_EvaluateNurbsSurfaceSpan(
310  int dim,
311  bool is_rat,
312  int order0,
313  int order1,
314  const double* knot0,
315  const double* knot1,
316  int cv_stride0,
317  int cv_stride1,
318  const double* cv,
319  int der_count,
320  double s,
321  double t,
322  int v_stride,
323  double* v
324  );
325 
326 
327 
328 /*
329 Description:
330  Evaluate a NURBS cage trispan.
331 Parameters:
332  dim - [in] >0
333  is_rat - [in] true of false
334  order0 - [in] >= 2
335  order1 - [in] >= 2
336  order2 - [in] >= 2
337  knot0 - [in]
338  NURBS knot vector with 2*(order0-1) knots, knot0[order0-2] != knot0[order0-1]
339  knot1 - [in]
340  NURBS knot vector with 2*(order1-1) knots, knot1[order1-2] != knot1[order1-1]
341  knot2 - [in]
342  NURBS knot vector with 2*(order1-1) knots, knot2[order2-2] != knot2[order2-1]
343  cv_stride0 - [in]
344  cv_stride1 - [in]
345  cv_stride2 - [in]
346  cv - [in]
347  For 0 <= i < order0, 0 <= j < order1, and 0 <= k < order2,
348  the (i,j,k)-th control vertex is
349 
350  cv[n],...,cv[n+(is_rat?dim:dim+1)],
351 
352  where n = i*cv_stride0 + j*cv_stride1 *k*cv_stride2.
353  If is_rat is true the cv is in homogeneous form.
354 
355  der_count - [in] (>=0)
356  r - [in]
357  s - [in]
358  t - [in] (r,s,t) is the evaluation parameter
359  v_stride - [in] (>=dim)
360  v - [out] An array of length v_stride*(der_count+1)*(der_count+2)*(der_count+3)/6.
361  The evaluation results are stored in this array.
362 
363  P = v[0],...,v[m_dim-1]
364  Dr = v[v_stride],...
365  Ds = v[2*v_stride],...
366  Dt = v[3*v_stride],...
367  Drr = v[4*v_stride],...
368  Drs = v[5*v_stride],...
369  Drt = v[6*v_stride],...
370  Dss = v[7*v_stride],...
371  Dst = v[8*v_stride],...
372  Dtt = v[9*v_stride],...
373 
374  In general, Dr^i Ds^j Dt^k is returned in v[n],...,v[n+dim-1], where
375 
376  d = (i+j+k)
377  n = v_stride*( d*(d+1)*(d+2)/6 + (j+k)*(j+k+1)/2 + k)
378 
379 Returns:
380  True if succcessful.
381 See Also:
382  ON_NurbsCage::Evaluate
383  ON_EvaluateNurbsSpan
384  ON_EvaluateNurbsSurfaceSpan
385 */
386 ON_DECL
387 bool ON_EvaluateNurbsCageSpan(
388  int dim,
389  bool is_rat,
390  int order0, int order1, int order2,
391  const double* knot0,
392  const double* knot1,
393  const double* knot2,
394  int cv_stride0, int cv_stride1, int cv_stride2,
395  const double* cv,
396  int der_count,
397  double t0, double t1, double t2,
398  int v_stride,
399  double* v
400  );
401 
402 
403 ON_DECL
404 bool ON_EvaluateNurbsDeBoor( // for expert users only - no support available
405  int, // cv_dim ( dim+1 for rational cvs )
406  int, // order (>=2)
407  int, // cv_stride (>=cv_dim)
408  double*, // cv array - values changed to result of applying De Boor's algorithm
409  const double*, // knot array
410  int, // side,
411  // -1 return left side of B-spline span in cv array
412  // +1 return right side of B-spline span in cv array
413  // -2 return left side of B-spline span in cv array
414  // Ignore values of knots[0,...,order-3] and assume
415  // left end of span has a fully multiple knot with
416  // value "mult_k".
417  // +2 return right side of B-spline span in cv array
418  // Ignore values of knots[order,...,2*order-2] and
419  // assume right end of span has a fully multiple
420  // knot with value "mult_k".
421  double, // mult_k - used when side is +2 or -2. See above for usage.
422  double // t
423  // If side < 0, then the cv's for the portion of the NURB span to
424  // the LEFT of t are computed. If side > 0, then the cv's for the
425  // portion the span to the RIGHT of t are computed. The following
426  // table summarizes the restrictions on t:
427  //
428  // value of side condition t must satisfy
429  // -2 mult_k < t and mult_k < knots[order-1]
430  // -1 knots[order-2] < t
431  // +1 t < knots[order-1]
432  // +2 t < mult_k and knots[order-2] < mult_k
433  );
434 
435 
436 ON_DECL
437 bool ON_EvaluateNurbsBlossom(int, // cvdim,
438  int, // order,
439  int, // cv_stride,
440  const double*, //CV, size cv_stride*order
441  const double*, //knot, nondecreasing, size 2*(order-1)
442  // knot[order-2] != knot[order-1]
443  const double*, //t, input parameters size order-1
444  double* // P
445 
446  // DeBoor algorithm with different input at each step.
447  // returns false for bad input.
448  );
449 
450 
451 ON_DECL
452 void ON_ConvertNurbSpanToBezier(
453  int, // cvdim (dim+1 for rational curves)
454  int, // order,
455  int, // cvstride (>=cvdim)
456  double*, // cv array - input has NURBS cvs, output has Bezier cvs
457  const double*, // (2*order-2) knots for the NURBS span
458  double, // t0, NURBS span parameter of start point
459  double // t1, NURBS span parameter of end point
460  );
461 #endif