HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CVEX_Data.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: CVEX Library (C++)
7  *
8  */
9 
10 #ifndef __CVEX_Data_h__
11 #define __CVEX_Data_h__
12 
13 #include "CVEX_API.h"
14 #include "CVEX_Value.h" // for CVEX_Type
15 #include <VEX/VEX_PodTypes.h>
16 #include <UT/UT_NonCopyable.h>
18 #include <UT/UT_StringMap.h>
19 #include <UT/UT_UniquePtr.h>
20 #include <UT/UT_Vector.h>
21 
22 // ============================================================================
23 /// Class for storing CVEX data buffers, where each buffer contains data for
24 /// a CVEX_Value object. The CVEX_Data class owns the buffers and manages
25 /// their allocation and deallocation.
26 /// Each buffer also has a corresponding name and CVEX type,
27 /// which can be useful when transferring data to and from the buffers.
28 ///
29 /// For example: @code
30 /// CVEX_Data data;
31 /// CVEX_ValueT<PREC> *value = cvex_context.findInput("foo");
32 /// auto *buffer = data.addDataBuffer<fpreal32>("foo", value->getType());
33 /// buffer.setSize( 10 );
34 /// for( int i=0; i<10; ++i )
35 /// buffer[i] = 0.1 * (fpreal32) i;
36 /// value->setTypedData( buffer->data(), buffer->size() );
37 /// @endcode
38 ///
40 {
41 public:
42  /// Creates an object that holds and manages the data buffers.
43  CVEX_Data();
44  ~CVEX_Data();
45 
47 
48  /// @{ Adds a new buffer and returns it as a reference.
49  /// If a buffer by that name has already been added, it is returned,
50  /// provinding the type matches. If type does not match, returns nullptr.
51  /// The given @p type is associated with that buffer
52  template<typename T> UT_Array<T> *
53  addDataBuffer(const UT_StringRef &name, CVEX_Type type);
54  template<typename T> UT_PackedArrayOfArrays<T> *
55  addArrayDataBuffer(const UT_StringRef &name, CVEX_Type type);
56  /// @}
57 
58  /// @{ Returns the data buffer given by its name and type T, or null
59  /// if not found.
60  template<typename T> UT_Array<T> *
61  findDataBuffer(const UT_StringRef &name) const;
62  template<typename T> UT_PackedArrayOfArrays<T> *
63  findArrayDataBuffer(const UT_StringRef &name) const;
64  /// @}
65 
66  /// Returns true if the data has a buffer of the given name.
67  bool hasBuffer( const UT_StringRef &name ) const;
68 
69  /// Returns the CVEX type associated with the data buffer given its name,
70  /// or, if buffer is not found, returns CVEX_TYPE_INVALID.
71  CVEX_Type getCvexType(const UT_StringRef &name) const;
72 
73  /// @{ Sets and gets the varying flag.
74  /// Note, caller needs to maintain the consistent value of that flag.
75  void setIsVarying(const UT_StringRef &name, bool is_var) const;
76  bool isVarying(const UT_StringRef &name) const;
77  /// @}
78 
79 private:
80  /// @{ Private helper method templates for adding and finding buffers.
81  template<typename T> T *add(const UT_StringRef &name, CVEX_Type type);
82  template<typename T> T *find(const UT_StringRef &name) const;
83  /// @}
84 
85 private:
86  // Base class for buffer holders.
87  class Data
88  {
89  public:
90  Data( CVEX_Type cvex_type )
91  : myCvexType(cvex_type), myIsVarying(true) {}
92  virtual ~Data() {}
93 
94  UT_NON_COPYABLE(Data)
95 
96  CVEX_Type getCvexType() const { return myCvexType; }
97 
98  void setIsVarying(bool var) { myIsVarying = var; }
99  bool isVarying() const { return myIsVarying; }
100  private:
101  CVEX_Type myCvexType; // CVEX type for which this buffer was created
102  bool myIsVarying; // True if data is varying;
103  // false otherwise (buffer size is 1).
104  };
105 
106  // Templetized buffer holders.
107  template<typename T> class DataImpl : public Data
108  {
109  public:
110  DataImpl( UT_UniquePtr<T> &&data_array, CVEX_Type cvex_type)
111  : Data( cvex_type )
112  , myDataPtr( std::move( data_array )) {}
113  T * getData()
114  { return myDataPtr.get(); }
115  private:
116  UT_UniquePtr<T> myDataPtr; // data buffer object (an array)
117  };
118 
119 private:
120  /// The actual data buffers objects.
121  UT_StringMap< Data *> myBufferMap;
122 };
123 
124 
125 template<typename T>
126 T *
127 CVEX_Data::add(const UT_StringRef &name, CVEX_Type type)
128 {
129  if( myBufferMap.contains( name ))
130  return find<T>( name );
131 
132  auto data = new DataImpl<T>( std::move( UTmakeUnique<T>() ), type);
133  myBufferMap[ name ] = data;
134  return data->getData();
135 }
136 
137 template<typename T>
138 T *
139 CVEX_Data::find( const UT_StringRef &name ) const
140 {
141  auto it = myBufferMap.find( name );
142  if( it == myBufferMap.end() )
143  return nullptr;
144 
145  auto data = dynamic_cast<DataImpl<T> *>( it->second );
146  return data ? data->getData() : nullptr;
147 }
148 
149 template<typename T>
150 UT_Array<T> *
152 {
153  return add<UT_Array<T>>( name, type );
154 }
155 
156 template<typename T>
159 {
160  return add<UT_PackedArrayOfArrays<T>>( name, type );
161 }
162 
163 template<typename T>
164 UT_Array<T> *
166 {
167  return find<UT_Array<T>>( name );
168 }
169 
170 template<typename T>
173 {
174  return find<UT_PackedArrayOfArrays<T>>( name );
175 }
176 
177 // ============================================================================
178 /// A convenience class to store input and output data in two separate data
179 /// objects, to avoid name clashes between input and output CVEX_Value with
180 /// the same names.
182 {
183 public:
184  /// Creates a holder for the data buffers.
186  /// @{ Accessors
187  CVEX_Data &getInputData() { return myInputData; }
188  const CVEX_Data &getInputData() const { return myInputData; }
189  CVEX_Data &getOutputData() { return myOutputData; }
190  const CVEX_Data &getOutputData() const { return myOutputData; }
191  /// @}
192 
193 private:
194  CVEX_Data myInputData;
195  CVEX_Data myOutputData;
196 };
197 
198 // ============================================================================
199 /// Precision-dependent types of CVEX data.
200 template <VEX_Precision PREC>
202 {
203 public:
204  using Int = VEXint<PREC>;
213 };
214 
215 #define DECLARE_CVEX_DATA_TYPES \
216  using Int = typename CVEX_DataType<PREC>::Int; \
217  using Float = typename CVEX_DataType<PREC>::Float; \
218  using String = UT_StringHolder; \
219  using Dict = UT_OptionsHolder; \
220  using Vec2 = typename CVEX_DataType<PREC>::Vec2; \
221  using Vec3 = typename CVEX_DataType<PREC>::Vec3; \
222  using Vec4 = typename CVEX_DataType<PREC>::Vec4; \
223  using Mat2 = typename CVEX_DataType<PREC>::Mat2; \
224  using Mat3 = typename CVEX_DataType<PREC>::Mat3; \
225  using Mat4 = typename CVEX_DataType<PREC>::Mat4; \
226  using Quat = typename CVEX_DataType<PREC>::Quat; \
227 
228 
229 // ============================================================================
230 /// A helper class for binding data buffers to CVEX values.
231 /// It abstracts the buffer management by allowing to override a virtual
232 /// method for the particular data type.
233 ///
234 /// For example: @code
235 /// class MY_Binder : public CVEX_DataBinder32
236 /// {
237 /// public:
238 /// MY_Binder(CVEX_Data &data, exint size, fpreal32 multipiler)
239 /// : CVEX_DataBinder32(data, size), myMultiplier(multipiler) {}
240 /// ...
241 /// virtual bool setData( UT_Array<Float> &data,
242 /// const UT_StringRef &data_name ) override
243 /// {
244 /// for( int i=0; i < getBufferSize(); i++ )
245 /// data = myMultiplier * (fpreal32) i;
246 /// }
247 /// private:
248 /// fpreal32 myMultiplier;
249 /// };
250 ///
251 /// CVEX_Data data;
252 /// MY_Binder binder( data, 10, 0.1 );
253 /// binder.setAndBindData( *cvex_context.findInput( "foo_in" ));
254 /// @endcode
255 //
256 /// For example, binding an output buffer: @code
257 /// CVEX_Data data;
258 /// CVEX_DataBinder32 binder( data, 10 );
259 /// binder.bindData( *cvex_context.findOutput( "bar_out" ));
260 /// @endcode
261 ///
262 template <VEX_Precision PREC>
264 {
265 public:
266  /// Creates a binder object for binding data buffers to CVEX values.
267  /// The @data is the data holder that stores the data buffers.
268  /// The @p buffer_size specifies the size of buffers this class will create,
269  /// and should be equal to the value passed into CVEX_Context::run().
270  CVEX_DataBinder( CVEX_Data &data, exint buffer_size );
271  virtual ~CVEX_DataBinder();
272 
274 
275  /// Return the size of the data buffers.
276  exint getBufferSize() const
277  { return myBufferSize; }
278 
279  /// Creates a new data buffer, calls the virtuals to fill it with data,
280  /// then binds it to the given CVEX value.
281  bool setAndBindData( CVEX_ValueT<PREC> &value );
282 
283  /// Creates a new data buffer, initializes it to zero (without calling
284  /// the virtuals), then binds it to the given CVEX value.
285  bool bindData( CVEX_ValueT<PREC> &value );
286 
287  /// After binding data, this query will return true if the value is
288  /// varying (and the associated buffer size is large as specified in
289  /// the constructor parameter) or uniform (and size is 1).
290  bool isVarying(const UT_StringRef &name) const
291  { return myData.isVarying( name ); }
292 
293  /// Precision-dependent data types (Int, Float, Vec2, ...) used in virtuals.
295 
296 protected:
297  /// @{ Virtuals intended to be overriden by the subclass.
298  /// Their purpose is to get the values from some custom data source
299  /// and set the value of the @data parameter.
300  /// The @p data is the data buffer over which the CVEX program will run.
301  /// The @p data_size is the number of elements to set. It will be equal
302  /// to getBufferSize() for varying data, and 1 for uniform.
303  /// UT_Array @data is pre-sized to this size, however
304  /// UT_PackedArrayOfArray() can't be pre-sized; so this many elements
305  /// must be appended.
306  /// The @p data_name is the name of the data buffer.
307  virtual bool setData( UT_Array<Int> &data, exint data_size,
308  const UT_StringRef &data_name );
309  virtual bool setData( UT_Array<Float> &data, exint data_size,
310  const UT_StringRef &data_name );
311  virtual bool setData( UT_Array<String> &data, exint data_size,
312  const UT_StringRef &data_name );
313  virtual bool setData( UT_Array<Dict> &data, exint data_size,
314  const UT_StringRef &data_name );
315  virtual bool setData( UT_Array<Vec2> &data, exint data_size,
316  const UT_StringRef &data_name );
317  virtual bool setData( UT_Array<Vec3> &data, exint data_size,
318  const UT_StringRef &data_name );
319  virtual bool setData( UT_Array<Vec4> &data, exint data_size,
320  const UT_StringRef &data_name );
321  virtual bool setData( UT_Array<Mat2> &data, exint data_size,
322  const UT_StringRef &data_name );
323  virtual bool setData( UT_Array<Mat3> &data, exint data_size,
324  const UT_StringRef &data_name );
325  virtual bool setData( UT_Array<Mat4> &data, exint data_size,
326  const UT_StringRef &data_name );
327 
328  virtual bool setData( UT_PackedArrayOfArrays<Int> &data, exint data_size,
329  const UT_StringRef &data_name );
330  virtual bool setData( UT_PackedArrayOfArrays<Float> &data, exint data_size,
331  const UT_StringRef &data_name );
332  virtual bool setData( UT_PackedArrayOfArrays<String> &data, exint data_size,
333  const UT_StringRef &data_name );
334  virtual bool setData( UT_PackedArrayOfArrays<Dict> &data, exint data_size,
335  const UT_StringRef &data_name );
336  virtual bool setData( UT_PackedArrayOfArrays<Vec2> &data, exint data_size,
337  const UT_StringRef &data_name );
338  virtual bool setData( UT_PackedArrayOfArrays<Vec3> &data, exint data_size,
339  const UT_StringRef &data_name );
340  virtual bool setData( UT_PackedArrayOfArrays<Vec4> &data, exint data_size,
341  const UT_StringRef &data_name );
342  virtual bool setData( UT_PackedArrayOfArrays<Mat2> &data, exint data_size,
343  const UT_StringRef &data_name );
344  virtual bool setData( UT_PackedArrayOfArrays<Mat3> &data, exint data_size,
345  const UT_StringRef &data_name );
346  virtual bool setData( UT_PackedArrayOfArrays<Mat4> &data, exint data_size,
347  const UT_StringRef &data_name );
348  /// @}
349 
350 private:
351  /// @{ Helper methods and templates for managing the buffers.
352  bool setIfRequestedAndBindData( CVEX_ValueT<PREC> &value, bool set_data );
353 
354  template<typename T, typename BIND>
355  bool addBufferAndBind( CVEX_ValueT<PREC> &value, bool set_data, BIND bind );
356  template<typename T>
357  bool addBufferAndBindAsPtr( CVEX_ValueT<PREC> &value, bool set_data );
358  template<typename T>
359  bool addBufferAndBindAsObj( CVEX_ValueT<PREC> &value, bool set_data );
360 
361  template<typename T>
362  bool addSclrArrayBufferAndBind( CVEX_ValueT<PREC> &value, bool set_data );
363  template<typename T>
364  bool addVecArrayBufferAndBind( CVEX_ValueT<PREC> &value, bool set_data );
365  bool addStrArrayBufferAndBind( CVEX_ValueT<PREC> &value, bool set_data );
366  bool addDictArrayBufferAndBind( CVEX_ValueT<PREC> &value, bool set_data );
367  /// @}
368 
369 private:
370  /// Data buffers to fill and to bind to CVEX values.
371  CVEX_Data &myData;
372 
373  /// The size of each data buffer created and bound by this class.
374  exint myBufferSize;
375 };
376 
379 
380 
381 // ============================================================================
382 /// A helper class for retrieving data from CVEX buffers to custom destination.
383 /// It abstracts the buffer management by allowing to override virtual
384 /// methods for the particular data types.
385 ///
386 /// For example: @code
387 /// class MY_Printer : public CVEX_DataRetriever32
388 /// {
389 /// public:
390 /// MyPrinter( const CVEX_Data &data )
391 /// : CVEX_DataRetriever32( data ) {}
392 /// ...
393 /// virtual bool takeData( const UT_Array<Float> &data,
394 /// const UT_StringRef &data_name ) override
395 /// {
396 /// for( exint i = 0; i < data.size(); i++ )
397 /// cout << "Entry " << i << ": " << data[i] << "\n";
398 /// }
399 /// };
400 ///
401 /// CVEX_Data data;
402 /// ... // ... bind data buffers and run CVEX...
403 /// MY_Printer retriever( data );
404 /// cout << "Computed data for 'bar_out' buffer:\n";
405 /// retriever.retrieveData( "bar_out" );
406 /// @endcode
407 ///
408 template <VEX_Precision PREC>
410 {
411 public:
412  /// Creates a retriever object for obtaining data from the buffers.
414  virtual ~CVEX_DataRetriever();
415 
417 
418  /// @{ Looks for a data buffer given the CVEX value or a name,
419  /// and calls the virtuals to retrieve the data from the bufer.
420  bool retrieveData( const CVEX_ValueT<PREC> &value );
421  bool retrieveData( const UT_StringRef &data_name );
422  /// @}
423 
424  /// Utility method for checking if the value is varying (and
425  /// the associated buffer size is large as specified in the constructor
426  // p/arameter) or uniform (and size is 1).
427  bool isVarying(const UT_StringRef &name) const
428  { return myData.isVarying( name ); }
429 
430 protected:
431  /// Precision-dependent data types (Int, Float, Vec2, ...) used in virtuals.
433 
434  /// @{ Virtuals intended to be overriden by the subclasses.
435  /// Their purpose is to take the value given in the @data parameter
436  /// and transfer it to the intended destination.
437  /// The @p data represents a data buffer on which the CVEX program was run.
438  /// The @p name is the name of the data buffer.
439  virtual bool takeData( const UT_Array<Int> &data,
440  const UT_StringRef &data_name );
441  virtual bool takeData( const UT_Array<Float> &data,
442  const UT_StringRef &data_name );
443  virtual bool takeData( const UT_Array<String> &data,
444  const UT_StringRef &data_name );
445  virtual bool takeData( const UT_Array<Dict> &data,
446  const UT_StringRef &data_name );
447  virtual bool takeData( const UT_Array<Vec2> &data,
448  const UT_StringRef &data_name );
449  virtual bool takeData( const UT_Array<Vec3> &data,
450  const UT_StringRef &data_name );
451  virtual bool takeData( const UT_Array<Vec4> &data,
452  const UT_StringRef &data_name );
453  virtual bool takeData( const UT_Array<Mat2> &data,
454  const UT_StringRef &data_name );
455  virtual bool takeData( const UT_Array<Mat3> &data,
456  const UT_StringRef &data_name );
457  virtual bool takeData( const UT_Array<Mat4> &data,
458  const UT_StringRef &data_name );
459 
460  virtual bool takeData( const UT_PackedArrayOfArrays<Int> &data,
461  const UT_StringRef &data_name );
462  virtual bool takeData( const UT_PackedArrayOfArrays<Float> &data,
463  const UT_StringRef &data_name );
464  virtual bool takeData( const UT_PackedArrayOfArrays<String> &data,
465  const UT_StringRef &data_name );
466  virtual bool takeData( const UT_PackedArrayOfArrays<Dict> &data,
467  const UT_StringRef &data_name );
468  virtual bool takeData( const UT_PackedArrayOfArrays<Vec2> &data,
469  const UT_StringRef &data_name );
470  virtual bool takeData( const UT_PackedArrayOfArrays<Vec3> &data,
471  const UT_StringRef &data_name );
472  virtual bool takeData( const UT_PackedArrayOfArrays<Vec4> &data,
473  const UT_StringRef &data_name );
474  virtual bool takeData( const UT_PackedArrayOfArrays<Mat2> &data,
475  const UT_StringRef &data_name );
476  virtual bool takeData( const UT_PackedArrayOfArrays<Mat3> &data,
477  const UT_StringRef &data_name );
478  virtual bool takeData( const UT_PackedArrayOfArrays<Mat4> &data,
479  const UT_StringRef &data_name );
480  /// @}
481 
482 private:
483  /// @{ Helper methods and templates for managing the buffers.
484  template<typename T>
485  bool retrieveBuffer(const UT_StringRef &data_name);
486 
487  template<typename T>
488  bool retrieveSclrArrayBuffer(const UT_StringRef &data_name);
489  template<typename T>
490  bool retrieveVecArrayBuffer(const UT_StringRef &data_name);
491  bool retrieveStrArrayBuffer(const UT_StringRef &data_name);
492  bool retrieveDictArrayBuffer(const UT_StringRef &data_name);
493  /// @}
494 
495 private:
496  /// Data buffers from which to retrieve the data.
497  const CVEX_Data &myData;
498 };
499 
502 
503 
504 #endif
CVEX_InOutData()
Creates a holder for the data buffers.
Definition: CVEX_Data.h:185
bool isVarying(const UT_StringRef &name) const
Definition: CVEX_Data.h:290
Definition: ImathVec.h:32
Definition: ImathQuat.h:42
#define DECLARE_CVEX_DATA_TYPES
Definition: CVEX_Data.h:215
GLboolean * data
Definition: glcorearb.h:131
int64 exint
Definition: SYS_Types.h:125
Precision-dependent types of CVEX data.
Definition: CVEX_Data.h:201
CVEX_Data & getOutputData()
Accessors.
Definition: CVEX_Data.h:189
VEXmat3< PREC > Mat3
Definition: CVEX_Data.h:210
typename VEX_PrecisionResolver< P >::vec3_type VEXvec3
Definition: VEX_PodTypes.h:70
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
VEXint< PREC > Int
Definition: CVEX_Data.h:204
A class representing a VEX value.
Definition: CVEX_Value.h:60
const CVEX_Data & getInputData() const
Accessors.
Definition: CVEX_Data.h:188
bool isVarying(const UT_StringRef &name) const
Definition: CVEX_Data.h:427
typename VEX_PrecisionResolver< P >::quat_type VEXquaternion
Definition: VEX_PodTypes.h:75
typename VEX_PrecisionResolver< P >::float_type VEXfloat
Definition: VEX_PodTypes.h:67
CVEX_Data & getInputData()
Accessors.
Definition: CVEX_Data.h:187
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
typename VEX_PrecisionResolver< P >::mat4_type VEXmat4
Definition: VEX_PodTypes.h:74
GLuint const GLchar * name
Definition: glcorearb.h:786
VEXfloat< PREC > Float
Definition: CVEX_Data.h:205
CVEX_Type
The CVEX_Type enum defines the VEX types available to CVEX.
Definition: CVEX_Value.h:29
VEXmat2< PREC > Mat2
Definition: CVEX_Data.h:209
UT_PackedArrayOfArrays< T > * addArrayDataBuffer(const UT_StringRef &name, CVEX_Type type)
Definition: CVEX_Data.h:158
typename VEX_PrecisionResolver< P >::mat2_type VEXmat2
Definition: VEX_PodTypes.h:72
UT_Array< T > * addDataBuffer(const UT_StringRef &name, CVEX_Type type)
Definition: CVEX_Data.h:151
typename VEX_PrecisionResolver< P >::vec2_type VEXvec2
Definition: VEX_PodTypes.h:69
Definition: ImathVec.h:31
#define CVEX_API
Definition: CVEX_API.h:12
typename VEX_PrecisionResolver< P >::vec4_type VEXvec4
Definition: VEX_PodTypes.h:71
UT_Array< T > * findDataBuffer(const UT_StringRef &name) const
Definition: CVEX_Data.h:165
typename VEX_PrecisionResolver< P >::int_type VEXint
Definition: VEX_PodTypes.h:68
Definition: core.h:1131
ImageBuf OIIO_API add(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
Definition: ImathVec.h:33
type
Definition: core.h:1059
typename VEX_PrecisionResolver< P >::mat3_type VEXmat3
Definition: VEX_PodTypes.h:73
const CVEX_Data & getOutputData() const
Accessors.
Definition: CVEX_Data.h:190
UT_PackedArrayOfArrays< T > * findArrayDataBuffer(const UT_StringRef &name) const
Definition: CVEX_Data.h:172
Definition: format.h:895
VEXmat4< PREC > Mat4
Definition: CVEX_Data.h:211
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
Definition: core.h:2089
bool contains(const key_type &key) const
Returns true if a value with the key is contained in the map.
Definition: UT_Map.h:159