Skip to content

Commit b86086f

Browse files
TMHSDigitalclaude
andcommitted
fix(showcase): chopping-block quality pass with rivet-seat and haft-section budgets
The log read as a tub: flat-shaded equal facets made staves, the hoop was a flat-shaded stripe with piano-key highlights, the end grain was a triangle-fan sunburst, a pale ring ran round the base, and the haft was a round dowel with a pencil-stub knob in the bark's material. The generator now smooth-shades the log and hoop and carries bark furrows, growth rings and drying checks in the materials, keeps bark down to the ground, builds the hoop as a lapped strip with two rivets aimed down the host normal, and sweeps an oval haft that hooks at the knob in its own material slot. New budgets: rivet seat band and proud minimum (exit 18, --float-rivets) and haft section ratio (exit 19, --round-haft). --fat-haft now thickens across the cheeks only so it still fails on eye clearance. Triangle band, AABB and collider ceiling re-fitted to the new measurements. The temp glTF is removed after measuring. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
1 parent 0b447b9 commit b86086f

8 files changed

Lines changed: 1306 additions & 235 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ Budget-conformance props. Not examples. Conventions: [`showcase/README.md`](show
128128
<a href="showcase/grindstone/"><img src="showcase/grindstone/preview.webp" width="24%" alt="Grindstone: a stone wheel on a timber A-frame with an iron axle, hubs, crank, and tray on a dark studio floor" /></a>
129129
<a href="showcase/hand-pump/"><img src="showcase/hand-pump/preview.webp" width="24%" alt="Hand pump: a cast-iron village pump on a wooden plinth with a spout and handle on a dark studio floor" /></a>
130130
<a href="showcase/signpost/"><img src="showcase/signpost/preview.webp" width="24%" alt="Signpost: a timber post with two painted fingerboards, iron straps, and a pyramidal cap on a dark studio floor" /></a>
131-
<a href="showcase/chopping-block/"><img src="showcase/chopping-block/preview.webp" width="24%" alt="Chopping block: a hooped timber stump with an embedded axe on a dark studio floor" /></a>
131+
<a href="showcase/chopping-block/"><img src="showcase/chopping-block/preview.webp" width="24%" alt="Chopping block: a bark-sided log round with growth rings and drying checks on its sawn top, a riveted iron hoop, and a felling axe buried in the top, on a dark studio floor" /></a>
132132
<a href="showcase/wooden-bucket/"><img src="showcase/wooden-bucket/preview.webp" width="24%" alt="Wooden bucket: a coopered pail with a round rope bail through ear rings and chord-lofted iron hoops on a dark studio floor" /></a>
133133
<a href="showcase/wall-torch/"><img src="showcase/wall-torch/preview.webp" width="24%" alt="Wall torch: a dressed stone plaque with an iron sconce, wooden haft, and flame on a dark studio floor" /></a>
134134
<a href="showcase/tavern-stool/"><img src="showcase/tavern-stool/preview.webp" width="24%" alt="Tavern stool: a round wooden seat on turned splayed legs with stretchers and iron ferrules on a dark studio floor" /></a>
5.73 KB
Loading

‎docs/gallery/chopping-block/index.html‎

Lines changed: 626 additions & 108 deletions
Large diffs are not rendered by default.
46.4 KB
Loading

‎showcase/chopping-block/README.md‎

Lines changed: 74 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
# Chopping block
22

3-
A showcase piece, not an example. Procedural chopping block (a hooped
4-
log round with a felling axe buried in the sawn face) then the shipped
5-
pipeline: unique-cell UVs, Cycles high-to-low normal bake, LOD chain,
6-
convex collider, Unity glTF export.
3+
A showcase piece, not an example. Procedural chopping block (a log round
4+
with a riveted iron hoop and a felling axe buried in the sawn face) then
5+
the shipped pipeline: unique-cell UVs, Cycles high-to-low normal bake,
6+
LOD chain, convex collider, Unity glTF export.
77

88
The log is an out-of-round loft whose radius is a closed-form function
9-
of angle and height; the hoop, the top rim and the drying checks are all
10-
generated from that same function, so they stay seated when a dimension
11-
changes. The axe head is one lofted shell from poll to bit with its
12-
chamfers modelled into the section profile, and the haft is swept
13-
through the eye rather than pushed into it.
9+
of angle and height; the hoop, its rivets, the top rim and the drying
10+
checks are all generated from that same function, so they stay seated
11+
when a dimension changes. The hoop is a lapped strip with two domed
12+
rivets through the lap. The axe head is one lofted shell from poll to
13+
bit with its chamfers modelled into the section profile, and the haft is
14+
swept through the eye rather than pushed into it. The haft is oval,
15+
bows away from the bit, and hooks toward it at the knob.
1416

1517
It asserts **budget conformance** of the generated result. It does not
1618
witness an API contract. "It rendered without error" is not a check.
@@ -28,14 +30,19 @@ materials, UVs, evaluated LOD, collider, or export file.
2830

2931
| Axis | Declared | Measured (4.5.11 / 5.1.2 / 5.2.1) |
3032
| --- | --- | --- |
31-
| Base triangles | 1410–1530 | 1472 / 1472 / 1472 |
33+
| Base triangles | 1730–1870 | 1800 / 1800 / 1800 |
3234
| LOD1 ratio | 0.32–0.62 of base | 0.5000 / 0.5000 / 0.5000 |
33-
| LOD2 ratio | 0.10–0.35 of base | 0.2188 / 0.2188 / 0.2188 |
34-
| Materials | exactly 3 distinct; ≥160 bark, ≥90 grain, ≥24 metal faces | 3 slots; 252 / 252 / 288 |
35+
| LOD2 ratio | 0.10–0.35 of base | 0.2200 / 0.2200 / 0.2200 |
36+
| Materials | exactly 4 distinct; ≥160 bark, ≥90 grain, ≥170 metal, ≥150 haft faces | 4 slots; 180 / 216 / 404 / 176 |
3537
| UVs | in `0..1`, AABB overlap ≤ 1e-5 | in range, overlap 0 |
36-
| Outer AABB | (0.526, 0.526, 1.012) m ± 0.01 | (0.5264, 0.5264, 1.0117) |
37-
| Collider tris | ≤ 470 | 434 |
38-
| Export | written, size > 0 | 150784 / 150784 / 150776 bytes |
38+
| Outer AABB | (0.526, 0.526, 1.006) m ± 0.012 | (0.5264, 0.5264, 1.0064) |
39+
| Collider tris | ≤ 560 | 538 |
40+
| Export | written, size > 0 | 180588 / 180588 / 180572 bytes |
41+
42+
The triangle band, the outer AABB and the collider ceiling were re-fitted
43+
in the quality pass that added the lap, the rivets and the 16-segment
44+
oval haft (1472 → 1800 triangles, collider 434 → 538). The triangle band
45+
is centred on the new measurement, ± 4 %.
3946

4047
### Hygiene
4148

@@ -49,39 +56,67 @@ Recomputed from the generated mesh, not asserted about the script.
4956
| Zero-area faces | 0 | 0 |
5057
| N-gons | 0 | 0 |
5158
| Coplanar disjoint face pairs | 0 | 0 |
52-
| Grounded: `zmin` | within 1e-5 of 0 | 0.0000 |
53-
| Log axis out of plumb | ≤ 2e-4 | 0.0000000 |
54-
| Log size | 0.535 × 0.360 m ± 0.03 / ± 0.02 | 0.5464 × 0.3600 |
59+
| Grounded: `zmin` | within 1e-4 of 0 | 0.0000 |
60+
| Log axis out of plumb | ≤ 1e-5 | 0.0000000 |
61+
| Log size | 0.535 × 0.360 m ± 0.030 / ± 0.010 | 0.5464 × 0.3600 |
62+
| Haft section, wide over thick at the grip | 1.25–1.60 | 1.3500 |
5563

5664
### Joint fit
5765

58-
Four shells that have to meet correctly: log, hoop, head, haft.
66+
Six shells that have to meet correctly: log, hoop, head, haft, and the
67+
two rivets through the hoop's lap.
5968

6069
| Axis | Declared | Measured (all three) |
6170
| --- | --- | --- |
62-
| Shell count | exactly 4 | 4 |
71+
| Shell count | exactly 6 | 6 |
6372
| Haft clearance inside the eye | ≥ 0.006 m | 0.01800 |
64-
| Haft engagement through the eye | ≥ 0.020 m | 0.08049 |
65-
| Haft breakout margin below the head | ≥ 0.006 m | 0.02351 |
73+
| Haft engagement through the eye | ≥ 0.020 m | 0.08225 |
74+
| Haft breakout margin below the head | ≥ 0.006 m | 0.02175 |
6675
| Bit bury below the sawn top | ≥ 0.030 m | 0.07871 |
6776
| Bit inset from the rim | ≥ 0.030 m | 0.14647 |
68-
| Hoop bite into the log, every segment | 0.002–0.007 m | 0.00371–0.00400 |
69-
| Haft clearance above the log | ≥ 0.015 m, 0 verts inside | 0.07858, 0 |
77+
| Hoop bite into the log, every segment | 0.002–0.007 m | 0.00371–0.00422 |
78+
| Haft clearance above the log | ≥ 0.015 m, 0 verts inside | 0.07531, 0 |
79+
| Rivet seat into the hoop, each rivet | 0.0008–0.0025 m | 0.00150, 0.00154 |
80+
| Rivet dome proud of the hoop, each rivet | ≥ 0.0025 m | 0.00419, 0.00432 |
7081

7182
The hoop bite is binned by angular segment against the log's own radius
7283
function. A single global midpoint radius misclassifies outer chamfer
7384
vertices as inner ones on an out-of-round log, which is how a hoop that
7485
visibly floated on one side still passed.
7586

87+
The rivet seat is measured radially at each rivet vertex's own angle,
88+
against the hoop's outer face read off the mesh by a ray cast from the
89+
axis. Each rivet is aimed down the hoop's surface normal, not the
90+
radial: the log is out of round, so across one 12 mm head its surface
91+
falls by up to 1.4 mm, and radially aimed heads seated 1.87 and 2.82 mm
92+
against a 1.5 mm design bite, one edge sunk and the other lifted.
93+
7694
DECIMATE COLLAPSE triangle counts happen to agree across all three
7795
series here; the gate is still a ratio band, not an exact count. Bake
7896
pixels are stochastic; the gate is `has_data` plus operator `FINISHED`,
79-
not byte-identity. Construction uses no RNG. Export byte counts differ
80-
by 8 B on 5.2.1 (glTF serializer), not a gated axis.
97+
not byte-identity. Construction uses no RNG: two runs on each binary
98+
print identical measurements, and the three binaries agree on every
99+
gated axis. Export byte counts differ by 16 B on 5.2.1 (glTF
100+
serializer), not a gated axis.
101+
102+
### Shading and materials
103+
104+
Only the axe head is flat-shaded: it is a chamfered forging, and its
105+
facets are its form. The log and the hoop are smooth-shaded.
106+
Flat-shaded, the log's 36 equal facets read as coopered staves and the
107+
block as a tub, and the hoop threw one highlight per facet. The log's
108+
wobble still reads in the silhouette, and its surface is carried by the
109+
materials: vertical bark furrows with a bump, growth rings about an
110+
off-centre pith on the sawn face, and dark radial checks drawn at the
111+
same angles the geometry notches. Every material boundary is a hard
112+
edge, so the sawn rim stays crisp against the bark.
113+
114+
The haft has its own material slot. It used to share the bark's, which
115+
made the hickory handle the darkest wood on the piece.
81116

82117
### Falsifiers
83118

84-
Each violates one named budget. All five were run on 4.5.11, 5.1.2 and
119+
Each violates one named budget. All seven were run on 4.5.11, 5.1.2 and
85120
5.2.1 and returned the same code on each.
86121

87122
| Flag | Budget violated | Exit |
@@ -91,6 +126,12 @@ Each violates one named budget. All five were run on 4.5.11, 5.1.2 and
91126
| `--lift-z` | bounding box `zmin` is 0 | 16 |
92127
| `--fat-haft` | haft clearance inside the eye | 17 |
93128
| `--round-band` | hoop bite into the log | 18 |
129+
| `--float-rivets` | rivet seat into the hoop | 18 |
130+
| `--round-haft` | haft section wide over thick | 19 |
131+
132+
`--fat-haft` thickens the haft across the cheeks only, which is the
133+
dimension the eye clearance measures. Scaling the whole oval section
134+
grew the knob 16 mm past the bounding box, so it exited 8 instead.
94135

95136
## Run
96137

@@ -101,6 +142,8 @@ blender --background --python chopping_block.py -- --stray-vert
101142
blender --background --python chopping_block.py -- --lift-z
102143
blender --background --python chopping_block.py -- --fat-haft
103144
blender --background --python chopping_block.py -- --round-band
145+
blender --background --python chopping_block.py -- --float-rivets
146+
blender --background --python chopping_block.py -- --round-haft
104147
blender --background --python chopping_block.py -- --output chopping-block.png
105148
```
106149

@@ -119,7 +162,7 @@ hygiene and joint-fit family.
119162
| 2 | argparse / usage |
120163
| 3 | Mesh did not build / no UV layer |
121164
| 4 | Base triangle count outside range |
122-
| 5 | Material count ≠ 3 distinct slots, or a face-count floor missed |
165+
| 5 | Material count ≠ 4 distinct slots, or a face-count floor missed |
123166
| 6 | UVs outside 0..1 |
124167
| 7 | UV AABB overlap above tolerance |
125168
| 8 | World AABB off declared outer size |
@@ -131,6 +174,6 @@ hygiene and joint-fit family.
131174
| 14 | `--output` produced no file |
132175
| 15 | Mesh hygiene: loose, non-manifold, zero-area, doubles, n-gons, z-fight |
133176
| 16 | Not grounded: bounding box `zmin` off 0 |
134-
| 17 | Axe joint fit: shell count, eye clearance, engagement, breakout, bury, inset |
135-
| 18 | Contact fit: hoop bite band, or haft fouling the log |
136-
| 19 | Log out of plumb, or off its stated real-world size |
177+
| 17 | Joint fit: shell count, eye clearance, engagement, breakout, bury, inset |
178+
| 18 | Contact fit: hoop bite band, haft fouling the log, or a rivet off its seat band |
179+
| 19 | Log out of plumb, off its stated real-world size, or a round haft section |

0 commit comments

Comments
 (0)