All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
alembicUtil.h
Go to the documentation of this file.
1 //
2 // Copyright 2016-2019 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 USDABC_ALEMBICUTIL_H
25 #define USDABC_ALEMBICUTIL_H
26 
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/usdAbc/alembicReader.h"
31 #include "pxr/usd/sdf/abstractData.h"
32 #include "pxr/usd/sdf/schema.h"
33 #include "pxr/usd/sdf/types.h"
34 #include "pxr/base/vt/array.h"
35 #include "pxr/base/vt/value.h"
36 #include "pxr/base/arch/demangle.h"
37 #include "pxr/base/tf/staticTokens.h"
38 #include <Alembic/Abc/ICompoundProperty.h>
39 #include <Alembic/Abc/ISampleSelector.h>
40 #include <boost/call_traits.hpp>
41 #include <boost/operators.hpp>
42 #include <boost/optional.hpp>
43 #include <boost/shared_array.hpp>
44 #include <boost/shared_ptr.hpp>
45 #include <boost/type_traits/is_same.hpp>
46 #include <boost/type_traits/remove_const.hpp>
47 #include <boost/type_traits/remove_reference.hpp>
48 #include <boost/variant.hpp>
49 
50 #include <functional>
51 #include <algorithm>
52 #include <iosfwd>
53 #include <map>
54 #include <string>
55 #include <vector>
56 
57 
58 namespace Alembic {
59 namespace Util {
60 namespace ALEMBIC_VERSION_NS {
61  template <> struct PODTraitsFromType<PXR_NS::GfHalf>
62  : public Float16PODTraits {};
63 }}}// end namespace Alembic
64 
65 
66 PXR_NAMESPACE_OPEN_SCOPE
67 
68 
70 
72 #define USDABC_ALEMBIC_CONTEXT_FLAG_NAMES \
73  (verbose) \
74  (expandInstances) \
75  (disableInstancing) \
76  (promoteInstances) \
77  /* end */
78 TF_DECLARE_PUBLIC_TOKENS(UsdAbc_AlembicContextFlagNames,
80 
81 // A namespace so we can bring Alembic namespaces into it.
82 namespace UsdAbc_AlembicUtil {
83 
84 using namespace ::Alembic::Abc;
85 
86 // Prim type names in the UsdGeom schema except we create new names for
87 // types that don't map directly to Alembic.
88 #define USD_ABC_PRIM_TYPE_NAMES \
89  (BasisCurves) \
90  (Camera) \
91  (Mesh) \
92  (NurbsCurves) \
93  (Points) \
94  (PolyMesh) \
95  (PseudoRoot) \
96  (Scope) \
97  (Xform) \
98  (GeomSubset)\
99  /* end */
100 TF_DECLARE_PUBLIC_TOKENS(UsdAbcPrimTypeNames, USD_ABC_PRIM_TYPE_NAMES);
101 
102 // Property names in the UsdGeom schema.
103 #define USD_ABC_GPRIM_NAMES \
104  (primvars) \
105  (userProperties) \
106  ((defaultFamilyName, "materialBind")) \
107  ((defaultFamilyTypeAttributeName, "subsetFamily:materialBind:familyType")) \
108  /* end */
109 #define USD_ABC_POINTBASED_NAMES \
110  ((uv, "primvars:uv")) \
111  ((uvIndices, "primvars:uv:indices")) \
112  ((st, "primvars:st")) \
113  ((stIndices, "primvars:st:indices")) \
114  /* end */
115 #define USD_ABC_PROPERTY_NAMES \
116  USD_ABC_GPRIM_NAMES \
117  USD_ABC_POINTBASED_NAMES \
118  /* end */
119 TF_DECLARE_PUBLIC_TOKENS(UsdAbcPropertyNames, USD_ABC_PROPERTY_NAMES);
120 
121 #define USD_ABC_CUSTOM_METADATA \
122  (gprimDataRender) \
123  (riName) \
124  (riType) \
125  (singleSampleAsDefault) \
126  /* end */
127 TF_DECLARE_PUBLIC_TOKENS(UsdAbcCustomMetadata, USD_ABC_CUSTOM_METADATA);
128 
129 //
130 // Alembic property value types.
131 //
132 
136 struct UsdAbc_AlembicType : boost::totally_ordered<UsdAbc_AlembicType> {
137  PlainOldDataType pod; // POD type in scalar and array.
138  uint8_t extent; // Extent of POD (e.g. 3 for a 3-tuple).
139  bool_t array; // true for array, false otherwise.
140 
141  // An empty type.
142  UsdAbc_AlembicType() :
143  pod(kUnknownPOD), extent(0), array(false)
144  {
145  // Do nothing
146  }
147 
148  // An array or scalar type.
149  UsdAbc_AlembicType(PlainOldDataType pod_, uint8_t extent_, bool_t array_) :
150  pod(pod_), extent(extent_), array(array_)
151  {
152  // Do nothing
153  }
154 
155  // An Alembic property's type.
156  UsdAbc_AlembicType(const PropertyHeader& header) :
157  pod(header.getPropertyType() == kCompoundProperty ?
158  kUnknownPOD : header.getDataType().getPod()),
159  extent(header.getPropertyType() == kCompoundProperty ?
160  0 : header.getDataType().getExtent()),
161  array(header.getPropertyType() == kArrayProperty)
162  {
163  // Do nothing
164  }
165 
166  bool IsEmpty() const
167  {
168  return pod == kUnknownPOD;
169  }
170 
173  DataType GetDataType() const
174  {
175  return DataType(pod, extent);
176  }
177 
178  PropertyType GetPropertyType() const
179  {
180  return array ? kArrayProperty : kScalarProperty;
181  }
182 
183  // Debugging
184  std::string Stringify() const;
185 
186  bool operator==(const UsdAbc_AlembicType& rhs) const;
187  bool operator<(const UsdAbc_AlembicType& rhs) const;
188 };
189 
190 //
191 // Property value wrappers.
192 //
193 
197 class UsdAbc_AlembicDataAny {
198 public:
200  UsdAbc_AlembicDataAny() { }
201 
204  template <class T>
205  explicit UsdAbc_AlembicDataAny(T* any)
206  {
207  if (any) {
208  _valuePtr = any;
209  }
210  }
211 
213  bool Set(const VtValue& rhs) const
214  {
215  return boost::apply_visitor(_Set(rhs), _valuePtr);
216  }
217 
219  template <class T>
220  bool Set(T rhs) const
221  {
222  typedef typename boost::remove_reference<
223  typename boost::remove_const<T>::type>::type Type;
224  return boost::apply_visitor(_SetTyped<Type>(rhs), _valuePtr);
225  }
226 
228  bool IsEmpty() const
229  {
230  return _valuePtr.which() == 0;
231  }
232 
235  explicit operator bool() const
236  {
237  return !IsEmpty();
238  }
239 
240 private:
241  // Object representing the NULL pointer.
242  class _Empty {};
243 
244  // Visitor for assignment.
245  struct _Set : public boost::static_visitor<bool> {
246  _Set(const VtValue& rhs) : value(rhs) { }
247 
248  bool operator()(_Empty) const
249  {
250  // Convenience for "Has" methods. Discard the value and
251  // return true.
252  return true;
253  }
254 
255  bool operator()(VtValue* dst) const
256  {
257  *dst = value;
258  return true;
259  }
260 
261  bool operator()(SdfAbstractDataValue* dst) const
262  {
263  return dst->StoreValue(value);
264  }
265 
266  const VtValue& value;
267  };
268 
269  // Visitor for assignment.
270  template <class T>
271  struct _SetTyped : public boost::static_visitor<bool> {
272  _SetTyped(typename boost::call_traits<T>::param_type rhs) : value(rhs){}
273 
274  bool operator()(_Empty) const
275  {
276  // Convenience for "Has" methods. Discard the value and
277  // return true.
278  return true;
279  }
280 
281  bool operator()(VtValue* dst) const
282  {
283  *dst = value;
284  return true;
285  }
286 
287  bool operator()(SdfAbstractDataValue* dst) const
288  {
289  return dst->StoreValue(value);
290  }
291 
292  typename boost::call_traits<T>::param_type value;
293  };
294 
295 private:
296  boost::variant<_Empty, VtValue*, SdfAbstractDataValue*> _valuePtr;
297 };
298 
299 //
300 // Usd -> Alembic sample
301 //
302 
303 // Helpers for _SampleForAlembic.
304 template <class T>
305 struct _ExtractAddressOfSampleForAlembic {
306  const void* operator()(const T& value) const
307  {
308  return &value;
309  }
310 };
311 template <class T, class A = _ExtractAddressOfSampleForAlembic<T> >
312 struct _ExtractSampleForAlembic {
313  const void* operator()(const VtValue& v, size_t* numSamples) const
314  {
315  *numSamples = 1;
316  return A()(v.UncheckedGet<T>());
317  }
318 };
319 template <class T>
320 struct _ExtractSampleForAlembic<VtArray<T> > {
321  const void* operator()(const VtValue& v, size_t* numSamples) const
322  {
323  const VtArray<T>& result = v.UncheckedGet<VtArray<T> >();
324  *numSamples = result.size();
325  return result.cdata();
326  }
327 };
328 
331 class _SampleForAlembic {
332 public:
333  typedef std::vector<uint32_t> IndexArray;
334  typedef boost::shared_ptr<IndexArray> IndexArrayPtr;
335 
336  class Error {
337  public:
338  Error(const std::string& msg) : message(msg) { }
339  const std::string& message;
340  };
341 
343  _SampleForAlembic() :
344  _numSamples(0),
345  _value(_HolderValue(new _EmptyHolder))
346  {
347  // Do nothing
348  }
349 
352  _SampleForAlembic(const Error& error) :
353  _numSamples(0),
354  _value(_HolderValue(new _ErrorHolder(error.message)))
355  {
356  // Do nothing
357  }
358 
360  template <class T>
361  _SampleForAlembic(const T& value) :
362  _numSamples(1),
363  _value(_HolderValue(new _RawHolder<T>(value)))
364  {
365  // Do nothing
366  }
367 
369  template <class T>
370  _SampleForAlembic(const std::vector<T>& value) :
371  _numSamples(value.size()),
372  _value(_MakeRawArrayHolder(value))
373  {
374  // Do nothing
375  }
376 
382  template <class E>
383  _SampleForAlembic(const VtValue& value, const E& extractor) :
384  _value(_HolderValue(new _VtValueHolder(value, &_numSamples, extractor)))
385  {
386  // Do nothing
387  }
388 
390  template <class T>
391  _SampleForAlembic(const boost::shared_ptr<T>& value) :
392  _numSamples(1),
393  _value(_HolderValue(new _ScalarHolder<T>(value)))
394  {
395  TF_VERIFY(value);
396  }
397 
399  template <class T>
400  _SampleForAlembic(const boost::shared_array<T>& values, size_t count) :
401  _numSamples(count),
402  _value(_HolderValue(new _ArrayHolder<T>(values)))
403  {
404  TF_VERIFY(values);
405  }
406 
407  bool IsError(std::string* message) const
408  {
409  return _value.IsError(message);
410  }
411 
414  explicit operator bool() const
415  {
416  return _IsValid();
417  }
418 
420  const void* GetData() const
421  {
422  return _value.Get();
423  }
424 
427  template <class T>
428  const T* GetDataAs() const
429  {
430  return reinterpret_cast<const T*>(_value.Get());
431  }
432 
434  size_t GetCount() const
435  {
436  return _numSamples;
437  }
438 
440  void SetIndices(const IndexArrayPtr& indices)
441  {
442  _indices = indices;
443  }
444 
446  IndexArrayPtr GetIndices() const
447  {
448  return _indices;
449  }
450 
451 private:
452  bool _IsValid() const
453  {
454  return _value.Get();
455  }
456 
457  // Type erased holder for pointers.
458  class _Holder {
459  public:
460  virtual ~_Holder();
461  virtual const void* Get() const = 0;
462  virtual bool Error(std::string*) const;
463  };
464 
465  // Hold nothing.
466  class _EmptyHolder : public _Holder {
467  public:
468  _EmptyHolder();
469  virtual ~_EmptyHolder();
470  virtual const void* Get() const { return NULL; }
471  };
472 
473  // Hold an error and no sample.
474  class _ErrorHolder : public _Holder {
475  public:
476  _ErrorHolder(const std::string& message);
477  virtual ~_ErrorHolder();
478  virtual const void* Get() const { return NULL; }
479  virtual bool Error(std::string*) const;
480 
481  private:
482  std::string _message;
483  };
484 
485  // Hold nothing.
486  template <class T>
487  class _RawHolder : public _Holder {
488  public:
489  _RawHolder(const T& value) : _value(value) { }
490  virtual ~_RawHolder() { }
491  virtual const void* Get() const { return &_value; }
492 
493  private:
494  const T _value;
495  };
496 
497  // Hold a VtValue.
498  class _VtValueHolder : public _Holder {
499  public:
500  template <class E>
501  _VtValueHolder(const VtValue& value,
502  size_t* numSamples, const E& extractor) :
503  _value(new VtValue(value)),
504  _ptr(extractor(*_value, numSamples)) { }
505  virtual ~_VtValueHolder();
506  virtual const void* Get() const { return _ptr; }
507 
508  private:
509  boost::shared_ptr<VtValue> _value;
510  const void* _ptr;
511  };
512 
513  // Hold a shared_ptr.
514  template <class T>
515  class _ScalarHolder : public _Holder {
516  public:
517  _ScalarHolder(const boost::shared_ptr<T>& ptr) : _ptr(ptr) { }
518  virtual ~_ScalarHolder() { }
519  virtual const void* Get() const { return _ptr.get(); }
520 
521  private:
522  boost::shared_ptr<T> _ptr;
523  };
524 
525  // Hold a shared_array.
526  template <class T>
527  class _ArrayHolder : public _Holder {
528  public:
529  _ArrayHolder(const boost::shared_array<T>& ptr) : _ptr(ptr) { }
530  virtual ~_ArrayHolder() { }
531  virtual const void* Get() const { return _ptr.get(); }
532 
533  private:
534  boost::shared_array<T> _ptr;
535  };
536 
537  // Hold a _Holder as a value type.
538  class _HolderValue {
539  public:
540  explicit _HolderValue(_Holder* holder) : _holder(holder) { }
541 
542  const void* Get() const { return _holder->Get(); }
543  bool IsError(std::string* msg) const { return _holder->Error(msg); }
544 
545  private:
546  boost::shared_ptr<_Holder> _holder;
547  };
548 
549  template <class T>
550  static _HolderValue _MakeRawArrayHolder(const std::vector<T>& value)
551  {
552  boost::shared_array<T> copy(new T[value.size()]);
553  std::copy(value.begin(), value.end(), copy.get());
554  return _HolderValue(new _ArrayHolder<T>(copy));
555  }
556 
557 private:
558  size_t _numSamples;
559  _HolderValue _value;
560  IndexArrayPtr _indices;
561 };
562 
563 _SampleForAlembic _ErrorSampleForAlembic(const std::string& msg);
564 
567 template <class UsdType>
568 struct _SampleForAlembicIdentityConverter {
569  _SampleForAlembic operator()(const VtValue& value) const
570  {
571  return _SampleForAlembic(value, _ExtractSampleForAlembic<UsdType>());
572  }
573 };
574 
578 template <class UsdType, class AlembicType>
579 struct _SampleForAlembicConstructConverter {
580  _SampleForAlembic operator()(const VtValue& value) const
581  {
582  return _SampleForAlembic(boost::shared_ptr<AlembicType>(
583  new AlembicType(value.UncheckedGet<UsdType>())));
584  }
585 };
586 // Special case to identity converter.
587 template <class U>
588 struct _SampleForAlembicConstructConverter<U, U> :
589  public _SampleForAlembicIdentityConverter<U> {
590 };
591 
592 //
593 // Alembic <-> Usd POD conversions.
594 //
595 
596 //
597 // POD conversion to Usd.
598 //
599 
600 template <class UsdType, class AlembicType, size_t extent>
601 struct _ConvertPODToUsd { };
602 
603 // No conversion necessary.
604 template <class UsdType>
605 struct _ConvertPODToUsd<UsdType, UsdType, 1> {
606  const UsdType& operator()(const void* data) const
607  {
608  return *reinterpret_cast<const UsdType*>(data);
609  }
610 };
611 
612 // Conversion by construction.
613 template <class UsdType, class AlembicType>
614 struct _ConvertPODToUsd<UsdType, AlembicType, 1> {
615  UsdType operator()(const void* data) const
616  {
617  return UsdType(*reinterpret_cast<const AlembicType*>(data));
618  }
619 };
620 
621 // Construct vector.
622 template <class UsdType>
623 struct _ConvertPODToUsdVec {
624  UsdType operator()(const void* data) const
625  {
626  typedef typename UsdType::ScalarType ScalarType;
627  return UsdType(reinterpret_cast<const ScalarType*>(data));
628  }
629 };
630 template <>
631 struct _ConvertPODToUsd<GfVec2i, int32_t, 2> : _ConvertPODToUsdVec<GfVec2i>{};
632 template <>
633 struct _ConvertPODToUsd<GfVec2h, GfHalf, 2> : _ConvertPODToUsdVec<GfVec2h>{};
634 template <>
635 struct _ConvertPODToUsd<GfVec2f, float32_t, 2> : _ConvertPODToUsdVec<GfVec2f>{};
636 template <>
637 struct _ConvertPODToUsd<GfVec2d, float64_t, 2> : _ConvertPODToUsdVec<GfVec2d>{};
638 template <>
639 struct _ConvertPODToUsd<GfVec3i, int32_t, 3> : _ConvertPODToUsdVec<GfVec3i>{};
640 template <>
641 struct _ConvertPODToUsd<GfVec3h, GfHalf, 3> : _ConvertPODToUsdVec<GfVec3h>{};
642 template <>
643 struct _ConvertPODToUsd<GfVec3f, float32_t, 3> : _ConvertPODToUsdVec<GfVec3f>{};
644 template <>
645 struct _ConvertPODToUsd<GfVec3d, float64_t, 3> : _ConvertPODToUsdVec<GfVec3d>{};
646 template <>
647 struct _ConvertPODToUsd<GfVec4i, int32_t, 4> : _ConvertPODToUsdVec<GfVec4i>{};
648 template <>
649 struct _ConvertPODToUsd<GfVec4h, GfHalf, 4> : _ConvertPODToUsdVec<GfVec4h>{};
650 template <>
651 struct _ConvertPODToUsd<GfVec4f, float32_t, 4> : _ConvertPODToUsdVec<GfVec4f>{};
652 template <>
653 struct _ConvertPODToUsd<GfVec4d, float64_t, 4> : _ConvertPODToUsdVec<GfVec4d>{};
654 
655 // Construct quaternion.
656 // Note: Imath quaternions are stored as (r, i0, i1, i2) whereas the Gf
657 // versions are stored as (i0, i1, i2, r)
658 template <>
659 struct _ConvertPODToUsd<GfQuatf, float32_t, 4> {
660  GfQuatf operator()(const void* data) const
661  {
662  const float32_t* src = reinterpret_cast<const float32_t*>(data);
663  GfVec3f imaginary(src[1], src[2], src[3]);
664  return GfQuatf(src[0], imaginary);
665  }
666 };
667 
668 template <>
669 struct _ConvertPODToUsd<GfQuatd, float64_t, 4> {
670  GfQuatd operator()(const void* data) const
671  {
672  const float64_t* src = reinterpret_cast<const float64_t*>(data);
673  GfVec3d imaginary(src[1], src[2], src[3]);
674  return GfQuatd(src[0], imaginary);
675  }
676 };
677 
678 
679 // Construct matrix.
680 template <>
681 struct _ConvertPODToUsd<GfMatrix4d, float32_t, 16> {
682  GfMatrix4d operator()(const void* data) const
683  {
684  float64_t buffer[4][4];
685  const float32_t* src = reinterpret_cast<const float32_t*>(data);
686  std::copy(src, src + 16, &buffer[0][0]);
687  return GfMatrix4d(buffer);
688  }
689 };
690 template <>
691 struct _ConvertPODToUsd<GfMatrix4d, float64_t, 16> {
692  GfMatrix4d operator()(const void* data) const
693  {
694  return GfMatrix4d(reinterpret_cast<const float64_t(*)[4]>(data));
695  }
696 };
697 
698 // Copy an array -- general case.
699 template <class UsdType, class AlembicType, size_t extent>
700 struct _ConvertPODToUsdArray {
701  void operator()(UsdType* dst, const void* src, size_t size)
702  {
703  const uint8_t* typedSrc = reinterpret_cast<const uint8_t*>(src);
704  const size_t step = extent * sizeof(AlembicType);
705  for (size_t i = 0, n = size; i != n; typedSrc += step, ++i) {
706  dst[i] = _ConvertPODToUsd<UsdType, AlembicType, extent>()(typedSrc);
707  }
708  }
709 };
710 
711 // Copy an array -- no conversion necessary.
712 template <class UsdType>
713 struct _ConvertPODToUsdArray<UsdType, UsdType, 1> {
714  void operator()(UsdType* dst, const void* src, size_t size)
715  {
716  const UsdType* typedSrc = reinterpret_cast<const UsdType*>(src);
717  std::copy(typedSrc, typedSrc + size, dst);
718  }
719 };
720 
721 //
722 // POD conversion from Usd.
723 //
724 
725 template <class UsdType, class AlembicType, size_t extent>
726 struct _ConvertPODFromUsd { };
727 
728 // No conversion necessary.
729 template <class UsdType>
730 struct _ConvertPODFromUsd<UsdType, UsdType, 1> {
731  void operator()(const UsdType& src, UsdType* dst) const
732  {
733  *dst = src;
734  }
735 };
736 
737 // Conversion by construction.
738 template <class UsdType, class AlembicType>
739 struct _ConvertPODFromUsd<UsdType, AlembicType, 1> {
740  void operator()(const UsdType& src, AlembicType* dst) const
741  {
742  *dst = AlembicType(src);
743  }
744 };
745 
746 // Conversion for TfToken to std::string.
747 template <>
748 struct _ConvertPODFromUsd<TfToken, std::string, 1> {
749  void operator()(const TfToken& src, std::string* dst) const
750  {
751  *dst = src.GetString();
752  }
753 };
754 
755 // Construct vector.
756 template <class UsdType>
757 struct _ConvertPODFromUsdVec {
758  void operator()(const UsdType& src, typename UsdType::ScalarType* dst) const
759  {
760  std::copy(src.GetArray(), src.GetArray() + UsdType::dimension, dst);
761  }
762 };
763 template <>
764 struct _ConvertPODFromUsd<GfVec2i, int32_t, 2> :
765  _ConvertPODFromUsdVec<GfVec2i> { };
766 template <>
767 struct _ConvertPODFromUsd<GfVec2h, GfHalf, 2> :
768  _ConvertPODFromUsdVec<GfVec2h> { };
769 template <>
770 struct _ConvertPODFromUsd<GfVec2f, float32_t, 2> :
771  _ConvertPODFromUsdVec<GfVec2f> { };
772 template <>
773 struct _ConvertPODFromUsd<GfVec2d, float64_t, 2> :
774  _ConvertPODFromUsdVec<GfVec2d> { };
775 template <>
776 struct _ConvertPODFromUsd<GfVec3i, int32_t, 3> :
777  _ConvertPODFromUsdVec<GfVec3i> { };
778 template <>
779 struct _ConvertPODFromUsd<GfVec3h, GfHalf, 3> :
780  _ConvertPODFromUsdVec<GfVec3h> { };
781 template <>
782 struct _ConvertPODFromUsd<GfVec3f, float32_t, 3> :
783  _ConvertPODFromUsdVec<GfVec3f> { };
784 template <>
785 struct _ConvertPODFromUsd<GfVec3d, float64_t, 3> :
786  _ConvertPODFromUsdVec<GfVec3d> { };
787 template <>
788 struct _ConvertPODFromUsd<GfVec4i, int32_t, 4> :
789  _ConvertPODFromUsdVec<GfVec4i> { };
790 template <>
791 struct _ConvertPODFromUsd<GfVec4h, GfHalf, 4> :
792  _ConvertPODFromUsdVec<GfVec4h> { };
793 template <>
794 struct _ConvertPODFromUsd<GfVec4f, float32_t, 4> :
795  _ConvertPODFromUsdVec<GfVec4f> { };
796 template <>
797 struct _ConvertPODFromUsd<GfVec4d, float64_t, 4> :
798  _ConvertPODFromUsdVec<GfVec4d> { };
799 
800 // Construct quaternion.
801 // Note: Imath quaternions are stored as (r, i0, i1, i2) whereas the Gf
802 // versions are stored as (i0, i1, i2, r)
803 template <>
804 struct _ConvertPODFromUsd<GfQuatf, float32_t, 4> {
805  void operator()(const GfQuatf& src, float32_t* dst) const
806  {
807  dst[0] = src.GetReal();
808  dst[1] = src.GetImaginary()[0];
809  dst[2] = src.GetImaginary()[1];
810  dst[3] = src.GetImaginary()[2];
811  }
812 };
813 
814 template <>
815 struct _ConvertPODFromUsd<GfQuatd, float64_t, 4> {
816  void operator()(const GfQuatd& src, float64_t* dst) const
817  {
818  dst[0] = src.GetReal();
819  dst[1] = src.GetImaginary()[0];
820  dst[2] = src.GetImaginary()[1];
821  dst[3] = src.GetImaginary()[2];
822  }
823 };
824 
825 // Construct matrix.
826 template <>
827 struct _ConvertPODFromUsd<GfMatrix4d, float32_t, 16> {
828  void operator()(const GfMatrix4d& src, float32_t* dst) const
829  {
830  std::copy(src.GetArray(), src.GetArray() + 16, dst);
831  }
832 };
833 template <>
834 struct _ConvertPODFromUsd<GfMatrix4d, float64_t, 16> {
835  void operator()(const GfMatrix4d& src, float64_t* dst) const
836  {
837  std::copy(src.GetArray(), src.GetArray() + 16, dst);
838  }
839 };
840 
841 // Copy a scalar -- general case.
842 template <class UsdType, class AlembicType, size_t extent>
843 struct _ConvertPODFromUsdScalar {
844  _SampleForAlembic operator()(const VtValue& src) const
845  {
846  boost::shared_array<AlembicType> dst(new AlembicType[extent]);
847  _ConvertPODFromUsd<UsdType, AlembicType, extent>()(
848  src.UncheckedGet<UsdType>(), dst.get());
849  return _SampleForAlembic(dst, extent);
850  }
851 };
852 
853 // Copy a scalar -- POD.
854 template <class UsdType, class AlembicType>
855 struct _ConvertPODFromUsdScalar<UsdType, AlembicType, 1> {
856  _SampleForAlembic operator()(const VtValue& src) const
857  {
858  AlembicType dst;
859  _ConvertPODFromUsd<UsdType, AlembicType, 1>()(
860  src.UncheckedGet<UsdType>(), &dst);
861  return _SampleForAlembic(dst);
862  }
863 };
864 
865 // Copy an array -- general case.
866 template <class UsdType, class AlembicType, size_t extent>
867 struct _ConvertPODFromUsdArray {
868  _SampleForAlembic operator()(const VtValue& src)
869  {
870  const VtArray<UsdType>& data = src.UncheckedGet<VtArray<UsdType> >();
871  const size_t size = data.size();
872  boost::shared_array<AlembicType> array(new AlembicType[size * extent]);
873  AlembicType* ptr = array.get();
874  for (size_t i = 0, n = size; i != n; ptr += extent, ++i) {
875  _ConvertPODFromUsd<UsdType, AlembicType, extent>()(data[i], ptr);
876  }
877  return _SampleForAlembic(array, size * extent);
878  }
879 };
880 
881 //
882 // Alembic <-> Usd conversion registries.
883 //
884 
885 template <class UsdType, class AlembicType, size_t extent>
886 struct _ConvertPODScalar;
887 template <class UsdType, class AlembicType, size_t extent>
888 struct _ConvertPODArray;
889 
892 class UsdAbc_AlembicDataConversion {
893 public:
898  typedef std::function<bool (const ICompoundProperty&,
899  const std::string&,
900  const ISampleSelector&,
901  const UsdAbc_AlembicDataAny&)> ToUsdConverter;
902 
906  typedef std::function<_SampleForAlembic(const VtValue&)> FromUsdConverter;
907 
908  UsdAbc_AlembicDataConversion();
909 
914  template <class UsdType, class AlembicType, size_t extent>
915  void AddConverter(const SdfValueTypeName& usdType)
916  {
917  const PlainOldDataType pod = PODTraitsFromType<AlembicType>::pod_enum;
918  _AddConverter(UsdAbc_AlembicType(pod, extent, false),
919  usdType,
920  _ConvertPODScalar<UsdType, AlembicType, extent>(),
921  _ConvertPODScalar<UsdType, AlembicType, extent>());
922  _AddConverter(UsdAbc_AlembicType(pod, extent, true),
923  usdType.GetArrayType(),
924  _ConvertPODArray<UsdType, AlembicType, extent>(),
925  _ConvertPODArray<UsdType, AlembicType, extent>());
926  }
927 
932  template <class UsdType, class AlembicType, size_t extent>
933  void AddConverter()
934  {
935  AddConverter<UsdType, AlembicType, extent>(
936  SdfSchema::GetInstance().FindType(TfType::Find<UsdType>()));
937  }
938 
939  template <class UsdType, class AlembicType>
940  void AddConverter(const SdfValueTypeName& usdType)
941  {
942  AddConverter<UsdType, AlembicType, 1>(usdType);
943  }
944 
945  template <class UsdType, class AlembicType>
946  void AddConverter()
947  {
948  AddConverter<UsdType, AlembicType, 1>();
949  }
950 
954  SdfValueTypeName FindConverter(const UsdAbc_AlembicType& alembicType) const;
955 
958  const ToUsdConverter& GetToUsdConverter(
959  const UsdAbc_AlembicType& alembicType,
960  const SdfValueTypeName& usdType) const;
961 
964  UsdAbc_AlembicType FindConverter(const SdfValueTypeName& usdType) const;
965 
967  const FromUsdConverter& GetConverter(const SdfValueTypeName& usdType) const;
968 
969 private:
970  void _AddConverter(const UsdAbc_AlembicType& alembicType,
971  const SdfValueTypeName& usdType,
972  const ToUsdConverter&, const FromUsdConverter&);
973 
974 private:
975 
976  // All the data that we need to convert between usd and abc types.
977  struct _ConverterData {
978  _ConverterData(const SdfValueTypeName &usdType_,
979  const UsdAbc_AlembicType &abcType_,
980  const ToUsdConverter &toUsdFn_,
981  const FromUsdConverter &fromUsdFn_)
982  : usdType(usdType_)
983  , abcType(abcType_)
984  , toUsdFn(toUsdFn_)
985  , fromUsdFn(fromUsdFn_)
986  { }
987 
988  SdfValueTypeName usdType;
989  UsdAbc_AlembicType abcType;
990  ToUsdConverter toUsdFn;
991  FromUsdConverter fromUsdFn;
992  };
993 
994  // All the type converters that we have registered.
995  std::vector<_ConverterData> _typeConverters;
996 };
997 
1000 struct UsdAbc_AlembicConversions {
1001  UsdAbc_AlembicConversions();
1002 
1003  UsdAbc_AlembicDataConversion data;
1004 };
1005 
1006 //
1007 // Utilities
1008 //
1009 
1011 std::string
1012 UsdAbc_FormatAlembicVersion(int32_t n);
1013 
1016 template <class T>
1017 static bool
1018 UsdAbc_ReverseOrderImpl(
1019  VtArray<T>& values,
1020  const VtArray<int>& counts)
1021 {
1022  // Reverse items.
1023  for (size_t j = 0, n = values.size(),
1024  k = 0, m = counts.size(); k != m; ++k) {
1025  const int count = counts[k];
1026 
1027  // Bail out with failure if we run out of items.
1028  if (!TF_VERIFY(j + count <= n)) {
1029  return false;
1030  }
1031 
1032  // Reverse the range.
1033  std::reverse(values.begin() + j, values.begin() + j + count);
1034 
1035  // Next range.
1036  j += count;
1037  }
1038  return true;
1039 }
1040 
1041 } // namespace UsdAbc_AlembicUtil
1042 
1043 
1044 PXR_NAMESPACE_CLOSE_SCOPE
1045 
1046 #endif // USDABC_ALEMBICUTIL_H
std::string const & GetString() const
Return the string that this token represents.
Definition: token.h:209
Basic type for a vector of 4 int components.
Definition: vec4i.h:61
double GetReal() const
Return the real coefficient.
Definition: quatd.h:102
T const & UncheckedGet() const
Returns a const reference to the held object if the held object is of type T.
Definition: value.h:836
Basic type for a vector of 2 int components.
Definition: vec2i.h:61
pxr_half::half GfHalf
A 16-bit floating point data type.
Definition: half.h:42
A type-erased container for a field value in an SdfAbstractData.
Definition: abstractData.h:394
const GfVec3d & GetImaginary() const
Return the imaginary coefficient.
Definition: quatd.h:108
iterator begin()
Return a non-const iterator to the start of the array.
Definition: array.h:345
SDF_API SdfValueTypeName GetArrayType() const
Returns the array version of this type name if it&#39;s an scalar type name, otherwise returns this type ...
Basic type for a vector of 3 float components.
Definition: vec3f.h:63
Basic type for a vector of 4 double components.
Definition: vec4d.h:63
Represents a value type name, i.e.
Definition: valueTypeName.h:83
float GetReal() const
Return the real coefficient.
Definition: quatf.h:102
#define USDABC_ALEMBIC_CONTEXT_FLAG_NAMES
Flags for readers and writers.
Definition: alembicUtil.h:72
Basic type: a quaternion, a complex number with a real coefficient and three imaginary coefficients...
Definition: quatf.h:60
Basic type for a vector of 2 double components.
Definition: vec2d.h:63
Basic type for a vector of 4 GfHalf components.
Definition: vec4h.h:64
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:89
const_pointer cdata() const
Return a const pointer to the data held by this array.
Definition: array.h:387
Basic type for a vector of 2 GfHalf components.
Definition: vec2h.h:64
Stores a 4x4 matrix of double elements.
Definition: matrix4d.h:88
#define TF_VERIFY(cond, format,...)
Checks a condition and reports an error if it evaluates false.
Definition: diagnostic.h:289
#define TF_DECLARE_PUBLIC_TOKENS(...)
Macro to define public tokens.
Definition: staticTokens.h:118
SDF_API SdfValueTypeName FindType(const std::string &typeName) const
Return the type name object for the given type name string.
Basic type for a vector of 3 int components.
Definition: vec3i.h:61
size_t size() const
Return the total number of elements in this array.
Definition: array.h:428
Represents an arbitrary dimensional rectangular container class.
Definition: array.h:193
double * GetArray()
Returns vector components as an array of double values.
Definition: matrix4d.h:285
Basic type for a vector of 4 float components.
Definition: vec4f.h:63
Basic type for a vector of 2 float components.
Definition: vec2f.h:63
Basic type for a vector of 3 double components.
Definition: vec3d.h:63
const GfVec3f & GetImaginary() const
Return the imaginary coefficient.
Definition: quatf.h:108
VT_API bool operator==(VtDictionary const &, VtDictionary const &)
Equality comparison.
Basic type: a quaternion, a complex number with a real coefficient and three imaginary coefficients...
Definition: quatd.h:60
Basic type for a vector of 3 GfHalf components.
Definition: vec3h.h:64
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:182