Skip to content

Commit ec43b85

Browse files
TMHSDigitalclaude
andcommitted
refactor: asset-sheet object selection lives on each gallery entry, not in SELECT
Every new showcase piece edited the same SELECT dict at the end of scripts/asset_sheet.py (its most-changed code file), so concurrent piece additions collided on one hunk and a separate gate existed only to catch a forgotten row. Each entry in examples/ and showcase/gallery.json now carries assetSelect {include, exclude?}; the 102 rows were migrated mechanically and checked identical to SELECT before it was deleted. check_asset_sheet_select now requires a compilable assetSelect on every showcase piece and reference (falsified: a missing one and a bad regex both fail). Generated gallery pages are unchanged. Closes #530 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LpkeXRvikhJZSVGBFM91Dv Signed-off-by: TM Hospitality Strategies <TMHospitalityStrategies@gmail.com>
1 parent 6697af7 commit ec43b85

6 files changed

Lines changed: 483 additions & 249 deletions

File tree

‎docs/new-example-prompt.md‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,12 @@ proof that the image is good, and neither is the second.
159159
Asset-sheet gate (required when the subject is a game asset: a prop, kit piece or
160160
vehicle the example ships as a model): render the hero asset alone (neutral
161161
three-quarter view, plain studio light, no staging, labels or comparison props)
162-
beside the pinned asset-quality reference set, whose canonical membership is also in
163-
`CLAUDE.md` § Quality Gates for Example Runs, with
164-
`python scripts/asset_sheet.py --blender PATH NAME`. Add the entry's row to that
165-
script's `SELECT` table first (`tests/check_asset_sheet_select.py` enforces it for
166-
showcase pieces). Commit the composite under `docs/gallery/asset-sheets/`, link it in
162+
beside the pinned asset-quality reference set (`scripts/gallery_refs.py`, named in
163+
`CLAUDE.md` § Quality Gates for Example Runs), with
164+
`python scripts/asset_sheet.py --blender PATH NAME`. Give the gallery entry an
165+
`assetSelect` first: `{"include": "<regex>"}` (plus `"exclude"` if needed) on the
166+
object names that make up the hero asset (`tests/check_asset_sheet_select.py`
167+
enforces it for showcase pieces). Commit the composite under `docs/gallery/asset-sheets/`, link it in
167168
the PR body, and report a verdict. The asset ships only if it is not identifiable as
168169
the least-designed object in the lineup: a strong scene can carry a weak model, and
169170
this gate removes the scene. Its measurable floors (naming, material variation, edge

‎examples/gallery.json‎

Lines changed: 90 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"_comment": "FORWARD-COMPATIBLE SOURCE OF TRUTH for the examples gallery. The local page at docs/gallery/index.html is GENERATED from this file by scripts/build_gallery.py -- do not hand-edit the HTML. When the fleet template (Developer-Tools-Directory: site-template/build_site.py + template.html.j2) gains examples support (see ROADMAP: 'Fleet Pages examples support'), it reads this same file and the local page is retired. That migration is a lift-and-shift, not a rewrite: keep this schema stable. Per-entry schema: {name, dir, teaches, witnessesFix, hero, preview, tags?}; hero/preview/dir are repo-root-relative; tags is an optional additive list driving the gallery filter chips. build_gallery.py also emits a detail page per example at docs/gallery/<name>/.",
2+
"_comment": "FORWARD-COMPATIBLE SOURCE OF TRUTH for the examples gallery. The local page at docs/gallery/index.html is GENERATED from this file by scripts/build_gallery.py -- do not hand-edit the HTML. When the fleet template (Developer-Tools-Directory: site-template/build_site.py + template.html.j2) gains examples support (see ROADMAP: 'Fleet Pages examples support'), it reads this same file and the local page is retired. That migration is a lift-and-shift, not a rewrite: keep this schema stable. Per-entry schema: {name, dir, teaches, witnessesFix, hero, preview, tags?, assetSelect?}; hero/preview/dir are repo-root-relative; tags is an optional additive list driving the gallery filter chips; assetSelect ({include, exclude?} regexes on object names) tells scripts/asset_sheet.py which objects are the hero asset. build_gallery.py also emits a detail page per example at docs/gallery/<name>/.",
33
"title": "Examples and Showcase",
44
"description": "Runnable Blender Python examples, each run headless on Blender 5.2 LTS and 4.5 LTS in CI, so every render reflects code that actually runs — shown beside budget-conformance showcase props.",
55
"repoBaseUrl": "https://github.com/TMHSDigital/Blender-Developer-Tools/tree/main",
@@ -54,7 +54,10 @@
5454
"tags": [
5555
"depsgraph",
5656
"export"
57-
]
57+
],
58+
"assetSelect": {
59+
"include": "^Gamepad\\."
60+
}
5861
},
5962
{
6063
"name": "wave-displace",
@@ -120,7 +123,10 @@
120123
"tags": [
121124
"operators",
122125
"context"
123-
]
126+
],
127+
"assetSelect": {
128+
"include": "^Lantern$"
129+
}
124130
},
125131
{
126132
"name": "gn-instance-grid",
@@ -133,7 +139,10 @@
133139
"tags": [
134140
"geometry-nodes",
135141
"instancing"
136-
]
142+
],
143+
"assetSelect": {
144+
"include": "^Macropad\\."
145+
}
137146
},
138147
{
139148
"name": "gn-modifier-inputs",
@@ -146,7 +155,10 @@
146155
"tags": [
147156
"geometry-nodes",
148157
"modifiers"
149-
]
158+
],
159+
"assetSelect": {
160+
"include": "^SpiralStair\\.H3$"
161+
}
150162
},
151163
{
152164
"name": "shape-key-blend",
@@ -159,7 +171,10 @@
159171
"tags": [
160172
"mesh",
161173
"shape-keys"
162-
]
174+
],
175+
"assetSelect": {
176+
"include": "^Vase$"
177+
}
163178
},
164179
{
165180
"name": "curve-bevel-arc",
@@ -172,7 +187,10 @@
172187
"tags": [
173188
"curves",
174189
"bevel"
175-
]
190+
],
191+
"assetSelect": {
192+
"include": "^(Magnet|Clip\\w+|PoleBearings)$"
193+
}
176194
},
177195
{
178196
"name": "compositor-glare",
@@ -336,7 +354,10 @@
336354
"tags": [
337355
"export",
338356
"uv"
339-
]
357+
],
358+
"assetSelect": {
359+
"include": "^Crate\\.Authored$"
360+
}
340361
},
341362
{
342363
"name": "export-preset-axis",
@@ -348,7 +369,10 @@
348369
"preview": "examples/export-preset-axis/preview.webp",
349370
"tags": [
350371
"export"
351-
]
372+
],
373+
"assetSelect": {
374+
"include": "^RadioMast\\.Unity$"
375+
}
352376
},
353377
{
354378
"name": "lod-decimate-chain",
@@ -361,7 +385,10 @@
361385
"tags": [
362386
"depsgraph",
363387
"mesh"
364-
]
388+
],
389+
"assetSelect": {
390+
"include": "^Rocket$"
391+
}
365392
},
366393
{
367394
"name": "vertex-weight-limit",
@@ -374,7 +401,10 @@
374401
"tags": [
375402
"armature",
376403
"mesh"
377-
]
404+
],
405+
"assetSelect": {
406+
"include": "^MechArm$"
407+
}
378408
},
379409
{
380410
"name": "triangulate-tangents",
@@ -387,7 +417,10 @@
387417
"tags": [
388418
"mesh",
389419
"uv"
390-
]
420+
],
421+
"assetSelect": {
422+
"include": "^Buckler(\\.Rivets)?$"
423+
}
391424
},
392425
{
393426
"name": "gltf-skin-roundtrip",
@@ -400,7 +433,10 @@
400433
"tags": [
401434
"export",
402435
"armature"
403-
]
436+
],
437+
"assetSelect": {
438+
"include": "^ScorpionAuthored$"
439+
}
404440
},
405441
{
406442
"name": "vse-gamma-cross",
@@ -441,7 +477,10 @@
441477
"bmesh",
442478
"mesh"
443479
],
444-
"featured_rank": 5
480+
"featured_rank": 5,
481+
"assetSelect": {
482+
"include": "^(Body|Nut|PumperCap|Lug\\d|SideCap\\d)$"
483+
}
445484
},
446485
{
447486
"name": "custom-normals-shade",
@@ -454,7 +493,10 @@
454493
"tags": [
455494
"mesh",
456495
"attributes"
457-
]
496+
],
497+
"assetSelect": {
498+
"include": "_byangle$"
499+
}
458500
},
459501
{
460502
"name": "sky-texture-sun-elevation",
@@ -496,7 +538,10 @@
496538
"bmesh",
497539
"mesh",
498540
"game-pipeline"
499-
]
541+
],
542+
"assetSelect": {
543+
"include": "^Valve\\."
544+
}
500545
},
501546
{
502547
"name": "prop-origin-transform",
@@ -510,7 +555,10 @@
510555
"transforms",
511556
"parenting",
512557
"game-pipeline"
513-
]
558+
],
559+
"assetSelect": {
560+
"include": "^(Pedestal|Conduit)\\.Keep$"
561+
}
514562
},
515563
{
516564
"name": "soccer-ball-goldberg",
@@ -538,7 +586,10 @@
538586
"modifiers",
539587
"depsgraph"
540588
],
541-
"featured_rank": 1
589+
"featured_rank": 1,
590+
"assetSelect": {
591+
"include": "^(CarBody|Wheel(Front|Rear)|Headlamp|Taillamp|Grille|DoorMirror|DoorHandle(Front|Rear))$"
592+
}
542593
},
543594
{
544595
"name": "attribute-domain-shear",
@@ -566,7 +617,10 @@
566617
"bmesh",
567618
"mesh",
568619
"game-pipeline"
569-
]
620+
],
621+
"assetSelect": {
622+
"include": "^CaseSafe\\."
623+
}
570624
},
571625
{
572626
"name": "modular-kit-snap",
@@ -582,7 +636,11 @@
582636
"game-pipeline",
583637
"instancing"
584638
],
585-
"featured_rank": 8
639+
"featured_rank": 8,
640+
"assetSelect": {
641+
"include": "^Kit\\.CorridorSeg\\.",
642+
"exclude": "\\.0\\d\\d$"
643+
}
586644
},
587645
{
588646
"name": "lightmap-uv-channel",
@@ -596,7 +654,10 @@
596654
"uv",
597655
"game-pipeline",
598656
"rendering"
599-
]
657+
],
658+
"assetSelect": {
659+
"include": "^Cart\\."
660+
}
600661
},
601662
{
602663
"name": "socket-attach-points",
@@ -611,7 +672,10 @@
611672
"transforms",
612673
"game-pipeline",
613674
"instancing"
614-
]
675+
],
676+
"assetSelect": {
677+
"include": "^Drone\\.Survey\\."
678+
}
615679
},
616680
{
617681
"name": "vertex-color-ao",
@@ -626,7 +690,10 @@
626690
"attributes",
627691
"game-pipeline",
628692
"rendering"
629-
]
693+
],
694+
"assetSelect": {
695+
"include": "^Well\\.Stone\\."
696+
}
630697
},
631698
{
632699
"name": "cross-version-property-delete",

0 commit comments

Comments
 (0)