Shapenet using the Python API

I managed to piece together a pipeline which can use Isaac’s shapenet_convert() method on a local copy of the Shapenet dataset. However this produces a a series of assets in usd format which are a little harder to move around with code than their .usdz counterparts.

I have tried using Pixar’s UsdZipFileWritter class but the archives it produces after adding files and calling save seem to be corrupted in some way. They can’t be opened by Isaac and although a archive viewer can see all the files added in the .usdz it fails to extract them claiming there is no end to the archive.

Has anyone else got any insight on this?

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

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.