I ended up just using the python standard zipfile package to create the .usdz files. Here is the class I am using to do it:
import os
from typing import List
from zipfile import ZipFile
class UsdToUsdz:
"""
Converts a folder containing a Usd asset to a Usd archive
"""
def __init__(self):
self._archive = None
def convert(self, usd_object_path: str):
"""
Adds the files and folders contained in the directory usd_object_path
to usdz archive. The usdz archive is saved as <usd directory>.usdz
in the folder containing the usd directory
Args:
- usd_object_path:
Path to the directory containing the usd file and any assets
"""
self._setup_archive(usd_object_path)
self._add_assets_to_archive(usd_object_path, "")
self._archive.close()
def _setup_archive(self, usd_object_path: str):
object_id = os.path.basename(usd_object_path)
parent_path = os.path.dirname(usd_object_path)
output_path = os.path.join(parent_path, f"{object_id}.usdz")
self._archive = ZipFile(output_path, "w")
def _add_assets_to_archive(self, current_path: str, archive_path: str):
self._add_files_to_archive(current_path, archive_path)
self._maybe_add_subfolders(current_path, archive_path)
def _add_files_to_archive(self, current_path: str, archive_path: str):
file_names = self._get_filenames(current_path)
for file_name in file_names:
asset_file_path = os.path.join(current_path, file_name)
asset_archive_path = os.path.join(archive_path, file_name)
self._archive.write(asset_file_path, asset_archive_path)
def _maybe_add_subfolders(self, current_path: str, archive_path: str):
folder_names = self._get_folder_names(current_path)
if len(folder_names) > 0:
self._add_assets_from_subfolders(current_path, archive_path)
def _add_assets_from_subfolders(self, current_path: str, archive_path: str):
folder_names = self._get_folder_names(current_path)
for folder_name in folder_names:
next_path = os.path.join(current_path, folder_name)
next_archive_path = os.path.join(archive_path, folder_name)
self._add_assets_to_archive(next_path, next_archive_path)
def _get_filenames(self, path: str) -> List[str]:
return next(os.walk(path))[2]
def _get_folder_names(self, path: str) -> List[str]:
return next(os.walk(path))[1]
Works for the simple usds produced on Shapenet at least