Usage Examples#
Add and Check MDL Modules in Registry#
import omni.UsdMdl as UsdMdl
from pxr import Sdf, Ar
import os
# Get asset path for an MDL module
module_path = "/path/to/material.mdl"
asset_path = Sdf.AssetPath(module_path, Ar.GetResolver().Resolve(module_path))
# Check if a module is already loaded
if not UsdMdl.RegistryUtils.IsModuleLoaded(asset_path):
# Only try to add the module if it exists (to avoid errors)
if os.path.exists(module_path):
# Add a single module to the registry
success = UsdMdl.RegistryUtils.AddModuleToRegistry(asset_path)
print(f"Module added successfully: {success}")
else:
print(f"Note: Module does not exist: {module_path}")
print("Replace with a valid MDL file path in production code.")
# These operations would need valid MDL files to execute without errors
print("\n# Example code for use with real MDL files:")
# Add multiple modules at once
module_paths = [
Sdf.AssetPath("/path/to/module1.mdl"),
Sdf.AssetPath("/path/to/module2.mdl")
]
print("module_paths = [Sdf.AssetPath(...), ...]")
print("success = UsdMdl.RegistryUtils.AddModulesToRegistry(module_paths)")
# Get available subidentifiers in a module
print("subidentifiers = UsdMdl.RegistryUtils.GetSubIdentifiersForAsset(asset_path)")
print("for subid in subidentifiers:")
print(" print(f\"Available subidentifier: {subid}\")")
Create USD Shader with MDL Source#
import omni.UsdMdl as UsdMdl
from pxr import UsdShade, Sdf
# Create a USD shader with MDL source
def create_mdl_shader(stage, prim_path, mdl_module_path, subidentifier):
# Create a Shader prim
prim = stage.DefinePrim(prim_path, "Shader")
usdshade_shader = UsdShade.Shader(prim)
# Set the MDL module as the source asset
source_asset = Sdf.AssetPath(mdl_module_path)
usdshade_shader.SetSourceAsset(source_asset, UsdMdl.Tokens.Mdl)
usdshade_shader.SetSourceAssetSubIdentifier(subidentifier, UsdMdl.Tokens.Mdl)
# Get the shader node for this prim
sdr_node = UsdMdl.RegistryUtils.GetShaderNodeForPrim(prim)
if sdr_node:
# Apply metadata from the shader node
usdshade_shader.SetSdrMetadata(sdr_node.GetMetadata())
# Create parameter inputs based on shader definition
for name in sdr_node.GetInputNames():
prop = sdr_node.GetInput(name)
sdf_type = prop.GetTypeAsSdfType()[0]
# Create input and set default value
input = usdshade_shader.CreateInput(name, sdf_type)
default_value = prop.GetDefaultValue()
if default_value is not None:
input.Set(default_value)
return usdshade_shader
# Example usage:
# stage = get_current_stage()
# shader = create_mdl_shader(stage, "/World/Material", "/path/to/materials.mdl", "my_material")
Find Shader Overloads and Properties#
import omni.UsdMdl as UsdMdl
from pxr import Sdr
# Find all available overloads for a shader
def find_shader_overloads(prim, connected_only=False):
overloads = UsdMdl.RegistryUtils.GetOverloads(prim, connected_only)
print(f"Found {len(overloads)} overloads:")
for sdr_node in overloads:
print(f" • {sdr_node.GetSubIdentifier()}")
print(f" Module: {sdr_node.GetModuleUsdIdentifier()}")
print(f" Name with signature: {sdr_node.GetNameWithSignature()}")
return overloads
# Print detailed information about a shader node
def print_shader_node_info(sdr_node):
print(f"Shader node: {sdr_node.GetName()}")
print(f"Version: {sdr_node.GetVersion()}")
print(f"Identifier: {sdr_node.GetIdentifier()}")
print(f"Module UUID identifier: {sdr_node.GetModuleUsdIdentifier()}")
print(f"Asset path: {sdr_node.GetAssetPath()}")
# Print inputs
print("\nInputs:")
for name in sdr_node.GetInputNames():
input_prop = sdr_node.GetInput(name)
print(f" • {name}: {input_prop.GetTypeAsSdfType()[0]}")
print(f" Default value: {input_prop.GetDefaultValue()}")
# Print outputs
print("\nOutputs:")
for name in sdr_node.GetOutputNames():
output_prop = sdr_node.GetOutput(name)
print(f" • {name}: {output_prop.GetTypeAsSdfType()[0]}")
Work with MDL Types and Metadata#
import omni.UsdMdl as UsdMdl
from pxr import UsdShade, Sdf
# Create a shader with different MDL type properties
def create_shader_with_mdl_types(stage, prim_path):
# Create a shader prim
prim = stage.DefinePrim(prim_path, "Shader")
shader = UsdShade.Shader(prim)
# Create color input with MDL metadata
color_input = shader.CreateInput("diffuseColor", Sdf.ValueTypeNames.Color3f)
color_input.Set((0.8, 0.2, 0.2))
color_input.SetMetadata("sdrMetadata", {
"renderType": UsdMdl.Types.Color
})
# Create float input with uniform modifier
roughness = shader.CreateInput("roughness", Sdf.ValueTypeNames.Float)
roughness.Set(0.5)
roughness.SetMetadata("sdrMetadata", {
"renderType": UsdMdl.Types.Float,
UsdMdl.Metadata.Modifier: UsdMdl.TypeModifiers.Uniform
})
# Create texture input with gamma metadata
texture = shader.CreateInput("albedoTexture", Sdf.ValueTypeNames.Asset)
texture.Set(Sdf.AssetPath("/textures/albedo.png"))
texture.SetMetadata("sdrMetadata", {
"renderType": UsdMdl.Types.Texture2d,
"isAssetIdentifier": "1",
UsdMdl.Metadata.TextureGamma: "2.2"
})
# Create struct input for material
material = shader.CreateInput("material", Sdf.ValueTypeNames.Token)
material.SetMetadata("sdrMetadata", {
"renderType": UsdMdl.Types.Struct,
UsdMdl.Metadata.StructType: UsdMdl.StructTypes.Material,
UsdMdl.Metadata.Symbol: "::material"
})
return shader
# Print all available metadata tokens
metadata_tokens = UsdMdl.GetAllMetadataTokens()
print("Available MDL metadata tokens:", metadata_tokens)
Respond to MDL Module Load/Reload Events#
from pxr import Tf
import omni.UsdMdl as UsdMdl
# Function to handle module loaded notifications
def on_module_loaded(notice, sender):
# Get the path of the loaded module
resolved_path = notice.GetResolvedPath()
print(f"MDL Module loaded: {resolved_path}")
# You could perform actions like:
# - Refresh UI showing available MDL materials
# - Update material previews
# - Log loading events
# Function to handle module reloaded notifications
def on_module_reloaded(notice, sender):
resolved_path = notice.GetResolvedPath()
print(f"MDL Module reloaded: {resolved_path}")
# You could perform actions like:
# - Update materials that use this module
# - Refresh property UIs
# - Notify users of updated modules
# Register notification listeners
load_listener = Tf.Notice.Register(UsdMdl.Notice.ModuleLoaded, on_module_loaded, None)
reload_listener = Tf.Notice.Register(UsdMdl.Notice.ModuleReloaded, on_module_reloaded, None)
# When no longer needed:
# load_listener = None # This will unregister the listener
# reload_listener = None