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 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 USDSKEL_ANIMMAPPER_H
25 #define USDSKEL_ANIMMAPPER_H
26 
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/usdSkel/api.h"
31 
32 #include "pxr/base/gf/matrix4d.h"
33 #include "pxr/base/gf/matrix4f.h"
34 #include "pxr/base/tf/span.h"
35 #include "pxr/base/vt/array.h"
36 #include "pxr/usd/sdf/types.h"
37 
38 #include <type_traits>
39 #include <vector>
40 
41 
42 PXR_NAMESPACE_OPEN_SCOPE
43 
44 
45 using UsdSkelAnimMapperRefPtr = std::shared_ptr<class UsdSkelAnimMapper>;
46 
47 
52 class UsdSkelAnimMapper {
53 public:
55  USDSKEL_API
56  UsdSkelAnimMapper();
57 
60  USDSKEL_API
61  UsdSkelAnimMapper(size_t size);
62 
65  USDSKEL_API
66  UsdSkelAnimMapper(const VtTokenArray& sourceOrder,
67  const VtTokenArray& targetOrder);
68 
72  USDSKEL_API
73  UsdSkelAnimMapper(const TfToken* sourceOrder, size_t sourceOrderSize,
74  const TfToken* targetOrder, size_t targetOrderSize);
75 
84  template <typename Container>
85  bool Remap(const Container& source,
86  Container* target,
87  int elementSize=1,
88  const typename Container::value_type*
89  defaultValue=nullptr) const;
90 
100  USDSKEL_API
101  bool Remap(const VtValue& source, VtValue* target,
102  int elementSize=1, const VtValue& defaultValue=VtValue()) const;
103 
107  template <typename Matrix4>
108  USDSKEL_API
109  bool RemapTransforms(const VtArray<Matrix4>& source,
110  VtArray<Matrix4>* target,
111  int elementSize=1) const;
112 
115  USDSKEL_API
116  bool IsIdentity() const;
117 
121  USDSKEL_API
122  bool IsSparse() const;
123 
126  USDSKEL_API
127  bool IsNull() const;
128 
131  USDSKEL_API
132  size_t size() const { return _targetSize; }
133 
134  bool operator==(const UsdSkelAnimMapper& o) const;
135 
136  bool operator!=(const UsdSkelAnimMapper& o) const {
137  return !(*this == o);
138  }
139 
140 private:
141 
142  template <typename T>
143  bool _UntypedRemap(const VtValue& source, VtValue* target,
144  int elementSize, const VtValue& defaultValue) const;
145 
146  template <typename T>
147  static void _ResizeContainer(VtArray<T>* array,
148  size_t size,
149  const T& defaultValue);
150 
151  template <typename Container>
152  static void _ResizeContainer(
153  Container* container,
154  size_t size,
155  const typename Container::value_type& defaultValue,
156  typename std::enable_if<
158  Container>::type* = 0)
159  { container->resize(size, defaultValue); }
160 
161  USDSKEL_API
162  bool _IsOrdered() const;
163 
165  size_t _targetSize;
166 
169  size_t _offset;
170 
173  VtIntArray _indexMap;
174  int _flags;
175 };
176 
177 
178 template <typename T>
179 void
180 UsdSkelAnimMapper::_ResizeContainer(VtArray<T>* array, size_t size,
181  const T& defaultValue)
182 {
183  // XXX: VtArray::resize() doesn't take an default value atm.
184  // We should fix this...
185  const size_t prevSize = array->size();
186  array->resize(size);
187  auto span = TfMakeSpan(*array);
188  for(size_t i = prevSize; i < size; ++i) {
189  span[i] = defaultValue;
190  }
191 }
192 
193 
194 template <typename Container>
195 bool
196 UsdSkelAnimMapper::Remap(const Container& source,
197  Container* target,
198  int elementSize,
199  const typename Container::value_type* defaultValue) const
200 {
201  using _ValueType = typename Container::value_type;
202 
203  if (!target) {
204  TF_CODING_ERROR("'target' is null");
205  return false;
206  }
207  if (elementSize <= 0) {
208  TF_WARN("Invalid elementSize [%d]: "
209  "size must be greater than zero.", elementSize);
210  return false;
211  }
212 
213  const size_t targetArraySize = _targetSize*elementSize;
214 
215  if (IsIdentity() && source.size() == targetArraySize) {
216  // Can make copy of the array.
217  *target = source;
218  return true;
219  }
220 
221  // Resize the target array to the expected size.
222  _ResizeContainer(target, targetArraySize,
223  defaultValue ? *defaultValue : _ValueType());
224 
225  if (IsNull()) {
226  return true;
227  } else if (_IsOrdered()) {
228 
229  size_t copyCount =
230  std::min(source.size(), targetArraySize - _offset*elementSize);
231  std::copy(source.cdata(), source.cdata()+copyCount,
232  target->data() + _offset*elementSize);
233  } else {
234 
235  const _ValueType* sourceData = source.cdata();
236 
237  _ValueType* targetData = target->data();
238  size_t copyCount = std::min(source.size()/elementSize,
239  _indexMap.size());
240 
241  const int* indexMap = _indexMap.data();
242 
243  for (size_t i = 0; i < copyCount; ++i) {
244  int targetIdx = indexMap[i];
245  if (targetIdx >= 0 &&
246  static_cast<size_t>(targetIdx) < target->size()) {
247  TF_DEV_AXIOM(i*elementSize < source.size());
248  TF_DEV_AXIOM((i+1)*elementSize <= source.size());
249  TF_DEV_AXIOM(static_cast<size_t>((targetIdx+1)*elementSize)
250  <= target->size());
251  std::copy(sourceData + i*elementSize,
252  sourceData + (i+1)*elementSize,
253  targetData + targetIdx*elementSize);
254  }
255  }
256  }
257  return true;
258 }
259 
260 
261 PXR_NAMESPACE_CLOSE_SCOPE
262 
263 #endif // USDSKEL_ANIMMAPPER_H
#define TF_DEV_AXIOM(cond)
The same as TF_AXIOM, but compiled only in dev builds.
Definition: diagnostic.h:227
#define TF_WARN(...)
Issue a warning, but continue execution.
Definition: diagnostic.h:153
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:87
void resize(size_t newSize)
Resize this array.
Definition: array.h:481
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:89
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
Array concept. By default, types are not arrays.
Definition: traits.h:41
VT_API bool operator==(VtDictionary const &, VtDictionary const &)
Equality comparison.
TfSpan< typename Container::value_type > TfMakeSpan(Container &cont)
Helper for constructing a non-const TfSpan from a container.
Definition: span.h:218
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:182