Skip to content

Commit 8461626

Browse files
fix(showcase): terrain-scatter and park-bench visual quality pass (#182)
* docs(showcase): add sampled-host-seat convention for scatter pieces Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(showcase): seat terrain-scatter stones on sampled dirt instead of crate cubes Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(showcase): rebuild park-bench with tangent tube scroll feet 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 e9db80a commit 8461626

13 files changed

Lines changed: 2012 additions & 480 deletions

File tree

25.4 KB
Loading
-8.36 KB
Loading

‎docs/gallery/index.html‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -964,12 +964,12 @@ <h2><a href="treasure-chest/">treasure-chest</a></h2>
964964
</article>
965965
<article class="card" data-tags="mesh export showcase">
966966
<a class="card-media" href="terrain-scatter/" aria-label="terrain-scatter example detail page">
967-
<img src="assets/terrain-scatter-hero.webp" alt="terrain-scatter — A Geometry Nodes hill tile with masonry scatter through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract." loading="lazy" decoding="async" />
967+
<img src="assets/terrain-scatter-hero.webp" alt="terrain-scatter — A Geometry Nodes hill tile with seated icosphere scatter through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API…" loading="lazy" decoding="async" />
968968
</a>
969969
<div class="card-body">
970970
<h2><a href="terrain-scatter/">terrain-scatter</a></h2>
971-
<p class="teaches">A Geometry Nodes hill tile with masonry scatter through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.</p>
972-
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 1194 tris, two materials with 486 stone faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.800×1.800×0.655 m, LOD ratios in band, convex collider 52 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.</p>
971+
<p class="teaches">A Geometry Nodes hill tile with seated icosphere scatter through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.</p>
972+
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 1758 tris, two materials with 720 stone faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.800×1.800×0.552 m, grounded zmin, 9 stones of ≥80 faces seated on sampled dirt Z (offset −35 mm, floor zmin 0.113 m), LOD ratios in band, convex collider 81 tris, hygiene zero, non-empty glTF. --skip-decimate exits 9; --stray-vert 15; --lift-z 16; --poke-rock 17; --float-rocks 18; --box-rocks 19.</p>
973973
<a class="card-link" href="terrain-scatter/">View example <span aria-hidden="true">&rarr;</span></a>
974974
</div>
975975
</article>
@@ -1008,12 +1008,12 @@ <h2><a href="cart/">cart</a></h2>
10081008
</article>
10091009
<article class="card" data-tags="mesh export showcase">
10101010
<a class="card-media" href="park-bench/" aria-label="park-bench example detail page">
1011-
<img src="assets/park-bench-hero.webp" alt="park-bench — A procedural wrought-iron park bench through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract." loading="lazy" decoding="async" />
1011+
<img src="assets/park-bench-hero.webp" alt="park-bench — A procedural wrought-iron park bench with tangent tube scroll feet through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than…" loading="lazy" decoding="async" />
10121012
</a>
10131013
<div class="card-body">
10141014
<h2><a href="park-bench/">park-bench</a></h2>
1015-
<p class="teaches">A procedural wrought-iron park bench through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.</p>
1016-
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 2100 tris, two materials with 510 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.080×0.566×0.853 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>
1015+
<p class="teaches">A procedural wrought-iron park bench with tangent tube scroll feet through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.</p>
1016+
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 2520 tris, two materials with 540 metal and 756 wood faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.295×0.632×0.884 m, grounded zmin, 4 named toes, stretcher gap 1.2 mm, slat gap 0.3 mm, seat span 1.272 m, LOD ratios in band, convex collider 82 tris, hygiene zero, non-empty glTF. --skip-decimate exits 9; --stray-vert 15; --lift-z/--short-feet 16; --float-stretcher 17; --gap-slats 18; --narrow-seat 19.</p>
10171017
<a class="card-link" href="park-bench/">View example <span aria-hidden="true">&rarr;</span></a>
10181018
</div>
10191019
</article>

‎docs/gallery/park-bench/index.html‎

Lines changed: 555 additions & 142 deletions
Large diffs are not rendered by default.

‎docs/gallery/terrain-scatter/index.html‎

Lines changed: 389 additions & 86 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
@@ -89,6 +89,13 @@ entry in `showcase/gallery.json`, and a rendered still.
8989
vertices as inner ones the moment the host is out of round, which is
9090
how a hoop that visibly gapped on one side still passed. The paired
9191
falsifier makes the wrapper a true circle on an out-of-round host.
92+
- **Sampled host seat (exit 17/18 on scatter).** Instanced scatter
93+
seats by sampling the host surface Z at each instance's XY, biting a
94+
named depth, then clamping instance verts above the slab floor. A
95+
closed-form icosphere (or equivalent) replaces the GN cube so the
96+
scatter is stones, not open crates; a per-shell face floor is the
97+
budget that catches a cube leftover (exit 19). `--poke-rock` skips
98+
the clamp and over-bites; `--float-rocks` seats above the host.
9299
- **Plumb and real-world size (exit 19).** Assert that the axis of a
93100
turned or lofted body is vertical, by comparing the XY centroid of a
94101
bottom slab against a top slab — not the exact `zmin` and `zmax`

‎showcase/gallery.json‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@
9292
{
9393
"name": "terrain-scatter",
9494
"dir": "showcase/terrain-scatter",
95-
"teaches": "A Geometry Nodes hill tile with masonry scatter through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.",
96-
"witnessesFix": "Recomputed: 1194 tris, two materials with 486 stone faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.800×1.800×0.655 m, LOD ratios in band, convex collider 52 tris, non-empty glTF. --skip-decimate exits 9 on the LOD1 ratio budget.",
95+
"teaches": "A Geometry Nodes hill tile with seated icosphere scatter through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.",
96+
"witnessesFix": "Recomputed: 1758 tris, two materials with 720 stone faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.800×1.800×0.552 m, grounded zmin, 9 stones of ≥80 faces seated on sampled dirt Z (offset −35 mm, floor zmin 0.113 m), LOD ratios in band, convex collider 81 tris, hygiene zero, non-empty glTF. --skip-decimate exits 9; --stray-vert 15; --lift-z 16; --poke-rock 17; --float-rocks 18; --box-rocks 19.",
9797
"hero": "docs/gallery/assets/terrain-scatter-hero.webp",
9898
"preview": "showcase/terrain-scatter/preview.webp",
9999
"tags": [
@@ -140,8 +140,8 @@
140140
{
141141
"name": "park-bench",
142142
"dir": "showcase/park-bench",
143-
"teaches": "A procedural wrought-iron park bench through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.",
144-
"witnessesFix": "Recomputed: 2100 tris, two materials with 510 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.080×0.566×0.853 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.",
143+
"teaches": "A procedural wrought-iron park bench with tangent tube scroll feet through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.",
144+
"witnessesFix": "Recomputed: 2520 tris, two materials with 540 metal and 756 wood faces, UVs in 0..1 with zero AABB overlap, outer AABB 1.295×0.632×0.884 m, grounded zmin, 4 named toes, stretcher gap 1.2 mm, slat gap 0.3 mm, seat span 1.272 m, LOD ratios in band, convex collider 82 tris, hygiene zero, non-empty glTF. --skip-decimate exits 9; --stray-vert 15; --lift-z/--short-feet 16; --float-stretcher 17; --gap-slats 18; --narrow-seat 19.",
145145
"hero": "docs/gallery/assets/park-bench-hero.webp",
146146
"preview": "showcase/park-bench/preview.webp",
147147
"tags": [

‎showcase/park-bench/README.md‎

Lines changed: 87 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
# Park bench
22

33
A showcase piece, not an example. Procedural wrought-iron park bench
4-
(scrolled legs, slatted seat and back, armrests) then the shipped
5-
pipeline: unique-cell UVs, Cycles high-to-low normal bake, LOD chain,
6-
convex collider, Unity glTF export.
4+
(quarter-circle tube scroll feet tangent to the posts, slatted seat and
5+
back, arm scrolls, wood arm caps) then the shipped pipeline: unique-cell
6+
UVs, Cycles high-to-low normal bake, LOD chain, convex collider, Unity
7+
glTF export.
8+
9+
Posts, feet, stretchers and arms share named stations (`hx`, `hy`,
10+
`SEAT_Z`, `ARM_Z`, `SCROLL_R`). A foot is a 6-gon tube about
11+
`(hy ± R, R)` so it is tangent to the post at `z=R` and plants at `z=0`.
12+
The H-stretcher meets the posts at those stations; slats insert into the
13+
post volume without sharing corner verts with the seat rails.
714

815
It asserts **budget conformance** of the generated result. It does not
916
witness an API contract. "It rendered without error" is not a check.
@@ -13,6 +20,11 @@ witness an API contract. "It rendered without error" is not a check.
1320
`bake_normal_high_to_low.py`, `setup_bake_target_image.py`,
1421
`lod_chain.py` / `decimate_to_budget.py`, `convex_hull_collider.py`,
1522
`export_preset_unity.py` (helpers copied, not imported as a package).
23+
Hygiene combinatorics match `examples/mesh-hygiene-audit` (copied, not
24+
imported).
25+
26+
Intended size: 1.40 m sitting width, 0.50 m seat depth, 0.43 m seat
27+
height, 0.64 m arm height; outer AABB 1.295 × 0.632 × 0.884 m.
1628

1729
## Budgets
1830

@@ -21,39 +33,89 @@ materials, UVs, evaluated LOD, collider, or export file.
2133

2234
| Axis | Declared | Measured (4.5.11 / 5.1.2 / 5.2.1) |
2335
| --- | --- | --- |
24-
| Base triangles | 2000–2200 | 2100 / 2100 / 2100 |
25-
| LOD1 ratio | 0.32–0.62 of base | 0.5000 / 0.5000 / 0.4952 |
26-
| LOD2 ratio | 0.10–0.35 of base | 0.2200 / 0.2200 / 0.1400 |
27-
| Materials | exactly 2 distinct, ≥48 metal faces | 2 slots, 510 metal |
36+
| Base triangles | 2200–4200 | 2520 / 2520 / 2520 |
37+
| LOD1 ratio | 0.32–0.62 of base | 0.5000 / 0.5000 / 0.5000 |
38+
| LOD2 ratio | 0.10–0.35 of base | 0.2198 / 0.2198 / 0.2198 |
39+
| Materials | exactly 2 distinct, ≥48 metal, ≥24 wood | 2 slots, 540 metal / 756 wood |
2840
| UVs | in `0..1`, AABB overlap ≤ 1e-5 | in range, overlap 0 |
29-
| Outer AABB | (1.080, 0.566, 0.853) m ± 0.01 | (1.0800, 0.5657, 0.8531), zmin 0 |
30-
| Collider tris | ≤ 140 | 106 |
31-
| Export | written, size > 0 | 159868 / 159868 / 159852 bytes |
41+
| Outer AABB | (1.295, 0.632, 0.884) m ± 0.015 | (1.2945, 0.6314, 0.8840), zmin 0 |
42+
| Collider tris | ≤ 180 | 82 |
43+
| Export | written, size > 0 | 188164 / 188164 / 188148 bytes |
44+
45+
Base triangles rose from **2100 to 2520** in the quality pass: box-segment
46+
scrolls became 6-gon tubes. Outer AABB widened from 1.080 × 0.566 × 0.853 m
47+
to a 1.40 m sitting-width bench.
48+
49+
DECIMATE COLLAPSE triangle counts are **not** guaranteed identical across
50+
series — the gate is a ratio band, not an exact count. This mesh matched
51+
on 4.5.11 / 5.1.2 / 5.2.1. Bake pixels are stochastic; the gate is
52+
`has_data` plus operator `FINISHED`, not byte-identity. Construction uses
53+
no RNG. Export byte counts differ by 16 B on 5.2.1 (glTF serializer), not
54+
a gated axis.
55+
56+
### Hygiene
57+
58+
Recomputed from the generated mesh, not asserted about the script.
59+
60+
| Axis | Declared | Measured (all three) |
61+
| --- | --- | --- |
62+
| Non-manifold edges | 0 | 0 |
63+
| Loose verts / edges | 0 / 0 | 0 / 0 |
64+
| Doubles merged at 1e-5 | 0 | 0 |
65+
| Zero-area faces | 0 | 0 |
66+
| N-gons | 0 | 0 |
67+
| Coplanar disjoint face pairs | 0 | 0 |
68+
| Grounded: `zmin` | within 1e-4 of 0 | 0.0000 |
69+
| Named toes | 4, each `zmin` ≤ 0.002 | 4, 0.00000 |
70+
71+
### Joint fit and seat
72+
73+
| Axis | Declared | Measured (all three) |
74+
| --- | --- | --- |
75+
| Stretcher-to-post BVH gap | ≤ 0.008 m | 0.00120 |
76+
| Slat-to-post BVH gap | ≤ 0.008 m | 0.00028 |
77+
| Seat span vs `2·hx` | ± 0.08 m | 1.2720 vs 1.260 |
3278

33-
DECIMATE COLLAPSE triangle counts are **not** identical across series —
34-
5.2.1 is more aggressive on LOD2. The gate is a ratio band, not an
35-
exact count. Bake pixels are stochastic; the gate is `has_data` plus
36-
operator `FINISHED`, not byte-identity. Construction uses no RNG.
37-
Export byte counts differ by 16 B on 5.2.1 (glTF serializer), not a
38-
gated axis.
79+
### Falsifiers
80+
81+
Each violates one named budget. All were run on 4.5.11, 5.1.2 and 5.2.1
82+
and returned the same code on each.
83+
84+
| Flag | Budget violated | Exit |
85+
| --- | --- | --- |
86+
| `--skip-decimate` | LOD1 ratio band | 9 |
87+
| `--stray-vert` | loose vertex count is 0 | 15 |
88+
| `--lift-z` | bounding box `zmin` is 0 | 16 |
89+
| `--short-feet` | named toes plant at z=0 | 16 |
90+
| `--float-stretcher` | stretcher-to-post BVH gap | 17 |
91+
| `--gap-slats` | slat-to-post BVH gap | 18 |
92+
| `--narrow-seat` | seat span vs `2·hx` | 19 |
3993

40-
`--skip-decimate` skips the LOD DECIMATE stage so LOD1 ratio is 1.0 and
41-
exit 9 fires. That is the named budget the falsifier violates.
94+
`--short-feet` lifts only the outward toe verts. After recenter the post
95+
join is the AABB `zmin`, so the AABB gate would still pass; the named-toe
96+
stations fail.
4297

4398
## Run
4499

45100
```bash
46101
blender --background --python park_bench.py --
47102
blender --background --python park_bench.py -- --skip-decimate
103+
blender --background --python park_bench.py -- --stray-vert
104+
blender --background --python park_bench.py -- --lift-z
105+
blender --background --python park_bench.py -- --short-feet
106+
blender --background --python park_bench.py -- --float-stretcher
107+
blender --background --python park_bench.py -- --gap-slats
108+
blender --background --python park_bench.py -- --narrow-seat
48109
blender --background --python park_bench.py -- --output bench.png
49110
```
50111

51-
Smoke does not pass `--output` or `--skip-decimate`.
112+
Smoke passes no flags.
52113

53114
## Exit codes
54115

55116
File-local. `9` is a valid check code. `10` is reserved for
56-
`gallery_framing.check_framing` on the `--output` path.
117+
`gallery_framing.check_framing` on the `--output` path. `15`–`19` are the
118+
hygiene and joint-fit family.
57119

58120
| Code | Meaning |
59121
| --- | --- |
@@ -72,3 +134,8 @@ File-local. `9` is a valid check code. `10` is reserved for
72134
| 12 | Bake did not finish or image has no data |
73135
| 13 | Export file missing or empty |
74136
| 14 | `--output` produced no file |
137+
| 15 | Hygiene (`--stray-vert` lands here) |
138+
| 16 | Grounded zmin / named toes (`--lift-z`, `--short-feet`) |
139+
| 17 | Stretcher-to-post gap (`--float-stretcher`) |
140+
| 18 | Slat-to-post gap (`--gap-slats`) |
141+
| 19 | Seat span (`--narrow-seat`) |

0 commit comments

Comments
 (0)