Loading...
Searching...
No Matches
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 PXR_USD_USD_PRIM_FLAGS_H
25#define PXR_USD_USD_PRIM_FLAGS_H
26
74
75#include "pxr/pxr.h"
76#include "pxr/usd/usd/api.h"
77#include "pxr/base/arch/hints.h"
79#include "pxr/base/tf/hash.h"
80
81#include <bitset>
82
83PXR_NAMESPACE_OPEN_SCOPE
84
85class SdfPath;
86
87// Enum for cached flags on prims.
88enum Usd_PrimFlags {
89 // Flags for use with predicates.
90 Usd_PrimActiveFlag,
91 Usd_PrimLoadedFlag,
92 Usd_PrimModelFlag,
93 Usd_PrimGroupFlag,
94 Usd_PrimComponentFlag,
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_PrimPrototypeFlag,
105 Usd_PrimInstanceProxyFlag,
106 Usd_PrimPseudoRootFlag,
107
108 Usd_PrimNumFlags
109};
110
111typedef std::bitset<Usd_PrimNumFlags> Usd_PrimFlagBits;
112
113// Term class. This class exists merely to allow building up conjunctions or
114// disjunctions of terms. See Usd_PrimFlagsPredicate, Usd_PrimFlagsConjunction,
115// Usd_PrimFlagsDisjunction which provide the logcial operators.
116struct Usd_Term {
117 Usd_Term(Usd_PrimFlags flag) : flag(flag), negated(false) {}
118 Usd_Term(Usd_PrimFlags flag, bool negated) : flag(flag), negated(negated) {}
119 Usd_Term operator!() const { return Usd_Term(flag, !negated); }
120 bool operator==(Usd_Term other) const {
121 return flag == other.flag && negated == other.negated;
122 }
123 bool operator!=(Usd_Term other) const {
124 return !(*this == other);
125 }
126 Usd_PrimFlags flag;
127 bool negated;
128};
129
130inline Usd_Term
131operator!(Usd_PrimFlags flag) {
132 return Usd_Term(flag, /*negated=*/true);
133}
134
135// Predicate functor class that tests a prim's flags against desired values.
136class Usd_PrimFlagsPredicate
137{
138public:
139 // Functor result type.
140 typedef bool result_type;
141
142 // Default ctor produces a tautology.
143 Usd_PrimFlagsPredicate() : _negate(false) {}
144
145 Usd_PrimFlagsPredicate(Usd_PrimFlags flag)
146 : _negate(false) {
147 _mask[flag] = 1;
148 _values[flag] = true;
149 }
150
151 // Implicit conversion from a single term.
152 Usd_PrimFlagsPredicate(Usd_Term term)
153 : _negate(false) {
154 _mask[term.flag] = 1;
155 _values[term.flag] = !term.negated;
156 }
157
158 // Convenience to produce a tautological predicate. Returns a
159 // default-constructed predicate.
160 static Usd_PrimFlagsPredicate Tautology() {
161 return Usd_PrimFlagsPredicate();
162 }
163
164 // Convenience to produce a contradictory predicate. Returns a negated
165 // default-constructed predicate.
166 static Usd_PrimFlagsPredicate Contradiction() {
167 return Usd_PrimFlagsPredicate()._Negate();
168 }
169
170 // Set flag to indicate whether prim traversal functions using this
171 // predicate should traverse beneath instances and return descendants
172 // that pass this predicate as instance proxy prims.
173 Usd_PrimFlagsPredicate &TraverseInstanceProxies(bool traverse) {
174 if (traverse) {
175 _mask[Usd_PrimInstanceProxyFlag] = 0;
176 _values[Usd_PrimInstanceProxyFlag] = 1;
177 }
178 else {
179 _mask[Usd_PrimInstanceProxyFlag] = 1;
180 _values[Usd_PrimInstanceProxyFlag] = 0;
181 }
182 return *this;
183 }
184
185 // Returns true if this predicate was explicitly set to include
186 // instance proxies, false otherwise.
187 bool IncludeInstanceProxiesInTraversal() const {
188 return !_mask[Usd_PrimInstanceProxyFlag] &&
189 _values[Usd_PrimInstanceProxyFlag];
190 }
191
192 // Invoke boolean predicate on UsdPrim \p prim.
193 USD_API
194 bool operator()(const class UsdPrim &prim) const;
195
196protected:
197
198 // Return true if this predicate is a tautology, false otherwise.
199 bool _IsTautology() const { return *this == Tautology(); }
200
201 // Set this predicate to be a tautology.
202 void _MakeTautology() { *this = Tautology(); }
203
204 // Return true if this predicate is a contradiction, false otherwise.
205 bool _IsContradiction() const { return *this == Contradiction(); }
206
207 // Set this predicate to be a contradiction.
208 void _MakeContradiction() { *this = Contradiction(); }
209
210 // Negate this predicate.
211 Usd_PrimFlagsPredicate &_Negate() {
212 _negate = !_negate;
213 return *this;
214 }
215
216 // Return a negated copy of this predicate.
217 Usd_PrimFlagsPredicate _GetNegated() const {
218 return Usd_PrimFlagsPredicate(*this)._Negate();
219 }
220
221 // Mask indicating which flags are of interest.
222 Usd_PrimFlagBits _mask;
223
224 // Desired values for prim flags.
225 Usd_PrimFlagBits _values;
226
227private:
228 // Evaluate this predicate with prim data \p prim. \p isInstanceProxy
229 // should be true if this is being evaluated for an instance proxy prim.
230 template <class PrimPtr>
231 bool _Eval(const PrimPtr &prim, bool isInstanceProxy) const {
232 // Manually set the instance proxy bit, since instance proxy
233 // state is never stored in Usd_PrimData's flags.
234 const Usd_PrimFlagBits primFlags = Usd_PrimFlagBits(prim->_GetFlags())
235 .set(Usd_PrimInstanceProxyFlag, isInstanceProxy);
236
237 // Mask the prim's flags, compare to desired values, then optionally
238 // negate the result.
239 return ((primFlags & _mask) == (_values & _mask)) ^ _negate;
240 }
241
242 // Evaluate the predicate \p pred with prim data \p prim. \p isInstanceProxy
243 // should be true if this is being evaluated for an instance proxy prim.
244 template <class PrimPtr>
245 friend bool
246 Usd_EvalPredicate(const Usd_PrimFlagsPredicate &pred, const PrimPtr &prim,
247 bool isInstanceProxy) {
248 return pred._Eval(prim, isInstanceProxy);
249 }
250
251 // Convenience method for evaluating \p pred using \p prim and
252 // \p proxyPrimPath to determine whether this is for an instance proxy
253 // prim.
254 template <class PrimPtr>
255 friend bool
256 Usd_EvalPredicate(const Usd_PrimFlagsPredicate &pred, const PrimPtr &prim,
257 const SdfPath &proxyPrimPath) {
258 return pred._Eval(prim, Usd_IsInstanceProxy(prim, proxyPrimPath));
259 }
260
261 // Equality comparison.
262 friend bool
263 operator==(const Usd_PrimFlagsPredicate &lhs,
264 const Usd_PrimFlagsPredicate &rhs) {
265 return lhs._mask == rhs._mask &&
266 lhs._values == rhs._values &&
267 lhs._negate == rhs._negate;
268 }
269 // Inequality comparison.
270 friend bool
271 operator!=(const Usd_PrimFlagsPredicate &lhs,
272 const Usd_PrimFlagsPredicate &rhs) {
273 return !(lhs == rhs);
274 }
275
276 // hash overload.
277 friend size_t hash_value(const Usd_PrimFlagsPredicate &p) {
278 return TfHash::Combine(
279 p._mask.to_ulong(), p._values.to_ulong(), p._negate
280 );
281 }
282
283 // Whether or not to negate the predicate's result.
284 bool _negate;
285
286};
287
288
299class Usd_PrimFlagsConjunction : public Usd_PrimFlagsPredicate {
300public:
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
348private:
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
368inline Usd_PrimFlagsConjunction
369operator&&(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
376inline Usd_PrimFlagsConjunction
377operator&&(const Usd_PrimFlagsConjunction &conjunction, Usd_Term rhs) {
378 return Usd_PrimFlagsConjunction(conjunction) &= rhs;
379}
380
381inline Usd_PrimFlagsConjunction
382operator&&(Usd_Term lhs, const Usd_PrimFlagsConjunction &conjunction) {
383 return Usd_PrimFlagsConjunction(conjunction) &= lhs;
384}
385
386inline Usd_PrimFlagsConjunction
387operator&&(Usd_PrimFlags lhs, Usd_PrimFlags rhs) {
388 return Usd_Term(lhs) && Usd_Term(rhs);
389}
390
391
402class Usd_PrimFlagsDisjunction : public Usd_PrimFlagsPredicate {
403public:
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
452private:
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
471inline Usd_PrimFlagsDisjunction
472operator||(Usd_Term lhs, Usd_Term rhs) {
473 return (Usd_PrimFlagsDisjunction() || lhs) || rhs;
474}
475
476inline Usd_PrimFlagsDisjunction
477operator||(const Usd_PrimFlagsDisjunction &disjunction, Usd_Term rhs) {
478 return Usd_PrimFlagsDisjunction(disjunction) |= rhs;
479}
480
481inline Usd_PrimFlagsDisjunction
482operator||(Usd_Term lhs, const Usd_PrimFlagsDisjunction &disjunction) {
483 return Usd_PrimFlagsDisjunction(disjunction) |= lhs;
484}
485
486inline Usd_PrimFlagsDisjunction
487operator||(Usd_PrimFlags lhs, Usd_PrimFlags rhs) {
488 return Usd_Term(lhs) || Usd_Term(rhs);
489}
490
491#ifdef doxygen
492
494extern unspecified UsdPrimIsActive;
496extern unspecified UsdPrimIsLoaded;
498extern unspecified UsdPrimIsModel;
500extern unspecified UsdPrimIsGroup;
502extern unspecified UsdPrimIsAbstract;
504extern unspecified UsdPrimIsDefined;
506extern unspecified UsdPrimIsInstance;
508extern unspecified UsdPrimHasDefiningSpecifier;
509
522extern unspecified UsdPrimDefaultPredicate;
523
527extern unspecified UsdPrimAllPrimsPredicate;
528
529#else
530
531static const Usd_PrimFlags UsdPrimIsActive = Usd_PrimActiveFlag;
532static const Usd_PrimFlags UsdPrimIsLoaded = Usd_PrimLoadedFlag;
533static const Usd_PrimFlags UsdPrimIsModel = Usd_PrimModelFlag;
534static const Usd_PrimFlags UsdPrimIsGroup = Usd_PrimGroupFlag;
535static const Usd_PrimFlags UsdPrimIsAbstract = Usd_PrimAbstractFlag;
536static const Usd_PrimFlags UsdPrimIsDefined = Usd_PrimDefinedFlag;
537static const Usd_PrimFlags UsdPrimIsInstance = Usd_PrimInstanceFlag;
538static const Usd_PrimFlags UsdPrimHasDefiningSpecifier
539 = Usd_PrimHasDefiningSpecifierFlag;
540
541USD_API extern const Usd_PrimFlagsConjunction UsdPrimDefaultPredicate;
542USD_API extern const Usd_PrimFlagsPredicate UsdPrimAllPrimsPredicate;
543
544#endif // doxygen
545
576inline Usd_PrimFlagsPredicate
577UsdTraverseInstanceProxies(Usd_PrimFlagsPredicate predicate)
578{
579 return predicate.TraverseInstanceProxies(true);
580}
581
586inline Usd_PrimFlagsPredicate
588{
590}
591
592PXR_NAMESPACE_CLOSE_SCOPE
593
594#endif // PXR_USD_USD_PRIM_FLAGS_H
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:290
static size_t Combine(Args &&... args)
Produce a hash code by combining the hash codes of several objects.
Definition: hash.h:492
UsdPrim is the sole persistent scenegraph object on a UsdStage, and is the embodiment of a "Prim" as ...
Definition: prim.h:134
size_t hash_value(const half h)
Overload hash_value for half.
Definition: half.h:45
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 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:587
unspecified UsdPrimAllPrimsPredicate
Predicate that includes all prims.