Skip to content

Commit dfcbd52

Browse files
TMHSDigitalclaude
andcommitted
fix(examples): regenerate the gallery page and examples index after #489
3c5490b changed temp-override-join's README and the smoke catalog without regenerating docs/gallery/temp-override-join/ or examples/index.json, so both drift checks went red. The exit-13 row also still pointed at --clear-active-on-deselect as if it were a falsifier. Refs #489 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
1 parent 3c5490b commit dfcbd52

3 files changed

Lines changed: 9 additions & 14 deletions

File tree

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ <h1>Temp Override Join</h1>
6464
<p>A runnable example that assembles a hurricane lantern from seven separate part objects with one <code>object.join</code> under <code>bpy.context.temp_override</code>, following the <a href="https://github.com/TMHSDigital/Blender-Developer-Tools/tree/main/rules/prefer-temp-override-over-context-copy.mdc"><code>prefer-temp-override-over-context-copy</code></a> rule and the <a href="https://github.com/TMHSDigital/Blender-Developer-Tools/tree/main/skills/operators/SKILL.md"><code>operators</code></a> skill: operators that need a fabricated active/selection context run under <code>temp_override(**kwargs)</code>, not the deprecated <code>bpy.context.copy()</code> dict-pass form removed in Blender 5.x.</p>
6565
<p>The parts are the way a prop artist blocks the lantern out: a red enamel fount, an amber glass globe, an iron wire guard, the two hurricane side air tubes, the bell cap, the wire bail with its wooden grip, and the brass wick knob and filler cap. Each is its own object with its own mesh, materials and transform. The join produces the single <code>Lantern</code> object an engine wants.</p>
6666
<p><strong>What it witnesses:</strong> <code>object.join</code> under <code>temp_override</code> actually consumes the sources and merges their material slots. The check asserts that exactly one mesh remains and it is the target, that all six sources are gone, and that no geometry was lost (verts and faces equal the sum over the parts). The joined mesh must carry exactly the five part materials, once each, and every material must still own exactly the faces its parts brought. So the glass is still glass and the grip is still wood. The local Z span must run from the fount&#x27;s foot (0) to the top of the grip (closed form 2.303), which proves the part transforms were applied. A no-op override (the 5.x failure mode of the old dict-pass path) leaves seven objects.</p>
67-
<p><strong>Why the override passes the selection explicitly.</strong> Before the join, the check makes the target active, selects every part, and runs <code>select_all(action=&#x27;DESELECT&#x27;)</code>. The target is still <code>context.active_object</code> while <code>selected_objects</code> is empty and <code>target.select_get()</code> is <code>False</code>. Active and selected are independent, so an <code>if obj is None</code> guard passes on a selection that is gone (see the <a href="https://github.com/TMHSDigital/Blender-Developer-Tools/tree/main/skills/operators/SKILL.md"><code>operators</code></a> skill, Defensive context handling). The scene is then reset to no active object before the join. <code>--clear-active-on-deselect</code> models the wrong belief that deselecting clears the active object, and exits 13.</p>
67+
<p><strong>Why the override passes the selection explicitly.</strong> Before the join, the check makes the target active, selects every part, and runs <code>select_all(action=&#x27;DESELECT&#x27;)</code>. The target is still <code>context.active_object</code> while <code>selected_objects</code> is empty and <code>target.select_get()</code> is <code>False</code>. Active and selected are independent, so an <code>if obj is None</code> guard passes on a selection that is gone (see the <a href="https://github.com/TMHSDigital/Blender-Developer-Tools/tree/main/skills/operators/SKILL.md"><code>operators</code></a> skill, Defensive context handling). The scene is then reset to no active object before the join. <code>--clear-active-on-deselect</code> is a self-check, not a falsifier: the script clears the active object itself, then shows exit 13 reports it. No Blender deselection clears the active object (that is the contract), so the default run is the witness: if a Blender release changed that, it would exit 13 (#489).</p>
6868
<p><strong>The render is the joined object.</strong> Everything in the still is one mesh object. It shows five materials because the slots merged and the per-face indices were remapped. If they had not been, the lantern would render in the target&#x27;s red enamel from grip to foot. A shadowless warm point light inside the globe (render-only) stands in for the lit wick.</p>
6969
<h2 id="run">Run<a class="anchor" href="#run" aria-label="Link to this section">#</a></h2>
7070
<pre tabindex="0"><code># Cheap correctness check (no render) — the CI check:
@@ -73,16 +73,16 @@ <h2 id="run">Run<a class="anchor" href="#run" aria-label="Link to this section">
7373
# Falsifier: join without temp_override. Must exit non-zero.
7474
blender --background --python temp_override_join.py -- --no-override
7575

76-
# Falsifier: pretend deselect-all clears the active object. Must exit 13.
76+
# Self-check (not a falsifier): clear the active object by hand; exit 13 reports it.
7777
blender --background --python temp_override_join.py -- --clear-active-on-deselect
7878

7979
# Also render a still (EEVEE on a GPU host; use --engine cycles on GPU-less hosts):
8080
blender --background --python temp_override_join.py -- --output join.png
8181
blender --background --python temp_override_join.py -- --output join.png --engine cycles</code></pre>
8282
<h2 id="exit-codes">Exit codes<a class="anchor" href="#exit-codes" aria-label="Link to this section">#</a></h2>
8383
<p>Per-script sequential checks. <code>9</code> is a valid check code; there is no rule against it.</p>
84-
<div class="table-wrap"><table><thead><tr><th scope="col">Code</th><th scope="col">Meaning</th></tr></thead><tbody><tr><td>0</td><td>Success</td></tr><tr><td>1</td><td>Uncaught exception (FATAL wrapper)</td></tr><tr><td>2</td><td>argparse / usage</td></tr><tr><td>3</td><td>Mesh object count after join ≠ 1 (<code>--no-override</code> lands here)</td></tr><tr><td>4</td><td>Joined target is not the sole remaining mesh</td></tr><tr><td>5</td><td>Verts / faces ≠ the sum over the seven parts</td></tr><tr><td>6</td><td>Source objects still present</td></tr><tr><td>7</td><td>Local Z span ≠ [0, 2.303]: a part transform was not applied</td></tr><tr><td>8</td><td>Material slots ≠ the five part materials, once each</td></tr><tr><td>9</td><td>Faces per material ≠ what the parts brought (indices not remapped)</td></tr><tr><td>10</td><td><code>--output</code> framing gate (<code>gallery_framing</code>)</td></tr><tr><td>11</td><td><code>--output</code> asset-quality floors (<code>gallery_asset_quality</code>)</td></tr><tr><td>12</td><td><code>--output</code> produced no file</td></tr><tr><td>13</td><td>After deselect-all the target is not still active-but-unselected, or something is still selected (<code>--clear-active-on-deselect</code> lands here)</td></tr></tbody></table></div>
85-
<p>The <code>blender-smoke</code> workflow runs the check on Blender 5.2 LTS and 4.5 LTS (5.1 on the weekly cron, the <code>needs-5.1</code> PR label, or manual dispatch). Smoke does not pass <code>--output</code>. Its catalog falsifiers are <code>--no-override</code> (expects exit 3) and <code>--clear-active-on-deselect</code> (exit 13).</p>
84+
<div class="table-wrap"><table><thead><tr><th scope="col">Code</th><th scope="col">Meaning</th></tr></thead><tbody><tr><td>0</td><td>Success</td></tr><tr><td>1</td><td>Uncaught exception (FATAL wrapper)</td></tr><tr><td>2</td><td>argparse / usage</td></tr><tr><td>3</td><td>Mesh object count after join ≠ 1 (<code>--no-override</code> lands here)</td></tr><tr><td>4</td><td>Joined target is not the sole remaining mesh</td></tr><tr><td>5</td><td>Verts / faces ≠ the sum over the seven parts</td></tr><tr><td>6</td><td>Source objects still present</td></tr><tr><td>7</td><td>Local Z span ≠ [0, 2.303]: a part transform was not applied</td></tr><tr><td>8</td><td>Material slots ≠ the five part materials, once each</td></tr><tr><td>9</td><td>Faces per material ≠ what the parts brought (indices not remapped)</td></tr><tr><td>10</td><td><code>--output</code> framing gate (<code>gallery_framing</code>)</td></tr><tr><td>11</td><td><code>--output</code> asset-quality floors (<code>gallery_asset_quality</code>)</td></tr><tr><td>12</td><td><code>--output</code> produced no file</td></tr><tr><td>13</td><td>After deselect-all the target is not still active-but-unselected, or something is still selected (the <code>--clear-active-on-deselect</code> self-check lands here)</td></tr></tbody></table></div>
85+
<p>The <code>blender-smoke</code> workflow runs the check on Blender 5.2 LTS and 4.5 LTS (5.1 on the weekly cron, the <code>needs-5.1</code> PR label, or manual dispatch). Smoke does not pass <code>--output</code>. Its catalog falsifier is <code>--no-override</code> (expects exit 3). <code>--clear-active-on-deselect</code> is not in the catalog: it reaches exit 13 only by writing the value the check reads, so it would pass whatever Blender did (#489).</p>
8686
</section>
8787
<section class="detail-section src" id="source">
8888
<h2>Source</h2>

‎examples/index.json‎

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -750,11 +750,12 @@
750750
"1": "Uncaught exception (FATAL wrapper)",
751751
"2": "argparse / usage",
752752
"3": "Template does not validate or build, or the zip lacks its manifest",
753-
"4": "`build` accepted the missing-wheel package, or `validate` rejected it (`--ship-wheel` lands here)",
753+
"4": "`build` accepted the missing-wheel package (`--ship-wheel` lands here)",
754754
"5": "`server-generate` listing missing or wrong",
755755
"6": "Install, import, upgrade or remove failed, or `__package__` wrong",
756756
"7": "User data inside the install tree, lost on upgrade, or kept after removal (`--data-next-to-file` lands here)",
757-
"8": "`online_access` default or `--online-mode` value wrong"
757+
"8": "`online_access` default or `--online-mode` value wrong",
758+
"9": "`validate` rejected the missing-wheel package: the validate-is-not-a-gate trap is gone"
758759
}
759760
},
760761
{
@@ -1909,12 +1910,6 @@
19091910
"--no-override"
19101911
],
19111912
"expect_exit": 3
1912-
},
1913-
{
1914-
"args": [
1915-
"--clear-active-on-deselect"
1916-
],
1917-
"expect_exit": 13
19181913
}
19191914
],
19201915
"exit_codes": {
@@ -1931,7 +1926,7 @@
19311926
"10": "`--output` framing gate (`gallery_framing`)",
19321927
"11": "`--output` asset-quality floors (`gallery_asset_quality`)",
19331928
"12": "`--output` produced no file",
1934-
"13": "After deselect-all the target is not still active-but-unselected, or something is still selected (`--clear-active-on-deselect` lands here)"
1929+
"13": "After deselect-all the target is not still active-but-unselected, or something is still selected (the `--clear-active-on-deselect` self-check lands here)"
19351930
}
19361931
},
19371932
{

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ against it.
7676
| 10 | `--output` framing gate (`gallery_framing`) |
7777
| 11 | `--output` asset-quality floors (`gallery_asset_quality`) |
7878
| 12 | `--output` produced no file |
79-
| 13 | After deselect-all the target is not still active-but-unselected, or something is still selected (`--clear-active-on-deselect` lands here) |
79+
| 13 | After deselect-all the target is not still active-but-unselected, or something is still selected (the `--clear-active-on-deselect` self-check lands here) |
8080

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

0 commit comments

Comments
 (0)