Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tower of Babel

A Python pipeline that turns the Palatial asset library into Isaac-Sim-ready USD / USDz files, stored in Cloudflare R2.

Two stages:

  • Acquire — pull every library asset's parts (meshes, textures, physics, validation artifacts) into R2 under runs/<run-id>/, tracked by a resumable manifest.
  • Compose — assemble each asset's textured mesh + convex-hull collider + physics spec into a rigid-body .usda / .usdz, written to a global usd/<assetId>/ library.

It's a uv project exposing a library and the usd-pipeline CLI (acquire · resume · status · compose).

Setup

uv sync
cp .env.example .env   # then fill in your Cloudflare R2 endpoint, bucket, and keys

CLI

# Full acquisition into R2 (endpoint + bucket from .env)
uv run usd-pipeline acquire

# Smoke test: only the first asset, into a local directory (no R2 needed)
uv run usd-pipeline acquire --limit 1 --local ./output

# Resume an interrupted run (skips completed steps)
uv run usd-pipeline resume 2026-06-25T14-30-00Z

# Inspect progress
uv run usd-pipeline status 2026-06-25T14-30-00Z

# Compose USD/USDz from an acquired run's parts (textured + collision + physics)
uv run usd-pipeline compose 2026-06-25T14-30-00Z --delight

Compose (USD/USDz)

compose turns each acquired asset's parts into an Isaac-Sim-ready rigid-body USD:

  • inputs (resolved from the acquisition manifest): the textured mesh GLB, the collision-hull GLB, and embedded-physics.json (the Palatial "newton" spec);
  • outputs: <assetId>.usda + .usdz + _basecolor.png, written to a global local USD dir (PIPELINE_USD_DIR, default ~/usd; --usd-dir to override) as <usdDir>/<assetId>/, and also uploaded to R2 under a global usd/<assetId>/ prefix (parallel to runs/, keyed by asset id — a single canonical USD library, not per-run);
  • each asset's USD dir is replaced on rerun; progress is tracked in runs/<run-id>/compose-manifest.json (--skip-existing resumes, default replaces);
  • assets missing any of the textured mesh, collision mesh, or embedded-physics JSON — or whose physics has no parts — are recorded absent (not composable).
uv run usd-pipeline compose <run-id> [--usd-dir ~/usd] [--concurrency 4] [--limit N] \
    [--skip-existing] [--delight] [--inertia auto|predicted|derive] [--no-usdz] [--local DIR]

Library use (notebooks)

from usd_pipeline import run_acquisition, run_compose, compose_usd, Settings, LocalStore

manifest = run_acquisition(Settings(), store=LocalStore("./output"), limit=5)
print(manifest.stats())

# Compose the acquired run (USD/USDz) ...
ledger = run_compose(manifest.data["run_id"], Settings(), store=LocalStore("./output"),
                     usd_dir="./usd", limit=5)
print(ledger.stats())

# ... or compose a single asset directly from local files:
compose_usd("textured.glb", "collision.glb", "physics.json", "out/asset.usda", usdz=True)

Notebooks

Interactive marimo notebooks. Each previews a composed asset with a textured GLB via <model-viewer>, a best-effort three.js render of the actual .usdz, and a download/AR link.

# Self-contained: browse library → pick one → acquire → compose → preview.
# Public Palatial API into a local temp dir — no R2 credentials needed.
uv run --extra notebook marimo edit notebooks/explore.py

# Compose from an already-acquired R2 run: pick run → pick asset → compose → preview.
# Reads/writes Cloudflare R2 — requires credentials in .env.
uv run --extra notebook marimo edit notebooks/compose_from_r2.py

How it works

For every result of the library search, the tool runs 8 steps and stores both each endpoint's JSON response and the file its downloadUrl points to:

  1. detailGET /assets/{id} (unlocked by minting a per-asset asset_share_viewer cookie via POST /share/library-viewer-session) 2-6. process-file/*shape-generation, texture, collision-preview, physics-predictions, validation-playback
  2. embedded-physicsGET /assets/{id}/embedded/physics (inline JSON)
  3. validation-reportGET /assets/{id}/media/validation-report

Assets are fetched concurrently (--concurrency, default 8). A process-file response with no downloadUrl, or a validation-report 404 (no report exists), is recorded as absent (not an error). An asset that is gated server-side (403 "not available in the library") has its steps recorded as skipped (discarded, not a failure). A shared HDR environment map is fetched once per run and saved at the run root.

Layout in R2

runs/<run-id>/
  library-search.json                    # search reference
  studio_country_hall_1k-3e5b7ed8.hdr    # shared HDR env map (once per run)
  manifest.json                          # acquisition progress / recovery
  compose-manifest.json                  # compose progress / recovery
  <assetId>/
    detail.json
    <kind>.response.json + <kind>/<file>     # shape-generation, texture, ...
    embedded-physics.json
    validation-report.response.json + validation-report/<file>

usd/                                     # global composed USD library (parallel to runs/)
  <assetId>/
    <assetId>.usda
    <assetId>.usdz
    <assetId>_basecolor.png

Each run uses a UTC-timestamped prefix; the manifest records per-step status (done, absent, failed, skipped) so runs are resumable: resume <run-id> reruns only the steps that are not yet complete.

Configuration

All settings come from environment variables / .env (see .env.example): R2_ENDPOINT_URL, R2_BUCKET, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_REGION, PALATIAL_BASE_URL, PALATIAL_COOKIE (optional override), PIPELINE_CONCURRENCY. Credentials are never committed.

Tests

uv run pytest            # unit tests (HTTP mocked with respx, R2 mocked with moto)
uv run pytest -m live    # opt-in checks against the real Palatial API (network)

License

Copyright © 2026 Nejc Drobnič.

Licensed under the GNU General Public License v3.0 or later (GPL-3.0-or-later) — see LICENSE.

About

Acquire Palatial library assets into Cloudflare R2 and compose them into Isaac-Sim-ready USD/USDz — a uv library + CLI.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages