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 PCP_MAP_EXPRESSION_H
25 #define 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/optional.hpp>
32 
33 #include <tbb/atomic.h>
34 #include <tbb/spin_rw_mutex.h>
35 
36 #include <memory>
37 
38 PXR_NAMESPACE_OPEN_SCOPE
39 
56 {
57 public:
60 
65  PCP_API
66  const Value & Evaluate() const;
67 
69  PCP_API
71 
73  PCP_API
74  void Swap(PcpMapExpression &other);
75 
77  PCP_API
78  bool IsNull() const;
79 
82 
84  PCP_API
85  static PcpMapExpression Identity();
86 
88  PCP_API
89  static PcpMapExpression Constant( const Value & constValue );
90 
94  class Variable {
95  Variable(Variable const &) = delete;
96  Variable &operator=(Variable const &) = delete;
97  public:
98  Variable() = default;
99  virtual ~Variable();
101  virtual const Value & GetValue() const = 0;
104  virtual void SetValue(const Value & value) = 0;
107  virtual PcpMapExpression GetExpression() const = 0;
108  };
109 
111  typedef std::shared_ptr<Variable> VariableRefPtr;
112 
119  PCP_API
120  static VariableRefPtr NewVariable( const Value & initialValue );
121 
124  PCP_API
125  PcpMapExpression Compose(const PcpMapExpression &f) const;
126 
128  PCP_API
129  PcpMapExpression Inverse() const;
130 
133  PCP_API
135 
137  bool IsConstantIdentity() const {
138  return _node && _node->key.op == _OpConstant &&
139  _node->key.valueForConstant.IsIdentity();
140  }
141 
143 
148 
151  bool IsIdentity() const {
152  return Evaluate().IsIdentity();
153  }
154 
157  SdfPath MapSourceToTarget(const SdfPath &path) const {
158  return Evaluate().MapSourceToTarget(path);
159  }
160 
163  SdfPath MapTargetToSource(const SdfPath &path) const {
164  return Evaluate().MapTargetToSource(path);
165  }
166 
168  const SdfLayerOffset &GetTimeOffset() const {
169  return Evaluate().GetTimeOffset();
170  }
171 
174  std::string GetString() const {
175  return Evaluate().GetString();
176  }
177 
179 
180 private:
181  // Allow Pcp_Statistics access to internal data for diagnostics.
182  friend class Pcp_Statistics;
183  friend struct Pcp_VariableImpl;
184 
185  class _Node;
186  typedef boost::intrusive_ptr<_Node> _NodeRefPtr;
187 
188  explicit PcpMapExpression(const _NodeRefPtr & node) : _node(node) {}
189 
190 private: // data
191  enum _Op {
192  _OpConstant,
193  _OpVariable,
194  _OpInverse,
195  _OpCompose,
196  _OpAddRootIdentity
197  };
198 
199  class _Node : public boost::noncopyable {
200  public:
201  // The Key holds all the state needed to uniquely identify
202  // this (sub-)expression.
203  struct Key {
204  const _Op op;
205  const _NodeRefPtr arg1, arg2;
206  const Value valueForConstant;
207 
208  Key( _Op op_,
209  const _NodeRefPtr & arg1_,
210  const _NodeRefPtr & arg2_,
211  const Value & valueForConstant_ )
212  : op(op_)
213  , arg1(arg1_)
214  , arg2(arg2_)
215  , valueForConstant(valueForConstant_)
216  {}
217  inline size_t GetHash() const;
218  bool operator==(const Key &key) const;
219  };
220 
221  // The Key of a node is const, and established when it is created.
222  const Key key;
223 
224  // Whether or not the expression tree up to and including this node
225  // will always include an identity mapping.
226  const bool expressionTreeAlwaysHasIdentity;
227 
228  // Factory method to create new nodes.
229  static _NodeRefPtr
230  New( _Op op,
231  const _NodeRefPtr & arg1 = _NodeRefPtr(),
232  const _NodeRefPtr & arg2 = _NodeRefPtr(),
233  const Value & valueForConstant = Value() );
234  ~_Node();
235 
236  // Evaluate (and internally cache) the value of this node.
237  const Value & EvaluateAndCache() const;
238 
239  // For _OpVariable nodes, sets the variable's value.
240  void SetValueForVariable(const Value &newValue);
241 
242  // For _OpVariable nodes, returns the variable's value.
243  const Value & GetValueForVariable() const {
244  return _valueForVariable;
245  }
246 
247  private:
248  explicit _Node( const Key &key_ );
249  void _Invalidate();
250  Value _EvaluateUncached() const;
251 
252  // Helper to determine if the expression tree indicated by key
253  // will always contains the root identity.
254  static bool _ExpressionTreeAlwaysHasIdentity(const Key& key);
255 
256  // Ref-counting ops manage _refCount.
257  // Need to friend them here to have access to _refCount.
258  friend PCP_API void intrusive_ptr_add_ref(_Node*);
259  friend PCP_API void intrusive_ptr_release(_Node*);
260 
261  // Registry of node instances, identified by Key.
262  // Note: variable nodes are not tracked by the registry.
263  struct _NodeMap;
264  static TfStaticData<_NodeMap> _nodeRegistry;
265 
266  mutable tbb::atomic<int> _refCount;
267  mutable boost::optional<Value> _cachedValue;
268  mutable std::set<_Node*> _dependentExpressions;
269  Value _valueForVariable;
270  mutable tbb::spin_rw_mutex _mutex;
271  };
272 
273  // Need to friend them here to have visibility to private class _Node.
274  friend PCP_API void intrusive_ptr_add_ref(_Node*);
275  friend PCP_API void intrusive_ptr_release(_Node*);
276 
277  _NodeRefPtr _node;
278 };
279 
280 PXR_NAMESPACE_CLOSE_SCOPE
281 
282 #endif // PCP_MAP_EXPRESSION_H
An expression that yields a PcpMapFunction value.
Definition: mapExpression.h:55
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.
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:164
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:59
virtual void SetValue(const Value &value)=0
Mutate the variable to have the new value.
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:287
std::shared_ptr< Variable > VariableRefPtr
Variables are held by reference.
A Variable is a mutable memory cell that holds a value.
Definition: mapExpression.h:94
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.
static PCP_API VariableRefPtr NewVariable(const Value &initialValue)
Create a new variable.