All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
primFlags.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 USD_PRIMFLAGS_H
25 #define USD_PRIMFLAGS_H
26 
74 
75 #include "pxr/pxr.h"
76 #include "pxr/usd/usd/api.h"
77 #include "pxr/base/arch/hints.h"
78 #include "pxr/base/tf/bitUtils.h"
79 
80 #include <boost/functional/hash.hpp>
81 
82 #include <bitset>
83 
84 PXR_NAMESPACE_OPEN_SCOPE
85 
86 class SdfPath;
87 
88 // Enum for cached flags on prims.
89 enum Usd_PrimFlags {
90  // Flags for use with predicates.
91  Usd_PrimActiveFlag,
92  Usd_PrimLoadedFlag,
93  Usd_PrimModelFlag,
94  Usd_PrimGroupFlag,
95  Usd_PrimAbstractFlag,
96  Usd_PrimDefinedFlag,
97  Usd_PrimHasDefiningSpecifierFlag,
98  Usd_PrimInstanceFlag,
99 
100  // Flags for internal use.
101  Usd_PrimHasPayloadFlag,
102  Usd_PrimClipsFlag,
103  Usd_PrimDeadFlag,
104  Usd_PrimMasterFlag,
105  Usd_PrimInstanceProxyFlag,
106 
107  Usd_PrimNumFlags
108 };
109 
110 typedef std::bitset<Usd_PrimNumFlags> Usd_PrimFlagBits;
111 
112 // Term class. This class exists merely to allow building up conjunctions or
113 // disjunctions of terms. See Usd_PrimFlagsPredicate, Usd_PrimFlagsConjunction,
114 // Usd_PrimFlagsDisjunction which provide the logcial operators.
115 struct Usd_Term {
116  Usd_Term(Usd_PrimFlags flag) : flag(flag), negated(false) {}
117  Usd_Term(Usd_PrimFlags flag, bool negated) : flag(flag), negated(negated) {}
118  Usd_Term operator!() const { return Usd_Term(flag, !negated); }
119  bool operator==(Usd_Term other) const {
120  return flag == other.flag && negated == other.negated;
121  }
122  bool operator!=(Usd_Term other) const {
123  return !(*this == other);
124  }
125  Usd_PrimFlags flag;
126  bool negated;
127 };
128 
129 inline Usd_Term
130 operator!(Usd_PrimFlags flag) {
131  return Usd_Term(flag, /*negated=*/true);
132 }
133 
134 // Predicate functor class that tests a prim's flags against desired values.
135 class Usd_PrimFlagsPredicate
136 {
137 public:
138  // Functor result type.
139  typedef bool result_type;
140 
141  // Default ctor produces a tautology.
142  Usd_PrimFlagsPredicate() : _negate(false) {}
143 
144  Usd_PrimFlagsPredicate(Usd_PrimFlags flag)
145  : _negate(false) {
146  _mask[flag] = 1;
147  _values[flag] = true;
148  }
149 
150  // Implicit conversion from a single term.
151  Usd_PrimFlagsPredicate(Usd_Term term)
152  : _negate(false) {
153  _mask[term.flag] = 1;
154  _values[term.flag] = !term.negated;
155  }
156 
157  // Convenience to produce a tautological predicate. Returns a
158  // default-constructed predicate.
159  static Usd_PrimFlagsPredicate Tautology() {
160  return Usd_PrimFlagsPredicate();
161  }
162 
163  // Convenience to produce a contradictory predicate. Returns a negated
164  // default-constructed predicate.
165  static Usd_PrimFlagsPredicate Contradiction() {
166  return Usd_PrimFlagsPredicate()._Negate();
167  }
168 
169  // Set flag to indicate whether prim traversal functions using this
170  // predicate should traverse beneath instances and return descendants
171  // that pass this predicate as instance proxy prims.
172  Usd_PrimFlagsPredicate &TraverseInstanceProxies(bool traverse) {
173  if (traverse) {
174  _mask[Usd_PrimInstanceProxyFlag] = 0;
175  _values[Usd_PrimInstanceProxyFlag] = 1;
176  }
177  else {
178  _mask[Usd_PrimInstanceProxyFlag] = 1;
179  _values[Usd_PrimInstanceProxyFlag] = 0;
180  }
181  return *this;
182  }
183 
184  // Returns true if this predicate was explicitly set to include
185  // instance proxies, false otherwise.
186  bool IncludeInstanceProxiesInTraversal() const {
187  return !_mask[Usd_PrimInstanceProxyFlag] &&
188  _values[Usd_PrimInstanceProxyFlag];
189  }
190 
191  // Invoke boolean predicate on UsdPrim \p prim.
192  USD_API
193  bool operator()(const class UsdPrim &prim) const;
194 
195 protected:
196 
197  // Return true if this predicate is a tautology, false otherwise.
198  bool _IsTautology() const { return *this == Tautology(); }
199 
200  // Set this predicate to be a tautology.
201  void _MakeTautology() { *this = Tautology(); }
202 
203  // Return true if this predicate is a contradiction, false otherwise.
204  bool _IsContradiction() const { return *this == Contradiction(); }
205 
206  // Set this predicate to be a contradiction.
207  void _MakeContradiction() { *this = Contradiction(); }
208 
209  // Negate this predicate.
210  Usd_PrimFlagsPredicate &_Negate() {
211  _negate = !_negate;
212  return *this;
213  }
214 
215  // Return a negated copy of this predicate.
216  Usd_PrimFlagsPredicate _GetNegated() const {
217  return Usd_PrimFlagsPredicate(*this)._Negate();
218  }
219 
220  // Mask indicating which flags are of interest.
221  Usd_PrimFlagBits _mask;
222 
223  // Desired values for prim flags.
224  Usd_PrimFlagBits _values;
225 
226 private:
227  // Evaluate this predicate with prim data \p prim. \p isInstanceProxy
228  // should be true if this is being evaluated for an instance proxy prim.
229  template <class PrimPtr>
230  bool _Eval(const PrimPtr &prim, bool isInstanceProxy) const {
231  // Manually set the instance proxy bit, since instance proxy
232  // state is never stored in Usd_PrimData's flags.
233  const Usd_PrimFlagBits primFlags = Usd_PrimFlagBits(prim->_GetFlags())
234  .set(Usd_PrimInstanceProxyFlag, isInstanceProxy);
235 
236  // Mask the prim's flags, compare to desired values, then optionally
237  // negate the result.
238  return ((primFlags & _mask) == (_values & _mask)) ^ _negate;
239  }
240 
241  // Evaluate the predicate \p pred with prim data \p prim. \p isInstanceProxy
242  // should be true if this is being evaluated for an instance proxy prim.
243  template <class PrimPtr>
244  friend bool
245  Usd_EvalPredicate(const Usd_PrimFlagsPredicate &pred, const PrimPtr &prim,
246  bool isInstanceProxy) {
247  return pred._Eval(prim, isInstanceProxy);
248  }
249 
250  // Convenience method for evaluating \p pred using \p prim and
251  // \p proxyPrimPath to determine whether this is for an instance proxy
252  // prim.
253  template <class PrimPtr>
254  friend bool
255  Usd_EvalPredicate(const Usd_PrimFlagsPredicate &pred, const PrimPtr &prim,
256  const SdfPath &proxyPrimPath) {
257  return pred._Eval(prim, Usd_IsInstanceProxy(prim, proxyPrimPath));
258  }
259 
260  // Equality comparison.
261  friend bool
262  operator==(const Usd_PrimFlagsPredicate &lhs,
263  const Usd_PrimFlagsPredicate &rhs) {
264  return lhs._mask == rhs._mask &&
265  lhs._values == rhs._values &&
266  lhs._negate == rhs._negate;
267  }
268  // Inequality comparison.
269  friend bool
270  operator!=(const Usd_PrimFlagsPredicate &lhs,
271  const Usd_PrimFlagsPredicate &rhs) {
272  return !(lhs == rhs);
273  }
274 
275  // hash overload.
276  friend size_t hash_value(const Usd_PrimFlagsPredicate &p) {
277  size_t hash = p._mask.to_ulong();
278  boost::hash_combine(hash, p._values.to_ulong());
279  boost::hash_combine(hash, p._negate);
280  return hash;
281  }
282 
283  // Whether or not to negate the predicate's result.
284  bool _negate;
285 
286 };
287 
288 
299 class Usd_PrimFlagsConjunction : public Usd_PrimFlagsPredicate {
300 public:
302  Usd_PrimFlagsConjunction() {};
303 
305  explicit Usd_PrimFlagsConjunction(Usd_Term term) {
306  *this &= term;
307  }
308 
310  Usd_PrimFlagsConjunction &operator&=(Usd_Term term) {
311  // If this conjunction is a contradiction, do nothing.
312  if (ARCH_UNLIKELY(_IsContradiction()))
313  return *this;
314 
315  // If we don't have the bit, set it in _mask and _values (if needed).
316  if (!_mask[term.flag]) {
317  _mask[term.flag] = 1;
318  _values[term.flag] = !term.negated;
319  } else if (_values[term.flag] != !term.negated) {
320  // If we do have the bit and the values disagree, then this entire
321  // conjunction becomes a contradiction. If the values agree, it's
322  // redundant and we do nothing.
323  _MakeContradiction();
324  }
325  return *this;
326  }
327 
345  USD_API
346  class Usd_PrimFlagsDisjunction operator!() const;
347 
348 private:
349 
350  // Let Usd_PrimFlagsDisjunction produce conjunctions when negated
351  friend class Usd_PrimFlagsDisjunction;
352  Usd_PrimFlagsConjunction(const Usd_PrimFlagsPredicate &base) :
353  Usd_PrimFlagsPredicate(base) {}
354 
356  friend Usd_PrimFlagsConjunction
357  operator&&(Usd_Term lhs, Usd_Term rhs);
358 
360  friend Usd_PrimFlagsConjunction
361  operator&&(const Usd_PrimFlagsConjunction &conjunction, Usd_Term rhs);
362 
364  friend Usd_PrimFlagsConjunction
365  operator&&(Usd_Term lhs, const Usd_PrimFlagsConjunction &conjunction);
366 };
367 
368 inline Usd_PrimFlagsConjunction
369 operator&&(Usd_Term lhs, Usd_Term rhs) {
370  // Apparently gcc 4.8.x doesn't like this as:
371  // return (Usd_PrimFlagsConjunction() && lhs) && rhs;
372  Usd_PrimFlagsConjunction tmp;
373  return (tmp && lhs) && rhs;
374 }
375 
376 inline Usd_PrimFlagsConjunction
377 operator&&(const Usd_PrimFlagsConjunction &conjunction, Usd_Term rhs) {
378  return Usd_PrimFlagsConjunction(conjunction) &= rhs;
379 }
380 
381 inline Usd_PrimFlagsConjunction
382 operator&&(Usd_Term lhs, const Usd_PrimFlagsConjunction &conjunction) {
383  return Usd_PrimFlagsConjunction(conjunction) &= lhs;
384 }
385 
386 inline Usd_PrimFlagsConjunction
387 operator&&(Usd_PrimFlags lhs, Usd_PrimFlags rhs) {
388  return Usd_Term(lhs) && Usd_Term(rhs);
389 }
390 
391 
402 class Usd_PrimFlagsDisjunction : public Usd_PrimFlagsPredicate {
403 public:
404  // Default constructed disjunction is a contradiction.
405  Usd_PrimFlagsDisjunction() { _Negate(); };
406 
407  // Construct with a term.
408  explicit Usd_PrimFlagsDisjunction(Usd_Term term) {
409  _Negate();
410  *this |= term;
411  }
412 
414  Usd_PrimFlagsDisjunction &operator|=(Usd_Term term) {
415  // If this disjunction is a tautology, do nothing.
416  if (ARCH_UNLIKELY(_IsTautology()))
417  return *this;
418 
419  // If we don't have the bit, set it in _mask and _values (if needed).
420  if (!_mask[term.flag]) {
421  _mask[term.flag] = 1;
422  _values[term.flag] = term.negated;
423  } else if (_values[term.flag] != term.negated) {
424  // If we do have the bit and the values disagree, then this entire
425  // disjunction becomes a tautology. If the values agree, it's
426  // redundant and we do nothing.
427  _MakeTautology();
428  }
429  return *this;
430  }
431 
449  USD_API
450  class Usd_PrimFlagsConjunction operator!() const;
451 
452 private:
453 
454  // Let Usd_PrimFlagsDisjunction produce conjunctions when negated.
455  friend class Usd_PrimFlagsConjunction;
456  Usd_PrimFlagsDisjunction(const Usd_PrimFlagsPredicate &base) :
457  Usd_PrimFlagsPredicate(base) {}
458 
460  friend Usd_PrimFlagsDisjunction operator||(Usd_Term lhs, Usd_Term rhs);
461 
463  friend Usd_PrimFlagsDisjunction
464  operator||(const Usd_PrimFlagsDisjunction &disjunction, Usd_Term rhs);
465 
467  friend Usd_PrimFlagsDisjunction
468  operator||(Usd_Term lhs, const Usd_PrimFlagsDisjunction &disjunction);
469 };
470 
471 inline Usd_PrimFlagsDisjunction
472 operator||(Usd_Term lhs, Usd_Term rhs) {
473  return (Usd_PrimFlagsDisjunction() || lhs) || rhs;
474 }
475 
476 inline Usd_PrimFlagsDisjunction
477 operator||(const Usd_PrimFlagsDisjunction &disjunction, Usd_Term rhs) {
478  return Usd_PrimFlagsDisjunction(disjunction) |= rhs;
479 }
480 
481 inline Usd_PrimFlagsDisjunction
482 operator||(Usd_Term lhs, const Usd_PrimFlagsDisjunction &disjunction) {
483  return Usd_PrimFlagsDisjunction(disjunction) |= lhs;
484 }
485 
486 inline Usd_PrimFlagsDisjunction
487 operator||(Usd_PrimFlags lhs, Usd_PrimFlags rhs) {
488  return Usd_Term(lhs) || Usd_Term(rhs);
489 }
490 
491 #ifdef doxygen
492 
494 extern unspecified UsdPrimIsActive;
496 extern unspecified UsdPrimIsLoaded;
498 extern unspecified UsdPrimIsModel;
500 extern unspecified UsdPrimIsGroup;
502 extern unspecified UsdPrimIsAbstract;
504 extern unspecified UsdPrimIsDefined;
506 extern unspecified UsdPrimIsInstance;
508 extern unspecified UsdPrimHasDefiningSpecifier;
509 
522 extern unspecified UsdPrimDefaultPredicate;
523 
527 extern unspecified UsdPrimAllPrimsPredicate;
528 
529 #else
530 
531 static const Usd_PrimFlags UsdPrimIsActive = Usd_PrimActiveFlag;
532 static const Usd_PrimFlags UsdPrimIsLoaded = Usd_PrimLoadedFlag;
533 static const Usd_PrimFlags UsdPrimIsModel = Usd_PrimModelFlag;
534 static const Usd_PrimFlags UsdPrimIsGroup = Usd_PrimGroupFlag;
535 static const Usd_PrimFlags UsdPrimIsAbstract = Usd_PrimAbstractFlag;
536 static const Usd_PrimFlags UsdPrimIsDefined = Usd_PrimDefinedFlag;
537 static const Usd_PrimFlags UsdPrimIsInstance = Usd_PrimInstanceFlag;
538 static const Usd_PrimFlags UsdPrimHasDefiningSpecifier
539  = Usd_PrimHasDefiningSpecifierFlag;
540 
541 USD_API extern const Usd_PrimFlagsConjunction UsdPrimDefaultPredicate;
542 USD_API extern const Usd_PrimFlagsPredicate UsdPrimAllPrimsPredicate;
543 
544 #endif // doxygen
545 
576 inline Usd_PrimFlagsPredicate
577 UsdTraverseInstanceProxies(Usd_PrimFlagsPredicate predicate)
578 {
579  return predicate.TraverseInstanceProxies(true);
580 }
581 
586 inline Usd_PrimFlagsPredicate
588 {
589  return UsdTraverseInstanceProxies(UsdPrimDefaultPredicate);
590 }
591 
592 PXR_NAMESPACE_CLOSE_SCOPE
593 
594 #endif // USD_PRIMFLAGS_H
unspecified UsdPrimDefaultPredicate
The default predicate used for prim traversals in methods like UsdPrim::GetChildren, UsdStage::Traverse, and by UsdPrimRange.
unspecified UsdPrimIsAbstract
Tests UsdPrim::IsAbstract()
unspecified UsdPrimHasDefiningSpecifier
Tests UsdPrim::HasDefiningSpecifier()
unspecified UsdPrimIsModel
Tests UsdPrim::IsModel()
unspecified UsdPrimIsActive
Tests UsdPrim::IsActive()
unspecified UsdPrimIsLoaded
Tests UsdPrim::IsLoaded()
unspecified UsdPrimIsDefined
Tests UsdPrim::IsDefined()
UsdPrim is the sole persistent scenegraph object on a UsdStage, and is the embodiment of a &quot;Prim&quot; as ...
Definition: prim.h:131
Usd_PrimFlagsPredicate UsdTraverseInstanceProxies(Usd_PrimFlagsPredicate predicate)
This function is used to allow the prim traversal functions listed under Prim predicate flags to trav...
Definition: primFlags.h:577
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:287
unspecified UsdPrimAllPrimsPredicate
Predicate that includes all prims.
unspecified UsdPrimIsInstance
Tests UsdPrim::IsInstance()
VT_API bool operator==(VtDictionary const &, VtDictionary const &)
Equality comparison.
unspecified UsdPrimIsGroup
Tests UsdPrim::IsGroup()