Skip to content

usda: parse typed tuple values inside time samples#59

Merged
mxpv merged 2 commits intomxpv:mainfrom
bresilla:fix/typed-timesample-tuples
Apr 26, 2026
Merged

usda: parse typed tuple values inside time samples#59
mxpv merged 2 commits intomxpv:mainfrom
bresilla:fix/typed-timesample-tuples

Conversation

@bresilla
Copy link
Copy Markdown
Contributor

What

.timeSamples = { ... } was dispatching each per-time value through parse_property_metadata_value, which is type-blind and has no case for tuple syntax. So typed-tuple samples like quatf[] rotations (w, x, y, z), float3[] translations (x, y, z), and matrix4d rows bailed with Unsupported property metadata value token: Punctuation('(').

The fix threads the property's TypeInfo (already in scope at the call site) through to parse_time_samples and dispatches each sample via parse_value(info), so they land in the right QuatfVec / Vec3fVec / Matrix4d variant.

Why I needed this

Trying to load Pixar's UsdSkel test asset HumanFemale.walk.usd, whose rotation and translation timeSamples are arrays of tuples. Without this fix, basically every UsdSkel rig in the wild fails to parse.

Test

Adds parse_typed_tuple_time_samples covering quatf[], float3[], and matrix4d time samples. All 338 lib tests pass, cargo fmt --check is clean.

`.timeSamples = { ... }` previously dispatched each per-time value
through `parse_property_metadata_value`, which is the type-blind
metadata-block parser and has no case for tuple syntax. Typed-tuple
samples — `quatf[]` rotations `(w, x, y, z)`, `float3[]` translations
`(r, g, b)`, `matrix4d` xforms — bailed with `Unsupported property
metadata value token: Punctuation('(')`.

Thread the property's `TypeInfo` from the call site through to
`parse_time_samples` and dispatch each per-time value through
`parse_value(info)` so it lands in the matching `Value::QuatfVec` /
`Vec3fVec` / `Matrix4d` variant.

Pixar's `UsdSkelExamples/HumanFemale.walk.usd` is the canonical
broken case; with the fix it parses to a usable stage. Adds a
parser-level regression covering quatf[], float3[], and matrix4d
time samples.
Copilot AI review requested due to automatic review settings April 26, 2026 15:49
@bresilla
Copy link
Copy Markdown
Contributor Author

Quick note: this only touches USDA. USDC was already fine, since each per-time value in the binary stream carries its own type tag and decodes through the typed value path. So both formats parse typed-tuple time samples correctly after this lands.

Copy link
Copy Markdown

Copilot AI left a comment

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 fixes the USDA parser’s handling of .timeSamples = { ... } for attributes whose per-sample values require type-aware parsing (notably tuple-based syntaxes like quatf[], float3[], and matrix4d). It threads the attribute’s already-parsed TypeInfo into parse_time_samples and parses each sample using the same typed parse_value(...) path used for default values.

Changes:

  • Pass the attribute TypeInfo into parse_time_samples(...) at the .timeSamples parsing site.
  • Update parse_time_samples to dispatch each sample via parse_value(info) (type-aware), instead of parse_property_metadata_value() (type-blind).
  • Add a regression test covering tuple-array quaternion samples, tuple-array float3 samples, and matrix4d row tuple samples.

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

The first revision of this PR moved every per-time value through
parse_value(info), which broke the spec corpus's attributes.usda
fixture. That fixture deliberately authors bare scalars (5.67, -7)
and `None` against a typed `vector3f` property to check parser
tolerance — strict typed dispatch rejected them.

Peek the next token first: only route through the typed path when
the property's type expects a tuple AND the next token actually
opens one (`(` or `[`). Otherwise fall back to
parse_property_metadata_value(), preserving the historical
tolerance.

Adds a parse_lenient_time_samples_keep_scalar_and_none regression
covering the attributes.usda shape that was failing CI.
@bresilla bresilla force-pushed the fix/typed-timesample-tuples branch from f9d3388 to 7b81499 Compare April 26, 2026 16:21
@mxpv
Copy link
Copy Markdown
Owner

mxpv commented Apr 26, 2026

Nice!

@mxpv mxpv merged commit 0d235ab into mxpv:main Apr 26, 2026
5 checks passed
@mxpv mxpv added the usda Text format label Apr 26, 2026
mxpv added a commit that referenced this pull request Apr 26, 2026
Broadens the type-aware time-sample dispatch from PR #59 to cover
scalar array types (int[], float[], token[], bool[], …) in addition
to tuple types. Each per-time value whose declared type is an array
and whose literal opens with `[` now routes through `parse_value`,
landing in the precise `IntVec` / `FloatVec` / `TokenVec` / `BoolVec`
variant rather than the type-blind metadata path's `Int64Vec` /
`DoubleVec` / `StringVec` fallbacks.

The lenient fallback (bare scalars and `None` authored against typed
properties, as in the spec corpus's `attributes.usda`) is preserved:
the dispatch only kicks in when the next token opens a literal whose
shape matches the declared type.

Renames `next_is_typed_tuple_value` to `next_is_typed_value` since
it now covers more than tuples, and updates docs accordingly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

usda Text format

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants