'Empty typeName for </Looks/Carpet_Cream/Shader.inputs:project_uvw>'
Interestingly, after I click on the material in the GUI, the attributes can be found and set using the above script.
Did I do something wrong when creating the material? Is there anyway to ensure the attributes to be accessible in the python api after creating the material?
Hi @chris.tung - The error message you’re seeing suggests that the attribute you’re trying to access doesn’t exist at the time you’re trying to set it. This could be because the material hasn’t been fully created and loaded into the stage at the time you’re trying to access its attributes.
In the Omniverse Kit, the creation of materials and other operations are asynchronous. This means that they don’t complete immediately when the command is issued, but instead they are scheduled to be completed in the future. This allows the system to continue processing other tasks without waiting for the material creation to complete.
To ensure that the material is fully created and its attributes are accessible, you can use the omni.kit.commands.wait_for_commands() function after creating the material. This function will block the script until all previously issued commands have completed.
Here’s how you can modify your script:
from pxr import UsdShade
f_path = "/NVIDIA/Materials/Base/Carpet/Carpet_Cream.mdl"
mtl_url = self.default_server+f_path
mtl_name = f_path.split("/")[-1].split(".")[0]
omni.kit.commands.execute("CreateMdlMaterialPrim",
mtl_url=mtl_url,
mtl_name=mtl_name,
mtl_path="/Looks/"+mtl_name)
# Wait for the material creation command to complete
omni.kit.commands.wait_for_commands()
mtl_prim = self._my_world.stage.GetPrimAtPath("/Looks/"+mtl_name)
mat_shade = UsdShade.Material(mtl_prim)
UsdShade.MaterialBindingAPI(target_prim).Bind(mat_shade,
UsdShade.Tokens.strongerThanDescendants)
shade_prim = mtl_prim.GetAllChildren()[0]
# Now the attributes should be accessible
shade_prim.GetAttribute('inputs:project_uvw').Set(True)
shade_prim.GetAttribute('inputs:world_or_object').Set(True)
This should ensure that the material is fully created and its attributes are accessible before you try to set them.
Big thank you to @Simplychenable. I have managed to find the attributes after adding
lp = stage.GetPrimAtPath('/Looks')
mtl_prims = lp.GetAllChildren()
shd_prims = [p.GetPrimPath().pathString+'/Shader' for p in mtl_prims]
selection = omni.usd.get_context().get_selection()
selection.set_selected_prim_paths(shd_prims, False)
for _ in range(5):
kit.update()
The key is to select the prims with the python api, then the attributes will be authored.
Once again, really appreciate your help.