All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
internalFromVt.h
1 //
2 // Copyright 2018 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 #include "pxr/pxr.h"
25 
26 #include <memory>
27 #include <type_traits>
28 
29 #include <FnAttribute/FnAttribute.h>
30 #include <FnAttribute/FnDataBuilder.h>
31 
32 #include "pxr/base/tf/envSetting.h"
33 #include "pxr/base/vt/array.h"
34 
35 #include "vtKatana/internalTraits.h"
36 
37 PXR_NAMESPACE_OPEN_SCOPE
38 
39 namespace VtKatana_Internal {
40 
43 template <typename ElementType,
44  typename = typename std::enable_if<
47  typedef
48  typename VtKatana_GetNumericScalarType<ElementType>::type ScalarType;
49  const VtArray<ElementType> _array;
50 
51 public:
52  explicit VtKatana_Context(const VtArray<ElementType>& array)
53  : _array(array) {}
54 
55  const ScalarType* GetData() { return VtKatana_GetScalarPtr(_array); }
56 
57  static void Free(void* self) {
58  auto context = static_cast<VtKatana_Context*>(self);
59  delete context;
60  }
61 };
62 
65 template <typename ElementType,
66  typename = typename std::enable_if<
69  typedef
70  typename VtKatana_GetNumericScalarType<ElementType>::type ScalarType;
71  const std::vector<VtArray<ElementType>> _arrays;
72 
73 public:
74  explicit VtKatana_MultiContext(
75  const typename std::vector<VtArray<ElementType>>& arrays)
76  : _arrays(arrays) {}
77 
78  std::vector<const ScalarType*> GetData() {
79  std::vector<const ScalarType*> ptrs(_arrays.size());
80  std::transform(_arrays.cbegin(), _arrays.cend(), ptrs.begin(),
81  [](const VtArray<ElementType>& array) {
82  return VtKatana_GetScalarPtr(array);
83  });
84  return ptrs;
85  }
86  static void Free(void* self) {
87  auto context = static_cast<VtKatana_MultiContext*>(self);
88  delete context;
89  }
90 };
91 
94 template <typename StringType,
95  typename = typename std::enable_if<
97 std::vector<const char*> VtKatana_ExtractStringVec(
98  const VtArray<StringType>& array) {
99  std::vector<const char*> result(array.size());
100  std::transform(
101  array.begin(), array.end(), result.begin(),
102  [](const StringType& element) { return VtKatana_GetText(element); });
103  return result;
104 }
105 
107 template <typename ElementType>
109  typedef typename VtKatana_GetKatanaAttrType<ElementType>::type AttrType;
110  typedef
111  typename VtKatana_GetKatanaAttrValueType<ElementType>::type ValueType;
112  typedef typename AttrType::array_type SampleType;
113  typedef typename FnKat::DataBuilder<AttrType> BuilderType;
114 
115 public:
116  // ZERO COPY SPECIALIZATIONS
117 
120  template <typename T = ElementType>
121  static typename std::enable_if<VtKatana_IsNumericCastable<T>::value,
122  AttrType>::type
123  ZeroCopy(const VtArray<T>& array) {
124  typedef VtKatana_Context<T> ZeroCopyContext;
125  TF_VERIFY(!array.empty());
126  size_t size = array.size() * VtKatana_GetNumericTupleSize<T>::value;
127  std::unique_ptr<ZeroCopyContext> ptr(new ZeroCopyContext(array));
128  auto data = ptr->GetData();
129  AttrType attr(data, size, VtKatana_GetNumericTupleSize<T>::value,
130  ptr.release(), ZeroCopyContext::Free);
131  return attr;
132  }
133 
136  template <typename T = ElementType>
137  static typename std::enable_if<VtKatana_IsNumericCastable<T>::value,
138  AttrType>::type
139  ZeroCopy(const std::vector<float>& times,
140  const std::vector<VtArray<T>>& values) {
141  TF_VERIFY(times.size() == values.size() && !times.empty() &&
142  !values.front().empty());
143  typedef VtKatana_MultiContext<T> ZeroCopyContext;
144  size_t size =
145  values.front().size() * VtKatana_GetNumericTupleSize<T>::value;
146  std::unique_ptr<ZeroCopyContext> context(new ZeroCopyContext(values));
147  auto data = context->GetData();
148  AttrType attr(times.data(), times.size(), data.data(), size,
149  VtKatana_GetNumericTupleSize<T>::value, context.release(),
150  ZeroCopyContext::Free);
151  return attr;
152  }
153 
154  // COPY INTERMEDIATE TO STD::VECTOR IMPLEMENTATIONS
155 
159  template <typename T = ElementType>
160  static typename std::enable_if<VtKatana_IsNumeric<T>::value,
161  std::vector<ValueType>>::type
162  CopyIntermediate(const VtArray<T>& array) {
163  typedef typename VtKatana_GetNumericScalarType<ElementType>::type
164  ScalarType;
165  size_t size = array.size() * VtKatana_GetNumericTupleSize<T>::value;
166  auto dataBegin = VtKatana_GetScalarPtr(array);
167  auto dataEnd = dataBegin + size;
168  std::vector<ValueType> intermediate(dataBegin, dataEnd);
169  return intermediate;
170  }
171 
175  template <typename T = ElementType>
176  static typename std::enable_if<VtKatana_HoldsString<T>::value,
177  std::vector<ValueType>>::type
178  CopyIntermediate(const VtArray<T>& array) {
179  std::vector<std::string> intermediate(array.size());
180  std::transform(array.begin(), array.end(), intermediate.begin(),
181  [](const T& element) {
182  return std::string(VtKatana_GetText(element));
183  });
184  return intermediate;
185  }
186 
190  template <typename T = ElementType>
191  static typename std::enable_if<VtKatana_IsString<T>::value,
192  std::vector<ValueType>>::type
193  CopyIntermediate(const VtArray<T>& array) {
194  std::vector<std::string> intermediate(array.begin(), array.end());
195  return intermediate;
196  }
197 
198  // COPY FROM VTARRAY => KATANA ATTRIBUTE UTILITY
199 
202  template <typename T = ElementType>
203  static typename std::enable_if<VtKatana_IsNumericCastable<T>::value,
204  AttrType>::type
205  Copy(const VtArray<T>& array) {
206  typedef typename VtKatana_GetNumericScalarType<ElementType>::type
207  ScalarType;
208  const ScalarType* data = VtKatana_GetScalarPtr(array);
209  size_t size = array.size() * VtKatana_GetNumericTupleSize<T>::value;
210  AttrType attr(data, size, VtKatana_GetNumericTupleSize<T>::value);
211  return attr;
212  }
213 
217  template <typename T = ElementType>
218  static typename std::enable_if<VtKatana_IsNumericCopyRequired<T>::value,
219  AttrType>::type
220  Copy(const VtArray<T>& array) {
221  auto intermediate = CopyIntermediate(array);
222  size_t size = intermediate.size();
223  auto data = intermediate.data();
224  return AttrType(data, size, VtKatana_GetNumericTupleSize<T>::value);
225  }
226 
230  template <typename T = ElementType>
231  static
232  typename std::enable_if<VtKatana_HoldsString<T>::value, AttrType>::type
233  Copy(const VtArray<T>& array) {
234  std::vector<const char*> intermediate =
235  VtKatana_ExtractStringVec(array);
236  size_t size = intermediate.size();
237  auto dataBegin = intermediate.data();
238  AttrType attr(dataBegin, size, 1);
239  return attr;
240  }
241 
243  template <typename T = ElementType>
244  static typename std::enable_if<VtKatana_IsString<T>::value, AttrType>::type
245  Copy(const VtArray<T>& array) {
246  AttrType attr(array.cdata(), array.size(), 1);
247  return attr;
248  }
249 
252  template <typename T = ElementType>
253  static typename std::enable_if<VtKatana_IsNumericCastable<T>::value,
254  AttrType>::type
255  Copy(const std::vector<float>& times,
256  const std::vector<VtArray<T>>& values) {
257  typedef typename VtKatana_GetNumericScalarType<ElementType>::type
258  ScalarType;
259  TF_VERIFY(times.size() == values.size() && !times.empty() &&
260  !values.front().empty());
261  size_t size =
262  values.front().size() * VtKatana_GetNumericTupleSize<T>::value;
263  std::vector<const ScalarType*> ptrs(values.size());
264  std::transform(values.cbegin(), values.cend(), ptrs.begin(),
265  [](const VtArray<T>& array) {
266  return VtKatana_GetScalarPtr(array);
267  });
268  AttrType attr(times.data(), times.size(), ptrs.data(), size,
270  return attr;
271  }
272 
275  template <typename T = ElementType>
276  static typename std::enable_if<VtKatana_IsOrHoldsString<T>::value,
277  AttrType>::type
278  Copy(const std::vector<float>& times,
279  const std::vector<VtArray<T>>& values) {
280  TF_VERIFY(times.size() == values.size() && !times.empty() &&
281  !values.front().empty());
282  size_t size = values.front().size();
283  std::vector<std::vector<const char*>> holders;
284  std::transform(values.begin(), values.end(),
285  std::back_inserter(holders),
286  [](const VtArray<T>& array) {
287  return VtKatana_ExtractStringVec(array);
288  });
289  std::vector<const char* const*> holdersHolder;
290  std::transform(holders.begin(), holders.end(),
291  std::back_inserter(holdersHolder),
292  [](const std::vector<const char*>& holder) {
293  return holder.data();
294  });
295  AttrType attr(times.data(), times.size(),
296  const_cast<const char***>(holdersHolder.data()), size, 1);
297  return attr;
298  }
299 
301  template <typename T = ElementType>
302  static typename std::enable_if<VtKatana_IsNumericCopyRequired<T>::value,
303  AttrType>::type
304  Copy(const std::vector<float>& times,
305  const typename std::vector<VtArray<T>>& values) {
306  BuilderType builder;
307  auto timesIt = times.begin();
308  for (const VtArray<T>& value : values) {
309  builder.set(CopyIntermediate(value), *timesIt);
310  ++timesIt;
311  }
312  return builder.build();
313  }
314 
318  template <typename T = ElementType>
319  static typename std::enable_if<VtKatana_IsNumericCopyRequired<T>::value,
320  AttrType>::type
321  MapInternal(const VtArray<T>& value) {
322  return Copy(value);
323  }
324 
329  template <typename T = ElementType>
330  static typename std::enable_if<VtKatana_IsOrHoldsString<T>::value,
331  AttrType>::type
332  MapInternal(const VtArray<T>& value) {
333  return Copy(value);
334  }
335 
339  template <typename T = ElementType>
340  static typename std::enable_if<VtKatana_IsNumericCastable<T>::value,
341  AttrType>::type
342  MapInternal(const VtArray<T>& value) {
343  static const bool zeroCopyEnabled =
344  TfGetEnvSetting(VTKATANA_ENABLE_ZERO_COPY_ARRAYS);
345  if (zeroCopyEnabled)
346  return ZeroCopy(value);
347  else
348  return Copy(value);
349  }
350 
354  template <typename T = ElementType>
355  static typename std::enable_if<VtKatana_IsNumericCopyRequired<T>::value,
356  AttrType>::type
357  MapInternalMultiple(const std::vector<float>& times,
358  const typename std::vector<VtArray<T>>& values) {
359  return Copy(times, values);
360  }
361 
366  template <typename T = ElementType>
367  static typename std::enable_if<VtKatana_IsOrHoldsString<T>::value,
368  AttrType>::type
369  MapInternalMultiple(const std::vector<float>& times,
370  const typename std::vector<VtArray<T>>& values) {
371  return Copy(times, values);
372  }
373 
377  template <typename T = ElementType>
378  static typename std::enable_if<VtKatana_IsNumericCastable<T>::value,
379  AttrType>::type
380  MapInternalMultiple(const std::vector<float>& times,
381  const typename std::vector<VtArray<T>>& values) {
382  static const bool zeroCopyEnabled =
383  TfGetEnvSetting(VTKATANA_ENABLE_ZERO_COPY_ARRAYS);
384  if (zeroCopyEnabled)
385  return ZeroCopy(times, values);
386  else
387  return Copy(times, values);
388  }
389 
391  template <typename T = ElementType>
392  static typename std::enable_if<VtKatana_IsOrHoldsString<T>::value,
393  AttrType>::type
394  CopyElement(const T& value) {
395  return AttrType(VtKatana_GetText<T>(value));
396  }
397 
399  template <typename T = ElementType>
400  static typename std::enable_if<VtKatana_IsNumericScalar<T>::value,
401  AttrType>::type
402  CopyElement(T value) {
403  return AttrType(value);
404  }
405 
407  template <typename T = ElementType>
408  static typename std::enable_if<VtKatana_IsNumericCastableTuple<T>::value,
409  AttrType>::type
410  CopyElement(const T& value) {
411  auto data = value.data();
413  return AttrType(data, size, size);
414  }
415 
417  template <typename T = ElementType>
418  static typename std::enable_if<VtKatana_IsNumericCopyRequiredTuple<T>::value,
419  AttrType>::type
420  CopyElement(const T& value) {
421  typedef typename VtKatana_GetNumericCopyTuplePeer<T>::type TupleCopyPeer;
422  static_assert(
423  std::is_same<typename VtKatana_GetNumericScalarType<T>::type,
424  GfHalf>::value, "");
427  TupleCopyPeer peer(value);
428  auto data = peer.data();
430  return AttrType(data, size, size);
431  }
432 };
433 }
434 
435 PXR_NAMESPACE_CLOSE_SCOPE
static std::enable_if< VtKatana_IsOrHoldsString< T >::value, AttrType >::type MapInternalMultiple(const std::vector< float > &times, const typename std::vector< VtArray< T >> &values)
Iternals of map for string types We haven&#39;t found signifcant zero copy performance improvements in pr...
static std::enable_if< VtKatana_IsNumericCastable< T >::value, AttrType >::type MapInternalMultiple(const std::vector< float > &times, const typename std::vector< VtArray< T >> &values)
Iternals of map for types that do not require an intermediate copy of values to construct an attribut...
static std::enable_if< VtKatana_IsNumericCastable< T >::value, AttrType >::type Copy(const VtArray< T > &array)
Utility for copying tuple types that don&#39;t require an intermediate copy (ie.
Gets the &#39;tuple size&#39; of T, or number of elements a numeric type contains.
pxr_half::half GfHalf
A 16-bit floating point data type.
Definition: half.h:42
T const & TfGetEnvSetting(TfEnvSetting< T > &setting)
Returns the value of the specified env setting, registered using TF_DEFINE_ENV_SETTING.
Definition: envSetting.h:158
iterator begin()
Return a non-const iterator to the start of the array.
Definition: array.h:345
static std::enable_if< VtKatana_IsString< T >::value, AttrType >::type Copy(const VtArray< T > &array)
Utility for copying std::string types.
static std::enable_if< VtKatana_IsOrHoldsString< T >::value, AttrType >::type CopyElement(const T &value)
Utility for copying string holder types.
iterator end()
Returns a non-const iterator to the end of the array.
Definition: array.h:348
const_pointer cdata() const
Return a const pointer to the data held by this array.
Definition: array.h:387
#define TF_VERIFY(cond, format,...)
Checks a condition and reports an error if it evaluates false.
Definition: diagnostic.h:289
Utilties for efficiently converting VtArrays to Katana attributes.
static std::enable_if< VtKatana_IsNumericCopyRequired< T >::value, AttrType >::type Copy(const VtArray< T > &array)
Utility for copying types that require an intermediate translation for use with Katana APIs...
static std::enable_if< VtKatana_IsNumeric< T >::value, std::vector< ValueType > >::type CopyIntermediate(const VtArray< T > &array)
Utility for copying numeric types to an intermediate std::vector suitable for use with Katana APIs...
static std::enable_if< VtKatana_IsNumericCastable< T >::value, AttrType >::type MapInternal(const VtArray< T > &value)
Iternals of map for types that do not require an intermediate copy of values to construct an attribut...
static std::enable_if< VtKatana_IsOrHoldsString< T >::value, AttrType >::type MapInternal(const VtArray< T > &value)
Iternals of map for string like types We haven&#39;t found signifcant zero copy performance improvements ...
static std::enable_if< VtKatana_IsNumericCastable< T >::value, AttrType >::type Copy(const std::vector< float > &times, const std::vector< VtArray< T >> &values)
Utility for copying numeric types that don&#39;t require an intermediate copy (ie.
static std::enable_if< VtKatana_IsNumericCopyRequired< T >::value, AttrType >::type MapInternal(const VtArray< T > &value)
Iternals of map for types that are not castable, requiring an intermediate copy of values to construc...
size_t size() const
Return the total number of elements in this array.
Definition: array.h:428
static std::enable_if< VtKatana_IsString< T >::value, std::vector< ValueType > >::type CopyIntermediate(const VtArray< T > &array)
Utility for copying tuple types to an intermediate std::vector suitable for use with Katana APIs...
static std::enable_if< VtKatana_IsNumericCastable< T >::value, AttrType >::type ZeroCopy(const std::vector< float > &times, const std::vector< VtArray< T >> &values)
Utility constructing attributes without copies by retaining references to the originating VtArrays...
static std::enable_if< VtKatana_IsOrHoldsString< T >::value, AttrType >::type Copy(const std::vector< float > &times, const std::vector< VtArray< T >> &values)
Utility for copying string holder types that don&#39;t require intermediate copies.
Katana attribute zero copy context for a VtArray whose element type is directly castable with multipl...
static std::enable_if< VtKatana_HoldsString< T >::value, std::vector< ValueType > >::type CopyIntermediate(const VtArray< T > &array)
Utility for copying tuple types to an intermediate std::vector suitable for use with Katana APIs...
static std::enable_if< VtKatana_HoldsString< T >::value, AttrType >::type Copy(const VtArray< T > &array)
Utility for copying string types that require an intermediate translation for use with Katana APIs...
static std::enable_if< VtKatana_IsNumericCopyRequiredTuple< T >::value, AttrType >::type CopyElement(const T &value)
Utility for copying numeric tuple types.
static std::enable_if< VtKatana_IsNumericScalar< T >::value, AttrType >::type CopyElement(T value)
Utility for copying numeric scalar types.
Castable numeric types don&#39;t require intermediate copies, and allows for ZeroCopy behavior...
static std::enable_if< VtKatana_IsNumericCastable< T >::value, AttrType >::type ZeroCopy(const VtArray< T > &array)
Utility constructing attributes without copies by retaining a reference to the originating VtArray...
static std::enable_if< VtKatana_IsNumericCopyRequired< T >::value, AttrType >::type Copy(const std::vector< float > &times, const typename std::vector< VtArray< T >> &values)
Utility for copying numeric types that do require intermediate copies.
bool empty() const
Return true if this array contains no elements, false otherwise.
Definition: array.h:444
static std::enable_if< VtKatana_IsNumericCastableTuple< T >::value, AttrType >::type CopyElement(const T &value)
Utility for copying numeric scalar types.
static std::enable_if< VtKatana_IsNumericCopyRequired< T >::value, AttrType >::type MapInternalMultiple(const std::vector< float > &times, const typename std::vector< VtArray< T >> &values)
Iternals of map for types that are not castable, requiring an intermediate copy of values to construc...
Katana attribute zero copy context for a VtArray whose element type is directly castable from the VtT...