Skip to content

USDC Parser Parity Notes

This document maps @cinevva/usdjs's USDC (.usdc) decoding to Pixar's reference implementation in OpenUSD.

Reference Files (Pixar/OpenUSD)

  • ValueRep / structural reader: pxr/usd/sdf/crateFile.h, pxr/usd/sdf/crateFile.cpp
  • TypeEnum numeric values: pxr/usd/sdf/crateDataTypes.h
  • Integer compression API: pxr/usd/sdf/integerCoding.h (+ implementation in integerCoding.cpp)

All OpenUSD sources referenced below are from the pixaranimationstudios/openusd repo (branch dev).


ValueRep: Bit Layout and Semantics

Pixar defines Sdf_CrateFile::ValueRep as a packed uint64:

BitsNameDescription
63IsArrayValue is an array
62IsInlinedValue is inlined in the payload
61IsCompressedValue uses compression
60IsArrayEditValue is an array edit operation
55..48TypeEnum8-bit type identifier
47..0Payload48-bit payload (offset or inlined value)

See ValueRep in pxr/usd/sdf/crateFile.h.

In @cinevva/usdjs

We extract type with (rep >> 48) & 0xFF and flags with (rep >> 56) & 0xFF:

  • 0x80 → array
  • 0x40 → inlined
  • 0x20 → compressed
  • 0x10 → arrayEdit

Implementation: src/usdc/parser.ts (decodeValueRep).


TypeEnum Numeric Values

Pixar's crateDataTypes.h defines the authoritative enum values (changing them breaks compatibility).

@cinevva/usdjs mirrors these values in its internal ValueType enum:

TypeValueNotes
Invalid0
Bool1
UChar2
Int3
UInt4
Int645
UInt646
Half7
Float8
Double9
String10
Token11
AssetPath12
Matrix2d13
Matrix3d14
Matrix4d15
Quatd16
Quatf17
Quath18
Vec2d19
Vec2f20
Vec2h21
Vec2i22
Vec3d23
Vec3f24
Vec3h25
Vec3i26
Vec4d27
Vec4f28
Vec4h29
Vec4i30
Dictionary31
TokenListOp32
StringListOp33
PathListOp34
ReferenceListOp35
IntListOp36
Int64ListOp37
UIntListOp38
UInt64ListOp39
PathVector40
TokenVector41
Specifier42
Permission43
Variability44
VariantSelectionMap45
TimeSamples46
Payload47
DoubleVector48
LayerOffsetVector49
StringVector50
ValueBlock51
Value52
UnregisteredValue53
UnregisteredValueListOp54
PayloadListOp55

Structural Sections

Pixar's CrateFile::_ReadStructuralSections() reads:

SectionDescription
TOKENSToken strings (compressed in newer versions)
STRINGSTokenIndex[] indirection table
FIELDSField{TokenIndex, ValueRep} pairs
FIELDSETSRuns of FieldIndex terminated by default index
PATHSCompressed path tree arrays
SPECSCompressed specs arrays

See pxr/usd/sdf/crateFile.cpp (_ReadTokens, _ReadStrings, _ReadFields, _ReadFieldSets, _ReadCompressedPaths, _ReadSpecs).

In @cinevva/usdjs, these are handled in src/usdc/parser.ts via readTokens/readStrings/readFields/readFieldSets/readPaths/readSpecs.


TimeSamples Encoding

Pixar encodes TimeSamples as:

  1. int64: relative offset to the timesRep ValueRep
  2. At timesRep: ValueRep for the times container (typically DoubleVector)
  3. int64: relative offset to the values area
  4. At values area: uint64 numValues, then numValues contiguous ValueRep

See CrateFile::_Reader::Read<TimeSamples>() in pxr/usd/sdf/crateFile.cpp.

In @cinevva/usdjs

  • We decode this layout and materialize a Map<number, SdfValue> attached to SdfPropertySpec.timeSamples
  • We match the observable USDA shape usdcat produces for stable comparisons

Implementation: src/usdc/parser.ts (ValueType.TimeSamples case + addProperty wiring).


Compressed Float/Double Arrays (Crate 0.6.0+)

Pixar supports compressed floating point arrays using:

CodeMethod
'i'Floats stored as compressed int32s
't'Lookup table + compressed indexes

See _ReadPossiblyCompressedArray() specializations in pxr/usd/sdf/crateFile.cpp.

In @cinevva/usdjs, we implement the same format for float[] and double[] and validate against the external corpus.


Known Gaps (Intentional)

  • ArrayEdits (ValueRep::IsArrayEdit): not decoded as a first-class value yet
  • Some TypeEnum cases not exercised by our corpus are not fully implemented (e.g., Spline, Relocates)

These will be addressed as real-world files requiring them are encountered.

Released under the MIT License.