1/*! 2 3\page Usd_Page_GeneratingSchemas Creating New Schema Classes with usdGenSchema 4 5USD provides a code generator script 'usdGenSchema' for creating new schema 6classes. The script is driven by a USD layer (typically named schema.usda) and 7generates the necessary C++ classes and supporting Python code for all the 8schema classes defined in it. 9 10This USD layer must meet the following prerequisites in order for generated code 11to compile and work with USD Core successfully. 12 13 - Must specify the libraryName as layer metadata. 14 - Schema typenames must be unique across all libraries. 15 - Attribute names and tokens must be camelCased valid C/python identifiers, 16 with the allowance that ':' signifies property namespacing. See 17 \ref Usd_OM_UsdProperty and \ref Usd_NameSpacedPropertiesInCodeGen 18 for more information. 19 - usd/schema.usda must exist in the LayerStack, not necessarily as a direct 20 subLayer. 21 22See pxr/usd/lib/usdGeom/schema.usda for an example. 23 24\section Usd_IsAVsAPISchemas IsA Vs. API Schemas 25 26Schema classes can be classified into the following two types: 27 28 - <b>API schema</b> - An API schema provides an interface to a 29 prim's qualities, but does not specify a typeName for the underlying prim. 30 The prim's qualities include its inheritance structure, attributes, 31 relationships etc. Since it cannot provide a typeName, an API schema is 32 considered to be non-concrete. As a convention, the C++/python class name for 33 an API schema must end with "API". In core USD, UsdModelAPI is an example of 34 an API schema; UsdRiMaterialAPI is an example from our RenderMan schema 35 module, which adds/extracts RenderMan-specific shading information from a 36 generic UsdShadeMaterial-typed prim. Also by convention (with which 37 usdGenSchema can help), the properties that "belong" to an API schema are 38 typically namespaced with the base-name of the schema, camelCased. For 39 example, UsdRiMaterialAPI::CreateSurfaceAttr() will create an attribute named 40 outputs:ri:surface. 41 API schemas are classified into the following two sub-types: 42 - <b>Non-applied API schemas</b> - If an API schema only provides an 43 interface to certain core bits of metadata (like UsdModelAPI, which sets 44 model kind and UsdClipsAPI, which sets value-clips related metadata) or 45 if there is no use of recording the application of the API schema on a 46 prim (for the purpose of interchange), we make it a non-applied API 47 schema. Examples of non-applied API schemas include UsdModelAPI, 48 UsdClipsAPI, UsdShadeConnectableAPI and UsdGeomPrimvarsAPI. Typically, 49 non-applied API schemas can apply to any prim-type (eg, UsdClipsAPI) or 50 to a known fixed set of prim types, like in the case of 51 UsdShadeConnectableAPI which is only applicable to types that implement 52 connectability behaviors such as shaders and lights. 53 - <b>Applied API Schemas</b> - If there is a need to record and discover 54 whether an API schema has been applied to a prim, we make it an applied 55 API schema. An applied schema will impart its properties as additional 56 built-in properties on the prim. A public Apply() method is 57 auto-generated for applied API schemas. Once an API schema has been 58 applied to a prim, prim.HasAPI<APISchemaType>() will return 59 true. An applied API schema must be applied to a prim via a call to the 60 Apply() method, for the schema object to evaluate to true when 61 converted to a bool using the explicit bool conversion operator. 62 Examples of applied API schemas include UsdCollectionAPI, 63 UsdGeomModelAPI and UsdGeomMotionAPI. All API schemas must inherit from 64 UsdAPISchemaBase directly and cannot inherit from other schemas. Applied 65 API schemas are further classified into the following two categories: 66 - <b>Single-Apply API Schemas</b> - Applied API schemas that can 67 only be applied as a single instance to a prim. Even though API 68 schemas cannot inherit from other API schemas, single-apply API 69 schemas can include other API schemas as 70 \ref Usd_BuiltinAPISchemas "built-ins". 71 Examples of single-apply API schemas include UsdGeomModelAPI and 72 UsdGeomMotionAPI. 73 - <b>Multiple-Apply API Schemas</b> - Applied API schemas that can 74 be applied multiple times on the same prim with different instance 75 names. For example, UsdCollectionAPI, which must be applied once 76 per collection owned by a prim. Properties instantiated by this 77 API schema are prefixed with the namespace prefix of the schema 78 followed by the instance name. There is specific metadata one 79 authors in schema.usda to identify the prefix for multi-apply 80 schemas, and the properties for a multi-apply schema should 81 be listed without any prefix. 82 83 - <b>IsA schema</b> - An IsA schema can impart a typeName to a prim in 84 addition to providing an interface to a prim's qualities. Every IsA 85 schema must derive from the core class UsdTyped, which is the base class 86 for all typed schemas. Furthermore, an IsA schema can be concrete or 87 non-concrete. An IsA schema will be concrete (or instantiable) if its 88 schema declaration provides both a name for the schema (in quotes) and a 89 typeName in the schema.usda file in which it is defined. A non-concrete 90 (abstract) IsA schema provides only a name for the schema, and hence 91 cannot be instantiated; non-concrete schemas exist to serve as 92 super-classes for related sets of concrete IsA schemas. UsdGeomImageable 93 is an example of a non-concrete IsA schema. UsdGeomScope is an example of 94 a concrete, typed IsA schema. 95 96\note "Instantiable," in this context, means instantiable as a typed prim in 97scene description. The generated classes for all schemas, be they API, 98concrete-typed or non-concrete-typed are always instantiable in C++ or python 99as interface objects through which one can interact with UsdPrim objects. 100 101The definitions of both IsA schemas and applied API schemas are published, at 102runtime, into an introspectable 103\ref Usd_OM_SchemaDefinitionRegistry "schema definition registry", which 104produces the \ref UsdPrimDefinition "prim definitions" consulted by 105core USD when performing property value resolution (i.e. retrieving a property's 106value at a given UsdTimeCode). This allows IsA and applied API schemas to 107provide \em fallback \em values for their properties, that is, a value 108that the property will possess, even when none has been authored. Because a 109prim can only have one typeName, a prim can "be" (IsA) at most a single type, 110but can host data for any number of API schemas. This combination of IsA and 111applied API schemas constitutes the prim's complete type signature and is used 112to construct a single \ref UsdPrimDefinition "prim definition" that provides 113all the built-in properties and fallback values for the prim. 114 115The author of an API schema has to decide on the type of API schema at the time 116of its creation by setting token-valued customData entry 'apiSchemaType' in the 117schema definition. It can be set to one of 'nonApplied', 'singleApply' or 118'multipleApply'. When unspecified, the fallback apiSchemaType for an API schema 119is 'singleApply'. An API schema can only inherit from another compatible API 120schema with matching customData["apiSchemaType"] or from "/APISchemaBase" 121directly. This is enforced by the schema code generation script 'usdGenSchema'. 122 123API schemas and non-concrete typed schemas must not provide a typeName in their 124class declaration in a schema.usda file. 125 126See \ref Usd_ExampleSchema for examples of each type of schema class. 127 128\section Usd_BuiltinAPISchemas Built-in applied API schemas 129 130In some cases an IsA schema may want to have certain API schemas always applied 131to prims of its schema type. To avoid having to manually apply these API schemas 132to all instances of these prim types we provide a few ways to specify built-in 133applied API schemas for IsA schema types. When a prim of an IsA schema type 134with built-in applied API schemas is created, all properties from the API 135schemas will also be built-in properties of the prim. The list of built-in API 136schemas can be queried from the prim type's 137\ref UsdPrimDefinition::GetAppliedAPISchemas "prim definition" and the prim will 138also return true from UsdPrim::HasAPI for all of its built-in API schemas. 139 140Additionally, for some applied API schema types, we may want the application of 141the API schema to additionally apply one or more other API schemas. We also 142provide, through the same mechanisms as we have for IsA schemas, the ability to 143specify built-in applied API schemas for single-apply API schema types. When a 144single-apply API schema with built-in API schemas is applied to a prim (or is 145included as a built-in for another type), all of its built-in API schemas are 146also applied. These built-ins nest, so an API schema can include another 147built-in API schema which itself includes yet another built-in API schema and 148all these be applied when the top level API schema is applied. 149 150\subsection Usd_SchemaDefinedBuiltinAPIs Schema defined built-in APIs 151 152The first and most straightforward way an IsA or single-apply API schema author 153can specify which applied API schemas it wants built-in is by adding them 154through the \em apiSchemas field in their schema definition like so: 155 156\code 157# Example of a concrete, typed (IsA) schema with built-in applied API schemas 158class MyCustomPrim "MyCustomPrim" ( 159 inherits = </Typed> 160 161 # These listed applied API schemas will be built-in to this schema type. 162 apiSchemas = ["ExampleSingleApplyAPI", "ExampleMultiApplyAPI:foo"] 163) { 164 # Example of a default value override for a theoretical property defined in 165 # the API schema instance "ExampleMultiApplyAPI:foo" 166 bool exampleMulti:foo:boolAttr = true 167} 168 169# Example of a single-apply API schema with built-in applied API schemas 170class "MyCustomAPI" ( 171 inherits = </APISchemaBase> 172 173 # These listed applied API schemas will be built-in to this schema type and 174 # will always be applied when this schema is applied. 175 apiSchemas = ["ExampleSingleApplyAPI", "ExampleMultiApplyAPI:foo"] 176) { 177 # Example of a default value override for a theoretical property defined in 178 # the API schema instance "ExampleMultiApplyAPI:foo". This schema will be 179 # stronger when applied than its built-in API schemas and this default value 180 # will be used for the added property. 181 bool exampleMulti:foo:boolAttr = true 182} 183\endcode 184 185The listed API schemas will be built-in to the declared schema type. For IsA 186schemas, derived types of the IsA schema will inherit its built-in API schemas 187(applied API schemas cannot inherit from each other.) Any schema can specify 188overrides to properties that would come from one of its built-in API schemas by 189declaring the property itself. This should be done carefully to avoid breaking 190conformance with the built-in schema itself (like changing the property's type) 191and is typically used for changing the default value for the property. 192\sa \ref Usd_APISchemaStrengthOrdering 193 194\subsection Usd_AutoAppliedAPISchemas Auto applied API schemas 195 196In addition to schemas being able to declare built-in applied API schemas, 197an applied API schema can specify that it should be automatically applied to 198any number of IsA or single-apply API schemas. The primary use case for this is 199when a schema author wants to extend an existing schema with properties from 200their own applied API schema without altering the existing schema itself. 201Specifying the API schema to auto apply can accomplish this goal without having 202to manually apply the API to every prim instance of a schema type (or to every 203prim instance with a specific API schema applied). A concrete example would be a 204renderer providing an API schema for its own specific render properties that can 205then be automatically applied to UsdLux light typed prims when the renderer and 206its API schema are available. 207 208An author of an API schema can specify the IsA and/or single-apply API schemas 209to which it wants to be automatically applied through the 210\em apiSchemaAutoApplyTo field in the API schema definition's customData like 211so: 212 213\code 214# Example of an applied API schema specified to auto apply to both a concrete 215# and an abstract IsA schema as well as another single-apply API schema. 216class "MyCustomAPI" ( 217 inherits = </APISchemaBase> 218 customData = { 219 # These listed IsA and API schemas add this API schema to their built-in 220 # API schemas. 221 token[] apiSchemaAutoApplyTo = [ 222 "MyCustomConcretePrim", "MyCustomAbstractPrim", "MyCustomAPI"] 223 } 224) { 225 int autoApplyApiAttr = 1 226} 227\endcode 228 229The specified schema names in the \em apiSchemaAutoApplyTo field can refer to 230another single-apply API schema and to both abstract and concrete IsA schema 231types. For the IsA schema types, the applied schema will be added to the 232built-in schemas for the listed types as well as for any derived schemas of the 233listed types. Note that this customData field is only supported for single apply 234API schemas as multiple apply API schemas cannot be applied without an instance 235name. 236 237\subsection Usd_PluginAutoAppliedAPISchemas Plugin defined auto applied API schemas 238 239Lastly, it is also possible for plugins to specify additional built-in API 240schemas for other schema types outside of schema generation. This is useful if a 241client desires schema types to have built-in API schemas but doesn't want to 242force this upon all clients by changing the generated schemas themselves. An 243example use case for this would be a client pipeline that wants an available UI 244related API schema applied to all shader prim types as this is not something all 245users of these schemas may necessarily want. 246 247A plugin author can specify their additional built-in API schemas in their 248plugin's plugInfo.json file using the \em AutoApplyAPISchemas metadata like so: 249 250\code 251{ 252 "Plugins": [ 253 { 254 "Info": { 255 "AutoApplyAPISchemas" : { 256 "ExistingSingleApplyAPI": { 257 "apiSchemaAutoApplyTo": [ 258 "ExistingPrimType" 259 ] 260 }, 261 "ExistingMultiApplyAPI:foo": { 262 "apiSchemaAutoApplyTo": [ 263 "ExistingPrimType", "ExistingSingleApplyAPI" 264 ] 265 } 266 } 267 } 268 } 269 ] 270} 271\endcode 272 273The metadata format is a dictionary of API schema names to a list of the schemas 274the plugin wants them to be applied to as a built-in API. Like with the schema 275generated \ref Usd_AutoAppliedAPISchemas "auto apply schemas", the API schemas 276will also be applied to any derived schema types of any listed IsA schemas. 277Multiple apply schemas (in addition to single apply) can also be auto applied 278using this plugin metadata as long as the fully qualified instance name for the 279mulitple apply schema is provided. 280 281\subsection Usd_APISchemaStrengthOrdering Property conflicts and API schema strength ordering 282 283Given that we encourage (or even require in the case of multi apply schemas) the 284use of namespace prefixes for API schema property names, we expect most 285properties defined in API schemas will be unique to the schema. However, there 286will always be the possibility that properties with the same name may be defined 287in multiple API schemas applied to the same prim. To account for this, there is 288a strength ordering for applied API schemas that we use to determine which 289property definition "wins" when more than one API schema can define it. Note 290that in this situation, we do not compose the competing property definitions; 291the entirety of the "winning" property definition is used and any weaker 292definitions are ignored. 293 294Firstly, the strongest opinion for a built-in property in an IsA schema's 295\ref UsdPrimDefinition "prim definition" will always come from the IsA schema 296itself. This is what allows us to override things like property default values 297from a built-in API schema. 298 299Next, any auto applied API schemas, whether defined in the 300\ref Usd_AutoAppliedAPISchemas "API schema's definition" or in a 301\ref Usd_PluginAutoAppliedAPISchemas "plugin's metadata", will be appended to 302the end of the list of built-in applied API schemas for the IsA or single-apply 303API they apply to. Since the built-in schema list is ordered strongest to 304weakest for application, this also means that <b> auto applied schemas will 305always be weaker relative to the built-in API schemas defined in the schema they 306are auto applied to</b>. When more then one API schema is auto applied to the 307same schema type, they are always sorted into alphabetical order by schema name 308before they are appended to the built-in schemas. The alphabetical ordering is 309arbitrary but deterministic as there is no provided way to indicate strength 310ordering between auto applied API schemas. 311 312Lastly, the \ref Usd_SchemaDefinedBuiltinAPIs "built-in schemas" that are 313defined in the apiSchemas metadata of the IsA schema are applied in the order 314they appear in the composed list operation of the apiSchemas field, using a 315depth first expansion of any API schema that itself has included built-in API 316schemas. This list order is strongest to weakest, so property name conflicts 317will prefer a property definition from an API schema earlier in the list. 318 319Also note that any API schemas that are applied to a prim instance in scene 320description will still have a stronger opinion on properties they define that 321are also present as built-in properties from the prim's schema type definition. 322 323\section Usd_SchemaCodeGeneration Schema Code Generation 324 325Simply run the ```usdGenSchema``` command to generate code in the current 326directory for the schema classes defined in the file named 'schema.usda'. 327 328The code generator uses \c jinja2 templates that are installed with USD. 329build. The default schema class templates that ship with USD include the 330following files: 331 332 - <b>schemaClass.h, schemaClass.cpp, wrapSchemaClass.cpp</b>: 333 One set for each class found in schema.usda 334 335 - <b>%tokens.h, tokens.cpp, wrapTokens.cpp</b>: 336 Contains static TfTokens for use with all schema in the library. 337 338 - <b>plugInfo.json</b>: 339 Every Pxr module that contains plugins has one of these. We add a 340 declaration for every generated schema class into this file so that 341 USD core can discover all plugin prim types cheaply and robustly. 342 343 - <b>%api.h</b>: 344 Boilerplate macro definitions for exporting symbols on various platforms. 345 346In addition to the files in schemata and tokens related files, the following 347files are edited by the script: 348 349 - <b>generatedSchema.usda</b>: 350 Processed form of schema definitions that will be consumed at runtime by 351 USD core. 352 353\parblock 354\note usdGenSchema will update existing files in the current directory 355if it detects any differences with the code it generates. Make sure these 356files are editable before running usdGenSchema 357\endparblock 358 359\parblock 360\note usdGenSchema does not update the CMakeLists.txt and module.cpp files, 361even if they are editable. If you have added a new class(es), you must 362add them to these files yourself. 363\endparblock 364 365Various command-line options are available for customizing the code generation 366process. Run ```usdGenSchema --help``` for more details. 367 368\section Usd_NameSpacedPropertiesInCodeGen Namespaced Properties in Code Generation 369 370usdGenSchema also supports the use of namespaced properties for code generation. 371For example, float foo:bar will generate UsdMyClass::GetFooBarAttr() and 372UsdTokens->fooBar (with a value of "foo:bar"). usdGenSchema will raise 373exceptions to avoid naming collisions in the schema API and enforces a 374One-to-One mapping of token identifiers to token values, as shown below. 375 376\code 377class MyClass "MyClass" { 378 # Generates UsdMyClass::GetFooBarAttr() and UsdTokens->fooBar with value 379 # "fooBar" 380 float fooBar 381 382 # ERROR: Naming collision in both API and tokens. Generates 383 # UsdMyClass::GetFooBarAttr() and UsdTokens->fooBar with value "foo:bar" 384 float foo:bar 385 386 # ERROR: Naming collision in tokens. Generates UsdMyClass::GetMyTokenAttr() 387 # and UsdTokens->fooBar with value "foo-bar" 388 token myToken = "foo-bar" (allowedTokens = ["foo-bar"]) 389} 390\endcode 391 392\section Usd_GlobalSchemaProperties Global Schema Properties 393 394Each schema.usda file can contain a \em GLOBAL section like the following to 395provide customizations that apply to all the classes in the module: 396 397\code 398over "GLOBAL" ( 399 customData = { 400 string libraryName = "pxUsdGeom" 401 string libraryPath = "folder/pxUsdGeom" 402 string libraryPrefix = "PxUsdGeom" 403 string tokensPrefix = "PxUsdGeom" 404 dictionary libraryTokens = { 405 dictionary libraryToken1 = {} 406 dictionary libraryToken2 = { 407 string value = "/non-identifier-tokenValue!" 408 string doc = """doc for libraryToken2""" 409 } 410 } 411 bool skipCodeGeneration = true 412 } 413) 414{ 415\endcode 416 417Here's a short description of each datum in the global customData dictionary: 418 419 - \b libraryName - The name of the module into which the schema-generated files 420 will be installed. \b Required! 421 422 - \b libraryPath - The partial path with which to prefix '#include' statements 423 of generated files for this module. For external (non-Pixar) plugins, we 424 recommend setting libraryPath to ".", so that the headers inside src 425 directory are included in the generated files. \b Required unless 426 skipCodeGeneration is true! 427 428 - \b libraryPrefix - The prefix for all generated schema classes in the module. 429 If not specified, falls back to ProperCase(libraryName) 430 431 - \b tokensPrefix - The prefix to use for the tokens class, if it needs to be 432 different from libraryPrefix 433 434 - \b libraryTokens - a place to declare tokens meaningful to the module. 435 These tokens will be included in the module's static tokens. If 436 provided, the "doc" string will be included in the tokens documentation. 437 If provided, the "value" string will be assigned as the token's value; 438 otherwise, the token's value will be its identifier (as a TfToken). 439 440 - \anchor codeless_schema \b skipCodeGeneration - Flag that, when set to 441 true, tells schema generation that it should not generate any C++ code for 442 the classes in this module. We call a schema without any corresponding C++ 443 classes a "codeless schema". Note that if skipCodeGeneration is set to true 444 for a schema module, then any other schema module that includes it will 445 also not generate any code. This is because we don't want to generate C++ 446 code for classes that would possibly inherit from another C++ class that 447 doesn't exist. 448 449\section Usd_PerClassProperties Customizing Per-Class Properties 450 451\code 452class PxHairman "PxHairman" ( 453 customData = { 454 string className = "Hairman" 455 string fileName = "_hairman" 456 string extraIncludes = """ 457#include "pxr/usd/usdGeom/primvar.h" 458""" 459 dictionary extraPlugInfo = { 460 string customString = "metadata" 461 bool customBool = true 462 int customInt = 0 463 dictionary customDict = { 464 string customNestedString = "nested" 465 } 466 } 467 dictionary schemaTokens = { 468 dictionary schemaToken1 = {} 469 dictionary schemaToken2 = { 470 string value = "/non-identifier-tokenValue!" 471 string doc = """doc for schemaToken2""" 472 } 473 } 474 token[] fallbackTypes = ["PrimTypeName1", "PrimTypeName2"] 475 } 476) 477{ 478} 479\endcode 480 481Here's a short description of each datum in the per-class customData dictionary: 482 483 - \b className - If the USD prim typeName for the schema must be different than 484 the un-prefixed class name, then use className customData to provide the 485 class name for the C++ (which will be prefixed) and python schema classes. 486 487 - \b fileName - if specified, will be the base name for the .h and .cpp generated 488 files. If not specified, base name falls back to CamelCase(className) 489 490 - \b extraIncludes - if specified, will add extra include paths for files 491 required by the "custom" section of this class only. Note that this will 492 add includes to the generated header file for the class. If includes 493 are only needed in the generated implementation file(.cpp), 494 one can instead add the header includes to the custom 495 section of the cpp file specifically. 496 497 - \b extraPlugInfo - if specified, the (key, value) pairs in this dictionary 498 will be added as additional metadata for this class in the library's 499 plugInfo.json file. The values in this dictionary must be numeric types, 500 strings, booleans, or dictionaries containing these types. 501 Examples of such extraPlugInfo include 502 _providesUsdShadeConnectableAPIBehavior_, _isUsdShadeContainer_, 503 _requiresUsdShadeEncapsulation_ -- these can be used to configure 504 UsdShadeConnectableAPIBehavior for Typed or API schemas. 505 506 - \b schemaTokens - a place to declare tokens meaningful to the schema. 507 These tokens will be included in the module's static tokens. See docs 508 above for the libraryTokens entry in the global customData dictionary 509 for details about the contents of this dictionary. 510 511 - \b apiSchemaType - must only be specified for an API schema. Defaults to 512 the token 'singleApply', to indicate a single-apply API schema. 513 Can be set to 'nonApplied', to create a non-applied API schema or to 514 "multipleApply" to create a multiple-apply API schema. 515 516 - \b propertyNamespacePrefix - must only be specified on multiple apply API 517 schemas which have properties. This token, alongside the instance name, 518 will be inserted as a prefix to all properties created by this 519 multiple-apply API schema. 520 521 - \b apiSchemaAutoApplyTo - must only be specified on single apply API 522 schemas. This is a token array value that lists the names of typed schemas 523 and other single apply API schemas that this API schema will be 524 automatically applied to when the listed typed schemas are processed by the 525 \ref Usd_OM_SchemaDefinitionRegistry "schema definition registry." 526 527 - \b apiSchemaCanOnlyApplyTo - must only be specified on single and multiple 528 apply API schemas. This is a token array value that, when specified, is used 529 by UsdPrim::CanApplyAPI and the schema's generated CanApply function to 530 limit the prims to which this API schema can be validly applied to only the 531 schema types whose names are in this list. 532 533 - \b apiSchemaAllowedInstanceNames - must only be specified on multiple apply 534 API schemas. This is a token array value that, when specified, is used by 535 UsdPrim::CanApplyAPI and the schema's generated CanApply function to limit 536 the instance names that are valid to use when applying this API schema to 537 only the instance names included in this list. 538 539 - \b apiSchemaInstances - must only be specified on multiple apply API 540 schemas. This is a dictionary value that allows additional custom data 541 to be specified for specific instance names of this multiple apply API 542 schema. This dictionary can map an instance name to another dictionary value 543 containing the custom data fields that will only apply to that instance 544 name. Currently only \em apiSchemaCanOnlyApplyTo custom data can be 545 specified in these per instance name dictionaries and will take precedence 546 over the \em apiSchemaCanOnlyApplyTo custom data (specified for the entire 547 schema type) for that instance name when present. The GridCrittersAPI 548 in the \ref Usd_ExampleSchema "examples section" demonstrates how this can 549 be used. 550 551 - \b fallbackTypes - must only be specified for a concrete typed schema. 552 This is a token array value used to specify the preferred fallback schema 553 types that can be used instead when this schema isn't present. 554 This data is used by UsdStage::WriteFallbackPrimTypes to record, on a stage, 555 the \ref Usd_OM_FallbackPrimTypes "fallback prim types" metadata that USD 556 versions which lack this schema will use to choose a suitable alternative 557 schema type. 558 559\section Usd_CustomizingPerProperty Customizing Per-Property 560 561\code 562ColorFloat[] primvars:displayColor ( 563 customData = { 564 string apiName = "displayColor" 565 } 566) 567\endcode 568 569Here's a short description of each datum in the per-property customData 570dictionary: 571 572 - \b apiName - Schema properties may define an 'apiName' in customData to 573 override the default generated accessor API. For example, the above spec 574 produces GetDisplayColorAttr instead of GetPrimVarsDisplayColorAttr as the 575 attribute accessor. As a special case, if 'apiName' is set to the 576 empty string, then no accessor API will be generated. 577 Note: The actual name of the property as defined on the prim is still 578 primvars:displayColor. 579 - \b apiGetImplementation - Optionally control schema gen behavior for a property's 580 'Get' implementation. Valid values: 581 - \e generated - Generate default header and implementation (Fallback value if unspecified). 582 - \e custom - Generate default header ONLY. User must supply the implementation 583 Custom should be used sparingly, primarily as a tool for API migration 584 Given the performance expectations of Get, it is NOT appropriate to 585 add complicated validation logic in this method. 586 587\section Usd_ExampleSchema Example Schema Classes 588 589\code 590#usda 1.0 591( 592 """ This file describes an example schemata used for code generation using 593 usdGenSchema. 594 """ 595 subLayers = [ 596 # This is mainly needed for definition of UsdTyped. 597 @usd/schema.usda@ 598 ] 599) 600 601over "GLOBAL" ( 602 customData = { 603 string libraryName = "myLib" 604 string libraryPath = "componentName/myLib" 605 dictionary libraryTokens = { 606 dictionary sampleToken = { 607 string doc = "Documentation for sample token." 608 } 609 } 610 } 611) { 612 613} 614 615# Example of a non-concrete IsA schema 616# Note that non-concrete IsA schemas cannot specify a typeName in the class 617# declaration, but they are allowed to provide fallback values for attributes. 618class "MyBaseCustomPrim" ( 619 doc = """Defines a non-instantiable (non-concrete) typed schema that derives 620 from MyCustomPrim. Derived schema classes can inherit from this 621 schema to add (for e.g.) geometric properties.""" 622 623 # IsA schemas should derive from </Typed> or a Schema that derives from 624 # Typed. 625 # 626 # API schemas need not specify inherits. usdGenSchema sets the parent 627 # class for such schemas to UsdSchemaBase. 628 inherits = </Typed> 629 customData = { 630 string className = "MyBasePrim" 631 } 632) { 633 # Some base attributes common to all derived schemas 634 uniform double uniformScale = 1.0 ( 635 doc = "A double valued uniform attribute representing scale." 636 ) 637 638 float3 rotation = (0, 0, 0) ( 639 doc = "A varying 3D vector in floating-pt precision representing rotation." 640 ) 641 642 double3 translation = (0, 0, 0) ( 643 doc = "A varying double valued 3D vector representing translation." 644 ) 645} 646 647# Example of a concrete, typed (IsA) schema 648class MyCustomPrim "MyCustomPrim" ( 649 doc = """Defines a custom typed (IsA) schema prim""" 650 651 inherits = </MyBaseCustomPrim> 652 653 customData = { 654 string className = "MyPrim" 655 customData = { 656 string extraIncludes = """ 657 #include "pxr/base/gf/bbox3d.h" 658 #include "pxr/usd/usdGeom/primvar.h" """ 659 } 660 } 661) { 662 # Attributes with fallback values. 663 asset filePath = @/path/to/default/file@ ( 664 doc = """An asset path valued attribute that points to a file on disk.""" 665 ) 666 667 uniform token axis = "X" ( 668 allowedTokens = ["X", "Y", "Z"] 669 doc = """A token valued attribute representing an axis.""" 670 ) 671 672 matrix4d transform = ((1,0,0,0), (0,1,0,0), (0,0,1,0), (0,0,0,1)) ( 673 doc = """Double-precision transformation matrix, which should encode 674 the entire local transformation for a prim.""") 675 ) 676 677 # Attributes with no fallback values. 678 point3f[] points ( 679 doc = """An attribute representing a list of points in 3D space.""" 680 ) 681 682 string[] strArray ( 683 doc = """A string array valued attribute.""" 684 ) 685 686 string str ( 687 doc = """An int valued attribute.""" 688 ) 689 690 # Relationships 691 rel target ( 692 doc = """A relationship called target that could point to another prim 693 or a property""" 694 ) 695} 696 697# Example API schema that provides an interface for manipulating a specific 698# set of attributes on a prim. 699# 700# API schemas can "declare" and provide access to properties defined by 701# collections of other IsA and API schemas, gathered into one API for 702# convenience. They can also (more commonly, in our use, thus far), define 703# their own properties with their own fallbacks. In this capacity, 704# the convention is to namespace each property with the API's name (camelCased), 705# for easy identification, as well as to help prevent built-in properties from 706# API schemas from unintentionally overriding built-in properties of the IsA 707# schema when applied. 708# For example... 709class "MyParamsAPI" ( 710 inherits = </APISchemaBase> 711 customData = { 712 token apiSchemaType = "singleApply" 713 714 # This is an example of specifying typed schemas that this single apply 715 # schema will be automatically applied to. 716 token[] apiSchemaAutoApplyTo = ["MyCustomPrim", 717 "OutsidePluginCustomPrim"] 718 719 # This is an example of specifying typed schemas that this single apply 720 # API can only be applied to. Specifying this means that the generated 721 # MyParamsAPI::CanApply(prim) and prim.CanApplyAPI<MyParamsAPI>() 722 # will only return true if the prim is one of these listed types. 723 token[] apiSchemaCanOnlyApplyTo = ["MyCustomPrim", 724 "OutsidePluginCustomPrim", 725 "AnotherCustomPrim"] 726 } 727) 728{ 729 double myParams:size ( 730 customData = { 731 string apiName = "size" 732 } 733 doc = "double specifying the size." 734 ) 735 736 uniform int myParams:numSamples ( 737 customData = { 738 string apiName = "numSamples" 739 } 740 doc = "Uniform int specifying the number of samples." 741 ) 742 743 double3 myParams:offset = (0, 0, 0) ( 744 customData = { 745 string apiName = "offset" 746 } 747 doc = "3D offset." 748 ) 749 750 # By default, all properties of IsA and API schemas are considered 751 # "builtin", i.e. not \ref UsdProperty::IsCustom() "custom". However, 752 # one can force a schema property to be considered custom by explicitly 753 # declaring it to be so. 754 custom string info 755} 756 757# Example multiple-apply API that gives an interface to create instances of 758# "critters" on a prim. 759class "GridCrittersAPI" ( 760 inherits = </APISchemaBase> 761 customData = { 762 token apiSchemaType = "multipleApply" 763 token propertyNamespacePrefix = "critter" 764 765 # This is an example of all the ways we can specify how the schema's 766 # generated CanApply and UsdPrim::CanApplyAPI behave for this multiple 767 # apply schema. The following customData specifies that: 768 # 1. GridCrittersAPI::CanApply(prim, instanceName) will return false 769 # if instanceName is anything but "insect" or "rodent" because of 770 # apiSchemaAllowedInstanceNames. 771 # 2. GridCrittersAPI::CanApply(prim, "insect") will only return true 772 # if prim.IsA<MyCustomPrim>() because this is specified in 773 # apiSchemaInstances 774 # 3. GridCrittersAPI::CanApply(prim, "rodent") will only return true 775 # if prim.IsA<MyCustomPrim>() or prim.IsA<AnotherCustomPrim>() 776 # because this is specified in apiSchemaCanOnlyApplyTo and there is 777 # no override in apiSchemaInstances 778 token[] apiSchemaAllowedInstanceNames = ["insect", "rodent"] 779 token[] apiSchemaCanOnlyApplyTo = ["MyCustomPrim", 780 "AnotherCustomPrim"] 781 dictionary apiSchemaInstances = { 782 dictionary insect = { 783 token[] apiSchemaCanOnlyApplyTo = ["MyCustomPrim"] 784 } 785 } 786 } 787) 788{ 789 # this will be instantiated as "critter:<instance name>:xform" 790 matrix4d xform = ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) ) 791 # this will be instantiated as "critter:<instance name>:color" 792 color4f color 793} 794\endcode 795 796See \ref Usd_Page_Datatypes for the list of all data types provided by Sdf. 797 798\section Usd_GeneratedSchemaCustomCode Adding Custom Code To Generated Schemas 799 800Custom code written after the "// --(BEGIN CUSTOM CODE)--" delimiter in the 801generated schema files will be preserved between successive usdGenSchema runs. 802Typically, this will include additional API you may want to provide on your 803schema classes. 804 805\section Usd_SchemaExtensionPhilosophy Impact on Interchange of Creating and Extending Schemas 806 807Coming soon! 808 809*/ 810