Specifiers#
What are Specifiers?#
Specifiers in OpenUSD convey the intent for how a prim or a primSpec should be interpreted in the composed scene. The specifier can be one of three values: def
, over
or class
.
How Does It Work?#
def
, which is short for define , defines the prim in the current layer. def
indicates a prim exists and concretely defined on the stage.
The resolved specifier of a prim–essentially, which specifier wins when the composition is completed–determines which stage traversals (like rendering) will visit that prim. Default traversals will only visit defined (def
), non-abstract prims. Abstract prims are those that resolve to the class
specifiers. over
, the weakest specifier, will resolve to either a def
or class
specifier.
over
, which is short for override , holds overrides for opinions that already exist in the composed scene on another layer. The over
will not translate back to the original prim, and is what enables non-destructive editing workflows, such as changing a property of a prim, like its color, in another layer.
A class
prim essentially signals that it is a blueprint. class
prims abstract and contain opinions that are meant to be composed onto other prims. It’s worth noting that class
prims are intended as the target of a reference, payload, inherit, or specialize composition arc or as a relationship target for a PointInstancer. These are concepts we’ll cover in a later lesson.
Prims that resolve to class
specifiers will also be present and composed on a stage, but won’t be visited by default stage traversals, meaning it will be ignored by traversals such as those used for rendering.
Working With Python#
Below is an example of how we can get or set a prim’s specifier using Python.
1# Get a prim’s specifier
2prim.GetSpecifier()
3
4# Set a prim’s specifier
5prim.SetSpecifier(specifier)
It’s helpful to look at USDA files to understand how USD encodes specifiers in a USD layer. In this example, we’re defining a new prim called “Box” with the type Cube and a size
property set to 4
. The def
specifier indicates that box is being concretely defined on the stage.
1def Cube "Box" {
2 double size = 4
3}
The over
specifier sparsely modifies the size
property without defining anything else about the prim; in this case, size
is overriden to have a value of 10
. With an override like this, we may be trusting that the box has been defined in another layer, for example.
1over "Box" {
2 double size = 10
3}
Lastly, we’re authoring a new prim as a class
called "_box"
. This can be used as a reusable template in the USD scene.
1class "_box" {
2 double size = 4
3}
Key Takeaways#
Again, every prim will have a specifier. To have a prim present on the stage and available for processing you would define (def
) that prim. You can use override specifiers, (over
), to hold opinions that will be applied to prims defined in another layer and leverage non-destructive editing workflows, while class specifiers (class
) can be leveraged to set up a set of opinions and properties to be composed by other prims.