HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mapFunction.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 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"
32 
33 #include <atomic>
34 #include <memory>
35 
37 
38 /// \class PcpMapFunction
39 ///
40 /// A function that maps values from one namespace (and time domain) to
41 /// another. It represents the transformation that an arc such as a reference
42 /// arc applies as it incorporates values across the arc.
43 ///
44 /// Take the example of a reference arc, where a source path
45 /// </Model> is referenced as a target path, </Model_1>.
46 /// The source path </Model> is the source of the opinions;
47 /// the target path </Model_1> is where they are incorporated in the scene.
48 /// Values in the model that refer to paths relative to </Model> must be
49 /// transformed to be relative to </Model_1> instead.
50 /// The PcpMapFunction for the arc provides this service.
51 ///
52 /// Map functions have a specific \em domain, or set of values they can
53 /// operate on. Any values outside the domain cannot be mapped.
54 /// The domain precisely tracks what areas of namespace can be
55 /// referred to across various forms of arcs.
56 ///
57 /// Map functions can be chained to represent a series of map
58 /// operations applied in sequence. The map function represent the
59 /// cumulative effect as efficiently as possible. For example, in
60 /// the case of a chained reference from </Model> to </Model>
61 /// to </Model> to </Model_1>, this is effectively the same as
62 /// a mapping directly from </Model> to </Model_1>. Representing
63 /// the cumulative effect of arcs in this way is important for
64 /// handling larger scenes efficiently.
65 ///
66 /// Map functions can be \em inverted. Formally, map functions are
67 /// bijections (one-to-one and onto), which ensures that they can
68 /// be inverted. Put differently, no information is lost by applying
69 /// a map function to set of values within its domain; they retain
70 /// their distinct identities and can always be mapped back.
71 ///
72 /// One analogy that may or may not be helpful:
73 /// In the same way a geometric transform maps a model's points in its
74 /// rest space into the world coordinates for a particular instance,
75 /// a PcpMapFunction maps values about a referenced model into the
76 /// composed scene for a particular instance of that model. But rather
77 /// than translating and rotating points, the map function shifts the
78 /// values in namespace (and time).
79 ///
80 ///
82 {
83 public:
84  /// A mapping from path to path.
85  typedef std::map<SdfPath, SdfPath, SdfPath::FastLessThan> PathMap;
86  typedef std::pair<SdfPath, SdfPath> PathPair;
87  typedef std::vector<PathPair> PathPairVector;
88 
89  /// Construct a null function.
90  PcpMapFunction() = default;
91 
92  /// Constructs a map function with the given arguments.
93  /// Returns a null map function on error (see IsNull()).
94  ///
95  /// \param sourceToTargetMap The map from source paths to target paths.
96  /// \param offset The time offset to apply from source to target.
97  ///
98  PCP_API
99  static PcpMapFunction
100  Create(const PathMap &sourceToTargetMap,
101  const SdfLayerOffset &offset);
102 
103  /// Construct an identity map function.
104  PCP_API
105  static const PcpMapFunction &Identity();
106 
107  /// Returns an identity path mapping.
108  PCP_API
109  static const PathMap &IdentityPathMap();
110 
111  /// Swap the contents of this map function with \p map.
112  PCP_API
113  void Swap(PcpMapFunction &map);
114  void swap(PcpMapFunction &map) { Swap(map); }
115 
116  /// Equality.
117  PCP_API
118  bool operator==(const PcpMapFunction &map) const;
119 
120  /// Inequality.
121  PCP_API
122  bool operator!=(const PcpMapFunction &map) const;
123 
124  /// Return true if this map function is the null function.
125  /// For a null function, MapSourceToTarget() always returns an empty path.
126  PCP_API
127  bool IsNull() const;
128 
129  /// Return true if the map function is the identity function.
130  /// The identity function has an identity path mapping and time offset.
131  PCP_API
132  bool IsIdentity() const;
133 
134  /// Return true if the map function uses the identity path mapping.
135  /// If true, MapSourceToTarget() always returns the path unchanged.
136  /// However, this map function may have a non-identity time offset.
137  PCP_API
138  bool IsIdentityPathMapping() const;
139 
140  /// Return true if the map function maps the absolute root path to the
141  /// absolute root path, false otherwise.
142  bool HasRootIdentity() const { return _data.hasRootIdentity; }
143 
144  /// Map a path in the source namespace to the target.
145  /// If the path is not in the domain, returns an empty path.
146  PCP_API
147  SdfPath MapSourceToTarget(const SdfPath &path) const;
148 
149  /// Map a path in the target namespace to the source.
150  /// If the path is not in the co-domain, returns an empty path.
151  PCP_API
152  SdfPath MapTargetToSource(const SdfPath &path) const;
153 
154  /// Map all path pattern prefix paths and expression reference paths in the
155  /// source namespace to the target. For any references or patterns with
156  /// prefix paths that are not in the domain, replace with an
157  /// SdfPathPattern::Nothing() subexpression, to be simplified.
158  ///
159  /// For example, if the mapping specifies /Foo -> /World/Foo_1, and the
160  /// expression is '/Foo/Bar//Baz + /Something/Else//Entirely', the resulting
161  /// expression will be '/World/Foo_1/Bar//Baz', since the
162  /// /Something/Else prefix is outside the domain.
163  ///
164  /// If \p excludedPatterns and/or \p excludedReferences are supplied, they
165  /// are populated with those patterns & references that could not be
166  /// translated and were replaced with SdfPathPattern::Nothing().
167  PCP_API
170  const SdfPathExpression &pathExpr,
171  std::vector<SdfPathExpression::PathPattern>
172  *unmappedPatterns = nullptr,
173  std::vector<SdfPathExpression::ExpressionReference>
174  *unmappedRefs = nullptr
175  ) const;
176 
177  /// Map all path pattern prefix paths and expression reference paths in the
178  /// target namespace to the source. For any references or patterns with
179  /// prefix paths that are not in the co-domain, replace with an
180  /// SdfPathPattern::Nothing() subexpression, to be simplified.
181  ///
182  /// For example, if the mapping specifies /World/Foo_1 -> /Foo, and the
183  /// expression is '/World/Foo_1/Bar//Baz + /World/Bar//', the resulting
184  /// expression will be '/Foo/Bar//Baz', since the /World/Bar prefix is
185  /// outside the co-domain.
186  ///
187  /// If \p excludedPatterns and/or \p excludedReferences are supplied, they
188  /// are populated with those patterns & references that could not be
189  /// translated and were replaced with SdfPathPattern::Nothing().
190  PCP_API
193  const SdfPathExpression &pathExpr,
194  std::vector<SdfPathExpression::PathPattern>
195  *unmappedPatterns = nullptr,
196  std::vector<SdfPathExpression::ExpressionReference>
197  *unmappedRefs = nullptr
198  ) const;
199 
200  /// Compose this map over the given map function.
201  /// The result will represent the application of f followed by
202  /// the application of this function.
203  PCP_API
204  PcpMapFunction Compose(const PcpMapFunction &f) const;
205 
206  /// Compose this map function over a hypothetical map function that has an
207  /// identity path mapping and \p offset. This is equivalent to building
208  /// such a map function and invoking Compose(), but is faster.
209  PCP_API
210  PcpMapFunction ComposeOffset(const SdfLayerOffset &newOffset) const;
211 
212  /// Return the inverse of this map function.
213  /// This returns a true inverse \p inv: for any path p in this function's
214  /// domain that it maps to p', inv(p') -> p.
215  PCP_API
216  PcpMapFunction GetInverse() const;
217 
218  /// The set of path mappings, from source to target.
219  PCP_API
221 
222  /// The time offset of the mapping.
223  const SdfLayerOffset &GetTimeOffset() const { return _offset; }
224 
225  /// Returns a string representation of this mapping for debugging
226  /// purposes.
227  PCP_API
228  std::string GetString() const;
229 
230  /// Return a size_t hash for this map function.
231  PCP_API
232  size_t Hash() const;
233 
234 private:
235 
236  PCP_API
237  PcpMapFunction(PathPair const *sourceToTargetBegin,
238  PathPair const *sourceToTargetEnd,
240  bool hasRootIdentity);
241 
242  PCP_API
244  _MapPathExpressionImpl(
245  bool invert,
246  const SdfPathExpression &pathExpr,
247  std::vector<SdfPathExpression::PathPattern> *unmappedPatterns,
248  std::vector<SdfPathExpression::ExpressionReference> *unmappedRefs
249  ) const;
250 
251 private:
253 
254  static const int _MaxLocalPairs = 2;
255  struct _Data final {
256  _Data() {};
257 
258  _Data(PathPair const *begin, PathPair const *end, bool hasRootIdentity)
259  : numPairs(end-begin)
260  , hasRootIdentity(hasRootIdentity) {
261  if (numPairs == 0)
262  return;
263  if (numPairs <= _MaxLocalPairs) {
264  std::uninitialized_copy(begin, end, localPairs);
265  }
266  else {
267  new (&remotePairs) std::shared_ptr<PathPair>(
268  new PathPair[numPairs], std::default_delete<PathPair[]>());
269  std::copy(begin, end, remotePairs.get());
270  }
271  }
272 
273  _Data(_Data const &other)
274  : numPairs(other.numPairs)
275  , hasRootIdentity(other.hasRootIdentity) {
276  if (numPairs <= _MaxLocalPairs) {
277  std::uninitialized_copy(
278  other.localPairs,
279  other.localPairs + other.numPairs, localPairs);
280  }
281  else {
282  new (&remotePairs) std::shared_ptr<PathPair>(other.remotePairs);
283  }
284  }
285  _Data(_Data &&other)
286  : numPairs(other.numPairs)
287  , hasRootIdentity(other.hasRootIdentity) {
288  if (numPairs <= _MaxLocalPairs) {
289  PathPair *dst = localPairs;
290  PathPair *src = other.localPairs;
291  PathPair *srcEnd = other.localPairs + other.numPairs;
292  for (; src != srcEnd; ++src, ++dst) {
293  ::new (static_cast<void*>(std::addressof(*dst)))
294  PathPair(std::move(*src));
295  }
296  }
297  else {
298  new (&remotePairs)
299  std::shared_ptr<PathPair>(std::move(other.remotePairs));
300  }
301  }
302  _Data &operator=(_Data const &other) {
303  if (this != &other) {
304  this->~_Data();
305  new (this) _Data(other);
306  }
307  return *this;
308  }
309  _Data &operator=(_Data &&other) {
310  if (this != &other) {
311  this->~_Data();
312  new (this) _Data(std::move(other));
313  }
314  return *this;
315  }
316  ~_Data() {
317  if (numPairs <= _MaxLocalPairs) {
318  for (PathPair *p = localPairs; numPairs--; ++p) {
319  p->~PathPair();
320  }
321  }
322  else {
323  remotePairs.~shared_ptr<PathPair>();
324  }
325  }
326 
327  bool IsNull() const {
328  return numPairs == 0 && !hasRootIdentity;
329  }
330 
331  PathPair const *begin() const {
332  return numPairs <= _MaxLocalPairs ? localPairs : remotePairs.get();
333  }
334 
335  PathPair const *end() const {
336  return begin() + numPairs;
337  }
338 
339  bool operator==(_Data const &other) const {
340  return numPairs == other.numPairs &&
341  hasRootIdentity == other.hasRootIdentity &&
342  std::equal(begin(), end(), other.begin());
343  }
344 
345  bool operator!=(_Data const &other) const {
346  return !(*this == other);
347  }
348 
349  template <class HashState>
350  friend void TfHashAppend(HashState &h, _Data const &data){
351  h.Append(data.hasRootIdentity);
352  h.Append(data.numPairs);
353  h.AppendRange(std::begin(data), std::end(data));
354  }
355 
356  union {
357  PathPair localPairs[_MaxLocalPairs > 0 ? _MaxLocalPairs : 1];
358  std::shared_ptr<PathPair> remotePairs;
359  };
360  typedef int PairCount;
361  PairCount numPairs = 0;
362  bool hasRootIdentity = false;
363  };
364 
365  // Specialize TfHashAppend for PcpMapFunction.
366  template <typename HashState>
367  friend inline
368  void TfHashAppend(HashState& h, const PcpMapFunction& x){
369  h.Append(x._data);
370  h.Append(x._offset);
371  }
372 
373  _Data _data;
374  SdfLayerOffset _offset;
375 };
376 
377 // Specialize hash_value for PcpMapFunction.
378 inline
380 {
381  return TfHash{}(x);
382 }
383 
385 
386 #endif // PXR_USD_PCP_MAP_FUNCTION_H
PCP_API size_t Hash() const
Return a size_t hash for this map function.
PCP_API bool IsIdentityPathMapping() const
PCP_API PathMap GetSourceToTargetMap() const
The set of path mappings, from source to target.
static PCP_API const PcpMapFunction & Identity()
Construct an identity map function.
GLboolean invert
Definition: glcorearb.h:549
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
PCP_API bool IsIdentity() const
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
static PCP_API const PathMap & IdentityPathMap()
Returns an identity path mapping.
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
PCP_API bool operator!=(const PcpMapFunction &map) const
Inequality.
PCP_API SdfPath MapSourceToTarget(const SdfPath &path) const
static PCP_API PcpMapFunction Create(const PathMap &sourceToTargetMap, const SdfLayerOffset &offset)
friend PcpMapFunction * Pcp_MakeIdentity()
IMATH_HOSTDEVICE constexpr bool equal(T1 a, T2 b, T3 t) IMATH_NOEXCEPT
Definition: ImathFun.h:105
PCP_API bool operator==(const PcpMapFunction &map) const
Equality.
const SdfLayerOffset & GetTimeOffset() const
The time offset of the mapping.
Definition: mapFunction.h:223
Definition: hash.h:477
GLfloat f
Definition: glcorearb.h:1926
GLintptr offset
Definition: glcorearb.h:665
friend void TfHashAppend(HashState &h, const PcpMapFunction &x)
Definition: mapFunction.h:368
std::map< SdfPath, SdfPath, SdfPath::FastLessThan > PathMap
A mapping from path to path.
Definition: mapFunction.h:85
std::pair< SdfPath, SdfPath > PathPair
Definition: mapFunction.h:86
GLuint GLuint end
Definition: glcorearb.h:475
Definition: path.h:290
GLint GLenum GLint x
Definition: glcorearb.h:409
void swap(PcpMapFunction &map)
Definition: mapFunction.h:114
std::vector< PathPair > PathPairVector
Definition: mapFunction.h:87
PCP_API PcpMapFunction Compose(const PcpMapFunction &f) const
PCP_API void Swap(PcpMapFunction &map)
Swap the contents of this map function with map.
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
GLenum GLenum dst
Definition: glcorearb.h:1793
PCP_API PcpMapFunction GetInverse() const
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1432
PcpMapFunction()=default
Construct a null function.
LeafData & operator=(const LeafData &)=delete
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
bool HasRootIdentity() const
Definition: mapFunction.h:142
size_t hash_value(const PcpMapFunction &x)
Definition: mapFunction.h:379
PCP_API std::string GetString() const
PCP_API SdfPath MapTargetToSource(const SdfPath &path) const
PCP_API bool IsNull() const
PCP_API PcpMapFunction ComposeOffset(const SdfLayerOffset &newOffset) const
Definition: format.h:895
#define PCP_API
Definition: api.h:40
GLenum src
Definition: glcorearb.h:1793
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:558