HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
animMapper.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_USD_USD_SKEL_ANIM_MAPPER_H
8 #define PXR_USD_USD_SKEL_ANIM_MAPPER_H
9 
10 /// \file usdSkel/animMapper.h
11 
12 #include "pxr/pxr.h"
13 #include "pxr/usd/usdSkel/api.h"
14 
15 #include "pxr/base/gf/matrix4d.h"
16 #include "pxr/base/gf/matrix4f.h"
17 #include "pxr/base/tf/span.h"
18 #include "pxr/base/vt/array.h"
19 #include "pxr/usd/sdf/types.h"
20 
21 #include <type_traits>
22 #include <vector>
23 
24 
26 
27 
28 using UsdSkelAnimMapperRefPtr = std::shared_ptr<class UsdSkelAnimMapper>;
29 
30 
31 /// \class UsdSkelAnimMap
32 ///
33 /// Helper class for remapping vectorized animation data from
34 /// one ordering of tokens to another.
36 public:
37  /// Construct a null mapper.
40 
41  /// Construct an identity mapper for remapping a range of \p size elems.
42  /// An identity mapper is used to indicate that no remapping is required.
44  UsdSkelAnimMapper(size_t size);
45 
46  /// Construct a mapper for mapping data from \p sourceOrder to
47  /// \p targetOrder.
49  UsdSkelAnimMapper(const VtTokenArray& sourceOrder,
50  const VtTokenArray& targetOrder);
51 
52  /// Construct a mapper for mapping data from \p sourceOrder to
53  /// \p targetOrder, each being arrays of size \p sourceOrderSize
54  /// and \p targetOrderSize, respectively.
56  UsdSkelAnimMapper(const TfToken* sourceOrder, size_t sourceOrderSize,
57  const TfToken* targetOrder, size_t targetOrderSize);
58 
59  /// Typed remapping of data in an arbitrary, stl-like container.
60  /// The \p source array provides a run of \p elementSize for each path in
61  /// the \\em sourceOrder. These elements are remapped and copied over the
62  /// \p target array.
63  /// Prior to remapping, the \p target array is resized to the size of the
64  /// \\em targetOrder (as given at mapper construction time) multiplied by
65  /// the \p elementSize. New element created in the array are initialized
66  /// to \p defaultValue, if provided.
67  template <typename Container>
68  bool Remap(const Container& source,
69  Container* target,
70  int elementSize=1,
71  const typename Container::value_type*
72  defaultValue=nullptr) const;
73 
74  /// Type-erased remapping of data from \p source into \p target.
75  /// The \p source array provides a run of \p elementSize elements for each
76  /// path in the \\em sourceOrder. These elements are remapped and copied
77  /// over the \p target array.
78  /// Prior to remapping, the \p target array is resized to the size of the
79  /// \\em targetOrder (as given at mapper construction time) multiplied by
80  /// the \p elementSize. New elements created in the array are initialized
81  /// to \p defaultValue, if provided.
82  /// Remapping is supported for registered Sdf array value types only.
84  bool Remap(const VtValue& source, VtValue* target,
85  int elementSize=1, const VtValue& defaultValue=VtValue()) const;
86 
87  /// Convenience method for the common task of remapping transform arrays.
88  /// This performs the same operation as Remap(), but sets the matrix
89  /// identity as the default value.
90  template <typename Matrix4>
92  bool RemapTransforms(const VtArray<Matrix4>& source,
93  VtArray<Matrix4>* target,
94  int elementSize=1) const;
95 
96  /// Returns true if this is an identity map.
97  /// The source and target orders of an identity map are identical.
99  bool IsIdentity() const;
100 
101  /// Returns true if this is a sparse mapping.
102  /// A sparse mapping means that not all target values will be overridden
103  /// by source values, when mapped with Remap().
105  bool IsSparse() const;
106 
107  /// Returns true if this is a null mapping.
108  /// No source elements of a null map are mapped to the target.
110  bool IsNull() const;
111 
112  /// Get the size of the output array that this mapper expects to
113  /// map data into.
115  size_t size() const { return _targetSize; }
116 
117  bool operator==(const UsdSkelAnimMapper& o) const;
118 
119  bool operator!=(const UsdSkelAnimMapper& o) const {
120  return !(*this == o);
121  }
122 
123 private:
124 
125  template <typename T>
126  bool _UntypedRemap(const VtValue& source, VtValue* target,
127  int elementSize, const VtValue& defaultValue) const;
128 
129  template <typename T>
130  static void _ResizeContainer(VtArray<T>* array,
131  size_t size,
132  const T& defaultValue);
133 
134  template <typename Container>
135  static void _ResizeContainer(
136  Container* container,
137  size_t size,
138  const typename Container::value_type& defaultValue,
139  typename std::enable_if<
141  Container>::type* = 0)
142  { container->resize(size, defaultValue); }
143 
145  bool _IsOrdered() const;
146 
147  /// Size of the output map.
148  size_t _targetSize;
149 
150  /// For ordered mappings, an offset into the output array at which
151  /// to map the source data.
152  size_t _offset;
153 
154  /// For unordered mappings, an index map, mapping from source
155  /// indices to target indices.
156  VtIntArray _indexMap;
157  int _flags;
158 };
159 
160 
161 template <typename T>
162 void
163 UsdSkelAnimMapper::_ResizeContainer(VtArray<T>* array, size_t size,
164  const T& defaultValue)
165 {
166  // XXX: VtArray::resize() doesn't take an default value atm.
167  // We should fix this...
168  const size_t prevSize = array->size();
169  array->resize(size);
170  auto span = TfMakeSpan(*array);
171  for(size_t i = prevSize; i < size; ++i) {
172  span[i] = defaultValue;
173  }
174 }
175 
176 
177 template <typename Container>
178 bool
179 UsdSkelAnimMapper::Remap(const Container& source,
180  Container* target,
181  int elementSize,
182  const typename Container::value_type* defaultValue) const
183 {
184  using _ValueType = typename Container::value_type;
185 
186  if (!target) {
187  TF_CODING_ERROR("'target' is null");
188  return false;
189  }
190  if (elementSize <= 0) {
191  TF_WARN("Invalid elementSize [%d]: "
192  "size must be greater than zero.", elementSize);
193  return false;
194  }
195 
196  const size_t targetArraySize = _targetSize*elementSize;
197 
198  if (IsIdentity() && source.size() == targetArraySize) {
199  // Can make copy of the array.
200  *target = source;
201  return true;
202  }
203 
204  // Resize the target array to the expected size.
205  _ResizeContainer(target, targetArraySize,
206  defaultValue ? *defaultValue : _ValueType());
207 
208  if (IsNull()) {
209  return true;
210  } else if (_IsOrdered()) {
211 
212  size_t copyCount =
213  std::min(source.size(), targetArraySize - _offset*elementSize);
214  std::copy(source.cdata(), source.cdata()+copyCount,
215  target->data() + _offset*elementSize);
216  } else {
217 
218  const _ValueType* sourceData = source.cdata();
219 
220  _ValueType* targetData = target->data();
221  size_t copyCount = std::min(source.size()/elementSize,
222  _indexMap.size());
223 
224  const int* indexMap = _indexMap.data();
225 
226  for (size_t i = 0; i < copyCount; ++i) {
227  int targetIdx = indexMap[i];
228  if (targetIdx >= 0 &&
229  static_cast<size_t>(targetIdx) < target->size()) {
230  TF_DEV_AXIOM(i*elementSize < source.size());
231  TF_DEV_AXIOM((i+1)*elementSize <= source.size());
232  TF_DEV_AXIOM(static_cast<size_t>((targetIdx+1)*elementSize)
233  <= target->size());
234  std::copy(sourceData + i*elementSize,
235  sourceData + (i+1)*elementSize,
236  targetData + targetIdx*elementSize);
237  }
238  }
239  }
240  return true;
241 }
242 
243 
245 
246 #endif // PXR_USD_USD_SKEL_ANIM_MAPPER_H
bool Remap(const Container &source, Container *target, int elementSize=1, const typename Container::value_type *defaultValue=nullptr) const
Definition: animMapper.h:179
USDSKEL_API bool RemapTransforms(const VtArray< Matrix4 > &source, VtArray< Matrix4 > *target, int elementSize=1) const
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
Definition: span.h:74
#define TF_CODING_ERROR
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
uint64 value_type
Definition: GA_PrimCompat.h:29
#define TF_DEV_AXIOM(cond)
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
Definition: token.h:70
std::shared_ptr< class UsdSkelAnimMapper > UsdSkelAnimMapperRefPtr
Definition: animMapper.h:28
bool operator!=(const UsdSkelAnimMapper &o) const
Definition: animMapper.h:119
#define TF_WARN
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
GLenum target
Definition: glcorearb.h:1667
USDSKEL_API bool IsNull() const
#define USDSKEL_API
Definition: api.h:23
Definition: types.h:153
USDSKEL_API bool IsSparse() const
Array concept. By default, types are not arrays.
Definition: traits.h:22
GLsizeiptr size
Definition: glcorearb.h:664
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
USDSKEL_API bool IsIdentity() const
bool operator==(const UsdSkelAnimMapper &o) const
USDSKEL_API size_t size() const
Definition: animMapper.h:115
TfSpan< typename Container::value_type > TfMakeSpan(Container &cont)
Helper for constructing a non-const TfSpan from a container.
Definition: span.h:224
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
USDSKEL_API UsdSkelAnimMapper()
Construct a null mapper.
Definition: value.h:146