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 
27 /// \file usd/primFlags.h
28 ///
29 /// \anchor Usd_PrimFlags
30 ///
31 /// Provides terms for UsdPrim flags that can be combined to form either a
32 /// conjunction (via &&) or a disjunction (via ||).  The result is a
33 /// predicate functor object that tests those flags on the passed prim.
34 /// Currently UsdPrim::GetFilteredChildren(), UsdPrim::GetNextFilteredSibling(),
35 /// UsdPrim::GetFilteredDescendants(), and UsdPrimRange() accept these
36 /// predicates to filter out unwanted prims.
37 ///
38 /// For example:
39 /// \code
40 /// // Get only loaded model children.
41 /// prim.GetFilteredChildren(UsdPrimIsModel && UsdPrimIsLoaded)
42 /// \endcode
43 ///
44 /// For performance, these predicates are implemented by a bitwise test, so
45 /// arbitrary boolean expressions cannot be represented.  The set of boolean
46 /// expressions that can be represented are conjunctions with possibly negated
47 /// terms (or disjunctions, by De Morgan's law).  Here are some examples of
48 /// valid expressions:
49 /// \code
50 /// // simple conjunction.
51 /// (UsdPrimIsLoaded && UsdPrimIsGroup)
52 /// // conjunction with negated term.
53 /// (UsdPrimIsDefined && !UsdPrimIsAbstract)
54 /// // disjunction with negated term.
55 /// (!UsdPrimIsDefined || !UsdPrimIsActive)
56 /// // negated conjunction gives a disjunction.
57 /// !(UsdPrimIsLoaded && UsdPrimIsModel)
58 /// // negated conjunction gives a disjunction, which is further extended.
59 /// (!(UsdPrimIsLoaded && UsdPrimIsModel) || UsdPrimIsAbstract)
60 /// // equivalent to above.
61 /// (!UsdPrimIsLoaded || !UsdPrimIsModel || UsdPrimIsAbstract)
62 /// \endcode
63 /// Here are some examples of invalid expressions:
64 /// \code
65 /// // error: cannot || a term with a conjunction.
66 /// (UsdPrimIsLoaded && UsdPrimIsModel) || UsdPrimIsAbstract
67 /// // error: cannot && disjunctions.
68 /// (!UsdPrimIsDefined || UsdPrimIsAbstract) && (UsdPrimIsModel || !UsdPrimIsActive)
69 /// \endcode
70 ///
71 ///
72 /// The following variables provide the clauses that can be combined and
73 /// negated to produce predicates:
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_PrimPrototypeFlag,
105     Usd_PrimInstanceProxyFlag,
106     Usd_PrimPseudoRootFlag,
107 
108     Usd_PrimNumFlags
109 };
110 
111 typedef 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.
116 struct Usd_Term {
Usd_TermUsd_Term117     Usd_Term(Usd_PrimFlags flag) : flag(flag), negated(false) {}
Usd_TermUsd_Term118     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 
130 inline Usd_Term
131 operator!(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.
136 class Usd_PrimFlagsPredicate
137 {
138 public:
139     // Functor result type.
140     typedef bool result_type;
141 
142     // Default ctor produces a tautology.
Usd_PrimFlagsPredicate()143     Usd_PrimFlagsPredicate() : _negate(false) {}
144 
Usd_PrimFlagsPredicate(Usd_PrimFlags flag)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.
Usd_PrimFlagsPredicate(Usd_Term 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.
Tautology()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.
Contradiction()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.
TraverseInstanceProxies(bool traverse)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.
IncludeInstanceProxiesInTraversal()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 
196 protected:
197 
198     // Return true if this predicate is a tautology, false otherwise.
_IsTautology()199     bool _IsTautology() const { return *this == Tautology(); }
200 
201     // Set this predicate to be a tautology.
_MakeTautology()202     void _MakeTautology() { *this = Tautology(); }
203 
204     // Return true if this predicate is a contradiction, false otherwise.
_IsContradiction()205     bool _IsContradiction() const { return *this == Contradiction(); }
206 
207     // Set this predicate to be a contradiction.
_MakeContradiction()208     void _MakeContradiction() { *this = Contradiction(); }
209 
210     // Negate this predicate.
_Negate()211     Usd_PrimFlagsPredicate &_Negate() {
212         _negate = !_negate;
213         return *this;
214     }
215 
216     // Return a negated copy of this predicate.
_GetNegated()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 
227 private:
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>
_Eval(const PrimPtr & prim,bool isInstanceProxy)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
Usd_EvalPredicate(const Usd_PrimFlagsPredicate & pred,const PrimPtr & prim,bool isInstanceProxy)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
Usd_EvalPredicate(const Usd_PrimFlagsPredicate & pred,const PrimPtr & prim,const SdfPath & proxyPrimPath)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.
hash_value(const Usd_PrimFlagsPredicate & p)277     friend size_t hash_value(const Usd_PrimFlagsPredicate &p) {
278         size_t hash = p._mask.to_ulong();
279         boost::hash_combine(hash, p._values.to_ulong());
280         boost::hash_combine(hash, p._negate);
281         return hash;
282     }
283 
284     // Whether or not to negate the predicate's result.
285     bool _negate;
286 
287 };
288 
289 
290 /// Conjunction of prim flag predicate terms.
291 ///
292 /// Usually clients will implicitly create conjunctions by &&-ing together flag
293 /// predicate terms.  For example:
294 /// \code
295 /// // Get all loaded model children.
296 /// prim.GetFilteredChildren(UsdPrimIsModel && UsdPrimIsLoaded)
297 /// \endcode
298 ///
299 /// See primFlags.h for more details.
300 class Usd_PrimFlagsConjunction : public Usd_PrimFlagsPredicate {
301 public:
302     /// Default constructed conjunction is a tautology.
Usd_PrimFlagsConjunction()303     Usd_PrimFlagsConjunction() {};
304 
305     /// Construct with a term.
Usd_PrimFlagsConjunction(Usd_Term term)306     explicit Usd_PrimFlagsConjunction(Usd_Term term) {
307         *this &= term;
308     }
309 
310     /// Add an additional term to this conjunction.
311     Usd_PrimFlagsConjunction &operator&=(Usd_Term term) {
312         // If this conjunction is a contradiction, do nothing.
313         if (ARCH_UNLIKELY(_IsContradiction()))
314             return *this;
315 
316         // If we don't have the bit, set it in _mask and _values (if needed).
317         if (!_mask[term.flag]) {
318             _mask[term.flag] = 1;
319             _values[term.flag] = !term.negated;
320         } else if (_values[term.flag] != !term.negated) {
321             // If we do have the bit and the values disagree, then this entire
322             // conjunction becomes a contradiction.  If the values agree, it's
323             // redundant and we do nothing.
324             _MakeContradiction();
325         }
326         return *this;
327     }
328 
329     /// Negate this conjunction, producing a disjunction by De Morgan's law.
330     /// For instance:
331     ///
332     /// \code
333     /// !(UsdPrimIsLoaded && UsdPrimIsModel)
334     /// \endcode
335     ///
336     /// Will negate the conjunction in parens to produce a disjunction
337     /// equivalent to:
338     ///
339     /// \code
340     /// (!UsdPrimIsLoaded || !UsdPrimIsModel)
341     /// \endcode
342     ///
343     /// Every expression may be formulated as either a disjunction or a
344     /// conjuction, but allowing both affords increased expressiveness.
345     ///
346     USD_API
347     class Usd_PrimFlagsDisjunction operator!() const;
348 
349 private:
350 
351     // Let Usd_PrimFlagsDisjunction produce conjunctions when negated
352     friend class Usd_PrimFlagsDisjunction;
Usd_PrimFlagsConjunction(const Usd_PrimFlagsPredicate & base)353     Usd_PrimFlagsConjunction(const Usd_PrimFlagsPredicate &base) :
354         Usd_PrimFlagsPredicate(base) {}
355 
356     /// Combine two terms to make a conjunction.
357     friend Usd_PrimFlagsConjunction
358     operator&&(Usd_Term lhs, Usd_Term rhs);
359 
360     /// Create a new conjunction with the term \p rhs added.
361     friend Usd_PrimFlagsConjunction
362     operator&&(const Usd_PrimFlagsConjunction &conjunction, Usd_Term rhs);
363 
364     /// Create a new conjunction with the term \p lhs added.
365     friend Usd_PrimFlagsConjunction
366     operator&&(Usd_Term lhs, const Usd_PrimFlagsConjunction &conjunction);
367 };
368 
369 inline Usd_PrimFlagsConjunction
370 operator&&(Usd_Term lhs, Usd_Term rhs) {
371     // Apparently gcc 4.8.x doesn't like this as:
372     // return (Usd_PrimFlagsConjunction() && lhs) && rhs;
373     Usd_PrimFlagsConjunction tmp;
374     return (tmp && lhs) && rhs;
375 }
376 
377 inline Usd_PrimFlagsConjunction
378 operator&&(const Usd_PrimFlagsConjunction &conjunction, Usd_Term rhs) {
379     return Usd_PrimFlagsConjunction(conjunction) &= rhs;
380 }
381 
382 inline Usd_PrimFlagsConjunction
383 operator&&(Usd_Term lhs, const Usd_PrimFlagsConjunction &conjunction) {
384     return Usd_PrimFlagsConjunction(conjunction) &= lhs;
385 }
386 
387 inline Usd_PrimFlagsConjunction
388 operator&&(Usd_PrimFlags lhs, Usd_PrimFlags rhs) {
389     return Usd_Term(lhs) && Usd_Term(rhs);
390 }
391 
392 
393 /// Disjunction of prim flag predicate terms.
394 ///
395 /// Usually clients will implicitly create disjunctions by ||-ing together flag
396 /// predicate terms.  For example:
397 /// \code
398 /// // Get all deactivated or undefined children.
399 /// prim.GetFilteredChildren(!UsdPrimIsActive || !UsdPrimIsDefined)
400 /// \endcode
401 ///
402 /// See primFlags.h for more details.
403 class Usd_PrimFlagsDisjunction : public Usd_PrimFlagsPredicate {
404 public:
405     // Default constructed disjunction is a contradiction.
Usd_PrimFlagsDisjunction()406     Usd_PrimFlagsDisjunction() { _Negate(); };
407 
408     // Construct with a term.
Usd_PrimFlagsDisjunction(Usd_Term term)409     explicit Usd_PrimFlagsDisjunction(Usd_Term term) {
410         _Negate();
411         *this |= term;
412     }
413 
414     /// Add an additional term to this disjunction.
415     Usd_PrimFlagsDisjunction &operator|=(Usd_Term term) {
416         // If this disjunction is a tautology, do nothing.
417         if (ARCH_UNLIKELY(_IsTautology()))
418             return *this;
419 
420         // If we don't have the bit, set it in _mask and _values (if needed).
421         if (!_mask[term.flag]) {
422             _mask[term.flag] = 1;
423             _values[term.flag] = term.negated;
424         } else if (_values[term.flag] != term.negated) {
425             // If we do have the bit and the values disagree, then this entire
426             // disjunction becomes a tautology.  If the values agree, it's
427             // redundant and we do nothing.
428             _MakeTautology();
429         }
430         return *this;
431     }
432 
433     /// Negate this disjunction, producing a disjunction by De Morgan's law.
434     /// For instance:
435     ///
436     /// \code
437     /// !(UsdPrimIsLoaded || UsdPrimIsModel)
438     /// \endcode
439     ///
440     /// Will negate the disjunction in parens to produce a conjunction
441     /// equivalent to:
442     ///
443     /// \code
444     /// (!UsdPrimIsLoaded && !UsdPrimIsModel)
445     /// \endcode
446     ///
447     /// Every expression may be formulated as either a disjunction or a
448     /// conjuction, but allowing both affords increased expressiveness.
449     ///
450     USD_API
451     class Usd_PrimFlagsConjunction operator!() const;
452 
453 private:
454 
455     // Let Usd_PrimFlagsDisjunction produce conjunctions when negated.
456     friend class Usd_PrimFlagsConjunction;
Usd_PrimFlagsDisjunction(const Usd_PrimFlagsPredicate & base)457     Usd_PrimFlagsDisjunction(const Usd_PrimFlagsPredicate &base) :
458         Usd_PrimFlagsPredicate(base) {}
459 
460     /// Combine two terms to make a disjunction.
461     friend Usd_PrimFlagsDisjunction operator||(Usd_Term lhs, Usd_Term rhs);
462 
463     /// Create a new disjunction with the term \p rhs added.
464     friend Usd_PrimFlagsDisjunction
465     operator||(const Usd_PrimFlagsDisjunction &disjunction, Usd_Term rhs);
466 
467     /// Create a new disjunction with the term \p lhs added.
468     friend Usd_PrimFlagsDisjunction
469     operator||(Usd_Term lhs, const Usd_PrimFlagsDisjunction &disjunction);
470 };
471 
472 inline Usd_PrimFlagsDisjunction
473 operator||(Usd_Term lhs, Usd_Term rhs) {
474     return (Usd_PrimFlagsDisjunction() || lhs) || rhs;
475 }
476 
477 inline Usd_PrimFlagsDisjunction
478 operator||(const Usd_PrimFlagsDisjunction &disjunction, Usd_Term rhs) {
479     return Usd_PrimFlagsDisjunction(disjunction) |= rhs;
480 }
481 
482 inline Usd_PrimFlagsDisjunction
483 operator||(Usd_Term lhs, const Usd_PrimFlagsDisjunction &disjunction) {
484     return Usd_PrimFlagsDisjunction(disjunction) |= lhs;
485 }
486 
487 inline Usd_PrimFlagsDisjunction
488 operator||(Usd_PrimFlags lhs, Usd_PrimFlags rhs) {
489     return Usd_Term(lhs) || Usd_Term(rhs);
490 }
491 
492 #ifdef doxygen
493 
494 /// Tests UsdPrim::IsActive()
495 extern unspecified UsdPrimIsActive;
496 /// Tests UsdPrim::IsLoaded()
497 extern unspecified UsdPrimIsLoaded;
498 /// Tests UsdPrim::IsModel()
499 extern unspecified UsdPrimIsModel;
500 /// Tests UsdPrim::IsGroup()
501 extern unspecified UsdPrimIsGroup;
502 /// Tests UsdPrim::IsAbstract()
503 extern unspecified UsdPrimIsAbstract;
504 /// Tests UsdPrim::IsDefined()
505 extern unspecified UsdPrimIsDefined;
506 /// Tests UsdPrim::IsInstance()
507 extern unspecified UsdPrimIsInstance;
508 /// Tests UsdPrim::HasDefiningSpecifier()
509 extern unspecified UsdPrimHasDefiningSpecifier;
510 
511 /// The default predicate used for prim traversals in methods like
512 /// UsdPrim::GetChildren, UsdStage::Traverse, and by UsdPrimRange.
513 /// This is a conjunction that includes all active, loaded, defined,
514 /// non-abstract prims, equivalent to:
515 /// \code
516 /// UsdPrimIsActive && UsdPrimIsDefined && UsdPrimIsLoaded && !UsdPrimIsAbstract
517 /// \endcode
518 ///
519 /// This represents the prims on a stage that a processor would typically
520 /// consider present, meaningful, and needful of consideration.
521 ///
522 /// See \ref Usd_PrimFlags "Prim predicate flags" for more information.
523 extern unspecified UsdPrimDefaultPredicate;
524 
525 /// Predicate that includes all prims.
526 ///
527 /// See \ref Usd_PrimFlags "Prim predicate flags" for more information.
528 extern unspecified UsdPrimAllPrimsPredicate;
529 
530 #else
531 
532 static const Usd_PrimFlags UsdPrimIsActive = Usd_PrimActiveFlag;
533 static const Usd_PrimFlags UsdPrimIsLoaded = Usd_PrimLoadedFlag;
534 static const Usd_PrimFlags UsdPrimIsModel = Usd_PrimModelFlag;
535 static const Usd_PrimFlags UsdPrimIsGroup = Usd_PrimGroupFlag;
536 static const Usd_PrimFlags UsdPrimIsAbstract = Usd_PrimAbstractFlag;
537 static const Usd_PrimFlags UsdPrimIsDefined = Usd_PrimDefinedFlag;
538 static const Usd_PrimFlags UsdPrimIsInstance = Usd_PrimInstanceFlag;
539 static const Usd_PrimFlags UsdPrimHasDefiningSpecifier
540     = Usd_PrimHasDefiningSpecifierFlag;
541 
542 USD_API extern const Usd_PrimFlagsConjunction UsdPrimDefaultPredicate;
543 USD_API extern const Usd_PrimFlagsPredicate UsdPrimAllPrimsPredicate;
544 
545 #endif // doxygen
546 
547 /// This function is used to allow the prim traversal functions listed under
548 /// \ref Usd_PrimFlags "Prim predicate flags" to traverse beneath instance
549 /// prims and return descendants that pass the specified \p predicate
550 /// as instance proxy prims.  For example:
551 ///
552 /// \code
553 /// // Return all children of the specified prim.
554 /// // If prim is an instance, return all children as instance proxy prims.
555 /// prim.GetFilteredChildren(
556 ///     UsdTraverseInstanceProxies(UsdPrimAllPrimsPredicate))
557 ///
558 /// // Return children of the specified prim that pass the default predicate.
559 /// // If prim is an instance, return the children that pass this predicate
560 /// // as instance proxy prims.
561 /// prim.GetFilteredChildren(UsdTraverseInstanceProxies());
562 ///
563 /// // Return all model or group children of the specified prim.
564 /// // If prim is an instance, return the children that pass this predicate
565 /// // as instance proxy prims.
566 /// prim.GetFilteredChildren(UsdTraverseInstanceProxies(UsdPrimIsModel || UsdPrimIsGroup));
567 /// \endcode
568 ///
569 /// Users may also call Usd_PrimFlagsPredicate::TraverseInstanceProxies to
570 /// enable traversal beneath instance prims.  This function is equivalent to:
571 /// \code
572 /// predicate.TraverseInstanceProxies(true);
573 /// \endcode
574 ///
575 /// However, this function may be more convenient, especially when calling
576 /// a prim traversal function with a default-constructed tautology predicate.
577 inline Usd_PrimFlagsPredicate
UsdTraverseInstanceProxies(Usd_PrimFlagsPredicate predicate)578 UsdTraverseInstanceProxies(Usd_PrimFlagsPredicate predicate)
579 {
580     return predicate.TraverseInstanceProxies(true);
581 }
582 
583 /// \overload
584 /// Convenience method equivalent to calling UsdTraverseInstanceProxies
585 /// with the UsdPrimDefaultPredicate that is used by default for prim
586 /// traversals.
587 inline Usd_PrimFlagsPredicate
UsdTraverseInstanceProxies()588 UsdTraverseInstanceProxies()
589 {
590     return UsdTraverseInstanceProxies(UsdPrimDefaultPredicate);
591 }
592 
593 PXR_NAMESPACE_CLOSE_SCOPE
594 
595 #endif // PXR_USD_USD_PRIM_FLAGS_H
596