HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GT_VtArray.h
Go to the documentation of this file.
1 //
2 // Copyright 2017 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef _GUSD_GT_VTARRAY_H_
25 #define _GUSD_GT_VTARRAY_H_
26 
27 #include <GT/GT_DataArray.h>
28 #include <GT/GT_DANumeric.h>
29 #include <UT/UT_XXHash.h>
30 #include <SYS/SYS_Compiler.h>
31 #include <SYS/SYS_Math.h>
32 
33 #include "pxr/pxr.h"
34 #include "pxr/base/vt/array.h"
35 
36 #include "gusd/UT_TypeTraits.h"
37 #include "gusd/GT_Utils.h"
38 
40 
41 /// GT_DataArray implementation that wraps a VtArray.
42 ///
43 /// This allows, in some cases, for arrays read in from USD to be
44 /// pushed into GT prims without having to incur copying.
45 /// Example:
46 /// \code
47 /// VtArray<int> valsFromUSD;
48 /// GT_DataArrayHandle hnd(new GusdGT_VtArray<int>(valsFromUSD));
49 /// \endcode
50 ///
51 /// These arrays are designed to be read-only.
52 /// If you need to make edits, use the following pattern:
53 ///
54 /// \code
55 /// GusdGT_VtArray<int> srcData;
56 /// // swap data into tmp array, modify.
57 /// VtArray<int> tmp;
58 /// srcData.swap(tmp);
59 /// tmp[10] = 37;
60 /// // swap data back into place.
61 /// srcData.swap(tmp);
62 /// \endcode
63 ///
64 /// Note that this kind of swapping trick does *not* require the
65 /// full array to be copied; only the internal references are swapped.
66 template <class T>
68 {
69 public:
70  SYS_STATIC_ASSERT(GusdIsPodTuple<T>());
71 
73  using ValueType = T;
76 
77  static const int tupleSize = GusdGetTupleSize<T>();
78  static const GT_Storage storage =
80 
83 
84  ~GusdGT_VtArray() override = default;
85 
86  const char* className() const override { return "GusdGT_VtArray"; }
87 
88  const T& operator()(GT_Offset o) const
89  {
90  UT_ASSERT_P(o >= 0 && o <= _size);
91  return reinterpret_cast<T*>(_data)[o];
92  }
93 
94  PODType operator()(GT_Offset o, int idx) const
95  { return getT<PODType>(o, idx); }
96 
97  const ArrayType& operator*() const { return _array; }
98 
99  const PODType* data() const { return _data; }
100  const void * getBackingData() const override { return _data; }
101 
102  /// Swap our array contents with another array.
103  void swap(ArrayType& o);
104 
105  SYS_HashType hashRange(exint b, exint e) const override
106  {
107  return UTxxhash64(_data+b*tupleSize, sizeof(PODType)*tupleSize*(e-b));
108  }
109  bool isEqual(const GT_DataArray &src) const override
110  {
111  if (&src == this)
112  return true;
113  if (src.entries() != _size)
114  return false;
115  if (src.getTupleSize() != tupleSize)
116  return false;
117  if (src.getStorage() != storage)
118  return false;
119  const auto *other = dynamic_cast<const This *>(&src);
120  if (!other)
121  return GT_DataArray::isEqual(src);
122  if (_data == other->_data)
123  return true;
124  // If we use std::equal and the arrays have matching Nan's, the
125  // std::equal comparison will fail while memcmp will succeed.
126  return !::memcmp(_data, other->_data, sizeof(PODType)*tupleSize*_size);
127  }
128 
129  GT_DataArrayHandle harden() const override;
130 
131  const PODType* getData(GT_Offset o) const
132  {
133  UT_ASSERT_P(o >= 0 && o <= _size);
134  return _data + o*tupleSize;
135  }
136 
137  /// Access to individual elements as given POD type.
138  /// For performance, this is preferred to the virtual getXX() methods.
139  template <typename PODT>
140  PODT getT(GT_Offset o, int idx=0) const;
141 
142  /// Get access to a raw array of data.
143  /// If @a OTHERPODT is not the same as the array's underlying type,
144  /// the raw array will be stored in the given @a buf.
145  template <typename PODT>
146  const PODT* getArrayT(GT_DataArrayHandle& buf) const;
147 
148  /// Extract a tuple into @a dst
149  template <typename PODT>
150  void importT(GT_Offset o, PODT* dst, int tsize=-1) const;
151 
152  /// Extract data for entire array into @a dst.
153  template <typename PODT>
155  int tsize=-1, int stride=-1) const;
156 
157  /// Extended form of array extraction that supports repeated elems.
158  template <typename PODT>
159  void extendedFillT(PODT* dst, GT_Offset start,
160  GT_Size length, int tsize=-1,
161  int nrepeats=1, int stride=-1) const;
162 
163  GT_Storage getStorage() const override { return storage; }
164  GT_Size getTupleSize() const override { return tupleSize; }
165  GT_Size entries() const override { return _size; }
166  GT_Type getTypeInfo() const override { return _type; }
167  int64 getMemoryUsage() const override
168  { return sizeof(*this) + sizeof(T)*_size; }
169 
170  // Type-specific virtual getters.
171 
172 #define _DECL_GETTERS(suffix,podt) \
173 public: \
174  virtual podt SYS_CONCAT(get,suffix)(GT_Offset o, \
175  int idx=0) const override \
176  { return getT<podt>(o, idx); } \
177  \
178  virtual const podt* SYS_CONCAT(get,SYS_CONCAT(suffix,Array)) \
179  (GT_DataArrayHandle& buf) const override \
180  { return getArrayT<podt>(buf); } \
181  \
182 protected: \
183  virtual void doImport(GT_Offset o, podt* dst, \
184  GT_Size tsize) const override \
185  { importT(o, dst, tsize); } \
186  \
187  virtual void doFillArray(podt* dst, GT_Offset start, \
188  GT_Size length, int tsize, \
189  int stride) const override \
190  { fillArrayT(dst, start, length, \
191  tsize, stride); } \
192  \
193  virtual void extendedFill(podt* dst, GT_Offset start, \
194  GT_Size length, int tsize, \
195  int nrepeats, \
196  int stride=-1) const override \
197  { extendedFillT(dst, start, length, \
198  tsize, nrepeats, stride); } \
199  /* end of macro */
200 
201  _DECL_GETTERS(I8, int8);
202  _DECL_GETTERS(I16, int16);
203  _DECL_GETTERS(U8, uint8);
204  _DECL_GETTERS(I32, int32);
205  _DECL_GETTERS(I64, int64);
206  _DECL_GETTERS(F16, fpreal16);
207  _DECL_GETTERS(F32, fpreal32);
208  _DECL_GETTERS(F64, fpreal64);
209 
210 #undef _DECL_GETTER
211 
212 protected:
213  /// Update our @a _data member to point at the array data.
214  /// This must be called after any operation that changes
215  /// the contents of @a _array.
216  void _UpdateDataPointer(bool makeUnique);
217 
218 private:
219  // No string support. For strings, use GusdGT_VtStringArray.
220  GT_String getS(GT_Offset, int) const override { return nullptr; }
221  GT_Size getStringIndexCount() const override { return -1; }
222  GT_Offset getStringIndex(GT_Offset,int) const override { return -1; }
223  void getIndexedStrings(UT_StringArray&,
224  UT_IntArray&) const override {}
225  // No dictionary support.
226  GT_Size getDictIndexCount() const override { return -1; }
227  GT_Offset getDictIndex(GT_Offset, int) const override { return -1; }
228  void getIndexedDicts(UT_Array<UT_OptionsHolder>&,
229  UT_IntArray&) const override {}
230 
231 protected:
233  const GT_Type _type;
235  const PODType* _data; /// Raw pointer to the underlying data.
236  /// Held separately as an optimization.
237 };
238 
239 
240 template <class T>
242  : _array(array), _type(type), _size(array.size())
243 {
244  _UpdateDataPointer(false);
245 }
246 
247 
248 template <class T>
250  : _type(type), _size(0), _data(nullptr)
251 {}
252 
253 
254 template <class T>
255 void
257 {
258  // Access a non-const pointer to make the array unique.
259  _data = reinterpret_cast<const PODType*>(
260  makeUnique ? _array.data() : _array.cdata());
261  UT_ASSERT(_size == 0 || _data != nullptr);
262 }
263 
264 
265 template <class T>
266 void
268 {
269  _array.swap(o);
270  _size = _array.size();
271  _UpdateDataPointer(false);
272 }
273 
274 
275 template <class T>
278 {
279  This* copy = new This(_array, _type);
280  copy->_UpdateDataPointer(true);
281  return GT_DataArrayHandle(copy);
282 }
283 
284 
285 template <class T>
286 template <typename PODT>
287 PODT
289 {
290  UT_ASSERT_P(o >= 0 && o < _size);
291  UT_ASSERT_P(idx >= 0 && idx < tupleSize);
292  return static_cast<PODT>(_data[tupleSize*o + idx]);
293 }
294 
295 
296 template <class T>
297 template <typename PODT>
298 const PODT*
300 {
302  return reinterpret_cast<const PODT*>(_data);
303 
304  using _GTArrayType = GT_DANumeric<PODT>;
305 
306  _GTArrayType* tmpArray = new _GTArrayType(_size, tupleSize, _type);
307  fillArrayT(tmpArray->data(), 0, _size, tupleSize);
308  buf = tmpArray;
309  return tmpArray->data();
310 }
311 
312 
313 template <class T>
314 template <typename PODT>
315 void
316 GusdGT_VtArray<T>::importT(GT_Offset o, PODT* dst, int tsize) const
317 {
318  tsize = tsize < 1 ? tupleSize : SYSmin(tsize, tupleSize);
319  const PODType* src = getData(o);
320  if( src )
321  {
322  for(int i = 0; i < tsize; ++i)
323  dst[i] = static_cast<PODT>(src[i]);
324  }
325 }
326 
327 
328 template <class T>
329 template <typename PODT>
330 void
332  int tsize, int stride) const
333 {
334  if(_size == 0)
335  return;
336  if(tsize < 1)
337  tsize = tupleSize;
338  // Stride is >= the unclamped tuple size.
339  // This seems wrong, but is consistent with GT_DANumeric.
340  stride = SYSmax(stride, tsize);
341  tsize = SYSmin(tsize, tupleSize);
343  tsize == tupleSize && stride == tupleSize) {
344  // direct copy is safe
345  memcpy(dst, getData(start), length*tsize*sizeof(PODT));
346  } else {
347  const PODType* src = getData(start*tupleSize);
348  for(GT_Offset i = 0; i < length; ++i, src += tupleSize, dst += stride) {
349  for(int j = 0; j < tsize; ++j)
350  dst[j] = static_cast<PODT>(src[j]);
351  }
352  }
353 }
354 
355 
356 template <class T>
357 template <typename PODT>
358 void
360  GT_Size length, int tsize,
361  int nrepeats, int stride) const
362 {
363  if(nrepeats == 1)
364  return fillArrayT(dst, start, length, tsize, stride);
365  if(_size == 0)
366  return;
367  if(tsize < 1)
368  tsize = tupleSize;
369  stride = SYSmax(stride, tsize);
370  tsize = SYSmin(tsize, tupleSize);
371 
372  const PODType* src = getData(start*tupleSize);
373  for(GT_Offset i = 0; i < length; ++i, src += tupleSize) {
374  for(int r = 0; r < nrepeats; ++r, dst += stride) {
375  for(int j = 0; j < tsize; ++j)
376  dst[j] = static_cast<PODT>(src[j]);
377  }
378  }
379 }
380 
382 
383 #endif /*_GUSD_GT_VTARRAY_H_*/
#define SYSmax(a, b)
Definition: SYS_Math.h:1570
GT_Storage
Definition: GT_Types.h:19
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
const void * getBackingData() const override
Definition: GT_VtArray.h:100
int int32
Definition: SYS_Types.h:39
const T & operator()(GT_Offset o) const
Definition: GT_VtArray.h:88
getFileOption("OpenEXR:storage") storage
Definition: HDK_Image.dox:276
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
GLuint start
Definition: glcorearb.h:475
typename GusdPodTupleTraits< T >::ValueType PODType
Definition: GT_VtArray.h:75
SYS_FORCE_INLINE UT_API XXH64_hash_t UTxxhash64(const void *data, size_t len)
Definition: UT_XXHash.h:6215
GT_Type getTypeInfo() const override
Return "type" information for the data. This defaults to GT_TYPE_NONE.
Definition: GT_VtArray.h:166
_DECL_GETTERS(I8, int8)
int64 exint
Definition: SYS_Types.h:125
GT_Type
Definition: GT_Types.h:36
std::size_t SYS_HashType
Define the type for hash values.
Definition: SYS_Hash.h:19
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
float fpreal32
Definition: SYS_Types.h:200
GT_DataArrayHandle harden() const override
Create a "hardened" version of the array.
Definition: GT_VtArray.h:277
const PODType * getData(GT_Offset o) const
Definition: GT_VtArray.h:131
double fpreal64
Definition: SYS_Types.h:201
unsigned char uint8
Definition: SYS_Types.h:36
GT_Size getTupleSize() const override
Number of elements for each array element.
Definition: GT_VtArray.h:164
static const GT_Storage storage
Definition: GT_VtArray.h:78
ArrayType _array
Definition: GT_VtArray.h:232
const PODT * getArrayT(GT_DataArrayHandle &buf) const
Definition: GT_VtArray.h:299
GT_Size _size
Definition: GT_VtArray.h:234
Abstract data class for an array of float, int or string data.
Definition: GT_DataArray.h:40
PODType operator()(GT_Offset o, int idx) const
Definition: GT_VtArray.h:94
UT_IntrusivePtr< GT_DataArray > GT_DataArrayHandle
Definition: GT_DataArray.h:32
void extendedFillT(PODT *dst, GT_Offset start, GT_Size length, int tsize=-1, int nrepeats=1, int stride=-1) const
Extended form of array extraction that supports repeated elems.
Definition: GT_VtArray.h:359
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
void importT(GT_Offset o, PODT *dst, int tsize=-1) const
Extract a tuple into dst.
Definition: GT_VtArray.h:316
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:872
int64 GT_Offset
Definition: GT_Types.h:129
long long int64
Definition: SYS_Types.h:116
void swap(ArrayType &o)
Swap our array contents with another array.
Definition: GT_VtArray.h:267
VtArray< T > ArrayType
Definition: GT_VtArray.h:74
static const int tupleSize
Definition: GT_VtArray.h:77
signed char int8
Definition: SYS_Types.h:35
Definition: types.h:170
SYS_STATIC_ASSERT(GusdIsPodTuple< T >())
void _UpdateDataPointer(bool makeUnique)
Definition: GT_VtArray.h:256
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
const PODType * data() const
Definition: GT_VtArray.h:99
GT_Storage getStorage() const override
Type of data stored in the array.
Definition: GT_VtArray.h:163
const GT_Type _type
Definition: GT_VtArray.h:233
virtual GT_Size entries() const =0
Number of entries in the array.
GLint j
Definition: glad.h:2733
int64 GT_Size
Definition: GT_Types.h:128
GLsizeiptr size
Definition: glcorearb.h:664
GLenum GLenum dst
Definition: glcorearb.h:1793
GusdGT_VtArray(const ArrayType &array, GT_Type type=GT_TYPE_NONE)
Definition: GT_VtArray.h:241
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1432
short int16
Definition: SYS_Types.h:37
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
virtual GT_Storage getStorage() const =0
Type of data stored in the array.
An array of numeric values (int32, int64, fpreal16, fpreal32, fpreal64)
Definition: GT_DANumeric.h:23
int64 getMemoryUsage() const override
Definition: GT_VtArray.h:167
const ArrayType & operator*() const
Definition: GT_VtArray.h:97
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
SYS_HashType hashRange(exint b, exint e) const override
Definition: GT_VtArray.h:105
GLboolean r
Definition: glcorearb.h:1222
const char * className() const override
Definition: GT_VtArray.h:86
virtual GT_Size getTupleSize() const =0
Number of elements for each array element.
#define SYSmin(a, b)
Definition: SYS_Math.h:1571
type
Definition: core.h:1059
GT_Size entries() const override
Number of entries in the array.
Definition: GT_VtArray.h:165
virtual bool isEqual(const GT_DataArray &src) const
Compare whether two data arrays are equal.
bool isEqual(const GT_DataArray &src) const override
Compare whether two data arrays are equal.
Definition: GT_VtArray.h:109
void fillArrayT(PODT *dst, GT_Offset start, GT_Size length, int tsize=-1, int stride=-1) const
Extract data for entire array into dst.
Definition: GT_VtArray.h:331
~GusdGT_VtArray() override=default
PODT getT(GT_Offset o, int idx=0) const
Definition: GT_VtArray.h:288
const PODType * _data
Definition: GT_VtArray.h:235
GLenum src
Definition: glcorearb.h:1793