fix(showcase): rebuild cart and stone-well joints, with eight new hygiene budgets - #206
Merged
Merged
Conversation
The tyre's inner radius was set equal to the felloe's outer radius (`r_mid = RIM_OUTER + TYRE_T/2, radial_t = TYRE_T/2`), which put both surfaces on one plane for every segment: 32 coplanar cross-shell face pairs, 16 per wheel. It was visible as speckle on the committed hero and in a clay pass, and no budget could see it. Derive the tyre's inner radius from the felloe's outer radius minus a named interference (TYRE_SEAT) and its tread from the felloe plus its own thickness, so the band bites into the rim and still owns the ground contact. Wheel segments 16 -> 24: at 16 the rim read as a polygon and the facet facing the key light rendered as a hard white plate. Iron raised from (0.13, rough 0.32) to (0.20, rough 0.50), inside the range its sibling pieces use, because the tyre was reading as black plastic. Four new budgets, each recomputed from the generated mesh: - coplanar cross-shell face pairs = 0 (hay-bale's combinatorics, copied) - each tyre's own zmin on the floor, not just the AABB's - tyre seat depth banded per angular station, 48 stations - the two wheels mirrored in Y within 5e-5 m Four new falsifiers, each landing on its own code and sized to stay inside BBOX_TOL so the AABB gate cannot steal the failure: --flush-tyre (15), --sink-tyre (18), --float-wheel (16), --skew-wheel (19). Also drops the temp .glb once measured — the leak PR #205 found in hay-bale is in this piece too. Base triangles re-fitted to 2760-2960: narrower than the 2470-2900 it replaces and centred on the measured 2856. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
…them in Three structural defects, all found by looking at an inspection sheet: 1. The four roof posts stood at 0/90/180/270 degrees while the roof's 4-gon cone is rotated pi/4, so its corners sit on the diagonals. The posts were under the midpoint of each eave: the roof's corners cantilevered 0.80 m unsupported, and one post stood dead centre in the well mouth in every orthographic view. Posts moved to the diagonals, and the windlass, crank and grip turn with them. 2. Each post's bottom face landed exactly on the coping's top face — 4 coplanar cross-shell face pairs, one per post. Posts are now tenoned POST_SEAT into the coping, with POST_TOP held fixed so nothing above them moves. 3. EAVE_HALF was derived from the post ring plus an overhang, giving a 1.64 m roof over a 1.08 m drum: an umbrella, not a well house. It is now derived from what the roof must cover — the curb's own radius plus a named clearance — which brings the AABB to 1.312 m. The bucket hung at z=0.68 with only its rim level with the coping: invisible in the hero and in all six orthographic views. It now hangs BUCKET_CLEAR above the measured coping top and reads in the still. Five new budgets, each recomputed from the generated mesh — the tenon and the bucket clearance measure against the coping top read off the stone material, not against the constant the builder used: - coplanar cross-shell face pairs = 0 - all 12 bottom-course stones on the floor, not just the lowest - post tenon depth banded, per post - each post within 0.02 rad in plan of a roof hip corner - bucket clearance banded above the coping Five new falsifiers. Two needed re-aiming to hit their own budget: --stand-posts also returns the posts to the axis, because flush alone at 45 degrees leaves no coping face within COPLANAR_CENTRE_MAX of a foot; --turn-posts rotates by exactly one curb facet, because any other angle sets the feet on different coping geometry and the gap gate (17) steals the failure, and a full 45 degrees swings the crank past the eave and fails the AABB gate (8). Collider ceiling 320 -> 380: the convex hull of the resized roof measures 346. Also drops the temp .glb once measured. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
`--skip-triangulate` printed an error and returned 4 from its own branch. The flag announced a failure rather than causing one, and the handling assertions it exists to falsify never ran. It now skips the repair and lets those assertions catch the unrepaired mesh, which reports the real measurement (`ngons=1 tris=0 quads=4`). The contract, the assertions and the exit codes are unchanged. Proven identical before and after on 4.5.11 LTS, 5.1.2 and 5.2.1 LTS: default 0, --no-dissolve 3, --skip-triangulate 4. README: adds the verified `calc_tangents` abort text, which is byte-identical on all three binaries, a falsifier table naming what each flag breaks, and 4.5/5.2 API links for calc_tangents, dissolve_edges and triangulate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
Seven conventions every future piece inherits, each from a defect in this pass that no existing budget could see: a band is hooped onto its host and never set flush against it; a member is tenoned into its seat and never stood on it, measured against the host read off the mesh; posts go under a roof's corners, with the corners taken from the pooled eave vertices rather than one fascia board; a roof is sized from what it covers, not from what carries it; the subject hangs where it can be seen; mirrored assemblies pair and compare, with the falsifier sized inside BBOX_TOL; and segment counts are a silhouette budget. Also registers this pass's falsifier flags in the shared list and regenerates the gallery for the two rebuilt pieces. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
TMHSDigital
added a commit
that referenced
this pull request
Sep 22, 2026
… pass (#207) * docs(showcase): conventions for shading, material slots, fastener seats and section budgets Adds four conventions from the chopping-block quality pass: equal facets on an organic or turned body read as staves, so smooth it and carry the surface in the material; one substance per material slot; fasteners aimed down the host's surface normal with a radial seat band (--float-rivets, exit 18); a recognisable cross-section asserted as a ratio band (--round-haft, exit 19). Also records that a thickening falsifier scales only the axis its budget measures. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> * 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> * fix(examples): gn-socket-rename renders its Random Value axis Presentation only; the contract, assertions and exit codes are unchanged. The column shader now draws gauge graduations from the evaluated POINT gauge_h attribute, so an unwired Random Value renders a blank column where before the still looked identical either way. Brushed copper with engraved ticks from each corner, a steel plinth that no longer mirrors the dark stage into a void, the rim light cut so its floor reflection stops lifting the stage, and an 18 degree presentation turn so two faces show. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> * fix(examples): gn-bundle-roundtrip exit-5 falsifier and re-verified version table Exit 5 had no falsifier. --mismatch-mark renames only Separate's Float item, so count and bbox pass and bundle_mark reads 0.0, exit 5. The README now states the RNA per version as a table, re-verified by probe on 4.5.11, 5.0.1, 5.1.2 and 5.2.1: GeometryNodeCombineBundle is undefined on all of 5.x, not only 5.2; on 4.5 it exists with the experimental flag off and evaluates empty. --force-run on 4.5 is documented as exit 1, not under exit 3. Assertions and exit codes unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> * docs(gallery): regenerate the index and the stale cart and stone-well pages Output of scripts/build_gallery.py. The cart and stone-well detail pages were not regenerated after #206 changed their scripts and READMEs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> --------- Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
8 tasks
TMHSDigital
added a commit
that referenced
this pull request
Sep 23, 2026
…sifier-table check (#210) All three READMEs gained falsifier tables in #205 and #206, and the static checker already parses them (28 pieces, 181 falsifiers), but they stayed listed in KNOWN_UNDOCUMENTED. That exemption is now a hole: if one of those tables were deleted, the checker would skip the piece silently instead of failing it. Every falsifier was run, not read: the runtime mode reports 19/19 exits matching their declared budgets on Blender 5.2.1, and a direct sweep gives the same 19 codes on 4.5.11. Closes #203 Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Quality pass over three items: two showcase pieces on Track A and one
check-only example on Track C. Both showcase pieces were the weakest in
the tree by budget coverage — 18 exit codes and two falsifiers each,
last touched in #171, before the joint-fit, named-support,
seat-conformance and mirror-symmetry convention classes existed.
Every defect below was found by rendering an inspection sheet to
.scratch/(six orthographic views, two three-quarters, a clay pass, awireframe overlay, joint close-ups, a ground close-up) and looking at
the images. None of them is visible in the script.
1.
showcase/cart— Track ADefects found
bdt_cart_*.glbin the repo root.git statusafter a runDefect 1 is the one that matters: it is a construction bug
(
r_mid = RIM_OUTER + TYRE_T/2, radial_t = TYRE_T/2makesr_in == RIM_OUTERexactly), it shipped, and no budget could see it.Fixes, and why they are structural
minus a named interference (
TYRE_SEAT), and the tread from thefelloe plus its own thickness. The band is hooped onto the rim and
still owns the ground contact. A nudge to one radius would have
reopened the moment
RIM_RADIALorTYRE_Tchanged; deriving bothends from the host surface survives that.
WHEEL_SEGMENTS = 24, named, used by both rings andby the seat-depth binning, so the budget and the geometry cannot
drift apart.
and the wear colour lifted off near-black so the noise varies the
surface at all.
AABB is unchanged at (1.5393, 0.7486, 0.6400) — the tread radius
did not move.
New hygiene budgets
All recomputed from the generated mesh. Measured identically on
4.5.11 LTS / 5.1.2 / 5.2.1 LTS:
Falsifiers
Proven on all three binaries. Magnitudes sized to stay inside
BBOX_TOLso the AABB gate (8) cannot steal the failure.--skip-decimate--lift-z--flush-tyre--sink-tyre--float-wheel--skew-wheel--flush-tyrerestores exactly the bug this piece was rebuilt toremove, so the budget is proven against the real defect and not a
synthetic one.
Triangles: 2600 → 2856. Band re-fitted to 2760–2960, which is
narrower than the 2470–2900 it replaces (200 wide vs 430) and
centred on the measurement — a tightening, not a widening.
Inspection rounds: 2.
Remains (not fixed, reported rather than hidden)
the hero.
bed frame.
None of these is measurable without inventing a budget that would fail
on a correct model, so none became an assertion.
2.
showcase/stone-well— Track ADefects found
EAVE_HALFwas derived from the post ring plus an overhang, giving a 1.64 m roof over a 1.08 m drum (1.52×). It read as an umbrella, or a bird feeder..glbleak as the cart.git statusFixes, and why they are structural
POST_ANGLES, and thewindlass, crank arm and grip turn with them, so the drum still spans
an opposed pair of posts. Moving the roof instead would have been the
nudge: the posts must be under the corners, not the corners moved to
wherever the posts happen to be.
POST_BOTTOMis derived from the coping top minusPOST_SEAT, andPOST_TOPis held fixed, so nothing above the postsmoves and the eave, peak and overall height are untouched.
EAVE_HALF = R_OUTER + CURB_OUT + EAVE_CLEAR— derived fromwhat the roof must cover, with the overhang falling out of it. AABB
1.640 → 1.312 over a 1.08 m drum (1.21×).
BUCKET_Zderived from the coping top plus a namedclearance, so it cannot drift back down the shaft when the masonry
changes.
The tenon and bucket budgets measure against the coping top read off
the generated mesh (max z over the stone material), not against
CURB_TOP— an assertion that restates the builder's own constantwitnesses nothing.
New hygiene budgets
Falsifiers
--skip-decimate--lift-z--stand-posts--float-stone--shallow-tenon--drop-bucket--turn-postsTwo falsifiers had to be re-aimed, which is the point of declaring
the target:
--stand-postsseats the posts flush and returns them to theaxis. Flush alone, at the corrected 45°, leaves no coping top face
within
COPLANAR_CENTRE_MAXof a foot, so it fell through to thetenon band (18) and witnessed nothing about z-fighting.
--turn-postsrotates by exactly one curb facet (30°). At 0.12 radthe feet land on different coping geometry and the stone–wood gap
gate steals it (observed exit 17,
gap 0.01439 > 0.008); at afull 45° the crank grip swings past the eave and the AABB gate steals
it (observed exit 8,
bbox (1.3600, 1.3120, 1.7606)). One facetis the only rotation whose local seat geometry is identical by
symmetry. Same trap
stone-archway's--flat-archfell into.I also had to abandon a
--twin-copingfalsifier: duplicating a copingblock reuses its UVs, so the UV-overlap gate (7) fires before the
z-fight gate. Recorded here so the next run does not retry it.
Triangles: 9380, unchanged. Collider ceiling 320 → 380: the
convex hull of the resized roof measures 346. That is a budget moving
with a deliberate geometry change, documented at the constant.
Inspection rounds: 2.
Remains
reads as rubble rather than a dressed coping.
3.
examples/ngon-triangulate— Track CContract frozen. No assertion, no exit code and no witnessed
behaviour changed.
A falsifier that falsified nothing
--skip-triangulateprinted an error and returned 4 from its ownbranch, before the repair and before the assertions it exists to
break. The flag announced a failure rather than causing one, and the
handling assertions never ran. It now skips
bmesh.ops.triangulateandlets those assertions catch the unrepaired mesh, which reports the real
measurement:
triangulate handling failed ngons=1 tris=0 quads=4.Exit codes, before and after
Identical on all three binaries:
--no-dissolve--skip-triangulateRe-verification of the documented behaviour
Mesh.calc_tangentsaborts on the constructed hexagon with a messagethat is byte-identical on 4.5.11 LTS, 5.1.2 and 5.2.1 LTS:
TANGENT_ABORT = "tris/quads"is therefore correct and version-stable.Default measurements also match on all three:
ngons=1 loops=6 faces_before=5 tris=4 quads=4 loops_after=28 tangents=ok.README
Adds the verified abort text, a falsifier table naming what each flag
breaks and the assertion it lands on, and 4.5/5.2 API links for
calc_tangents,bmesh.ops.dissolve_edgesandbmesh.ops.triangulate— it had no doc links at all.
4.
showcase/README.mdconventionsSeven conventions every future piece inherits, each from a defect above
that no existing budget could see:
obvious spelling makes the band's inner cylinder and the host's
tread the same surface.
seat is measured against the host surface read off the generated
mesh, not the builder's constant.
with the corners taken from the pooled eave vertices, because
pulling them from one shell picks a fascia board whose own extremes
sit 90° off the corners it is nailed to (this cost me a false
failure of 1.549 rad on a correct model).
it — and expect the collider budget to move with it.
displacement sized inside
BBOX_TOL.and re-fit the triangle band narrower, centred on the new count.
Plus this pass's falsifier flags registered in the shared list.
Gates
Framing gate, 5.2.1, no
deviation=: cart fill 0.806 (band0.70–0.90), margins 0.153/0.150/0.150/0.044,
framing_ok; well fill0.861, margins 0.278/0.275/0.033/0.106,
framing_ok.Contact sheets committed at
docs/gallery/contact-sheets/cart-contact-sheet.webpandstone-well-contact-sheet.webp, each against the pinned set(
armature-bend,damped-track-aim,bmesh-gear).stone-well's saturation is below the calibration floor (0.1369 vs
0.1449): grey stone against one warm roof. Stated rather than
massaged.
The asset-sheet gate is scoped to asset-type examples; its
pinned reference set is four examples, and every recent showcase pass
(feat: add crate-stack and stone-archway showcase pieces #199, fix(showcase): hay-bale quality pass with five new hygiene budgets, and exit-pre-sidecar doc accuracy #205) shipped a contact sheet only. Followed that precedent.
Determinism: both pieces run twice per binary, six runs each, all
exit 0 with byte-identical measurements within each binary. Base
triangles identical across all three series (2856 / 9380). The only
cross-version difference is cart LOD2 (628 on 4.5/5.1, 616 on 5.2 —
DECIMATE COLLAPSE), r2 0.2199 vs 0.2157, both inside the declared
band.
tests/check_falsifier_targets.py: 179 falsifiers across 28showcase pieces, passed.
Generated gallery HTML re-read after
build_gallery.py: cardalttext and the witnesses callouts on both detail pages arecomplete and untruncated (the
teaches.split(".")[0]class of bugfrom fix: gallery alts truncate on dotted API paths + version example prompt #68).
Proven by live run vs. inspection
Live run on all three binaries (
.scratch/blender-4.5.11-windows-x64/blender.exereporting 4.5.11 LTS,
blender-5.1.2-windows-x64reporting 5.1.2,blender-5.2.1-windows-x64reporting 5.2.1 LTS): every exit code inevery table above, every measured budget figure, the two mis-aimed
falsifier exits (17 and 8) quoted with their messages, the
calc_tangentsabort text, determinism, the framing gate, and thetemp-export cleanup.
Inspection only: the contact-sheet verdicts other than the two
measured numbers are my judgement of the committed composites, and the
"remains" lists are judgement calls, not measurements.
Inspection renders stayed in
.scratch/, which is gitignored.🤖 Generated with Claude Code