Skip to content

Commit 173621d

Browse files
fix(showcase): lock shipping-crate tenons and filleted handles as hygiene budgets
Posts hung over a skid cave and 90-degree handle lofts sat on the plates. Shared post/skid planes and quarter-circle bails close those joints without magic offsets. Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 4581522 commit 173621d

7 files changed

Lines changed: 1524 additions & 332 deletions

File tree

21.6 KB
Loading

‎docs/gallery/index.html‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -892,7 +892,7 @@ <h2><a href="gn-socket-rename/">gn-socket-rename</a></h2>
892892
<div class="card-body">
893893
<h2><a href="shipping-crate/">shipping-crate</a></h2>
894894
<p class="teaches">A procedural shipping crate through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.</p>
895-
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 624 tris, two materials with 132 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.352×0.856×0.748 m, LOD ratios in band (5.2 COLLAPSE more aggressive), convex collider 36 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.</p>
895+
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 2508 tris, two materials with 1170 wood and 280 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.146×0.726×0.612 m, grounded zmin, 3 skids, handle-end and slat-post join 0, mesh hygiene all zero, LOD ratios in band (5.2 COLLAPSE leaner on LOD2), convex collider 76 tris, non-empty glTF. --skip-decimate exits 9; --stray-vert 15; --lift-z/--short-skids 16; --float-handle 17; --omit-slats 18.</p>
896896
<a class="card-link" href="shipping-crate/">View example <span aria-hidden="true">&rarr;</span></a>
897897
</div>
898898
</article>
@@ -1145,7 +1145,7 @@ <h2><a href="tavern-stool/">tavern-stool</a></h2>
11451145
<div class="card-body">
11461146
<h2><a href="iron-cauldron/">iron-cauldron</a></h2>
11471147
<p class="teaches">A procedural hanging iron cauldron with a bulged open pot, bail, and timber tripod through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.</p>
1148-
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 3388 tris, two materials with 450 wood and 1198 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.013×0.986×0.827 m, pot–leg clearance 0.051 m, LOD ratios in band (5.2 COLLAPSE 8 tris leaner on LOD2), convex collider 98 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.</p>
1148+
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 3664 tris, two materials with 224 wood and 1768 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 0.987×0.961×0.860 m, pot–leg clearance 0.046 m, 3 coaxial ferrules at zmin 0, ferrule bite −0.00185 m, hook-bail join 0, mesh hygiene all zero, LOD ratios in band, convex collider 250 tris, non-empty glTF. --skip-decimate exits 9; --stray-vert 15; --lift-z/--short-legs 16; --float-hook 17; --pipe-ferrule 18.</p>
11491149
<a class="card-link" href="iron-cauldron/">View example <span aria-hidden="true">&rarr;</span></a>
11501150
</div>
11511151
</article>

‎docs/gallery/shipping-crate/index.html‎

Lines changed: 734 additions & 159 deletions
Large diffs are not rendered by default.

‎showcase/gallery.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"name": "shipping-crate",
1010
"dir": "showcase/shipping-crate",
1111
"teaches": "A procedural shipping crate through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.",
12-
"witnessesFix": "Recomputed: 624 tris, two materials with 132 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.352×0.856×0.748 m, LOD ratios in band (5.2 COLLAPSE more aggressive), convex collider 36 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.",
12+
"witnessesFix": "Recomputed: 2508 tris, two materials with 1170 wood and 280 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.146×0.726×0.612 m, grounded zmin, 3 skids, handle-end and slat-post join 0, mesh hygiene all zero, LOD ratios in band (5.2 COLLAPSE leaner on LOD2), convex collider 76 tris, non-empty glTF. --skip-decimate exits 9; --stray-vert 15; --lift-z/--short-skids 16; --float-handle 17; --omit-slats 18.",
1313
"hero": "docs/gallery/assets/shipping-crate-hero.webp",
1414
"preview": "showcase/shipping-crate/preview.webp",
1515
"tags": [
@@ -285,7 +285,7 @@
285285
"name": "iron-cauldron",
286286
"dir": "showcase/iron-cauldron",
287287
"teaches": "A procedural hanging iron cauldron with a bulged open pot, bail, and timber tripod through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.",
288-
"witnessesFix": "Recomputed: 3388 tris, two materials with 450 wood and 1198 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.013×0.986×0.827 m, pot–leg clearance 0.051 m, LOD ratios in band (5.2 COLLAPSE 8 tris leaner on LOD2), convex collider 98 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.",
288+
"witnessesFix": "Recomputed: 3664 tris, two materials with 224 wood and 1768 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 0.987×0.961×0.860 m, pot–leg clearance 0.046 m, 3 coaxial ferrules at zmin 0, ferrule bite −0.00185 m, hook-bail join 0, mesh hygiene all zero, LOD ratios in band, convex collider 250 tris, non-empty glTF. --skip-decimate exits 9; --stray-vert 15; --lift-z/--short-legs 16; --float-hook 17; --pipe-ferrule 18.",
289289
"hero": "docs/gallery/assets/iron-cauldron-hero.webp",
290290
"preview": "showcase/iron-cauldron/preview.webp",
291291
"tags": [

‎showcase/shipping-crate/README.md‎

Lines changed: 74 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
# Shipping crate
22

3-
A showcase piece, not an example. Procedural crate (beveled body, arrayed
4-
slats, iron corner brackets and end handles, two materials) then the shipped
5-
pipeline: unique-cell UVs, Cycles high-to-low normal bake, LOD chain, convex
6-
collider, Unity glTF export.
3+
A showcase piece, not an example. Procedural crate (skids under the
4+
posts, corner posts with tenoned slats and seeded width jitter, bottom
5+
sills, L-straps, filleted iron bail handles through mounting plates)
6+
then the shipped pipeline: unique-cell UVs, Cycles high-to-low normal
7+
bake, LOD chain, convex collider, Unity glTF export.
8+
9+
Skids sit under the posts so the outer corner is a mortise, not a cave.
10+
Handle bails use quarter-circle corners so a 90-degree loft cannot sit
11+
the bar on the plate.
712

813
It asserts **budget conformance** of the generated result. It does not
914
witness an API contract. "It rendered without error" is not a check.
@@ -21,37 +26,83 @@ materials, UVs, evaluated LOD, collider, or export file.
2126

2227
| Axis | Declared | Measured (4.5.11 / 5.1.2 / 5.2.1) |
2328
| --- | --- | --- |
24-
| Base triangles | 580–680 | 624 / 624 / 624 |
25-
| LOD1 ratio | 0.32–0.62 of base | 0.5000 / 0.5000 / 0.4455 |
26-
| LOD2 ratio | 0.10–0.35 of base | 0.2179 / 0.2179 / 0.1571 |
27-
| Materials | exactly 2 distinct, ≥24 metal faces | 2 slots, 180 wood, 132 metal |
29+
| Base triangles | 1200–2800 | 2508 / 2508 / 2508 |
30+
| LOD1 ratio | 0.32–0.62 of base | 0.5000 / 0.5000 / 0.5000 |
31+
| LOD2 ratio | 0.10–0.35 of base | 0.2193 / 0.2193 / 0.2057 |
32+
| Materials | exactly 2 distinct; ≥200 wood, ≥48 metal faces | 2 slots; 1170 / 280 |
2833
| UVs | in `0..1`, AABB overlap ≤ 1e-5 | in range, overlap 0 |
29-
| Outer AABB | (1.352, 0.856, 0.748) m ± 0.01 | (1.3520, 0.8560, 0.7480), zmin 0 |
30-
| Collider tris | ≤ 48 | 36 |
31-
| Export | written, size > 0 | 50148 / 50148 / 50140 bytes |
34+
| Outer AABB | (1.146, 0.726, 0.612) m ± 0.015 | (1.1460, 0.7260, 0.6120), zmin 0 |
35+
| Collider tris | ≤ 220 | 76 |
36+
| Export | written, size > 0 | 197408 / 197408 / 197392 bytes |
37+
38+
Base triangles rose from **624 to 2508** in the quality pass: the old
39+
beveled cube with glued-on slats became a post-and-slat crate with
40+
tenons, sills, L-straps, and pipe handles.
3241

3342
DECIMATE COLLAPSE triangle counts are **not** identical across series —
34-
5.2.1 is more aggressive. The gate is a ratio band, not an exact count.
43+
5.2.1 is leaner on LOD2. The gate is a ratio band, not an exact count.
3544
Bake pixels are stochastic; the gate is `has_data` plus operator
36-
`FINISHED`, not byte-identity. Construction uses no RNG.
45+
`FINISHED`, not byte-identity. Slat-width jitter uses fixed seed 17.
46+
Export byte counts differ by 16 B on 5.2.1 (glTF serializer), not a
47+
gated axis.
48+
49+
### Hygiene
50+
51+
Recomputed from the generated mesh, not asserted about the script.
52+
53+
| Axis | Declared | Measured (all three) |
54+
| --- | --- | --- |
55+
| Non-manifold edges | 0 | 0 |
56+
| Loose verts / edges | 0 / 0 | 0 / 0 |
57+
| Doubles merged at 1e-5 | 0 | 0 |
58+
| Zero-area faces | 0 | 0 |
59+
| N-gons | 0 | 0 |
60+
| Coplanar disjoint face pairs | 0 | 0 |
61+
| Grounded: `zmin` | within 1e-4 of 0 | 0.0000 |
62+
| Named supports: 3 skids | each `zmin` ≤ 1e-3 | 3, skid_z 0.00000 |
63+
| Body plan | 1.056 × 0.716 m ± 0.05 | 1.0560 × 0.7160 |
3764

38-
`--skip-decimate` skips the LOD DECIMATE stage so LOD1 ratio is 1.0 and
39-
exit 9 fires. That is the named budget the falsifier violates.
65+
### Joint fit and seat
66+
67+
| Axis | Declared | Measured (all three) |
68+
| --- | --- | --- |
69+
| Handle-end BVH gap | ≤ 0.008 m | 0.00000 |
70+
| Slat-post BVH gap | ≤ 0.006 m | 0.00000 |
71+
72+
### Falsifiers
73+
74+
Each violates one named budget. All seven were run on 4.5.11, 5.1.2 and
75+
5.2.1 and returned the same code on each.
76+
77+
| Flag | Budget violated | Exit |
78+
| --- | --- | --- |
79+
| `--skip-decimate` | LOD1 ratio band | 9 |
80+
| `--stray-vert` | loose vertex count is 0 | 15 |
81+
| `--lift-z` | bounding box `zmin` is 0 | 16 |
82+
| `--short-skids` | named skid supports at Z=0 | 16 |
83+
| `--float-handle` | handle-end gap | 17 |
84+
| `--omit-slats` | slat-post seat | 18 |
4085

4186
## Run
4287

4388
```bash
4489
blender --background --python shipping_crate.py --
4590
blender --background --python shipping_crate.py -- --skip-decimate
91+
blender --background --python shipping_crate.py -- --stray-vert
92+
blender --background --python shipping_crate.py -- --lift-z
93+
blender --background --python shipping_crate.py -- --short-skids
94+
blender --background --python shipping_crate.py -- --float-handle
95+
blender --background --python shipping_crate.py -- --omit-slats
4696
blender --background --python shipping_crate.py -- --output crate.png
4797
```
4898

49-
Smoke does not pass `--output` or `--skip-decimate`.
99+
Smoke passes no flags.
50100

51101
## Exit codes
52102

53103
File-local. `9` is a valid check code. `10` is reserved for
54-
`gallery_framing.check_framing` on the `--output` path.
104+
`gallery_framing.check_framing` on the `--output` path. `15`–`19` are the
105+
hygiene and joint-fit family.
55106

56107
| Code | Meaning |
57108
| --- | --- |
@@ -60,7 +111,7 @@ File-local. `9` is a valid check code. `10` is reserved for
60111
| 2 | argparse / usage |
61112
| 3 | Mesh did not build / no UV layer |
62113
| 4 | Base triangle count outside range |
63-
| 5 | Material count ≠ 2 distinct slots, or metal faces missing |
114+
| 5 | Material count ≠ 2 distinct slots, or a face-count floor missed |
64115
| 6 | UVs outside 0..1 |
65116
| 7 | UV AABB overlap above tolerance |
66117
| 8 | World AABB off declared outer size |
@@ -70,3 +121,8 @@ File-local. `9` is a valid check code. `10` is reserved for
70121
| 12 | Bake did not finish or image has no data |
71122
| 13 | Export file missing or empty |
72123
| 14 | `--output` produced no file |
124+
| 15 | Mesh hygiene: loose, non-manifold, zero-area, doubles, n-gons, z-fight |
125+
| 16 | Not grounded: bounding box `zmin` off 0, or a named skid floats |
126+
| 17 | Joint fit: handle-end gap |
127+
| 18 | Seat: slat-post gap |
128+
| 19 | Body plan off the stated real-world size |
8.45 KB
Loading

0 commit comments

Comments
 (0)