feat: add soccer-ball-goldberg example#104
Merged
Merged
Conversation
Witness the Goldberg polyhedron as a bmesh contract: a soccer ball built by truncating a bmesh icosphere at 1/3 per edge, faces ordered by link-topology walks. Closed-form invariants asserted with printed tolerances: 60/90/32 + Euler 2, 12-pentagon/20-hexagon census, uniform degree 3, edge-length and circumsphere uniformity at the float32 noise floor, face planarity against an independent Newell normal, and panel materials bound by face vertex count rather than enumeration order. Distinct from bmesh-gear (parametric extrusion): this carries polyhedral invariants plus per-face-class material binding, and the smoothed render inverts on sight if the binding does. Signed-off-by: fOuttaMyPaint <TMhospitalitystrategies@gmail.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.
Summary
Adds
examples/soccer-ball-goldberg/— a soccer ball built as a Goldbergpolyhedron: a bmesh icosphere truncated at exactly 1/3 of every edge (12
pentagons, 20 hexagons), with faces ordered by walking the source mesh's link
topology (fan walk per vertex, loop order per triangle) — nothing hand-listed.
The recognizable object is the contract: the truncated icosahedron is an
Archimedean solid, so its topology is entirely closed-form.
Sibling, not twin, to
bmesh-gear: that one witnesses parametric extrusionownership; this witnesses polyhedral topology invariants plus
per-face-class material binding (panels bound by face vertex count, never
enumeration order).
Contract witnessed
Truncation at 1/3 makes every new edge
a/3, which puts all 60 vertices onone sphere. The check asserts, exit non-zero on failure, tolerances printed
on success: counts 60/90/32 + Euler 2 · 12×5 + 20×6 census · uniform degree
3 · watertight · edge-length uniformity · face planarity vs an independent
Newell normal (not Blender's polygon normal) · centroid-at-origin
circumsphere · panel binding by vertex count.
Measured check values (live runs, both binaries)
Binaries:
.scratch/blender-5.1.2-windows-x64/blender.exe(reportsBlender 5.1.2) and.scratch/blender-4.5.11-windows-x64/blender.exe(reportsBlender 4.5.11 LTS). Output byte-identical on both:Tolerance basis: float32 mesh storage +
create_icospheretrig put theinvariants at a deterministic ~9e-6 noise floor (identical on both versions);
the 3e-5 gates sit ~3x above it, while any real break is ≥1e-2.
Falsification evidence (live runs)
Probe harness breaks the built mesh, then runs the shipped
check():Note: "first 12 faces black" passes by luck — construction enumerates
pentagons first. That coincidence is exactly why the check reads vertex
counts, and the README says so.
Render / visual-pass log
Hero: white leather hexagons + black pentagons, unapplied Subsurf over the
Goldberg cage (panel materials carry through Catmull-Clark), default stage
per
docs/VISUAL-STYLE.md(no deviation). 2 draft iterations: draft 1floated the ball (cage circumradius ≠ smoothed surface radius — grounded by
the depsgraph-evaluated lowest vertex instead, ~5 cm sink) and reframed;
draft 2 shipped. Pass 1 crops: no clipped highlights, contact shadow
grounded, seam in shadow only. Pass 2 falsification pair: material-inverted
variant renders white pentagons on a black ball — the named visible
difference; it fails on sight. Pass 3: card-size webp reads as a soccer ball
in under a second.
Contact sheet:
docs/gallery/contact-sheets/soccer-ball-goldberg-contact-sheet.webp
(candidate TL; armature-bend TR; damped-track-aim BL; bmesh-gear BR).
Verdicts: stage darkness match ✓ · wedge warmth subtle, within family range
(armature-bend is similarly cool) ✓ · subject fill comparable ✓ · saturation
monochrome by subject nature, designed leather finishes ✓ · thumbnail
legibility highest-contrast of the four ✓. Mean luminance 0.2377 vs set
0.2787 / 0.1722 / 0.3048 — inside the set's range. Not sortable as the odd
one out.
Pass 4 (Playwright, live local server)
Card captured in situ at desktop (1280px) and ~390px mobile widths, plus the
detail page: image fills card media at both widths, teaches/WITNESSES copy
complete (no truncation), ball recognizable at both sizes. Generated HTML
read character-by-character: initial
teacheswas 166 chars and the card alttruncated at the generator's 160-char cap — trimmed, rebuilt, alt now
complete; no dotted-path truncation (
assert_alts_survive_dotted_pathspasses); single-asterisk italics removed from the README so the detail page
carries no literal
*artifacts.Hazards found while authoring (in code comments + README)
Object.to_mesh_clear()takes no argument on current Blender —passing the mesh raises TypeError (both 5.1.2 and 4.5.11).
the face inradii, so grounding uses the evaluated lowest vertex.
img.save(filepath=..., quality=85)webp recipesilently writes PNG bytes on these builds (the two newest shipped heroes
are PNG-magic). Hero/preview here are true RIFF WebP via
save_renderwith WEBP image settings, matching the bulk of the gallery(verified magic bytes; max channel deviation 0.067 at panel edges, q85
ringing only).
Integration
Example dir + README + preview webp (1200×675) · hero webp (1280×720, true
RIFF) ·
examples/gallery.json·.cursor-plugin/plugin.json·blender-smoke.ymlstep · README counts 36→37 + gallery row · ROADMAP pooldrained (soccer-ball) and restocked (mirror-symmetry, chess-lathe, dice-pair,
bicycle-wheel directions) · gallery regenerated (
37 detail pages).Test plan
blender --background --python examples/soccer-ball-goldberg/soccer_ball_goldberg.py --→ exit 0(live-run locally on both, values above).
sbg_draft2*.png).blender-smokematrix jobs (4.5, 5.1) must pass on this PR head.Live-run vs inspection-only
both renders, webp conversion + magic-byte verification, gallery build,
Playwright captures, contact-sheet luminance.
invocation shape as 23 merged siblings); GitHub Pages deploy (path-filtered,
post-merge).