Generating New Schema Classes
VERIFIED ON USD VERSION 0.7.4
There are a couple of prerequisites to dealing with schema generation in USD.
- usdGenSchema, our tool for generating C++ classes from a schema.usda file requires the jinja2 template substitution module and argpase modules be installed and available in your python syspath.
- Ensure that you have setup your python environment properly, so it can find USD python modules. We'll refer to the install location of your USD build with USD_INSTALL_ROOT, this is determined in the build with the cmake flag, -DCMAKE_INSTALL_PREFIX.
|PYTHONPATH||This is a path list which Python uses to find modules.||$PYTHONPATH:USD_INSTALL_ROOT/lib/python/|
For more information see our page on Advanced Build Configuration.
The files used in this tutorial are available in USD/extras/usd/examples/usdSchemaExamples/. The objective of this tutorial is to introduce the user to various types of schema classes and to provide instructions for generating, compiling and using them. For a detailed description of schema classes and the various options that usdGenSchema provides for customizing them, see API documentation for generating schemas
What is a Schema Class?
A schema class is simply a container of a UsdPrim that provides a layer of specific, named API atop the underlying scene graph. USD provides a code generator script called 'usdGenSchema' for creating new schema classes. For more info on the script and all of the options it provides see the references section below.
UsdModel, UsdGeomImageable, UsdGeomMesh etc. are examples of schema classes generated using the script. There are other schemas in USD/pxr/usd/lib/usd under usdGeom, usdRi, usdShade and more!
Types of Schema Classes
copied from the API documentation...
Schema classes are classified into the following two types:
- API schema - An API schema provides an interface to a prim's qualities, but does not specify a typeName for the underlying prim. The prim's qualities include its inheritance structure, attributes, relationships etc. Since it cannot provide a typeName, an API schema is considered to be non-concrete. We are in-process as of 5/15 on establishing a convention that the C++/python class name for API schemas ends in "API". In core USD, UsdModel is an (not-yet-conforming) example of an API schema; UsdRiLookAPI is an example from our RenderMan schema module, which adds/extracts RenderMan-specific shading information from a generic UsdShadeLook-typed prim. Also by convention (with which usdGenSchema can help), the properties that "belong" to an API schema are typically namespaced with the base-name of the schema, camelCased. For example, UsdRiLookAPI::CreateBxdfRel() will create a relationship named riLook:bxdf.
- IsA schema - An IsA schema can impart a typeName to a prim in addition to providing an interface to a prim's qualities. Every IsA schema must derive from the core class UsdTyped, which is the base class for all typed schemas. Furthermore, an IsA schema can be concrete or non-concrete. An IsA schema will be concrete (or instantiable) if its schema declaration provides both a name for the schema (in quotes) and a typeName in the schema.usda file in which it is defined. A non-concrete (abstract) IsA schema provides only a name for the schema, and hence cannot be instantiated; non-concrete schemas exist to serve as super-classes for related sets of concrete IsA schemas. UsdGeomImageable is an example of a non-concrete IsA schema. UsdGeomScope is an example of a concrete, typed IsA schema.
The definition of an IsA schema is published, at runtime, into an introspectable "schema definition registry", which is consulted by core Usd when performing property value resolution (i.e. retrieving a property's value at a given UsdTime). This allows IsA schemas to provide fallback values for their properties, i.e., a value that the property will possess, even when none has been authored. Because the definition registry is keyed by prim typeName, a prim can "be" at most (or IsA) a single type, whereas a prim can host data for any number of API schemas, which cannot provide fallback values.
Although we will not cover it in this tutorial, you can add (and we have for many of the core schemas) custom methods to any generated IsA or API schema that will be preserved if/when you need to re-run usdGenSchema. Custom methods are handy for providing computations, or authoring operations that require coordinated authoring of more than a single value on a property at once.
Schema Generation Prerequisites
The schema generation script 'usdGenSchema' is driven by a USD layer (typically named schema.usda). Every schema.usda layer must meet the following requirements in order for generated code to compile and work with USD core successfully.
- Must specify the libraryName as layer metadata.
- usd/schema.usda must exist in the layer stack, not necessarily as a direct subLayer.
- Schema typenames must be unique across all libraries.
- Attribute names and tokens must be camelCased valid identifiers.
In our examples, we'll use the following as the base layer (or starting point) for creating new schema classes in order to satisfy the first two requirements above.
Example Untyped (Non-Concrete) IsA Schema
A simple untyped IsA schema prim with one attribute and one relationship would look as follows:
Example Typed IsA Schema
The following is an example of a typed IsA schema class. It derives from the untyped </SimplePrim> defined above, specifies a typeName 'ComplexPrim' and adds a string attribute with a fallback value.
Example API Schema
The following is a simple example of an API schema that provides API for manipulating three custom double valued attributes. Note again that API schemas are not allowed to specify a fallback value for the attributes.
All of the above schema classes are available in the schema.usda file in extras/usd/examples/usdSchemaExamples/. You can run usdGenSchema to generate all the necessary files. See below for the list of files generated (or edited if they already exist).
Compiling the Schema Prims
To rebuild the plugin, simply go to the root of your build directory and run.
That should be it. To test that the plugin was installed correctly, create a usd file named Test.usda with the following content:
You should be able to load the above usda file in usdview without warnings or errors.
Using the Schema Classes
The following C++ code loads the above test scene, constructs schema prims and uses the API provided by schema code generation.
The following python code loads the above test scene, constructs schema prims and uses the API provided by schema code generation.