Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ Budget-conformance props. Not examples. Conventions: [`showcase/README.md`](show
<a href="showcase/cart/"><img src="showcase/cart/preview.webp" width="24%" alt="Cart: a two-wheel wooden cart with spoked wheels, slatted bed, and shafts on a dark studio floor" /></a>
<a href="showcase/park-bench/"><img src="showcase/park-bench/preview.webp" width="24%" alt="Park bench: a wrought-iron bench with scrolled legs and wooden slats on a dark studio floor" /></a>
<a href="showcase/wheelbarrow/"><img src="showcase/wheelbarrow/preview.webp" width="24%" alt="Wheelbarrow: a wooden tray with walls of stacked boards and iron straps, a spoked wheel, rear legs, and handles on a dark studio floor" /></a>
<a href="showcase/anvil/"><img src="showcase/anvil/preview.webp" width="24%" alt="Anvil: a London-pattern anvil on a hooped timber stump on a dark studio floor" /></a>
<a href="showcase/anvil/"><img src="showcase/anvil/preview.webp" width="24%" alt="Anvil: a dark forged-steel London-pattern anvil with a flared, squared waist on a hooped timber stump on a dark studio floor" /></a>
<a href="showcase/water-trough/"><img src="showcase/water-trough/preview.webp" width="24%" alt="Water trough: a watertight wooden trough with plank ends, contained water, and trestle legs on a dark studio floor" /></a>
<a href="showcase/hitching-post/"><img src="showcase/hitching-post/preview.webp" width="24%" alt="Hitching post: a square timber post with a pyramidal cap, cross-arm, iron bands wrapped around it, and two hitching rings on a dark studio floor" /></a>
<a href="showcase/grindstone/"><img src="showcase/grindstone/preview.webp" width="24%" alt="Grindstone: a stone wheel on a timber A-frame with an iron axle, hubs, crank, and tray on a dark studio floor" /></a>
Expand Down Expand Up @@ -165,7 +165,7 @@ Budget-conformance props. Not examples. Conventions: [`showcase/README.md`](show

[`wheelbarrow`](showcase/wheelbarrow/) — procedural wheelbarrow with board-built tray walls, a spoked wheel, iron straps, legs, and handles through the same pipeline. Falsifiers `--skip-decimate` exits 9, `--wide-seams` exits 17.

[`anvil`](showcase/anvil/) — procedural London-pattern anvil on a timber stump through the same pipeline. Falsifier `--skip-decimate` exits 9.
[`anvil`](showcase/anvil/) — procedural London-pattern anvil on a timber stump through the same pipeline. Falsifiers `--skip-decimate` exits 9, `--round-waist` exits 19.

[`water-trough`](showcase/water-trough/) — procedural watertight water trough on a timber stand through the same pipeline. Falsifier `--skip-decimate` exits 9.

Expand Down Expand Up @@ -404,7 +404,7 @@ evaluated topology 1044 verts / 1028 faces.
</tr>
<tr>
<td width="46%" valign="middle">
<a href="examples/text-version-stamp/"><img src="examples/text-version-stamp/preview.webp" alt="Text version stamp: beveled brass 5.1.2 numerals standing on a dark studio floor over a glowing teal underline, with a small steel BLENDER caption above — the body text is the live bpy.app.version_string" /></a>
<a href="examples/text-version-stamp/"><img src="examples/text-version-stamp/preview.webp" alt="Text version stamp: beveled brass version numerals standing on a dark plinth with a steel BLENDER caption set into its face — the body text is the live bpy.app.version_string" /></a>
</td>
<td valign="middle">

Expand Down Expand Up @@ -744,7 +744,7 @@ sources are gone, and local Z spans all three steps.
</tr>
<tr>
<td width="46%" valign="middle">
<a href="examples/cross-version-property-delete/"><img src="examples/cross-version-property-delete/preview.webp" alt="Cross-version property delete: two brass specimen tags on a dark studio stand — left tag with a cyan emissive enamel inlay (ID property kept), right tag with an empty grey pocket (ID property deleted)" /></a>
<a href="examples/cross-version-property-delete/"><img src="examples/cross-version-property-delete/preview.webp" alt="Cross-version property delete: two brass specimen tags hanging on rods from a dark studio stand — left tag with a cyan emissive enamel inlay (ID property kept), right tag with an empty grey pocket (ID property deleted)" /></a>
</td>
<td valign="middle">

Expand Down
269 changes: 237 additions & 32 deletions docs/gallery/anvil/index.html

Large diffs are not rendered by default.

Binary file modified docs/gallery/assets/anvil-hero.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/gallery/assets/cross-version-property-delete-hero.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/gallery/assets/signpost-hero.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/gallery/assets/text-version-stamp-hero.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/gallery/contact-sheets/anvil-contact-sheet.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/gallery/contact-sheets/signpost-contact-sheet.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/gallery/contact-sheets/text-version-stamp-contact-sheet.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 35 additions & 8 deletions docs/gallery/cross-version-property-delete/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
<meta property="og:image" content="https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/assets/cross-version-property-delete-hero.webp" />
<meta property="og:image:width" content="1280" />
<meta property="og:image:height" content="720" />
<meta property="og:image:alt" content="Two framed display panels on a stand: the left shows a lit cyan screen, the right a blank grey one." />
<meta property="og:image:alt" content="Two brass tags hanging from a stand on steel rods: the left shows a lit cyan inlay, the right a blank grey pocket." />
<meta property="og:site_name" content="Blender Developer Tools" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="cross-version-property-delete — Examples — Blender Developer Tools" />
<meta name="twitter:description" content="Custom ID properties are removed with del, not property_unset. The IDs are built through bpy.data.objects.new so the check does not depend on active_object." />
<meta name="twitter:image" content="https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/assets/cross-version-property-delete-hero.webp" />
<meta name="twitter:image:alt" content="Two framed display panels on a stand: the left shows a lit cyan screen, the right a blank grey one." />
<meta name="twitter:image:alt" content="Two brass tags hanging from a stand on steel rods: the left shows a lit cyan inlay, the right a blank grey pocket." />
<style>
/* fonts are deployed by the landing build (docs/fonts/) */
@font-face { font-family: 'Barlow Condensed'; font-weight: 600; font-display: swap;
Expand Down Expand Up @@ -268,8 +268,8 @@ <h1>cross-version-property-delete</h1>
<p>Custom ID properties are removed with del, not property_unset. The IDs are built through bpy.data.objects.new so the check does not depend on active_object.</p>
</header>
<main id="main">
<button class="detail-hero" id="heroZoom" type="button" aria-label="View full size: Two framed display panels on a stand: the left shows a lit cyan screen, the right a blank grey one.">
<img src="../assets/cross-version-property-delete-hero.webp" alt="Two framed display panels on a stand: the left shows a lit cyan screen, the right a blank grey one." width="1280" height="720" />
<button class="detail-hero" id="heroZoom" type="button" aria-label="View full size: Two brass tags hanging from a stand on steel rods: the left shows a lit cyan inlay, the right a blank grey pocket.">
<img src="../assets/cross-version-property-delete-hero.webp" alt="Two brass tags hanging from a stand on steel rods: the left shows a lit cyan inlay, the right a blank grey pocket." width="1280" height="720" />
</button>
<p class="zoom-hint">Rendered headless by the example itself — click to zoom.</p>
<div class="callout"><span class="tag">witnesses</span> Factory-empty has no active_object; property_unset raises TypeError and leaves the key; del removes it (clear_has=False). --skip-delete and --unset-instead exit 7.</div>
Expand All @@ -283,6 +283,8 @@ <h1>cross-version-property-delete</h1>
<p><strong>What it witnesses:</strong> <code>property_unset</code> is a TypeError on a custom ID key and does <strong>not</strong> remove it. <code>del id_block[key]</code> does. After factory-empty, there is no <code>active_object</code>.</p>
<p><strong>What failure each check would catch:</strong></p>
<ul><li>exit 2 — someone set an active object; the snippet <code>__main__</code> would have been the only path</li><li>exit 3 — the ID property never landed</li><li>exit 4 — <code>property_unset</code> removed the key or failed to raise</li><li>exit 7 — <code>del</code> did not run (<code>--skip-delete</code> / <code>--unset-instead</code> falsify this: measured <code>clear_has=True</code>)</li></ul>
<h2>Staging</h2>
<p>The two tags now hang from the stand&#x27;s bar on steel rods. The bar used to run 0.17 m behind the plates with nothing joining them, and the &quot;rings&quot; were solid discs, so the plates hung on air. The bar spans both plates, the post rises to it, and the base is as wide as what it carries. Render path only: the check reads ID properties, never geometry.</p>
<h2>Run</h2>
<pre><code>blender --background --python cross_version_property_delete.py --
blender --background --python cross_version_property_delete.py -- --output tags.png</code></pre>
Expand Down Expand Up @@ -508,6 +510,31 @@ <h2>Source</h2>
<span class="k">for</span> ob <span class="k">in</span> stand:
assign(ob, steel)

<span class="c"># Render-only staging: the check reads ID properties, never geometry.</span>
<span class="c"># The build left the bar 0.17 m behind the plates with nothing joining</span>
<span class="c"># them, and the &quot;rings&quot; are solid discs, so the plates hung on air.</span>
<span class="c"># Here the bar runs in the plates&#x27; plane above their tops, spans both,</span>
<span class="c"># and each plate hangs from it on two rods; the post rises to the bar</span>
<span class="c"># and the base is as wide as what it carries.</span>
post, base, bar = stand
plate_top = keep_plate.location.z + <span class="n">0.525</span>
bar_z = plate_top + <span class="n">0.16</span>
bar.location = (<span class="n">0.0</span>, <span class="n">0.0</span>, bar_z)
bar.scale.x = <span class="n">4.4</span> / <span class="n">2.6</span>
post.location = (<span class="n">0.0</span>, <span class="n">0.0</span>, <span class="n">0.5</span> * bar_z)
post.scale.z = bar_z / <span class="n">1.55</span>
base.location = (<span class="n">0.0</span>, <span class="n">0.0</span>, <span class="n">0.06</span>)
base.scale.x = <span class="n">4.6</span> / <span class="n">3.4</span>
hangers = []
<span class="k">for</span> plate <span class="k">in</span> (keep_plate, clear_plate):
<span class="k">for</span> dx <span class="k">in</span> (-<span class="n">0.62</span>, <span class="n">0.62</span>):
rod = cylinder(<span class="s">f&quot;</span><span class="s">Hanger</span>{len(hangers)}<span class="s">&quot;</span>, <span class="n">0.018</span>, bar_z - plate_top + <span class="n">0.05</span>,
(plate.location.x + dx, <span class="n">0.0</span>, <span class="n">0.5</span> * (plate_top - <span class="n">0.03</span> + bar_z)), segs=<span class="n">12</span>)
assign(rod, steel)
hangers.append(rod)
<span class="k">for</span> ring <span class="k">in</span> (keep_ring, clear_ring):
ring.hide_render = <span class="k">True</span>

inlay = <span class="k">None</span>
<span class="k">if</span> KEY <span class="k">in</span> keep_plate.keys():
inlay = add_inlay(<span class="s">&quot;Keep&quot;</span>, keep_plate)
Expand Down Expand Up @@ -554,13 +581,13 @@ <h2>Source</h2>
light(<span class="s">&quot;Glint&quot;</span>, (<span class="n">1.6</span>, -<span class="n">5.0</span>, <span class="n">6.0</span>), <span class="n">850.0</span>, <span class="n">0.9</span>, (<span class="n">1.0</span>, <span class="n">0.9</span>, <span class="n">0.7</span>), (<span class="n">40</span>, <span class="n">0</span>, <span class="n">18</span>))

aim = bpy.data.objects.new(<span class="s">&quot;Aim&quot;</span>, <span class="k">None</span>)
aim.location = (<span class="n">0.0</span>, <span class="n">0.0</span>, <span class="n">1.15</span>)
aim.location = (<span class="n">0.0</span>, <span class="n">0.0</span>, <span class="n">0.95</span>)
aim.hide_render = <span class="k">True</span>
scene.collection.objects.link(aim)
cam_data = bpy.data.cameras.new(<span class="s">&quot;Cam&quot;</span>)
cam_data.lens = <span class="n">50.0</span>
cam = bpy.data.objects.new(<span class="s">&quot;Cam&quot;</span>, cam_data)
cam.location = (<span class="n">3.55</span>, -<span class="n">6.59</span>, <span class="n">3.30</span>)
cam.location = (<span class="n">3.95</span>, -<span class="n">7.35</span>, <span class="n">3.3</span>)
scene.collection.objects.link(cam)
scene.camera = cam
track = cam.constraints.new(<span class="s">&quot;TRACK_TO&quot;</span>)
Expand All @@ -582,7 +609,7 @@ <h2>Source</h2>
scene.render.filepath = path
scene.view_settings.view_transform = <span class="s">&quot;Standard&quot;</span>

hero = [keep_plate, clear_plate, keep_ring, clear_ring] + list(stand)
hero = [keep_plate, clear_plate] + list(stand) + hangers
<span class="k">if</span> inlay <span class="k">is</span> <span class="k">not</span> <span class="k">None</span>:
hero.append(inlay)
fcode = gallery_framing.check_framing(
Expand Down Expand Up @@ -646,7 +673,7 @@ <h2>Source</h2>
</main>
<dialog class="lightbox" id="lightbox" aria-label="Full-size render">
<button class="lightbox-close" type="button" autofocus>Close</button>
<img src="../assets/cross-version-property-delete-hero.webp" alt="Two framed display panels on a stand: the left shows a lit cyan screen, the right a blank grey one." />
<img src="../assets/cross-version-property-delete-hero.webp" alt="Two brass tags hanging from a stand on steel rods: the left shows a lit cyan inlay, the right a blank grey pocket." />
</dialog>
<footer>
<div class="statusbar">
Expand Down
10 changes: 5 additions & 5 deletions docs/gallery/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ <h2><a href="armature-bend/">armature-bend</a></h2>
</article>
<article class="card" data-tags="curves depsgraph rendering">
<a class="card-media" href="text-version-stamp/" tabindex="-1" aria-hidden="true">
<img src="assets/text-version-stamp-hero.webp" alt="The word BLENDER above the Blender version number in large gold 3D characters." loading="lazy" decoding="async" />
<img src="assets/text-version-stamp-hero.webp" alt="The Blender version number in large gold 3D characters standing on a dark plinth, the word BLENDER set into its face." loading="lazy" decoding="async" />
</a>
<div class="card-body">
<h2><a href="text-version-stamp/">text-version-stamp</a></h2>
Expand Down Expand Up @@ -849,7 +849,7 @@ <h2><a href="vertex-color-ao/">vertex-color-ao</a></h2>
</article>
<article class="card" data-tags="context properties">
<a class="card-media" href="cross-version-property-delete/" tabindex="-1" aria-hidden="true">
<img src="assets/cross-version-property-delete-hero.webp" alt="Two framed display panels on a stand: the left shows a lit cyan screen, the right a blank grey one." loading="lazy" decoding="async" />
<img src="assets/cross-version-property-delete-hero.webp" alt="Two brass tags hanging from a stand on steel rods: the left shows a lit cyan inlay, the right a blank grey pocket." loading="lazy" decoding="async" />
</a>
<div class="card-body">
<h2><a href="cross-version-property-delete/">cross-version-property-delete</a></h2>
Expand Down Expand Up @@ -1047,12 +1047,12 @@ <h2><a href="wheelbarrow/">wheelbarrow</a></h2>
</article>
<article class="card" data-tags="mesh export showcase">
<a class="card-media" href="anvil/" tabindex="-1" aria-hidden="true">
<img src="assets/anvil-hero.webp" alt="A black iron anvil mounted on a hooped timber stump." loading="lazy" decoding="async" />
<img src="assets/anvil-hero.webp" alt="A dark forged-steel anvil with a flared, squared waist, mounted on a hooped timber stump." loading="lazy" decoding="async" />
</a>
<div class="card-body">
<h2><a href="anvil/">anvil</a></h2>
<p class="teaches">A procedural blacksmith anvil on a timber stump through UVs, bake, LOD, collider, and Unity glTF, asserting recomputed budgets rather than an API contract.</p>
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 2988 tris, two materials with 1040 wood and 822 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 0.621×0.414×0.489 m, LOD ratios in band, convex collider 134 tris, hygiene 0, 16 grounded staves, hoop bite 0.003 m, foot-on-head gap 0.003 m, non-empty glTF. --skip-decimate exits 9; --stray-vert 15; --lift-z/--short-staves 16; --float-anvil 17; --round-band 18.</p>
<p class="witnesses"><span class="tag">witnesses</span> Recomputed: 3052 tris, two materials with 1040 wood and 854 metal faces, UVs in 0..1 with zero AABB overlap, outer AABB 0.621×0.414×0.489 m, LOD ratios in band, convex collider 134 tris, hygiene 0, 16 grounded staves, hoop bite 0.003 m, foot-on-head gap 0.003 m, waist corner reach 0.8572, non-empty glTF. --skip-decimate exits 9; --stray-vert 15; --lift-z/--short-staves 16; --float-anvil 17; --round-band 18; --round-waist 19.</p>
<a class="card-link" href="anvil/">View showcase piece<span class="sr-only"> anvil</span> <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
Expand Down Expand Up @@ -1102,7 +1102,7 @@ <h2><a href="hand-pump/">hand-pump</a></h2>
</article>
<article class="card" data-tags="mesh export showcase">
<a class="card-media" href="signpost/" tabindex="-1" aria-hidden="true">
<img src="assets/signpost-hero.webp" alt="A wooden signpost with two pointed finger boards and dark iron bands on the post." loading="lazy" decoding="async" />
<img src="assets/signpost-hero.webp" alt="A wooden signpost with two pointed finger boards in worn cream paint and rusted iron bands on the post." loading="lazy" decoding="async" />
</a>
<div class="card-body">
<h2><a href="signpost/">signpost</a></h2>
Expand Down
Loading
Loading