All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
internalToVt.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 
31 #include "pxr/base/tf/envSetting.h"
32 #include "pxr/base/vt/array.h"
33 
34 #include "vtKatana/internalTraits.h"
35 
36 PXR_NAMESPACE_OPEN_SCOPE
37 
38 namespace VtKatana_Internal {
39 
42 template <typename AttributeType>
43 class VtKatana_SampleSource : public Vt_ArrayForeignDataSource {
44  typedef typename AttributeType::array_type SampleType;
45 
46 public:
47  explicit VtKatana_SampleSource(const AttributeType& attribute)
48  : Vt_ArrayForeignDataSource(VtKatana_SampleSource::_Detached),
49  _dataAttribute(attribute) {}
50  SampleType _GetNearestSample(float sample) {
51  return _dataAttribute.getNearestSample(sample);
52  }
53 
54 private:
55  static void _Detached(Vt_ArrayForeignDataSource* selfBase) {
56  auto* self = static_cast<VtKatana_SampleSource*>(selfBase);
57  delete self;
58  }
59 
60 private:
61  AttributeType _dataAttribute;
62 };
63 
65 template <typename ElementType>
67  typedef typename VtKatana_GetKatanaAttrType<ElementType>::type AttrType;
68  typedef
69  typename VtKatana_GetKatanaAttrValueType<ElementType>::type ValueType;
70  typedef typename AttrType::array_type SampleType;
72 
73  template <typename T = ElementType>
74  static
75  typename std::enable_if<VtKatana_IsNumericScalar<T>::value, void>::type
76  _CheckAndWarnSize(size_t size) {
77  static_assert(VtKatana_GetNumericTupleSize<T>::value == 1, "");
78  }
79 
80  template <typename T = ElementType>
81  static
82  typename std::enable_if<VtKatana_IsNumericTuple<T>::value, void>::type
83  _CheckAndWarnSize(size_t size) {
85  TF_WARN(
86  "Elements sequence will be truncated because size '%zu' is "
87  "not divisible by element tuple size '%zu'.",
89  }
90  }
91 
92  template <typename T = ElementType>
93  static typename std::enable_if<VtKatana_IsNumericCastableTuple<T>::value,
94  const VtArray<T>>::type
95  _CopyUnaligned(const SampleType& sample) {
96  size_t size = sample.size() / VtKatana_GetNumericTupleSize<T>::value;
97  VtArray<T> result(size);
98  for (size_t i = 0; i < size;
100  result[i] =
101  T(sample.data()[i * VtKatana_GetNumericTupleSize<T>::value]);
102  }
103  return result;
104  }
105 
106  template <typename T = ElementType>
107  static typename std::enable_if<VtKatana_IsNumericCastableScalar<T>::value,
108  const VtArray<T>>::type
109  _CopyUnaligned(const SampleType& sample) {
110  VtArray<T> result;
111  result.assign(sample.begin(), sample.end());
112  return result;
113  }
114 
115 public:
119  template <typename T = ElementType>
120  static typename std::enable_if<VtKatana_IsNumericCastable<T>::value,
121  const VtArray<T>>::type
122  ZeroCopy(const AttrType& attribute, float time) {
123  typedef typename VtKatana_GetNumericScalarType<ElementType>::type
124  ScalarType;
125  std::unique_ptr<ZeroCopySource> source(new ZeroCopySource(attribute));
126  auto sample = source->_GetNearestSample(time);
127  _CheckAndWarnSize<T>(sample.size());
128  T* data = NULL;
129  size_t size = sample.size() / VtKatana_GetNumericTupleSize<T>::value;
130  if (VtKatana_IsSampleAligned<T>(sample)) {
131  // GetVtPtr's reinterpret cast requires aligned data.
132  data = const_cast<T*>(VtKatana_GetVtPtr<T>(sample));
133  VtArray<T> result(source.release(), data, size);
134  return result;
135  } else {
136  return _CopyUnaligned(sample);
137  }
138  }
139 
142  template <typename T = ElementType>
143  static typename std::enable_if<VtKatana_IsNumericCastable<T>::value,
144  VtArray<T>>::type
145  Copy(const SampleType& sample) {
146  _CheckAndWarnSize<T>(sample.size());
147  size_t size = sample.size() / VtKatana_GetNumericTupleSize<T>::value;
148  if (VtKatana_IsSampleAligned<T>(sample)) {
149  auto dataBegin = VtKatana_GetVtPtr<T>(sample);
150  auto dataEnd = dataBegin + size;
151  VtArray<T> result;
152  result.assign(dataBegin, dataEnd);
153  return result;
154  } else {
155  return _CopyUnaligned(sample);
156  }
157  }
158 
161  template <typename T = ElementType>
162  static
163  typename std::enable_if<VtKatana_IsNumericCopyRequiredScalar<T>::value,
164  VtArray<T>>::type
165  Copy(const SampleType& array) {
166  typedef typename VtKatana_GetNumericScalarType<ElementType>::type
167  ScalarType;
168  VtArray<ScalarType> result;
169  result.assign(array.begin(), array.end());
170  return result;
171  }
172 
175  template <typename T = ElementType>
176  static
177  typename std::enable_if<VtKatana_IsNumericCopyRequiredTuple<T>::value,
178  VtArray<T>>::type
179  Copy(const SampleType& array) {
180  typedef
181  typename VtKatana_GetNumericCopyTuplePeer<T>::type TupleCopyPeer;
182  typedef typename VtKatana_GetNumericScalarType<ElementType>::type
183  ScalarType;
184  // This only works on GfHalf based types currently.
185  // See VtKatana_GetNumericCopyTuplePeer for more info.
186  static_assert(std::is_same<ScalarType, GfHalf>::value, "");
189  "");
190  _CheckAndWarnSize<T>(array.size());
191  size_t size = array.size() / VtKatana_GetNumericTupleSize<T>::value;
192  auto data = reinterpret_cast<const TupleCopyPeer*>(array.data());
193  VtArray<T> result(size);
194  std::transform(data, data + size, result.begin(),
195  [](const TupleCopyPeer& peer) { return T(peer); });
196  return result;
197  }
198 
200  template <typename T = ElementType>
201  static
202  typename std::enable_if<VtKatana_IsString<T>::value, VtArray<T>>::type
203  Copy(const SampleType& sample) {
204  VtArray<T> result;
205  result.assign(sample.begin(), sample.end());
206  return result;
207  }
208 
215  template <typename T = ElementType>
216  static typename std::enable_if<VtKatana_HoldsString<T>::value,
217  VtArray<T>>::type
218  Copy(const SampleType& sample) {
219  VtArray<T> result(sample.size());
220  std::transform(sample.begin(), sample.end(), result.begin(),
221  [](const std::string& element) { return T(element); });
222  return result;
223  }
224 
228  template <typename T = ElementType>
229  static typename std::enable_if<VtKatana_IsNumericCopyRequired<T>::value ||
231  const VtArray<T>>::type
232  MapInternal(const AttrType& attribute, float sample = 0.0f) {
233  auto nearestSample = attribute.getNearestSample(sample);
234  return Copy(nearestSample);
235  }
236 
240  template <typename T = ElementType>
241  static typename std::enable_if<VtKatana_IsNumericCastable<T>::value,
242  const VtArray<T>>::type
243  MapInternal(const AttrType& attribute, float sample = 0.0f) {
244  static bool zeroCopyEnabled =
245  TfGetEnvSetting(VTKATANA_ENABLE_ZERO_COPY_ARRAYS);
246  if (zeroCopyEnabled) {
247  return ZeroCopy(attribute, sample);
248  } else {
249  auto nearestSample = attribute.getNearestSample(sample);
250  return Copy(nearestSample);
251  }
252  }
253 
254  template <typename T = ElementType>
255  static typename std::enable_if<VtKatana_IsNumericScalar<T>::value, T>::type
256  CopyElement(const AttrType& attr, float time) {
257  auto nearestSample = attr.getNearestSample(time);
258  return nearestSample.data()[0];
259  }
260 
261  template <typename T = ElementType>
262  static typename std::enable_if<GfIsGfVec<T>::value && VtKatana_IsNumericCastable<T>::value, T>::type
263  CopyElement(const AttrType& attr, float time) {
264  auto nearestSample = attr.getNearestSample(time);
265  return T(nearestSample.data());
266  }
267 
268  template <typename T = ElementType>
269  static typename std::enable_if<GfIsGfVec<T>::value && !VtKatana_IsNumericCastable<T>::value, T>::type
270  CopyElement(const AttrType& attr) {
271  typedef
272  typename VtKatana_GetNumericCopyTuplePeer<T>::type TupleCopyPeer;
273  typedef typename VtKatana_GetNumericScalarType<ElementType>::type
274  ScalarType;
275  // This only works on GfHalf based types currently.
276  // See VtKatana_GetNumericCopyTuplePeer for more info.
277  static_assert(std::is_same<ScalarType, GfHalf>::value, "");
280  "");
281  auto nearestSample = attr.getNearestSample(0.0f);
282  const TupleCopyPeer* peer = reinterpret_cast<const TupleCopyPeer*>(nearestSample.data());
283  return T(*peer);
284  }
285 
286  template <typename T = ElementType>
287  static typename std::enable_if<GfIsGfMatrix<T>::value, T>::type
288  CopyElement(const AttrType& attr) {
289  typedef typename VtKatana_GetNumericScalarType<ElementType>::type
290  ScalarType;
291  auto nearestSample = attr.getNearestSample(0.0f);
292  auto data = reinterpret_cast<const ScalarType(*)[T::numRows]>(
293  nearestSample.data());
294  return T(data);
295  }
296 
297  template <typename T = ElementType>
298  static typename std::enable_if<VtKatana_IsString<T>::value, T>::type
299  CopyElement(const AttrType& attr) {
300  static const std::string defValue;
301  return attr.getValue(defValue, false);
302  }
303 
304  template <typename T = ElementType>
305  static typename std::enable_if<VtKatana_HoldsString<T>::value, T>::type
306  CopyElement(const AttrType& attr) {
307  static const std::string defValue;
308  std::string value = attr.getValue(defValue, false);
309  return T(value);
310  }
311 };
312 }
313 
314 PXR_NAMESPACE_CLOSE_SCOPE
Gets the &#39;tuple size&#39; of T, or number of elements a numeric type contains.
static std::enable_if< VtKatana_IsNumericCopyRequiredTuple< T >::value, VtArray< T > >::type Copy(const SampleType &array)
Copy utility for numeric tuple types require an intermediate copy to construct a VtArray (ie...
Definition: internalToVt.h:179
T const & TfGetEnvSetting(TfEnvSetting< T > &setting)
Returns the value of the specified env setting, registered using TF_DEFINE_ENV_SETTING.
Definition: envSetting.h:158
static std::enable_if< VtKatana_IsNumericCopyRequiredScalar< T >::value, VtArray< T > >::type Copy(const SampleType &array)
Copy utility for numeric scalar types require an intermediate copy to construct a VtArray (ie...
Definition: internalToVt.h:165
#define TF_WARN(...)
Issue a warning, but continue execution.
Definition: diagnostic.h:153
static std::enable_if< VtKatana_IsNumericCastable< T >::value, const VtArray< T > >::type ZeroCopy(const AttrType &attribute, float time)
Zero copy utility for numeric types (GfVec3f, GfMatrix4d, ...).
Definition: internalToVt.h:122
iterator begin()
Return a non-const iterator to the start of the array.
Definition: array.h:345
static std::enable_if< VtKatana_IsNumericCastable< T >::value, VtArray< T > >::type Copy(const SampleType &sample)
Copy utility for numeric types that don&#39;t require an intermediate copy to construct a VtArray (ie...
Definition: internalToVt.h:145
The VtKatana_SampleSource holds a reference to the katana attribute to preserve the lifetime of all i...
Definition: internalToVt.h:43
static std::enable_if< VtKatana_IsNumericCopyRequired< T >::value||VtKatana_IsOrHoldsString< T >::value, const VtArray< T > >::type MapInternal(const AttrType &attribute, float sample=0.0f)
Maps a given attribute sample to a VtArray.
Definition: internalToVt.h:232
size_t size() const
Return the total number of elements in this array.
Definition: array.h:428
static std::enable_if< VtKatana_IsNumericCastable< T >::value, const VtArray< T > >::type MapInternal(const AttrType &attribute, float sample=0.0f)
Maps a given attribute sample to a VtArray.
Definition: internalToVt.h:243
static std::enable_if< VtKatana_HoldsString< T >::value, VtArray< T > >::type Copy(const SampleType &sample)
Copy utility for holders of std::string (This assumes that the holder can be constructed from a strin...
Definition: internalToVt.h:218
Castable numeric types don&#39;t require intermediate copies, and allows for ZeroCopy behavior...
Conversion utilities for Katana attributes to VtArrays containing type T.
Definition: internalToVt.h:66
static std::enable_if< VtKatana_IsString< T >::value, VtArray< T > >::type Copy(const SampleType &sample)
Copy utility for std::string.
Definition: internalToVt.h:203
void assign(ForwardIter first, ForwardIter last)
Assign array contents.
Definition: array.h:559