mapFunction.h
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 PXR_USD_PCP_MAP_FUNCTION_H
25 #define PXR_USD_PCP_MAP_FUNCTION_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/usd/pcp/api.h"
29 #include "pxr/usd/sdf/path.h"
31 
32 #include <atomic>
33 #include <memory>
34 
35 PXR_NAMESPACE_OPEN_SCOPE
36 
81 {
82 public:
84  typedef std::map<SdfPath, SdfPath, SdfPath::FastLessThan> PathMap;
85  typedef std::pair<SdfPath, SdfPath> PathPair;
86  typedef std::vector<PathPair> PathPairVector;
87 
89  PcpMapFunction() = default;
90 
97  PCP_API
98  static PcpMapFunction
99  Create(const PathMap &sourceToTargetMap,
100  const SdfLayerOffset &offset);
101 
103  PCP_API
104  static const PcpMapFunction &Identity();
105 
107  PCP_API
108  static const PathMap &IdentityPathMap();
109 
111  PCP_API
112  void Swap(PcpMapFunction &map);
113  void swap(PcpMapFunction &map) { Swap(map); }
114 
116  PCP_API
117  bool operator==(const PcpMapFunction &map) const;
118 
120  PCP_API
121  bool operator!=(const PcpMapFunction &map) const;
122 
125  PCP_API
126  bool IsNull() const;
127 
130  PCP_API
131  bool IsIdentity() const;
132 
136  PCP_API
137  bool IsIdentityPathMapping() const;
138 
141  bool HasRootIdentity() const { return _data.hasRootIdentity; }
142 
145  PCP_API
146  SdfPath MapSourceToTarget(const SdfPath &path) const;
147 
150  PCP_API
151  SdfPath MapTargetToSource(const SdfPath &path) const;
152 
156  PCP_API
157  PcpMapFunction Compose(const PcpMapFunction &f) const;
158 
162  PCP_API
163  PcpMapFunction ComposeOffset(const SdfLayerOffset &newOffset) const;
164 
168  PCP_API
169  PcpMapFunction GetInverse() const;
170 
172  PCP_API
174 
176  const SdfLayerOffset &GetTimeOffset() const { return _offset; }
177 
180  PCP_API
181  std::string GetString() const;
182 
184  PCP_API
185  size_t Hash() const;
186 
187 private:
188 
189  PCP_API
190  PcpMapFunction(PathPair const *sourceToTargetBegin,
191  PathPair const *sourceToTargetEnd,
192  SdfLayerOffset offset,
193  bool hasRootIdentity);
194 
195 private:
196  friend PcpMapFunction *Pcp_MakeIdentity();
197 
198  static const int _MaxLocalPairs = 2;
199  struct _Data final {
200  _Data() {};
201 
202  _Data(PathPair const *begin, PathPair const *end, bool hasRootIdentity)
203  : numPairs(end-begin)
204  , hasRootIdentity(hasRootIdentity) {
205  if (numPairs == 0)
206  return;
207  if (numPairs <= _MaxLocalPairs) {
208  std::uninitialized_copy(begin, end, localPairs);
209  }
210  else {
211  new (&remotePairs) std::shared_ptr<PathPair>(
212  new PathPair[numPairs], std::default_delete<PathPair[]>());
213  std::copy(begin, end, remotePairs.get());
214  }
215  }
216 
217  _Data(_Data const &other)
218  : numPairs(other.numPairs)
219  , hasRootIdentity(other.hasRootIdentity) {
220  if (numPairs <= _MaxLocalPairs) {
221  std::uninitialized_copy(
222  other.localPairs,
223  other.localPairs + other.numPairs, localPairs);
224  }
225  else {
226  new (&remotePairs) std::shared_ptr<PathPair>(other.remotePairs);
227  }
228  }
229  _Data(_Data &&other)
230  : numPairs(other.numPairs)
231  , hasRootIdentity(other.hasRootIdentity) {
232  if (numPairs <= _MaxLocalPairs) {
233  PathPair *dst = localPairs;
234  PathPair *src = other.localPairs;
235  PathPair *srcEnd = other.localPairs + other.numPairs;
236  for (; src != srcEnd; ++src, ++dst) {
237  ::new (static_cast<void*>(std::addressof(*dst)))
238  PathPair(std::move(*src));
239  }
240  }
241  else {
242  new (&remotePairs)
243  std::shared_ptr<PathPair>(std::move(other.remotePairs));
244  }
245  }
246  _Data &operator=(_Data const &other) {
247  if (this != &other) {
248  this->~_Data();
249  new (this) _Data(other);
250  }
251  return *this;
252  }
253  _Data &operator=(_Data &&other) {
254  if (this != &other) {
255  this->~_Data();
256  new (this) _Data(std::move(other));
257  }
258  return *this;
259  }
260  ~_Data() {
261  if (numPairs <= _MaxLocalPairs) {
262  for (PathPair *p = localPairs; numPairs--; ++p) {
263  p->~PathPair();
264  }
265  }
266  else {
267  remotePairs.~shared_ptr<PathPair>();
268  }
269  }
270 
271  bool IsNull() const {
272  return numPairs == 0 && !hasRootIdentity;
273  }
274 
275  PathPair const *begin() const {
276  return numPairs <= _MaxLocalPairs ? localPairs : remotePairs.get();
277  }
278 
279  PathPair const *end() const {
280  return begin() + numPairs;
281  }
282 
283  bool operator==(_Data const &other) const {
284  return numPairs == other.numPairs &&
285  hasRootIdentity == other.hasRootIdentity &&
286  std::equal(begin(), end(), other.begin());
287  }
288 
289  bool operator!=(_Data const &other) const {
290  return !(*this == other);
291  }
292 
293  union {
294  PathPair localPairs[_MaxLocalPairs > 0 ? _MaxLocalPairs : 1];
295  std::shared_ptr<PathPair> remotePairs;
296  };
297  typedef int PairCount;
298  PairCount numPairs = 0;
299  bool hasRootIdentity = false;
300  };
301 
302  _Data _data;
303  SdfLayerOffset _offset;
304 };
305 
306 // Specialize hash_value for PcpMapFunction.
307 inline
308 size_t hash_value(const PcpMapFunction& x)
309 {
310  return x.Hash();
311 }
312 
313 PXR_NAMESPACE_CLOSE_SCOPE
314 
315 #endif // PXR_USD_PCP_MAP_FUNCTION_H
PCP_API bool operator!=(const PcpMapFunction &map) const
Inequality.
const SdfLayerOffset & GetTimeOffset() const
The time offset of the mapping.
Definition: mapFunction.h:176
PCP_API PathMap GetSourceToTargetMap() const
The set of path mappings, from source to target.
PCP_API bool IsIdentityPathMapping() const
Return true if the map function uses the identity path mapping.
PCP_API bool IsNull() const
Return true if this map function is the null function.
PcpMapFunction()=default
Construct a null function.
PCP_API bool IsIdentity() const
Return true if the map function is the identity function.
bool HasRootIdentity() const
Return true if the map function maps the absolute root path to the absolute root path,...
Definition: mapFunction.h:141
PCP_API PcpMapFunction Compose(const PcpMapFunction &f) const
Compose this map over the given map function.
PCP_API std::string GetString() const
Returns a string representation of this mapping for debugging purposes.
static PCP_API const PathMap & IdentityPathMap()
Returns an identity path mapping.
A function that maps values from one namespace (and time domain) to another.
Definition: mapFunction.h:80
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:290
PCP_API PcpMapFunction GetInverse() const
Return the inverse of this map function.
std::map< SdfPath, SdfPath, SdfPath::FastLessThan > PathMap
A mapping from path to path.
Definition: mapFunction.h:84
PCP_API void Swap(PcpMapFunction &map)
Swap the contents of this map function with map.
PCP_API SdfPath MapTargetToSource(const SdfPath &path) const
Map a path in the target namespace to the source.
std::enable_if< std::is_same< Half, half >::value, size_t >::type hash_value(const Half &h)
Overload hash_value for half.
Definition: half.h:50
PCP_API PcpMapFunction ComposeOffset(const SdfLayerOffset &newOffset) const
Compose this map function over a hypothetical map function that has an identity path mapping and offs...
PCP_API bool operator==(const PcpMapFunction &map) const
Equality.
static PCP_API const PcpMapFunction & Identity()
Construct an identity map function.
PCP_API SdfPath MapSourceToTarget(const SdfPath &path) const
Map a path in the source namespace to the target.
Represents a time offset and scale between layers.
Definition: layerOffset.h:61
PCP_API size_t Hash() const
Return a size_t hash for this map function.
static PCP_API PcpMapFunction Create(const PathMap &sourceToTargetMap, const SdfLayerOffset &offset)
Constructs a map function with the given arguments.