OmniIsaacGymEnvs
OmniIsaacGymEnvs copied to clipboard
Creating An Instanceable USD Assets
Issue: Problem with converting USD files to Instanceable Assets
Description
I am encountering an issue while attempting to convert normal USD files to Instanceable USD Assets. I have followed the provided guide and tried using the URDF file and the converter, but I have been unsuccessful in achieving the desired results.
Background
My first attempt at converting the files was to use the URDF file and the provided converter. However, the resulting go1.py
and go1.usd
files, which can be found here and here, respectively, seemed to be fixed in space in some way. I also tried a different approach using the larger NVIDIA USD for go1
file from this location it works, but is too large to work with. I need to use Instanceable USD Assets for my project.
I have reached out on Discord and asked a question regarding this issue, which you can find here.
Issue Details
I am new to creating USD files, and I attempted to create an Instanceable Go1
asset following the guide provided here. Unfortunately, I did not achieve the desired outcome.
I downloaded the original go1.usd
file from Isaac Sim, and after running the code provided in the create_instanceable_assets.py
script, I obtained go1_instanceable.usd
and go1_instanceable_meshes.usd
files. However, both of these files have the same size as the original Go1.usd
file, which indicates that the conversion process did not work as intended.
To convert the asset to an Instanceable Asset, I ran the following code in the Script Editor:
import omni.usd
import omni.client
from pxr import UsdGeom, Sdf
def update_reference(source_prim_path, source_reference_path, target_reference_path):
stage = omni.usd.get_context().get_stage()
prims = [stage.GetPrimAtPath(source_prim_path)]
while len(prims) > 0:
prim = prims.pop(0)
prim_spec = stage.GetRootLayer().GetPrimAtPath(prim.GetPath())
reference_list = prim_spec.referenceList
refs = reference_list.GetAddedOrExplicitItems()
if len(refs) > 0:
for ref in refs:
if ref.assetPath == source_reference_path:
prim.GetReferences().RemoveReference(ref)
prim.GetReferences().AddReference(assetPath=target_reference_path, primPath=prim.GetPath())
prims = prims + prim.GetChildren()
def create_parent_xforms(asset_usd_path, source_prim_path, save_as_path=None):
""" Adds a new UsdGeom.Xform prim for each Mesh/Geometry prim under source_prim_path.
Moves material assignment to new parent prim if any exists on the Mesh/Geometry prim.
Args:
asset_usd_path (str): USD file path for asset
source_prim_path (str): USD path of root prim
save_as_path (str): USD file path for modified USD stage. Defaults to None, will save in same file.
"""
omni.usd.get_context().open_stage(asset_usd_path)
stage = omni.usd.get_context().get_stage()
prims = [stage.GetPrimAtPath(source_prim_path)]
edits = Sdf.BatchNamespaceEdit()
while len(prims) > 0:
prim = prims.pop(0)
print(prim)
if prim.GetTypeName() in ["Mesh", "Capsule", "Sphere", "Box"]:
new_xform = UsdGeom.Xform.Define(stage, str(prim.GetPath()) + "_xform")
print(prim, new_xform)
edits.Add(Sdf.NamespaceEdit.Reparent(prim.GetPath(), new_xform.GetPath(), 0))
continue
children_prims = prim.GetChildren()
prims = prims + children_prims
stage.GetRootLayer().Apply(edits)
if save_as_path is None:
omni.usd.get_context().save_stage()
else:
omni.usd.get_context().save_as_stage(save_as_path)
def convert_asset_instanceable(asset_usd_path, source_prim_path, save_as_path=None, create_xforms=True):
""" Makes all mesh/geometry prims instanceable.
Can optionally add UsdGeom.Xform prim as parent for all mesh/geometry prims.
Makes a copy of the asset USD file, which will be used for referencing.
Updates asset file to convert all parent prims of mesh/geometry prims to reference cloned USD file.
Args:
asset_usd_path (str): USD file path for asset
source_prim_path (str): USD path of root prim
save_as_path (str): USD file path for modified USD stage. Defaults to None, will save in same file.
create_xforms (bool): Whether to add new UsdGeom.Xform prims to mesh/geometry prims.
"""
if create_xforms:
create_parent_xforms(asset_usd_path, source_prim_path, save_as_path)
asset_usd_path = save_as_path
instance_usd_path = ".".join(asset_usd_path.split(".")[:-1]) + "_meshes.usd"
omni.client.copy(asset_usd_path, instance_usd_path)
omni.usd.get_context().open_stage(asset_usd_path)
stage = omni.usd.get_context().get_stage()
prims = [stage.GetPrimAtPath(source_prim_path)]
while len(prims) > 0:
prim = prims.pop(0)
if prim:
if prim.GetTypeName() in ["Mesh", "Capsule", "Sphere", "Box"]:
parent_prim = prim.GetParent()
if parent_prim and not parent_prim.IsInstance():
parent_prim.GetReferences().AddReference(assetPath=instance_usd_path, primPath=str(parent_prim.GetPath()))
parent_prim.SetInstanceable(True)
continue
children_prims = prim.GetChildren()
prims = prims + children_prims
if save_as_path is None:
omni.usd.get_context().save_stage()
else:
omni.usd.get_context().save_as_stage(save_as_path)
ASSET_USD_PATH = "/home/ctaw/.local/share/ov/pkg/isaac_sim-2022.2.1/GO1_USD/go1.usd"
SOURCE_PRIM_PATH = "/go1_description"
SAVE_AS_PATH = "/home/ctaw/.local/share/ov/pkg/isaac_sim-2022.2.1/GO1_USD/go1_instanceable.usd"
convert_asset_instanceable(
asset_usd_path=ASSET_USD_PATH,
source_prim_path=SOURCE_PRIM_PATH,
save_as_path=SAVE_AS_PATH,
create_xforms=True
)
Steps to Reproduce
Download the necessary files and dependencies:
- Download the go1.usd file from Isaac Sim [link to the file].
- Copy and paste the code snippet from the create_instanceable_assets.py script into the editor.
- Modify the code snippet with the correct file paths:
- Update the ASSET_USD_PATH variable with the correct path to the go1.usd file.
- Ensure that the SOURCE_PRIM_PATH variable is set to the correct USD path of the root prim.
- Run the code
- Check the directory where the conversion script was run and verify that the go1_instanceable.usd and go1_instanceable_meshes.usd files have been created.
- Compare the file sizes: Check the file sizes of the resulting instanceable USD files (go1_instanceable.usd and go1_instanceable_meshes.usd).
Additional Information
Ubuntu 20.04.6 LTS, CPU: AMD Ryzen 9 5900X 12-Core Processor, Mem: 62GB, NVIDIA GeForce RTX 3090
Hi there, it is expected that the two files are of the same size as the original file. The utility script is only updating the references of the meshes of the original asset and marking certain objects in the file as instanceable. This will be processed by the USD framework when loaded in Isaac Sim, which will reduce the memory consumption required for the asset.