Loading...
Searching...
No Matches
primFlags.h
Go to the documentation of this file.
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_USD_USD_PRIM_FLAGS_H
8#define PXR_USD_USD_PRIM_FLAGS_H
9
57
58#include "pxr/pxr.h"
59#include "pxr/usd/usd/api.h"
60#include "pxr/base/arch/hints.h"
62#include "pxr/base/tf/hash.h"
63
64#include <bitset>
65
66PXR_NAMESPACE_OPEN_SCOPE
67
68class SdfPath;
69
70// Enum for cached flags on prims.
71enum Usd_PrimFlags {
72 // Flags for use with predicates.
73 Usd_PrimActiveFlag,
74 Usd_PrimLoadedFlag,
75 Usd_PrimModelFlag,
76 Usd_PrimGroupFlag,
77 Usd_PrimComponentFlag,
78 Usd_PrimAbstractFlag,
79 Usd_PrimDefinedFlag,
80 Usd_PrimHasClassSpecifierFlag,
81 Usd_PrimHasDefiningSpecifierFlag,
82 Usd_PrimInstanceFlag,
83
84 // Flags for internal use.
85 Usd_PrimHasPayloadFlag,
86 Usd_PrimClipsFlag,
87 Usd_PrimDeadFlag,
88 Usd_PrimPrototypeFlag,
89 Usd_PrimInstanceProxyFlag,
90 Usd_PrimPseudoRootFlag,
91
92 Usd_PrimNumFlags
93};
94
95typedef std::bitset<Usd_PrimNumFlags> Usd_PrimFlagBits;
96
97// Term class. This class exists merely to allow building up conjunctions or
98// disjunctions of terms. See Usd_PrimFlagsPredicate, Usd_PrimFlagsConjunction,
99// Usd_PrimFlagsDisjunction which provide the logcial operators.
100struct Usd_Term {
101 Usd_Term(Usd_PrimFlags flag) : flag(flag), negated(false) {}
102 Usd_Term(Usd_PrimFlags flag, bool negated) : flag(flag), negated(negated) {}
103 Usd_Term operator!() const { return Usd_Term(flag, !negated); }
104 bool operator==(Usd_Term other) const {
105 return flag == other.flag && negated == other.negated;
106 }
107 bool operator!=(Usd_Term other) const {
108 return !(*this == other);
109 }
110 Usd_PrimFlags flag;
111 bool negated;
112};
113
114inline Usd_Term
115operator!(Usd_PrimFlags flag) {
116 return Usd_Term(flag, /*negated=*/true);
117}
118
119// Predicate functor class that tests a prim's flags against desired values.
120class Usd_PrimFlagsPredicate
121{
122public:
123 // Functor result type.
124 typedef bool result_type;
125
126 // Default ctor produces a tautology.
127 Usd_PrimFlagsPredicate() : _negate(false) {}
128
129 Usd_PrimFlagsPredicate(Usd_PrimFlags flag)
130 : _negate(false) {
131 _mask[flag] = 1;
132 _values[flag] = true;
133 }
134
135 // Implicit conversion from a single term.
136 Usd_PrimFlagsPredicate(Usd_Term term)
137 : _negate(false) {
138 _mask[term.flag] = 1;
139 _values[term.flag] = !term.negated;
140 }
141
142 // Convenience to produce a tautological predicate. Returns a
143 // default-constructed predicate.
144 static Usd_PrimFlagsPredicate Tautology() {
145 return Usd_PrimFlagsPredicate();
146 }
147
148 // Convenience to produce a contradictory predicate. Returns a negated
149 // default-constructed predicate.
150 static Usd_PrimFlagsPredicate Contradiction() {
151 return Usd_PrimFlagsPredicate()._Negate();
152 }
153
154 // Set flag to indicate whether prim traversal functions using this
155 // predicate should traverse beneath instances and return descendants
156 // that pass this predicate as instance proxy prims.
157 Usd_PrimFlagsPredicate &TraverseInstanceProxies(bool traverse) {
158 if (traverse) {
159 _mask[Usd_PrimInstanceProxyFlag] = 0;
160 _values[Usd_PrimInstanceProxyFlag] = 1;
161 }
162 else {
163 _mask[Usd_PrimInstanceProxyFlag] = 1;
164 _values[Usd_PrimInstanceProxyFlag] = 0;
165 }
166 return *this;
167 }
168
169 // Returns true if this predicate was explicitly set to include
170 // instance proxies, false otherwise.
171 bool IncludeInstanceProxiesInTraversal() const {
172 return !_mask[Usd_PrimInstanceProxyFlag] &&
173 _values[Usd_PrimInstanceProxyFlag];
174 }
175
176 // Invoke boolean predicate on UsdPrim \p prim.
177 USD_API
178 bool operator()(const class UsdPrim &prim) const;
179
180protected:
181
182 // Return true if this predicate is a tautology, false otherwise.
183 bool _IsTautology() const { return *this == Tautology(); }
184
185 // Set this predicate to be a tautology.
186 void _MakeTautology() { *this = Tautology(); }
187
188 // Return true if this predicate is a contradiction, false otherwise.
189 bool _IsContradiction() const { return *this == Contradiction(); }
190
191 // Set this predicate to be a contradiction.
192 void _MakeContradiction() { *this = Contradiction(); }
193
194 // Negate this predicate.
195 Usd_PrimFlagsPredicate &_Negate() {
196 _negate = !_negate;
197 return *this;
198 }
199
200 // Return a negated copy of this predicate.
201 Usd_PrimFlagsPredicate _GetNegated() const {
202 return Usd_PrimFlagsPredicate(*this)._Negate();
203 }
204
205 // Mask indicating which flags are of interest.
206 Usd_PrimFlagBits _mask;
207
208 // Desired values for prim flags.
209 Usd_PrimFlagBits _values;
210
211private:
212 // Evaluate this predicate with prim data \p prim. \p isInstanceProxy
213 // should be true if this is being evaluated for an instance proxy prim.
214 template <class PrimPtr>
215 bool _Eval(const PrimPtr &prim, bool isInstanceProxy) const {
216 // Manually set the instance proxy bit, since instance proxy
217 // state is never stored in Usd_PrimData's flags.
218 const Usd_PrimFlagBits primFlags = Usd_PrimFlagBits(prim->_GetFlags())
219 .set(Usd_PrimInstanceProxyFlag, isInstanceProxy);
220
221 // Mask the prim's flags, compare to desired values, then optionally
222 // negate the result.
223 return ((primFlags & _mask) == (_values & _mask)) ^ _negate;
224 }
225
226 // Evaluate the predicate \p pred with prim data \p prim. \p isInstanceProxy
227 // should be true if this is being evaluated for an instance proxy prim.
228 template <class PrimPtr>
229 friend bool
230 Usd_EvalPredicate(const Usd_PrimFlagsPredicate &pred, const PrimPtr &prim,
231 bool isInstanceProxy) {
232 return pred._Eval(prim, isInstanceProxy);
233 }
234
235 // Convenience method for evaluating \p pred using \p prim and
236 // \p proxyPrimPath to determine whether this is for an instance proxy
237 // prim.
238 template <class PrimPtr>
239 friend bool
240 Usd_EvalPredicate(const Usd_PrimFlagsPredicate &pred, const PrimPtr &prim,
241 const SdfPath &proxyPrimPath) {
242 return pred._Eval(prim, Usd_IsInstanceProxy(prim, proxyPrimPath));
243 }
244
245 // Equality comparison.
246 friend bool
247 operator==(const Usd_PrimFlagsPredicate &lhs,
248 const Usd_PrimFlagsPredicate &rhs) {
249 return lhs._mask == rhs._mask &&
250 lhs._values == rhs._values &&
251 lhs._negate == rhs._negate;
252 }
253 // Inequality comparison.
254 friend bool
255 operator!=(const Usd_PrimFlagsPredicate &lhs,
256 const Usd_PrimFlagsPredicate &rhs) {
257 return !(lhs == rhs);
258 }
259
260 // hash overload.
261 friend size_t hash_value(const Usd_PrimFlagsPredicate &p) {
262 return TfHash::Combine(
263 p._mask.to_ulong(), p._values.to_ulong(), p._negate
264 );
265 }
266
267 // Whether or not to negate the predicate's result.
268 bool _negate;
269
270};
271
272
283class Usd_PrimFlagsConjunction : public Usd_PrimFlagsPredicate {
284public:
286 Usd_PrimFlagsConjunction() {};
287
289 explicit Usd_PrimFlagsConjunction(Usd_Term term) {
290 *this &= term;
291 }
292
294 Usd_PrimFlagsConjunction &operator&=(Usd_Term term) {
295 // If this conjunction is a contradiction, do nothing.
296 if (ARCH_UNLIKELY(_IsContradiction()))
297 return *this;
298
299 // If we don't have the bit, set it in _mask and _values (if needed).
300 if (!_mask[term.flag]) {
301 _mask[term.flag] = 1;
302 _values[term.flag] = !term.negated;
303 } else if (_values[term.flag] != !term.negated) {
304 // If we do have the bit and the values disagree, then this entire
305 // conjunction becomes a contradiction. If the values agree, it's
306 // redundant and we do nothing.
307 _MakeContradiction();
308 }
309 return *this;
310 }
311
329 USD_API
330 class Usd_PrimFlagsDisjunction operator!() const;
331
332private:
333
334 // Let Usd_PrimFlagsDisjunction produce conjunctions when negated
335 friend class Usd_PrimFlagsDisjunction;
336 Usd_PrimFlagsConjunction(const Usd_PrimFlagsPredicate &base) :
337 Usd_PrimFlagsPredicate(base) {}
338
340 friend Usd_PrimFlagsConjunction
341 operator&&(Usd_Term lhs, Usd_Term rhs);
342
344 friend Usd_PrimFlagsConjunction
345 operator&&(const Usd_PrimFlagsConjunction &conjunction, Usd_Term rhs);
346
348 friend Usd_PrimFlagsConjunction
349 operator&&(Usd_Term lhs, const Usd_PrimFlagsConjunction &conjunction);
350};
351
352inline Usd_PrimFlagsConjunction
353operator&&(Usd_Term lhs, Usd_Term rhs) {
354 // Apparently gcc 4.8.x doesn't like this as:
355 // return (Usd_PrimFlagsConjunction() && lhs) && rhs;
356 Usd_PrimFlagsConjunction tmp;
357 return (tmp && lhs) && rhs;
358}
359
360inline Usd_PrimFlagsConjunction
361operator&&(const Usd_PrimFlagsConjunction &conjunction, Usd_Term rhs) {
362 return Usd_PrimFlagsConjunction(conjunction) &= rhs;
363}
364
365inline Usd_PrimFlagsConjunction
366operator&&(Usd_Term lhs, const Usd_PrimFlagsConjunction &conjunction) {
367 return Usd_PrimFlagsConjunction(conjunction) &= lhs;
368}
369
370inline Usd_PrimFlagsConjunction
371operator&&(Usd_PrimFlags lhs, Usd_PrimFlags rhs) {
372 return Usd_Term(lhs) && Usd_Term(rhs);
373}
374
375
386class Usd_PrimFlagsDisjunction : public Usd_PrimFlagsPredicate {
387public:
388 // Default constructed disjunction is a contradiction.
389 Usd_PrimFlagsDisjunction() { _Negate(); };
390
391 // Construct with a term.
392 explicit Usd_PrimFlagsDisjunction(Usd_Term term) {
393 _Negate();
394 *this |= term;
395 }
396
398 Usd_PrimFlagsDisjunction &operator|=(Usd_Term term) {
399 // If this disjunction is a tautology, do nothing.
400 if (ARCH_UNLIKELY(_IsTautology()))
401 return *this;
402
403 // If we don't have the bit, set it in _mask and _values (if needed).
404 if (!_mask[term.flag]) {
405 _mask[term.flag] = 1;
406 _values[term.flag] = term.negated;
407 } else if (_values[term.flag] != term.negated) {
408 // If we do have the bit and the values disagree, then this entire
409 // disjunction becomes a tautology. If the values agree, it's
410 // redundant and we do nothing.
411 _MakeTautology();
412 }
413 return *this;
414 }
415
433 USD_API
434 class Usd_PrimFlagsConjunction operator!() const;
435
436private:
437
438 // Let Usd_PrimFlagsDisjunction produce conjunctions when negated.
439 friend class Usd_PrimFlagsConjunction;
440 Usd_PrimFlagsDisjunction(const Usd_PrimFlagsPredicate &base) :
441 Usd_PrimFlagsPredicate(base) {}
442
444 friend Usd_PrimFlagsDisjunction operator||(Usd_Term lhs, Usd_Term rhs);
445
447 friend Usd_PrimFlagsDisjunction
448 operator||(const Usd_PrimFlagsDisjunction &disjunction, Usd_Term rhs);
449
451 friend Usd_PrimFlagsDisjunction
452 operator||(Usd_Term lhs, const Usd_PrimFlagsDisjunction &disjunction);
453};
454
455inline Usd_PrimFlagsDisjunction
456operator||(Usd_Term lhs, Usd_Term rhs) {
457 return (Usd_PrimFlagsDisjunction() || lhs) || rhs;
458}
459
460inline Usd_PrimFlagsDisjunction
461operator||(const Usd_PrimFlagsDisjunction &disjunction, Usd_Term rhs) {
462 return Usd_PrimFlagsDisjunction(disjunction) |= rhs;
463}
464
465inline Usd_PrimFlagsDisjunction
466operator||(Usd_Term lhs, const Usd_PrimFlagsDisjunction &disjunction) {
467 return Usd_PrimFlagsDisjunction(disjunction) |= lhs;
468}
469
470inline Usd_PrimFlagsDisjunction
471operator||(Usd_PrimFlags lhs, Usd_PrimFlags rhs) {
472 return Usd_Term(lhs) || Usd_Term(rhs);
473}
474
475#ifdef doxygen
476
478extern unspecified UsdPrimIsActive;
480extern unspecified UsdPrimIsLoaded;
482extern unspecified UsdPrimIsModel;
484extern unspecified UsdPrimIsGroup;
486extern unspecified UsdPrimIsAbstract;
488extern unspecified UsdPrimIsDefined;
490extern unspecified UsdPrimIsInstance;
492extern unspecified UsdPrimHasClassSpecifier;
494extern unspecified UsdPrimHasDefiningSpecifier;
495
508extern unspecified UsdPrimDefaultPredicate;
509
513extern unspecified UsdPrimAllPrimsPredicate;
514
515#else
516
517static const Usd_PrimFlags UsdPrimIsActive = Usd_PrimActiveFlag;
518static const Usd_PrimFlags UsdPrimIsLoaded = Usd_PrimLoadedFlag;
519static const Usd_PrimFlags UsdPrimIsModel = Usd_PrimModelFlag;
520static const Usd_PrimFlags UsdPrimIsGroup = Usd_PrimGroupFlag;
521static const Usd_PrimFlags UsdPrimIsAbstract = Usd_PrimAbstractFlag;
522static const Usd_PrimFlags UsdPrimIsDefined = Usd_PrimDefinedFlag;
523static const Usd_PrimFlags UsdPrimIsInstance = Usd_PrimInstanceFlag;
524static const Usd_PrimFlags UsdPrimHasClassSpecifier
525 = Usd_PrimHasClassSpecifierFlag;
526static const Usd_PrimFlags UsdPrimHasDefiningSpecifier
527 = Usd_PrimHasDefiningSpecifierFlag;
528
529USD_API extern const Usd_PrimFlagsConjunction UsdPrimDefaultPredicate;
530USD_API extern const Usd_PrimFlagsPredicate UsdPrimAllPrimsPredicate;
531
532#endif // doxygen
533
564inline Usd_PrimFlagsPredicate
565UsdTraverseInstanceProxies(Usd_PrimFlagsPredicate predicate)
566{
567 return predicate.TraverseInstanceProxies(true);
568}
569
574inline Usd_PrimFlagsPredicate
576{
578}
579
580PXR_NAMESPACE_CLOSE_SCOPE
581
582#endif // PXR_USD_USD_PRIM_FLAGS_H
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:281
static size_t Combine(Args &&... args)
Produce a hash code by combining the hash codes of several objects.
Definition: hash.h:487
UsdPrim is the sole persistent scenegraph object on a UsdStage, and is the embodiment of a "Prim" as ...
Definition: prim.h:117
std::size_t hash_value(const half h)
Overload hash_value for half.
Definition: half.h:30
Compiler hints.
unspecified UsdPrimIsGroup
Tests UsdPrim::IsGroup()
unspecified UsdPrimIsActive
Tests UsdPrim::IsActive()
unspecified UsdPrimIsDefined
Tests UsdPrim::IsDefined()
unspecified UsdPrimIsInstance
Tests UsdPrim::IsInstance()
unspecified UsdPrimIsLoaded
Tests UsdPrim::IsLoaded()
unspecified UsdPrimDefaultPredicate
The default predicate used for prim traversals in methods like UsdPrim::GetChildren,...
unspecified UsdPrimIsAbstract
Tests UsdPrim::IsAbstract()
unspecified UsdPrimHasClassSpecifier
Tests UsdPrim::HasClassSpecifier()
unspecified UsdPrimIsModel
Tests UsdPrim::IsModel()
unspecified UsdPrimHasDefiningSpecifier
Tests UsdPrim::HasDefiningSpecifier()
Usd_PrimFlagsPredicate UsdTraverseInstanceProxies()
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: primFlags.h:575
unspecified UsdPrimAllPrimsPredicate
Predicate that includes all prims.