Variant Sets Basics#

What are Variant Sets?#

How Does It Work?#

Working With Python#

Examples#

Setup#

Before we begin, let’s create a USD stage using the stage class from the Usd module.

Run the cell below to create a new USD Stage. This will setup a stage that contains a variety of prims of different schemas. We’ll use this content to demonstrate how to build VariantSets in the rest of this lesson.

 1from pxr import Usd, UsdGeom
 2
 3stage: Usd.Stage = create_new_stage("_assets/variant_prims.usda")
 4
 5world: UsdGeom.Xform = UsdGeom.Xform.Define(stage, "/World")
 6stage.SetDefaultPrim(world.GetPrim())
 7
 8box: UsdGeom.Xform = UsdGeom.Xform.Define(stage, world.GetPath().AppendPath("Box"))
 9geo_scope: UsdGeom.Scope = UsdGeom.Scope.Define(stage, box.GetPath().AppendPath("Geometry"))
10
11stage.Save()
12DisplayUSD("_assets/variant_prims.usda", show_usd_code=True)
Loading your model...
_assets/variant_prims.usda
        
    

Example 1: Verifying VariantSets Exist#

A variantSet is like a group of options that you can apply to a single item (called a “prim”). Imagine it as a switch that lets a content creator bundle different choices together. This way, someone using the content later can easily switch between these options or add new ones without changing the original item.

To check if a variantSet exists, use the HasVariantSets() method.

Run the cell below to check if the variantSet exists in the variant_prims.usda we created in the previous cell.

 1from pxr import Usd
 2
 3# Open the USD stage from the specified file:
 4stage = Usd.Stage.Open("_assets/variant_prims.usda")
 5
 6# Get the prim at the specified path:
 7geo_scope = stage.GetPrimAtPath("/World/Box/Geometry")
 8
 9# Print whether the prim has variant sets:
10print(geo_scope.HasVariantSets())
False

Example 2: Adding a VariantSet and Variants#

Variants can hold different settings or details, like properties or metadata, and even entire sections of a scene. A variant is just one specific version within a group called a variantSet. Each variantSet can have one or none of these versions selected in a scene.

To create a variantSet, it needs to have at least one variant in the variantSet.

To get all varaintSets, we would use GetVariantSets().

To add a variantSet, we’d use AddVariantSet().

For adding variants to the variantSet, we would use AddVariant().

A small example on how to use the methods can be found below:

 1from pxr import Usd
 2
 3# Open the USD stage from the specified file:
 4stage = Usd.Stage.Open("_assets/variant_prims.usda")
 5
 6# Get the prim at the specified path:
 7geo_scope = stage.GetPrimAtPath("/World/Box/Geometry")
 8
 9# Get the "shapes" variant set for the geometry scope:
10geo_variant_sets = geo_scope.GetVariantSets()
11shapes_variant_set = geo_variant_sets.AddVariantSet("shapes")
12
13# Add a variant named "Cube" to the "shapes" variant set:
14geo_variant_set.AddVariant("Cube")
15
16# Print whether the geometry scope now has variant sets:
17print(geo_scope.HasVariantSets())
18
19# Save the changes to the stage:
20stage.Save()

Let’s add some variants to the shapes variant set.

Add the following code to the cell below, then run the cell:

1geo_variant_sets = geo_scope.GetVariantSets()
2shapes_variant_set = geo_variant_sets.AddVariantSet("shapes")
3for shape in shapes:
4    shapes_variant_set.AddVariant(shape)
 1from pxr import Usd
 2
 3# Open the USD stage from the specified file:
 4stage = Usd.Stage.Open("_assets/variant_prims.usda")
 5
 6# List of shapes to add as variants:
 7shapes = ["Cube", "Sphere", "Cylinder", "Cone"]
 8
 9# Get the prim at the specified path "/World/Box/Geometry":
10geo_scope = stage.GetPrimAtPath("/World/Box/Geometry")
11
12# ADD CODE BELOW HERE
13# vvvvvvvvvvvvvvvvvvv
14
15# [...]
16
17# ^^^^^^^^^^^^^^^^^^^^
18# ADD CODE ABOVE HERE
19
20
21# Save the changes to the stage:
22stage.Save()
23# Print the unflattened Root Layer:
24DisplayUSD("_assets/variant_prims.usda", show_usd_code=True)
Loading your model...
_assets/variant_prims.usda
        
    

Example 3: Modifying Variants#

To edit a variant, switch to it by using the SetVariantSelection() method. Then, we can edit the variant and make our changes, such as modifying properties or adding new details.

In our case, we will be modifying what shape will be defined under the geometry scope.

Add the following code to the cell below, then run the cell:

 1# Loop over each shape in the list of shapes
 2for shape in shapes:
 3    # Print the shape being added
 4    print("adding: " + shape)
 5    
 6    # Add a variant named after the shape to the "shapes" variant set
 7    shapes_variant_set.AddVariant(shape)
 8    
 9    # Select the current variant for editing
10    shapes_variant_set.SetVariantSelection(shape)
11    
12    # Enter the variant edit context to make changes specific to the current variant
13    with shapes_variant_set.GetVariantEditContext():
14        # Define a new prim for the current shape under the geometry scope
15        shape_prim = stage.DefinePrim(geo_scope.GetPath().AppendPath(shape))
16        
17        # Set the type of the new prim to the current shape
18        shape_prim.SetTypeName(shape)
 1from pxr import Usd
 2
 3# Open the USD stage from the specified file:
 4stage = Usd.Stage.Open("_assets/variant_prims.usda")
 5
 6# List of shapes to add as variants:
 7shapes = ["Cube", "Sphere", "Cylinder", "Cone"]
 8
 9# Get the prim at the specified path "/World/Box/Geometry":
10geo_scope = stage.GetPrimAtPath("/World/Box/Geometry")
11
12# Get the "shapes" variant set for the geometry scope:
13geo_variant_sets = geo_scope.GetVariantSets()
14shapes_variant_set = geo_variant_sets.AddVariantSet("shapes")
15    
16# ADD CODE BELOW HERE
17# vvvvvvvvvvvvvvvvvvv
18
19# [...]
20
21# ^^^^^^^^^^^^^^^^^^^^
22# ADD CODE ABOVE HERE
23
24
25# Here we define what Variant from the VariantSet is selected. Change this between "Cube", "Sphere", "Cylinder", and "Cone"
26# to see the different geometries:
27shapes_variant_set.SetVariantSelection("Cube")
28# shapes_variant_set.SetVariantSelection("Sphere")
29# shapes_variant_set.SetVariantSelection("Cylinder")
30# shapes_variant_set.SetVariantSelection("Cone")
31
32# Save the changes to the stage
33stage.Save()
34DisplayUSD("_assets/variant_prims.usda", show_usd_code=True)
Loading your model...
_assets/variant_prims.usda
        
    

In OpenUSD, VariantSets and Variants enable the creation of flexible, dynamic scenes by allowing multiple versions of models or components to coexist within a single scene graph. This facilitates efficient asset management, easy customization, and the ability to switch between different configurations seamlessly.

Key Takeaways#