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