All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GT_VtArray.h
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 <SYS/SYS_Compiler.h>
30 #include <SYS/SYS_Version.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 
39 PXR_NAMESPACE_OPEN_SCOPE
40 
66 template <class T>
67 class GusdGT_VtArray : public GT_DataArray
68 {
69 public:
70  SYS_STATIC_ASSERT(GusdIsPodTuple<T>());
71 
72  using This = GusdGT_VtArray<T>;
73  using ValueType = T;
74  using ArrayType = VtArray<T>;
75  using PODType = typename GusdPodTupleTraits<T>::ValueType;
76 
77  static const int tupleSize = GusdGetTupleSize<T>();
78  static const GT_Storage storage =
80 
81  GusdGT_VtArray(const ArrayType& array, GT_Type type=GT_TYPE_NONE);
82  GusdGT_VtArray(GT_Type type=GT_TYPE_NONE);
83 
84  ~GusdGT_VtArray() override = default;
85 
86  virtual const char* className() const { 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 
102  void swap(ArrayType& o);
103 
104  virtual GT_DataArrayHandle harden() const;
105 
106  const PODType* getData(GT_Offset o) const
107  {
108  UT_ASSERT_P(o >= 0 && o <= _size);
109  return _data + o*tupleSize;
110  }
111 
114  template <typename PODT>
115  PODT getT(GT_Offset o, int idx=0) const;
116 
120  template <typename PODT>
121  const PODT* getArrayT(GT_DataArrayHandle& buf) const;
122 
124  template <typename PODT>
125  void importT(GT_Offset o, PODT* dst, int tsize=-1) const;
126 
128  template <typename PODT>
129  void fillArrayT(PODT* dst, GT_Offset start, GT_Size length,
130  int tsize=-1, int stride=-1) const;
131 
133  template <typename PODT>
134  void extendedFillT(PODT* dst, GT_Offset start,
135  GT_Size length, int tsize=-1,
136  int nrepeats=1, int stride=-1) const;
137 
138  virtual GT_Storage getStorage() const { return storage; }
139  virtual GT_Size getTupleSize() const { return tupleSize; }
140  virtual GT_Size entries() const { return _size; }
141  virtual GT_Type getTypeInfo() const { return _type; }
142  virtual int64 getMemoryUsage() const
143  { return sizeof(*this) + sizeof(T)*_size; }
144 
145  // Type-specific virtual getters.
146 
147 #define _DECL_GETTERS(suffix,podt) \
148 public: \
149  virtual podt SYS_CONCAT(get,suffix)(GT_Offset o, int idx=0) const\
150  { return getT<podt>(o, idx); } \
151  \
152  virtual const podt* SYS_CONCAT(get,SYS_CONCAT(suffix,Array)) \
153  (GT_DataArrayHandle& buf) const \
154  { return getArrayT<podt>(buf); } \
155  \
156 protected: \
157  virtual void doImport(GT_Offset o, podt* dst, GT_Size tsize) const\
158  { importT(o, dst, tsize); } \
159  \
160  virtual void doFillArray(podt* dst, GT_Offset start, GT_Size length,\
161  int tsize, int stride) const \
162  { fillArrayT(dst, start, length, tsize, stride); }\
163  \
164  virtual void extendedFill(podt* dst, GT_Offset start, \
165  GT_Size length, int tsize, \
166  int nrepeats, int stride=-1) const \
167  { extendedFillT(dst, start, length, \
168  tsize, nrepeats, stride); }
169 
170 #if SYS_VERSION_FULL_INT >= 0x10050000
171  _DECL_GETTERS(I8, int8);
172  _DECL_GETTERS(I16, int16);
173 #endif
174  _DECL_GETTERS(U8, uint8);
175  _DECL_GETTERS(I32, int32);
176  _DECL_GETTERS(I64, int64);
177  _DECL_GETTERS(F16, fpreal16);
178  _DECL_GETTERS(F32, fpreal32);
179  _DECL_GETTERS(F64, fpreal64);
180 
181 #undef _DECL_GETTER
182 
183 protected:
187  void _UpdateDataPointer(bool makeUnique);
188 
189 private:
190  // No string support. For strings, use GusdGT_VtStringArray.
191  virtual GT_String getS(GT_Offset, int) const { return nullptr; }
192  virtual GT_Size getStringIndexCount() const { return -1; }
193  virtual GT_Offset getStringIndex(GT_Offset,int) const { return -1; }
194  virtual void getIndexedStrings(UT_StringArray&,
195  UT_IntArray&) const {}
196 
197 protected:
198  ArrayType _array;
199  const GT_Type _type;
200  GT_Size _size;
201  const PODType* _data;
202 };
204 
205 
206 template <class T>
207 GusdGT_VtArray<T>::GusdGT_VtArray(const ArrayType& array, GT_Type type)
208  : _array(array), _type(type), _size(array.size())
209 {
210  _UpdateDataPointer(false);
211 }
212 
213 
214 template <class T>
216  : _type(type), _size(0), _data(nullptr)
217 {}
218 
219 
220 template <class T>
221 void
223 {
224  // Access a non-const pointer to make the array unique.
225  _data = reinterpret_cast<const PODType*>(
226  makeUnique ? _array.data() : _array.cdata());
227  UT_ASSERT(_size == 0 || _data != nullptr);
228 }
229 
230 
231 template <class T>
232 void
234 {
235  _array.swap(o);
236  _size = _array.GetSize();
237  _UpdateDataPointer(false);
238 }
239 
240 
241 template <class T>
242 GT_DataArrayHandle
244 {
245  This* copy = new This(_array, _type);
246  copy->_UpdateDataPointer(true);
247  return GT_DataArrayHandle(copy);
248 }
249 
250 
251 template <class T>
252 template <typename PODT>
253 PODT
254 GusdGT_VtArray<T>::getT(GT_Offset o, int idx) const
255 {
256  UT_ASSERT_P(o >= 0 && o < _size);
257  UT_ASSERT_P(idx >= 0 && idx < tupleSize);
258  return static_cast<PODT>(_data[tupleSize*o + idx]);
259 }
260 
261 
262 template <class T>
263 template <typename PODT>
264 const PODT*
265 GusdGT_VtArray<T>::getArrayT(GT_DataArrayHandle& buf) const
266 {
267  if(SYS_IsSame<PODType,PODT>::value)
268  return reinterpret_cast<const PODT*>(_data);
269 
270 #if SYS_VERSION_FULL_INT < 0x10050000
271  using _GTArrayType =
272  GT_DANumeric<PODT, GusdGT_Utils::StorageByType<PODType>::value>;
273 #else
274  using _GTArrayType = GT_DANumeric<PODT>;
275 #endif
276 
277  _GTArrayType* tmpArray = new _GTArrayType(_size, tupleSize, _type);
278  fillArrayT(tmpArray->data(), 0, _size, tupleSize);
279  buf = tmpArray;
280  return tmpArray->data();
281 }
282 
283 
284 template <class T>
285 template <typename PODT>
286 void
287 GusdGT_VtArray<T>::importT(GT_Offset o, PODT* dst, int tsize) const
288 {
289  tsize = tsize < 1 ? tupleSize : SYSmin(tsize, tupleSize);
290  const PODType* src = getData(o);
291  if( src )
292  {
293  for(int i = 0; i < tsize; ++i)
294  dst[i] = static_cast<PODT>(src[i]);
295  }
296 }
297 
298 
299 template <class T>
300 template <typename PODT>
301 void
302 GusdGT_VtArray<T>::fillArrayT(PODT* dst, GT_Offset start, GT_Size length,
303  int tsize, int stride) const
304 {
305  if(_size == 0)
306  return;
307  if(tsize < 1)
308  tsize = tupleSize;
309  // Stride is >= the unclamped tuple size.
310  // This seems wrong, but is consistent with GT_DANumeric.
311  stride = SYSmax(stride, tsize);
312  tsize = SYSmin(tsize, tupleSize);
313  if(SYS_IsSame<PODT,PODType>::value &&
314  tsize == tupleSize && stride == tupleSize) {
315  // direct copy is safe
316  memcpy(dst, getData(start), length*tsize*sizeof(PODT));
317  } else {
318  const PODType* src = getData(start*tupleSize);
319  for(GT_Offset i = 0; i < length; ++i, src += tupleSize, dst += stride) {
320  for(int j = 0; j < tsize; ++j)
321  dst[j] = static_cast<PODT>(src[j]);
322  }
323  }
324 }
325 
326 
327 template <class T>
328 template <typename PODT>
329 void
330 GusdGT_VtArray<T>::extendedFillT(PODT* dst, GT_Offset start,
331  GT_Size length, int tsize,
332  int nrepeats, int stride) const
333 {
334  if(nrepeats == 1)
335  return fillArrayT(dst, start, length, tsize, stride);
336  if(_size == 0)
337  return;
338  if(tsize < 1)
339  tsize = tupleSize;
340  stride = SYSmax(stride, tsize);
341  tsize = SYSmin(tsize, tupleSize);
342 
343  const PODType* src = getData(start*tupleSize);
344  for(GT_Offset i = 0; i < length; ++i, src += tupleSize) {
345  for(int r = 0; r < nrepeats; ++r, dst += stride) {
346  for(int j = 0; j < tsize; ++j)
347  dst[j] = static_cast<PODT>(src[j]);
348  }
349  }
350 }
351 
352 PXR_NAMESPACE_CLOSE_SCOPE
353 
354 #endif /*_GUSD_GT_VTARRAY_H_*/
void _UpdateDataPointer(bool makeUnique)
Update our _data member to point at the array data.
Definition: GT_VtArray.h:222
void swap(ArrayType &o)
Swap our array contents with another array.
Definition: GT_VtArray.h:233
void importT(GT_Offset o, PODT *dst, int tsize=-1) const
Extract a tuple into dst.
Definition: GT_VtArray.h:287
PODT getT(GT_Offset o, int idx=0) const
Access to individual elements as given POD type.
Definition: GT_VtArray.h:254
const PODT * getArrayT(GT_DataArrayHandle &buf) const
Get access to a raw array of data.
Definition: GT_VtArray.h:265
Struct for querying storage by POD type.
Definition: GT_Utils.h:167
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:330
GT_DataArray implementation that wraps a VtArray.
Definition: GT_VtArray.h:67
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:302