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