HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
prim.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_USD_USD_PRIM_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"
35 
36 #include "pxr/usd/sdf/schema.h"
37 #include "pxr/base/trace/trace.h"
38 
40 #include "pxr/base/tf/refBase.h"
41 #include "pxr/base/tf/token.h"
42 #include "pxr/base/tf/weakBase.h"
43 
44 #include "pxr/usd/sdf/path.h"
45 
46 #include <hboost/iterator/iterator_adaptor.hpp>
47 #include <hboost/range/iterator_range.hpp>
48 
49 #include <string>
50 #include <type_traits>
51 #include <vector>
52 
54 
55 class UsdPrim;
56 class UsdPrimDefinition;
57 class UsdPrimRange;
58 class Usd_PrimData;
59 
60 class UsdAttribute;
61 class UsdEditTarget;
62 class UsdRelationship;
63 class UsdPayloads;
64 class UsdReferences;
65 class UsdResolveTarget;
66 class UsdSchemaBase;
67 class UsdAPISchemaBase;
68 class UsdInherits;
69 class UsdSpecializes;
70 class UsdVariantSets;
71 class UsdVariantSet;
72 
73 class SdfPayload;
74 
76 typedef hboost::iterator_range<UsdPrimSiblingIterator> UsdPrimSiblingRange;
77 
79 typedef hboost::iterator_range<UsdPrimSubtreeIterator> UsdPrimSubtreeRange;
80 
81 /// \class UsdPrim
82 ///
83 /// UsdPrim is the sole persistent scenegraph object on a UsdStage, and
84 /// is the embodiment of a "Prim" as described in the <em>Universal Scene
85 /// Description Composition Compendium</em>
86 ///
87 /// A UsdPrim is the principal container of other types of scene description.
88 /// It provides API for accessing and creating all of the contained kinds
89 /// of scene description, which include:
90 /// \li UsdVariantSets - all VariantSets on the prim (GetVariantSets(), GetVariantSet())
91 /// \li UsdReferences - all references on the prim (GetReferences())
92 /// \li UsdInherits - all inherits on the prim (GetInherits())
93 /// \li UsdSpecializes - all specializes on the prim (GetSpecializes())
94 ///
95 /// As well as access to the API objects for properties contained within the
96 /// prim - UsdPrim as well as all of the following classes are subclasses
97 /// of UsdObject:
98 /// \li UsdProperty - generic access to all attributes and relationships.
99 /// A UsdProperty can be queried and cast to a UsdAttribute or UsdRelationship
100 /// using UsdObject::Is<>() and UsdObject::As<>(). (GetPropertyNames(),
101 /// GetProperties(), GetPropertiesInNamespace(), GetPropertyOrder(),
102 /// SetPropertyOrder())
103 /// \li UsdAttribute - access to default and timesampled attribute values, as
104 /// well as value resolution information, and attribute-specific metadata
105 /// (CreateAttribute(), GetAttribute(), GetAttributes(), HasAttribute())
106 /// \li UsdRelationship - access to authoring and resolving relationships
107 /// to other prims and properties (CreateRelationship(), GetRelationship(),
108 /// GetRelationships(), HasRelationship())
109 ///
110 /// UsdPrim also provides access to iteration through its prim children,
111 /// optionally making use of the \ref primFlags.h "prim predicates facility"
112 /// (GetChildren(), GetAllChildren(), GetFilteredChildren()).
113 ///
114 /// \section Lifetime Management
115 ///
116 /// Clients acquire UsdPrim objects, which act like weak/guarded pointers
117 /// to persistent objects owned and managed by their originating UsdStage.
118 /// We provide the following guarantees for a UsdPrim acquired via
119 /// UsdStage::GetPrimAtPath() or UsdStage::OverridePrim() or
120 /// UsdStage::DefinePrim():
121 /// \li As long as no further mutations to the structure of the UsdStage
122 /// are made, the UsdPrim will still be valid. Loading and
123 /// Unloading are considered structural mutations.
124 /// \li When the UsdStage's structure \em is mutated, the thread performing
125 /// the mutation will receive a UsdNotice::ObjectsChanged notice
126 /// after the stage has been reconfigured, which provides details as to
127 /// what prims may have been created or destroyed, and what prims
128 /// may simply have changed in some structural way.
129 ///
130 /// Prim access in "reader" threads should be limited to GetPrimAtPath(), which
131 /// will never cause a mutation to the Stage or its layers.
132 ///
133 /// Please refer to \ref UsdNotice for a listing of
134 /// the events that could cause UsdNotice::ObjectsChanged to be emitted.
135 class UsdPrim : public UsdObject
136 {
137 public:
138  /// Convenience typedefs.
141 
142  /// Convenience typedefs.
145 
146  /// Construct an invalid prim.
148 
149  /// Return the prim's full type info composed from its type name, applied
150  /// API schemas, and any fallback types defined on the stage for
151  /// unrecognized prim type names. The returned type structure contains the
152  /// "true" schema type used to create this prim's prim definition and answer
153  /// the IsA query. This value is cached and efficient to query. The cached
154  /// values are guaranteed to exist for (at least) as long as the prim's
155  /// stage is open.
156  /// \sa GetTypeName
157  /// \sa GetAppliedSchemas
158  /// \sa \ref Usd_OM_FallbackPrimTypes
160  return _Prim()->GetPrimTypeInfo();
161  }
162 
163  /// Return this prim's definition based on the prim's type if the type
164  /// is a registered prim type. Returns an empty prim definition if it is
165  /// not.
167  return _Prim()->GetPrimDefinition();
168  }
169 
170  /// Return this prim's composed specifier.
171  SdfSpecifier GetSpecifier() const { return _Prim()->GetSpecifier(); };
172 
173  /// Return all the authored SdfPrimSpecs that may contain opinions for this
174  /// prim in order from strong to weak.
175  ///
176  /// This does not include all the places where contributing prim specs could
177  /// potentially be created; rather, it includes only those prim specs that
178  /// already exist. To discover all the places that prim specs could be
179  /// authored that would contribute opinions, see
180  /// \ref "Composition Structure"
181  ///
182  /// \note Use this method for debugging and diagnostic purposes. It is
183  /// **not** advisable to retain a PrimStack for expedited metadata value
184  /// resolution, since not all metadata resolves with simple "strongest
185  /// opinion wins" semantics.
186  USD_API
187  SdfPrimSpecHandleVector GetPrimStack() const;
188 
189  /// Return all the authored SdfPrimSpecs that may contain opinions for this
190  /// prim in order from strong to weak paired with the cumulative layer
191  /// offset from the stage's root layer to the layer containing the prim
192  /// spec.
193  ///
194  /// This behaves exactly the same as UsdPrim::GetPrimStack with the
195  /// addition of providing the cumulative layer offset of each spec's layer.
196  ///
197  /// \note Use this method for debugging and diagnostic purposes. It is
198  /// **not** advisable to retain a PrimStack for expedited metadata value
199  /// resolution, since not all metadata resolves with simple "strongest
200  /// opinion wins" semantics.
201  USD_API
202  std::vector<std::pair<SdfPrimSpecHandle, SdfLayerOffset>>
204 
205  /// Author an opinion for this Prim's specifier at the current edit
206  /// target.
207  bool SetSpecifier(SdfSpecifier specifier) const {
208  return SetMetadata(SdfFieldKeys->Specifier, specifier);
209  }
210 
211  /// Return this prim's composed type name. This value is cached and is
212  /// efficient to query.
213  /// Note that this is just the composed type name as authored and may not
214  /// represent the full type of the prim and its prim definition. If you
215  /// need to reason about the actual type of the prim, use GetPrimTypeInfo
216  /// instead as it accounts for recognized schemas, applied API schemas,
217  /// fallback types, etc.
218  const TfToken &GetTypeName() const { return _Prim()->GetTypeName(); };
219 
220  /// Author this Prim's typeName at the current EditTarget.
221  bool SetTypeName(const TfToken & typeName) const {
222  return SetMetadata(SdfFieldKeys->TypeName, typeName);
223  }
224 
225  /// Clear the opinion for this Prim's typeName at the current edit
226  /// target.
227  bool ClearTypeName() const {
228  return ClearMetadata(SdfFieldKeys->TypeName);
229  }
230 
231  /// Return true if a typeName has been authored.
232  bool HasAuthoredTypeName() const {
233  return HasAuthoredMetadata(SdfFieldKeys->TypeName);
234  }
235 
236  /// Return true if this prim is active, meaning neither it nor any of its
237  /// ancestors have active=false. Return false otherwise.
238  ///
239  /// See \ref Usd_ActiveInactive for what it means for a prim to be active.
240  bool IsActive() const { return _Prim()->IsActive(); }
241 
242  /// Author 'active' metadata for this prim at the current EditTarget.
243  ///
244  /// See \ref Usd_ActiveInactive for the effects of activating or deactivating
245  /// a prim.
246  bool SetActive(bool active) const {
247  return SetMetadata(SdfFieldKeys->Active, active);
248  }
249 
250  /// Remove the authored 'active' opinion at the current EditTarget. Do
251  /// nothing if there is no authored opinion.
252  ///
253  /// See \ref Usd_ActiveInactive for the effects of activating or deactivating
254  /// a prim.
255  bool ClearActive() const {
256  return ClearMetadata(SdfFieldKeys->Active);
257  }
258 
259  /// Return true if this prim has an authored opinion for 'active', false
260  /// otherwise.
261  ///
262  /// See \ref Usd_ActiveInactive for what it means for a prim to be active.
263  bool HasAuthoredActive() const {
264  return HasAuthoredMetadata(SdfFieldKeys->Active);
265  }
266 
267  /// Return true if this prim is active, and \em either it is loadable and
268  /// it is loaded, \em or its nearest loadable ancestor is loaded, \em or it
269  /// has no loadable ancestor; false otherwise.
270  bool IsLoaded() const { return _Prim()->IsLoaded(); }
271 
272  /// Return true if this prim is a model based on its kind metadata, false
273  /// otherwise.
274  bool IsModel() const { return _Prim()->IsModel(); }
275 
276  /// Return true if this prim is a model group based on its kind metadata,
277  /// false otherwise. If this prim is a group, it is also necessarily a
278  /// model.
279  bool IsGroup() const { return _Prim()->IsGroup(); }
280 
281  /// Return true if this prim or any of its ancestors is a class.
282  bool IsAbstract() const { return _Prim()->IsAbstract(); }
283 
284  /// Return true if this prim and all its ancestors have defining specifiers,
285  /// false otherwise. \sa SdfIsDefiningSpecifier.
286  bool IsDefined() const { return _Prim()->IsDefined(); }
287 
288  /// Return true if this prim has a specifier of type SdfSpecifierDef
289  /// or SdfSpecifierClass. \sa SdfIsDefiningSpecifier
290  bool HasDefiningSpecifier() const {
291  return _Prim()->HasDefiningSpecifier();
292  }
293 
294  /// Return a vector containing the names of API schemas which have
295  /// been applied to this prim. This includes both the authored API schemas
296  /// applied using the Apply() method on the particular schema class as
297  /// well as any built-in API schemas that are automatically included
298  /// through the prim type's prim definition.
299  /// To get only the authored API schemas use GetPrimTypeInfo instead.
300  USD_API
302 
303  /// Alias for the "predicate" function parameter passed into the various
304  /// Get{Authored}{PropertyNames,Properties} methods.
305  using PropertyPredicateFunc =
306  std::function<bool (const TfToken &propertyName)>;
307 
308  /// Return all of this prim's property names (attributes and relationships),
309  /// including all builtin properties.
310  ///
311  /// If a valid \p predicate is passed in, then only properties whose names
312  /// pass the predicate are included in the result. This is useful if the
313  /// client is interested only in a subset of properties on the prim. For
314  /// example, only the ones in a given namespace or only the ones needed to
315  /// compute a value.
316  ///
317  /// \sa GetAuthoredPropertyNames()
318  /// \sa UsdProperty::IsAuthored()
319  USD_API
321  const PropertyPredicateFunc &predicate={}) const;
322 
323  /// Return this prim's property names (attributes and relationships) that
324  /// have authored scene description, ordered according to the strongest
325  /// propertyOrder statement in scene description if one exists, otherwise
326  /// ordered according to TfDictionaryLessThan.
327  ///
328  /// If a valid \p predicate is passed in, then only the authored properties
329  /// whose names pass the predicate are included in the result. This is
330  /// useful if the client is interested only in a subset of authored
331  /// properties on the prim. For example, only the ones in a given namespace
332  /// or only the ones needed to compute a value.
333  ///
334  /// \sa GetPropertyNames()
335  /// \sa UsdProperty::IsAuthored()
336  USD_API
338  const PropertyPredicateFunc &predicate={}) const;
339 
340  /// Return all of this prim's properties (attributes and relationships),
341  /// including all builtin properties, ordered by name according to the
342  /// strongest propertyOrder statement in scene description if one exists,
343  /// otherwise ordered according to TfDictionaryLessThan.
344  ///
345  /// If a valid \p predicate is passed in, then only properties whose names
346  /// pass the predicate are included in the result. This is useful if the
347  /// client is interested only in a subset of properties on the prim. For
348  /// example, only the ones in a given namespace or only the ones needed to
349  /// compute a value.
350  ///
351  /// To obtain only either attributes or relationships, use either
352  /// GetAttributes() or GetRelationships().
353  ///
354  /// To determine whether a property is either an attribute or a
355  /// relationship, use the UsdObject::As() and UsdObject::Is() methods in
356  /// C++:
357  ///
358  /// \code
359  /// // Use As<>() to obtain a subclass instance.
360  /// if (UsdAttribute attr = property.As<UsdAttribute>()) {
361  /// // use attribute 'attr'.
362  /// else if (UsdRelationship rel = property.As<UsdRelationship>()) {
363  /// // use relationship 'rel'.
364  /// }
365  ///
366  /// // Use Is<>() to discriminate only.
367  /// if (property.Is<UsdAttribute>()) {
368  /// // property is an attribute.
369  /// }
370  /// \endcode
371  ///
372  /// In Python, use the standard isinstance() function:
373  ///
374  /// \code
375  /// if isinstance(property, Usd.Attribute):
376  /// # property is a Usd.Attribute.
377  /// elif isinstance(property, Usd.Relationship):
378  /// # property is a Usd.Relationship.
379  /// \endcode
380  ///
381  /// \sa GetAuthoredProperties()
382  /// \sa UsdProperty::IsAuthored()
383  USD_API
384  std::vector<UsdProperty> GetProperties(
385  const PropertyPredicateFunc &predicate={}) const;
386 
387  /// Return this prim's properties (attributes and relationships) that have
388  /// authored scene description, ordered by name according to the strongest
389  /// propertyOrder statement in scene description if one exists, otherwise
390  /// ordered according to TfDictionaryLessThan.
391  ///
392  /// If a valid \p predicate is passed in, then only authored properties
393  /// whose names pass the predicate are included in the result. This is
394  /// useful if the client is interested only in a subset of authored
395  /// properties on the prim. For example, only the ones in a given namespace
396  /// or only the ones needed to compute a value.
397  ///
398  /// \sa GetProperties()
399  /// \sa UsdProperty::IsAuthored()
400  USD_API
401  std::vector<UsdProperty> GetAuthoredProperties(
402  const PropertyPredicateFunc &predicate={}) const;
403 
404  /// Return this prim's properties that are inside the given property
405  /// namespace ordered according to the strongest propertyOrder statement in
406  /// scene description if one exists, otherwise ordered according to
407  /// TfDictionaryLessThan.
408  ///
409  /// A \p namespaces argument whose elements are ["ri", "attribute"] will
410  /// return all the properties under the namespace "ri:attribute",
411  /// i.e. "ri:attribute:*". An empty \p namespaces argument is equivalent to
412  /// GetProperties().
413  ///
414  /// For details of namespaced properties, see \ref Usd_Ordering
415  USD_API
416  std::vector<UsdProperty>
417  GetPropertiesInNamespace(const std::vector<std::string> &namespaces) const;
418 
419  /// \overload
420  /// \p namespaces must be an already-concatenated ordered set of namespaces,
421  /// and may or may not terminate with the namespace-separator character. If
422  /// \p namespaces is empty, this method is equivalent to GetProperties().
423  USD_API
424  std::vector<UsdProperty>
425  GetPropertiesInNamespace(const std::string &namespaces) const;
426 
427  /// Like GetPropertiesInNamespace(), but exclude properties that do not have
428  /// authored scene description from the result. See
429  /// UsdProperty::IsAuthored().
430  ///
431  /// For details of namespaced properties, see \ref Usd_Ordering
432  USD_API
433  std::vector<UsdProperty>
435  const std::vector<std::string> &namespaces) const;
436 
437  /// \overload
438  /// \p namespaces must be an already-concatenated ordered set of namespaces,
439  /// and may or may not terminate with the namespace-separator character. If
440  /// \p namespaces is empty, this method is equivalent to
441  /// GetAuthoredProperties().
442  USD_API
443  std::vector<UsdProperty>
444  GetAuthoredPropertiesInNamespace(const std::string &namespaces) const;
445 
446  /// Return the strongest propertyOrder metadata value authored on this prim.
447  USD_API
449 
450  /// Author an opinion for propertyOrder metadata on this prim at the current
451  /// EditTarget.
452  void SetPropertyOrder(const TfTokenVector &order) const {
453  SetMetadata(SdfFieldKeys->PropertyOrder, order);
454  }
455 
456  /// Remove the opinion for propertyOrder metadata on this prim at the current
457  /// EditTarget.
458  void ClearPropertyOrder() const {
459  ClearMetadata(SdfFieldKeys->PropertyOrder);
460  }
461 
462  /// Remove all scene description for the property with the
463  /// given \p propName <em>in the current UsdEditTarget</em>.
464  /// Return true if the property is removed, false otherwise.
465  ///
466  /// Because this method can only remove opinions about the property from
467  /// the current EditTarget, you may generally find it more useful to use
468  /// UsdAttribute::Block(), which will ensure that all values from the
469  /// EditTarget and weaker layers for the property will be ignored.
470  USD_API
471  bool RemoveProperty(const TfToken &propName);
472 
473  /// Return a UsdProperty with the name \a propName. The property
474  /// returned may or may not \b actually exist so it must be checked for
475  /// validity. Suggested use:
476  ///
477  /// \code
478  /// if (UsdProperty myProp = prim.GetProperty("myProp")) {
479  /// // myProp is safe to use.
480  /// // Edits to the owning stage requires subsequent validation.
481  /// } else {
482  /// // myProp was not defined/authored
483  /// }
484  /// \endcode
485  USD_API
486  UsdProperty GetProperty(const TfToken &propName) const;
487 
488  /// Return true if this prim has an property named \p propName, false
489  /// otherwise.
490  USD_API
491  bool HasProperty(const TfToken &propName) const;
492 
493 private:
494  // Helper functions for the public schema query and API schema
495  // authoring functions. The public functions have overloads that take
496  // a type, an identifier, or a family which all are used to find the
497  // SchemaInfo from the schema registry.
498  USD_API
499  bool _IsA(const UsdSchemaRegistry::SchemaInfo *schemaInfo) const;
500 
501  USD_API
502  bool _HasAPI(const UsdSchemaRegistry::SchemaInfo *schemaInfo) const;
503 
504  USD_API
505  bool _HasAPIInstance(
506  const UsdSchemaRegistry::SchemaInfo *schemaInfo,
507  const TfToken &instanceName) const;
508 
509  USD_API
510  bool _CanApplySingleApplyAPI(
511  const UsdSchemaRegistry::SchemaInfo &schemaInfo,
512  std::string *whyNot) const;
513 
514  USD_API
515  bool _CanApplyMultipleApplyAPI(
516  const UsdSchemaRegistry::SchemaInfo &schemaInfo,
517  const TfToken& instanceName,
518  std::string *whyNot) const;
519 
520  USD_API
521  bool _ApplySingleApplyAPI(
522  const UsdSchemaRegistry::SchemaInfo &schemaInfo) const;
523 
524  USD_API
525  bool _ApplyMultipleApplyAPI(
526  const UsdSchemaRegistry::SchemaInfo &schemaInfo,
527  const TfToken &instanceName) const;
528 
529  USD_API
530  bool _RemoveSingleApplyAPI(
531  const UsdSchemaRegistry::SchemaInfo &schemaInfo) const;
532 
533  USD_API
534  bool _RemoveMultipleApplyAPI(
535  const UsdSchemaRegistry::SchemaInfo &schemaInfo,
536  const TfToken &instanceName) const;
537 
538 public:
539  /// \name IsA
540  ///
541  /// @{
542 
543  /// Return true if the prim's schema type, is or inherits from the TfType
544  /// of the schema class type \p SchemaType.
545  ///
546  /// \sa GetPrimTypeInfo
547  /// \sa UsdPrimTypeInfo::GetSchemaType
548  /// \sa \ref Usd_OM_FallbackPrimTypes
549  template <typename SchemaType>
550  bool IsA() const {
552  "Provided type must derive UsdSchemaBase.");
553  return _IsA(UsdSchemaRegistry::FindSchemaInfo<SchemaType>());
554  };
555 
556  /// This is an overload of \ref IsA that takes a TfType \p schemaType .
557  USD_API
558  bool IsA(const TfType& schemaType) const;
559 
560  /// This is an overload of \ref IsA that takes a \p schemaIdentifier to
561  /// determine the schema type.
562  USD_API
563  bool IsA(const TfToken& schemaIdentifier) const;
564 
565  /// This is an overload of \ref IsA that takes a \p schemaFamily and
566  /// \p schemaVersion to determine the schema type.
567  USD_API
568  bool IsA(const TfToken& schemaFamily,
569  UsdSchemaVersion schemaVersion) const;
570 
571  /// @}
572 
573  /// \name IsInFamily
574  ///
575  /// @{
576 
577  /// Return true if the prim's schema type is or inherits from the schema
578  /// type of any version of the schemas in the given \p schemaFamily.
579  USD_API
580  bool IsInFamily(const TfToken &schemaFamily) const;
581 
582  /// Return true if the prim's schema type, is or inherits from the schema
583  /// type of any schema in the given \p schemaFamily that matches the version
584  /// filter provided by \p schemaVersion and \p versionPolicy.
585  USD_API
586  bool IsInFamily(
587  const TfToken &schemaFamily,
588  UsdSchemaVersion schemaVersion,
589  UsdSchemaRegistry::VersionPolicy versionPolicy) const;
590 
591  /// Overload for convenience of
592  /// \ref IsInFamily(const TfToken&, UsdSchemaVersion, UsdSchemaRegistry::VersionPolicy) const "IsInFamily"
593  /// that finds a registered schema for the C++ schema class \p SchemaType
594  /// and uses that schema's family and version.
595  template <typename SchemaType>
597  UsdSchemaRegistry::VersionPolicy versionPolicy) const {
599  "Provided type must derive UsdSchemaBase.");
600  const UsdSchemaRegistry::SchemaInfo *schemaInfo =
601  UsdSchemaRegistry::FindSchemaInfo<SchemaType>();
602  if (!schemaInfo) {
603  TF_CODING_ERROR("Class '%s' is not correctly registered with the "
604  "UsdSchemaRegistry as a schema type. The schema may need to be "
605  "regenerated.",
606  TfType::Find<SchemaType>().GetTypeName().c_str());
607  return false;
608  }
609  return IsInFamily(schemaInfo->family, schemaInfo->version,
610  versionPolicy);
611  };
612 
613  /// Overload for convenience of
614  /// \ref IsInFamily(const TfToken&, UsdSchemaVersion, UsdSchemaRegistry::VersionPolicy) const "IsInFamily"
615  /// that finds a registered schema for the given \p schemaType and uses that
616  /// schema's family and version.
617  USD_API
618  bool IsInFamily(
619  const TfType &schemaType,
620  UsdSchemaRegistry::VersionPolicy versionPolicy) const;
621 
622  /// Overload for convenience of
623  /// \ref IsInFamily(const TfToken&, UsdSchemaVersion, UsdSchemaRegistry::VersionPolicy) const "IsInFamily"
624  /// that parses the schema family and version to use from the given
625  /// \p schemaIdentifier.
626  ///
627  /// Note that the schema identifier is not required to be a registered
628  /// schema as it only parsed to get what its family and version would be
629  /// See UsdSchemaRegistry::ParseSchemaFamilyAndVersionFromIdentifier.
630  USD_API
631  bool IsInFamily(
632  const TfToken &schemaIdentifier,
633  UsdSchemaRegistry::VersionPolicy versionPolicy) const;
634 
635  /// Return true if the prim's schema type, is or inherits from the schema
636  /// type of any version the schema in the given \p schemaFamily and if so,
637  /// populates \p schemaVersion with the version of the schema that this
638  /// prim \ref IsA.
639  USD_API
641  const TfToken &schemaFamily,
642  UsdSchemaVersion *schemaVersion) const;
643 
644  /// @}
645 
646  /// \name HasAPI
647  ///
648  /// __Using HasAPI in C++__
649  /// \code
650  /// UsdPrim prim = stage->OverridePrim("/path/to/prim");
651  /// MyDomainBozAPI = MyDomainBozAPI::Apply(prim);
652  /// assert(prim.HasAPI<MyDomainBozAPI>());
653  /// assert(prim.HasAPI(TfToken("BozAPI")));
654  /// assert(prim.HasAPI(TfToken("BozAPI"), /*schemaVersion*/ 0));
655  ///
656  /// UsdCollectionAPI collAPI = UsdCollectionAPI::Apply(prim,
657  /// /*instanceName*/ TfToken("geom"));
658  /// assert(prim.HasAPI<UsdCollectionAPI>();
659  /// assert(prim.HasAPI(TfToken("CollectionAPI"));
660  /// assert(prim.HasAPI(TfToken("CollectionAPI"), /*schemaVersion*/ 0);
661  ///
662  /// assert(prim.HasAPI<UsdCollectionAPI>(/*instanceName*/ TfToken("geom")))
663  /// assert(prim.HasAPI(TfToken("CollectionAPI",
664  /// /*instanceName*/ TfToken("geom")));
665  /// assert(prim.HasAPI(TfToken("CollectionAPI"), /*schemaVersion*/ 0,
666  /// /*instanceName*/ TfToken("geom"));
667  /// \endcode
668  ///
669  /// The python version of this method takes as an argument the TfType
670  /// of the API schema class.
671  ///
672  /// __Using HasAPI in Python__
673  /// \code{.py}
674  /// prim = stage.OverridePrim("/path/to/prim")
675  /// bozAPI = MyDomain.BozAPI.Apply(prim)
676  /// assert(prim.HasAPI(MyDomain.BozAPI))
677  /// assert(prim.HasAPI("BozAPI"))
678  /// assert(prim.HasAPI("BozAPI", 0))
679  ///
680  /// collAPI = Usd.CollectionAPI.Apply(prim, "geom")
681  /// assert(prim.HasAPI(Usd.CollectionAPI))
682  /// assert(prim.HasAPI("CollectionAPI"))
683  /// assert(prim.HasAPI("CollectionAPI", 0))
684  ///
685  /// assert(prim.HasAPI(Usd.CollectionAPI, instanceName="geom"))
686  /// assert(prim.HasAPI("CollectionAPI", instanceName="geom"))
687  /// assert(prim.HasAPI("CollectionAPI", 0, instanceName="geom"))
688  /// \endcode
689  ///
690  /// @{
691 
692  /// Return true if the UsdPrim has had an applied API schema represented by
693  /// the C++ class type \p SchemaType applied to it.
694  ///
695  /// This function works for both single-apply and multiple-apply API schema
696  /// types. If the schema is a multiple-apply API schema this will return
697  /// true if any instance of the multiple-apply API has been applied.
698  template <typename SchemaType>
699  bool
700  HasAPI() const {
702  "Provided type must derive UsdAPISchemaBase.");
704  "Provided type must not be UsdAPISchemaBase.");
705  static_assert(
706  SchemaType::schemaKind == UsdSchemaKind::SingleApplyAPI ||
707  SchemaType::schemaKind == UsdSchemaKind::MultipleApplyAPI,
708  "Provided schema type must be an applied API schema.");
709 
710  return _HasAPI(UsdSchemaRegistry::FindSchemaInfo<SchemaType>());
711  }
712 
713  /// Return true if the UsdPrim has the specific instance, \p instanceName,
714  /// of the multiple-apply API schema represented by the C++ class type
715  /// \p SchemaType applied to it.
716  ///
717  /// \p instanceName must be non-empty, otherwise it is a coding error.
718  template <typename SchemaType>
719  bool
720  HasAPI(const TfToken &instanceName) const {
722  "Provided type must derive UsdAPISchemaBase.");
724  "Provided type must not be UsdAPISchemaBase.");
725  static_assert(SchemaType::schemaKind == UsdSchemaKind::MultipleApplyAPI,
726  "Provided schema type must be a multi apply API schema.");
727 
728  return _HasAPIInstance(
729  UsdSchemaRegistry::FindSchemaInfo<SchemaType>(), instanceName);
730  }
731 
732  /// This is an overload of \ref HasAPI that takes a TfType \p schemaType .
733  USD_API
734  bool HasAPI(const TfType& schemaType) const;
735 
736  /// This is an overload of \ref HasAPI(const TfToken &) const "HasAPI" with
737  /// \p instanceName that takes a TfType \p schemaType .
738  USD_API
739  bool HasAPI(const TfType& schemaType,
740  const TfToken& instanceName) const;
741 
742  /// This is an overload of \ref HasAPI that takes a \p schemaIdentifier to
743  /// determine the schema type.
744  USD_API
745  bool HasAPI(const TfToken& schemaIdentifier) const;
746 
747  /// This is an overload of \ref HasAPI(const TfToken &) const "HasAPI" with
748  /// \p instanceName that takes a \p schemaIdentifier to determine the schema
749  /// type.
750  USD_API
751  bool HasAPI(const TfToken& schemaIdentifier,
752  const TfToken& instanceName) const;
753 
754  /// This is an overload of \ref HasAPI that takes a \p schemaFamily and
755  /// \p schemaVersion to determine the schema type.
756  USD_API
757  bool HasAPI(const TfToken& schemaFamily,
758  UsdSchemaVersion schemaVersion) const;
759 
760  /// This is an overload of \ref HasAPI(const TfToken &) const "HasAPI" with
761  /// \p instanceName that takes a \p schemaFamily and \p schemaVersion to
762  /// determine the schema type.
763  USD_API
764  bool HasAPI(const TfToken& schemaFamily,
765  UsdSchemaVersion schemaVersion,
766  const TfToken& instanceName) const;
767 
768  /// @}
769 
770  /// \name HasAPIInFamily
771  ///
772  /// @{
773 
774  /// Return true if the prim has an applied API schema that is any version of
775  /// the schemas in the given \p schemaFamily.
776  ///
777  /// This function will consider both single-apply and multiple-apply API
778  /// schemas in the schema family. For the multiple-apply API schemas, this
779  /// will return true if any instance of one of the schemas has been applied.
780  USD_API
781  bool HasAPIInFamily(
782  const TfToken &schemaFamily) const;
783 
784  /// Return true if the prim has a specific instance \p instanceName of an
785  /// applied multiple-apply API schema that is any version the schemas in
786  /// the given \p schemaFamily.
787  ///
788  /// \p instanceName must be non-empty, otherwise it is a coding error.
789  USD_API
790  bool HasAPIInFamily(
791  const TfToken &schemaFamily,
792  const TfToken &instanceName) const;
793 
794  /// Return true if the prim has an applied API schema that is a schema in
795  /// the given \p schemaFamily that matches the version filter provided by
796  /// \p schemaVersion and \p versionPolicy.
797  ///
798  /// This function will consider both single-apply and multiple-apply API
799  /// schemas in the schema family. For the multiple-apply API schemas, this
800  /// will return true if any instance of one of the filter-passing schemas
801  /// has been applied.
802  USD_API
803  bool HasAPIInFamily(
804  const TfToken &schemaFamily,
805  UsdSchemaVersion schemaVersion,
806  UsdSchemaRegistry::VersionPolicy versionPolicy) const;
807 
808  /// Return true if the prim has a specific instance \p instanceName of an
809  /// applied multiple-apply API schema in the given \p schemaFamily that
810  /// matches the version filter provided by \p schemaVersion and
811  /// \p versionPolicy.
812  ///
813  /// \p instanceName must be non-empty, otherwise it is a coding error.
814  USD_API
815  bool HasAPIInFamily(
816  const TfToken &schemaFamily,
817  UsdSchemaVersion schemaVersion,
818  UsdSchemaRegistry::VersionPolicy versionPolicy,
819  const TfToken &instanceName) const;
820 
821  /// Overload for convenience of
822  /// \ref HasAPIInFamily(const TfToken&, UsdSchemaVersion, UsdSchemaRegistry::VersionPolicy) const "HasAPIInFamily"
823  /// that finds a registered schema for the C++ schema class \p SchemaType
824  /// and uses that schema's family and version.
825  template <typename SchemaType>
827  UsdSchemaRegistry::VersionPolicy versionPolicy) const {
829  "Provided type must derive UsdSchemaBase.");
830  const UsdSchemaRegistry::SchemaInfo *schemaInfo =
831  UsdSchemaRegistry::FindSchemaInfo<SchemaType>();
832  if (!schemaInfo) {
833  TF_CODING_ERROR("Class '%s' is not correctly registered with the "
834  "UsdSchemaRegistry as a schema type. The schema may need to be "
835  "regenerated.",
836  TfType::Find<SchemaType>().GetTypeName().c_str());
837  return false;
838  }
839  return HasAPIInFamily(schemaInfo->family, schemaInfo->version,
840  versionPolicy);
841  };
842 
843  /// Overload for convenience of
844  /// \ref HasAPIInFamily(const TfToken&, UsdSchemaVersion, UsdSchemaRegistry::VersionPolicy, const TfToken &) const "HasAPIInFamily"
845  /// that finds a registered schema for the C++ schema class \p SchemaType
846  /// and uses that schema's family and version.
847  template <typename SchemaType>
849  UsdSchemaRegistry::VersionPolicy versionPolicy,
850  const TfToken &instanceName) const {
852  "Provided type must derive UsdSchemaBase.");
853  const UsdSchemaRegistry::SchemaInfo *schemaInfo =
854  UsdSchemaRegistry::FindSchemaInfo<SchemaType>();
855  if (!schemaInfo) {
856  TF_CODING_ERROR("Class '%s' is not correctly registered with the "
857  "UsdSchemaRegistry as a schema type. The schema may need to be "
858  "regenerated.",
859  TfType::Find<SchemaType>().GetTypeName().c_str());
860  return false;
861  }
862  return HasAPIInFamily(schemaInfo->family, schemaInfo->version,
863  versionPolicy, instanceName);
864  };
865 
866  /// Overload for convenience of
867  /// \ref HasAPIInFamily(const TfToken&, UsdSchemaVersion, UsdSchemaRegistry::VersionPolicy) const "HasAPIInFamily"
868  /// that finds a registered schema for the given \p schemaType and uses that
869  /// schema's family and version.
870  USD_API
871  bool HasAPIInFamily(
872  const TfType &schemaType,
873  UsdSchemaRegistry::VersionPolicy versionPolicy) const;
874 
875  /// Overload for convenience of
876  /// \ref HasAPIInFamily(const TfToken&, UsdSchemaVersion, UsdSchemaRegistry::VersionPolicy, const TfToken &) const "HasAPIInFamily"
877  /// that finds a registered schema for the given \p schemaType and uses that
878  /// schema's family and version.
879  USD_API
880  bool HasAPIInFamily(
881  const TfType &schemaType,
882  UsdSchemaRegistry::VersionPolicy versionPolicy,
883  const TfToken &instanceName) const;
884 
885  /// Overload for convenience of
886  /// \ref HasAPIInFamily(const TfToken&, UsdSchemaVersion, UsdSchemaRegistry::VersionPolicy) const "HasAPIInFamily"
887  /// that parses the schema family and version to use from the given
888  /// \p schemaIdentifier.
889  ///
890  /// Note that the schema identifier is not required to be a registered
891  /// schema as it only parsed to get what its family and version would be
892  /// See UsdSchemaRegistry::ParseSchemaFamilyAndVersionFromIdentifier.
893  USD_API
894  bool HasAPIInFamily(
895  const TfToken &schemaIdentifier,
896  UsdSchemaRegistry::VersionPolicy versionPolicy) const;
897 
898  /// Overload for convenience of
899  /// \ref HasAPIInFamily(const TfToken&, UsdSchemaVersion, UsdSchemaRegistry::VersionPolicy, const TfToken &) const "HasAPIInFamily"
900  /// that parses the schema family and version to use from the given
901  /// \p schemaIdentifier.
902  ///
903  /// Note that the schema identifier is not required to be a registered
904  /// schema as it only parsed to get what its family and version would be
905  /// See UsdSchemaRegistry::ParseSchemaFamilyAndVersionFromIdentifier.
906  USD_API
907  bool HasAPIInFamily(
908  const TfToken &schemaIdentifier,
909  UsdSchemaRegistry::VersionPolicy versionPolicy,
910  const TfToken &instanceName) const;
911 
912  /// Return true if the prim has an applied API schema that is any version
913  /// the schemas in the given \p schemaFamily and if so, populates
914  /// \p schemaVersion with the version of the schema that this prim
915  /// \ref HasAPI.
916  ///
917  /// This function will consider both single-apply and multiple-apply API
918  /// schemas in the schema family. For the multiple-apply API schemas is a
919  /// this will return true if any instance of one of the schemas has been
920  /// applied.
921  ///
922  /// Note that if more than one version of the schemas in \p schemaFamily
923  /// are applied to this prim, the highest version number of these schemas
924  /// will be populated in \p schemaVersion.
925  USD_API
926  bool
928  const TfToken &schemaFamily,
929  UsdSchemaVersion *schemaVersion) const;
930 
931  /// Return true if the prim has a specific instance \p instanceName of an
932  /// applied multiple-apply API schema that is any version the schemas in
933  /// the given \p schemaFamily and if so, populates \p schemaVersion with the
934  /// version of the schema that this prim
935  /// \ref HasAPI(const TfToken &) const "HasAPI".
936  ///
937  /// \p instanceName must be non-empty, otherwise it is a coding error.
938  ///
939  /// Note that if more than one version of the schemas in \p schemaFamily
940  /// is multiple-apply and applied to this prim with the given
941  /// \p instanceName, the highest version number of these schemas will be
942  /// populated in \p schemaVersion.
943  USD_API
944  bool
946  const TfToken &schemaFamily,
947  const TfToken &instanceName,
948  UsdSchemaVersion *schemaVersion) const;
949 
950  /// @}
951 
952  /// \name CanApplyAPI
953  ///
954  /// @{
955 
956  /// Returns whether a __single-apply__ API schema with the given C++ type
957  /// \p SchemaType can be applied to this prim. If the return value is false,
958  /// and \p whyNot is provided, the reason the schema cannot be applied is
959  /// written to whyNot.
960  ///
961  /// Whether the schema can be applied is determined by the schema type
962  /// definition which may specify that the API schema can only be applied to
963  /// certain prim types.
964  ///
965  /// The return value of this function only indicates whether it would be
966  /// valid to apply this schema to the prim. It has no bearing on whether
967  /// calling ApplyAPI will be successful or not.
968  template <typename SchemaType>
969  bool CanApplyAPI(std::string *whyNot = nullptr) const {
971  "Provided type must derive UsdAPISchemaBase.");
973  "Provided type must not be UsdAPISchemaBase.");
974  static_assert(SchemaType::schemaKind == UsdSchemaKind::SingleApplyAPI,
975  "Provided schema type must be a single apply API schema.");
976 
977  const UsdSchemaRegistry::SchemaInfo *schemaInfo =
978  UsdSchemaRegistry::FindSchemaInfo<SchemaType>();
979  if (!schemaInfo) {
980  TF_CODING_ERROR("Class '%s' is not correctly registered with the "
981  "UsdSchemaRegistry as a schema type. The schema may need to be "
982  "regenerated.",
983  TfType::Find<SchemaType>().GetTypeName().c_str());
984  return false;
985  }
986  return _CanApplySingleApplyAPI(*schemaInfo, whyNot);
987  }
988 
989  /// Returns whether a __multiple-apply__ API schema with the given C++
990  /// type \p SchemaType can be applied to this prim with the given
991  /// \p instanceName. If the return value is false, and \p whyNot is
992  /// provided, the reason the schema cannot be applied is written to whyNot.
993  ///
994  /// Whether the schema can be applied is determined by the schema type
995  /// definition which may specify that the API schema can only be applied to
996  /// certain prim types. It also determines whether the instance name is a
997  /// valid instance name for the multiple apply schema.
998  ///
999  /// The return value of this function only indicates whether it would be
1000  /// valid to apply this schema to the prim. It has no bearing on whether
1001  /// calling ApplyAPI will be successful or not.
1002  template <typename SchemaType>
1003  bool CanApplyAPI(const TfToken &instanceName,
1004  std::string *whyNot = nullptr) const {
1006  "Provided type must derive UsdAPISchemaBase.");
1008  "Provided type must not be UsdAPISchemaBase.");
1009  static_assert(SchemaType::schemaKind == UsdSchemaKind::MultipleApplyAPI,
1010  "Provided schema type must be a multiple apply API schema.");
1011 
1012  const UsdSchemaRegistry::SchemaInfo *schemaInfo =
1013  UsdSchemaRegistry::FindSchemaInfo<SchemaType>();
1014  if (!schemaInfo) {
1015  TF_CODING_ERROR("Class '%s' is not correctly registered with the "
1016  "UsdSchemaRegistry as a schema type. The schema may need to be "
1017  "regenerated.",
1018  TfType::Find<SchemaType>().GetTypeName().c_str());
1019  return false;
1020  }
1021  return _CanApplyMultipleApplyAPI(*schemaInfo, instanceName, whyNot);
1022  }
1023 
1024  /// This is an overload of \ref CanApplyAPI that takes a TfType
1025  /// \p schemaType .
1026  USD_API
1027  bool CanApplyAPI(const TfType& schemaType,
1028  std::string *whyNot = nullptr) const;
1029 
1030  /// This is an overload of
1031  /// \ref CanApplyAPI(const TfToken &, std::string *) const "CanApplyAPI"
1032  /// with \p instanceName that takes a TfType \p schemaType .
1033  USD_API
1034  bool CanApplyAPI(const TfType& schemaType,
1035  const TfToken& instanceName,
1036  std::string *whyNot = nullptr) const;
1037 
1038  /// This is an overload of \ref CanApplyAPI that takes a \p schemaIdentifier
1039  /// to determine the schema type.
1040  USD_API
1041  bool CanApplyAPI(const TfToken& schemaIdentifier,
1042  std::string *whyNot = nullptr) const;
1043 
1044  /// This is an overload of
1045  /// \ref CanApplyAPI(const TfToken &, std::string *) const "CanApplyAPI"
1046  /// with \p instanceName that takes a \p schemaIdentifier to determine the
1047  /// schema type.
1048  USD_API
1049  bool CanApplyAPI(const TfToken& schemaIdentifier,
1050  const TfToken& instanceName,
1051  std::string *whyNot = nullptr) const;
1052 
1053  /// This is an overload of \ref CanApplyAPI that takes a \p schemaFamily and
1054  /// \p schemaVersion to determine the schema type.
1055  USD_API
1056  bool CanApplyAPI(const TfToken& schemaFamily,
1057  UsdSchemaVersion schemaVersion,
1058  std::string *whyNot = nullptr) const;
1059 
1060  /// This is an overload of
1061  /// \ref CanApplyAPI(const TfToken &, std::string *) const "CanApplyAPI"
1062  /// with \p instanceName that takes a \p schemaFamily and \p schemaVersion
1063  /// to determine the schema type.
1064  USD_API
1065  bool CanApplyAPI(const TfToken& schemaFamily,
1066  UsdSchemaVersion schemaVersion,
1067  const TfToken& instanceName,
1068  std::string *whyNot = nullptr) const;
1069 
1070  /// @}
1071 
1072  /// \name ApplyAPI
1073  ///
1074  /// @{
1075 
1076  /// Applies a __single-apply__ API schema with the given C++ type
1077  /// \p SchemaType to this prim in the current edit target.
1078  ///
1079  /// This information is stored by adding the API schema's name token to the
1080  /// token-valued, listOp metadata \em apiSchemas on this prim.
1081  ///
1082  /// Returns true upon success or if the API schema is already applied in
1083  /// the current edit target.
1084  ///
1085  /// An error is issued and false returned for any of the following
1086  /// conditions:
1087  /// \li this prim is not a valid prim for editing
1088  /// \li this prim is valid, but cannot be reached or overridden in the
1089  /// current edit target
1090  /// \li the schema name cannot be added to the apiSchemas listOp metadata
1091  template <typename SchemaType>
1092  bool ApplyAPI() const {
1094  "Provided type must derive UsdAPISchemaBase.");
1096  "Provided type must not be UsdAPISchemaBase.");
1097  static_assert(SchemaType::schemaKind == UsdSchemaKind::SingleApplyAPI,
1098  "Provided schema type must be a single apply API schema.");
1099 
1100  const UsdSchemaRegistry::SchemaInfo *schemaInfo =
1101  UsdSchemaRegistry::FindSchemaInfo<SchemaType>();
1102  if (!schemaInfo) {
1103  TF_CODING_ERROR("Class '%s' is not correctly registered with the "
1104  "UsdSchemaRegistry as a schema type. The schema may need to be "
1105  "regenerated.",
1106  TfType::Find<SchemaType>().GetTypeName().c_str());
1107  return false;
1108  }
1109  return _ApplySingleApplyAPI(*schemaInfo);
1110  }
1111 
1112  /// Applies a __multiple-apply__ API schema with the given C++ type
1113  /// \p SchemaType and instance name \p instanceName to this prim in the
1114  /// current edit target.
1115  ///
1116  /// This information is stored in the token-valued, listOp metadata
1117  /// \em apiSchemas on this prim. For example, if SchemaType is
1118  /// 'UsdCollectionAPI' and \p instanceName is 'plasticStuff', the name
1119  /// 'CollectionAPI:plasticStuff' is added to the 'apiSchemas' listOp
1120  /// metadata.
1121  ///
1122  /// Returns true upon success or if the API schema is already applied with
1123  /// this \p instanceName in the current edit target.
1124  ///
1125  /// An error is issued and false returned for any of the following
1126  /// conditions:
1127  /// \li \p instanceName is empty
1128  /// \li this prim is not a valid prim for editing
1129  /// \li this prim is valid, but cannot be reached or overridden in the
1130  /// current edit target
1131  /// \li the schema name cannot be added to the apiSchemas listOp metadata
1132  template <typename SchemaType>
1133  bool ApplyAPI(const TfToken &instanceName) const {
1135  "Provided type must derive UsdAPISchemaBase.");
1137  "Provided type must not be UsdAPISchemaBase.");
1138  static_assert(SchemaType::schemaKind == UsdSchemaKind::MultipleApplyAPI,
1139  "Provided schema type must be a multiple apply API schema.");
1140 
1141  const UsdSchemaRegistry::SchemaInfo *schemaInfo =
1142  UsdSchemaRegistry::FindSchemaInfo<SchemaType>();
1143  if (!schemaInfo) {
1144  TF_CODING_ERROR("Class '%s' is not correctly registered with the "
1145  "UsdSchemaRegistry as a schema type. The schema may need to be "
1146  "regenerated.",
1147  TfType::Find<SchemaType>().GetTypeName().c_str());
1148  return false;
1149  }
1150  return _ApplyMultipleApplyAPI(*schemaInfo, instanceName);
1151  }
1152 
1153  /// This is an overload of \ref ApplyAPI that takes a TfType \p schemaType .
1154  USD_API
1155  bool ApplyAPI(const TfType& schemaType) const;
1156 
1157  /// This is an overload of \ref ApplyAPI(const TfToken &) const "ApplyAPI"
1158  /// with \p instanceName that takes a TfType \p schemaType .
1159  USD_API
1160  bool ApplyAPI(const TfType& schemaType,
1161  const TfToken& instanceName) const;
1162 
1163  /// This is an overload of \ref ApplyAPI that takes a \p schemaIdentifier
1164  /// to determine the schema type.
1165  USD_API
1166  bool ApplyAPI(const TfToken& schemaIdentifier) const;
1167 
1168  /// This is an overload of \ref ApplyAPI(const TfToken &) const "ApplyAPI"
1169  /// with \p instanceName that takes a \p schemaIdentifier to determine the
1170  /// schema type.
1171  USD_API
1172  bool ApplyAPI(const TfToken& schemaIdentifier,
1173  const TfToken& instanceName) const;
1174 
1175  /// This is an overload of \ref ApplyAPI that takes a \p schemaFamily and
1176  /// \p schemaVersion to determine the schema type.
1177  USD_API
1178  bool ApplyAPI(const TfToken& schemaFamily,
1179  UsdSchemaVersion schemaVersion) const;
1180 
1181  /// This is an overload of \ref ApplyAPI(const TfToken &) const "ApplyAPI"
1182  /// with \p instanceName that takes a \p schemaFamily and \p schemaVersion
1183  /// to determine the schema type.
1184  USD_API
1185  bool ApplyAPI(const TfToken& schemaFamily,
1186  UsdSchemaVersion schemaVersion,
1187  const TfToken& instanceName) const;
1188 
1189  /// @}
1190 
1191  /// \name RemoveAPI
1192  ///
1193  /// @{
1194 
1195  /// Removes a __single-apply__ API schema with the given C++ type
1196  /// \p SchemaType from this prim in the current edit target.
1197  ///
1198  /// This is done by removing the API schema's name token from the
1199  /// token-valued, listOp metadata \em apiSchemas on this prim as well as
1200  /// authoring an explicit deletion of schema name from the listOp.
1201  ///
1202  /// Returns true upon success or if the API schema is already deleted in
1203  /// the current edit target.
1204  ///
1205  /// An error is issued and false returned for any of the following
1206  /// conditions:
1207  /// \li this prim is not a valid prim for editing
1208  /// \li this prim is valid, but cannot be reached or overridden in the
1209  /// current edit target
1210  /// \li the schema name cannot be deleted in the apiSchemas listOp metadata
1211  template <typename SchemaType>
1212  bool RemoveAPI() const {
1214  "Provided type must derive UsdAPISchemaBase.");
1216  "Provided type must not be UsdAPISchemaBase.");
1217  static_assert(SchemaType::schemaKind == UsdSchemaKind::SingleApplyAPI,
1218  "Provided schema type must be a single apply API schema.");
1219 
1220  const UsdSchemaRegistry::SchemaInfo *schemaInfo =
1221  UsdSchemaRegistry::FindSchemaInfo<SchemaType>();
1222  if (!schemaInfo) {
1223  TF_CODING_ERROR("Class '%s' is not correctly registered with the "
1224  "UsdSchemaRegistry as a schema type. The schema may need to be "
1225  "regenerated.",
1226  TfType::Find<SchemaType>().GetTypeName().c_str());
1227  return false;
1228  }
1229  return _RemoveSingleApplyAPI(*schemaInfo);
1230  }
1231 
1232  /// Removes a __multiple-apply__ API schema with the given C++ type
1233  /// 'SchemaType' and instance name \p instanceName from this prim in the
1234  /// current edit target.
1235  ///
1236  /// This is done by removing the instanced schema name token from the
1237  /// token-valued, listOp metadata \em apiSchemas on this prim as well as
1238  /// authoring an explicit deletion of the name from the listOp. For example,
1239  /// if SchemaType is 'UsdCollectionAPI' and \p instanceName is
1240  /// 'plasticStuff', the name 'CollectionAPI:plasticStuff' is deleted
1241  /// from the 'apiSchemas' listOp metadata.
1242  ///
1243  /// Returns true upon success or if the API schema with this \p instanceName
1244  /// is already deleted in the current edit target.
1245  ///
1246  /// An error is issued and false returned for any of the following
1247  /// conditions:
1248  /// \li \p instanceName is empty
1249  /// \li this prim is not a valid prim for editing
1250  /// \li this prim is valid, but cannot be reached or overridden in the
1251  /// current edit target
1252  /// \li the schema name cannot be deleted in the apiSchemas listOp metadata
1253  template <typename SchemaType>
1254  bool RemoveAPI(const TfToken &instanceName) const {
1256  "Provided type must derive UsdAPISchemaBase.");
1258  "Provided type must not be UsdAPISchemaBase.");
1259  static_assert(SchemaType::schemaKind == UsdSchemaKind::MultipleApplyAPI,
1260  "Provided schema type must be a multiple apply API schema.");
1261 
1262  const UsdSchemaRegistry::SchemaInfo *schemaInfo =
1263  UsdSchemaRegistry::FindSchemaInfo<SchemaType>();
1264  if (!schemaInfo) {
1265  TF_CODING_ERROR("Class '%s' is not correctly registered with the "
1266  "UsdSchemaRegistry as a schema type. The schema may need to be "
1267  "regenerated.",
1268  TfType::Find<SchemaType>().GetTypeName().c_str());
1269  return false;
1270  }
1271  return _RemoveMultipleApplyAPI(*schemaInfo, instanceName);
1272  }
1273 
1274  /// This is an overload of \ref RemoveAPI that takes a TfType \p schemaType .
1275  USD_API
1276  bool RemoveAPI(const TfType& schemaType) const;
1277 
1278  /// This is an overload of \ref RemoveAPI(const TfToken &) const "RemoveAPI"
1279  /// with \p instanceName that takes a TfType \p schemaType .
1280  USD_API
1281  bool RemoveAPI(const TfType& schemaType,
1282  const TfToken& instanceName) const;
1283 
1284  /// This is an overload of \ref RemoveAPI that takes a \p schemaIdentifier
1285  /// to determine the schema type.
1286  USD_API
1287  bool RemoveAPI(const TfToken& schemaIdentifier) const;
1288 
1289  /// This is an overload of \ref RemoveAPI(const TfToken &) const "RemoveAPI"
1290  /// with \p instanceName that takes a \p schemaIdentifier to determine the
1291  /// schema type.
1292  USD_API
1293  bool RemoveAPI(const TfToken& schemaIdentifier,
1294  const TfToken& instanceName) const;
1295 
1296  /// This is an overload of \ref RemoveAPI that takes a \p schemaFamily and
1297  /// \p schemaVersion to determine the schema type.
1298  USD_API
1299  bool RemoveAPI(const TfToken& schemaFamily,
1300  UsdSchemaVersion schemaVersion) const;
1301 
1302  /// This is an overload of \ref RemoveAPI(const TfToken &) const "RemoveAPI"
1303  /// with \p instanceName that takes a \p schemaFamily and \p schemaVersion
1304  /// to determine the schema type.
1305  USD_API
1306  bool RemoveAPI(const TfToken& schemaFamily,
1307  UsdSchemaVersion schemaVersion,
1308  const TfToken& instanceName) const;
1309 
1310  /// @}
1311 
1312  /// Adds the applied API schema name token \p appliedSchemaName to the
1313  /// \em apiSchemas metadata for this prim at the current edit target. For
1314  /// multiple-apply schemas the name token should include the instance name
1315  /// for the applied schema, for example 'CollectionAPI:plasticStuff'.
1316  ///
1317  /// The name will only be added if the \ref SdfListOp "list operation" at
1318  /// the edit target does not already have this applied schema in its
1319  /// explicit, prepended, or appended lists and is always added to the end
1320  /// of either the prepended or explicit items.
1321  ///
1322  /// Returns true upon success or if the API schema is already applied in
1323  /// the current edit target.
1324  ///
1325  /// An error is issued and false returned for any of the following
1326  /// conditions:
1327  /// \li this prim is not a valid prim for editing
1328  /// \li this prim is valid, but cannot be reached or overridden in the
1329  /// current edit target
1330  /// \li the schema name cannot be added to the apiSchemas listOp metadata
1331  ///
1332  /// Unlike ApplyAPI this method does not require that the name token
1333  /// refer to a valid API schema type. ApplyAPI is the preferred method
1334  /// for applying valid API schemas.
1335  USD_API
1336  bool AddAppliedSchema(const TfToken &appliedSchemaName) const;
1337 
1338  /// Removes the applied API schema name token \p appliedSchemaName from the
1339  /// \em apiSchemas metadata for this prim at the current edit target. For
1340  /// multiple-apply schemas the name token should include the instance name
1341  /// for the applied schema, for example 'CollectionAPI:plasticStuff'
1342  ///
1343  /// For an explicit \ref SdfListOp "list operation", this removes the
1344  /// applied schema name from the explicit items list if it was present. For
1345  /// a non-explicit \ref SdfListOp "list operation", this will remove any
1346  /// occurrence of the applied schema name from the prepended and appended
1347  /// item as well as adding it to the deleted items list.
1348  ///
1349  /// Returns true upon success or if the API schema is already deleted in
1350  /// the current edit target.
1351  ///
1352  /// An error is issued and false returned for any of the following
1353  /// conditions:
1354  /// \li this prim is not a valid prim for editing
1355  /// \li this prim is valid, but cannot be reached or overridden in the
1356  /// current edit target
1357  /// \li the schema name cannot be deleted in the apiSchemas listOp metadata
1358  ///
1359  /// Unlike RemoveAPI this method does not require that the name token
1360  /// refer to a valid API schema type. RemoveAPI is the preferred method
1361  /// for removing valid API schemas.
1362  USD_API
1363  bool RemoveAppliedSchema(const TfToken &appliedSchemaName) const;
1364 
1365  // --------------------------------------------------------------------- //
1366  /// \name Prim Children
1367  // --------------------------------------------------------------------- //
1368 
1369  /// Return this prim's direct child named \p name if it has one, otherwise
1370  /// return an invalid UsdPrim. Equivalent to:
1371  /// \code
1372  /// prim.GetStage()->GetPrimAtPath(prim.GetPath().AppendChild(name))
1373  /// \endcode
1374  USD_API
1375  UsdPrim GetChild(const TfToken &name) const;
1376 
1377  /// Return this prim's active, loaded, defined, non-abstract children as an
1378  /// iterable range. Equivalent to:
1379  /// \code
1380  /// GetFilteredChildren(UsdPrimDefaultPredicate)
1381  /// \endcode
1382  ///
1383  /// See \ref Usd_PrimFlags "Prim predicate flags"
1384  /// and #UsdPrimDefaultPredicate for more information.
1385  inline SiblingRange GetChildren() const;
1386 
1387  /// Return all this prim's children as an iterable range.
1388  inline SiblingRange GetAllChildren() const;
1389 
1390  /// Return a subset of all of this prim's children filtered by \p predicate
1391  /// as an iterable range. The \p predicate is generated by combining a
1392  /// series of prim flag terms with either && or || and !.
1393  ///
1394  /// Example usage:
1395  /// \code
1396  /// // Get all active model children.
1397  /// GetFilteredChildren(UsdPrimIsActive && UsdPrimIsModel);
1398  ///
1399  /// // Get all model children that pass the default predicate.
1400  /// GetFilteredChildren(UsdPrimDefaultPredicate && UsdPrimIsModel);
1401  /// \endcode
1402  ///
1403  /// If this prim is an instance, no children will be returned unless
1404  /// #UsdTraverseInstanceProxies is used to allow instance proxies to be
1405  /// returned, or if this prim is itself an instance proxy.
1406  ///
1407  /// See \ref Usd_PrimFlags "Prim predicate flags"
1408  /// and #UsdPrimDefaultPredicate for more information.
1409  inline SiblingRange
1410  GetFilteredChildren(const Usd_PrimFlagsPredicate &predicate) const;
1411 
1412  /// Return the names of the child prims in the order they appear when
1413  /// iterating over GetChildren.
1414  USD_API
1416 
1417  /// Return the names of the child prims in the order they appear when
1418  /// iterating over GetAllChildren.
1419  USD_API
1421 
1422  /// Return the names of the child prims in the order they appear when
1423  /// iterating over GetFilteredChildren(\p predicate).
1424  USD_API
1426  const Usd_PrimFlagsPredicate &predicate) const;
1427 
1428  /// Return this prim's active, loaded, defined, non-abstract descendants as
1429  /// an iterable range. Equivalent to:
1430  /// \code
1431  /// GetFilteredDescendants(UsdPrimDefaultPredicate)
1432  /// \endcode
1433  ///
1434  /// \note This method is not yet available in python, pending some
1435  /// refactoring to make it more feasible.
1436  ///
1437  /// See \ref Usd_PrimFlags "Prim predicate flags" and
1438  /// #UsdPrimDefaultPredicate for more information, UsdStage::Traverse(),
1439  /// and \c UsdPrimRange for more general Stage traversal behaviors.
1440  inline SubtreeRange GetDescendants() const;
1441 
1442  /// Return all this prim's descendants as an iterable range.
1443  ///
1444  /// \note This method is not yet available in python, pending some
1445  /// refactoring to make it more feasible.
1446  ///
1447  /// See \ref Usd_PrimFlags "Prim predicate flags" and
1448  /// #UsdPrimDefaultPredicate for more information, UsdStage::Traverse(),
1449  /// and \c UsdPrimRange for more general Stage traversal behaviors.
1450  inline SubtreeRange GetAllDescendants() const;
1451 
1452  /// Return a subset of all of this prim's descendants filtered by
1453  /// \p predicate as an iterable range. The \p predicate is generated by
1454  /// combining a series of prim flag terms with either && or || and !.
1455  ///
1456  /// Example usage:
1457  /// \code
1458  /// // Get all active model descendants.
1459  /// GetFilteredDescendants(UsdPrimIsActive && UsdPrimIsModel);
1460  ///
1461  /// // Get all model descendants that pass the default predicate.
1462  /// GetFilteredDescendants(UsdPrimDefaultPredicate && UsdPrimIsModel);
1463  /// \endcode
1464  ///
1465  /// If this prim is an instance, no descendants will be returned unless
1466  /// #UsdTraverseInstanceProxies is used to allow instance proxies to be
1467  /// returned, or if this prim is itself an instance proxy.
1468  ///
1469  /// \note This method is not yet available in python, pending some
1470  /// refactoring to make it more feasible.
1471  ///
1472  /// See \ref Usd_PrimFlags "Prim predicate flags" and
1473  /// #UsdPrimDefaultPredicate for more information, UsdStage::Traverse(),
1474  /// and \c UsdPrimRange for more general Stage traversal behaviors.
1475  inline SubtreeRange
1476  GetFilteredDescendants(const Usd_PrimFlagsPredicate &predicate) const;
1477 
1478  /// Return the strongest opinion for the metadata used to reorder children
1479  /// of this prim. Due to how reordering of prim children is composed,
1480  /// this value cannot be relied on to get the actual order of the prim's
1481  /// children. Use GetChidrenNames, GetAllChildrenNames,
1482  /// GetFilteredChildrenNames to get the true child order if needed.
1483  USD_API
1485 
1486  /// Author an opinion for the metadata used to reorder children of this
1487  /// prim at the current EditTarget.
1489  SetMetadata(SdfFieldKeys->PrimOrder, order);
1490  }
1491 
1492  /// Remove the opinion for the metadata used to reorder children of this
1493  /// prim at the current EditTarget.
1494  void ClearChildrenReorder() const {
1495  ClearMetadata(SdfFieldKeys->PrimOrder);
1496  }
1497 
1498 public:
1499  // --------------------------------------------------------------------- //
1500  /// \name Parent & Stage
1501  // --------------------------------------------------------------------- //
1502 
1503  /// Return this prim's parent prim. Return an invalid UsdPrim if this is a
1504  /// root prim.
1505  UsdPrim GetParent() const {
1507  SdfPath proxyPrimPath = _ProxyPrimPath();
1508  Usd_MoveToParent(prim, proxyPrimPath);
1509  return UsdPrim(prim, proxyPrimPath);
1510  }
1511 
1512  /// Return this prim's next active, loaded, defined, non-abstract sibling
1513  /// if it has one, otherwise return an invalid UsdPrim. Equivalent to:
1514  /// \code
1515  /// GetFilteredNextSibling(UsdPrimDefaultPredicate)
1516  /// \endcode
1517  ///
1518  /// See \ref Usd_PrimFlags "Prim predicate flags"
1519  /// and #UsdPrimDefaultPredicate for more information.
1520  USD_API
1521  UsdPrim GetNextSibling() const;
1522 
1523  /// Return this prim's next sibling that matches \p predicate if it has one,
1524  /// otherwise return the invalid UsdPrim.
1525  ///
1526  /// See \ref Usd_PrimFlags "Prim predicate flags"
1527  /// and #UsdPrimDefaultPredicate for more information.
1528  USD_API
1530  const Usd_PrimFlagsPredicate &predicate) const;
1531 
1532  /// Returns true if the prim is the pseudo root.
1533  ///
1534  /// Equivalent to
1535  /// \code
1536  /// prim.GetPath() == SdfPath::AbsoluteRootPath()
1537  /// \endcode
1538  USD_API
1539  bool IsPseudoRoot() const;
1540 
1541  /// Returns the prim at \p path on the same stage as this prim.
1542  /// If path is is relative, it will be anchored to the path of this prim.
1543  /// \sa UsdStage::GetPrimAtPath(const SdfPath&) const
1544  USD_API UsdPrim GetPrimAtPath(const SdfPath& path) const;
1545 
1546  /// Returns the object at \p path on the same stage as this prim.
1547  /// If path is is relative, it will be anchored to the path of this prim.
1548  /// \sa UsdStage::GetObjectAtPath(const SdfPath&) const
1550 
1551  /// Returns the property at \p path on the same stage as this prim.
1552  /// If path is relative, it will be anchored to the path of this prim.
1553  ///
1554  /// \note There is no guarantee that this method returns a property on
1555  /// this prim. This is only guaranteed if path is a purely relative
1556  /// property path.
1557  /// \sa GetProperty(const TfToken&) const
1558  /// \sa UsdStage::GetPropertyAtPath(const SdfPath&) const
1560 
1561  /// Returns the attribute at \p path on the same stage as this prim.
1562  /// If path is relative, it will be anchored to the path of this prim.
1563  ///
1564  /// \note There is no guarantee that this method returns an attribute on
1565  /// this prim. This is only guaranteed if path is a purely relative
1566  /// property path.
1567  /// \sa GetAttribute(const TfToken&) const
1568  /// \sa UsdStage::GetAttributeAtPath(const SdfPath&) const
1570 
1571  /// Returns the relationship at \p path on the same stage as this prim.
1572  /// If path is relative, it will be anchored to the path of this prim.
1573  ///
1574  /// \note There is no guarantee that this method returns a relationship on
1575  /// this prim. This is only guaranteed if path is a purely relative
1576  /// property path.
1577  /// \sa GetRelationship(const TfToken&) const
1578  /// \sa UsdStage::GetRelationshipAtPath(const SdfPath&) const
1580 
1581  // --------------------------------------------------------------------- //
1582  /// \name Variants
1583  // --------------------------------------------------------------------- //
1584 
1585  /// Return a UsdVariantSets object representing all the VariantSets
1586  /// present on this prim.
1587  ///
1588  /// The returned object also provides the API for adding new VariantSets
1589  /// to the prim.
1590  USD_API
1592 
1593  /// Retrieve a specifically named VariantSet for editing or constructing
1594  /// a UsdEditTarget.
1595  ///
1596  /// This is a shortcut for
1597  /// \code
1598  /// prim.GetVariantSets().GetVariantSet(variantSetName)
1599  /// \endcode
1600  USD_API
1601  UsdVariantSet GetVariantSet(const std::string& variantSetName) const;
1602 
1603  /// Return true if this prim has any authored VariantSets.
1604  ///
1605  /// \note this connotes only the *existence* of one of more VariantSets,
1606  /// *not* that such VariantSets necessarily contain any variants or
1607  /// variant opinions.
1608  USD_API
1609  bool HasVariantSets() const;
1610 
1611  // --------------------------------------------------------------------- //
1612  /// \name Attributes
1613  // --------------------------------------------------------------------- //
1614 
1615  /// Author scene description for the attribute named \a attrName at the
1616  /// current EditTarget if none already exists. Return a valid attribute if
1617  /// scene description was successfully authored or if it already existed,
1618  /// return invalid attribute otherwise. Note that the supplied \a typeName
1619  /// and \a custom arguments are only used in one specific case. See below
1620  /// for details.
1621  ///
1622  /// Suggested use:
1623  /// \code
1624  /// if (UsdAttribute myAttr = prim.CreateAttribute(...)) {
1625  /// // success.
1626  /// }
1627  /// \endcode
1628  ///
1629  /// To call this, GetPrim() must return a valid prim.
1630  ///
1631  /// - If a spec for this attribute already exists at the current edit
1632  /// target, do nothing.
1633  ///
1634  /// - If a spec for \a attrName of a different spec type (e.g. a
1635  /// relationship) exists at the current EditTarget, issue an error.
1636  ///
1637  /// - If \a name refers to a builtin attribute according to the prim's
1638  /// definition, author an attribute spec with required metadata from the
1639  /// definition.
1640  ///
1641  /// - If \a name refers to a builtin relationship, issue an error.
1642  ///
1643  /// - If there exists an absolute strongest authored attribute spec for
1644  /// \a attrName, author an attribute spec at the current EditTarget by
1645  /// copying required metadata from that strongest spec.
1646  ///
1647  /// - If there exists an absolute strongest authored relationship spec for
1648  /// \a attrName, issue an error.
1649  ///
1650  /// - Otherwise author an attribute spec at the current EditTarget using
1651  /// the provided \a typeName and \a custom for the required metadata fields.
1652  /// Note that these supplied arguments are only ever used in this particular
1653  /// circumstance, in all other cases they are ignored.
1654  USD_API
1655  UsdAttribute
1656  CreateAttribute(const TfToken& name,
1657  const SdfValueTypeName &typeName,
1658  bool custom,
1659  SdfVariability variability = SdfVariabilityVarying) const;
1660  /// \overload
1661  /// Create a custom attribute with \p name, \p typeName and \p variability.
1662  USD_API
1663  UsdAttribute
1664  CreateAttribute(const TfToken& name,
1665  const SdfValueTypeName &typeName,
1666  SdfVariability variability = SdfVariabilityVarying) const;
1667 
1668  /// \overload
1669  /// This overload of CreateAttribute() accepts a vector of name components
1670  /// used to construct a \em namespaced property name. For details, see
1671  /// \ref Usd_Ordering
1672  USD_API
1674  const std::vector<std::string> &nameElts,
1675  const SdfValueTypeName &typeName,
1676  bool custom,
1677  SdfVariability variability = SdfVariabilityVarying) const;
1678  /// \overload
1679  /// Create a custom attribute with \p nameElts, \p typeName, and
1680  /// \p variability.
1681  USD_API
1683  const std::vector<std::string> &nameElts,
1684  const SdfValueTypeName &typeName,
1685  SdfVariability variability = SdfVariabilityVarying) const;
1686 
1687  /// Like GetProperties(), but exclude all relationships from the result.
1688  USD_API
1689  std::vector<UsdAttribute> GetAttributes() const;
1690 
1691  /// Like GetAttributes(), but exclude attributes without authored scene
1692  /// description from the result. See UsdProperty::IsAuthored().
1693  USD_API
1694  std::vector<UsdAttribute> GetAuthoredAttributes() const;
1695 
1696  /// Return a UsdAttribute with the name \a attrName. The attribute
1697  /// returned may or may not \b actually exist so it must be checked for
1698  /// validity. Suggested use:
1699  ///
1700  /// \code
1701  /// if (UsdAttribute myAttr = prim.GetAttribute("myAttr")) {
1702  /// // myAttr is safe to use.
1703  /// // Edits to the owning stage requires subsequent validation.
1704  /// } else {
1705  /// // myAttr was not defined/authored
1706  /// }
1707  /// \endcode
1708  USD_API
1709  UsdAttribute GetAttribute(const TfToken& attrName) const;
1710 
1711  /// Return true if this prim has an attribute named \p attrName, false
1712  /// otherwise.
1713  USD_API
1714  bool HasAttribute(const TfToken& attrName) const;
1715 
1716  /// Search the prim subtree rooted at this prim for attributes for which
1717  /// \p predicate returns true, collect their connection source paths and
1718  /// return them in an arbitrary order. If \p recurseOnSources is true,
1719  /// act as if this function was invoked on the connected prims and owning
1720  /// prims of connected properties also and return the union.
1721  USD_API
1724  std::function<bool (UsdAttribute const &)> const &pred = nullptr,
1725  bool recurseOnSources = false) const;
1726 
1727  // --------------------------------------------------------------------- //
1728  /// \name Relationships
1729  // --------------------------------------------------------------------- //
1730 
1731  /// Author scene description for the relationship named \a relName at the
1732  /// current EditTarget if none already exists. Return a valid relationship
1733  /// if scene description was successfully authored or if it already existed,
1734  /// return an invalid relationship otherwise.
1735  ///
1736  /// Suggested use:
1737  /// \code
1738  /// if (UsdRelationship myRel = prim.CreateRelationship(...)) {
1739  /// // success.
1740  /// }
1741  /// \endcode
1742  ///
1743  /// To call this, GetPrim() must return a valid prim.
1744  ///
1745  /// - If a spec for this relationship already exists at the current edit
1746  /// target, do nothing.
1747  ///
1748  /// - If a spec for \a relName of a different spec type (e.g. an
1749  /// attribute) exists at the current EditTarget, issue an error.
1750  ///
1751  /// - If \a name refers to a builtin relationship according to the prim's
1752  /// definition, author a relationship spec with required metadata from the
1753  /// definition.
1754  ///
1755  /// - If \a name refers to a builtin attribute, issue an error.
1756  ///
1757  /// - If there exists an absolute strongest authored relationship spec for
1758  /// \a relName, author a relationship spec at the current EditTarget by
1759  /// copying required metadata from that strongest spec.
1760  ///
1761  /// - If there exists an absolute strongest authored attribute spec for \a
1762  /// relName, issue an error.
1763  ///
1764  /// - Otherwise author a uniform relationship spec at the current
1765  /// EditTarget, honoring \p custom .
1766  ///
1767  USD_API
1769  bool custom=true) const;
1770 
1771  /// \overload
1772  /// This overload of CreateRelationship() accepts a vector of
1773  /// name components used to construct a \em namespaced property name.
1774  /// For details, see \ref Usd_Ordering
1775  USD_API
1776  UsdRelationship CreateRelationship(const std::vector<std::string> &nameElts,
1777  bool custom=true)
1778  const;
1779 
1780  /// Like GetProperties(), but exclude all attributes from the result.
1781  USD_API
1782  std::vector<UsdRelationship> GetRelationships() const;
1783 
1784  /// Like GetRelationships(), but exclude relationships without authored
1785  /// scene description from the result. See UsdProperty::IsAuthored().
1786  USD_API
1787  std::vector<UsdRelationship> GetAuthoredRelationships() const;
1788 
1789  /// Return a UsdRelationship with the name \a relName. The relationship
1790  /// returned may or may not \b actually exist so it must be checked for
1791  /// validity. Suggested use:
1792  ///
1793  /// \code
1794  /// if (UsdRelationship myRel = prim.GetRelationship("myRel")) {
1795  /// // myRel is safe to use.
1796  /// // Edits to the owning stage requires subsequent validation.
1797  /// } else {
1798  /// // myRel was not defined/authored
1799  /// }
1800  /// \endcode
1801  USD_API
1802  UsdRelationship GetRelationship(const TfToken& relName) const;
1803 
1804  /// Return true if this prim has a relationship named \p relName, false
1805  /// otherwise.
1806  USD_API
1807  bool HasRelationship(const TfToken& relName) const;
1808 
1809  /// Search the prim subtree rooted at this prim for relationships for which
1810  /// \p predicate returns true, collect their target paths and return them in
1811  /// an arbitrary order. If \p recurseOnTargets is true, act as if this
1812  /// function was invoked on the targeted prims and owning prims of targeted
1813  /// properties also (but not of forwarding relationships) and return the
1814  /// union.
1815  USD_API
1818  std::function<bool (UsdRelationship const &)> const &pred = nullptr,
1819  bool recurseOnTargets = false) const;
1820 
1821  // --------------------------------------------------------------------- //
1822  /// \name Payload Authoring
1823  /// \deprecated
1824  /// This API is now deprecated. Please use the HasAuthoredPayloads and the
1825  /// UsdPayloads API returned from GetPayloads() to query and author payloads
1826  /// instead.
1827  /// @{
1828  // --------------------------------------------------------------------- //
1829 
1830  /// \deprecated
1831  /// Clears the payload at the current EditTarget for this prim. Return false
1832  /// if the payload could not be cleared.
1833  USD_API
1834  bool ClearPayload() const;
1835 
1836  /// \deprecated
1837  /// Return true if a payload is present on this prim.
1838  ///
1839  /// \sa \ref Usd_Payloads
1840  USD_API
1841  bool HasPayload() const;
1842 
1843  /// \deprecated
1844  /// Author payload metadata for this prim at the current edit
1845  /// target. Return true on success, false if the value could not be set.
1846  ///
1847  /// \sa \ref Usd_Payloads
1848  USD_API
1849  bool SetPayload(const SdfPayload& payload) const;
1850 
1851  /// \deprecated
1852  /// Shorthand for SetPayload(SdfPayload(assetPath, primPath)).
1853  USD_API
1854  bool SetPayload(
1855  const std::string& assetPath, const SdfPath& primPath) const;
1856 
1857  /// \deprecated
1858  /// Shorthand for SetPayload(SdfPayload(layer->GetIdentifier(),
1859  /// primPath)).
1860  USD_API
1861  bool SetPayload(const SdfLayerHandle& layer, const SdfPath& primPath) const;
1862 
1863  /// @}
1864 
1865  // --------------------------------------------------------------------- //
1866  /// \name Payloads, Load and Unload
1867  // --------------------------------------------------------------------- //
1868 
1869  /// Return a UsdPayloads object that allows one to add, remove, or
1870  /// mutate payloads <em>at the currently set UsdEditTarget</em>.
1871  ///
1872  /// While the UsdPayloads object has no methods for \em listing the
1873  /// currently authored payloads on a prim, one can use a
1874  /// UsdPrimCompositionQuery to query the payload arcs that are composed
1875  /// by this prim.
1876  USD_API
1877  UsdPayloads GetPayloads() const;
1878 
1879  /// Return true if this prim has any authored payloads.
1880  USD_API
1881  bool HasAuthoredPayloads() const;
1882 
1883  /// Load this prim, all its ancestors, and by default all its descendants.
1884  /// If \p loadPolicy is UsdLoadWithoutDescendants, then load only this prim
1885  /// and its ancestors.
1886  ///
1887  /// See UsdStage::Load for additional details.
1888  USD_API
1890 
1891  /// Unloads this prim and all its descendants.
1892  ///
1893  /// See UsdStage::Unload for additional details.
1894  USD_API
1895  void Unload() const;
1896 
1897  // --------------------------------------------------------------------- //
1898  /// \name References
1899  // --------------------------------------------------------------------- //
1900 
1901  /// Return a UsdReferences object that allows one to add, remove, or
1902  /// mutate references <em>at the currently set UsdEditTarget</em>.
1903  ///
1904  /// While the UsdReferences object has no methods for \em listing the
1905  /// currently authored references on a prim, one can use a
1906  /// UsdPrimCompositionQuery to query the reference arcs that are composed
1907  /// by this prim.
1908  ///
1909  /// \sa UsdPrimCompositionQuery::GetDirectReferences
1910  USD_API
1911  UsdReferences GetReferences() const;
1912 
1913  /// Return true if this prim has any authored references.
1914  USD_API
1915  bool HasAuthoredReferences() const;
1916 
1917  // --------------------------------------------------------------------- //
1918  /// \name Inherits
1919  // --------------------------------------------------------------------- //
1920 
1921  /// Return a UsdInherits object that allows one to add, remove, or
1922  /// mutate inherits <em>at the currently set UsdEditTarget</em>.
1923  ///
1924  /// While the UsdInherits object has no methods for \em listing the
1925  /// currently authored inherits on a prim, one can use a
1926  /// UsdPrimCompositionQuery to query the inherits arcs that are composed
1927  /// by this prim.
1928  ///
1929  /// \sa UsdPrimCompositionQuery::GetDirectInherits
1930  USD_API
1931  UsdInherits GetInherits() const;
1932 
1933  /// Return true if this prim has any authored inherits.
1934  USD_API
1935  bool HasAuthoredInherits() const;
1936 
1937  // --------------------------------------------------------------------- //
1938  /// \name Specializes
1939  // --------------------------------------------------------------------- //
1940 
1941  /// Return a UsdSpecializes object that allows one to add, remove, or
1942  /// mutate specializes <em>at the currently set UsdEditTarget</em>.
1943  ///
1944  /// While the UsdSpecializes object has no methods for \em listing the
1945  /// currently authored specializes on a prim, one can use a
1946  /// UsdPrimCompositionQuery to query the specializes arcs that are composed
1947  /// by this prim.
1948  USD_API
1950 
1951  /// Returns true if this prim has any authored specializes.
1952  USD_API
1953  bool HasAuthoredSpecializes() const;
1954 
1955  // --------------------------------------------------------------------- //
1956  /// \name Instancing
1957  /// See \ref Usd_Page_ScenegraphInstancing for more details.
1958  /// @{
1959  // --------------------------------------------------------------------- //
1960 
1961  /// Return true if this prim has been marked as instanceable.
1962  ///
1963  /// Note that this is not the same as IsInstance(). A prim may return
1964  /// true for IsInstanceable() and false for IsInstance() if this prim
1965  /// is not active or if it is marked as instanceable but contains no
1966  /// instanceable data.
1967  bool IsInstanceable() const {
1968  bool instanceable = false;
1969  return GetMetadata(SdfFieldKeys->Instanceable, &instanceable) &&
1970  instanceable;
1971  }
1972 
1973  /// Author 'instanceable' metadata for this prim at the current
1974  /// EditTarget.
1975  bool SetInstanceable(bool instanceable) const {
1976  return SetMetadata(SdfFieldKeys->Instanceable, instanceable);
1977  }
1978 
1979  /// Remove the authored 'instanceable' opinion at the current EditTarget.
1980  /// Do nothing if there is no authored opinion.
1981  bool ClearInstanceable() const {
1982  return ClearMetadata(SdfFieldKeys->Instanceable);
1983  }
1984 
1985  /// Return true if this prim has an authored opinion for 'instanceable',
1986  /// false otherwise.
1988  return HasAuthoredMetadata(SdfFieldKeys->Instanceable);
1989  }
1990 
1991  /// Return true if this prim is an instance of a prototype, false
1992  /// otherwise.
1993  ///
1994  /// If this prim is an instance, calling GetPrototype() will return
1995  /// the UsdPrim for the corresponding prototype prim.
1996  bool IsInstance() const { return _Prim()->IsInstance(); }
1997 
1998  /// Return true if this prim is an instance proxy, false otherwise.
1999  /// An instance proxy prim represents a descendent of an instance
2000  /// prim.
2001  bool IsInstanceProxy() const {
2003  }
2004 
2005  /// Return true if the given \p path identifies a prototype prim,
2006  /// false otherwise.
2007  ///
2008  /// This function will return false for prim and property paths
2009  /// that are descendants of a prototype prim path.
2010  ///
2011  /// \sa IsPathInPrototype
2012  USD_API
2013  static bool IsPrototypePath(const SdfPath& path);
2014 
2015  /// Return true if the given \p path identifies a prototype prim or
2016  /// a prim or property descendant of a prototype prim, false otherwise.
2017  ///
2018  /// \sa IsPrototypePath
2019  USD_API
2020  static bool IsPathInPrototype(const SdfPath& path);
2021 
2022  /// Return true if this prim is an instancing prototype prim,
2023  /// false otherwise.
2024  ///
2025  /// \sa IsInPrototype
2026  bool IsPrototype() const { return _Prim()->IsPrototype(); }
2027 
2028  /// Return true if this prim is a prototype prim or a descendant
2029  /// of a prototype prim, false otherwise.
2030  ///
2031  /// \sa IsPrototype
2032  bool IsInPrototype() const {
2033  return (IsInstanceProxy() ?
2035  }
2036 
2037  /// If this prim is an instance, return the UsdPrim for the corresponding
2038  /// prototype. Otherwise, return an invalid UsdPrim.
2039  USD_API
2040  UsdPrim GetPrototype() const;
2041 
2042  /// If this prim is an instance proxy, return the UsdPrim for the
2043  /// corresponding prim in the instance's prototype. Otherwise, return an
2044  /// invalid UsdPrim.
2046  if (IsInstanceProxy()) {
2047  return UsdPrim(_Prim(), SdfPath());
2048  }
2049  return UsdPrim();
2050  }
2051 
2052  /// If this prim is a prototype prim, returns all prims that are instances
2053  /// of this prototype. Otherwise, returns an empty vector.
2054  ///
2055  /// Note that this function will return prims in prototypes for instances
2056  /// that are nested beneath other instances.
2057  USD_API
2058  std::vector<UsdPrim> GetInstances() const;
2059  /// @}
2060 
2061  // --------------------------------------------------------------------- //
2062  /// \name Composition Structure
2063  /// @{
2064  // --------------------------------------------------------------------- //
2065 
2066  /// Return the cached prim index containing all sites that can contribute
2067  /// opinions to this prim.
2068  ///
2069  /// The prim index can be used to examine the composition arcs and scene
2070  /// description sites that can contribute to this prim's property and
2071  /// metadata values.
2072  ///
2073  /// The prim index returned by this function is optimized and may not
2074  /// include sites that do not contribute opinions to this prim. Use
2075  /// UsdPrim::ComputeExpandedPrimIndex to compute a prim index that includes
2076  /// all possible sites that could contribute opinions.
2077  ///
2078  /// This prim index will be empty for prototype prims. This ensures that
2079  /// these prims do not provide any attribute or metadata values. For all
2080  /// other prims in prototypes, this is the prim index that was chosen to
2081  /// be shared with all other instances. In either case, the prim index's
2082  /// path will not be the same as the prim's path.
2083  ///
2084  /// Prim indexes may be invalidated by changes to the UsdStage and cannot
2085  /// detect if they are expired. Clients should avoid keeping copies of the
2086  /// prim index across such changes, which include scene description
2087  /// changes or changes to load state.
2088  const PcpPrimIndex &GetPrimIndex() const { return _Prim()->GetPrimIndex(); }
2089 
2090  /// Compute the prim index containing all sites that could contribute
2091  /// opinions to this prim.
2092  ///
2093  /// This function is similar to UsdPrim::GetPrimIndex. However, the
2094  /// returned prim index includes all sites that could possibly contribute
2095  /// opinions to this prim, not just the sites that currently do so. This is
2096  /// useful in certain situations; for example, this could be used to
2097  /// generate a list of sites where clients could make edits to affect this
2098  /// prim, or for debugging purposes.
2099  ///
2100  /// For all prims in prototypes, including the prototype prim itself, this
2101  /// is the expanded version of the prim index that was chosen to be shared
2102  /// with all other instances. Thus, the prim index's path will not be the
2103  /// same as the prim's path. Note that this behavior deviates slightly from
2104  /// UsdPrim::GetPrimIndex which always returns an empty prim index for the
2105  /// prototype prim itself.
2106  ///
2107  /// This function may be relatively slow, since it will recompute the prim
2108  /// index on every call. Clients should prefer UsdPrim::GetPrimIndex unless
2109  /// the additional site information is truly needed.
2110  USD_API
2112 
2113  /// Creates and returns a resolve target that, when passed to a
2114  /// UsdAttributeQuery for one of this prim's attributes, causes value
2115  /// resolution to only consider weaker specs up to and including the spec
2116  /// that would be authored for this prim when using the given \p editTarget.
2117  ///
2118  /// If the edit target would not affect any specs that could contribute to
2119  /// this prim, a null resolve target is returned.
2120  USD_API
2122  const UsdEditTarget &editTarget) const;
2123 
2124  /// Creates and returns a resolve target that, when passed to a
2125  /// UsdAttributeQuery for one of this prim's attributes, causes value
2126  /// resolution to only consider specs that are stronger than the spec
2127  /// that would be authored for this prim when using the given \p editTarget.
2128  ///
2129  /// If the edit target would not affect any specs that could contribute to
2130  /// this prim, a null resolve target is returned.
2131  USD_API
2133  const UsdEditTarget &editTarget) const;
2134 
2135  /// @}
2136 
2137 private:
2138  friend class UsdObject;
2141  friend class UsdProperty;
2142  friend class UsdSchemaBase;
2143  friend class UsdAPISchemaBase;
2144  friend class UsdStage;
2145  friend class UsdPrimRange;
2146  friend class Usd_PrimData;
2150 
2151  // Prim constructor.
2152  UsdPrim(const Usd_PrimDataHandle &primData,
2153  const SdfPath &proxyPrimPath)
2154  : UsdObject(primData, proxyPrimPath) { }
2155 
2156  // General constructor.
2157  UsdPrim(UsdObjType objType,
2158  const Usd_PrimDataHandle &prim,
2159  const SdfPath &proxyPrimPath,
2160  const TfToken &propName)
2161  : UsdObject(objType, prim, proxyPrimPath, propName) {}
2162 
2163  // Helper to make a sibling range.
2164  inline SiblingRange
2165  _MakeSiblingRange(const Usd_PrimFlagsPredicate &pred) const;
2166 
2167  // Helper to make a range of descendants.
2168  inline SubtreeRange
2169  _MakeDescendantsRange(const Usd_PrimFlagsPredicate &pred) const;
2170 
2171  // Helper to make a vector of properties from names.
2172  std::vector<UsdProperty>
2173  _MakeProperties(const TfTokenVector &names) const;
2174 
2175  // Helper for Get{Authored}{PropertyNames,Properties}
2176  TfTokenVector _GetPropertyNames(
2177  bool onlyAuthored,
2178  bool applyOrder=true,
2179  const PropertyPredicateFunc &predicate={}) const;
2180 
2181  // Helper for Get(Authored)PropertiesInNamespace.
2182  std::vector<UsdProperty>
2183  _GetPropertiesInNamespace(const std::string &namespaces,
2184  bool onlyAuthored) const;
2185 
2186  // Helper for Get(Authored)Attributes.
2187  std::vector<UsdAttribute>
2188  _GetAttributes(bool onlyAuthored, bool applyOrder=false) const;
2189 
2190  // Helper for Get(Authored)Relationships.
2191  std::vector<UsdRelationship>
2192  _GetRelationships(bool onlyAuthored, bool applyOrder=false) const;
2193 
2194  friend const PcpPrimIndex &Usd_PrimGetSourcePrimIndex(const UsdPrim&);
2195  // Return a const reference to the source PcpPrimIndex for this prim.
2196  //
2197  // For all prims in prototypes (which includes the prototype prim itself),
2198  // this is the prim index for the instance that was chosen to serve
2199  // as the prototype for all other instances. This prim index will not
2200  // have the same path as the prim's path.
2201  //
2202  // This is a private helper but is also wrapped out to Python
2203  // for testing and debugging purposes.
2204  const PcpPrimIndex &_GetSourcePrimIndex() const
2205  { return _Prim()->GetSourcePrimIndex(); }
2206 
2207  // Helper function for MakeResolveTargetUpToEditTarget and
2208  // MakeResolveTargetStrongerThanEditTarget.
2210  _MakeResolveTargetFromEditTarget(
2211  const UsdEditTarget &editTarget,
2212  bool makeAsStrongerThan) const;
2213 };
2214 
2215 #ifdef doxygen
2216 
2217 /// Forward traversal iterator of sibling ::UsdPrim s. This is a
2218 /// standard-compliant iterator that may be used with STL algorithms, etc.
2219 class UsdPrimSiblingIterator {
2220 public:
2221  /// Iterator value type.
2222  typedef UsdPrim value_type;
2223  /// Iterator reference type, in this case the same as \a value_type.
2224  typedef value_type reference;
2225  /// Iterator difference type.
2226  typedef unspecified-integral-type difference_type;
2227  /// Dereference.
2228  reference operator*() const;
2229  /// Indirection.
2230  unspecified-type operator->() const;
2231  /// Postincrement.
2232  UsdPrimSiblingIterator &operator++();
2233  /// Preincrement.
2234  UsdPrimSiblingIterator operator++(int);
2235 private:
2236  /// Equality.
2237  friend bool operator==(const UsdPrimSiblingIterator &lhs,
2238  const UsdPrimSiblingIterator &rhs);
2239  /// Inequality.
2240  friend bool operator!=(const UsdPrimSiblingIterator &lhs,
2241  const UsdPrimSiblingIterator &rhs);
2242 };
2243 
2244 /// Forward iterator range of sibling ::UsdPrim s. This range type contains a
2245 /// pair of UsdPrimSiblingIterator s, denoting a half-open range of UsdPrim
2246 /// siblings. It provides a subset of container-like API, such as begin(),
2247 /// end(), front(), empty(), etc.
2248 class UsdPrimSiblingRange {
2249 public:
2250  /// Iterator type.
2251  typedef UsdPrimSiblingIterator iterator;
2252  /// Const iterator type.
2253  typedef UsdPrimSiblingIterator const_iterator;
2254  /// Iterator difference type.
2255  typedef unspecified-integral-type difference_type;
2256  /// Iterator value_type.
2258  /// Iterator reference_type.
2259  typedef iterator::reference reference;
2260 
2261  /// Construct with a pair of iterators.
2264 
2265  /// Construct/convert from another compatible range type.
2266  template <class ForwardRange>
2267  UsdPrimSiblingRange(const ForwardRange &r);
2268 
2269  /// Assign from another compatible range type.
2270  template <class ForwardRange>
2271  UsdPrimSiblingRange &operator=(const ForwardRange &r);
2272 
2273  /// First iterator.
2274  iterator begin() const;
2275 
2276  /// Past-the-end iterator.
2277  iterator end() const;
2278 
2279  /// Return !empty().
2280  operator unspecified_bool_type() const;
2281 
2282  /// Equality compare.
2283  bool equal(const iterator_range&) const;
2284 
2285  /// Return *begin(). This range must not be empty.
2286  reference front() const;
2287 
2288  /// Advance this range's begin iterator.
2289  iterator_range& advance_begin(difference_type n);
2290 
2291  /// Advance this range's end iterator.
2292  iterator_range& advance_end(difference_type n);
2293 
2294  ; /// Return begin() == end().
2295  bool empty() const;
2296 
2297 private:
2298  /// Equality comparison.
2299  friend bool operator==(const UsdPrimSiblingRange &lhs,
2300  const UsdPrimSiblingRange &rhs);
2301  /// Inequality comparison.
2302  friend bool operator!=(const UsdPrimSiblingRange &lhs,
2303  const UsdPrimSiblingRange &rhs);
2304 };
2305 
2306 #else
2307 
2308 // Sibling iterator class. Converts ref to weak and filters according to a
2309 // supplied predicate.
2310 class UsdPrimSiblingIterator : public hboost::iterator_adaptor<
2311  UsdPrimSiblingIterator, // crtp base.
2312  const Usd_PrimData *, // base iterator.
2313  UsdPrim, // value type.
2314  hboost::forward_traversal_tag, // traversal
2315  UsdPrim> // reference type.
2316 {
2317 public:
2318  // Default ctor.
2320 
2321 private:
2322  friend class UsdPrim;
2323 
2324  // Constructor used by Prim.
2325  UsdPrimSiblingIterator(const base_type &i, const SdfPath& proxyPrimPath,
2326  const Usd_PrimFlagsPredicate &predicate)
2327  : iterator_adaptor_(i)
2328  , _proxyPrimPath(proxyPrimPath)
2329  , _predicate(predicate) {
2330  // Need to advance iterator to first matching element.
2331  if (base() && !Usd_EvalPredicate(_predicate, base(), _proxyPrimPath))
2332  increment();
2333  }
2334 
2335  // Core implementation invoked by iterator_adaptor.
2337  bool equal(const UsdPrimSiblingIterator &other) const {
2338  return base() == other.base() &&
2339  _proxyPrimPath == other._proxyPrimPath &&
2340  _predicate == other._predicate;
2341  }
2342 
2343  void increment() {
2344  base_type &base = base_reference();
2345  if (Usd_MoveToNextSiblingOrParent(base, _proxyPrimPath, _predicate)) {
2346  base = nullptr;
2347  _proxyPrimPath = SdfPath();
2348  }
2349  }
2350 
2351  reference dereference() const {
2352  return UsdPrim(base(), _proxyPrimPath);
2353  }
2354 
2355  SdfPath _proxyPrimPath;
2356  Usd_PrimFlagsPredicate _predicate;
2357 };
2358 
2359 // Typedef iterator range.
2360 typedef hboost::iterator_range<UsdPrimSiblingIterator> UsdPrimSiblingRange;
2361 
2362 // Inform TfIterator it should feel free to make copies of the range type.
2363 template <>
2365  UsdPrimSiblingRange> : std::true_type {};
2366 template <>
2368  const UsdPrimSiblingRange> : std::true_type {};
2369 
2370 #endif // doxygen
2371 
2372 
2373 UsdPrimSiblingRange
2375 {
2376  return _MakeSiblingRange(
2378 }
2379 
2380 UsdPrimSiblingRange
2382 {
2384 }
2385 
2386 UsdPrimSiblingRange
2388 {
2390 }
2391 
2392 // Helper to make a sibling range.
2394 UsdPrim::_MakeSiblingRange(const Usd_PrimFlagsPredicate &pred) const {
2395  Usd_PrimDataConstPtr firstChild = get_pointer(_Prim());
2396  SdfPath firstChildPath = _ProxyPrimPath();
2397  if (!Usd_MoveToChild(firstChild, firstChildPath, pred)) {
2398  firstChild = nullptr;
2399  firstChildPath = SdfPath();
2400  }
2401 
2402  return SiblingRange(
2403  SiblingIterator(firstChild, firstChildPath, pred),
2404  SiblingIterator(nullptr, SdfPath(), pred));
2405 }
2406 
2407 #ifdef doxygen
2408 
2409 /// Forward traversal iterator of sibling ::UsdPrim s. This is a
2410 /// standard-compliant iterator that may be used with STL algorithms, etc.
2411 class UsdPrimSubtreeIterator {
2412 public:
2413  /// Iterator value type.
2414  typedef UsdPrim value_type;
2415  /// Iterator reference type, in this case the same as \a value_type.
2416  typedef value_type reference;
2417  /// Iterator difference type.
2418  typedef unspecified-integral-type difference_type;
2419  /// Dereference.
2420  reference operator*() const;
2421  /// Indirection.
2422  unspecified-type operator->() const;
2423  /// Postincrement.
2424  UsdPrimSubtreeIterator &operator++();
2425  /// Preincrement.
2426  UsdPrimSubtreeIterator operator++(int);
2427 private:
2428  /// Equality.
2429  friend bool operator==(const UsdPrimSubtreeIterator &lhs,
2430  const UsdPrimSubtreeIterator &rhs);
2431  /// Inequality.
2432  friend bool operator!=(const UsdPrimSubtreeIterator &lhs,
2433  const UsdPrimSubtreeIterator &rhs);
2434 };
2435 
2436 /// Forward iterator range of sibling ::UsdPrim s. This range type contains a
2437 /// pair of UsdPrimSubtreeIterator s, denoting a half-open range of UsdPrim
2438 /// siblings. It provides a subset of container-like API, such as begin(),
2439 /// end(), front(), empty(), etc.
2440 class UsdPrimSubtreeRange {
2441 public:
2442  /// Iterator type.
2443  typedef UsdPrimSubtreeIterator iterator;
2444  /// Const iterator type.
2445  typedef UsdPrimSubtreeIterator const_iterator;
2446  /// Iterator difference type.
2447  typedef unspecified-integral-type difference_type;
2448  /// Iterator value_type.
2450  /// Iterator reference_type.
2451  typedef iterator::reference reference;
2452 
2453  /// Construct with a pair of iterators.
2456 
2457  /// Construct/convert from another compatible range type.
2458  template <class ForwardRange>
2459  UsdPrimSubtreeRange(const ForwardRange &r);
2460 
2461  /// Assign from another compatible range type.
2462  template <class ForwardRange>
2463  UsdPrimSubtreeRange &operator=(const ForwardRange &r);
2464 
2465  /// First iterator.
2466  iterator begin() const;
2467 
2468  /// Past-the-end iterator.
2469  iterator end() const;
2470 
2471  /// Return !empty().
2472  operator unspecified_bool_type() const;
2473 
2474  /// Equality compare.
2475  bool equal(const iterator_range&) const;
2476 
2477  /// Return *begin(). This range must not be empty.
2478  reference front() const;
2479 
2480  /// Advance this range's begin iterator.
2481  iterator_range& advance_begin(difference_type n);
2482 
2483  /// Advance this range's end iterator.
2484  iterator_range& advance_end(difference_type n);
2485 
2486  /// Return begin() == end().
2487  bool empty() const;
2488 
2489 private:
2490  /// Equality comparison.
2491  friend bool operator==(const UsdPrimSubtreeRange &lhs,
2492  const UsdPrimSubtreeRange &rhs);
2493  /// Inequality comparison.
2494  friend bool operator!=(const UsdPrimSubtreeRange &lhs,
2495  const UsdPrimSubtreeRange &rhs);
2496 };
2497 
2498 #else
2499 
2500 // Subtree iterator class. Converts ref to weak and filters according to a
2501 // supplied predicate.
2502 class UsdPrimSubtreeIterator : public hboost::iterator_adaptor<
2503  UsdPrimSubtreeIterator, // crtp base.
2504  const Usd_PrimData *, // base iterator.
2505  UsdPrim, // value type.
2506  hboost::forward_traversal_tag, // traversal
2507  UsdPrim> // reference type.
2508 {
2509 public:
2510  // Default ctor.
2512 
2513 private:
2514  friend class UsdPrim;
2515 
2516  // Constructor used by Prim.
2517  UsdPrimSubtreeIterator(const base_type &i, const SdfPath &proxyPrimPath,
2518  const Usd_PrimFlagsPredicate &predicate)
2519  : iterator_adaptor_(i)
2520  , _proxyPrimPath(proxyPrimPath)
2521  , _predicate(predicate) {
2522  // Need to advance iterator to first matching element.
2523  base_type &base = base_reference();
2524  if (base && !Usd_EvalPredicate(_predicate, base, _proxyPrimPath)) {
2525  if (Usd_MoveToNextSiblingOrParent(base, _proxyPrimPath,
2526  _predicate)) {
2527  base = nullptr;
2528  _proxyPrimPath = SdfPath();
2529  }
2530  }
2531  }
2532 
2533  // Core implementation invoked by iterator_adaptor.
2535  bool equal(const UsdPrimSubtreeIterator &other) const {
2536  return base() == other.base() &&
2537  _proxyPrimPath == other._proxyPrimPath &&
2538  _predicate == other._predicate;
2539  }
2540 
2541  void increment() {
2542  base_type &base = base_reference();
2543  if (!Usd_MoveToChild(base, _proxyPrimPath, _predicate)) {
2544  while (Usd_MoveToNextSiblingOrParent(base, _proxyPrimPath,
2545  _predicate)) {}
2546  }
2547  }
2548 
2549  reference dereference() const {
2550  return UsdPrim(base(), _proxyPrimPath);
2551  }
2552 
2553  SdfPath _proxyPrimPath;
2554  Usd_PrimFlagsPredicate _predicate;
2555 };
2556 
2557 // Typedef iterator range.
2558 typedef hboost::iterator_range<UsdPrimSubtreeIterator> UsdPrimSubtreeRange;
2559 
2560 // Inform TfIterator it should feel free to make copies of the range type.
2561 template <>
2563  UsdPrimSubtreeRange> : std::true_type {};
2564 template <>
2566  const UsdPrimSubtreeRange> : std::true_type {};
2567 
2568 #endif // doxygen
2569 
2570 UsdPrimSubtreeRange
2572 {
2573  return _MakeDescendantsRange(
2575 }
2576 
2577 UsdPrimSubtreeRange
2579 {
2581 }
2582 
2583 UsdPrimSubtreeRange
2585 {
2587 }
2588 
2589 // Helper to make a sibling range.
2591 UsdPrim::_MakeDescendantsRange(const Usd_PrimFlagsPredicate &pred) const {
2592  Usd_PrimDataConstPtr firstChild = get_pointer(_Prim());
2593  SdfPath firstChildPath = _ProxyPrimPath();
2594  Usd_PrimDataConstPtr endChild = firstChild;
2595  SdfPath endChildPath = firstChildPath;
2596  if (Usd_MoveToChild(firstChild, firstChildPath, pred)) {
2597  while (Usd_MoveToNextSiblingOrParent(endChild, endChildPath, pred)) {}
2598  }
2599 
2600  return SubtreeRange(
2601  SubtreeIterator(firstChild, firstChildPath, pred),
2602  SubtreeIterator(endChild, endChildPath, pred));
2603 }
2604 
2605 
2606 ////////////////////////////////////////////////////////////////////////
2607 // UsdObject methods that require UsdPrim be a complete type.
2608 
2609 inline UsdPrim
2611 {
2612  return UsdPrim(_prim, _proxyPrimPath);
2613 }
2614 
2616 
2617 #endif // PXR_USD_USD_PRIM_H
2618 
bool HasAPIInFamily(UsdSchemaRegistry::VersionPolicy versionPolicy, const TfToken &instanceName) const
Definition: prim.h:848
USD_API SdfPrimSpecHandleVector GetPrimStack() const
UsdLoadPolicy
Definition: common.h:116
void Usd_MoveToParent(PrimDataPtr &p, SdfPath &proxyPrimPath)
Definition: primData.h:515
friend class UsdPrim
Definition: prim.h:2322
bool HasAPI() const
Definition: prim.h:700
USD_API SdfPathVector FindAllRelationshipTargetPaths(std::function< bool(UsdRelationship const &)> const &pred=nullptr, bool recurseOnTargets=false) const
USD_API UsdResolveTarget MakeResolveTargetStrongerThanEditTarget(const UsdEditTarget &editTarget) const
UsdObjType
Definition: object.h:51
Usd_PrimFlagsPredicate Usd_CreatePredicateForTraversal(const PrimDataPtr &p, const SdfPath &proxyPrimPath, Usd_PrimFlagsPredicate pred)
Definition: primData.h:495
#define USD_API
Definition: api.h:40
friend class hboost::iterator_core_access
Definition: prim.h:2534
hboost::math::policies::policy< hboost::math::policies::domain_error< hboost::math::policies::ignore_error >, hboost::math::policies::pole_error< hboost::math::policies::ignore_error >, hboost::math::policies::overflow_error< hboost::math::policies::ignore_error >, hboost::math::policies::underflow_error< hboost::math::policies::ignore_error >, hboost::math::policies::denorm_error< hboost::math::policies::ignore_error >, hboost::math::policies::rounding_error< hboost::math::policies::ignore_error >, hboost::math::policies::evaluation_error< hboost::math::policies::ignore_error >, hboost::math::policies::indeterminate_result_error< hboost::math::policies::ignore_error > > policy
Definition: SYS_MathCbrt.h:35
USD_API bool HasAuthoredPayloads() const
Return true if this prim has any authored payloads.
UsdPrim GetPrimInPrototype() const
Definition: prim.h:2045
USD_API UsdVariantSet GetVariantSet(const std::string &variantSetName) const
USD_API std::vector< UsdAttribute > GetAuthoredAttributes() const
Single Apply API schema.
bool CanApplyAPI(std::string *whyNot=nullptr) const
Definition: prim.h:969
SiblingRange GetChildren() const
Definition: prim.h:2387
USD_API bool HasAuthoredInherits() const
Return true if this prim has any authored inherits.
USD_API bool HasAuthoredMetadata(const TfToken &key) const
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
GLsizei const GLfloat * value
Definition: glcorearb.h:824
SdfSpecifier GetSpecifier() const
Return this prim's composed specifier.
Definition: prim.h:171
bool HasAuthoredInstanceable() const
Definition: prim.h:1987
USD_API bool IsInFamily(const TfToken &schemaFamily) const
UsdPrimSiblingRange SiblingRange
Definition: prim.h:140
void ClearPropertyOrder() const
Definition: prim.h:458
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
USD_API UsdRelationship CreateRelationship(const TfToken &relName, bool custom=true) const
#define TF_CODING_ERROR
static USD_API bool IsPathInPrototype(const SdfPath &path)
SiblingRange GetAllChildren() const
Return all this prim's children as an iterable range.
Definition: prim.h:2381
const UsdPrimTypeInfo & GetPrimTypeInfo() const
Definition: prim.h:159
USD_API UsdAttribute CreateAttribute(const TfToken &name, const SdfValueTypeName &typeName, bool custom, SdfVariability variability=SdfVariabilityVarying) const
bool IsInstanceProxy() const
Definition: prim.h:2001
SubtreeRange GetAllDescendants() const
Definition: prim.h:2578
USD_API TfTokenVector GetAllChildrenNames() const
USD_API bool HasAuthoredReferences() const
Return true if this prim has any authored references.
void ClearChildrenReorder() const
Definition: prim.h:1494
const UsdPrimDefinition & GetPrimDefinition() const
Definition: prim.h:166
IMATH_HOSTDEVICE constexpr bool equal(T1 a, T2 b, T3 t) IMATH_NOEXCEPT
Definition: ImathFun.h:105
USD_API UsdProperty GetPropertyAtPath(const SdfPath &path) const
USD_API UsdPrim GetPrimAtPath(const SdfPath &path) const
USD_API bool GetVersionIfHasAPIInFamily(const TfToken &schemaFamily, UsdSchemaVersion *schemaVersion) const
bool SetMetadata(const TfToken &key, const T &value) const
Definition: object.h:764
USD_API bool HasProperty(const TfToken &propName) const
USD_API void Load(UsdLoadPolicy policy=UsdLoadWithDescendants) const
USD_API bool RemoveProperty(const TfToken &propName)
bool GetMetadata(const TfToken &key, T *value) const
Definition: object.h:756
USD_API bool ClearMetadata(const TfToken &key) const
uint64 value_type
Definition: GA_PrimCompat.h:29
USD_API bool RemoveAppliedSchema(const TfToken &appliedSchemaName) const
USD_API std::vector< UsdProperty > GetAuthoredProperties(const PropertyPredicateFunc &predicate={}) const
Y * get_pointer(TfWeakPtrFacade< X, Y > const &p)
Definition: weakPtrFacade.h:83
bool HasAPI(const TfToken &instanceName) const
Definition: prim.h:720
USD_API UsdPrim GetPrototype() const
bool IsDefined() const
Definition: prim.h:286
USD_API TfTokenVector GetPropertyNames(const PropertyPredicateFunc &predicate={}) const
USD_API std::vector< UsdProperty > GetProperties(const PropertyPredicateFunc &predicate={}) const
GLenum GLuint GLint GLint layer
Definition: glcorearb.h:1299
friend struct UsdPrim_AttrConnectionFinder
Definition: prim.h:2149
bool IsLoaded() const
Definition: prim.h:270
bool IsActive() const
Definition: prim.h:240
unsigned int UsdSchemaVersion
Schema versions are specified as a single unsigned integer value.
USD_API bool ClearPayload() const
bool IsA() const
Definition: prim.h:550
USD_API SdfPathVector FindAllAttributeConnectionPaths(std::function< bool(UsdAttribute const &)> const &pred=nullptr, bool recurseOnSources=false) const
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
bool IsInFamily(UsdSchemaRegistry::VersionPolicy versionPolicy) const
Definition: prim.h:596
GLdouble n
Definition: glcorearb.h:2008
bool RemoveAPI(const TfToken &instanceName) const
Definition: prim.h:1254
Definition: token.h:87
USD_API UsdProperty GetProperty(const TfToken &propName) const
bool IsGroup() const
Definition: prim.h:279
USD_API bool HasAttribute(const TfToken &attrName) const
USD_API bool HasRelationship(const TfToken &relName) const
USD_API void Unload() const
USD_API TfTokenVector GetFilteredChildrenNames(const Usd_PrimFlagsPredicate &predicate) const
bool Usd_IsInstanceProxy(const PrimDataPtr &p, const SdfPath &proxyPrimPath)
Definition: primData.h:481
USD_API bool HasAuthoredSpecializes() const
Returns true if this prim has any authored specializes.
GLuint GLuint end
Definition: glcorearb.h:475
USD_API UsdReferences GetReferences() const
friend class hboost::iterator_core_access
Definition: prim.h:2336
const SdfPath & GetPrimPath() const
Definition: object.h:218
bool SetInstanceable(bool instanceable) const
Definition: prim.h:1975
USD_API UsdAttribute GetAttributeAtPath(const SdfPath &path) const
bool HasAuthoredActive() const
Definition: prim.h:263
static USD_API bool IsPrototypePath(const SdfPath &path)
void SetPropertyOrder(const TfTokenVector &order) const
Definition: prim.h:452
USD_API bool AddAppliedSchema(const TfToken &appliedSchemaName) const
IMATH_HOSTDEVICE constexpr Color4< T > operator*(S a, const Color4< T > &v) IMATH_NOEXCEPT
Reverse multiplication: S * Color4.
Definition: ImathColor.h:732
GLdouble GLdouble GLint GLint order
Definition: glad.h:2676
USD_API bool SetPayload(const SdfPayload &payload) const
Definition: prim.h:135
bool ApplyAPI(const TfToken &instanceName) const
Definition: prim.h:1133
std::function< bool(const TfToken &propertyName)> PropertyPredicateFunc
Definition: prim.h:306
SdfSpecifier
Definition: types.h:122
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:442
friend struct UsdPrim_RelTargetFinder
Definition: prim.h:2148
hboost::iterator_range< UsdPrimSubtreeIterator > UsdPrimSubtreeRange
Definition: prim.h:78
const SdfPath & _ProxyPrimPath() const
Definition: object.h:734
bool IsAbstract() const
Return true if this prim or any of its ancestors is a class.
Definition: prim.h:282
GLuint const GLchar * name
Definition: glcorearb.h:786
Definition: path.h:291
bool IsPrototype() const
Definition: prim.h:2026
USD_API PcpPrimIndex ComputeExpandedPrimIndex() const
bool HasAuthoredTypeName() const
Return true if a typeName has been authored.
Definition: prim.h:232
USD_API UsdRelationship GetRelationshipAtPath(const SdfPath &path) const
bool ClearInstanceable() const
Definition: prim.h:1981
USD_API TfTokenVector GetAppliedSchemas() const
void SetChildrenReorder(const TfTokenVector &order) const
Definition: prim.h:1488
UsdPrim GetParent() const
Definition: prim.h:1505
USD_API UsdPayloads GetPayloads() const
bool ClearTypeName() const
Definition: prim.h:227
std::vector< class SdfPath > SdfPathVector
A vector of SdfPaths.
Definition: path.h:212
bool Usd_MoveToChild(PrimDataPtr &p, SdfPath &proxyPrimPath, PrimDataPtr end, const Usd_PrimFlagsPredicate &pred)
Definition: primData.h:602
USD_API TfTokenVector GetAuthoredPropertyNames(const PropertyPredicateFunc &predicate={}) const
USD_API UsdInherits GetInherits() const
bool RemoveAPI() const
Definition: prim.h:1212
USD_API UsdPrim GetNextSibling() const
SdfVariability
Definition: types.h:178
USD_API UsdVariantSets GetVariantSets() const
friend class UsdPrim
Definition: prim.h:2514
const Usd_PrimDataHandle & _Prim() const
Definition: object.h:728
UsdPrim GetPrim() const
Definition: prim.h:2610
SubtreeRange GetDescendants() const
Definition: prim.h:2584
USD_API std::vector< UsdRelationship > GetRelationships() const
Like GetProperties(), but exclude all attributes from the result.
bool IsInstance() const
Definition: prim.h:1996
SubtreeRange GetFilteredDescendants(const Usd_PrimFlagsPredicate &predicate) const
Definition: prim.h:2571
USD_API UsdResolveTarget MakeResolveTargetUpToEditTarget(const UsdEditTarget &editTarget) const
USD_API const Usd_PrimFlagsConjunction UsdPrimDefaultPredicate
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
bool ClearActive() const
Definition: prim.h:255
hboost::iterator_range< UsdPrimSiblingIterator > UsdPrimSiblingRange
Definition: prim.h:75
bool ApplyAPI() const
Definition: prim.h:1092
USD_API const Usd_PrimFlagsPredicate UsdPrimAllPrimsPredicate
bool Usd_MoveToNextSiblingOrParent(PrimDataPtr &p, SdfPath &proxyPrimPath, PrimDataPtr end, const Usd_PrimFlagsPredicate &pred)
Definition: primData.h:545
const PcpPrimIndex & GetPrimIndex() const
Definition: prim.h:2088
USD_API std::vector< UsdProperty > GetAuthoredPropertiesInNamespace(const std::vector< std::string > &namespaces) const
bool IsModel() const
Definition: prim.h:274
USD_API TfTokenVector GetPropertyOrder() const
Return the strongest propertyOrder metadata value authored on this prim.
bool IsInstanceable() const
Definition: prim.h:1967
UsdPrimSubtreeIterator SubtreeIterator
Convenience typedefs.
Definition: prim.h:143
USD_API UsdObject GetObjectAtPath(const SdfPath &path) const
USD_API std::vector< UsdRelationship > GetAuthoredRelationships() const
bool HasAPIInFamily(UsdSchemaRegistry::VersionPolicy versionPolicy) const
Definition: prim.h:826
USD_API TfTokenVector GetChildrenNames() const
USD_API UsdSpecializes GetSpecializes() const
const TfToken & GetTypeName() const
Definition: prim.h:218
USD_API std::vector< std::pair< SdfPrimSpecHandle, SdfLayerOffset > > GetPrimStackWithLayerOffsets() const
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
USD_API TfTokenVector GetChildrenReorder() const
USD_API UsdRelationship GetRelationship(const TfToken &relName) const
Definition: type.h:64
USD_API UsdPrim GetChild(const TfToken &name) const
USD_API bool HasVariantSets() const
bool CanApplyAPI(const TfToken &instanceName, std::string *whyNot=nullptr) const
Definition: prim.h:1003
USD_API bool HasAPIInFamily(const TfToken &schemaFamily) const
USD_API std::vector< UsdAttribute > GetAttributes() const
Like GetProperties(), but exclude all relationships from the result.
USD_API std::vector< UsdPrim > GetInstances() const
bool SetTypeName(const TfToken &typeName) const
Author this Prim's typeName at the current EditTarget.
Definition: prim.h:221
GLboolean r
Definition: glcorearb.h:1222
bool operator!=(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:165
#define const
Definition: zconf.h:214
bool SetSpecifier(SdfSpecifier specifier) const
Definition: prim.h:207
USD_API UsdPrim GetFilteredNextSibling(const Usd_PrimFlagsPredicate &predicate) const
USD_API bool GetVersionIfIsInFamily(const TfToken &schemaFamily, UsdSchemaVersion *schemaVersion) const
type
Definition: core.h:1059
UsdPrim()
Construct an invalid prim.
Definition: prim.h:147
bool SetActive(bool active) const
Definition: prim.h:246
USD_API UsdAttribute GetAttribute(const TfToken &attrName) const
bool HasDefiningSpecifier() const
Definition: prim.h:290
USD_API std::vector< UsdProperty > GetPropertiesInNamespace(const std::vector< std::string > &namespaces) const
UsdPrimSubtreeRange SubtreeRange
Definition: prim.h:144
UsdSchemaVersion version
The version number of the schema within its schema family.
USD_API bool HasPayload() const
UsdPrimSiblingIterator SiblingIterator
Convenience typedefs.
Definition: prim.h:139
Multiple Apply API Schema.
Load a prim plus all its descendants.
Definition: common.h:118
bool IsInPrototype() const
Definition: prim.h:2032
SiblingRange GetFilteredChildren(const Usd_PrimFlagsPredicate &predicate) const
Definition: prim.h:2374
friend const PcpPrimIndex & Usd_PrimGetSourcePrimIndex(const UsdPrim &)
USD_API bool IsPseudoRoot() const
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:483