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"
31 
32 #include <atomic>
33 #include <memory>
34 
36 
37 /// \class PcpMapFunction
38 ///
39 /// A function that maps values from one namespace (and time domain) to
40 /// another. It represents the transformation that an arc such as a reference
41 /// arc applies as it incorporates values across the arc.
42 ///
43 /// Take the example of a reference arc, where a source path
44 /// </Model> is referenced as a target path, </Model_1>.
45 /// The source path </Model> is the source of the opinions;
46 /// the target path </Model_1> is where they are incorporated in the scene.
47 /// Values in the model that refer to paths relative to </Model> must be
48 /// transformed to be relative to </Model_1> instead.
49 /// The PcpMapFunction for the arc provides this service.
50 ///
51 /// Map functions have a specific \em domain, or set of values they can
52 /// operate on. Any values outside the domain cannot be mapped.
53 /// The domain precisely tracks what areas of namespace can be
54 /// referred to across various forms of arcs.
55 ///
56 /// Map functions can be chained to represent a series of map
57 /// operations applied in sequence. The map function represent the
58 /// cumulative effect as efficiently as possible. For example, in
59 /// the case of a chained reference from </Model> to </Model>
60 /// to </Model> to </Model_1>, this is effectively the same as
61 /// a mapping directly from </Model> to </Model_1>. Representing
62 /// the cumulative effect of arcs in this way is important for
63 /// handling larger scenes efficiently.
64 ///
65 /// Map functions can be \em inverted. Formally, map functions are
66 /// bijections (one-to-one and onto), which ensures that they can
67 /// be inverted. Put differently, no information is lost by applying
68 /// a map function to set of values within its domain; they retain
69 /// their distinct identities and can always be mapped back.
70 ///
71 /// One analogy that may or may not be helpful:
72 /// In the same way a geometric transform maps a model's points in its
73 /// rest space into the world coordinates for a particular instance,
74 /// a PcpMapFunction maps values about a referenced model into the
75 /// composed scene for a particular instance of that model. But rather
76 /// than translating and rotating points, the map function shifts the
77 /// values in namespace (and time).
78 ///
79 ///
81 {
82 public:
83  /// A mapping from path to path.
84  typedef std::map<SdfPath, SdfPath, SdfPath::FastLessThan> PathMap;
85  typedef std::pair<SdfPath, SdfPath> PathPair;
86  typedef std::vector<PathPair> PathPairVector;
87 
88  /// Construct a null function.
89  PcpMapFunction() = default;
90 
91  /// Constructs a map function with the given arguments.
92  /// Returns a null map function on error (see IsNull()).
93  ///
94  /// \param sourceToTargetMap The map from source paths to target paths.
95  /// \param offset The time offset to apply from source to target.
96  ///
97  PCP_API
98  static PcpMapFunction
99  Create(const PathMap &sourceToTargetMap,
100  const SdfLayerOffset &offset);
101 
102  /// Construct an identity map function.
103  PCP_API
104  static const PcpMapFunction &Identity();
105 
106  /// Returns an identity path mapping.
107  PCP_API
108  static const PathMap &IdentityPathMap();
109 
110  /// Swap the contents of this map function with \p map.
111  PCP_API
112  void Swap(PcpMapFunction &map);
113  void swap(PcpMapFunction &map) { Swap(map); }
114 
115  /// Equality.
116  PCP_API
117  bool operator==(const PcpMapFunction &map) const;
118 
119  /// Inequality.
120  PCP_API
121  bool operator!=(const PcpMapFunction &map) const;
122 
123  /// Return true if this map function is the null function.
124  /// For a null function, MapSourceToTarget() always returns an empty path.
125  PCP_API
126  bool IsNull() const;
127 
128  /// Return true if the map function is the identity function.
129  /// For identity, MapSourceToTarget() always returns the path unchanged.
130  PCP_API
131  bool IsIdentity() const;
132 
133  /// Return true if the map function maps the absolute root path to the
134  /// absolute root path, false otherwise.
135  bool HasRootIdentity() const { return _data.hasRootIdentity; }
136 
137  /// Map a path in the source namespace to the target.
138  /// If the path is not in the domain, returns an empty path.
139  PCP_API
140  SdfPath MapSourceToTarget(const SdfPath &path) const;
141 
142  /// Map a path in the target namespace to the source.
143  /// If the path is not in the co-domain, returns an empty path.
144  PCP_API
145  SdfPath MapTargetToSource(const SdfPath &path) const;
146 
147  /// Compose this map over the given map function.
148  /// The result will represent the application of f followed by
149  /// the application of this function.
150  PCP_API
151  PcpMapFunction Compose(const PcpMapFunction &f) const;
152 
153  /// Compose this map function over a hypothetical map function that has an
154  /// identity path mapping and \p offset. This is equivalent to building
155  /// such a map function and invoking Compose(), but is faster.
156  PCP_API
157  PcpMapFunction ComposeOffset(const SdfLayerOffset &newOffset) const;
158 
159  /// Return the inverse of this map function.
160  /// This returns a true inverse \p inv: for any path p in this function's
161  /// domain that it maps to p', inv(p') -> p.
162  PCP_API
163  PcpMapFunction GetInverse() const;
164 
165  /// The set of path mappings, from source to target.
166  PCP_API
168 
169  /// The time offset of the mapping.
170  const SdfLayerOffset &GetTimeOffset() const { return _offset; }
171 
172  /// Returns a string representation of this mapping for debugging
173  /// purposes.
174  PCP_API
175  std::string GetString() const;
176 
177  /// Return a size_t hash for this map function.
178  PCP_API
179  size_t Hash() const;
180 
181 private:
182 
183  PCP_API
184  PcpMapFunction(PathPair const *sourceToTargetBegin,
185  PathPair const *sourceToTargetEnd,
187  bool hasRootIdentity);
188 
189 private:
191 
192  static const int _MaxLocalPairs = 2;
193  struct _Data final {
194  _Data() {};
195 
196  _Data(PathPair const *begin, PathPair const *end, bool hasRootIdentity)
197  : numPairs(end-begin)
198  , hasRootIdentity(hasRootIdentity) {
199  if (numPairs == 0)
200  return;
201  if (numPairs <= _MaxLocalPairs) {
202  std::uninitialized_copy(begin, end, localPairs);
203  }
204  else {
205  new (&remotePairs) std::shared_ptr<PathPair>(
206  new PathPair[numPairs], std::default_delete<PathPair[]>());
207  std::copy(begin, end, remotePairs.get());
208  }
209  }
210 
211  _Data(_Data const &other)
212  : numPairs(other.numPairs)
213  , hasRootIdentity(other.hasRootIdentity) {
214  if (numPairs <= _MaxLocalPairs) {
215  std::uninitialized_copy(
216  other.localPairs,
217  other.localPairs + other.numPairs, localPairs);
218  }
219  else {
220  new (&remotePairs) std::shared_ptr<PathPair>(other.remotePairs);
221  }
222  }
223  _Data(_Data &&other)
224  : numPairs(other.numPairs)
225  , hasRootIdentity(other.hasRootIdentity) {
226  if (numPairs <= _MaxLocalPairs) {
227  PathPair *dst = localPairs;
228  PathPair *src = other.localPairs;
229  PathPair *srcEnd = other.localPairs + other.numPairs;
230  for (; src != srcEnd; ++src, ++dst) {
231  ::new (static_cast<void*>(std::addressof(*dst)))
232  PathPair(std::move(*src));
233  }
234  }
235  else {
236  new (&remotePairs)
237  std::shared_ptr<PathPair>(std::move(other.remotePairs));
238  }
239  }
240  _Data &operator=(_Data const &other) {
241  if (this != &other) {
242  this->~_Data();
243  new (this) _Data(other);
244  }
245  return *this;
246  }
247  _Data &operator=(_Data &&other) {
248  if (this != &other) {
249  this->~_Data();
250  new (this) _Data(std::move(other));
251  }
252  return *this;
253  }
254  ~_Data() {
255  if (numPairs <= _MaxLocalPairs) {
256  for (PathPair *p = localPairs; numPairs--; ++p) {
257  p->~PathPair();
258  }
259  }
260  else {
261  remotePairs.~shared_ptr<PathPair>();
262  }
263  }
264 
265  bool IsNull() const {
266  return numPairs == 0 && !hasRootIdentity;
267  }
268 
269  PathPair const *begin() const {
270  return numPairs <= _MaxLocalPairs ? localPairs : remotePairs.get();
271  }
272 
273  PathPair const *end() const {
274  return begin() + numPairs;
275  }
276 
277  bool operator==(_Data const &other) const {
278  return numPairs == other.numPairs &&
279  hasRootIdentity == other.hasRootIdentity &&
280  std::equal(begin(), end(), other.begin());
281  }
282 
283  bool operator!=(_Data const &other) const {
284  return !(*this == other);
285  }
286 
287  union {
288  PathPair localPairs[_MaxLocalPairs > 0 ? _MaxLocalPairs : 1];
289  std::shared_ptr<PathPair> remotePairs;
290  };
291  typedef int PairCount;
292  PairCount numPairs = 0;
293  bool hasRootIdentity = false;
294  };
295 
296  _Data _data;
297  SdfLayerOffset _offset;
298 };
299 
300 // Specialize hash_value for PcpMapFunction.
301 inline
303 {
304  return x.Hash();
305 }
306 
308 
309 #endif // PXR_USD_PCP_MAP_FUNCTION_H
PCP_API size_t Hash() const
Return a size_t hash for this map function.
GLenum src
Definition: glew.h:2410
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.
FMT_CONSTEXPR auto begin(const C &c) -> decltype(c.begin())
Definition: format.h:251
PCP_API bool IsIdentity() const
static PCP_API const PathMap & IdentityPathMap()
Returns an identity path mapping.
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()
PCP_API bool operator==(const PcpMapFunction &map) const
Equality.
const SdfLayerOffset & GetTimeOffset() const
The time offset of the mapping.
Definition: mapFunction.h:170
GLclampf f
Definition: glew.h:3499
GLint GLint GLint GLint GLint x
Definition: glew.h:1252
std::map< SdfPath, SdfPath, SdfPath::FastLessThan > PathMap
A mapping from path to path.
Definition: mapFunction.h:84
std::pair< SdfPath, SdfPath > PathPair
Definition: mapFunction.h:85
GLuint GLuint end
Definition: glew.h:1253
GLenum GLenum dst
Definition: glew.h:2410
Definition: path.h:288
void swap(PcpMapFunction &map)
Definition: mapFunction.h:113
std::vector< PathPair > PathPairVector
Definition: mapFunction.h:86
GLsizei const GLchar *const * path
Definition: glew.h:6461
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 p
Definition: glew.h:16321
GLsizei const GLchar *const * string
Definition: glew.h:1844
PCP_API PcpMapFunction GetInverse() const
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1346
PcpMapFunction()=default
Construct a null function.
OIIO_API bool copy(string_view from, string_view to, std::string &err)
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
bool equal(T1 a, T2 b, T3 t)
Definition: ImathFun.h:143
bool HasRootIdentity() const
Definition: mapFunction.h:135
size_t hash_value(const PcpMapFunction &x)
Definition: mapFunction.h:302
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
#define PCP_API
Definition: api.h:40
GLintptr offset
Definition: glew.h:1682