Skip to content

Commit c4f7d7d

Browse files
TMHSDigitalclaude
andauthored
fix(examples): redesign gltf-export-roundtrip as one crate under its re-imported wire cage (#273)
The review found two identical crates labelled AUTHORED and ROUND-TRIP in small floor text. Nothing differed between them, so the eye had nothing to find. The hero is now one crate. The solid crate is the authored one. Laid over it is the actual re-imported mesh (the file's own triangles), drawn as a thin amber wire cage through a render-only Weld + Wireframe display stack, and masked to the right of a vertical cut. Neither object is moved: both keep the identity transform that check 13 proves, and the camera does the turning. The cage lands on every bevel, rivet and vent slat only because the importer undid the +Y-up bake exactly. A probe that puts back the missing quarter turn drops the cage through the floor, and the framing gate fails too (bottom margin 0.000). The crate grows from 35 to 43 box shells: vent slats under each carry handle and stiffening ribs across the lid. The trim is a lighter gunmetal and the paint a warmer olive. On the render path only, the authored copy gets noise-mottled paint and trim. The check logic is unchanged; its closed-form counts follow PARTS (344 cage verts, 9,288 evaluated loops). The render path now also runs gallery_asset_quality on the authored crate, with its 11 remapped to 23. The bevel is baked into the display mesh first, because the edge measure reads Object.data, which is still the square cage. The floor text is gone. read_gltf now opens the JSON with encoding="utf-8". scripts/asset_sheet.py gains a SELECT row. Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent f917bd6 commit c4f7d7d

11 files changed

Lines changed: 322 additions & 145 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,7 @@ portable path is `radius`.
832832
<table>
833833
<tr>
834834
<td width="46%" valign="middle">
835-
<a href="examples/gltf-export-roundtrip/"><img src="examples/gltf-export-roundtrip/preview.webp" alt="glTF export round-trip: two identical olive-drab sci-fi supply crates turned three-quarter on a dark studio floor - authored beside re-imported - with teal status strips, riveted panels, and corner armor, proving the export/import round-trip preserves the asset" /></a>
835+
<a href="examples/gltf-export-roundtrip/"><img src="examples/gltf-export-roundtrip/preview.webp" alt="glTF export round-trip: one olive-drab sci-fi supply crate on a dark studio floor, its right half traced by an amber wire cage of the re-imported glTF triangles that lands exactly on every bevel, rivet and vent slat, proving the export/import round-trip preserves the asset" /></a>
836836
</td>
837837
<td valign="middle">
838838

61.6 KB
Loading
49.1 KB
Loading
1.91 KB
Loading

‎docs/gallery/gltf-export-roundtrip/index.html‎

Lines changed: 149 additions & 68 deletions
Large diffs are not rendered by default.

‎docs/gallery/index.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ <h2><a href="vse-cut-list/">vse-cut-list</a></h2>
607607
</article>
608608
<article class="card" data-tags="export uv">
609609
<a class="card-media" href="gltf-export-roundtrip/" tabindex="-1" aria-hidden="true">
610-
<img src="assets/gltf-export-roundtrip-hero.webp" alt="Two identical olive equipment crates with cyan light strips, both turned to show a side, labelled AUTHORED and ROUND-TRIP." loading="lazy" decoding="async" />
610+
<img src="assets/gltf-export-roundtrip-hero.webp" alt="One olive sci-fi supply crate with a cyan light strip, its right half traced by an amber wire cage of the re-imported glTF triangles that lands exactly on every bevel, rivet and vent slat." loading="lazy" decoding="async" />
611611
</a>
612612
<div class="card-body">
613613
<h2><a href="gltf-export-roundtrip/">gltf-export-roundtrip</a></h2>

‎examples/gallery.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@
329329
"name": "gltf-export-roundtrip",
330330
"dir": "examples/gltf-export-roundtrip",
331331
"teaches": "A sci-fi supply crate exported to glTF and re-imported, verifying the round-trip against the depsgraph-evaluated mesh within float tolerances. Positions, loop normals, box-mapped UVs, and per-triangle material bindings must all survive; the on-disk JSON proves the +Y-up conversion and the V-flipped UV layout.",
332-
"alt": "Two identical olive equipment crates with cyan light strips, both turned to show a side, labelled AUTHORED and ROUND-TRIP.",
332+
"alt": "One olive sci-fi supply crate with a cyan light strip, its right half traced by an amber wire cage of the re-imported glTF triangles that lands exactly on every bevel, rivet and vent slat.",
333333
"witnessesFix": "export_yup bakes (x, y, z) -> (x, z, -y) into the vertex data with no node rotation (probed identical on 4.5.11 and 5.1.2); export_apply ships the evaluated mesh, not the base cage; exporter/importer RNA is guarded so a future kwarg rename fails loudly.",
334334
"hero": "docs/gallery/assets/gltf-export-roundtrip-hero.webp",
335335
"preview": "examples/gltf-export-roundtrip/preview.webp",

‎examples/gltf-export-roundtrip/README.md‎

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# glTF Export Round-Trip
22

3-
A runnable example that builds a sci-fi supply crate — 35 beveled box shells with
4-
three material slots and box-mapped UVs — exports it with
3+
A runnable example that builds a sci-fi supply crate — 43 beveled box shells (body, lid with
4+
stiffening ribs, corner armour, carry handles over vent slats, latches, rivets,
5+
a status plate with glowing pips) with three material slots and box-mapped UVs — exports it with
56
`bpy.ops.export_scene.gltf`, parses the file on disk, re-imports it, and verifies
67
the whole round-trip against the depsgraph-evaluated mesh, following
78
[`depsgraph-and-evaluated-data`](../../skills/depsgraph-and-evaluated-data/SKILL.md)
@@ -22,9 +23,9 @@ often gets silently wrong.
2223
lying on its back.
2324
- **`export_apply=True` ships the evaluated mesh, not the base cage.** The
2425
crate's bevel modifier lives only in the depsgraph; with flat shading and UV
25-
seams the exporter splits exactly one vertex per evaluated loop (7,560), so
26+
seams the exporter splits exactly one vertex per evaluated loop (9,288), so
2627
the on-disk POSITION count is an exact witness. `export_apply=False` silently
27-
writes the 624-vertex cage.
28+
writes the 344-vertex cage.
2829
- **The round-trip is faithful.** Re-imported positions (bit-exact here), loop
2930
normals (≤2e-4), box-mapped UVs (≤3e-5), and per-triangle material bindings
3031
all match the evaluated mesh. UVs are V-flipped on disk (glTF texture origin
@@ -46,18 +47,31 @@ between kit-bashed shells weld loops on export (the count check catches it), and
4647
`read_factory_settings` mid-check frees the original mesh — touching a freed RNA
4748
raises `ReferenceError`, so counts are captured before the wipe.
4849

49-
The render stages the authored crate beside the actual re-imported one — same
50-
bevels, same materials carried through the file itself. If the axis conversion
51-
broke, the right twin would lie on its side; if the modifier contract broke, its
52-
silhouette would lose the rounded edges. Both twins are turned 22° off
53-
square so each shows a side and its corner armour; dead-on, the pair read
54-
as two flat front elevations. The re-imported object comes back in
55-
`QUATERNION` rotation mode, so the render path switches it to `XYZ`
56-
before turning it — presentation only, after every check has run.
57-
58-
The render path gates framing through `gallery_framing.check_framing`.
59-
The helper returns 10, which is already a check code here, so the call
60-
site remaps a framing violation to 22.
50+
The render shows **one** crate. The solid crate is the authored one, rebuilt
51+
in place after the check. Laid over it is the actual re-imported mesh — the
52+
file's own triangles — drawn as a thin amber wire cage (a render-only Weld +
53+
Wireframe display stack on the imported object) and masked to the right of a
54+
vertical cut, so the left half reads as the authored asset and the right half
55+
as the file's geometry sitting on it. Neither object is moved: both keep the
56+
identity transform check 13 proved, and the camera does the turning. The cage
57+
lands on every bevel, rivet and vent slat only because the importer undid the
58+
+Y-up bake exactly and the file carried the evaluated (beveled) mesh. If the
59+
axis conversion broke, the cage would be rotated a quarter turn off the solid
60+
crate; a probe that re-applies that quarter turn to the imported object before
61+
rendering drops the cage through the floor and also fails the framing gate
62+
(bottom margin 0.000). If the modifier contract broke, the cage would trace
63+
square corners across the rounded ones.
64+
65+
Presentation only, after every check has run: the authored crate's bevel is
66+
baked into its display mesh (the asset-quality edge measure reads
67+
`Object.data`, which is still the square cage while the bevel lives in the
68+
modifier stack), and its paint and trim get a noise-mottled base colour and
69+
roughness. The exported file only ever carried the flat Principled values.
70+
71+
The render path gates framing through `gallery_framing.check_framing` and the
72+
asset floors through `gallery_asset_quality.check_asset_quality` on the
73+
authored crate. Both helpers' codes (10, 11) are already check codes here, so
74+
the call site remaps them to 22 and 23.
6175

6276
## Run
6377

@@ -103,6 +117,7 @@ against it.
103117
| 20 | Per-triangle material bindings drifted |
104118
| 21 | `--output` produced no file |
105119
| 22 | Gallery framing violation (render path only; the helper's 10, remapped) |
120+
| 23 | Gallery asset-quality violation (render path only; the helper's 11, remapped) |
106121

107122
The `blender-smoke` workflow runs the check on Blender 5.2 LTS and 4.5 LTS
108123
(5.1 on the weekly cron, the `needs-5.1` PR label, or manual dispatch).

0 commit comments

Comments
 (0)