Skip to content

Resolve references inside USDZ packages#122

Merged
mxpv merged 4 commits into
mxpv:mainfrom
bresilla:fix/usdz-usd-content-sniff
Jun 29, 2026
Merged

Resolve references inside USDZ packages#122
mxpv merged 4 commits into
mxpv:mainfrom
bresilla:fix/usdz-usd-content-sniff

Conversation

@bresilla

@bresilla bresilla commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

When I added the USDZ reader earlier it only read the package's first layer - references to other layers inside the same archive were never resolved. So opening something like Pixar's Kitchen_set.usdz composed the root but dropped every packaged sub-asset (untyped prims, no geometry), and composition reported UnsupportedUsdzReference / the eager collector bailed. My miss - this finishes it (completes ROADMAP 9.7 "Packaged resources").

What it does

Anchors a bare .usdz to its first layer in the resolver (pkg.usdz[first.usd], like C++ Ar), so a package composes through the normal path:

  • resolve() maps a bare .usdz -> its first packaged layer, uniformly for a root, sublayer, or referenced .usdz.
  • create_identifier anchors a relative reference into the enclosing package.
  • ResolvedPath::extension() reads the inner extension for package-relative paths.
  • UsdzFileFormat::read accepts either a package or a package-relative path.
  • content-sniffs an agnostic .usd inner layer (USDC magic vs USDA text), so a package whose root layer is .usd opens.
  • removes the now-obsolete sublayer bail and the UnsupportedUsdzReference guard/variant (cross-file refs now resolve).

Reads the package directory through the resolver's own open_asset rather than direct filesystem access, so a future host-provided byte source (#105's "get me the bytes for this layer") flows through unchanged - sync-only, no async, no new deps.


I put the package -> default-layer anchoring in ar::Resolver::resolve. C++ does this at the SdfLayer tier, so LayerRegistry might be the more faithful...

Copilot AI review requested due to automatic review settings June 28, 2026 21:08

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR completes in-archive resolution for USDZ packages so that references/sublayers authored inside a .usdz can target sibling layers within the same archive (e.g. Pixar Kitchen_set.usdz), composing packaged sub-assets through the normal resolver + layer registry pipeline.

Changes:

  • Anchor bare .usdz asset paths to the archive’s first layer via ar::Resolver::resolve, and make create_identifier anchor relative asset paths within the enclosing package.
  • Teach ResolvedPath::extension() and the USDZ archive reader to correctly identify inner-layer formats (including content-sniffing for .usd).
  • Remove the previous “unsupported in-package reference” guardrails and update tests to assert successful composition instead of error reporting.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/stage.rs Updates integration test to assert in-package reference resolution and composed opinions.
src/usdz/reader.rs Adds content-based format detection for inner .usd (USDC magic vs USDA text).
src/usdz/mod.rs Adjusts USDZ FileFormat::read handling and adds a focused unit test for packaged references.
src/sdf/layer_registry.rs Removes the previous USDZ sublayer bail-out and documents the new in-package resolution behavior.
src/pcp/prim_indexer.rs Removes the explicit UnsupportedUsdzReference error emission path.
src/pcp/mod.rs Deletes the UnsupportedUsdzReference error variant.
src/ar.rs Implements package anchoring in resolve, package-relative extension handling, and package-aware identifier anchoring.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/ar.rs Outdated
Comment thread src/ar.rs Outdated
Comment thread src/ar.rs Outdated
bresilla and others added 2 commits June 28, 2026 23:33
Give Layer a resolved real_path (C++ SdfLayer::GetRealPath) distinct
from its identifier, and anchor every in-package reference, sublayer,
and asset path against it. A package whose default layer lives in a
sub-directory previously lost that prefix when anchoring relative
paths; it now resolves in-package correctly.

The bare-package -> default-layer decision moves out of the generic
resolver into a FileFormat::resolve_layer hook, so resolve() stays
package-agnostic (asset-value resolution and the resolvability probe
get the package path itself) while usdz owns its own package rule.

Package-internal joins now emit forward slashes and collapse '..' to
match ZIP entry names on every platform, and a nested package-relative
target nests well-formed instead of forming a double-bracket
identifier. A package that cannot be opened, or lists no default
layer, falls back to its bare path so read() surfaces the precise
zip/parse error consistently rather than reporting a missing asset.

Also record the architectural-correctness preference in CLAUDE.md.
@mxpv

mxpv commented Jun 29, 2026

Copy link
Copy Markdown
Owner

Thanks!

@mxpv mxpv merged commit 7255b2d into mxpv:main Jun 29, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants