Dev rc0 26may#275
Conversation
USDC writer path encoding: - Replace EncodePaths-based path tree with direct pxrUSD-style BuildPathIndicesFromSortedPaths using Path::operator< sorting and pre-assigned PathIndex values (no intermediate UINT64_MAX sentinels) - Add ";-)" sentinel at token index 0 matching OpenUSD workaround for github issue #811 (-0 == 0 property path ambiguity) - Fix NurbsCurves roundtrip: add GeomNurbsCurves to GetPrimElementName and SetPrimElementName dispatch tables in prim-types.cc - Fix Path::_update for relative paths: set _element for ndots==0 case - Add "properties" field to prim specs for Pixar reader compatibility - Add "primChildren" to pseudoroot spec USDC writer property gaps fixed: - Camera: guard all properties with authored() to prevent default injection - Mesh: fix subdivisionScheme/interpolateBoundary/faceVaryingLinearInterpolation default injection; add velocities extraction; add normals interpolation metadata; route doubleSided through ConvertAttributeToFields - Points: add ids (int64[]) extraction - Skeleton: add bindTransforms/restTransforms (matrix4d[]) extraction - SkelAnimation: add scales (half3[]) extraction - All lights: add shadow API, shaping API, common light properties; fix inputs: prefix; fix has_value()->authored() default injection; fix DomeLight file asset type - Shader: add terminal output handling for UsdUVTexture, UsdTransform2d, UsdPrimvarReader_* with correct type names - Material: add MaterialXConfigAPI property extraction - Fix ConvertPropertyToFields EmptyAttrib handling for terminal attrs Crate writer type support: - Add WriteValueData for matrix2d/3d/4d[], half2/3/4[], int2-4[], uint2-4[] - Add ConvertValue handlers for texCoord2f/2d/3f/3d[], float2[], half2-4[], int2-4[], bool[], matrix2d/3d[] - Remove matrix[]/half[] upstream filters now that types are supported - Add GetPrimProps entries for NurbsCurves, PointInstancer, NodeGraph, GeometryLight, PortalLight Parser and pprint fixes: - USDA parser: reject multiple property statements on single line - Fix wrapS/wrapT name swap in pprint-shader.cc - Fix default value injection for connected token attrs in pprint-detail.hh Tools and testing: - Rewrite tusddiff to use LoadLayerFromFile with proper exit codes - Add usdc-writer-runner.py (tusdcat -> USDC -> tusddiff pipeline) - Register usdc-writer-diff-test in CMake - Add 28 comprehensive USDC writer unit tests covering usdGeom, usdSkel, usdShade, usdLux, usdMtlx, instancing, and apiSchemas - Update doc/testing-cpp.md with new test coverage Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Simplify Path::LessThan to use full_path_name() lexicographic comparison instead of complex subtree walking. This correctly handles property paths sorting before child prims (because '.' (0x2E) < '/' (0x2F) in ASCII) and fixes cases where property paths of deep hierarchies were sorted incorrectly, causing "path index not filled" errors. - Insert ";-)" sentinel token at start of Finalize (before field packing) to ensure no real path element gets token index 0. This matches OpenUSD's workaround for github issue #811. - Improve path index verification error message with full sorted path dump for debugging. Roundtrip results: 320/340 (remaining 20 are variant set issues). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract {varSet} and {varSet=sel} variant elements from full paths
before passing to tokenize_variantElement(). The function expects
just the brace-enclosed element (e.g., "{shapeVariant=Capsule}"),
not the full prim path (e.g., "/Implicits{shapeVariant=Capsule}").
This fixes the "Invalid Variant ElementPath" errors during USDC
roundtrip of variant sets.
Note: Variant roundtrips still fail with "failed to resolve variant
owner Prim" — the reader's DFS-based variant reconstruction doesn't
match the writer's tree structure. This will be addressed separately.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Path class fixes:
- Fix get_parent_path() and get_parent_prim_path() for variant paths:
/A{v} -> /A, /A{v=sel} -> /A. Check variant braces BEFORE
is_root_prim() since /A{v} falsely passes the root prim test.
- Fix has_prefix() to use string prefix matching instead of split-based
segment comparison. This correctly handles /A{v} having prefix /A
(the next char after prefix is '{').
- Fix Path::_update for relative paths: set _element for ndots==0.
USDC reader fixes:
- Extract variant element {name} or {name=sel} from full path before
passing to tokenize_variantElement() in VariantSet and Variant
reconstruction (both Stage and Layer paths).
- Extract variant element from element_name() in
AttachVariantPrimChildrenToOwner before validation.
Roundtrip results: 326/340 (was 320). 6 variant files now roundtrip
successfully. Remaining 14 failures: 13 variant sets with JSON
mismatch (data fidelity) + 1 layer metadata.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Path tree encoding:
- Add depth guard (max 512 levels) to buildImpl in WritePathsSection
- Fix get_parent_path() for paths like /A{v=sel}/C: only strip variant
element when it's the LAST component (no '/' after '}'), otherwise
use normal '/' splitting. Fixes 6 more variant roundtrip failures.
Comprehensive path tree tests (10 new tests):
- path_lessthan_basic_test: basic ordering /, /A, /A.prop, /A/B, /B
- path_lessthan_variant_test: variant ordering with {v} and {v=sel}
- path_has_prefix_basic_test: prefix matching with boundary check
- path_has_prefix_variant_test: /A{v} has_prefix /A, etc.
- path_get_parent_basic_test: /A/B -> /A, /A -> /
- path_get_parent_variant_test: /A{v} -> /A, /A{v=sel}/C -> /A{v=sel}
- path_tree_flat_siblings_test: 4 root-level siblings roundtrip
- path_tree_deep_hierarchy_test: 20-level deep nesting roundtrip
- path_tree_mixed_props_test: prims + properties + children
- path_tree_variant_basic_test: variant set roundtrip
Roundtrip results: 332/340 (97.6%, up from 326).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract variant element from full path in the _variantPropChildren
handler (line 956), matching the fix already applied to
AttachVariantPrimChildrenToOwner. The element_name() returns the
full path "/Prim{v=sel}" but is_variantElementName expects just
"{v=sel}".
This fixes the remaining 8 variant roundtrip failures:
variantSet-003/004/005/006, variantSet-comment-block-001,
variantSet-listop-append-001, variantSet-meta-001, variantSet-prop-001.
USDC roundtrip: 340/340 (100%)
All 13 ctest targets pass.
All 408 unit tests pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New variant USDC roundtrip tests (6 tests): - usdc_writer_variant_with_props_test: properties inside variant selections - usdc_writer_variant_multi_selection_test: 3 variant selections with child prims - usdc_writer_variant_nested_test: nested variant sets (level1 → level2) - usdc_writer_variant_with_selection_test: variant with default selection metadata - usdc_writer_variant_with_children_test: variant with both prims and properties - usdc_writer_variant_empty_test: empty variant selection alongside non-empty All tests verify variant set names, variant selection names, and child prim survival through USDC roundtrip. Nested variant set data fidelity is checked gracefully (nested variantSets may not fully roundtrip yet). Total: 414 unit tests, 44 USDC writer tests, all passing. 340/340 USDC roundtrip, 13/13 ctest targets pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
tests/diffusd/runner.py compares TinyUSDZ's USDC reading against
Pixar's reference output:
Pipeline per file:
1. Pixar usdcat writes USDC from input USDA (reference)
2. TinyUSDZ tusdcat writes USDC from same input
3. Pixar usdcat reads original → reference USDA text
4. TinyUSDZ tusdcat reads Pixar's USDC → test USDA text
5. compare-usda.js compares reference vs test (semantic)
This tests that TinyUSDZ can correctly read Pixar-produced USDC files
and produce semantically equivalent output.
Results: 302/340 passed (88.8%). 35 failures are files where
TinyUSDZ can't read Pixar's USDC (stage-meta-only files, empty
files, special metadata). 3 skipped (Pixar parse failures).
Usage:
python3 tests/diffusd/runner.py \
--tusdcat ./build/tusdcat \
--tusddiff ./build/tusddiff \
--usdcat /path/to/pixar/usdcat \
--basedir tests/usda --verbose
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove stderr debug output from fieldset decoding investigation. Replace with DCOUT for non-release debugging. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Identified root cause of Pixar USDC read failures: DecodeFieldSet fails on the second field (primChildren, type TokenVector=41) when reading Pixar-produced USDC files. This is a pre-existing issue in the crate reader's UnpackValueRep for TokenVector type — confirmed by testing against commit e53c8a5 (same error in both old and new). Not a regression from path tree encoding changes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Skip the stream read for zero-length TokenVector values. The stream reader returns false for 0-byte reads, which caused "Failed to decode fieldset id: 0" errors when reading Pixar-produced USDC files containing empty primChildren arrays (files with only stage metadata and no prims). Cross-writer Pixar USDC read: 333/340 (was 302). Remaining 4: material-binding-none (prim reconstruction), valuetypes-edge (empty arrays), stage-meta-comment (diff). USDC roundtrip: 340/340. All 13 ctest targets pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
runner.py now supports --mode usda|usdc|both (default: both). USDA mode pipeline: 1. Pixar usdcat reads input → USDA text (reference) 2. TinyUSDZ tusdcat reads same input → USDA text (test) 3. compare-usda.js compares both (semantic, order-independent) USDC mode (existing): 1. Pixar writes USDC from input 2. TinyUSDZ reads Pixar's USDC → USDA text 3. Compare against Pixar's reference USDA Results with --mode both: USDA: 337/340 (0 failed, 3 skipped) USDC: 333/340 (4 failed, 3 skipped) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Stream reader: - Return truthy value for 0-byte reads instead of 0 (falsy). Fixes empty TokenVector, empty arrays, and other 0-length data reads from Pixar-produced USDC files. Crate reader: - Handle empty arrays: non-inlined array with payload=0 treated as empty (Pixar's encoding for `string[] = []` etc.) - Add inner error details to fieldset decode error messages - Skip 0-byte TokenVector reads (guard added in previous commit) Prim reconstruction: - Accept empty pathvector (0 targets) for material:binding = None instead of rejecting it as "empty or has multiple Paths" - Set customLayerDataAuthored flag when reading customLayerData from USDC, so empty dicts are preserved in USDA output Pretty-print: - Output `None` for relationships with empty target path vector instead of `[]`, matching Pixar's output Cross-writer runner: - Set 10s timeout per file (was 60s) - Handle TimeoutExpired gracefully (skip with message) Cross-writer results: USDA: 337/340 (0 failed, 3 skipped) USDC: 327/340 (9 diff, 4 skipped) All 13 ctest targets pass. 340/340 USDC roundtrip. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add progress guards to all parsing loops (dictionary, array, tuple, prim body). If no tokens are consumed in a loop iteration, skip one token to prevent infinite loops on malformed USDA input like "void times = VALUE_PPRINT: TODO: (type: void)". Lower maxIterations from 50M to 5M for faster abort on edge cases. Set 10s per-file timeout in cross-writer runner with graceful skip. The clips-primmeta-001.usda file no longer hangs — completes in <1s. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When Pixar's crate writer stores empty arrays (e.g., double2[] = []), it uses non-inlined ValueRep with payload=0 and IsArray=true. The previous fix returned true without setting the CrateValue, leaving it as void type which produced "VALUE_PPRINT: TODO: (type: void)" in USDA output. Now set a properly-typed empty std::vector<T>() based on the CrateDataType, covering all numeric, vector, matrix, quaternion, string, token, and asset path array types. Cross-writer USDC: 336/340 (was 327). Only 1 diff remaining. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
OpenUSD uses two different inlining conventions for half vectors: - half2 (4 bytes = sizeof(uint32_t)): "always inlined" with raw half bit patterns via memcpy, matching _IsAlwaysInlined<T> trait - half3 (6 bytes): conditionally inlined via int8 compact encoding when all components are exactly int8-representable - half4 (8 bytes): never inlined, stored out-of-line Reader: half2 inline handler now reads uint16 bit patterns directly instead of int8+float_to_half_full. half3/half4 unchanged. Writer: half2 always inlines with uint16 memcpy. half3 conditionally inlines with int8 compact. Added out-of-line write handlers for half2/half3 scalars (PACK_SCALAR_TYPE + WRITE_HALFVEC_SCALAR). Fixes USDC cross-writer diff for valuetypes-edge-001.usda (half2 was read as (0, 56) instead of (0.5, 1.5), half3 as garbage instead of (1, 2, 3)). All cross-writer tests now pass: 335/340, 0 failures. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Detect TinyUSDZ pprinter placeholder "VALUE_PPRINT: TODO" in test outputs to catch unimplemented value printing early, rather than letting it appear as a cryptic value mismatch. - compare-usda.js: scan raw content before parsing, warn on stderr, add as value_pprint_todo difference (exit code 1) - diffusd/runner.py: check tusdcat USDA output in both USDA and USDC cross-writer modes, report as FAIL (VALUE_PPRINT) - usdc-writer-runner.py: check roundtripped USDA file content before running diff step Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move the crate path sorting/encoding library from sandbox/path-sort-and-encode-crate/ into src/crate-path-utils/ and compile it directly into the main library instead of as a separate static lib. Remove both sandbox/crate-writer/ (superseded by src/crate-writer.cc) and sandbox/path-sort-and-encode-crate/. Add XFAIL markers to 5 test files that Pixar's usdcat cannot parse, replacing the hardcoded PIXAR_SKIP set. Test runners and compare-usda.js now read `# XFAIL: <tag>` from file headers and report them clearly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
# Conflicts: # CMakeLists.txt # src/ascii-parser-basetype.cc # src/ascii-parser-timesamples-array.cc # src/ascii-parser-timesamples.cc # src/ascii-parser.cc # src/ascii-parser.hh # src/composition.cc # src/crate-format.hh # src/crate-reader.cc # src/crate-writer.cc # src/json-to-usd.cc # src/memory-budget.hh # src/pprinter.cc # src/prim-reconstruct-shader.cc # src/prim-reconstruct.cc # src/prim-types.cc # src/prim-types.hh # src/stage-converter.cc # src/stage.cc # src/str-util.cc # src/timesamples-pprint.cc # src/timesamples.cc # src/tinyusdz.cc # src/tydra/attribute-eval-typed-animatable-fallback.cc # src/tydra/attribute-eval-typed-animatable.cc # src/tydra/render-data-internal.hh # src/tydra/render-data.cc # src/tydra/scene-access.cc # src/usdGeom.hh # src/usdSkel.hh # src/usda-reader.cc # src/usdc-reader.cc # src/usdc-writer.cc # src/value-types.cc # src/value-types.hh # tests/unit/CMakeLists.txt # tests/unit/unit-prim-types.cc
Fix API mismatches introduced by the merge: - Fix memory_manager_ pointer dereference (. -> ->) in crate-reader.hh and MEMORY_BUDGET_CHECK/REDUCE_MEMORY_USAGE macros in crate-reader*.cc - Fix CrateReader constructor to initialize owned_memory_manager_ and point memory_manager_ to it - Fix RelationshipProperty API migration (.value() -> .relationship(), implicit bool -> .authored()) in collection-api.hh, pprint-meta.cc, sconv-geom.cc, sconv-light.cc, tydra/scene-access.cc - Add unit-usdc-reconstruct.cc to test CMakeLists.txt Increase maxTokenLength default from 4096 to 64K with improved error message suggesting CrateReaderConfig.maxTokenLength adjustment. Reduce oversized test fixture blobs (1.2MB -> 32K) to stay within token length limits. Disable 10 unit tests that depend on HEAD's CrateWriter Layer-writing path incompatible with spec-2026-mar's improved USDC reader. Document disabled tests in doc/testing-cpp.md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implement Layer-level variant writing (ConvertVariantSetSpecToFields, ConvertVariantSpecToFields) that was declared but never implemented. Fix the Layer reader's ReconstructPrimSpecNode to use unique_ptr so PrimSpecs are actually stored (was discarding all PrimSpecs due to nullptr output parameter). Fix variant field names to match crate format (variantSelection, variantSetNames with ListOp encoding). Fix nested variant support in both reader and writer paths: rfind for variant element extraction, Variant parent acceptance for VariantSets, full PrimSpec field copying during attachment. Re-enable 9 of 10 previously disabled tests (Stage nested variant roundtrip remains disabled as a separate issue). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Stage writer (stage-converter.cc): Add nested VariantSet iteration in ConvertVariantToFields so nested variant data is no longer silently dropped when writing Stage to USDC. - Layer reader (usdc-reader-reconstruct.cc): Fix is_parent_variant to use _variantPrimSpecs instead of _variantPrims during Layer reconstruction. Fix _variantPropChildren block to use PrimSpec types instead of Prim types. Add early-exit guard for Variant Attribute children already handled by BuildPropertyMap. - Re-enable usdc_stage_variant_roundtrip_test that validates Stage write→read roundtrip with nested variants. - Add usdc_layer_nested_variant_props_roundtrip_test covering nested variants with properties and child prims on the inner variant. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extract makeVariantWithProp lambda to deduplicate High/Low variant setup in usdc_layer_nested_variant_props_roundtrip_test. - Replace count()+at() double lookup with single find() in _variantPropChildren block of ReconstructPrimSpecRecursively. - Trim verbose comment to just the non-obvious WHY. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The early-exit guard in ReconstructPrimSpecNode prevents Attribute children of Variant nodes from populating _variantPropChildren during Layer reconstruction. Properties are already handled through BuildPropertyMap + _variantPrimSpecs[].props(), transferred in the _variantPrimChildren block via dest.props() = vp.props(). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rios Stage USDA→USDC→Stage roundtrip tests (unit-usdc-writer.cc): - variant_multiple_sets: two variant sets with selections on same prim - variant_props_and_children_roundtrip: properties + children in variants - variant_3level_nested: 3-level deep variant set nesting - variant_nested_with_props: nested inner variants carrying properties Strengthen existing variant_nested_test to assert nested variant set contents survive roundtrip (was a weak guard before the writer fix). Layer write→read roundtrip tests (unit-usdc-reconstruct.cc): - layer_multiple_variant_sets_roundtrip: two sets with selection metadata - layer_3level_nested_roundtrip: 3-level VariantSetSpec nesting - stage_variant_props_roundtrip: Stage variant with properties (no children) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace count()+at() with find() throughout new variant tests (~12 instances across both test files). - Extract makeVariantWithDoubleProp lambda in stage props test. - Use local ref for meta.variants.value() in multi-set test. - Verify property name "detail" in stage props test (was only checking !empty()). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add symlink-based local dev setup (npm run setup:local) so demo serves tinyusdz JS/WASM directly from ../js/src/tinyusdz/ without npm publish/install cycles - Use preserveSymlinks: true in Vite so bare imports (three, fzstd) resolve from demo's node_modules - WASM64 import uses @vite-ignore + try/catch fallback to 32-bit when tinyusdz_64.js is absent - Skip .wasm.zst static copy in dev mode - Rewrite DEVMEMO.md to document the symlink approach Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three hot-path changes found by perf profiling boston_dynamics_spot.usdz
(load) and panda-newton.usdc (renderscene conversion):
1. AsciiParser::LexFloat: std::stringstream -> stack char[64].
The stringstream caused locale init and char-by-char ostream::put
calls per float token (~63% of inclusive parse time on USDA-heavy
assets). A stack buffer with one final std::string::assign keeps
short floats in SSO and skips heap allocation entirely. Drops
tusdcat -l boston_dynamics_spot.usdz from 1.30s to 0.53s.
2. tydra::TryConvertFacevaryingToVertex{Float,Mat}: replace
HashMap<uint32_t, T> with direct-indexed std::vector<T> +
std::vector<uint8_t> seen-flags, growing lazily as vidx values
come in. Vertex indices are dense small ints, so the hashmap was
~⅔ of conversion time on USDC inputs. Drops
tydra_to_renderscene conversion on panda-newton.usdc from 33ms
to 21ms.
3. tydra_to_renderscene: add --profile flag that prints [timing]
lines for USD load and RenderScene conversion phases, so future
regressions are observable without rerunning perf.
Verified no regressions: ctest 13/13, full USDA corpus (365 files) and
USDC corpus (195 files) produce byte-identical tusdcat output pre vs
post fix, and tydra_to_renderscene output is byte-identical across all
560 corpus files plus the local sim assets (spot, panda, panda-newton,
shadow_dexee, unitree_go2). Pixar usdcat compare unchanged: USDA
360/0/5, USDC 194/0/1.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…t variants Same fix as 7ef3521 applied to ReadBasicType<int|uint32|int64|uint64> in ascii-parser-basetype.cc. The four integer lexers each constructed a std::stringstream per call, costing ~10% of total parse time on USDA-heavy assets via std::basic_ios::init / std::locale::locale / std::basic_ios::_M_cache_locale per call. A stack char[32] (sized for uint64's 22 digits + sign + slack) replaces the stream; a single std::string is built only for the final parseInt / std::stoll / std::stoull. Drops tusdcat -l boston_dynamics_spot.usdz from 0.53s to 0.48s. Verified no regressions: ctest 13/13, full USDA corpus (365 files) and USDC corpus (195 files) produce byte-identical tusdcat output pre vs post fix. Pixar usdcat compare unchanged: USDA 360/0/5, USDC 194/0/1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Char1 was an out-of-line one-liner `{ return _sr->read1(c); }` and the
profile showed it as the second-hottest function at ~15% self-time on
USDA-heavy parses, called from every per-byte scan loop (LexFloat,
SkipWhitespaceAndNewline, Expect, ReadBasicType integer/float, ...).
Moving the definition into the header lets the compiler also inline
StreamReader::read1 (already header-inline) and hoist the `_sr` pointer
load out of these hot loops, turning per-byte reads into a direct
bounds-check + load against the input buffer.
Drops tusdcat -l boston_dynamics_spot.usdz from 0.48s to 0.39s (~19%).
Verified no regressions: ctest 13/13, full USDA corpus (365 files) and
USDC corpus (195 files) produce byte-identical tusdcat output pre vs
post fix. Pixar usdcat compare unchanged: USDA 360/0/5, USDC 194/0/1.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Parse fixed-size tuples directly into their destination arrays instead of building temporary vectors, and route point3f[]/normal3f[] through the zero-copy fast tuple array parser.\n\nMeasured with tusdcat -l boston_dynamics_spot.usdz: build-prefix baseline ~0.37-0.38s, optimized build-rel ~0.17-0.18s.\n\nVerified with ctest 13/13, byte-diff USDA 365/0 and USDC 195/0, Pixar compare USDA 360/0/5 and USDC 194/0/1, and MaterialX roundtrip 19/19.
Use fast_float's returned end pointer when parsing tuple and matrix array scalars, avoiding a separate delimiter scan before each from_chars call.\n\nMeasured with tusdcat -l boston_dynamics_spot.usdz: pre-change build-prefix 0.18s, optimized build-rel 0.14-0.15s.\n\nVerified with ctest 13/13, byte-diff USDA 365/0 and USDC 195/0, Pixar compare USDA 360/0/5 and USDC 194/0/1, and MaterialX roundtrip 19/19.
Use the existing int array parser for std::vector<int32_t> and feed it a zero-copy view into the input buffer instead of rebuilding the array literal in a temporary string.\n\nMeasured with tusdcat -l boston_dynamics_spot.usdz: pre-change build-prefix 0.14-0.15s, optimized build-rel 0.13s.\n\nVerified with ctest 13/13, byte-diff USDA 365/0 and USDC 195/0, Pixar compare USDA 360/0/5 and USDC 194/0/1, and MaterialX roundtrip 19/19.
…usdz into physics-2026 Resolved web/CMakeLists.txt conflict by accepting upstream's refactored build-flag structure (TINYUSDZ_WASM_COMMON_COMPILE_OPTIONS). The Release 'speed over size' build still works under upstream's layout (CMake defaults -O3 -DNDEBUG plus SIMD via add_compile_options), with -sASSERTIONS=1 kept. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previously the reader only accepted empty/`prepend` qualifiers on the `apiSchemas` metadata, erroring out on `delete` / `append` / `add`. This blocked parsing of Newton/Omniverse-authored USDs that subtract schemas inherited from a stronger prepend on the same prim — pattern seen in newton-assets (unitree_h1/h1_minimal.usda line 84, anymal_c, allegro, dr_testmech). Changes: - Accept `prepend` / `append` / `add` / `delete` / unqualified qualifiers on `apiSchemas`. - Track `deletedNames` / `deletedUnknownSchemas` in `APISchemas` so future multi-layer composition can see what a strong layer deleted. - For single-layer files, immediately subtract deleted entries from the active `names` / `unknownSchemas` so downstream consumers see the resolved list with no API change. - Merge across multiple `apiSchemas` metadata entries on the same prim (e.g. `delete` followed by `prepend`). Verified on a minimal fixture and on Newton-asset files: prims with both `prepend apiSchemas = [...]` and `delete apiSchemas = [...]` resolve to the expected post-deletion set. Refs #271 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A `UsdShade.Material` without an authored `outputs:surface` connection used to abort the whole render-scene conversion. For pipelines that ingest Omniverse-authored USDs whose intermediate materials don't yet have a surface shader bound (common in newton-assets's unitree_g1/usd flat-USDC variants), this killed an otherwise loadable physics-only asset. Now: - Default: emit a warning and produce an unshaded material; the rest of the conversion (including physics extraction) proceeds. - Strict: set `MaterialConverterConfig.strict_material_check = true` to keep the old error-and-abort behavior. Use this when a downstream renderer requires a complete shading network and authoring gaps should fail the load. Verified on newton-assets/unitree_g1/usd/g1*.usd — all 5 USDC variants now parse + extract physics (215–592 prims each). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`MaybeNonFinite` correctly detected the candidate tokens but never advanced the cursor past them — `SeekTo(loc)` rewound after the peek and the success branches returned `true` without re-advancing. Result: the caller saw a successful float read but the cursor still pointed at `i`, then the next "expect newline" failed with the misleading "Newline expected after property statement" message. Now `try_match` advances `n` chars, peeks the next char to reject identifier prefixes (`info`, `infrared`), and rewinds on rejection. Verified on Newton-asset files: - anybotics_anymal_c/usd/anymal_c.usda (`-inf`/`inf` on joint limits): now loads 17 bodies / 16 joints - disneyresearch/dr_testmech/usd/dr_testmech.usda (`inf` on drive maxForce): now loads 10 bodies / 14 joints Refs #272 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…"` strings Two parser gaps blocking Omniverse-authored Newton-asset USDs: 1. `apiSchemas = None` (and other array-typed `meta = None`): `ParseMetaValue` now peeks for `None` before attempting `[` parsing on array-typed metas, storing `value::ValueBlock` on match. `ReconstructPrimMeta`'s `apiSchemas` branch handles the ValueBlock case by clearing the resolved list (semantically equivalent to `apiSchemas = []` with `ResetToExplicit`). 2. Multi-line `\"\"\"...\"\"\"` strings in attribute metas (e.g. `doc = \"\"\"multi-line MDL shader doc\"\"\"`): `ReadStringLiteral` previously had a TODO and only handled single-line `\"...\"`. Now peeks 3 chars and delegates to `MaybeTripleQuotedString` for triple-quoted input, falling back to single-line on non-triple-quote. Refs #273 #274 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
One fixture per recently-fixed parser/strictness gap, each exercising the specific code path that was broken — distinct from existing tests: - apishcema-delete-000.usda: `delete apiSchemas` list-op, mixed with `prepend` on same prim (issue #271). - fp-inf-nan-scalar.usda: scalar `-inf`/`inf`/`nan` on typed attribute values (issue #272). The array form is already covered by fp-inf-nan.usda; the scalar path goes through a different `ReadBasicType(float|double)` branch that was independently broken. - apishcema-none-000.usda: `apiSchemas = None` as prim-meta ValueBlock (issue #273). Distinct from none-001.usda which exercises typed attribute `None` on a primvar. - attr-meta-multiline-string-000.usda: multi-line `"""..."""` doc inside the attribute `(...)` meta block (issue #274). Distinct from stage-meta-multiline-string.usda which exercises a stage meta — those went through `ReadStringLiteral` from the property meta scanner. Also widen the gitignore whitelist for tests/usda/*.usda so future fixtures don't need `-f` to be added (mirrors the existing tests/usda/spec/*.usda whitelist). All 4 round-trip cleanly through tusdcat. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two Omniverse-authored USD patterns previously caused render-scene conversion to abort on otherwise loadable assets: 1. Shader with `info:id` declared but unset (e.g. `uniform token info:id` with no `= "..."`). Common for MDL shaders where the real identity comes from `info:implementationSource` + `info:mdl:sourceAsset`. Added `PrimReconstructOptions::strict_shader_check` (default false). In non-strict mode the parser emits a warning and reconstructs as a generic ShaderNode. In strict mode the previous error is kept. 2. `rel material:binding` with no target paths (declaration-only with `bindMaterialAs` metadata, or `= None`) or with a target path that doesn't resolve in the current stage. Both are valid USD authoring patterns — declaration-only signals "no material here, inherit from parent"; dangling targets are common when a material is composed in from a sublayer that was dropped. Demoted the misleading `must be single targetPath` error in GetDirectlyBoundMaterial to a silent `return false`, and made the find_prim_at_path lookup use a local error string that's swallowed on failure. The caller's parent-walk already handles "no binding here" gracefully, so propagating these errors only sabotaged otherwise loadable assets. Verified on newton-assets: - unitree_h1/usd/h1_minimal.usda: now loads 22 bodies / 19 joints - wonik_allegro/usd/allegro_left_hand_with_cube.usda: now loads 26 bodies / 22 joints Tests: - tests/usda/shader-info-id-unset.usda - tests/usda/material-binding-no-target.usda No regressions on go2, dr_legs, anymal_d/c, panda, spot, dr_testmech, g1 variants, or the menagerie corpus. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The `tydra_material_binding_validation_test` block at line 900-923 asserts that conversion fails with "outputs:surface isn't authored". After 9905944 demoted that error to a warning by default, the test needs to opt into strict mode (`material_config.strict_material_check = true`) to exercise the error path the assertions check. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Rewrite index.html as a dark/flat, responsive static landing page (inline CSS, no external stylesheet) with hero, demo preview frame, feature grid, and GitHub/npm/PyPI links. - Move the Three.js viewer to viewer.html; index.html is now the entry landing page. Add viewer.html to vite rollup input; repoint the demos.html "Basic USDZ loading" card to viewer.html. - Swap dat.gui jsdelivr CDN import for the bundled lil-gui dependency in main.js, usda-load.js, example-composition.js so the demo is fully self-contained on static hosts (GitHub Pages, no CORS headers). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-2026 Integrates the physics-2026 branch (Newton physics schema, urdf-to-usd converter, USDA parser perf work and gap fixes, web demo redesign) into dev-rc0 (TinySubdiv backend, nested variant support, Pixar USDC crate-format compatibility fixes). The two branches had a rewritten/divergent commit graph with no useful merge-base (degenerate base from 2020 -> 199 add/add conflicts). Used the true content-identical fork point as the merge base via a temporary `git replace --graft` (dev-rc0 a838958 == physics-2026 4b0171e, both "add unit test file.", identical trees), reducing real conflicts to 3: - .gitignore: union of both ignore lists - src/tydra/render-data-mesh.cc: keep both subdiv.hh and safe-arithmetic.hh includes - web/demo/package-lock.json: regenerated via npm install against the union-merged package.json Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The roundtrip/runtime tests emit tests/usdc/{memory-budget,variant}-*-runtime.usdc.
These were already covered by the broad `*.usdc` rule; add explicit,
documented patterns so it's clear they are generated and not fixtures.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The roundtrip tester globbed tests/usdc/*.usdc, which swept in the test-generated *-runtime.usdc files (now gitignored) and reported them as 11 spurious errors. Filter them out of glob-expanded file lists; they can still be passed explicitly for targeted debugging. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Prefer ../OpenUSD/dist/bin/usdcat (a recent OpenUSD build, currently v0.26.3) over the old ~/local/USD build (pxr 23.08) when present; fall back to the old path otherwise. USDCAT_PATH still overrides. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Claude finished @syoyo's task —— View job Code Review Complete ✅I've thoroughly reviewed this major development release candidate PR. Here's my comprehensive assessment: Review Tasks
📝 Review SummaryThis is a substantial and well-structured release candidate that significantly expands TinyUSDZ's capabilities. The changes demonstrate high code quality with strong attention to security, testing, and maintainability. ✅ Strengths
|
No description provided.