Skip to content

Commit c4dc4a1

Browse files
TMHSDigitalclaude
andcommitted
fix(examples): redesign temp-override-join as a hurricane lantern joined from seven parts
The review found three orange and grey cubes stacked like a bar chart. That is programmer art, and the render said nothing about joining. The subject is now a prop that is naturally assembled by a join: a hurricane lantern built as seven part objects (fount, glass globe, wire guard, side air tubes, bell cap, bail with wooden grip, brasswork). Each part has its own mesh, materials and object transform. One object.join under temp_override turns them into the single Lantern object. The hero is that joined object, and it shows five materials only because the join merged the slots and remapped the per-face indices. Checks: object count, target identity, sources gone and the Z span are kept. The Z span is now closed form from foot to grip top, and it proves the part transforms were applied. Topology is now the sum over the parts. Two checks are new: the slots must be exactly the five part materials, once each (exit 8), and faces per material must equal what the parts brought in (exit 9). The render path now runs gallery_framing (10) and gallery_asset_quality (11). It had never called the framing gate before. "no file" moves from 8 to 12. scripts/asset_sheet.py gains a SELECT row. The ROADMAP floor survey drops temp-override-join from the edge90 list, since it now measures 0.007. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
1 parent 1b096de commit c4dc4a1

12 files changed

Lines changed: 886 additions & 264 deletions

File tree

‎README.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -749,15 +749,15 @@ and every orbit lands on its closed form.
749749
<table>
750750
<tr>
751751
<td width="46%" valign="middle">
752-
<a href="examples/temp-override-join/"><img src="examples/temp-override-join/preview.webp" alt="Temp-override join: an amber three-step staircase of joined unit cubes on a dark studio floor" /></a>
752+
<a href="examples/temp-override-join/"><img src="examples/temp-override-join/preview.webp" alt="Temp-override join: a red enamel hurricane lantern with a glowing amber globe, wire guard, brass knob and wooden bail grip, joined from seven parts into one object" /></a>
753753
</td>
754754
<td valign="middle">
755755

756756
### [temp-override-join](examples/temp-override-join/)
757757

758-
Three unit cubes joined into a staircase under `bpy.context.temp_override` — the supported
759-
replacement for the removed `context.copy()` dict-pass form. Asserts one mesh remains,
760-
sources are gone, and local Z spans all three steps.
758+
A hurricane lantern joined from seven part objects under `bpy.context.temp_override` — the
759+
supported replacement for the removed `context.copy()` dict-pass form. Asserts one mesh
760+
remains, sources are gone, and the five part materials merge with every face kept on its own.
761761

762762
</td>
763763
</tr>

‎ROADMAP.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ any example remodel.
224224

225225
- naming (default datablock names): gltf-skin-roundtrip (3 parts), gn-sdf-remesh (`Torus`), turntable (`Suzanne`)
226226
- materials (multi-part, single material): armature-bend (3 parts/1 mat — vertex-color weight bands are the honest display), degenerate-bevel-weld (2/1), driver-wave (16/1, also edge90 1.0)
227-
- edge90 (raw right angles, 1.0): depsgraph-export (also naming + materials), image-pixels-testcard, png-exr-alpha, temp-override-join, text-version-stamp, vse-cut-list; vse-gamma-cross at 0.92
227+
- edge90 (raw right angles, 1.0): depsgraph-export (also naming + materials), image-pixels-testcard, png-exr-alpha, text-version-stamp, vse-cut-list; vse-gamma-cross at 0.92
228228
- reference: gallery best-modeled measure collision-hull-proxy 0.044, custom-normals-shade 0.288, vertex-weight-limit 0.150, lod-decimate-chain 0.019; calibration details in `docs/VISUAL-STYLE.md` § Asset quality
229229

230230
## Future (uncommitted)
54.4 KB
Loading
12.4 KB
Loading
-7.55 KB
Loading

‎docs/gallery/index.html‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -431,12 +431,12 @@ <h2><a href="shader-node-group/">shader-node-group</a></h2>
431431
</article>
432432
<article class="card" data-tags="operators context">
433433
<a class="card-media" href="temp-override-join/" tabindex="-1" aria-hidden="true">
434-
<img src="assets/temp-override-join-hero.webp" alt="Three amber cubes joined into a single diagonal staircase object, the upper steps standing on grey plinths." loading="lazy" decoding="async" />
434+
<img src="assets/temp-override-join-hero.webp" alt="A red enamel hurricane lantern with a glowing amber glass globe, black wire guard, side air tubes, brass wick knob and a wire bail with a wooden grip, all one joined object on a dark studio floor." loading="lazy" decoding="async" />
435435
</a>
436436
<div class="card-body">
437437
<h2><a href="temp-override-join/">temp-override-join</a></h2>
438-
<p class="teaches">Join three unit cubes into a staircase under bpy.context.temp_override — the supported replacement for the removed context.copy() dict-pass form.</p>
439-
<p class="witnesses"><span class="tag">witnesses</span> temp_override actually applies: join consumes the sources, exactly one mesh remains, topology is verts = 8 × steps, and local Z spans all three steps.</p>
438+
<p class="teaches">Join seven lantern parts into one object under bpy.context.temp_override — the supported replacement for the removed context.copy() dict-pass form.</p>
439+
<p class="witnesses"><span class="tag">witnesses</span> temp_override actually applies: join consumes all six sources, exactly one mesh remains, no geometry is lost, the five part materials merge into one slot each with every face still on its own material, and local Z spans foot to grip.</p>
440440
<a class="card-link" href="temp-override-join/">View example<span class="sr-only"> temp-override-join</span> <span aria-hidden="true">&rarr;</span></a>
441441
</div>
442442
</article>

‎docs/gallery/temp-override-join/index.html‎

Lines changed: 430 additions & 128 deletions
Large diffs are not rendered by default.

‎examples/gallery.json‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@
112112
{
113113
"name": "temp-override-join",
114114
"dir": "examples/temp-override-join",
115-
"teaches": "Join three unit cubes into a staircase under bpy.context.temp_override — the supported replacement for the removed context.copy() dict-pass form.",
116-
"alt": "Three amber cubes joined into a single diagonal staircase object, the upper steps standing on grey plinths.",
117-
"witnessesFix": "temp_override actually applies: join consumes the sources, exactly one mesh remains, topology is verts = 8 × steps, and local Z spans all three steps.",
115+
"teaches": "Join seven lantern parts into one object under bpy.context.temp_override — the supported replacement for the removed context.copy() dict-pass form.",
116+
"alt": "A red enamel hurricane lantern with a glowing amber glass globe, black wire guard, side air tubes, brass wick knob and a wire bail with a wooden grip, all one joined object on a dark studio floor.",
117+
"witnessesFix": "temp_override actually applies: join consumes all six sources, exactly one mesh remains, no geometry is lost, the five part materials merge into one slot each with every face still on its own material, and local Z spans foot to grip.",
118118
"hero": "docs/gallery/assets/temp-override-join-hero.webp",
119119
"preview": "examples/temp-override-join/preview.webp",
120120
"tags": [

‎examples/temp-override-join/README.md‎

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,32 @@
11
# Temp-Override Join
22

3-
A runnable example that joins three unit cubes into a staircase using
4-
`bpy.context.temp_override`, following the
3+
A runnable example that assembles a hurricane lantern from seven separate part objects
4+
with one `object.join` under `bpy.context.temp_override`, following the
55
[`prefer-temp-override-over-context-copy`](../../rules/prefer-temp-override-over-context-copy.mdc)
66
rule and the [`operators`](../../skills/operators/SKILL.md) skill: operators that need a
77
fabricated active/selection context run under `temp_override(**kwargs)`, not the deprecated
88
`bpy.context.copy()` dict-pass form removed in Blender 5.x.
99

10-
**What it witnesses:** `object.join` under `temp_override` actually consumes the sources.
11-
The check asserts closed-form topology (verts = 8 × steps, faces = 6 × steps), that exactly
12-
one mesh remains, that the sources are gone, and that the local Z span covers all three
13-
steps (`[-0.5, 2.5]`). A no-op override (the 5.x failure mode of the old dict-pass path)
14-
leaves only step 0 and the Z span fails.
10+
The parts are the way a prop artist blocks the lantern out: a red enamel fount, an amber
11+
glass globe, an iron wire guard, the two hurricane side air tubes, the bell cap, the wire
12+
bail with its wooden grip, and the brass wick knob and filler cap. Each is its own object
13+
with its own mesh, materials and transform. The join produces the single `Lantern` object an
14+
engine wants.
15+
16+
**What it witnesses:** `object.join` under `temp_override` actually consumes the sources
17+
and merges their material slots. The check asserts that exactly one mesh remains and it is
18+
the target, that all six sources are gone, and that no geometry was lost (verts and faces
19+
equal the sum over the parts). The joined mesh must carry exactly the five part materials,
20+
once each, and every material must still own exactly the faces its parts brought. So the
21+
glass is still glass and the grip is still wood. The local Z span must run from the fount's
22+
foot (0) to the top of the grip (closed form 2.303), which proves the part transforms were
23+
applied. A no-op override (the 5.x failure mode of the old dict-pass path) leaves seven
24+
objects.
25+
26+
**The render is the joined object.** Everything in the still is one mesh object. It shows
27+
five materials because the slots merged and the per-face indices were remapped. If they had
28+
not been, the lantern would render in the target's red enamel from grip to foot. A shadowless
29+
warm point light inside the globe (render-only) stands in for the lit wick.
1530

1631
## Run
1732

@@ -39,10 +54,14 @@ against it.
3954
| 2 | argparse / usage |
4055
| 3 | Mesh object count after join ≠ 1 (`--no-override` lands here) |
4156
| 4 | Joined target is not the sole remaining mesh |
42-
| 5 | Topology ≠ 24 verts / 18 faces |
57+
| 5 | Verts / faces ≠ the sum over the seven parts |
4358
| 6 | Source objects still present |
44-
| 7 | Local Z span did not cover all steps |
45-
| 8 | `--output` produced no file |
59+
| 7 | Local Z span ≠ [0, 2.303]: a part transform was not applied |
60+
| 8 | Material slots ≠ the five part materials, once each |
61+
| 9 | Faces per material ≠ what the parts brought (indices not remapped) |
62+
| 10 | `--output` framing gate (`gallery_framing`) |
63+
| 11 | `--output` asset-quality floors (`gallery_asset_quality`) |
64+
| 12 | `--output` produced no file |
4665

4766
The `blender-smoke` workflow runs the check on Blender 5.2 LTS and 4.5 LTS
4867
(5.1 on the weekly cron, the `needs-5.1` PR label, or manual dispatch).
11.2 KB
Loading

0 commit comments

Comments
 (0)