-
Notifications
You must be signed in to change notification settings - Fork 46
Usd import rework #358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Usd import rework #358
Changes from all commits
Commits
Show all changes
78 commits
Select commit
Hold shift + click to select a range
612d65b
docs(usd): specify USD Stage import rework
jeffamstutz b5bab5c
build(usd): add imaging + OpenSubdiv deps and make TSD_USE_USD public
jeffamstutz 70b8120
feat(usd): import Stages through a Hydra scene index
jeffamstutz 3d96fa1
fix(usd): correct clocks, sharing, and refinement gaps found in review
jeffamstutz 2aacbc5
feat(usd): emit native MaterialX materials when OpenUSD can convert them
jeffamstutz 6275e18
feat(usd): add a USD_MATX Importer Type for native MaterialX import
jeffamstutz febd2a0
fix(usd): anchor MaterialX texture paths before the document leaves TSD
jeffamstutz 16b390c
feat(usd): bind samplers to MaterialX texture inputs
jeffamstutz ce96a38
feat(io): decode TIFF textures via optional OpenImageIO
jeffamstutz 253118a
fix(core): teach tsd::Any that std::string is ANARI_STRING
jeffamstutz d6ae939
docs(adr): record why UDIM tile sets are reported, not approximated
jeffamstutz 19904db
fix(io): match stb's texel contract in the OpenImageIO path
jeffamstutz 274304a
docs(usd): record why mdlResourceSearchPaths cannot silence the MDL n…
jeffamstutz 404a8e2
fix(usd): reject MaterialX documents the device cannot compile
jeffamstutz 56ac4b0
fix(usd): give GeomSubsets the face-varying attributes they draw
jeffamstutz 25df87e
fix(usd): keep face-varying primvars on already-triangulated meshes
jeffamstutz fe8eaec
docs(style): require non-owning members be pointers, not references
jeffamstutz bb15951
docs(io): propose one image-import path with a stated orientation
jeffamstutz f9ebb0d
test(io): characterize image orientation across the importers
jeffamstutz 98b536a
refactor(io): put every image decode behind one ImageCache
jeffamstutz 82d68e1
fix(io): store decoded images in ANARI orientation
jeffamstutz e321b4d
refactor(io): route HDRI radiance through the image cache
jeffamstutz 9d15b55
fix(io): address code review of the image import path
jeffamstutz 56a9dd8
docs(io): record what landed and what is left of the image import
jeffamstutz 86a5501
fix(io): scale default curve/point radius to prim bounds on USD import
jeffamstutz b57afb8
rename matx --> mtlx
jeffamstutz dcd0fbe
fix(io): store decoded images top-down, as ANARI addresses them
jeffamstutz 6bfabc9
fix(tests): read image texels through helium instead of dataAs<uint8_t>
jeffamstutz 0835572
fix(tsd): compile error in optionally compiled region
jeffamstutz e342ec1
feat(io): support animated USD scenes via a shared Stage Session
jeffamstutz 0ccece9
fix(io): address code review of the animated USD import
jeffamstutz 45ef85a
refactor(io): split USD geometry conversion into resolve and build
jeffamstutz 1cc6b15
fix(io): address code review of the converter split
jeffamstutz 463cd80
fix(rendering): re-copy instance transforms when a transform Array is…
jeffamstutz 9595315
feat(io): map OmniPBR materials onto the portable material again
jeffamstutz 6ae6afa
refactor(io): make resolveMaterial a dispatcher over one material cache
jeffamstutz 9010894
fix(io): keep the Import's Animation reachable when another one is added
jeffamstutz a4eb07c
refactor(io): store ImportContext's non-owning members as pointers
jeffamstutz 0ef1079
refactor(io): store Traversal's non-owning members as pointers
jeffamstutz 6ab95b7
refactor(io): store the subdivision refiners' TopologyRefiner as a po…
jeffamstutz bf03c59
test(io): split the USD import suite by subject
jeffamstutz f13521d
test(io): collapse the USD import per-scenario preamble
jeffamstutz cebdf59
test(io): address code review of the USD import suite split
jeffamstutz 6a82579
refactor(io): move UsdVol conversion onto the shared spatial field di…
jeffamstutz cfeb64f
refactor(io): teach the spatial field dispatcher '.vdb'
jeffamstutz 473bdba
fix(io): address code review of the USD volume split
jeffamstutz 95d53ed
fix(io): convert the materials EnSight carrier prims bind
jeffamstutz 586cb41
docs(io): drop the restated "what" above boundMaterialOf
jeffamstutz 3a55998
fix(io): correct why a Claimed carrier's material is still reachable
jeffamstutz 9e4c0df
refactor(io): report every skipped USD prim from one place
jeffamstutz ee0598b
test(io): cover a UsdVol Volume whose field file is missing
jeffamstutz d0f99ac
refactor(io): let an ImageCache alone say which Scene a Sampler joins
jeffamstutz 0dcf19d
docs(io): record that the texture import shims stay
jeffamstutz 0caf746
refactor(io): stop building a one-call ImageCache for HDRI radiance
jeffamstutz ece64a1
test(io): pin the compressed sampler's format and size parameters
jeffamstutz baa79a0
refactor(io): let an Image carry its own format and dimensions
jeffamstutz a0a72e9
refactor(io): let NetworkWalker read a string-or-token shader input
jeffamstutz 904e3dd
refactor(io): build every non-dome light through one helper
jeffamstutz 5825c98
docs(io): reword makeLight's comment around why, not what
jeffamstutz dcacba4
refactor(io): record only the nodes native instancing places on
jeffamstutz b422918
build(io): regroup the source list by directory again
jeffamstutz 8a72d3d
refactor(io): find the native instancers through one shared walk
jeffamstutz 6e0c1a0
test(io): compare the empty-mesh material count against an empty Scene
jeffamstutz eb55470
style(io): clang-format the split USD import test files
jeffamstutz 1fccb4a
fix(io): check the magic before handing a file to the NanoVDB reader
jeffamstutz 7bcc7f0
test(io): cover the HDF5 half of the shared spatial-field dispatcher
jeffamstutz 53a3daf
fix(io): let fileOf() name a file that was given no directory
jeffamstutz a41fbc3
refactor(io): stop guarding importers on a filename being non-empty
jeffamstutz b681fd1
test(io): pin what an EnSight carrier's material outranks
jeffamstutz 3e49027
fix(io): let pathOf() keep the separator the path already used
jeffamstutz 728d48f
refactor(io): make the image cache the only way to name a Sampler's S…
jeffamstutz 15cc0b3
refactor(io): stop handing PBRT's light converter a cache it never uses
jeffamstutz 007459b
refactor(io): stop ImportContext from being copyable
jeffamstutz 4b18512
docs(io): correct the shim call-site count and the cache inventory
jeffamstutz 175ee2b
docs(io): say which images the orientation contract owns
jeffamstutz 04338ab
test(io): pin where each USD light type puts its brightness
jeffamstutz 062f1c7
style(io): clang-format one call in UsdInstancing
jeffamstutz 6e164e0
refactor(io): declare InstancerRegistry's copy and move intent
jeffamstutz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # Store images in ANARI orientation | ||
|
|
||
| A decoded image resident in a TSD Scene is stored in ANARI orientation: the | ||
| array's row 0 is the top row of the picture, because ANARI addresses texture | ||
| coordinate `(0, 0)` at the image's upper-left corner. Importers hand ANARI | ||
| texture coordinates in ANARI's convention, converting from the source format's | ||
| where they differ — glTF's `v` already runs down the image and is passed | ||
| through, while OBJ, USD, PBRT, and ASSIMP are all v-up and have their `v` | ||
| reversed. A format that also carries a uv transform of its own has it | ||
| conjugated by that reversal rather than flipped twice: PBRT's `vscale`/`vdelta` | ||
| and USD's `UsdTransform2d` both become `vs*v + (1 - vs - vd)`. | ||
|
|
||
| Decoders declare the row order their library produced and `ImageCache` | ||
| normalizes; no importer flips texels itself. Previously each of seven decode | ||
| paths carried its own unstated assumption, and the assumptions cancelled for | ||
| glTF, ASSIMP, and PBRT but not for OBJ and USD, whose textures rendered | ||
| mirrored. Two consequences follow from the contract: a cached image bound | ||
| somewhere that is not an image sampler asks `ImageCache` for the order that | ||
| consumer wants — a USD dome light's `radiance` runs bottom-up, so it says so | ||
| on its `ImageSource`; and block-compressed DDS, whose 4×4 blocks cannot be | ||
| row-reversed without decoding and re-encoding, would stay as authored and | ||
| instead get a `v`-flip composed into its sampler's `inTransform`/`inOffset` | ||
| — which is why `makeImageSampler` owns those two parameters outright and takes | ||
| the importer's own uv transform through `SamplerSettings`. Neither reversal | ||
| runs today: every decoder in `io/images/detail/decoders.hpp` emits top-down | ||
| rows, which is what a sampler asks for, so both paths are dormant rather than | ||
| dead. | ||
| The one loader that produces bottom-up rows, `importers/detail/HDRImage.h`, is | ||
| not one of those decoders, and its only cached consumer asks for bottom-up | ||
| delivery — so there is nothing to normalize there either. | ||
|
|
||
| This contract governs images the Image Cache owns. A radiance array bound to an | ||
| `hdri` light may be built without the cache and is not covered: `import_HDRI` | ||
| decodes exactly one image per call, so a cache scoped to the call can never be | ||
| hit, and PBRT's infinite light resamples equal-area to equirectangular, so what | ||
| it binds is not the decoded image and could not be keyed as one. Both keep the | ||
| bottom-up rows `HDRImage` produced, which is the order an `hdri` light wants. |
17 changes: 17 additions & 0 deletions
17
tsd/docs/adr/0015-import-usd-through-a-hydra-scene-index.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # Import USD through a Hydra scene index | ||
|
|
||
| TSD imports USD stages by consuming a UsdImaging scene index chain rather than | ||
| traversing UsdGeom and UsdShade schemas directly. Composition, purpose and | ||
| visibility resolution, native and point instancing, material binding and render | ||
| context selection, primvar interpolation, implicit-shape conversion, NURBS | ||
| approximation, and skinning are all resolved by OpenUSD's own filtering scene | ||
| indices; the importer contributes one converter per Hydra prim type and nothing | ||
| more. The stage stays open alongside the scene index, so TSD-specific data that | ||
| Hydra does not model — `customData` carriers, `anari:` and `tsd:io:` attributes, | ||
| render settings — is still read directly from prims by path. This costs links | ||
| against `hd`, `usdImaging`, `hio`, and `hdsi`, and requires working in | ||
| data-source idioms rather than schema APIs, but it removes the class of silent | ||
| omissions that a hand-rolled traversal accumulates one unhandled prim type at a | ||
| time. A Hydra render delegate was rejected for the same job: it is a push-based | ||
| sync architecture for repeated frame updates, not a one-shot conversion into a | ||
| scene the user then edits by hand. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # Bake prototype-internal transforms when importing instanced USD content | ||
|
|
||
| `TransformsToAnariVisitor` never pushes a transform-array node's matrices onto | ||
| the transform stack, so a transform node nested beneath one composes against | ||
| that array node's ancestors instead: its subtree renders once, un-instanced, | ||
| rather than once per instance. Transform-array nodes are therefore leaf-only | ||
| instancing, while USD prototypes are typically `Xform` subtrees holding several | ||
| gprims at their own local transforms. The importer resolves this by importing | ||
| each prototype exactly once into shared TSD objects and baking each gprim's | ||
| prototype-root-relative transform into its vertex data, leaving a flat set of | ||
| Surfaces that a transform-array node may legally instance; a point instancer | ||
| becomes one transform-array node and a native instance becomes one mat4 node | ||
| reusing the same objects. Baking is cheap precisely because a prototype is | ||
| imported once regardless of instance count. Prototypes whose internal transforms | ||
| are themselves animated cannot be baked and fall back to expanded per-instance | ||
| transform nodes. Do not "correct" the baked vertex data without first changing | ||
| how the render index composes transform-array nodes. |
15 changes: 15 additions & 0 deletions
15
tsd/docs/adr/0017-deviate-from-usdview-defaults-for-purpose-and-subdivision.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # Deviate from usdview defaults for purpose and subdivision | ||
|
|
||
| USD import is judged by visual parity with a reference Hydra render, and two | ||
| import defaults deliberately differ from stock usdview anyway. usdview defaults | ||
| to `showProxy(true)` and `showRender(false)`, so it displays proxy stand-in | ||
| geometry; TSD imports `default` + `render` because it renders with a path tracer | ||
| for which proxy assets are the wrong input, and because an asset whose real | ||
| content sits behind `purpose=render` would otherwise import as its bounding-box | ||
| card. usdview defaults to complexity 1.0, which maps to refinement level 0 and | ||
| draws subdivision meshes as their unrefined control cage; TSD refines with | ||
| OpenSubdiv by default so silhouettes are correct. Both are configurable through | ||
| `UsdImportOptions`, and any parity comparison must set matching purpose and | ||
| Complexity on the reference render before treating a difference as a defect. | ||
| Neither deviation is a bug, and neither should be "aligned" with usdview without | ||
| revisiting this decision. |
20 changes: 20 additions & 0 deletions
20
tsd/docs/adr/0018-let-imported-scenes-retain-an-open-usd-stage.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # Let imported scenes retain an open UsdStage | ||
|
|
||
| Time-varying geometry is imported as one eager first frame plus a `FileBinding` | ||
| that re-pulls point and index arrays from the still-open stage and scene index | ||
| at time `t`, rather than baking every sampled frame into TSD Arrays. Baking a | ||
| hundred-frame, million-vertex mesh costs on the order of a gigabyte per mesh, | ||
| while the lazy binding keeps memory flat regardless of frame count and follows | ||
| the pattern `EnSightFileBinding` and `SpatialFieldFileBinding` already | ||
| establish. The consequence is that import is not a fully detached operation for | ||
| animated content: an imported scene's lifetime holds a `UsdStage` and its scene | ||
| index, serialization records file and prim paths and reconstructs by re-opening | ||
| rather than by copying data, scrubbing performs real work per frame, and stage | ||
| access must be accounted for when a scene is used across threads. Static content | ||
| carries no such dependency. | ||
|
|
||
| Amended by | ||
| [ADR 0021](0021-share-one-usd-stage-session-across-import-and-animation.md): the | ||
| retained stage is now a Stage Session shared with the import rather than one the | ||
| binding opens for itself, and the scene index it holds really is retained, which | ||
| the code this ADR described did not do. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| # Report UDIM tile sets as unsupported rather than approximate them | ||
|
|
||
| A MaterialX `filename` input whose path contains a `<UDIM>` marker names a set | ||
| of tiles, not a file. `UsdMaterials.cpp` reports such an input as | ||
| `TEXTURE_LOAD_FAILED` with `(tiled texture sets are not supported)` and binds no | ||
| sampler, while still writing the anchored absolute path into the generated | ||
| document. On the OpenPBR Shader Playground reference asset that accounts for 89 | ||
| of the importer's 100 skipped prims -- every remaining texture failure after | ||
| TIFF decoding landed. | ||
|
|
||
| Two routes were investigated and both are closed at the level TSD can reach. | ||
|
|
||
| The device cannot resolve the tile set on TSD's behalf. VisRTX does load MDL | ||
| texture resources from disk -- `SamplerRegistry::loadFromImage` reads | ||
| `textureDesc.url` with stb -- but `libmdl::Core::resolveResource` returns | ||
| `get_element(0)->get_filename(0)`, a single filename. MDL's entity resolver | ||
| returns one element per tile for a `<UDIM>` resource; VisRTX discards all but | ||
| the first, and `loadFromImage` then builds exactly one `Image2D`. Nothing in | ||
| `devices/` carries a UDIM concept. So MDL's native `<UDIM>` support, which is | ||
| real, is not plumbed through this device at all, and setting | ||
| `mdlResourceSearchPaths` -- the seam that would fix the cosmetic | ||
| `Failed to resolve texture resource` log noise -- would not change the outcome. | ||
| Enabling it properly means multi-tile resolution in libmdl, a tile-indexed | ||
| texture in the MDL runtime PTX, and a representation for tiled textures in | ||
| ANARI, which has none: an ANARI sampler is a single image. | ||
|
|
||
| TSD cannot expand the tiles either, for the same reason. Rewriting the | ||
| MaterialX network into per-tile branches is a large amount of machinery, and | ||
| the obvious shortcut -- binding tile 1001 and dropping the rest -- is wrong for | ||
| every mesh that actually spans more than one tile, and worse, it converts a | ||
| reported gap into a silently incorrect render. | ||
|
|
||
| The gap is therefore left reported rather than approximated. Two properties | ||
| make that a deliberate stance and not neglect: the skip is counted in the | ||
| import report with a reason, so the cost is visible, and the anchored absolute | ||
| path is still written into the document, so a consumer that gains UDIM support | ||
| finds a well-formed path waiting. `SdfAssetPath::GetResolvedPath()` is empty | ||
| for every UDIM path -- a `<UDIM>` path names no file, so no resolver resolves | ||
| it -- which is why that path comes from `UsdMaterials.cpp`'s Stage-directory | ||
| fallback anchor rather than from USD's own resolution. | ||
|
|
||
| Revisit this when ANARI gains a tiled-texture or texture-array sampler, or when | ||
| VisRTX's MDL runtime grows tile-indexed lookup. Until one of those exists, | ||
| "supporting UDIM in TSD" has nowhere to send the texels. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| # Bind mesh attributes per Surface, not once per mesh | ||
|
|
||
| A USD Mesh with `GeomSubset` children converts to one TSD Surface per subset. | ||
| `UsdGeometry.cpp` used to build the attribute set once, on the parent mesh, and | ||
| let each subset borrow it through a hard-coded list of `vertex.normal`, | ||
| `vertex.attribute0`, and `vertex.color`. That works only for vertex-interpolated | ||
| data, which is indexed by the same vertex indices the subset already carries. | ||
|
|
||
| Face-varying data is not. It is indexed by `3 * triangle + corner` against the | ||
| mesh's full triangulation, so a subset -- which draws a chosen subset of those | ||
| triangles -- cannot point at the parent array; the corners it wants are not | ||
| contiguous and not at the offsets its own primitives imply. The same is true of | ||
| uniform data, which the importer expands to one value per triangle. Sharing was | ||
| therefore not merely incomplete, it was unavailable: assets authoring | ||
| `interpolation = "faceVarying"` texture coordinates -- which is what USD assets | ||
| overwhelmingly do -- rendered their subsets with no UVs at all. | ||
|
|
||
| Attributes are now expanded onto the triangulation once per mesh | ||
| (`triangulatePrimvars`) and then *gathered* per Surface for the triangles that | ||
| Surface draws (`buildTriangleGeometry`). Vertex-interpolated primvars still | ||
| create a single Array shared by every Surface, because for them the gather is | ||
| the identity; only per-triangle and per-corner data is copied per subset. The | ||
| cost of the copy is the price of correctness, and it is bounded by the size of | ||
| the mesh however many subsets divide it. | ||
|
|
||
| Two consequences follow from moving the binding to the Surface. | ||
|
|
||
| A subset can resolve its own material's UV primvar name. `ResolvedMaterial` | ||
| carries the primvar its texture reader asked for, and that answer now reaches | ||
| the geometry the material is bound to, instead of the mesh-level binding | ||
| deciding `attribute0` for subsets it knows nothing about. A subset without its | ||
| own answer falls back to the mesh's, then to the conventional `st`. | ||
|
|
||
| Faces that no subset claims become their own Surface under the mesh's material. | ||
| Previously the parent geometry was built, populated, and then never surfaced | ||
| when subsets existed -- unassigned faces were invisible and the objects were | ||
| dead weight in the scene. USD's own model is that a face outside every | ||
| `materialBind` subset keeps the mesh's binding, so that is what it gets. | ||
|
|
||
| One older gap is now easier to see and is deliberately left alone. `GeomSubset` | ||
| indices name coarse faces, but when a mesh is refined (ADR 0017 leaves | ||
| `refinementLevel` at 2) the triangulation this code selects from describes | ||
| *refined* faces, so a subset over coarse face 1 of a `catmullClark` quad pair | ||
| picks up refined face 1 -- 2 triangles rather than the 32 that face became. | ||
| Correcting it means carrying OpenSubdiv's refined-to-coarse face mapping out of | ||
| `refineMesh`, which is its own change; it is called out here so the leftover | ||
| Surface's suddenly-visible triangle count is not read as a regression from this | ||
| one. | ||
|
|
||
| The appeal to `materialBind` above is approximate in one respect, also unchanged | ||
| by this work: the importer treats every `geomSubset` child as a material subset, | ||
| because `HdGeomSubsetSchema` exposes only `type` and `indices` -- the scene | ||
| index does not carry `familyName`. A face claimed by a subset from some other | ||
| family is therefore counted as claimed and stays out of the leftover Surface. | ||
| Assets in the wild author `materialBind` subsets under a Mesh; if one appears | ||
| that does not, the family will have to be recovered from the Stage rather than | ||
| from the scene index. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.