Create an Attribute#

Creating an Attribute on a layer ensures that it is concretely defined on the Stage. It will always return a value Usd.Attribute object.

With the USD API, you can use Usd.Prim.CreateAttribute() to create attributes on Usd.Prim objects. You can set the value using Usd.Attribute.Set() and query the value using Usd.Attribute.Get()

from pxr import Gf, Sdf, Usd, UsdGeom

"""
Find all relevant data types at: https://openusd.org/release/api/_usd__page__datatypes.html
"""


def create_float_attribute(prim: Usd.Prim, attribute_name: str) -> Usd.Attribute:
    """Creates attribute for a prim that holds a float.
    See: https://openusd.org/release/api/class_usd_prim.html
    Args:
        prim (Usd.Prim): A Prim for holding the attribute.
        attribute_name (str): The name of the attribute to create.
    Returns:
        Usd.Attribute: An attribute created at specific prim.
    """
    attr: Usd.Attribute = prim.CreateAttribute(attribute_name, Sdf.ValueTypeNames.Float)
    return attr


def create_vector_attribute(prim: Usd.Prim, attribute_name: str) -> Usd.Attribute:
    """Creates attribute for a prim that holds a vector.
    See: https://openusd.org/release/api/class_usd_prim.html
    Args:
        prim (Usd.Prim): A Prim for holding the attribute.
        attribute_name (str): The name of the attribute to create.
    Returns:
        Usd.Attribute: An attribute created at specific prim.
    """
    attr: Usd.Attribute = prim.CreateAttribute(
        attribute_name, Sdf.ValueTypeNames.Float3
    )
    return attr


#############
# Full Usage
#############

# Create an in-memory Stage
stage: Usd.Stage = Usd.Stage.CreateInMemory()

# Create a prim named /World (type Xform) and make it the default prim.
prim_path = "/World"
xform: UsdGeom.Xform = UsdGeom.Xform.Define(stage, prim_path)
prim: Usd.Prim = xform.GetPrim()
stage.SetDefaultPrim(prim)

# Create a float attribute on /World
float_attr: Usd.Attribute = create_float_attribute(prim, "my_float_attr")

# Create a vector attribute on /World
vector_attr: Usd.Attribute = create_vector_attribute(prim, "my_vector_attr")

# Set and query values
print(float_attr.Get())
float_attr.Set(0.1)
print(float_attr.Get())

vector_value: Gf.Vec3f = Gf.Vec3f(0.1, 0.2, 0.3)
print(vector_attr.Get())
vector_attr.Set(vector_value)
print(vector_attr.Get())

# Optionally preview the usd
# print(stage.GetRootLayer().ExportToString())

The CreateUsdAttributeCommand command in Kit can create an Attribute on a prim. The Attribute name and type are required.

import omni.kit.commands
import omni.usd

from pxr import Gf, Sdf, Usd, UsdGeom


def create_float_attribute(prim: Usd.Prim, attribute_name: str) -> Usd.Attribute:
    """Creates attribute for a prim that holds a float.
    See: https://openusd.org/release/api/class_usd_prim.html
    See: https://docs.omniverse.nvidia.com/kit/docs/omni.usd/latest/omni.usd.commands/omni.usd.commands.CreateUsdAttributeCommand.html
    Args:
        prim (Usd.Prim): A Prim for holding the attribute.
        attribute_name (str): The name of the attribute to create.
    Returns:
        Usd.Attribute: An attribute created at specific prim.
    """
    omni.kit.commands.execute(
        "CreateUsdAttributeCommand",
        prim=prim,
        attr_name=attribute_name,
        attr_type=Sdf.ValueTypeNames.Float,
    )

    attr: Usd.Attribute = prim.GetAttribute(attribute_name)
    return attr


def create_vector_attribute(prim: Usd.Prim, attribute_name: str) -> Usd.Attribute:
    """Creates attribute for a prim that holds a vector.
    See: https://openusd.org/release/api/class_usd_prim.html
    See: https://docs.omniverse.nvidia.com/kit/docs/omni.usd/latest/omni.usd.commands/omni.usd.commands.CreateUsdAttributeCommand.html
    Args:
        prim (Usd.Prim): A Prim for holding the attribute.
        attribute_name (str): The name of the attribute to create.
    Returns:
        Usd.Attribute: An attribute created at specific prim.
    """
    omni.kit.commands.execute(
        "CreateUsdAttributeCommand",
        prim=prim,
        attr_name=attribute_name,
        attr_type=Sdf.ValueTypeNames.Float3,
    )
    attr: Usd.Attribute = prim.GetAttribute(attribute_name)
    return attr


#############
# Full Usage
#############

# Get the current stage
stage: Usd.Stage = omni.usd.get_context().get_stage()

# Get the default prim
prim: Usd.Prim = stage.GetDefaultPrim()

# Create a float attribute on /World
float_attr: Usd.Attribute = create_float_attribute(prim, "my_float_attr")

# Create a vector attribute on /World
vector_attr: Usd.Attribute = create_vector_attribute(prim, "my_vector_attr")

# Set and query values
print(float_attr.Get())
float_attr.Set(0.1)
print(float_attr.Get())

vector_value: Gf.Vec3f = Gf.Vec3f(0.1, 0.2, 0.3)
print(vector_attr.Get())
vector_attr.Set(vector_value)
print(vector_attr.Get())

# Optionally preview the usd
# print(stage.GetRootLayer().ExportToString())

This is an example USDA result from creating an Xform and Cube prim. Where the Cube prim is a child of the Xform and the Xform has it’s own Translation Ops.

#usda 1.0
(
    defaultPrim = "World"
)

def Xform "World"
{
    custom float my_float_attr = 0.1
    custom float3 my_vector_attr = (0.1, 0.2, 0.3)
}