Skip to content

Commit 0fffd74

Browse files
fix(showcase): grindstone and wheelbarrow visual quality pass (#174)
* docs(showcase): require named-support zmin on multi-foot props AABB zmin cannot catch a planted wheel hiding floating shoes. Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(showcase): rebuild the grindstone so the A-frame and trough actually join The trestle was two sticks with a hole under the bearing and a floating tub. King, nested sill, manifold basin, and shoe tenons close the joints, locked as hygiene and seat budgets. Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(showcase): rebuild the wheelbarrow so the tray and wheel joints actually meet Walls sat on the floor and spokes were audited against floor slats. Seated walls, nested handles, and a hub-local spoke metric lock the joints. Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(showcase): stop grindstone mat_of from looking like a product exit The README exit-table check treats return -1 as a process code. Missing material is None. Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> --------- Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent a80c139 commit 0fffd74

13 files changed

Lines changed: 3293 additions & 717 deletions

File tree

11.7 KB
Loading
15.5 KB
Loading

docs/gallery/grindstone/index.html

Lines changed: 753 additions & 157 deletions
Large diffs are not rendered by default.

docs/gallery/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@ <h2><a href="park-bench/">park-bench</a></h2>
10241024
<div class="card-body">
10251025
<h2><a href="wheelbarrow/">wheelbarrow</a></h2>
10261026
<p class="teaches">A procedural wooden wheelbarrow through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.</p>
1027-
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 3088 tris, two materials with 308 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.418×0.463×0.594 m, LOD ratios in band (5.2 COLLAPSE more aggressive on LOD2), convex collider 106 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.</p>
1027+
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 2500 tris, two materials with 1094 wood and 190 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.556×0.630×0.572 m, zmin 0, hygiene 0, wall-floor seat 12 mm, spoke clearance 40 mm, LOD ratios in band (5.2 COLLAPSE leaner on LOD2), convex collider 90 tris, non-empty glTF. --skip-decimate exits 9 on LOD1; --stray-vert exits 15 on hygiene; --lift-z / --short-legs exit 16 on grounded; --fat-spokes / --float-walls exit 17 on joint fit; --pipe-rim exits 18 on tread aspect.</p>
10281028
<a class="card-link" href="wheelbarrow/">View example <span aria-hidden="true">&rarr;</span></a>
10291029
</div>
10301030
</article>
@@ -1068,7 +1068,7 @@ <h2><a href="hitching-post/">hitching-post</a></h2>
10681068
<div class="card-body">
10691069
<h2><a href="grindstone/">grindstone</a></h2>
10701070
<p class="teaches">A procedural grindstone on a timber trestle through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.</p>
1071-
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 1604 tris, three materials with 80 metal and 26 stone faces, UVs in 0..1 with zero AABB overlap, outer AABB 0.630×0.615×0.575 m, LOD ratios in band, convex collider 130 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.</p>
1071+
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 928 tris, three materials with 216 wood / 160 stone / 180 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 0.710×0.419×0.610 m, zmin 0, hygiene 0, four shoes planted, trough seated in the sills, stone dip 26 mm, LOD ratios in band (5.2 COLLAPSE leaner on LOD2), convex collider 198 tris, non-empty glTF. --skip-decimate exits 9 on LOD1; --stray-vert exits 15 on hygiene; --lift-z / --short-legs exit 16 on grounded; --float-crank / --float-legs exit 17 on joint fit; --no-dip / --narrow-trough exit 18 on seat.</p>
10721072
<a class="card-link" href="grindstone/">View example <span aria-hidden="true">&rarr;</span></a>
10731073
</div>
10741074
</article>

docs/gallery/wheelbarrow/index.html

Lines changed: 836 additions & 189 deletions
Large diffs are not rendered by default.

showcase/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ entry in `showcase/gallery.json`, and a rendered still.
5353
single-shell contract. Pairs of parts meant to touch assert a BVH
5454
surface gap below a named epsilon (vert-vert is the wrong metric for
5555
thin straps and collars).
56+
- **Named supports (exit 16).** AABB `zmin` is necessary but not
57+
sufficient on a multi-support prop: a wheel, a sled floor, or one
58+
planted foot can ground the box while the other feet float. Split the
59+
mesh into shells and assert each named support (shoe, tyre, foot) has
60+
its own `zmin` within epsilon of 0. `--short-legs` (or the piece's
61+
equivalent) is the falsifier: float the named supports while leaving
62+
something else on the ground so the AABB gate would still pass.
5663
- **Joint-fit budgets.** Parts that interpenetrate on purpose — a tenon
5764
in a mortise, a peg in a hub — assert how deep the overlap goes, not
5865
just that it exists. Split the mesh into shells by edge connectivity,

showcase/gallery.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@
153153
"name": "wheelbarrow",
154154
"dir": "showcase/wheelbarrow",
155155
"teaches": "A procedural wooden wheelbarrow through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.",
156-
"witnessesFix": "Recomputed: 3088 tris, two materials with 308 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.418×0.463×0.594 m, LOD ratios in band (5.2 COLLAPSE more aggressive on LOD2), convex collider 106 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.",
156+
"witnessesFix": "Recomputed: 2500 tris, two materials with 1094 wood and 190 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.556×0.630×0.572 m, zmin 0, hygiene 0, wall-floor seat 12 mm, spoke clearance 40 mm, LOD ratios in band (5.2 COLLAPSE leaner on LOD2), convex collider 90 tris, non-empty glTF. --skip-decimate exits 9 on LOD1; --stray-vert exits 15 on hygiene; --lift-z / --short-legs exit 16 on grounded; --fat-spokes / --float-walls exit 17 on joint fit; --pipe-rim exits 18 on tread aspect.",
157157
"hero": "docs/gallery/assets/wheelbarrow-hero.webp",
158158
"preview": "showcase/wheelbarrow/preview.webp",
159159
"tags": [
@@ -201,7 +201,7 @@
201201
"name": "grindstone",
202202
"dir": "showcase/grindstone",
203203
"teaches": "A procedural grindstone on a timber trestle through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.",
204-
"witnessesFix": "Recomputed: 1604 tris, three materials with 80 metal and 26 stone faces, UVs in 0..1 with zero AABB overlap, outer AABB 0.630×0.615×0.575 m, LOD ratios in band, convex collider 130 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.",
204+
"witnessesFix": "Recomputed: 928 tris, three materials with 216 wood / 160 stone / 180 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 0.710×0.419×0.610 m, zmin 0, hygiene 0, four shoes planted, trough seated in the sills, stone dip 26 mm, LOD ratios in band (5.2 COLLAPSE leaner on LOD2), convex collider 198 tris, non-empty glTF. --skip-decimate exits 9 on LOD1; --stray-vert exits 15 on hygiene; --lift-z / --short-legs exit 16 on grounded; --float-crank / --float-legs exit 17 on joint fit; --no-dip / --narrow-trough exit 18 on seat.",
205205
"hero": "docs/gallery/assets/grindstone-hero.webp",
206206
"preview": "showcase/grindstone/preview.webp",
207207
"tags": [

showcase/grindstone/README.md

Lines changed: 76 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
# Grindstone
22

3-
A showcase piece, not an example. Procedural grindstone (stone wheel,
4-
timber A-frame trestle, iron axle, hubs, crank, and tray) then the
5-
shipped pipeline: unique-cell UVs, Cycles high-to-low normal bake, LOD
6-
chain, convex collider, Unity glTF export.
3+
A showcase piece, not an example. Procedural grindstone (sandstone
4+
wheel, timber A-frame trestle, iron shoes/axle/hubs/crank, open water
5+
trough) then the shipped pipeline: unique-cell UVs, Cycles high-to-low
6+
normal bake, LOD chain, convex collider, Unity glTF export.
7+
8+
The A-frame is a king post with diagonals tenoning into a fatter sill,
9+
not two sticks meeting at a point. The trough is one manifold basin
10+
seated into those sills. Iron shoes bury a short wood tenon so the
11+
angled leg end-cap cannot pierce Z=0.
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,38 +26,85 @@ 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 | 1480–1720 | 1604 / 1604 / 1604 |
29+
| Base triangles | 700–1000 | 928 / 928 / 928 |
2530
| LOD1 ratio | 0.32–0.62 of base | 0.5000 / 0.5000 / 0.5000 |
26-
| LOD2 ratio | 0.10–0.35 of base | 0.2195 / 0.2195 / 0.2195 |
27-
| Materials | exactly 3 distinct, ≥24 metal and stone faces | 3 slots, 80 metal, 26 stone |
31+
| LOD2 ratio | 0.10–0.35 of base | 0.2198 / 0.2198 / 0.1897 |
32+
| Materials | exactly 3 distinct; ≥80 wood, stone, metal faces | 3 slots; 216 / 160 / 180 |
2833
| UVs | in `0..1`, AABB overlap ≤ 1e-5 | in range, overlap 0 |
29-
| Outer AABB | (0.630, 0.615, 0.575) m ± 0.01 | (0.6300, 0.6150, 0.5750), zmin 0 |
30-
| Collider tris | ≤ 180 | 130 |
31-
| Export | written, size > 0 | 123436 / 123436 / 123416 bytes |
34+
| Outer AABB | (0.710, 0.419, 0.610) m ± 0.015 | (0.7100, 0.4185, 0.6100), zmin 0 |
35+
| Collider tris | ≤ 240 | 198 |
36+
| Export | written, size > 0 | 89316 / 89316 / 89312 bytes |
37+
38+
### Hygiene
39+
40+
Recomputed from the generated mesh, not asserted about the script.
41+
42+
| Axis | Declared | Measured (all three) |
43+
| --- | --- | --- |
44+
| Non-manifold edges | 0 | 0 |
45+
| Loose verts / edges | 0 / 0 | 0 / 0 |
46+
| Doubles merged at 1e-5 | 0 | 0 |
47+
| Zero-area faces | 0 | 0 |
48+
| N-gons | 0 | 0 |
49+
| Coplanar disjoint face pairs | 0 | 0 |
50+
| Grounded: `zmin` | within 1e-4 of 0 | 0.0000 |
51+
| Named supports: 4 shoes | each `zmin` ≤ 1e-3 | 4, shoe_z 0.00000 |
52+
| Stone size | 0.500 m dia × 0.095 m thick ± 0.02 / ± 0.015 | 0.5000 × 0.0950 |
53+
54+
### Joint fit and seat
55+
56+
| Axis | Declared | Measured (all three) |
57+
| --- | --- | --- |
58+
| Crank-axle gap | ≤ 0.008 m | 0.00418 |
59+
| Shoe-wood BVH gap | ≤ 0.008 m (overlap is 0) | 0.00000 |
60+
| Trough-sill per-side gap | ≤ 0.008 m (overlap is 0) | 0.00000 |
61+
| Stone dip into trough | 0.015–0.045 m | 0.02570 |
62+
| Trough floor zmin | ≥ 0.040 m | 0.05800 |
3263

3364
DECIMATE COLLAPSE triangle counts are **not** identical across series —
34-
the gate is a ratio band, not an exact count. Bake pixels are
35-
stochastic; the gate is `has_data` plus operator `FINISHED`, not
36-
byte-identity. Construction uses no RNG. Export byte counts differ by
37-
20 B on 5.2.1 (glTF serializer), not a gated axis.
65+
5.2.1 is leaner on LOD2. The gate is a ratio band, not an exact count.
66+
Bake pixels are stochastic; the gate is `has_data` plus operator
67+
`FINISHED`, not byte-identity. Construction uses no RNG. Export byte
68+
counts differ by 4 B on 5.2.1 (glTF serializer), not a gated axis.
69+
70+
### Falsifiers
3871

39-
`--skip-decimate` skips the LOD DECIMATE stage so LOD1 ratio is 1.0 and
40-
exit 9 fires. That is the named budget the falsifier violates.
72+
Each violates one named budget. All nine were run on 4.5.11, 5.1.2 and
73+
5.2.1 and returned the same code on each.
74+
75+
| Flag | Budget violated | Exit |
76+
| --- | --- | --- |
77+
| `--skip-decimate` | LOD1 ratio band | 9 |
78+
| `--stray-vert` | loose vertex count is 0 | 15 |
79+
| `--lift-z` | bounding box `zmin` is 0 | 16 |
80+
| `--short-legs` | named shoe supports at Z=0 | 16 |
81+
| `--float-crank` | crank-axle gap | 17 |
82+
| `--float-legs` | shoe-wood join | 17 |
83+
| `--no-dip` | stone dip band | 18 |
84+
| `--narrow-trough` | trough-sill seat | 18 |
4185

4286
## Run
4387

4488
```bash
4589
blender --background --python grindstone.py --
4690
blender --background --python grindstone.py -- --skip-decimate
91+
blender --background --python grindstone.py -- --stray-vert
92+
blender --background --python grindstone.py -- --lift-z
93+
blender --background --python grindstone.py -- --short-legs
94+
blender --background --python grindstone.py -- --float-crank
95+
blender --background --python grindstone.py -- --float-legs
96+
blender --background --python grindstone.py -- --no-dip
97+
blender --background --python grindstone.py -- --narrow-trough
4798
blender --background --python grindstone.py -- --output grindstone.png
4899
```
49100

50-
Smoke does not pass `--output` or `--skip-decimate`.
101+
Smoke passes no flags.
51102

52103
## Exit codes
53104

54105
File-local. `9` is a valid check code. `10` is reserved for
55-
`gallery_framing.check_framing` on the `--output` path.
106+
`gallery_framing.check_framing` on the `--output` path. `15``19` are the
107+
hygiene and joint-fit family.
56108

57109
| Code | Meaning |
58110
| --- | --- |
@@ -61,7 +113,7 @@ File-local. `9` is a valid check code. `10` is reserved for
61113
| 2 | argparse / usage |
62114
| 3 | Mesh did not build / no UV layer |
63115
| 4 | Base triangle count outside range |
64-
| 5 | Material count ≠ 3 distinct slots, or wood/stone/metal faces missing |
116+
| 5 | Material count ≠ 3 distinct slots, or a face-count floor missed |
65117
| 6 | UVs outside 0..1 |
66118
| 7 | UV AABB overlap above tolerance |
67119
| 8 | World AABB off declared outer size |
@@ -71,3 +123,8 @@ File-local. `9` is a valid check code. `10` is reserved for
71123
| 12 | Bake did not finish or image has no data |
72124
| 13 | Export file missing or empty |
73125
| 14 | `--output` produced no file |
126+
| 15 | Mesh hygiene: loose, non-manifold, zero-area, doubles, n-gons, z-fight |
127+
| 16 | Not grounded: bounding box `zmin` off 0, or a named shoe floats |
128+
| 17 | Joint fit: crank-axle gap, or shoe-wood join |
129+
| 18 | Seat: trough-sill gap, stone dip band, or trough sitting on the dirt |
130+
| 19 | Stone diameter or thickness off the stated real-world size |

0 commit comments

Comments
 (0)