All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mapExpression.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_EXPRESSION_H
25 #define PXR_USD_PCP_MAP_EXPRESSION_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/usd/pcp/api.h"
29 #include "pxr/usd/pcp/mapFunction.h"
30 
31 #include <boost/intrusive_ptr.hpp>
32 
33 #include <tbb/atomic.h>
34 #include <tbb/spin_mutex.h>
35 
36 #include <atomic>
37 #include <memory>
38 
39 PXR_NAMESPACE_OPEN_SCOPE
40 
57 {
58 public:
61 
66  PCP_API
67  const Value & Evaluate() const;
68 
70  PCP_API
72 
74  PCP_API
75  void Swap(PcpMapExpression &other);
76 
78  PCP_API
79  bool IsNull() const;
80 
83 
85  PCP_API
86  static PcpMapExpression Identity();
87 
89  PCP_API
90  static PcpMapExpression Constant( const Value & constValue );
91 
95  class Variable {
96  Variable(Variable const &) = delete;
97  Variable &operator=(Variable const &) = delete;
98  public:
99  Variable() = default;
100  virtual ~Variable();
102  virtual const Value & GetValue() const = 0;
105  virtual void SetValue(Value && value) = 0;
108  virtual PcpMapExpression GetExpression() const = 0;
109  };
110 
112  typedef std::unique_ptr<Variable> VariableUniquePtr;
113 
120  PCP_API
121  static VariableUniquePtr NewVariable(Value && initialValue);
122 
125  PCP_API
126  PcpMapExpression Compose(const PcpMapExpression &f) const;
127 
129  PCP_API
130  PcpMapExpression Inverse() const;
131 
134  PCP_API
136 
138  bool IsConstantIdentity() const {
139  return _node && _node->key.op == _OpConstant &&
140  _node->key.valueForConstant.IsIdentity();
141  }
142 
144 
149 
152  bool IsIdentity() const {
153  return Evaluate().IsIdentity();
154  }
155 
158  SdfPath MapSourceToTarget(const SdfPath &path) const {
159  return Evaluate().MapSourceToTarget(path);
160  }
161 
164  SdfPath MapTargetToSource(const SdfPath &path) const {
165  return Evaluate().MapTargetToSource(path);
166  }
167 
169  const SdfLayerOffset &GetTimeOffset() const {
170  return Evaluate().GetTimeOffset();
171  }
172 
175  std::string GetString() const {
176  return Evaluate().GetString();
177  }
178 
180 
181 private:
182  // Allow Pcp_Statistics access to internal data for diagnostics.
183  friend class Pcp_Statistics;
184  friend struct Pcp_VariableImpl;
185 
186  class _Node;
187  typedef boost::intrusive_ptr<_Node> _NodeRefPtr;
188 
189  explicit PcpMapExpression(const _NodeRefPtr & node) : _node(node) {}
190 
191 private: // data
192  enum _Op {
193  _OpConstant,
194  _OpVariable,
195  _OpInverse,
196  _OpCompose,
197  _OpAddRootIdentity
198  };
199 
200  class _Node : public boost::noncopyable {
201  public:
202  // The Key holds all the state needed to uniquely identify
203  // this (sub-)expression.
204  struct Key {
205  const _Op op;
206  const _NodeRefPtr arg1, arg2;
207  const Value valueForConstant;
208 
209  Key( _Op op_,
210  const _NodeRefPtr & arg1_,
211  const _NodeRefPtr & arg2_,
212  const Value & valueForConstant_ )
213  : op(op_)
214  , arg1(arg1_)
215  , arg2(arg2_)
216  , valueForConstant(valueForConstant_)
217  {}
218  inline size_t GetHash() const;
219  bool operator==(const Key &key) const;
220  };
221 
222  // The Key of a node is const, and established when it is created.
223  const Key key;
224 
225  // Whether or not the expression tree up to and including this node
226  // will always include an identity mapping.
227  const bool expressionTreeAlwaysHasIdentity;
228 
229  // Factory method to create new nodes.
230  static _NodeRefPtr
231  New( _Op op,
232  const _NodeRefPtr & arg1 = _NodeRefPtr(),
233  const _NodeRefPtr & arg2 = _NodeRefPtr(),
234  const Value & valueForConstant = Value() );
235  ~_Node();
236 
237  // Evaluate (and internally cache) the value of this node.
238  const Value & EvaluateAndCache() const;
239 
240  // For _OpVariable nodes, sets the variable's value.
241  void SetValueForVariable(Value &&newValue);
242 
243  // For _OpVariable nodes, returns the variable's value.
244  const Value & GetValueForVariable() const {
245  return _valueForVariable;
246  }
247 
248  private:
249  explicit _Node( const Key &key_ );
250  void _Invalidate();
251  Value _EvaluateUncached() const;
252 
253  // Helper to determine if the expression tree indicated by key
254  // will always contains the root identity.
255  static bool _ExpressionTreeAlwaysHasIdentity(const Key& key);
256 
257  // Ref-counting ops manage _refCount.
258  // Need to friend them here to have access to _refCount.
259  friend PCP_API void intrusive_ptr_add_ref(_Node*);
260  friend PCP_API void intrusive_ptr_release(_Node*);
261 
262  // Registry of node instances, identified by Key.
263  // Note: variable nodes are not tracked by the registry.
264  struct _NodeMap;
265  static TfStaticData<_NodeMap> _nodeRegistry;
266 
267  mutable tbb::atomic<int> _refCount;
268  mutable Value _cachedValue;
269  mutable std::set<_Node*> _dependentExpressions;
270  Value _valueForVariable;
271  mutable tbb::spin_mutex _mutex;
272  mutable std::atomic<bool> _hasCachedValue;
273  };
274 
275  // Need to friend them here to have visibility to private class _Node.
276  friend PCP_API void intrusive_ptr_add_ref(_Node*);
277  friend PCP_API void intrusive_ptr_release(_Node*);
278 
279  _NodeRefPtr _node;
280 };
281 
282 PXR_NAMESPACE_CLOSE_SCOPE
283 
284 #endif // PXR_USD_PCP_MAP_EXPRESSION_H
An expression that yields a PcpMapFunction value.
Definition: mapExpression.h:56
const SdfLayerOffset & GetTimeOffset() const
The time offset of the mapping.
static PCP_API PcpMapExpression Identity()
Return an expression representing PcpMapFunction::Identity().
PCP_API PcpMapExpression Compose(const PcpMapExpression &f) const
Create a new PcpMapExpression representing the application of f&#39;s value, followed by the application ...
virtual const Value & GetValue() const =0
Return the current value.
static PCP_API VariableUniquePtr NewVariable(Value &&initialValue)
Create a new variable.
std::string GetString() const
Returns a string representation of this mapping for debugging purposes.
const SdfLayerOffset & GetTimeOffset() const
The time offset of the mapping.
Definition: mapFunction.h:170
static PCP_API PcpMapExpression Constant(const Value &constValue)
Create a new constant.
PCP_API SdfPath MapTargetToSource(const SdfPath &path) const
Map a path in the target namespace to the source.
PCP_API void Swap(PcpMapExpression &other)
Swap this expression with the other.
PCP_API PcpMapExpression Inverse() const
Create a new PcpMapExpression representing the inverse of f.
PCP_API const Value & Evaluate() const
Evaluate this expression, yielding a PcpMapFunction value.
SdfPath MapSourceToTarget(const SdfPath &path) const
Map a path in the source namespace to the target.
bool IsConstantIdentity() const
Return true if the map function is the constant identity function.
PcpMapFunction Value
The value type of PcpMapExpression is a PcpMapFunction.
Definition: mapExpression.h:60
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:288
A Variable is a mutable memory cell that holds a value.
Definition: mapExpression.h:95
PCP_API bool IsNull() const
Return true if this is a null expression.
bool IsIdentity() const
Return true if the evaluated map function is the identity function.
PCP_API SdfPath MapSourceToTarget(const SdfPath &path) const
Map a path in the source namespace to the target.
PCP_API bool IsIdentity() const
Return true if the map function is the identity function.
SdfPath MapTargetToSource(const SdfPath &path) const
Map a path in the target namespace to the source.
VT_API bool operator==(VtDictionary const &, VtDictionary const &)
Equality comparison.
PCP_API PcpMapExpression()
Default-construct a NULL expression.
Represents a time offset and scale between layers.
Definition: layerOffset.h:61
virtual PcpMapExpression GetExpression() const =0
Return an expression representing the value of this variable.
PCP_API PcpMapExpression AddRootIdentity() const
Return a new expression representing this expression with an added (if necessary) mapping from &lt;/&gt; to...
PCP_API std::string GetString() const
Returns a string representation of this mapping for debugging purposes.
virtual void SetValue(Value &&value)=0
Mutate the variable to have the new value.
std::unique_ptr< Variable > VariableUniquePtr
Variables are held by reference.