HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GT_CurveEval.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GT_CurveEval.h (GT Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GT_CurveEval__
12 #define __GT_CurveEval__
13 
14 #include "GT_API.h"
15 #include "GT_Types.h"
16 
17 #include "GT_Handles.h"
18 #include <UT/UT_Array.h>
19 
20 class UT_JSONWriter;
21 
22 /// Class to perform evaluation of the curve spline types.
23 ///
24 /// This is similar to UT_Spline but supports higher order curves and a
25 /// different set of basis functions.
26 ///
27 /// To evaluate a curve, you do something like: @code
28 /// const GT_CurveEval eval(...);
29 /// int nspans = eval.spanCount(nvertices);
30 /// type result[nspans*points_per_span];
31 ///
32 /// Note: There only dependency on GT is the basis type. This can likely be
33 /// moved to a lower library (i.e. UT).
34 class GT_API GT_CurveEval
35 {
36 public:
37  static int maximumBezierOrder();
38  static void orderRange(GT_Basis basis, int &min_order, int &max_order);
39 
40  GT_CurveEval(GT_Basis basis, bool periodic);
41  GT_CurveEval(const GT_CurveEval &eval);
42 
43  void setOrder(int order)
44  {
45  if (order != myOrder)
46  cacheOrderComputation(order);
47  }
48 
49  /// Class to hold non-uniform knot vector.
50  class Knots
51  {
52  public:
53  Knots()
54  : myKnots(0)
55  , mySize(0)
56  {
57  }
58  /// The knots passed in are not owned by this class, so they must stay
59  /// in existence while the Knots object is in existence.
60  Knots(const fpreal *knots, int length)
61  : myKnots(knots)
62  , mySize(length)
63  {
64  }
65  /// Test validity
66  bool valid() const { return myKnots && mySize > 1; }
67  /// Return the full knot vector
68  const fpreal *knots() const { return myKnots; }
69  /// Return the knots for the given span
70  const fpreal *knots(int span) const { return myKnots + span; }
71  /// For a given @c span, and interpolant @c t (between 0 and 1), return
72  /// the proper knot value for interpolation.
73  fpreal getU(int span, int order, fpreal t) const
74  {
75  int n = span + order - 1;
76  UT_ASSERT(n >= 0 && n+1 < mySize);
77  return SYSlerp(myKnots[n], myKnots[n+1], t);
78  }
79  /// Return the length of the knot vector
80  int size() const { return mySize; }
81  /// Lookup a knot
82  fpreal operator()(int i) const
83  {
84  UT_ASSERT(i >= 0 && i < mySize);
85  return myKnots[i];
86  }
87  /// Lookup a knot
88  fpreal operator[](int i) const
89  {
90  UT_ASSERT(i >= 0 && i < mySize);
91  return myKnots[i];
92  }
93 
94  /// Set up knot vector
95  void setKnots(const fpreal *knots, int size)
96  {
97  myKnots = knots;
98  mySize = size;
99  }
100 
101  /// @{
102  /// Debug
103  bool save(UT_JSONWriter &w);
104  void dump(const char *msg="");
105  /// @}
106  private:
107  const fpreal *myKnots;
108  int mySize;
109  };
110 
111  /// Test if there's a valid count for the given curve type (of the given
112  /// order).
113  bool validCount(int nvertices, int order) const;
114 
115  /// @{
116  /// Access member data
117  GT_Basis basis() const { return myBasis; }
118  bool periodic() const { return myPeriodic; }
119  /// @}
120 
121  /// Return the step size for iterating through spans
122  int step() const { return myStep; }
123 
124  /// Return the number of spans for a given hull
125  int spanCount(int nvtx, int order) const
126  { return GTbasisSpans(myBasis, nvtx, myPeriodic, order); }
127 
128  /// The EvalBuffer class is used to store state for evaluation
129  class EvalBuffer
130  {
131  public:
132  EvalBuffer() {}
133  ~EvalBuffer() {}
134 
135  enum
136  {
137  // This size is tied to constants in GT_Binomial.h
138  EVAL_BUF_SIZE = 32
139  };
140 
141  /// Weights for each element in the span
142  const fpreal *w() const { return myW; }
143  fpreal *w() { return myW; }
144 
145  /// @{
146  /// Which element in the span contributes the most
147  int conditional() const { return myConditional; }
148  void setConditional(int c) { myConditional = c; }
149  /// @}
150 
151  /// Find the element which contributes the most in the span
152  void computeConditional(int nvals)
153  {
154  myConditional = 0;
155  for (int i = 1; i < nvals; ++i)
156  if (myW[i] > myW[myConditional])
157  myConditional = i;
158  }
159 
160  private:
161  fpreal myW[EVAL_BUF_SIZE];
162  int myConditional;
163  };
164  /// @{
165  /// Evaluate a the hull of a curve at a given parametric coordinate.
166  /// There should be @c order elements in the hull.
167  ///
168  /// The default template implementation performs conditional copying.
169  template <typename DATA_T>
170  inline DATA_T eval(int order, const EvalBuffer &ebuf,
171  const DATA_T *hull, int stride=1) const
172  { return hull[ebuf.conditional()*stride]; }
173  /// @}
174 
175  /// @{
176  /// Evaluate a the hull of a curve at a given parametric coordinate and an
177  /// indirection array. The elements in the indirection array are used to
178  /// perform the lookup.
179  /// There should be @c order elements in the index array.
180  template <typename DATA_T>
181  inline DATA_T evalIndex(int order, const EvalBuffer &ebuf,
182  const DATA_T *hull, const int *index) const
183  { return hull[index[ebuf.conditional()]]; }
184  /// @}
185 
186  /// Precompute the evaluation buffer for a span
187  void preCompute(int order, EvalBuffer &ebuf, fpreal t) const;
188 
189  /// @{
190  /// Refine to numeric arrays
191  /// - @c dest must be an array of GT_DANumeric sub-classes
192  /// - @c dest_offset into the dest arrays to begin writing the evaluated
193  /// data
194  /// - @c dest_count the number of evaluations
195  /// - @c hull The attributes to be evaluated
196  /// - @c hull_offset the offset into the hull arrays
197  /// - @c hull_count is the number of elements in the array for the hull
198  /// For example, given a GT_PrimCurveMesh with a two curves: @code
199  /// // Refine 1st curve to 10 points and the second to 32
200  /// int dpts[] = { 10, 32 }
201  /// UT_Array<GT_DataArrayHandle> arrays;
202  /// const GT_AttributeListHandle &vertex = curve->getcVertexAttributes();
203  /// eval.allocateNumericArrays(arrays, vertex, 42);
204  /// refineToNumeric(arrays, 0, 10, vertex,
205  /// curve->getVertexOffset(0),
206  /// curve->getVertexCount(0));
207  /// refineToNumeric(arrays, 10, 32, vertex,
208  /// curve->getVertexOffset(1),
209  /// curve->getVertexCount(1));
210  /// // Create a destination attribute list
211  /// GT_AttributeListHandle dest(new GT_AttributeListHandle(*vertex));
212  /// // And copy the array data into the attribute list
213  /// copyToAttributes(dest, arrays);
214  /// @endcode
215  /// @note You must ensure that @c setOrder() has been called
217  const GT_AttributeListHandle &hull,
218  GT_Size total_points) const;
219  bool refineToNumeric(int order,
221  GT_Offset dest_offset,
222  GT_Size dest_count,
223  const GT_AttributeListHandle &hull,
224  GT_Offset hull_offset,
225  GT_Size hull_count,
226  const GT_DataArrayHandle &knots,
227  GT_Offset knot_offset,
228  int segment=0) const;
231  int segment=0) const;
232  /// @}
233 
234  /// When computing with knots, there need to be Order*2+1 knots for a span
235  void preCompute(int order, EvalBuffer &ebuf, int span, fpreal t,
236  const Knots &knots) const;
237 
238 private:
239  void cacheOrderComputation(int order);
240 
241  template <typename T>
242  inline T evalF(int order, const EvalBuffer &ebuf,
243  const T *hull, int stride) const
244  {
245  fpreal v = 0;
246  const fpreal *w = ebuf.w();
247  for (int i = 0; i < order; ++i)
248  v += w[i] * hull[i*stride];
249  return v;
250  }
251  template <typename DATA_T>
252  inline DATA_T evalFIndex(int order, const EvalBuffer &ebuf,
253  const DATA_T *hull,
254  const int *index) const
255  {
256  fpreal v = 0;
257  const fpreal *w = ebuf.w();
258  for (int i = 0; i < order; ++i)
259  v += w[i] * hull[index[i]];
260  return v;
261  }
263  int myOrder;
264  int myStep;
266 };
267 
268 /// @{
269 /// Explicit floating point specializations that perform interpolation of values
270 template <> inline fpreal16
271 GT_CurveEval::eval<fpreal16>(int order, const EvalBuffer &ebuf,
272  const fpreal16 *hull, int stride) const
273  { return evalF(order, ebuf, hull, stride); }
274 template <> inline fpreal32
275 GT_CurveEval::eval<fpreal32>(int order, const EvalBuffer &ebuf,
276  const fpreal32 *hull, int stride) const
277  { return evalF(order, ebuf, hull, stride); }
278 template <> inline fpreal64
279 GT_CurveEval::eval<fpreal64>(int order, const EvalBuffer &ebuf,
280  const fpreal64 *hull, int stride) const
281  { return evalF(order, ebuf, hull, stride); }
282 
283 template <> inline fpreal16
284 GT_CurveEval::evalIndex<fpreal16>(int order, const EvalBuffer &ebuf,
285  const fpreal16 *hull, const int *index) const
286  { return evalFIndex<fpreal16>(order, ebuf, hull, index); }
287 template <> inline fpreal32
288 GT_CurveEval::evalIndex<fpreal32>(int order, const EvalBuffer &ebuf,
289  const fpreal32 *hull, const int *index) const
290  { return evalFIndex<fpreal32>(order, ebuf, hull, index); }
291 template <> inline fpreal64
292 GT_CurveEval::evalIndex<fpreal64>(int order, const EvalBuffer &ebuf,
293  const fpreal64 *hull, const int *index) const
294  { return evalFIndex<fpreal64>(order, ebuf, hull, index); }
295 /// @}
296 
297 
298 #endif
const GLuint * arrays
Definition: glcorearb.h:1303
int myOrder
Definition: GT_CurveEval.h:263
const GLdouble * v
Definition: glcorearb.h:837
Definition: span.h:73
int myStep
Definition: GT_CurveEval.h:264
#define GT_API
Definition: GT_API.h:13
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
void preCompute(int order, EvalBuffer &ebuf, int span, fpreal t, const Knots &knots) const
When computing with knots, there need to be Order*2+1 knots for a span.
UT_Matrix2T< T > SYSlerp(const UT_Matrix2T< T > &v1, const UT_Matrix2T< T > &v2, S t)
Definition: UT_Matrix2.h:675
float fpreal32
Definition: SYS_Types.h:200
bool copyToAttributes(GT_AttributeListHandle &dest, UT_Array< GT_DataArrayHandle > &arrays, int segment=0) const
double fpreal64
Definition: SYS_Types.h:201
GLdouble n
Definition: glcorearb.h:2008
bool myPeriodic
Definition: GT_CurveEval.h:265
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:872
int64 GT_Offset
Definition: GT_Types.h:129
GLdouble GLdouble GLint GLint order
Definition: glad.h:2676
HUSD_API bool eval(VtValue &val, T &ret_val)
GLdouble t
Definition: glad.h:2397
int64 GT_Size
Definition: GT_Types.h:128
GLsizeiptr size
Definition: glcorearb.h:664
GT_Basis myBasis
Definition: GT_CurveEval.h:262
fpreal64 fpreal
Definition: SYS_Types.h:277
bool refineToNumeric(int order, UT_Array< GT_DataArrayHandle > &arrays, GT_Offset dest_offset, GT_Size dest_count, const GT_AttributeListHandle &hull, GT_Offset hull_offset, GT_Size hull_count, const GT_DataArrayHandle &knots, GT_Offset knot_offset, int segment=0) const
GLuint index
Definition: glcorearb.h:786
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
GT_API GT_Size GTbasisSpans(GT_Basis basis, GT_Size count, bool wrapped, int order=4)
void allocateNumericArrays(UT_Array< GT_DataArrayHandle > &arrays, const GT_AttributeListHandle &hull, GT_Size total_points) const
GT_Basis
Definition: GT_Types.h:55
GLenum GLenum GLsizei void GLsizei void void * span
Definition: glad.h:5135