All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
valueUtils.h
1 //
2 // Copyright 2017 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 USD_VALUE_UTILS_H
25 #define USD_VALUE_UTILS_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/usd/usd/clip.h"
29 #include "pxr/usd/usd/common.h"
30 
31 #include "pxr/usd/sdf/abstractData.h"
32 #include "pxr/usd/sdf/layer.h"
33 #include "pxr/usd/sdf/types.h"
34 
35 #include "pxr/base/vt/value.h"
36 
37 PXR_NAMESPACE_OPEN_SCOPE
38 
39 class Usd_InterpolatorBase;
40 
42 template <class T>
43 inline bool
44 Usd_ValueContainsBlock(const T* value)
45 {
46  return false;
47 }
48 
50 template <class T>
51 inline bool
52 Usd_ValueContainsBlock(const SdfValueBlock* value)
53 {
54  return value;
55 }
56 
58 inline bool
59 Usd_ValueContainsBlock(const VtValue* value)
60 {
61  return value && value->IsHolding<SdfValueBlock>();
62 }
63 
65 inline bool
66 Usd_ValueContainsBlock(const SdfAbstractDataValue* value)
67 {
68  return value && value->isValueBlock;
69 }
70 
72 inline bool
73 Usd_ValueContainsBlock(const SdfAbstractDataConstValue* value)
74 {
75  return value && value->valueType == typeid(SdfValueBlock);
76 }
77 
80 template <class T>
81 inline bool
82 Usd_ClearValueIfBlocked(T* value)
83 {
84  // We can't actually clear the value here, since there's
85  // no good API for doing so. If the value is holding a
86  // block, we just return true and rely on the consumer
87  // to act as if the value were cleared.
88  return Usd_ValueContainsBlock(value);
89 }
90 
92 inline bool
93 Usd_ClearValueIfBlocked(VtValue* value)
94 {
95  if (Usd_ValueContainsBlock(value)) {
96  *value = VtValue();
97  return true;
98  }
99 
100  return false;
101 }
102 
103 template <class T>
104 inline bool
105 Usd_QueryTimeSample(
106  const SdfLayerRefPtr& layer, const SdfPath& path,
107  double time, Usd_InterpolatorBase* interpolator, T* result)
108 {
109  return layer->QueryTimeSample(path, time, result);
110 }
111 
112 template <class T>
113 inline bool
114 Usd_QueryTimeSample(
115  const Usd_ClipRefPtr& clip, const SdfPath& path,
116  double time, Usd_InterpolatorBase* interpolator, T* result)
117 {
118  return clip->QueryTimeSample(path, time, interpolator, result);
119 }
120 
127 void
128 Usd_MergeTimeSamples(std::vector<double> * const timeSamples,
129  const std::vector<double> &additionalTimeSamples,
130  std::vector<double> * tempUnionTimeSamples=nullptr);
131 
132 // Helper that implements the various options for adding items to lists
133 // enumerated by UsdListPosition.
134 //
135 // If the list op is in explicit mode, the item will be inserted into the
136 // explicit list regardless of the list specified in the position enum.
137 //
138 // If the item already exists in the list, but not in the requested
139 // position, it will be moved to the requested position.
140 template <class PROXY>
141 void
142 Usd_InsertListItem(PROXY proxy, const typename PROXY::value_type &item,
143  UsdListPosition position)
144 {
145  typename PROXY::ListProxy list(/* unused */ SdfListOpTypeExplicit);
146  bool atFront = false;
147  switch (position) {
149  list = proxy.GetPrependedItems();
150  atFront = false;
151  break;
153  list = proxy.GetPrependedItems();
154  atFront = true;
155  break;
157  list = proxy.GetAppendedItems();
158  atFront = false;
159  break;
161  list = proxy.GetAppendedItems();
162  atFront = true;
163  break;
164  }
165 
166  // This function previously used SdfListEditorProxy::Add, which would
167  // update the explicit list if the list op was in explicit mode. Clients
168  // currently expect this behavior, so we need to maintain it regardless
169  // of the list specified in the postiion enum.
170  if (proxy.IsExplicit()) {
171  list = proxy.GetExplicitItems();
172  }
173 
174  if (list.empty()) {
175  list.Insert(-1, item);
176  } else {
177  const size_t pos = list.Find(item);
178  if (pos != size_t(-1)) {
179  const size_t targetPos = atFront ? 0 : list.size()-1;
180  if (pos == targetPos) {
181  // Item already exists in the right position.
182  return;
183  }
184  list.Erase(pos);
185  }
186  list.Insert(atFront ? 0 : -1, item);
187  }
188 }
189 
194 template <typename Fn>
195 void
196 Usd_ResolveValuesInDictionary(VtDictionary *dict, const Fn &resolveFunc)
197 {
198  for (auto& entry : *dict) {
199  VtValue& v = entry.second;
200  if (v.IsHolding<VtDictionary>()) {
201  VtDictionary resolvedDict;
202  v.UncheckedSwap(resolvedDict);
203  Usd_ResolveValuesInDictionary(&resolvedDict, resolveFunc);
204  v.UncheckedSwap(resolvedDict);
205  }
206  else {
207  resolveFunc(&v);
208  }
209  }
210 }
211 
215 void
216 Usd_ApplyLayerOffsetToValue(VtValue *value, const SdfLayerOffset &offset);
217 
219 inline void
220 Usd_ApplyLayerOffsetToValue(SdfTimeCode *value, const SdfLayerOffset &offset)
221 {
222  *value = offset * (*value);
223 }
224 
226 inline void
227 Usd_ApplyLayerOffsetToValue(VtArray<SdfTimeCode> *value,
228  const SdfLayerOffset &offset)
229 {
230  for (SdfTimeCode &timeCode : *value) {
231  timeCode = offset * timeCode;
232  }
233 }
234 
236 inline void
237 Usd_ApplyLayerOffsetToValue(SdfTimeSampleMap *value,
238  const SdfLayerOffset &offset)
239 {
240  // Swap the original map so we can write new values back into the original
241  // value.
242  SdfTimeSampleMap origValue;
243  std::swap(origValue, *value);
244  for (const auto& sample : origValue) {
245  // Each time sample key must be mapped by the layer offset.
246  VtValue &newSample = (*value)[offset * sample.first];
247  newSample = std::move(sample.second);
248  // The value may also have be mapped if it is time mappable.
249  Usd_ApplyLayerOffsetToValue(&newSample, offset);
250  }
251 }
252 
254 inline void
255 Usd_ApplyLayerOffsetToValue(VtDictionary *value, const SdfLayerOffset &offset)
256 {
257  Usd_ResolveValuesInDictionary(value,
258  [&offset](VtValue *v)
259  {
260  Usd_ApplyLayerOffsetToValue(v, offset);
261  });
262 }
263 
264 PXR_NAMESPACE_CLOSE_SCOPE
265 
266 #endif // USD_VALUE_UTILS_H
The position at the front of the prepend list.
Definition: common.h:115
UsdListPosition
Specifies a position to add items to lists.
Definition: common.h:110
A type-erased container for a const field value in an SdfAbstractData.
Definition: abstractData.h:472
A type-erased container for a field value in an SdfAbstractData.
Definition: abstractData.h:394
A map with string keys and VtValue values.
Definition: dictionary.h:61
bool IsHolding() const
Return true if this value is holding an object of type T, false otherwise.
Definition: value.h:808
A special value type that can be used to explicitly author an opinion for an attribute&#39;s default valu...
Definition: types.h:561
The position at the front of the append list.
Definition: common.h:125
boost::enable_if< boost::is_same< T, typename Vt_ValueGetStored< T >::Type > >::type UncheckedSwap(T &rhs)
Swap the held value with rhs.
Definition: value.h:775
void swap(UsdStageLoadRules &l, UsdStageLoadRules &r)
Swap the contents of rules l and r.
Value type that represents a time code.
Definition: timeCode.h:44
Represents an arbitrary dimensional rectangular container class.
Definition: array.h:193
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:287
The position at the back of the append list.
Definition: common.h:130
The position at the back of the prepend list.
Definition: common.h:120
Represents a time offset and scale between layers.
Definition: layerOffset.h:61
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:182
std::map< double, VtValue > SdfTimeSampleMap
A map from sample times to sample values.
Definition: types.h:280