Skip to content

Commit 2c7051b

Browse files
TMHSDigitalclaude
andauthored
fix: gallery quality audit of the six newest examples (restage color-attribute-wheel, relight armature-bend) (#61)
Visual and editorial audit of the six most recently shipped gallery examples. color-attribute-wheel is restaged (disc leans toward camera, tighter framing, warm backdrop wedge, hue origin rotated off the horizon so the red wrap reads as a spoke, matte material so the horizon no longer reflects across the face). armature-bend is relit to the gallery's dark staged look (Standard view transform so the BoneTint weight bands stay saturated, shaped key, warm wedge). grease-pencil-rosette card copy fixed: frames.new() -> frames.new(1). The other three examples (parent-inverse-orrery, text-version-stamp, image-pixels-testcard) pass the audit untouched. Checks unchanged; both examples verified exit 0 on Blender 4.5.11 LTS and 5.1.2 locally. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 039e263 commit 2c7051b

12 files changed

Lines changed: 83 additions & 33 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ toward the core (dot ≥ 0.998).
252252
</tr>
253253
<tr>
254254
<td width="46%" valign="middle">
255-
<a href="examples/color-attribute-wheel/"><img src="examples/color-attribute-wheel/preview.webp" alt="Color attribute wheel: an HSV color wheel disc with a white center fading into a vivid rainbow rim, resting on a dark studio floor" /></a>
255+
<a href="examples/color-attribute-wheel/"><img src="examples/color-attribute-wheel/preview.webp" alt="Color attribute wheel: an HSV color wheel disc with a white center fading into a vivid rainbow rim, leaning upright toward the camera on a dark studio floor with a warm light pool behind it" /></a>
256256
</td>
257257
<td valign="middle">
258258

‎docs/gallery/armature-bend/index.html‎

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,8 @@ <h2>Source</h2>
434434
fmat = bpy.data.materials.new(<span class="s">&quot;Studio&quot;</span>)
435435
fmat.use_nodes = <span class="k">True</span>
436436
fb = fmat.node_tree.nodes[<span class="s">&quot;Principled BSDF&quot;</span>]
437-
fb.inputs[<span class="s">&quot;Base Color&quot;</span>].default_value = (<span class="n">0.05</span>, <span class="n">0.055</span>, <span class="n">0.065</span>, <span class="n">1.0</span>)
438-
fb.inputs[<span class="s">&quot;Roughness&quot;</span>].default_value = <span class="n">0.55</span>
437+
fb.inputs[<span class="s">&quot;Base Color&quot;</span>].default_value = (<span class="n">0.03</span>, <span class="n">0.032</span>, <span class="n">0.037</span>, <span class="n">1.0</span>)
438+
fb.inputs[<span class="s">&quot;Roughness&quot;</span>].default_value = <span class="n">0.7</span>
439439
floor_me.materials.append(fmat)
440440
floor = bpy.data.objects.new(<span class="s">&quot;Floor&quot;</span>, floor_me)
441441
scene.collection.objects.link(floor)
@@ -446,7 +446,7 @@ <h2>Source</h2>
446446

447447
world = bpy.data.worlds.new(<span class="s">&quot;World&quot;</span>)
448448
world.use_nodes = <span class="k">True</span>
449-
world.node_tree.nodes[<span class="s">&quot;Background&quot;</span>].inputs[<span class="s">&quot;Color&quot;</span>].default_value = (<span class="n">0.03</span>, <span class="n">0.033</span>, <span class="n">0.04</span>, <span class="n">1.0</span>)
449+
world.node_tree.nodes[<span class="s">&quot;Background&quot;</span>].inputs[<span class="s">&quot;Color&quot;</span>].default_value = (<span class="n">0.02</span>, <span class="n">0.021</span>, <span class="n">0.025</span>, <span class="n">1.0</span>)
450450
scene.world = world
451451

452452
<span class="k">def</span> light(name, loc, energy, size, col, rot):
@@ -457,9 +457,14 @@ <h2>Source</h2>
457457
ob.rotation_euler = tuple(math.radians(a) <span class="k">for</span> a <span class="k">in</span> rot)
458458
scene.collection.objects.link(ob)
459459

460-
light(<span class="s">&quot;Key&quot;</span>, (-<span class="n">4.0</span>, -<span class="n">5.0</span>, <span class="n">6.0</span>), <span class="n">1500.0</span>, <span class="n">7.0</span>, (<span class="n">1.0</span>, <span class="n">0.97</span>, <span class="n">0.92</span>), (<span class="n">48</span>, <span class="n">0</span>, -<span class="n">38</span>))
461-
light(<span class="s">&quot;Fill&quot;</span>, (<span class="n">5.0</span>, -<span class="n">4.0</span>, <span class="n">3.0</span>), <span class="n">500.0</span>, <span class="n">9.0</span>, (<span class="n">0.75</span>, <span class="n">0.85</span>, <span class="n">1.0</span>), (<span class="n">62</span>, <span class="n">0</span>, <span class="n">50</span>))
462-
light(<span class="s">&quot;Rim&quot;</span>, (<span class="n">0.5</span>, <span class="n">4.5</span>, <span class="n">5.0</span>), <span class="n">900.0</span>, <span class="n">5.0</span>, (<span class="n">0.55</span>, <span class="n">0.75</span>, <span class="n">1.0</span>), (-<span class="n">55</span>, <span class="n">0</span>, <span class="n">175</span>))
460+
<span class="c"># a shaped warm key from the upper left, a faint cool fill so the shadow</span>
461+
<span class="c"># side of each tube stays legible, a cool rim to lift the silhouettes off</span>
462+
<span class="c"># the backdrop, and a warm wedge raking the back wall — the falloff pool</span>
463+
<span class="c"># behind the subjects that the rest of the gallery stages against.</span>
464+
light(<span class="s">&quot;Key&quot;</span>, (-<span class="n">4.0</span>, -<span class="n">5.0</span>, <span class="n">6.0</span>), <span class="n">650.0</span>, <span class="n">4.5</span>, (<span class="n">1.0</span>, <span class="n">0.96</span>, <span class="n">0.9</span>), (<span class="n">48</span>, <span class="n">0</span>, -<span class="n">38</span>))
465+
light(<span class="s">&quot;Fill&quot;</span>, (<span class="n">5.0</span>, -<span class="n">4.0</span>, <span class="n">3.0</span>), <span class="n">110.0</span>, <span class="n">9.0</span>, (<span class="n">0.75</span>, <span class="n">0.85</span>, <span class="n">1.0</span>), (<span class="n">62</span>, <span class="n">0</span>, <span class="n">50</span>))
466+
light(<span class="s">&quot;Rim&quot;</span>, (<span class="n">0.5</span>, <span class="n">4.5</span>, <span class="n">5.0</span>), <span class="n">350.0</span>, <span class="n">4.0</span>, (<span class="n">0.6</span>, <span class="n">0.78</span>, <span class="n">1.0</span>), (-<span class="n">55</span>, <span class="n">0</span>, <span class="n">175</span>))
467+
light(<span class="s">&quot;Wedge&quot;</span>, (<span class="n">2.5</span>, <span class="n">3.5</span>, <span class="n">4.2</span>), <span class="n">520.0</span>, <span class="n">6.0</span>, (<span class="n">1.0</span>, <span class="n">0.76</span>, <span class="n">0.5</span>), (-<span class="n">72</span>, <span class="n">0</span>, <span class="n">195</span>))
463468

464469
cam_data = bpy.data.cameras.new(<span class="s">&quot;Cam&quot;</span>)
465470
cam_data.lens = <span class="n">45.0</span>
@@ -481,6 +486,9 @@ <h2>Source</h2>
481486
scene.render.resolution_y = <span class="n">720</span>
482487
scene.render.image_settings.file_format = <span class="s">&#x27;PNG&#x27;</span>
483488
scene.render.filepath = path
489+
<span class="c"># AgX (the 4.x/5.x default) desaturates the BoneTint bands toward pastel,</span>
490+
<span class="c"># hiding exactly the weight boundaries the LBS check asserts.</span>
491+
scene.view_settings.view_transform = <span class="s">&#x27;Standard&#x27;</span>
484492
bpy.ops.render.render(write_still=<span class="k">True</span>)
485493
<span class="k">return</span> os.path.exists(path) <span class="k">and</span> os.path.getsize(path) &gt; <span class="n">0</span>
486494

1.06 KB
Loading
-1.39 KB
Loading

‎docs/gallery/color-attribute-wheel/index.html‎

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,15 @@ <h2>Source</h2>
244244
<span class="s">&quot;&quot;&quot;Vertex coords and per-vertex (h, s, v) in the same order as vidx().&quot;&quot;&quot;</span>
245245
coords = [(<span class="n">0.0</span>, <span class="n">0.0</span>, <span class="n">0.0</span>)]
246246
hsv = [(<span class="n">0.0</span>, <span class="n">0.0</span>, <span class="n">1.0</span>)] <span class="c"># center: fully desaturated, white</span>
247+
<span class="c"># the hue origin is rotated off the picture horizontal: red is the</span>
248+
<span class="c"># perceptually sharpest hue transition, and the 0/360-degree wrap reads</span>
249+
<span class="c"># as a seam artifact when it lies level in frame</span>
250+
angle0 = math.radians(-<span class="n">52.0</span>)
247251
<span class="k">for</span> r <span class="k">in</span> range(<span class="n">1</span>, RINGS + <span class="n">1</span>):
248252
radius = R_OUTER * r / RINGS
249253
sat = min(<span class="n">1.0</span>, (r / RINGS) * <span class="n">1.4</span>)
250254
<span class="k">for</span> s <span class="k">in</span> range(SEGMENTS):
251-
angle = <span class="n">2.0</span> * math.pi * s / SEGMENTS
255+
angle = angle0 + <span class="n">2.0</span> * math.pi * s / SEGMENTS
252256
coords.append((radius * math.cos(angle), radius * math.sin(angle), <span class="n">0.0</span>))
253257
hsv.append((s / SEGMENTS, sat, <span class="n">1.0</span>))
254258
<span class="k">return</span> coords, hsv
@@ -360,7 +364,11 @@ <h2>Source</h2>
360364
<span class="k">if</span> <span class="s">&quot;Emission Color&quot;</span> <span class="k">in</span> bsdf.inputs: <span class="c"># Principled gained built-in emission in 4.x+</span>
361365
nt.links.new(attr_node.outputs[<span class="s">&quot;Color&quot;</span>], bsdf.inputs[<span class="s">&quot;Emission Color&quot;</span>])
362366
bsdf.inputs[<span class="s">&quot;Emission Strength&quot;</span>].default_value = <span class="n">0.12</span>
363-
bsdf.inputs[<span class="s">&quot;Roughness&quot;</span>].default_value = <span class="n">0.62</span>
367+
<span class="c"># fully matte: any specular component reflects the wall/floor horizon as</span>
368+
<span class="c"># a hard line across the disc face</span>
369+
bsdf.inputs[<span class="s">&quot;Roughness&quot;</span>].default_value = <span class="n">0.85</span>
370+
<span class="k">if</span> <span class="s">&quot;Specular IOR Level&quot;</span> <span class="k">in</span> bsdf.inputs:
371+
bsdf.inputs[<span class="s">&quot;Specular IOR Level&quot;</span>].default_value = <span class="n">0.0</span>
364372

365373
<span class="c"># The step AI code most often skips: the attribute must actually be wired</span>
366374
<span class="c"># into the shader, not just present on the mesh.</span>
@@ -385,8 +393,11 @@ <h2>Source</h2>
385393
<span class="k">if</span> mat <span class="k">is</span> <span class="k">None</span>:
386394
<span class="k">return</span> <span class="k">False</span>
387395
obj.data.materials.append(mat)
388-
obj.location = (<span class="n">0.0</span>, <span class="n">0.0</span>, <span class="n">0.55</span>)
389-
obj.rotation_euler = (math.radians(<span class="n">14</span>), <span class="n">0.0</span>, math.radians(<span class="n">12</span>))
396+
<span class="c"># stand the disc up toward the camera like an easel: the wheel is the</span>
397+
<span class="c"># subject, so it should present nearly face-on and fill the frame instead</span>
398+
<span class="c"># of lying foreshortened on the floor.</span>
399+
obj.location = (<span class="n">0.0</span>, <span class="n">0.0</span>, <span class="n">1.34</span>)
400+
obj.rotation_euler = (math.radians(<span class="n">52</span>), <span class="n">0.0</span>, math.radians(<span class="n">10</span>))
390401

391402
floor_me = bpy.data.meshes.new(<span class="s">&quot;Floor&quot;</span>)
392403
bm = bmesh.new()
@@ -424,9 +435,15 @@ <h2>Source</h2>
424435
<span class="c"># a bright soft key from above reads the hue ring clearly; a low cool fill</span>
425436
<span class="c"># keeps the shadow side legible; a faint warm rim separates the disc edge</span>
426437
<span class="c"># from the dark backdrop without washing out the attribute colors.</span>
427-
light(<span class="s">&quot;Key&quot;</span>, (-<span class="n">2.0</span>, -<span class="n">3.0</span>, <span class="n">5.5</span>), <span class="n">380.0</span>, <span class="n">11.0</span>, (<span class="n">1.0</span>, <span class="n">0.98</span>, <span class="n">0.96</span>), (<span class="n">58</span>, <span class="n">0</span>, -<span class="n">28</span>))
428-
light(<span class="s">&quot;Fill&quot;</span>, (<span class="n">4.5</span>, -<span class="n">2.5</span>, <span class="n">1.6</span>), <span class="n">140.0</span>, <span class="n">9.0</span>, (<span class="n">0.78</span>, <span class="n">0.86</span>, <span class="n">1.0</span>), (<span class="n">68</span>, <span class="n">0</span>, <span class="n">55</span>))
438+
light(<span class="s">&quot;Key&quot;</span>, (-<span class="n">2.0</span>, -<span class="n">3.0</span>, <span class="n">5.5</span>), <span class="n">320.0</span>, <span class="n">8.0</span>, (<span class="n">1.0</span>, <span class="n">0.98</span>, <span class="n">0.96</span>), (<span class="n">58</span>, <span class="n">0</span>, -<span class="n">28</span>))
439+
light(<span class="s">&quot;Fill&quot;</span>, (<span class="n">4.5</span>, -<span class="n">2.5</span>, <span class="n">1.6</span>), <span class="n">90.0</span>, <span class="n">9.0</span>, (<span class="n">0.78</span>, <span class="n">0.86</span>, <span class="n">1.0</span>), (<span class="n">68</span>, <span class="n">0</span>, <span class="n">55</span>))
429440
light(<span class="s">&quot;Rim&quot;</span>, (<span class="n">0.5</span>, <span class="n">3.6</span>, <span class="n">2.2</span>), <span class="n">170.0</span>, <span class="n">4.0</span>, (<span class="n">1.0</span>, <span class="n">0.78</span>, <span class="n">0.55</span>), (-<span class="n">70</span>, <span class="n">0</span>, <span class="n">175</span>))
441+
<span class="c"># a warm wedge raking the back wall — the falloff pool behind the subject</span>
442+
<span class="c"># the rest of the gallery stages against.</span>
443+
<span class="c"># placed between the disc and the back wall so it can only rake the wall:</span>
444+
<span class="c"># from any position in front, its grazing terminator draws a hard line</span>
445+
<span class="c"># across the flat disc face.</span>
446+
light(<span class="s">&quot;Wedge&quot;</span>, (<span class="n">2.0</span>, <span class="n">5.2</span>, <span class="n">3.6</span>), <span class="n">220.0</span>, <span class="n">6.0</span>, (<span class="n">1.0</span>, <span class="n">0.76</span>, <span class="n">0.5</span>), (-<span class="n">68</span>, <span class="n">0</span>, <span class="n">190</span>))
430447

431448
aim = bpy.data.objects.new(<span class="s">&quot;Aim&quot;</span>, <span class="k">None</span>)
432449
aim.location = obj.location
@@ -435,7 +452,7 @@ <h2>Source</h2>
435452
cam_data = bpy.data.cameras.new(<span class="s">&quot;Cam&quot;</span>)
436453
cam_data.lens = <span class="n">50.0</span>
437454
cam = bpy.data.objects.new(<span class="s">&quot;Cam&quot;</span>, cam_data)
438-
cam.location = (<span class="n">0.0</span>, -<span class="n">7.4</span>, <span class="n">3.6</span>)
455+
cam.location = (<span class="n">0.0</span>, -<span class="n">8.0</span>, <span class="n">2.4</span>)
439456
con = cam.constraints.new(<span class="s">&#x27;TRACK_TO&#x27;</span>)
440457
con.target = aim
441458
con.track_axis = <span class="s">&#x27;TRACK_NEGATIVE_Z&#x27;</span>

‎docs/gallery/grease-pencil-rosette/index.html‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44
<meta charset="utf-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1" />
66
<title>grease-pencil-rosette — Examples — Blender Developer Tools</title>
7-
<meta name="description" content="Grease Pencil v3&#x27;s attribute-based API — layer → frames.new().drawing → add_strokes → per-point position/radius/opacity/vertex_color — drawing five nested neon rose curves." />
7+
<meta name="description" content="Grease Pencil v3&#x27;s attribute-based API — layer → frames.new(1).drawing → add_strokes → per-point position/radius/opacity/vertex_color — drawing five nested neon rose curves." />
88
<link rel="canonical" href="https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/grease-pencil-rosette/" />
99
<link rel="icon" href="../../assets/favicon.svg" type="image/svg+xml" />
1010
<meta name="theme-color" content="#1a1b1e" />
1111
<meta property="og:type" content="website" />
1212
<meta property="og:title" content="grease-pencil-rosette — Examples — Blender Developer Tools" />
13-
<meta property="og:description" content="Grease Pencil v3&#x27;s attribute-based API — layer → frames.new().drawing → add_strokes → per-point position/radius/opacity/vertex_color — drawing five nested neon rose curves." />
13+
<meta property="og:description" content="Grease Pencil v3&#x27;s attribute-based API — layer → frames.new(1).drawing → add_strokes → per-point position/radius/opacity/vertex_color — drawing five nested neon rose curves." />
1414
<meta property="og:url" content="https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/grease-pencil-rosette/" />
1515
<meta property="og:image" content="https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/assets/grease-pencil-rosette-hero.webp" />
1616
<meta name="twitter:card" content="summary_large_image" />
1717
<meta name="twitter:title" content="grease-pencil-rosette — Examples — Blender Developer Tools" />
18-
<meta name="twitter:description" content="Grease Pencil v3&#x27;s attribute-based API — layer → frames.new().drawing → add_strokes → per-point position/radius/opacity/vertex_color — drawing five nested neon rose curves." />
18+
<meta name="twitter:description" content="Grease Pencil v3&#x27;s attribute-based API — layer → frames.new(1).drawing → add_strokes → per-point position/radius/opacity/vertex_color — drawing five nested neon rose curves." />
1919
<meta name="twitter:image" content="https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/assets/grease-pencil-rosette-hero.webp" />
2020
<style>
2121
/* fonts are deployed by the landing build (docs/fonts/) */
@@ -170,7 +170,7 @@
170170
</div>
171171
<header class="hero">
172172
<h1>grease-pencil-rosette</h1>
173-
<p>Grease Pencil v3&#x27;s attribute-based API — layer → frames.new().drawing → add_strokes → per-point position/radius/opacity/vertex_color — drawing five nested neon rose curves.</p>
173+
<p>Grease Pencil v3&#x27;s attribute-based API — layer → frames.new(1).drawing → add_strokes → per-point position/radius/opacity/vertex_color — drawing five nested neon rose curves.</p>
174174
</header>
175175
<main id="main">
176176
<button class="detail-hero" id="heroZoom" type="button" aria-label="Zoom grease-pencil-rosette render">

‎docs/gallery/index.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ <h2><a href="parent-inverse-orrery/">parent-inverse-orrery</a></h2>
384384
</a>
385385
<div class="card-body">
386386
<h2><a href="grease-pencil-rosette/">grease-pencil-rosette</a></h2>
387-
<p class="teaches">Grease Pencil v3&#x27;s attribute-based API — layer → frames.new().drawing → add_strokes → per-point position/radius/opacity/vertex_color — drawing five nested neon rose curves.</p>
387+
<p class="teaches">Grease Pencil v3&#x27;s attribute-based API — layer → frames.new(1).drawing → add_strokes → per-point position/radius/opacity/vertex_color — drawing five nested neon rose curves.</p>
388388
<p class="witnesses"><span class="tag">witnesses</span> The GPv3 address break: 4.5 keeps GPv3 at grease_pencils_v3 while grease_pencils is still legacy GPencil (frame.strokes, no .drawing); 5.x deletes legacy and GPv3 takes over the grease_pencils name. Point writes lazily materialize attribute layers, and every position round-trips through the raw POINT buffer.</p>
389389
<a class="card-link" href="grease-pencil-rosette/">View example <span aria-hidden="true">&rarr;</span></a>
390390
</div>

0 commit comments

Comments
 (0)