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_H
25 #define PXR_USD_USD_PRIM_H
26 
27 /// \file usd/prim.h
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/usd/api.h"
31 #include "pxr/usd/usd/common.h"
32 #include "pxr/usd/usd/object.h"
33 #include "pxr/usd/usd/primFlags.h"
34 
35 #include "pxr/usd/sdf/schema.h"
36 #include "pxr/base/trace/trace.h"
37 
38 #include "pxr/base/tf/declarePtrs.h"
39 #include "pxr/base/tf/refBase.h"
40 #include "pxr/base/tf/token.h"
41 #include "pxr/base/tf/weakBase.h"
42 
43 #include "pxr/usd/sdf/path.h"
44 
45 #include <boost/iterator/iterator_adaptor.hpp>
46 #include <boost/range/iterator_range.hpp>
47 
48 #include <string>
49 #include <type_traits>
50 #include <vector>
51 
52 PXR_NAMESPACE_OPEN_SCOPE
53 
54 class UsdPrim;
55 class UsdPrimDefinition;
56 class UsdPrimRange;
57 class Usd_PrimData;
58 
59 class UsdAttribute;
60 class UsdRelationship;
61 class UsdPayloads;
62 class UsdReferences;
63 class UsdSchemaBase;
64 class UsdAPISchemaBase;
65 class UsdInherits;
66 class UsdSpecializes;
67 class UsdVariantSets;
68 class UsdVariantSet;
69 
70 class SdfPayload;
71 
72 class UsdPrimSiblingIterator;
73 typedef boost::iterator_range<UsdPrimSiblingIterator> UsdPrimSiblingRange;
74 
75 class UsdPrimSubtreeIterator;
76 typedef boost::iterator_range<UsdPrimSubtreeIterator> UsdPrimSubtreeRange;
77 
78 /// \class UsdPrim
79 ///
80 /// UsdPrim is the sole persistent scenegraph object on a UsdStage, and
81 /// is the embodiment of a "Prim" as described in the <em>Universal Scene
82 /// Description Composition Compendium</em>
83 ///
84 /// A UsdPrim is the principal container of other types of scene description.
85 /// It provides API for accessing and creating all of the contained kinds
86 /// of scene description, which include:
87 /// \li UsdVariantSets - all VariantSets on the prim (GetVariantSets(), GetVariantSet())
88 /// \li UsdReferences - all references on the prim (GetReferences())
89 /// \li UsdInherits - all inherits on the prim (GetInherits())
90 /// \li UsdSpecializes - all specializes on the prim (GetSpecializes())
91 ///
92 /// As well as access to the API objects for properties contained within the
93 /// prim - UsdPrim as well as all of the following classes are subclasses
94 /// of UsdObject:
95 /// \li UsdProperty - generic access to all attributes and relationships.
96 /// A UsdProperty can be queried and cast to a UsdAttribute or UsdRelationship
97 /// using UsdObject::Is<>() and UsdObject::As<>(). (GetPropertyNames(),
98 /// GetProperties(), GetPropertiesInNamespace(), GetPropertyOrder(),
99 /// SetPropertyOrder())
100 /// \li UsdAttribute - access to default and timesampled attribute values, as
101 /// well as value resolution information, and attribute-specific metadata
102 /// (CreateAttribute(), GetAttribute(), GetAttributes(), HasAttribute())
103 /// \li UsdRelationship - access to authoring and resolving relationships
104 /// to other prims and properties (CreateRelationship(), GetRelationship(),
105 /// GetRelationships(), HasRelationship())
106 ///
107 /// UsdPrim also provides access to iteration through its prim children,
108 /// optionally making use of the \ref primFlags.h "prim predicates facility"
109 /// (GetChildren(), GetAllChildren(), GetFilteredChildren()).
110 ///
111 /// \section Lifetime Management
112 ///
113 /// Clients acquire UsdPrim objects, which act like weak/guarded pointers
114 /// to persistent objects owned and managed by their originating UsdStage.
115 /// We provide the following guarantees for a UsdPrim acquired via
116 /// UsdStage::GetPrimAtPath() or UsdStage::OverridePrim() or
117 /// UsdStage::DefinePrim():
118 /// \li As long as no further mutations to the structure of the UsdStage
119 ///     are made, the UsdPrim will still be valid.  Loading and
120 ///     Unloading are considered structural mutations.
121 /// \li When the UsdStage's structure \em is mutated, the thread performing
122 ///     the mutation will receive a UsdNotice::ObjectsChanged notice
123 ///     after the stage has been reconfigured, which provides details as to
124 ///     what prims may have been created or destroyed, and what prims
125 ///     may simply have changed in some structural way.
126 ///
127 /// Prim access in "reader" threads should be limited to GetPrimAtPath(), which
128 /// will never cause a mutation to the Stage or its layers.
129 ///
130 /// Please refer to \ref UsdNotice for a listing of
131 /// the events that could cause UsdNotice::ObjectsChanged to be emitted.
132 class UsdPrim : public UsdObject
133 {
134 public:
135     /// Convenience typedefs.
136     typedef UsdPrimSiblingIterator SiblingIterator;
137     typedef UsdPrimSiblingRange SiblingRange;
138 
139     /// Convenience typedefs.
140     typedef UsdPrimSubtreeIterator SubtreeIterator;
141     typedef UsdPrimSubtreeRange SubtreeRange;
142 
143     /// Construct an invalid prim.
UsdPrim()144     UsdPrim() : UsdObject(_Null<UsdPrim>()) {}
145 
146     /// Return the prim's full type info composed from its type name, applied
147     /// API schemas, and any fallback types defined on the stage for
148     /// unrecognized prim type names. The returned type structure contains the
149     /// "true" schema type used to create this prim's prim definition and answer
150     /// the IsA query. This value is cached and efficient to query.
151     /// \sa GetTypeName
152     /// \sa GetAppliedSchemas
153     /// \sa \ref Usd_OM_FallbackPrimTypes
GetPrimTypeInfo()154     const UsdPrimTypeInfo &GetPrimTypeInfo() const {
155         return _Prim()->GetPrimTypeInfo();
156     }
157 
158     /// Return this prim's definition based on the prim's type if the type
159     /// is a registered prim type. Returns an empty prim definition if it is
160     /// not.
GetPrimDefinition()161     const UsdPrimDefinition &GetPrimDefinition() const {
162         return _Prim()->GetPrimDefinition();
163     }
164 
165     /// Return this prim's composed specifier.
GetSpecifier()166     SdfSpecifier GetSpecifier() const { return _Prim()->GetSpecifier(); };
167 
168     /// Return all the authored SdfPrimSpecs that may contain opinions for this
169     /// prim in order from strong to weak.
170     ///
171     /// This does not include all the places where contributing prim specs could
172     /// potentially be created; rather, it includes only those prim specs that
173     /// already exist.  To discover all the places that prim specs could be
174     /// authored that would contribute opinions, see
175     /// \ref "Composition Structure"
176     ///
177     /// \note Use this method for debugging and diagnostic purposes.  It is
178     /// **not** advisable to retain a PrimStack for expedited metadata value
179     /// resolution, since not all metadata resolves with simple "strongest
180     /// opinion wins" semantics.
181     USD_API
182     SdfPrimSpecHandleVector GetPrimStack() const;
183 
184     /// Author an opinion for this Prim's specifier at the current edit
185     /// target.
SetSpecifier(SdfSpecifier specifier)186     bool SetSpecifier(SdfSpecifier specifier) const {
187         return SetMetadata(SdfFieldKeys->Specifier, specifier);
188     }
189 
190     /// Return this prim's composed type name. This value is cached and is
191     /// efficient to query.
192     /// Note that this is just the composed type name as authored and may not
193     /// represent the full type of the prim and its prim definition. If you
194     /// need to reason about the actual type of the prim, use GetPrimTypeInfo
195     /// instead as it accounts for recognized schemas, applied API schemas,
196     /// fallback types, etc.
GetTypeName()197     const TfToken &GetTypeName() const { return _Prim()->GetTypeName(); };
198 
199     /// Author this Prim's typeName at the current EditTarget.
SetTypeName(const TfToken & typeName)200     bool SetTypeName(const TfToken & typeName) const {
201         return SetMetadata(SdfFieldKeys->TypeName, typeName);
202     }
203 
204     /// Clear the opinion for this Prim's typeName at the current edit
205     /// target.
ClearTypeName()206     bool ClearTypeName() const {
207         return ClearMetadata(SdfFieldKeys->TypeName);
208     }
209 
210     /// Return true if a typeName has been authored.
HasAuthoredTypeName()211     bool HasAuthoredTypeName() const {
212         return HasAuthoredMetadata(SdfFieldKeys->TypeName);
213     }
214 
215     /// Return true if this prim is active, meaning neither it nor any of its
216     /// ancestors have active=false.  Return false otherwise.
217     ///
218     /// See \ref Usd_ActiveInactive for what it means for a prim to be active.
IsActive()219     bool IsActive() const { return _Prim()->IsActive(); }
220 
221     /// Author 'active' metadata for this prim at the current EditTarget.
222     ///
223     /// See \ref Usd_ActiveInactive for the effects of activating or deactivating
224     /// a prim.
SetActive(bool active)225     bool SetActive(bool active) const {
226         return SetMetadata(SdfFieldKeys->Active, active);
227     }
228 
229     /// Remove the authored 'active' opinion at the current EditTarget.  Do
230     /// nothing if there is no authored opinion.
231     ///
232     /// See \ref Usd_ActiveInactive for the effects of activating or deactivating
233     /// a prim.
ClearActive()234     bool ClearActive() const {
235         return ClearMetadata(SdfFieldKeys->Active);
236     }
237 
238     /// Return true if this prim has an authored opinion for 'active', false
239     /// otherwise.
240     ///
241     /// See \ref Usd_ActiveInactive for what it means for a prim to be active.
HasAuthoredActive()242     bool HasAuthoredActive() const {
243         return HasAuthoredMetadata(SdfFieldKeys->Active);
244     }
245 
246     /// Return true if this prim is active, and \em either it is loadable and
247     /// it is loaded, \em or its nearest loadable ancestor is loaded, \em or it
248     /// has no loadable ancestor; false otherwise.
IsLoaded()249     bool IsLoaded() const { return _Prim()->IsLoaded(); }
250 
251     /// Return true if this prim is a model based on its kind metadata, false
252     /// otherwise.
IsModel()253     bool IsModel() const { return _Prim()->IsModel(); }
254 
255     /// Return true if this prim is a model group based on its kind metadata,
256     /// false otherwise.  If this prim is a group, it is also necessarily a
257     /// model.
IsGroup()258     bool IsGroup() const { return _Prim()->IsGroup(); }
259 
260     /// Return true if this prim or any of its ancestors is a class.
IsAbstract()261     bool IsAbstract() const { return _Prim()->IsAbstract(); }
262 
263     /// Return true if this prim and all its ancestors have defining specifiers,
264     /// false otherwise. \sa SdfIsDefiningSpecifier.
IsDefined()265     bool IsDefined() const { return _Prim()->IsDefined(); }
266 
267     /// Return true if this prim has a specifier of type SdfSpecifierDef
268     /// or SdfSpecifierClass. \sa SdfIsDefiningSpecifier
HasDefiningSpecifier()269     bool HasDefiningSpecifier() const {
270         return _Prim()->HasDefiningSpecifier();
271     }
272 
273     /// Return a vector containing the names of API schemas which have
274     /// been applied to this prim. This includes both the authored API schemas
275     /// applied using the Apply() method on the particular schema class as
276     /// well as any built-in API schemas that are automatically included
277     /// through the prim type's prim definition.
278     /// To get only the authored API schemas use GetPrimTypeInfo instead.
279     USD_API
280     TfTokenVector GetAppliedSchemas() const;
281 
282     /// Alias for the "predicate" function parameter passed into the various
283     /// Get{Authored}{PropertyNames,Properties} methods.
284     using PropertyPredicateFunc =
285         std::function<bool (const TfToken &propertyName)>;
286 
287     /// Return all of this prim's property names (attributes and relationships),
288     /// including all builtin properties.
289     ///
290     /// If a valid \p predicate is passed in, then only properties whose names
291     /// pass the predicate are included in the result. This is useful if the
292     /// client is interested only in a subset of properties on the prim. For
293     /// example, only the ones in a given namespace or only the ones needed to
294     /// compute a value.
295     ///
296     /// \sa GetAuthoredPropertyNames()
297     /// \sa UsdProperty::IsAuthored()
298     USD_API
299     TfTokenVector GetPropertyNames(
300         const PropertyPredicateFunc &predicate={}) const;
301 
302     /// Return this prim's property names (attributes and relationships) that
303     /// have authored scene description, ordered according to the strongest
304     /// propertyOrder statement in scene description if one exists, otherwise
305     /// ordered according to TfDictionaryLessThan.
306     ///
307     /// If a valid \p predicate is passed in, then only the authored properties
308     /// whose names pass the predicate are included in the result. This is
309     /// useful if the client is interested only in a subset of authored
310     /// properties on the prim. For example, only the ones in a given namespace
311     /// or only the ones needed to compute a value.
312     ///
313     /// \sa GetPropertyNames()
314     /// \sa UsdProperty::IsAuthored()
315     USD_API
316     TfTokenVector GetAuthoredPropertyNames(
317         const PropertyPredicateFunc &predicate={}) const;
318 
319     /// Return all of this prim's properties (attributes and relationships),
320     /// including all builtin properties, ordered by name according to the
321     /// strongest propertyOrder statement in scene description if one exists,
322     /// otherwise ordered according to TfDictionaryLessThan.
323     ///
324     /// If a valid \p predicate is passed in, then only properties whose names
325     /// pass the predicate are included in the result. This is useful if the
326     /// client is interested only in a subset of properties on the prim. For
327     /// example, only the ones in a given namespace or only the ones needed to
328     /// compute a value.
329     ///
330     /// To obtain only either attributes or relationships, use either
331     /// GetAttributes() or GetRelationships().
332     ///
333     /// To determine whether a property is either an attribute or a
334     /// relationship, use the UsdObject::As() and UsdObject::Is() methods in
335     /// C++:
336     ///
337     /// \code
338     /// // Use As<>() to obtain a subclass instance.
339     /// if (UsdAttribute attr = property.As<UsdAttribute>()) {
340     ///     // use attribute 'attr'.
341     /// else if (UsdRelationship rel = property.As<UsdRelationship>()) {
342     ///     // use relationship 'rel'.
343     /// }
344     ///
345     /// // Use Is<>() to discriminate only.
346     /// if (property.Is<UsdAttribute>()) {
347     ///     // property is an attribute.
348     /// }
349     /// \endcode
350     ///
351     /// In Python, use the standard isinstance() function:
352     ///
353     /// \code
354     /// if isinstance(property, Usd.Attribute):
355     ///     # property is a Usd.Attribute.
356     /// elif isinstance(property, Usd.Relationship):
357     ///     # property is a Usd.Relationship.
358     /// \endcode
359     ///
360     /// \sa GetAuthoredProperties()
361     /// \sa UsdProperty::IsAuthored()
362     USD_API
363     std::vector<UsdProperty> GetProperties(
364         const PropertyPredicateFunc &predicate={}) const;
365 
366     /// Return this prim's properties (attributes and relationships) that have
367     /// authored scene description, ordered by name according to the strongest
368     /// propertyOrder statement in scene description if one exists, otherwise
369     /// ordered according to TfDictionaryLessThan.
370     ///
371     /// If a valid \p predicate is passed in, then only authored properties
372     /// whose names pass the predicate are included in the result. This is
373     /// useful if the client is interested only in a subset of authored
374     /// properties on the prim. For example, only the ones in a given namespace
375     /// or only the ones needed to compute a value.
376     ///
377     /// \sa GetProperties()
378     /// \sa UsdProperty::IsAuthored()
379     USD_API
380     std::vector<UsdProperty> GetAuthoredProperties(
381         const PropertyPredicateFunc &predicate={}) const;
382 
383     /// Return this prim's properties that are inside the given property
384     /// namespace ordered according to the strongest propertyOrder statement in
385     /// scene description if one exists, otherwise ordered according to
386     /// TfDictionaryLessThan.
387     ///
388     /// A \p namespaces argument whose elements are ["ri", "attribute"] will
389     /// return all the properties under the namespace "ri:attribute",
390     /// i.e. "ri:attribute:*". An empty \p namespaces argument is equivalent to
391     /// GetProperties().
392     ///
393     /// For details of namespaced properties, see \ref Usd_Ordering
394     USD_API
395     std::vector<UsdProperty>
396     GetPropertiesInNamespace(const std::vector<std::string> &namespaces) const;
397 
398     /// \overload
399     /// \p namespaces must be an already-concatenated ordered set of namespaces,
400     /// and may or may not terminate with the namespace-separator character. If
401     /// \p namespaces is empty, this method is equivalent to GetProperties().
402     USD_API
403     std::vector<UsdProperty>
404     GetPropertiesInNamespace(const std::string &namespaces) const;
405 
406     /// Like GetPropertiesInNamespace(), but exclude properties that do not have
407     /// authored scene description from the result.  See
408     /// UsdProperty::IsAuthored().
409     ///
410     /// For details of namespaced properties, see \ref Usd_Ordering
411     USD_API
412     std::vector<UsdProperty>
413     GetAuthoredPropertiesInNamespace(
414         const std::vector<std::string> &namespaces) const;
415 
416     /// \overload
417     /// \p namespaces must be an already-concatenated ordered set of namespaces,
418     /// and may or may not terminate with the namespace-separator character. If
419     /// \p namespaces is empty, this method is equivalent to
420     /// GetAuthoredProperties().
421     USD_API
422     std::vector<UsdProperty>
423     GetAuthoredPropertiesInNamespace(const std::string &namespaces) const;
424 
425     /// Return the strongest propertyOrder metadata value authored on this prim.
426     USD_API
427     TfTokenVector GetPropertyOrder() const;
428 
429     /// Author an opinion for propertyOrder metadata on this prim at the current
430     /// EditTarget.
SetPropertyOrder(const TfTokenVector & order)431     void SetPropertyOrder(const TfTokenVector &order) const {
432         SetMetadata(SdfFieldKeys->PropertyOrder, order);
433     }
434 
435     /// Remove the opinion for propertyOrder metadata on this prim at the current
436     /// EditTarget.
ClearPropertyOrder()437     void ClearPropertyOrder() const {
438         ClearMetadata(SdfFieldKeys->PropertyOrder);
439     }
440 
441     /// Remove all scene description for the property with the
442     /// given \p propName <em>in the current UsdEditTarget</em>.
443     /// Return true if the property is removed, false otherwise.
444     ///
445     /// Because this method can only remove opinions about the property from
446     /// the current EditTarget, you may generally find it more useful to use
447     /// UsdAttribute::Block(), which will ensure that all values from the
448     /// EditTarget and weaker layers for the property will be ignored.
449     USD_API
450     bool RemoveProperty(const TfToken &propName);
451 
452     /// Return a UsdProperty with the name \a propName. The property
453     /// returned may or may not \b actually exist so it must be checked for
454     /// validity. Suggested use:
455     ///
456     /// \code
457     /// if (UsdProperty myProp = prim.GetProperty("myProp")) {
458     ///    // myProp is safe to use.
459     ///    // Edits to the owning stage requires subsequent validation.
460     /// } else {
461     ///    // myProp was not defined/authored
462     /// }
463     /// \endcode
464     USD_API
465     UsdProperty GetProperty(const TfToken &propName) const;
466 
467     /// Return true if this prim has an property named \p propName, false
468     /// otherwise.
469     USD_API
470     bool HasProperty(const TfToken &propName) const;
471 
472 private:
473     // The non-templated implementation of UsdPrim::IsA using the
474     // TfType system. \p validateSchemaType is provided for python clients
475     // because they can't use compile time assertions on the input type.
476     USD_API
477     bool _IsA(const TfType& schemaType, bool validateSchemaType) const;
478 
479     // Separate implementations for UsdPrim::HasAPI for single and multiple
480     // apply API schema TfTypes.
481     USD_API
482     bool _HasSingleApplyAPI(const TfType& schemaType) const;
483 
484     USD_API
485     bool _HasMultiApplyAPI(const TfType& schemaType,
486                            const TfToken &instanceName) const;
487 
488     // Private implementation for all ApplyAPI, CanApplyAPI, and RemoveAPI
489     // methods for both single apply and multiple apply APIs. The multiple
490     // apply API methods validate that the instance name is non-empty, but
491     // otherwise all of these methods do no other input validation as the
492     // public methods are expected to have already done either compile time or
493     // runtime validation already.
494     USD_API
495     bool _CanApplyAPI(const TfType& schemaType,
496                       std::string *whyNot) const;
497 
498     USD_API
499     bool _CanApplyAPI(const TfType& schemaType,
500                       const TfToken& instanceName,
501                       std::string *whyNot) const;
502 
503     USD_API
504     bool _ApplyAPI(const TfType& schemaType) const;
505 
506     USD_API
507     bool _ApplyAPI(const TfType& schemaType,
508                    const TfToken& instanceName) const;
509 
510     USD_API
511     bool _RemoveAPI(const TfType& schemaType) const;
512 
513     USD_API
514     bool _RemoveAPI(const TfType& schemaType,
515                     const TfToken& instanceName) const;
516 
517 public:
518     /// Return true if the prim's schema type, is or inherits schema type T.
519     /// \sa GetPrimTypeInfo
520     /// \sa UsdPrimTypeInfo::GetSchemaType
521     /// \sa \ref Usd_OM_FallbackPrimTypes
522     template <typename T>
IsA()523     bool IsA() const {
524         static_assert(std::is_base_of<UsdSchemaBase, T>::value,
525                       "Provided type must derive UsdSchemaBase.");
526         return _IsA(TfType::Find<T>(), /*validateSchemaType=*/false);
527     };
528 
529     /// Return true if the prim's schema type is or inherits \p schemaType.
530     /// \sa GetPrimTypeInfo
531     /// \sa UsdPrimTypeInfo::GetSchemaType
532     /// \sa \ref Usd_OM_FallbackPrimTypes
533     USD_API
534     bool IsA(const TfType& schemaType) const;
535 
536     /// __Using HasAPI in C++__
537     /// \code
538     /// UsdPrim prim = stage->OverridePrim("/path/to/prim");
539     /// MyDomainBozAPI = MyDomainBozAPI::Apply(prim);
540     /// assert(prim.HasAPI<MyDomainBozAPI>());
541     ///
542     /// UsdCollectionAPI collAPI = UsdCollectionAPI::Apply(prim,
543     ///         /*instanceName*/ TfToken("geom"))
544     /// assert(prim.HasAPI<UsdCollectionAPI>()
545     /// assert(prim.HasAPI<UsdCollectionAPI>(/*instanceName*/ TfToken("geom")))
546     /// \endcode
547     ///
548     /// The python version of this method takes as an argument the TfType
549     /// of the API schema class. Similar validation of the schema type is
550     /// performed in python at run-time and a coding error is issued if
551     /// the given type is not a valid applied API schema.
552     ///
553     /// __Using HasAPI in Python__
554     /// \code{.py}
555     /// prim = stage.OverridePrim("/path/to/prim")
556     /// bozAPI = MyDomain.BozAPI.Apply(prim)
557     /// assert prim.HasAPI(MyDomain.BozAPI)
558     ///
559     /// collAPI = Usd.CollectionAPI.Apply(prim, "geom")
560     /// assert(prim.HasAPI(Usd.CollectionAPI))
561     /// assert(prim.HasAPI(Usd.CollectionAPI, instanceName="geom"))
562     /// \endcode
563     /// @{
564 
565     /// Return true if the UsdPrim has had a single API schema represented by
566     /// the C++ class type __T__ applied to it through the Apply() method
567     /// provided on the API schema class.
568     ///
569     template <typename T>
570     typename std::enable_if<T::schemaKind != UsdSchemaKind::MultipleApplyAPI,
571         bool>::type
HasAPI()572     HasAPI() const {
573         static_assert(std::is_base_of<UsdAPISchemaBase, T>::value,
574                       "Provided type must derive UsdAPISchemaBase.");
575         static_assert(!std::is_same<UsdAPISchemaBase, T>::value,
576                       "Provided type must not be UsdAPISchemaBase.");
577         // Note that this function template is enabled for any schema kind,
578         // other than MultipleApplyAPI, but is only valid for SingleApplyAPI.
579         // This static assert provides better error information for calling
580         // HasAPI with an invalid template type than if we limited HasAPI
581         // substitution matching to just the two valid schema kinds.
582         static_assert(T::schemaKind == UsdSchemaKind::SingleApplyAPI,
583             "Provided schema type must be a single apply API schema.");
584 
585         return _HasSingleApplyAPI(TfType::Find<T>());
586     }
587 
588     /// Return true if the UsdPrim has had a multiple-apply API schema
589     /// represented by the C++ class type __T__ applied to it through the
590     /// Apply() method provided on the API schema class.
591     ///
592     /// \p instanceName, if non-empty is used to determine if a particular
593     /// instance of a multiple-apply API schema (eg. UsdCollectionAPI) has been
594     /// applied to the prim, otherwise this returns true if any instance of
595     /// the multiple-apply API has been applied.
596     template <typename T>
597     typename std::enable_if<T::schemaKind == UsdSchemaKind::MultipleApplyAPI,
598         bool>::type
599     HasAPI(const TfToken &instanceName = TfToken()) const {
600         static_assert(std::is_base_of<UsdAPISchemaBase, T>::value,
601                       "Provided type must derive UsdAPISchemaBase.");
602         static_assert(!std::is_same<UsdAPISchemaBase, T>::value,
603                       "Provided type must not be UsdAPISchemaBase.");
604         static_assert(T::schemaKind == UsdSchemaKind::MultipleApplyAPI,
605             "Provided schema type must be a multi apply API schema.");
606 
607         return _HasMultiApplyAPI(TfType::Find<T>(), instanceName);
608     }
609 
610     /// Return true if a prim has an API schema with TfType \p schemaType.
611     ///
612     /// \p instanceName, if non-empty is used to determine if a particular
613     /// instance of a multiple-apply API schema (eg. UsdCollectionAPI) has been
614     /// applied to the prim. A coding error is issued if a non-empty
615     /// \p instanceName is passed in and __T__ represents a single-apply API
616     /// schema.
617     ///
618     /// This function behaves exactly like the templated HasAPI functions
619     /// except for the runtime schemaType validation which happens at compile
620     /// time in the templated versions. This method is provided for python
621     /// clients. Use of the templated HasAPI functions are preferred.
622     USD_API
623     bool HasAPI(const TfType& schemaType,
624                 const TfToken& instanceName=TfToken()) const;
625 
626     /// }@
627 
628     /// Returns whether a __single-apply__ API schema with the given C++ type
629     /// 'SchemaType' can be applied to this prim. If the return value is false,
630     /// and \p whyNot is provided, the reason the schema cannot be applied is
631     /// written to whyNot.
632     ///
633     /// Whether the schema can be applied is determined by the schema type
634     /// definition which may specify that the API schema can only be applied to
635     /// certain prim types.
636     ///
637     /// The return value of this function only indicates whether it would be
638     /// valid to apply this schema to the prim. It has no bearing on whether
639     /// calling ApplyAPI will be successful or not.
640     template <typename SchemaType>
641     bool CanApplyAPI(std::string *whyNot = nullptr) const {
642         static_assert(std::is_base_of<UsdAPISchemaBase, SchemaType>::value,
643             "Provided type must derive UsdAPISchemaBase.");
644         static_assert(!std::is_same<UsdAPISchemaBase, SchemaType>::value,
645             "Provided type must not be UsdAPISchemaBase.");
646         static_assert(SchemaType::schemaKind == UsdSchemaKind::SingleApplyAPI,
647             "Provided schema type must be a single apply API schema.");
648 
649         static const TfType schemaType = TfType::Find<SchemaType>();
650         return _CanApplyAPI(schemaType, whyNot);
651     }
652 
653     /// Non-templated overload of the templated CanApplyAPI above.
654     ///
655     /// This function behaves exactly like the templated CanApplyAPI
656     /// except for the runtime schemaType validation which happens at compile
657     /// time in the templated version. This method is provided for python
658     /// clients. Use of the templated CanApplyAPI is preferred.
659     USD_API
660     bool CanApplyAPI(const TfType& schemaType,
661                      std::string *whyNot = nullptr) const;
662 
663     /// Returns whether a __multiple-apply__ API schema with the given C++
664     /// type 'SchemaType' can be applied to this prim with the given
665     /// \p instanceName. If the return value is false, and \p whyNot is
666     /// provided, the reason the schema cannot be applied is written to whyNot.
667     ///
668     /// Whether the schema can be applied is determined by the schema type
669     /// definition which may specify that the API schema can only be applied to
670     /// certain prim types. It also determines whether the instance name is a
671     /// valid instance name for the multiple apply schema.
672     ///
673     /// The return value of this function only indicates whether it would be
674     /// valid to apply this schema to the prim. It has no bearing on whether
675     /// calling ApplyAPI will be successful or not.
676     template <typename SchemaType>
677     bool CanApplyAPI(const TfToken &instanceName,
678                      std::string *whyNot = nullptr) const {
679         static_assert(std::is_base_of<UsdAPISchemaBase, SchemaType>::value,
680             "Provided type must derive UsdAPISchemaBase.");
681         static_assert(!std::is_same<UsdAPISchemaBase, SchemaType>::value,
682             "Provided type must not be UsdAPISchemaBase.");
683         static_assert(SchemaType::schemaKind == UsdSchemaKind::MultipleApplyAPI,
684             "Provided schema type must be a multiple apply API schema.");
685 
686         static const TfType schemaType = TfType::Find<SchemaType>();
687         return _CanApplyAPI(schemaType, instanceName, whyNot);
688     }
689 
690     /// Non-templated overload of the templated CanApplyAPI above.
691     ///
692     /// This function behaves exactly like the templated CanApplyAPI
693     /// except for the runtime schemaType validation which happens at compile
694     /// time in the templated version. This method is provided for python
695     /// clients. Use of the templated CanApplyAPI is preferred.
696     USD_API
697     bool CanApplyAPI(const TfType& schemaType,
698                      const TfToken& instanceName,
699                      std::string *whyNot = nullptr) const;
700 
701     /// Applies a __single-apply__ API schema with the given C++ type
702     /// 'SchemaType' to this prim in the current edit target.
703     ///
704     /// This information is stored by adding the API schema's name token to the
705     /// token-valued, listOp metadata \em apiSchemas on this prim.
706     ///
707     /// Returns true upon success or if the API schema is already applied in
708     /// the current edit target.
709     ///
710     /// An error is issued and false returned for any of the following
711     /// conditions:
712     /// \li this prim is not a valid prim for editing
713     /// \li this prim is valid, but cannot be reached or overridden in the
714     /// current edit target
715     /// \li the schema name cannot be added to the apiSchemas listOp metadata
716     template <typename SchemaType>
ApplyAPI()717     bool ApplyAPI() const {
718         static_assert(std::is_base_of<UsdAPISchemaBase, SchemaType>::value,
719             "Provided type must derive UsdAPISchemaBase.");
720         static_assert(!std::is_same<UsdAPISchemaBase, SchemaType>::value,
721             "Provided type must not be UsdAPISchemaBase.");
722         static_assert(SchemaType::schemaKind == UsdSchemaKind::SingleApplyAPI,
723             "Provided schema type must be a single apply API schema.");
724 
725         static const TfType schemaType = TfType::Find<SchemaType>();
726         return _ApplyAPI(schemaType);
727     }
728 
729     /// Non-templated overload of the templated ApplyAPI above.
730     ///
731     /// This function behaves exactly like the templated ApplyAPI
732     /// except for the runtime schemaType validation which happens at compile
733     /// time in the templated version. This method is provided for python
734     /// clients. Use of the templated ApplyAPI is preferred.
735     USD_API
736     bool ApplyAPI(const TfType& schemaType) const;
737 
738     /// Applies a __multiple-apply__ API schema with the given C++ type
739     /// 'SchemaType' and instance name \p instanceName to this prim in the
740     /// current edit target.
741     ///
742     /// This information is stored in the token-valued, listOp metadata
743     /// \em apiSchemas on this prim. For example, if SchemaType is
744     /// 'UsdCollectionAPI' and \p instanceName is 'plasticStuff', the name
745     /// 'CollectionAPI:plasticStuff' is added to the 'apiSchemas' listOp
746     /// metadata.
747     ///
748     /// Returns true upon success or if the API schema is already applied with
749     /// this \p instanceName in the current edit target.
750     ///
751     /// An error is issued and false returned for any of the following
752     /// conditions:
753     /// \li \p instanceName is empty
754     /// \li this prim is not a valid prim for editing
755     /// \li this prim is valid, but cannot be reached or overridden in the
756     /// current edit target
757     /// \li the schema name cannot be added to the apiSchemas listOp metadata
758     template <typename SchemaType>
ApplyAPI(const TfToken & instanceName)759     bool ApplyAPI(const TfToken &instanceName) const {
760         static_assert(std::is_base_of<UsdAPISchemaBase, SchemaType>::value,
761             "Provided type must derive UsdAPISchemaBase.");
762         static_assert(!std::is_same<UsdAPISchemaBase, SchemaType>::value,
763             "Provided type must not be UsdAPISchemaBase.");
764         static_assert(SchemaType::schemaKind == UsdSchemaKind::MultipleApplyAPI,
765             "Provided schema type must be a multiple apply API schema.");
766 
767         static const TfType schemaType = TfType::Find<SchemaType>();
768         return _ApplyAPI(schemaType, instanceName);
769     }
770 
771     /// Non-templated overload of the templated ApplyAPI above.
772     ///
773     /// This function behaves exactly like the templated ApplyAPI
774     /// except for the runtime schemaType validation which happens at compile
775     /// time in the templated version. This method is provided for python
776     /// clients. Use of the templated ApplyAPI is preferred.
777     USD_API
778     bool ApplyAPI(const TfType& schemaType, const TfToken& instanceName) const;
779 
780     /// Removes a __single-apply__ API schema with the given C++ type
781     /// 'SchemaType' from this prim in the current edit target.
782     ///
783     /// This is done by removing the API schema's name token from the
784     /// token-valued, listOp metadata \em apiSchemas on this prim as well as
785     /// authoring an explicit deletion of schema name from the listOp.
786     ///
787     /// Returns true upon success or if the API schema is already deleted in
788     /// the current edit target.
789     ///
790     /// An error is issued and false returned for any of the following
791     /// conditions:
792     /// \li this prim is not a valid prim for editing
793     /// \li this prim is valid, but cannot be reached or overridden in the
794     /// current edit target
795     /// \li the schema name cannot be deleted in the apiSchemas listOp metadata
796     template <typename SchemaType>
RemoveAPI()797     bool RemoveAPI() const {
798         static_assert(std::is_base_of<UsdAPISchemaBase, SchemaType>::value,
799             "Provided type must derive UsdAPISchemaBase.");
800         static_assert(!std::is_same<UsdAPISchemaBase, SchemaType>::value,
801             "Provided type must not be UsdAPISchemaBase.");
802         static_assert(SchemaType::schemaKind == UsdSchemaKind::SingleApplyAPI,
803             "Provided schema type must be a single apply API schema.");
804 
805         static const TfType schemaType = TfType::Find<SchemaType>();
806         return _RemoveAPI(schemaType);
807     }
808 
809     /// Non-templated overload of the templated RemoveAPI above.
810     ///
811     /// This function behaves exactly like the templated RemoveAPI
812     /// except for the runtime schemaType validation which happens at compile
813     /// time in the templated version. This method is provided for python
814     /// clients. Use of the templated RemoveAPI is preferred.
815     USD_API
816     bool RemoveAPI(const TfType& schemaType) const;
817 
818     /// Removes a __multiple-apply__ API schema with the given C++ type
819     /// 'SchemaType' and instance name \p instanceName from this prim in the
820     /// current edit target.
821     ///
822     /// This is done by removing the instanced schema name token from the
823     /// token-valued, listOp metadata \em apiSchemas on this prim as well as
824     /// authoring an explicit deletion of the name from the listOp. For example,
825     /// if SchemaType is 'UsdCollectionAPI' and \p instanceName is
826     /// 'plasticStuff', the name 'CollectionAPI:plasticStuff' is deleted
827     /// from the 'apiSchemas' listOp  metadata.
828     ///
829     /// Returns true upon success or if the API schema with this \p instanceName
830     /// is already deleted in the current edit target.
831     ///
832     /// An error is issued and false returned for any of the following
833     /// conditions:
834     /// \li \p instanceName is empty
835     /// \li this prim is not a valid prim for editing
836     /// \li this prim is valid, but cannot be reached or overridden in the
837     /// current edit target
838     /// \li the schema name cannot be deleted in the apiSchemas listOp metadata
839     template <typename SchemaType>
RemoveAPI(const TfToken & instanceName)840     bool RemoveAPI(const TfToken &instanceName) const {
841         static_assert(std::is_base_of<UsdAPISchemaBase, SchemaType>::value,
842             "Provided type must derive UsdAPISchemaBase.");
843         static_assert(!std::is_same<UsdAPISchemaBase, SchemaType>::value,
844             "Provided type must not be UsdAPISchemaBase.");
845         static_assert(SchemaType::schemaKind == UsdSchemaKind::MultipleApplyAPI,
846             "Provided schema type must be a multiple apply API schema.");
847 
848         static const TfType schemaType = TfType::Find<SchemaType>();
849         return _RemoveAPI(schemaType, instanceName);
850     }
851 
852     /// Non-templated overload of the templated RemoveAPI above.
853     ///
854     /// This function behaves exactly like the templated RemoveAPI
855     /// except for the runtime schemaType validation which happens at compile
856     /// time in the templated version. This method is provided for python
857     /// clients. Use of the templated RemoveAPI is preferred.
858     USD_API
859     bool RemoveAPI(const TfType& schemaType,
860                    const TfToken& instanceName) const;
861 
862     /// Adds the applied API schema name token \p appliedSchemaName to the
863     /// \em apiSchemas metadata for this prim at the current edit target. For
864     /// multiple-apply schemas the name token should include the instance name
865     /// for the applied schema, for example 'CollectionAPI:plasticStuff'.
866     ///
867     /// The name will only be added if the \ref SdfListOp "list operation" at
868     /// the edit target does not already have this applied schema in its
869     /// explicit, prepended, or appended lists and is always added to the end
870     /// of either the prepended or explicit items.
871     ///
872     /// Returns true upon success or if the API schema is already applied in
873     /// the current edit target.
874     ///
875     /// An error is issued and false returned for any of the following
876     /// conditions:
877     /// \li this prim is not a valid prim for editing
878     /// \li this prim is valid, but cannot be reached or overridden in the
879     /// current edit target
880     /// \li the schema name cannot be added to the apiSchemas listOp metadata
881     ///
882     /// Unlike ApplyAPI this method does not require that the name token
883     /// refer to a valid API schema type. ApplyAPI is the preferred method
884     /// for applying valid API schemas.
885     USD_API
886     bool AddAppliedSchema(const TfToken &appliedSchemaName) const;
887 
888     /// Removes the applied API schema name token \p appliedSchemaName from the
889     /// \em apiSchemas metadata for this prim at the current edit target. For
890     /// multiple-apply schemas the name token should include the instance name
891     /// for the applied schema, for example 'CollectionAPI:plasticStuff'
892     ///
893     /// For an explicit \ref SdfListOp "list operation", this removes the
894     /// applied schema name from the explicit items list if it was present. For
895     /// a non-explicit \ref SdfListOp "list operation", this will remove any
896     /// occurrence of the applied schema name from the prepended and appended
897     /// item as well as adding it to the deleted items list.
898     ///
899     /// Returns true upon success or if the API schema is already deleted in
900     /// the current edit target.
901     ///
902     /// An error is issued and false returned for any of the following
903     /// conditions:
904     /// \li this prim is not a valid prim for editing
905     /// \li this prim is valid, but cannot be reached or overridden in the
906     /// current edit target
907     /// \li the schema name cannot be deleted in the apiSchemas listOp metadata
908     ///
909     /// Unlike RemoveAPI this method does not require that the name token
910     /// refer to a valid API schema type. RemoveAPI is the preferred method
911     /// for removing valid API schemas.
912     USD_API
913     bool RemoveAppliedSchema(const TfToken &appliedSchemaName) const;
914 
915     // --------------------------------------------------------------------- //
916     /// \name Prim Children
917     // --------------------------------------------------------------------- //
918 
919     /// Return this prim's direct child named \p name if it has one, otherwise
920     /// return an invalid UsdPrim.  Equivalent to:
921     /// \code
922     /// prim.GetStage()->GetPrimAtPath(prim.GetPath().AppendChild(name))
923     /// \endcode
924     USD_API
925     UsdPrim GetChild(const TfToken &name) const;
926 
927     /// Return this prim's active, loaded, defined, non-abstract children as an
928     /// iterable range.  Equivalent to:
929     /// \code
930     /// GetFilteredChildren(UsdPrimDefaultPredicate)
931     /// \endcode
932     ///
933     /// See \ref Usd_PrimFlags "Prim predicate flags"
934     /// and #UsdPrimDefaultPredicate for more information.
935     inline SiblingRange GetChildren() const;
936 
937     /// Return all this prim's children as an iterable range.
938     inline SiblingRange GetAllChildren() const;
939 
940     /// Return a subset of all of this prim's children filtered by \p predicate
941     /// as an iterable range.  The \p predicate is generated by combining a
942     /// series of prim flag terms with either && or || and !.
943     ///
944     /// Example usage:
945     /// \code
946     /// // Get all active model children.
947     /// GetFilteredChildren(UsdPrimIsActive && UsdPrimIsModel);
948     ///
949     /// // Get all model children that pass the default predicate.
950     /// GetFilteredChildren(UsdPrimDefaultPredicate && UsdPrimIsModel);
951     /// \endcode
952     ///
953     /// If this prim is an instance, no children will be returned unless
954     /// #UsdTraverseInstanceProxies is used to allow instance proxies to be
955     /// returned, or if this prim is itself an instance proxy.
956     ///
957     /// See \ref Usd_PrimFlags "Prim predicate flags"
958     /// and #UsdPrimDefaultPredicate for more information.
959     inline SiblingRange
960     GetFilteredChildren(const Usd_PrimFlagsPredicate &predicate) const;
961 
962     /// Return the names of the child prims in the order they appear when
963     /// iterating over GetChildren.
964     USD_API
965     TfTokenVector GetChildrenNames() const;
966 
967     /// Return the names of the child prims in the order they appear when
968     /// iterating over GetAllChildren.
969     USD_API
970     TfTokenVector GetAllChildrenNames() const;
971 
972     /// Return the names of the child prims in the order they appear when
973     /// iterating over GetFilteredChildren(\p predicate).
974     USD_API
975     TfTokenVector GetFilteredChildrenNames(
976         const Usd_PrimFlagsPredicate &predicate) const;
977 
978     /// Return this prim's active, loaded, defined, non-abstract descendants as
979     /// an iterable range.  Equivalent to:
980     /// \code
981     /// GetFilteredDescendants(UsdPrimDefaultPredicate)
982     /// \endcode
983     ///
984     /// \note This method is not yet available in python, pending some
985     /// refactoring to make it more feasible.
986     ///
987     /// See \ref Usd_PrimFlags "Prim predicate flags" and
988     /// #UsdPrimDefaultPredicate for more information, UsdStage::Traverse(),
989     /// and \c UsdPrimRange for more general Stage traversal behaviors.
990     inline SubtreeRange GetDescendants() const;
991 
992     /// Return all this prim's descendants as an iterable range.
993     ///
994     /// \note This method is not yet available in python, pending some
995     /// refactoring to make it more feasible.
996     ///
997     /// See \ref Usd_PrimFlags "Prim predicate flags" and
998     /// #UsdPrimDefaultPredicate for more information, UsdStage::Traverse(),
999     /// and \c UsdPrimRange for more general Stage traversal behaviors.
1000     inline SubtreeRange GetAllDescendants() const;
1001 
1002     /// Return a subset of all of this prim's descendants filtered by
1003     /// \p predicate as an iterable range.  The \p predicate is generated by
1004     /// combining a series of prim flag terms with either && or || and !.
1005     ///
1006     /// Example usage:
1007     /// \code
1008     /// // Get all active model descendants.
1009     /// GetFilteredDescendants(UsdPrimIsActive && UsdPrimIsModel);
1010     ///
1011     /// // Get all model descendants that pass the default predicate.
1012     /// GetFilteredDescendants(UsdPrimDefaultPredicate && UsdPrimIsModel);
1013     /// \endcode
1014     ///
1015     /// If this prim is an instance, no descendants will be returned unless
1016     /// #UsdTraverseInstanceProxies is used to allow instance proxies to be
1017     /// returned, or if this prim is itself an instance proxy.
1018     ///
1019     /// \note This method is not yet available in python, pending some
1020     /// refactoring to make it more feasible.
1021     ///
1022     /// See \ref Usd_PrimFlags "Prim predicate flags" and
1023     /// #UsdPrimDefaultPredicate for more information, UsdStage::Traverse(),
1024     /// and \c UsdPrimRange for more general Stage traversal behaviors.
1025     inline SubtreeRange
1026     GetFilteredDescendants(const Usd_PrimFlagsPredicate &predicate) const;
1027 
1028     /// Return the strongest opinion for the metadata used to reorder children
1029     /// of this prim. Due to how reordering of prim children is composed,
1030     /// this value cannot be relied on to get the actual order of the prim's
1031     /// children. Use GetChidrenNames, GetAllChildrenNames,
1032     /// GetFilteredChildrenNames to get the true child order if needed.
1033     USD_API
1034     TfTokenVector GetChildrenReorder() const;
1035 
1036     /// Author an opinion for the metadata used to reorder children of this
1037     /// prim at the current EditTarget.
SetChildrenReorder(const TfTokenVector & order)1038     void SetChildrenReorder(const TfTokenVector &order) const {
1039         SetMetadata(SdfFieldKeys->PrimOrder, order);
1040     }
1041 
1042     /// Remove the opinion for the metadata used to reorder children of this
1043     /// prim at the current EditTarget.
ClearChildrenReorder()1044     void ClearChildrenReorder() const {
1045         ClearMetadata(SdfFieldKeys->PrimOrder);
1046     }
1047 
1048 public:
1049     // --------------------------------------------------------------------- //
1050     /// \name Parent & Stage
1051     // --------------------------------------------------------------------- //
1052 
1053     /// Return this prim's parent prim.  Return an invalid UsdPrim if this is a
1054     /// root prim.
GetParent()1055     UsdPrim GetParent() const {
1056         Usd_PrimDataConstPtr prim = get_pointer(_Prim());
1057         SdfPath proxyPrimPath = _ProxyPrimPath();
1058         Usd_MoveToParent(prim, proxyPrimPath);
1059         return UsdPrim(prim, proxyPrimPath);
1060     }
1061 
1062     /// Return this prim's next active, loaded, defined, non-abstract sibling
1063     /// if it has one, otherwise return an invalid UsdPrim.  Equivalent to:
1064     /// \code
1065     /// GetFilteredNextSibling(UsdPrimDefaultPredicate)
1066     /// \endcode
1067     ///
1068     /// See \ref Usd_PrimFlags "Prim predicate flags"
1069     /// and #UsdPrimDefaultPredicate for more information.
1070     USD_API
1071     UsdPrim GetNextSibling() const;
1072 
1073     /// Return this prim's next sibling that matches \p predicate if it has one,
1074     /// otherwise return the invalid UsdPrim.
1075     ///
1076     /// See \ref Usd_PrimFlags "Prim predicate flags"
1077     /// and #UsdPrimDefaultPredicate for more information.
1078     USD_API
1079     UsdPrim GetFilteredNextSibling(
1080         const Usd_PrimFlagsPredicate &predicate) const;
1081 
1082     /// Returns true if the prim is the pseudo root.
1083     ///
1084     /// Equivalent to
1085     /// \code
1086     /// prim.GetPath() == SdfPath::AbsoluteRootPath()
1087     /// \endcode
1088     USD_API
1089     bool IsPseudoRoot() const;
1090 
1091     /// Returns the prim at \p path on the same stage as this prim.
1092     /// If path is is relative, it will be anchored to the path of this prim.
1093     /// \sa UsdStage::GetPrimAtPath(const SdfPath&) const
1094     USD_API UsdPrim GetPrimAtPath(const SdfPath& path) const;
1095 
1096     /// Returns the object at \p path on the same stage as this prim.
1097     /// If path is is relative, it will be anchored to the path of this prim.
1098     /// \sa UsdStage::GetObjectAtPath(const SdfPath&) const
1099     USD_API UsdObject GetObjectAtPath(const SdfPath& path) const;
1100 
1101     /// Returns the property at \p path on the same stage as this prim.
1102     /// If path is relative, it will be anchored to the path of this prim.
1103     ///
1104     /// \note There is no guarantee that this method returns a property on
1105     /// this prim. This is only guaranteed if path is a purely relative
1106     /// property path.
1107     /// \sa GetProperty(const TfToken&) const
1108     /// \sa UsdStage::GetPropertyAtPath(const SdfPath&) const
1109     USD_API UsdProperty GetPropertyAtPath(const SdfPath& path) const;
1110 
1111     /// Returns the attribute at \p path on the same stage as this prim.
1112     /// If path is relative, it will be anchored to the path of this prim.
1113     ///
1114     /// \note There is no guarantee that this method returns an attribute on
1115     /// this prim. This is only guaranteed if path is a purely relative
1116     /// property path.
1117     /// \sa GetAttribute(const TfToken&) const
1118     /// \sa UsdStage::GetAttributeAtPath(const SdfPath&) const
1119     USD_API UsdAttribute GetAttributeAtPath(const SdfPath& path) const;
1120 
1121     /// Returns the relationship at \p path on the same stage as this prim.
1122     /// If path is relative, it will be anchored to the path of this prim.
1123     ///
1124     /// \note There is no guarantee that this method returns a relationship on
1125     /// this prim. This is only guaranteed if path is a purely relative
1126     /// property path.
1127     /// \sa GetRelationship(const TfToken&) const
1128     /// \sa UsdStage::GetRelationshipAtPath(const SdfPath&) const
1129     USD_API UsdRelationship GetRelationshipAtPath(const SdfPath& path) const;
1130 
1131     // --------------------------------------------------------------------- //
1132     /// \name Variants
1133     // --------------------------------------------------------------------- //
1134 
1135     /// Return a UsdVariantSets object representing all the VariantSets
1136     /// present on this prim.
1137     ///
1138     /// The returned object also provides the API for adding new VariantSets
1139     /// to the prim.
1140     USD_API
1141     UsdVariantSets GetVariantSets() const;
1142 
1143     /// Retrieve a specifically named VariantSet for editing or constructing
1144     /// a UsdEditTarget.
1145     ///
1146     /// This is a shortcut for
1147     /// \code
1148     /// prim.GetVariantSets().GetVariantSet(variantSetName)
1149     /// \endcode
1150     USD_API
1151     UsdVariantSet GetVariantSet(const std::string& variantSetName) const;
1152 
1153     /// Return true if this prim has any authored VariantSets.
1154     ///
1155     /// \note this connotes only the *existence* of one of more VariantSets,
1156     /// *not* that such VariantSets necessarily contain any variants or
1157     /// variant opinions.
1158     USD_API
1159     bool HasVariantSets() const;
1160 
1161     // --------------------------------------------------------------------- //
1162     /// \name Attributes
1163     // --------------------------------------------------------------------- //
1164 
1165     /// Author scene description for the attribute named \a attrName at the
1166     /// current EditTarget if none already exists.  Return a valid attribute if
1167     /// scene description was successfully authored or if it already existed,
1168     /// return invalid attribute otherwise.  Note that the supplied \a typeName
1169     /// and \a custom arguments are only used in one specific case.  See below
1170     /// for details.
1171     ///
1172     /// Suggested use:
1173     /// \code
1174     /// if (UsdAttribute myAttr = prim.CreateAttribute(...)) {
1175     ///    // success.
1176     /// }
1177     /// \endcode
1178     ///
1179     /// To call this, GetPrim() must return a valid prim.
1180     ///
1181     /// - If a spec for this attribute already exists at the current edit
1182     /// target, do nothing.
1183     ///
1184     /// - If a spec for \a attrName of a different spec type (e.g. a
1185     /// relationship) exists at the current EditTarget, issue an error.
1186     ///
1187     /// - If \a name refers to a builtin attribute according to the prim's
1188     /// definition, author an attribute spec with required metadata from the
1189     /// definition.
1190     ///
1191     /// - If \a name refers to a builtin relationship, issue an error.
1192     ///
1193     /// - If there exists an absolute strongest authored attribute spec for
1194     /// \a attrName, author an attribute spec at the current EditTarget by
1195     /// copying required metadata from that strongest spec.
1196     ///
1197     /// - If there exists an absolute strongest authored relationship spec for
1198     /// \a attrName, issue an error.
1199     ///
1200     /// - Otherwise author an attribute spec at the current EditTarget using
1201     /// the provided \a typeName and \a custom for the required metadata fields.
1202     /// Note that these supplied arguments are only ever used in this particular
1203     /// circumstance, in all other cases they are ignored.
1204     USD_API
1205     UsdAttribute
1206     CreateAttribute(const TfToken& name,
1207                     const SdfValueTypeName &typeName,
1208                     bool custom,
1209                     SdfVariability variability = SdfVariabilityVarying) const;
1210     /// \overload
1211     /// Create a custom attribute with \p name, \p typeName and \p variability.
1212     USD_API
1213     UsdAttribute
1214     CreateAttribute(const TfToken& name,
1215                     const SdfValueTypeName &typeName,
1216                     SdfVariability variability = SdfVariabilityVarying) const;
1217 
1218     /// \overload
1219     /// This overload of CreateAttribute() accepts a vector of name components
1220     /// used to construct a \em namespaced property name.  For details, see
1221     /// \ref Usd_Ordering
1222     USD_API
1223     UsdAttribute CreateAttribute(
1224         const std::vector<std::string> &nameElts,
1225         const SdfValueTypeName &typeName,
1226         bool custom,
1227         SdfVariability variability = SdfVariabilityVarying) const;
1228     /// \overload
1229     /// Create a custom attribute with \p nameElts, \p typeName, and
1230     /// \p variability.
1231     USD_API
1232     UsdAttribute CreateAttribute(
1233         const std::vector<std::string> &nameElts,
1234         const SdfValueTypeName &typeName,
1235         SdfVariability variability = SdfVariabilityVarying) const;
1236 
1237     /// Like GetProperties(), but exclude all relationships from the result.
1238     USD_API
1239     std::vector<UsdAttribute> GetAttributes() const;
1240 
1241     /// Like GetAttributes(), but exclude attributes without authored scene
1242     /// description from the result.  See UsdProperty::IsAuthored().
1243     USD_API
1244     std::vector<UsdAttribute> GetAuthoredAttributes() const;
1245 
1246     /// Return a UsdAttribute with the name \a attrName. The attribute
1247     /// returned may or may not \b actually exist so it must be checked for
1248     /// validity. Suggested use:
1249     ///
1250     /// \code
1251     /// if (UsdAttribute myAttr = prim.GetAttribute("myAttr")) {
1252     ///    // myAttr is safe to use.
1253     ///    // Edits to the owning stage requires subsequent validation.
1254     /// } else {
1255     ///    // myAttr was not defined/authored
1256     /// }
1257     /// \endcode
1258     USD_API
1259     UsdAttribute GetAttribute(const TfToken& attrName) const;
1260 
1261     /// Return true if this prim has an attribute named \p attrName, false
1262     /// otherwise.
1263     USD_API
1264     bool HasAttribute(const TfToken& attrName) const;
1265 
1266     /// Search the prim subtree rooted at this prim for attributes for which
1267     /// \p predicate returns true, collect their connection source paths and
1268     /// return them in an arbitrary order.  If \p recurseOnSources is true,
1269     /// act as if this function was invoked on the connected prims and owning
1270     /// prims of connected properties also and return the union.
1271     USD_API
1272     SdfPathVector
1273     FindAllAttributeConnectionPaths(
1274         std::function<bool (UsdAttribute const &)> const &pred = nullptr,
1275         bool recurseOnSources = false) const;
1276 
1277     // --------------------------------------------------------------------- //
1278     /// \name Relationships
1279     // --------------------------------------------------------------------- //
1280 
1281     /// Author scene description for the relationship named \a relName at the
1282     /// current EditTarget if none already exists.  Return a valid relationship
1283     /// if scene description was successfully authored or if it already existed,
1284     /// return an invalid relationship otherwise.
1285     ///
1286     /// Suggested use:
1287     /// \code
1288     /// if (UsdRelationship myRel = prim.CreateRelationship(...)) {
1289     ///    // success.
1290     /// }
1291     /// \endcode
1292     ///
1293     /// To call this, GetPrim() must return a valid prim.
1294     ///
1295     /// - If a spec for this relationship already exists at the current edit
1296     /// target, do nothing.
1297     ///
1298     /// - If a spec for \a relName of a different spec type (e.g. an
1299     /// attribute) exists at the current EditTarget, issue an error.
1300     ///
1301     /// - If \a name refers to a builtin relationship according to the prim's
1302     /// definition, author a relationship spec with required metadata from the
1303     /// definition.
1304     ///
1305     /// - If \a name refers to a builtin attribute, issue an error.
1306     ///
1307     /// - If there exists an absolute strongest authored relationship spec for
1308     /// \a relName, author a relationship spec at the current EditTarget by
1309     /// copying required metadata from that strongest spec.
1310     ///
1311     /// - If there exists an absolute strongest authored attribute spec for \a
1312     /// relName, issue an error.
1313     ///
1314     /// - Otherwise author a uniform relationship spec at the current
1315     /// EditTarget, honoring \p custom .
1316     ///
1317     USD_API
1318     UsdRelationship CreateRelationship(const TfToken& relName,
1319                                        bool custom=true) const;
1320 
1321     /// \overload
1322     /// This overload of CreateRelationship() accepts a vector of
1323     /// name components used to construct a \em namespaced property name.
1324     /// For details, see \ref Usd_Ordering
1325     USD_API
1326     UsdRelationship CreateRelationship(const std::vector<std::string> &nameElts,
1327                                        bool custom=true)
1328         const;
1329 
1330     /// Like GetProperties(), but exclude all attributes from the result.
1331     USD_API
1332     std::vector<UsdRelationship> GetRelationships() const;
1333 
1334     /// Like GetRelationships(), but exclude relationships without authored
1335     /// scene description from the result.  See UsdProperty::IsAuthored().
1336     USD_API
1337     std::vector<UsdRelationship> GetAuthoredRelationships() const;
1338 
1339     /// Return a UsdRelationship with the name \a relName. The relationship
1340     /// returned may or may not \b actually exist so it must be checked for
1341     /// validity. Suggested use:
1342     ///
1343     /// \code
1344     /// if (UsdRelationship myRel = prim.GetRelationship("myRel")) {
1345     ///    // myRel is safe to use.
1346     ///    // Edits to the owning stage requires subsequent validation.
1347     /// } else {
1348     ///    // myRel was not defined/authored
1349     /// }
1350     /// \endcode
1351     USD_API
1352     UsdRelationship GetRelationship(const TfToken& relName) const;
1353 
1354     /// Return true if this prim has a relationship named \p relName, false
1355     /// otherwise.
1356     USD_API
1357     bool HasRelationship(const TfToken& relName) const;
1358 
1359     /// Search the prim subtree rooted at this prim for relationships for which
1360     /// \p predicate returns true, collect their target paths and return them in
1361     /// an arbitrary order.  If \p recurseOnTargets is true, act as if this
1362     /// function was invoked on the targeted prims and owning prims of targeted
1363     /// properties also (but not of forwarding relationships) and return the
1364     /// union.
1365     USD_API
1366     SdfPathVector
1367     FindAllRelationshipTargetPaths(
1368         std::function<bool (UsdRelationship const &)> const &pred = nullptr,
1369         bool recurseOnTargets = false) const;
1370 
1371     // --------------------------------------------------------------------- //
1372     /// \name Payload Authoring
1373     /// \deprecated
1374     /// This API is now deprecated. Please use the HasAuthoredPayloads and the
1375     /// UsdPayloads API returned from GetPayloads() to query and author payloads
1376     /// instead.
1377     /// @{
1378     // --------------------------------------------------------------------- //
1379 
1380     /// \deprecated
1381     /// Clears the payload at the current EditTarget for this prim. Return false
1382     /// if the payload could not be cleared.
1383     USD_API
1384     bool ClearPayload() const;
1385 
1386     /// \deprecated
1387     /// Return true if a payload is present on this prim.
1388     ///
1389     /// \sa \ref Usd_Payloads
1390     USD_API
1391     bool HasPayload() const;
1392 
1393     /// \deprecated
1394     /// Author payload metadata for this prim at the current edit
1395     /// target. Return true on success, false if the value could not be set.
1396     ///
1397     /// \sa \ref Usd_Payloads
1398     USD_API
1399     bool SetPayload(const SdfPayload& payload) const;
1400 
1401     /// \deprecated
1402     /// Shorthand for SetPayload(SdfPayload(assetPath, primPath)).
1403     USD_API
1404     bool SetPayload(
1405         const std::string& assetPath, const SdfPath& primPath) const;
1406 
1407     /// \deprecated
1408     /// Shorthand for SetPayload(SdfPayload(layer->GetIdentifier(),
1409     /// primPath)).
1410     USD_API
1411     bool SetPayload(const SdfLayerHandle& layer, const SdfPath& primPath) const;
1412 
1413     /// @}
1414 
1415     // --------------------------------------------------------------------- //
1416     /// \name Payloads, Load and Unload
1417     // --------------------------------------------------------------------- //
1418 
1419     /// Return a UsdPayloads object that allows one to add, remove, or
1420     /// mutate payloads <em>at the currently set UsdEditTarget</em>.
1421     ///
1422     /// While the UsdPayloads object has no methods for \em listing the
1423     /// currently authored payloads on a prim, one can use a
1424     /// UsdPrimCompositionQuery to query the payload arcs that are composed
1425     /// by this prim.
1426     USD_API
1427     UsdPayloads GetPayloads() const;
1428 
1429     /// Return true if this prim has any authored payloads.
1430     USD_API
1431     bool HasAuthoredPayloads() const;
1432 
1433     /// Load this prim, all its ancestors, and by default all its descendants.
1434     /// If \p loadPolicy is UsdLoadWithoutDescendants, then load only this prim
1435     /// and its ancestors.
1436     ///
1437     /// See UsdStage::Load for additional details.
1438     USD_API
1439     void Load(UsdLoadPolicy policy = UsdLoadWithDescendants) const;
1440 
1441     /// Unloads this prim and all its descendants.
1442     ///
1443     /// See UsdStage::Unload for additional details.
1444     USD_API
1445     void Unload() const;
1446 
1447     // --------------------------------------------------------------------- //
1448     /// \name References
1449     // --------------------------------------------------------------------- //
1450 
1451     /// Return a UsdReferences object that allows one to add, remove, or
1452     /// mutate references <em>at the currently set UsdEditTarget</em>.
1453     ///
1454     /// While the UsdReferences object has no methods for \em listing the
1455     /// currently authored references on a prim, one can use a
1456     /// UsdPrimCompositionQuery to query the reference arcs that are composed
1457     /// by this prim.
1458     ///
1459     /// \sa UsdPrimCompositionQuery::GetDirectReferences
1460     USD_API
1461     UsdReferences GetReferences() const;
1462 
1463     /// Return true if this prim has any authored references.
1464     USD_API
1465     bool HasAuthoredReferences() const;
1466 
1467     // --------------------------------------------------------------------- //
1468     /// \name Inherits
1469     // --------------------------------------------------------------------- //
1470 
1471     /// Return a UsdInherits object that allows one to add, remove, or
1472     /// mutate inherits <em>at the currently set UsdEditTarget</em>.
1473     ///
1474     /// While the UsdInherits object has no methods for \em listing the
1475     /// currently authored inherits on a prim, one can use a
1476     /// UsdPrimCompositionQuery to query the inherits arcs that are composed
1477     /// by this prim.
1478     ///
1479     /// \sa UsdPrimCompositionQuery::GetDirectInherits
1480     USD_API
1481     UsdInherits GetInherits() const;
1482 
1483     /// Return true if this prim has any authored inherits.
1484     USD_API
1485     bool HasAuthoredInherits() const;
1486 
1487     // --------------------------------------------------------------------- //
1488     /// \name Specializes
1489     // --------------------------------------------------------------------- //
1490 
1491     /// Return a UsdSpecializes object that allows one to add, remove, or
1492     /// mutate specializes <em>at the currently set UsdEditTarget</em>.
1493     ///
1494     /// While the UsdSpecializes object has no methods for \em listing the
1495     /// currently authored specializes on a prim, one can use a
1496     /// UsdPrimCompositionQuery to query the specializes arcs that are composed
1497     /// by this prim.
1498     USD_API
1499     UsdSpecializes GetSpecializes() const;
1500 
1501     /// Returns true if this prim has any authored specializes.
1502     USD_API
1503     bool HasAuthoredSpecializes() const;
1504 
1505     // --------------------------------------------------------------------- //
1506     /// \name Instancing
1507     /// See \ref Usd_Page_ScenegraphInstancing for more details.
1508     /// @{
1509     // --------------------------------------------------------------------- //
1510 
1511     /// Return true if this prim has been marked as instanceable.
1512     ///
1513     /// Note that this is not the same as IsInstance(). A prim may return
1514     /// true for IsInstanceable() and false for IsInstance() if this prim
1515     /// is not active or if it is marked as instanceable but contains no
1516     /// instanceable data.
IsInstanceable()1517     bool IsInstanceable() const {
1518         bool instanceable = false;
1519         return GetMetadata(SdfFieldKeys->Instanceable, &instanceable) &&
1520             instanceable;
1521     }
1522 
1523     /// Author 'instanceable' metadata for this prim at the current
1524     /// EditTarget.
SetInstanceable(bool instanceable)1525     bool SetInstanceable(bool instanceable) const {
1526         return SetMetadata(SdfFieldKeys->Instanceable, instanceable);
1527     }
1528 
1529     /// Remove the authored 'instanceable' opinion at the current EditTarget.
1530     /// Do nothing if there is no authored opinion.
ClearInstanceable()1531     bool ClearInstanceable() const {
1532         return ClearMetadata(SdfFieldKeys->Instanceable);
1533     }
1534 
1535     /// Return true if this prim has an authored opinion for 'instanceable',
1536     /// false otherwise.
HasAuthoredInstanceable()1537     bool HasAuthoredInstanceable() const {
1538         return HasAuthoredMetadata(SdfFieldKeys->Instanceable);
1539     }
1540 
1541     /// Return true if this prim is an instance of a prototype, false
1542     /// otherwise.
1543     ///
1544     /// If this prim is an instance, calling GetPrototype() will return
1545     /// the UsdPrim for the corresponding prototype prim.
IsInstance()1546     bool IsInstance() const { return _Prim()->IsInstance(); }
1547 
1548     /// Return true if this prim is an instance proxy, false otherwise.
1549     /// An instance proxy prim represents a descendent of an instance
1550     /// prim.
IsInstanceProxy()1551     bool IsInstanceProxy() const {
1552         return Usd_IsInstanceProxy(_Prim(), _ProxyPrimPath());
1553     }
1554 
1555     /// Return true if the given \p path identifies a prototype prim,
1556     /// false otherwise.
1557     ///
1558     /// This function will return false for prim and property paths
1559     /// that are descendants of a prototype prim path.
1560     ///
1561     /// \sa IsPathInPrototype
1562     USD_API
1563     static bool IsPrototypePath(const SdfPath& path);
1564 
1565     /// Return true if the given \p path identifies a prototype prim or
1566     /// a prim or property descendant of a prototype prim, false otherwise.
1567     ///
1568     /// \sa IsPrototypePath
1569     USD_API
1570     static bool IsPathInPrototype(const SdfPath& path);
1571 
1572     /// Return true if this prim is an instancing prototype prim,
1573     /// false otherwise.
1574     ///
1575     /// \sa IsInPrototype
IsPrototype()1576     bool IsPrototype() const { return _Prim()->IsPrototype(); }
1577 
1578     /// Return true if this prim is a prototype prim or a descendant
1579     /// of a prototype prim, false otherwise.
1580     ///
1581     /// \sa IsPrototype
IsInPrototype()1582     bool IsInPrototype() const {
1583         return (IsInstanceProxy() ?
1584             IsPathInPrototype(GetPrimPath()) : _Prim()->IsInPrototype());
1585     }
1586 
1587     /// If this prim is an instance, return the UsdPrim for the corresponding
1588     /// prototype. Otherwise, return an invalid UsdPrim.
1589     USD_API
1590     UsdPrim GetPrototype() const;
1591 
1592     /// If this prim is an instance proxy, return the UsdPrim for the
1593     /// corresponding prim in the instance's prototype. Otherwise, return an
1594     /// invalid UsdPrim.
GetPrimInPrototype()1595     UsdPrim GetPrimInPrototype() const {
1596         if (IsInstanceProxy()) {
1597             return UsdPrim(_Prim(), SdfPath());
1598         }
1599         return UsdPrim();
1600     }
1601 
1602     /// If this prim is a prototype prim, returns all prims that are instances
1603     /// of this prototype. Otherwise, returns an empty vector.
1604     ///
1605     /// Note that this function will return prims in prototypes for instances
1606     /// that are nested beneath other instances.
1607     USD_API
1608     std::vector<UsdPrim> GetInstances() const;
1609     /// @}
1610 
1611     // --------------------------------------------------------------------- //
1612     /// \name Composition Structure
1613     /// @{
1614     // --------------------------------------------------------------------- //
1615 
1616     /// Return the cached prim index containing all sites that can contribute
1617     /// opinions to this prim.
1618     ///
1619     /// The prim index can be used to examine the composition arcs and scene
1620     /// description sites that can contribute to this prim's property and
1621     /// metadata values.
1622     ///
1623     /// The prim index returned by this function is optimized and may not
1624     /// include sites that do not contribute opinions to this prim. Use
1625     /// UsdPrim::ComputeExpandedPrimIndex to compute a prim index that includes
1626     /// all possible sites that could contribute opinions.
1627     ///
1628     /// This prim index will be empty for prototype prims. This ensures that
1629     /// these prims do not provide any attribute or metadata values. For all
1630     /// other prims in prototypes, this is the prim index that was chosen to
1631     /// be shared with all other instances. In either case, the prim index's
1632     /// path will not be the same as the prim's path.
1633     ///
1634     /// Prim indexes may be invalidated by changes to the UsdStage and cannot
1635     /// detect if they are expired. Clients should avoid keeping copies of the
1636     /// prim index across such changes, which include scene description
1637     /// changes or changes to load state.
GetPrimIndex()1638     const PcpPrimIndex &GetPrimIndex() const { return _Prim()->GetPrimIndex(); }
1639 
1640     /// Compute the prim index containing all sites that could contribute
1641     /// opinions to this prim.
1642     ///
1643     /// This function is similar to UsdPrim::GetPrimIndex. However, the
1644     /// returned prim index includes all sites that could possibly contribute
1645     /// opinions to this prim, not just the sites that currently do so. This is
1646     /// useful in certain situations; for example, this could be used to
1647     /// generate a list of sites where clients could make edits to affect this
1648     /// prim, or for debugging purposes.
1649     ///
1650     /// This function may be relatively slow, since it will recompute the prim
1651     /// index on every call. Clients should prefer UsdPrim::GetPrimIndex unless
1652     /// the additional site information is truly needed.
1653     USD_API
1654     PcpPrimIndex ComputeExpandedPrimIndex() const;
1655 
1656     /// @}
1657 
1658 private:
1659     friend class UsdObject;
1660     friend class UsdPrimSiblingIterator;
1661     friend class UsdPrimSubtreeIterator;
1662     friend class UsdProperty;
1663     friend class UsdSchemaBase;
1664     friend class UsdAPISchemaBase;
1665     friend class UsdStage;
1666     friend class UsdPrimRange;
1667     friend class Usd_PrimData;
1668     friend class Usd_PrimFlagsPredicate;
1669     friend struct UsdPrim_RelTargetFinder;
1670     friend struct UsdPrim_AttrConnectionFinder;
1671 
1672     // Prim constructor.
UsdPrim(const Usd_PrimDataHandle & primData,const SdfPath & proxyPrimPath)1673     UsdPrim(const Usd_PrimDataHandle &primData,
1674             const SdfPath &proxyPrimPath)
1675         : UsdObject(primData, proxyPrimPath) { }
1676 
1677     // General constructor.
UsdPrim(UsdObjType objType,const Usd_PrimDataHandle & prim,const SdfPath & proxyPrimPath,const TfToken & propName)1678     UsdPrim(UsdObjType objType,
1679             const Usd_PrimDataHandle &prim,
1680             const SdfPath &proxyPrimPath,
1681             const TfToken &propName)
1682         : UsdObject(objType, prim, proxyPrimPath, propName) {}
1683 
1684     // Helper to make a sibling range.
1685     inline SiblingRange
1686     _MakeSiblingRange(const Usd_PrimFlagsPredicate &pred) const;
1687 
1688     // Helper to make a range of descendants.
1689     inline SubtreeRange
1690     _MakeDescendantsRange(const Usd_PrimFlagsPredicate &pred) const;
1691 
1692     // Helper to make a vector of properties from names.
1693     std::vector<UsdProperty>
1694     _MakeProperties(const TfTokenVector &names) const;
1695 
1696     // Helper for Get{Authored}{PropertyNames,Properties}
1697     TfTokenVector _GetPropertyNames(
1698         bool onlyAuthored,
1699         bool applyOrder=true,
1700         const PropertyPredicateFunc &predicate={}) const;
1701 
1702     // Helper for Get(Authored)PropertiesInNamespace.
1703     std::vector<UsdProperty>
1704     _GetPropertiesInNamespace(const std::string &namespaces,
1705                               bool onlyAuthored) const;
1706 
1707     // Helper for Get(Authored)Attributes.
1708     std::vector<UsdAttribute>
1709     _GetAttributes(bool onlyAuthored, bool applyOrder=false) const;
1710 
1711     // Helper for Get(Authored)Relationships.
1712     std::vector<UsdRelationship>
1713     _GetRelationships(bool onlyAuthored, bool applyOrder=false) const;
1714 
1715     friend const PcpPrimIndex &Usd_PrimGetSourcePrimIndex(const UsdPrim&);
1716     // Return a const reference to the source PcpPrimIndex for this prim.
1717     //
1718     // For all prims in prototypes (which includes the prototype prim itself),
1719     // this is the prim index for the instance that was chosen to serve
1720     // as the prototype for all other instances.  This prim index will not
1721     // have the same path as the prim's path.
1722     //
1723     // This is a private helper but is also wrapped out to Python
1724     // for testing and debugging purposes.
_GetSourcePrimIndex()1725     const PcpPrimIndex &_GetSourcePrimIndex() const
1726     { return _Prim()->GetSourcePrimIndex(); }
1727 };
1728 
1729 #ifdef doxygen
1730 
1731 /// Forward traversal iterator of sibling ::UsdPrim s.  This is a
1732 /// standard-compliant iterator that may be used with STL algorithms, etc.
1733 class UsdPrimSiblingIterator {
1734 public:
1735     /// Iterator value type.
1736     typedef UsdPrim value_type;
1737     /// Iterator reference type, in this case the same as \a value_type.
1738     typedef value_type reference;
1739     /// Iterator difference type.
1740     typedef unspecified-integral-type difference_type;
1741     /// Dereference.
1742     reference operator*() const;
1743     /// Indirection.
1744     unspecified-type operator->() const;
1745     /// Postincrement.
1746     UsdPrimSiblingIterator &operator++();
1747     /// Preincrement.
1748     UsdPrimSiblingIterator operator++(int);
1749 private:
1750     /// Equality.
1751     friend bool operator==(const UsdPrimSiblingIterator &lhs,
1752                            const UsdPrimSiblingIterator &rhs);
1753     /// Inequality.
1754     friend bool operator!=(const UsdPrimSiblingIterator &lhs,
1755                            const UsdPrimSiblingIterator &rhs);
1756 };
1757 
1758 /// Forward iterator range of sibling ::UsdPrim s.  This range type contains a
1759 /// pair of UsdPrimSiblingIterator s, denoting a half-open range of UsdPrim
1760 /// siblings.  It provides a subset of container-like API, such as begin(),
1761 /// end(), front(), empty(), etc.
1762 class UsdPrimSiblingRange {
1763 public:
1764     /// Iterator type.
1765     typedef UsdPrimSiblingIterator iterator;
1766     /// Const iterator type.
1767     typedef UsdPrimSiblingIterator const_iterator;
1768     /// Iterator difference type.
1769     typedef unspecified-integral-type difference_type;
1770     /// Iterator value_type.
1771     typedef iterator::value_type value_type;
1772     /// Iterator reference_type.
1773     typedef iterator::reference reference;
1774 
1775     /// Construct with a pair of iterators.
1776     UsdPrimSiblingRange(UsdPrimSiblingIterator begin,
1777                         UsdPrimSiblingIterator end);
1778 
1779     /// Construct/convert from another compatible range type.
1780     template <class ForwardRange>
1781     UsdPrimSiblingRange(const ForwardRange &r);
1782 
1783     /// Assign from another compatible range type.
1784     template <class ForwardRange>
1785     UsdPrimSiblingRange &operator=(const ForwardRange &r);
1786 
1787     /// First iterator.
1788     iterator begin() const;
1789 
1790     /// Past-the-end iterator.
1791     iterator end() const;
1792 
1793     /// Return !empty().
1794     operator unspecified_bool_type() const;
1795 
1796     /// Equality compare.
1797     bool equal(const iterator_range&) const;
1798 
1799     /// Return *begin().  This range must not be empty.
1800     reference front() const;
1801 
1802     /// Advance this range's begin iterator.
1803     iterator_range& advance_begin(difference_type n);
1804 
1805     /// Advance this range's end iterator.
1806     iterator_range& advance_end(difference_type n);
1807 
1808     ;    /// Return begin() == end().
1809     bool empty() const;
1810 
1811 private:
1812     /// Equality comparison.
1813     friend bool operator==(const UsdPrimSiblingRange &lhs,
1814                            const UsdPrimSiblingRange &rhs);
1815     /// Inequality comparison.
1816     friend bool operator!=(const UsdPrimSiblingRange &lhs,
1817                            const UsdPrimSiblingRange &rhs);
1818 };
1819 
1820 #else
1821 
1822 // Sibling iterator class.  Converts ref to weak and filters according to a
1823 // supplied predicate.
1824 class UsdPrimSiblingIterator : public boost::iterator_adaptor<
1825     UsdPrimSiblingIterator,                       // crtp base.
1826     const Usd_PrimData *,                         // base iterator.
1827     UsdPrim,                                      // value type.
1828     boost::forward_traversal_tag,                 // traversal
1829     UsdPrim>                                      // reference type.
1830 {
1831 public:
1832     // Default ctor.
UsdPrimSiblingIterator()1833     UsdPrimSiblingIterator() {}
1834 
1835 private:
1836     friend class UsdPrim;
1837 
1838     // Constructor used by Prim.
UsdPrimSiblingIterator(const base_type & i,const SdfPath & proxyPrimPath,const Usd_PrimFlagsPredicate & predicate)1839     UsdPrimSiblingIterator(const base_type &i, const SdfPath& proxyPrimPath,
1840                            const Usd_PrimFlagsPredicate &predicate)
1841         : iterator_adaptor_(i)
1842         , _proxyPrimPath(proxyPrimPath)
1843         , _predicate(predicate) {
1844         // Need to advance iterator to first matching element.
1845         if (base() && !Usd_EvalPredicate(_predicate, base(), _proxyPrimPath))
1846             increment();
1847     }
1848 
1849     // Core implementation invoked by iterator_adaptor.
1850     friend class boost::iterator_core_access;
equal(const UsdPrimSiblingIterator & other)1851     bool equal(const UsdPrimSiblingIterator &other) const {
1852         return base() == other.base() &&
1853             _proxyPrimPath == other._proxyPrimPath &&
1854             _predicate == other._predicate;
1855     }
1856 
increment()1857     void increment() {
1858         base_type &base = base_reference();
1859         if (Usd_MoveToNextSiblingOrParent(base, _proxyPrimPath, _predicate)) {
1860             base = nullptr;
1861             _proxyPrimPath = SdfPath();
1862         }
1863     }
1864 
dereference()1865     reference dereference() const {
1866         return UsdPrim(base(), _proxyPrimPath);
1867     }
1868 
1869     SdfPath _proxyPrimPath;
1870     Usd_PrimFlagsPredicate _predicate;
1871 };
1872 
1873 // Typedef iterator range.
1874 typedef boost::iterator_range<UsdPrimSiblingIterator> UsdPrimSiblingRange;
1875 
1876 // Inform TfIterator it should feel free to make copies of the range type.
1877 template <>
1878 struct Tf_ShouldIterateOverCopy<
1879     UsdPrimSiblingRange> : boost::true_type {};
1880 template <>
1881 struct Tf_ShouldIterateOverCopy<
1882     const UsdPrimSiblingRange> : boost::true_type {};
1883 
1884 #endif // doxygen
1885 
1886 
1887 UsdPrimSiblingRange
1888 UsdPrim::GetFilteredChildren(const Usd_PrimFlagsPredicate &pred) const
1889 {
1890     return _MakeSiblingRange(
1891         Usd_CreatePredicateForTraversal(_Prim(), _ProxyPrimPath(), pred));
1892 }
1893 
1894 UsdPrimSiblingRange
1895 UsdPrim::GetAllChildren() const
1896 {
1897     return GetFilteredChildren(UsdPrimAllPrimsPredicate);
1898 }
1899 
1900 UsdPrimSiblingRange
1901 UsdPrim::GetChildren() const
1902 {
1903     return GetFilteredChildren(UsdPrimDefaultPredicate);
1904 }
1905 
1906 // Helper to make a sibling range.
1907 UsdPrim::SiblingRange
1908 UsdPrim::_MakeSiblingRange(const Usd_PrimFlagsPredicate &pred) const {
1909     Usd_PrimDataConstPtr firstChild = get_pointer(_Prim());
1910     SdfPath firstChildPath = _ProxyPrimPath();
1911     if (!Usd_MoveToChild(firstChild, firstChildPath, pred)) {
1912         firstChild = nullptr;
1913         firstChildPath = SdfPath();
1914     }
1915 
1916     return SiblingRange(
1917         SiblingIterator(firstChild, firstChildPath, pred),
1918         SiblingIterator(nullptr, SdfPath(), pred));
1919 }
1920 
1921 #ifdef doxygen
1922 
1923 /// Forward traversal iterator of sibling ::UsdPrim s.  This is a
1924 /// standard-compliant iterator that may be used with STL algorithms, etc.
1925 class UsdPrimSubtreeIterator {
1926 public:
1927     /// Iterator value type.
1928     typedef UsdPrim value_type;
1929     /// Iterator reference type, in this case the same as \a value_type.
1930     typedef value_type reference;
1931     /// Iterator difference type.
1932     typedef unspecified-integral-type difference_type;
1933     /// Dereference.
1934     reference operator*() const;
1935     /// Indirection.
1936     unspecified-type operator->() const;
1937     /// Postincrement.
1938     UsdPrimSubtreeIterator &operator++();
1939     /// Preincrement.
1940     UsdPrimSubtreeIterator operator++(int);
1941 private:
1942     /// Equality.
1943     friend bool operator==(const UsdPrimSubtreeIterator &lhs,
1944                            const UsdPrimSubtreeIterator &rhs);
1945     /// Inequality.
1946     friend bool operator!=(const UsdPrimSubtreeIterator &lhs,
1947                            const UsdPrimSubtreeIterator &rhs);
1948 };
1949 
1950 /// Forward iterator range of sibling ::UsdPrim s.  This range type contains a
1951 /// pair of UsdPrimSubtreeIterator s, denoting a half-open range of UsdPrim
1952 /// siblings.  It provides a subset of container-like API, such as begin(),
1953 /// end(), front(), empty(), etc.
1954 class UsdPrimSubtreeRange {
1955 public:
1956     /// Iterator type.
1957     typedef UsdPrimSubtreeIterator iterator;
1958     /// Const iterator type.
1959     typedef UsdPrimSubtreeIterator const_iterator;
1960     /// Iterator difference type.
1961     typedef unspecified-integral-type difference_type;
1962     /// Iterator value_type.
1963     typedef iterator::value_type value_type;
1964     /// Iterator reference_type.
1965     typedef iterator::reference reference;
1966 
1967     /// Construct with a pair of iterators.
1968     UsdPrimSubtreeRange(UsdPrimSubtreeIterator begin,
1969                         UsdPrimSubtreeIterator end);
1970 
1971     /// Construct/convert from another compatible range type.
1972     template <class ForwardRange>
1973     UsdPrimSubtreeRange(const ForwardRange &r);
1974 
1975     /// Assign from another compatible range type.
1976     template <class ForwardRange>
1977     UsdPrimSubtreeRange &operator=(const ForwardRange &r);
1978 
1979     /// First iterator.
1980     iterator begin() const;
1981 
1982     /// Past-the-end iterator.
1983     iterator end() const;
1984 
1985     /// Return !empty().
1986     operator unspecified_bool_type() const;
1987 
1988     /// Equality compare.
1989     bool equal(const iterator_range&) const;
1990 
1991     /// Return *begin().  This range must not be empty.
1992     reference front() const;
1993 
1994     /// Advance this range's begin iterator.
1995     iterator_range& advance_begin(difference_type n);
1996 
1997     /// Advance this range's end iterator.
1998     iterator_range& advance_end(difference_type n);
1999 
2000     /// Return begin() == end().
2001     bool empty() const;
2002 
2003 private:
2004     /// Equality comparison.
2005     friend bool operator==(const UsdPrimSubtreeRange &lhs,
2006                            const UsdPrimSubtreeRange &rhs);
2007     /// Inequality comparison.
2008     friend bool operator!=(const UsdPrimSubtreeRange &lhs,
2009                            const UsdPrimSubtreeRange &rhs);
2010 };
2011 
2012 #else
2013 
2014 // Subtree iterator class.  Converts ref to weak and filters according to a
2015 // supplied predicate.
2016 class UsdPrimSubtreeIterator : public boost::iterator_adaptor<
2017     UsdPrimSubtreeIterator,                       // crtp base.
2018     const Usd_PrimData *,                         // base iterator.
2019     UsdPrim,                                      // value type.
2020     boost::forward_traversal_tag,                 // traversal
2021     UsdPrim>                                      // reference type.
2022 {
2023 public:
2024     // Default ctor.
2025     UsdPrimSubtreeIterator() {}
2026 
2027 private:
2028     friend class UsdPrim;
2029 
2030     // Constructor used by Prim.
2031     UsdPrimSubtreeIterator(const base_type &i, const SdfPath &proxyPrimPath,
2032                            const Usd_PrimFlagsPredicate &predicate)
2033         : iterator_adaptor_(i)
2034         , _proxyPrimPath(proxyPrimPath)
2035         , _predicate(predicate) {
2036         // Need to advance iterator to first matching element.
2037         base_type &base = base_reference();
2038         if (base && !Usd_EvalPredicate(_predicate, base, _proxyPrimPath)) {
2039             if (Usd_MoveToNextSiblingOrParent(base, _proxyPrimPath,
2040                                               _predicate)) {
2041                 base = nullptr;
2042                 _proxyPrimPath = SdfPath();
2043             }
2044         }
2045     }
2046 
2047     // Core implementation invoked by iterator_adaptor.
2048     friend class boost::iterator_core_access;
2049     bool equal(const UsdPrimSubtreeIterator &other) const {
2050         return base() == other.base() &&
2051             _proxyPrimPath == other._proxyPrimPath &&
2052             _predicate == other._predicate;
2053     }
2054 
2055     void increment() {
2056         base_type &base = base_reference();
2057         if (!Usd_MoveToChild(base, _proxyPrimPath, _predicate)) {
2058             while (Usd_MoveToNextSiblingOrParent(base, _proxyPrimPath,
2059                                                  _predicate)) {}
2060         }
2061     }
2062 
2063     reference dereference() const {
2064         return UsdPrim(base(), _proxyPrimPath);
2065     }
2066 
2067     SdfPath _proxyPrimPath;
2068     Usd_PrimFlagsPredicate _predicate;
2069 };
2070 
2071 // Typedef iterator range.
2072 typedef boost::iterator_range<UsdPrimSubtreeIterator> UsdPrimSubtreeRange;
2073 
2074 // Inform TfIterator it should feel free to make copies of the range type.
2075 template <>
2076 struct Tf_ShouldIterateOverCopy<
2077     UsdPrimSubtreeRange> : boost::true_type {};
2078 template <>
2079 struct Tf_ShouldIterateOverCopy<
2080     const UsdPrimSubtreeRange> : boost::true_type {};
2081 
2082 #endif // doxygen
2083 
2084 UsdPrimSubtreeRange
2085 UsdPrim::GetFilteredDescendants(const Usd_PrimFlagsPredicate &pred) const
2086 {
2087     return _MakeDescendantsRange(
2088         Usd_CreatePredicateForTraversal(_Prim(), _ProxyPrimPath(), pred));
2089 }
2090 
2091 UsdPrimSubtreeRange
2092 UsdPrim::GetAllDescendants() const
2093 {
2094     return GetFilteredDescendants(UsdPrimAllPrimsPredicate);
2095 }
2096 
2097 UsdPrimSubtreeRange
2098 UsdPrim::GetDescendants() const
2099 {
2100     return GetFilteredDescendants(UsdPrimDefaultPredicate);
2101 }
2102 
2103 // Helper to make a sibling range.
2104 UsdPrim::SubtreeRange
2105 UsdPrim::_MakeDescendantsRange(const Usd_PrimFlagsPredicate &pred) const {
2106     Usd_PrimDataConstPtr firstChild = get_pointer(_Prim());
2107     SdfPath firstChildPath = _ProxyPrimPath();
2108     Usd_PrimDataConstPtr endChild = firstChild;
2109     SdfPath endChildPath = firstChildPath;
2110     if (Usd_MoveToChild(firstChild, firstChildPath, pred)) {
2111         while (Usd_MoveToNextSiblingOrParent(endChild, endChildPath, pred)) {}
2112     }
2113 
2114     return SubtreeRange(
2115         SubtreeIterator(firstChild, firstChildPath, pred),
2116         SubtreeIterator(endChild, endChildPath, pred));
2117 }
2118 
2119 
2120 ////////////////////////////////////////////////////////////////////////
2121 // UsdObject methods that require UsdPrim be a complete type.
2122 
2123 inline UsdPrim
2124 UsdObject::GetPrim() const
2125 {
2126     return UsdPrim(_prim, _proxyPrimPath);
2127 }
2128 
2129 PXR_NAMESPACE_CLOSE_SCOPE
2130 
2131 #endif // PXR_USD_USD_PRIM_H
2132 
2133