|
16 | 16 | <meta property="og:image" content="https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/assets/gn-zone-iterate-hero.webp" /> |
17 | 17 | <meta property="og:image:width" content="1280" /> |
18 | 18 | <meta property="og:image:height" content="720" /> |
19 | | - <meta property="og:image:alt" content="Four ochre cubes in a row from a Repeat zone beside a vertical stack of six cyan cubes from a For Each zone." /> |
| 19 | + <meta property="og:image:alt" content="Four brass cubes evenly spaced in a row from a Repeat zone beside a vertical stack of six cyan cubes from a For Each zone." /> |
20 | 20 | <meta property="og:site_name" content="Blender Developer Tools" /> |
21 | 21 | <meta name="twitter:card" content="summary_large_image" /> |
22 | 22 | <meta name="twitter:title" content="gn-zone-iterate — Examples — Blender Developer Tools" /> |
23 | 23 | <meta name="twitter:description" content="Repeat Zone and For Each Element only iterate after pair_with_output. Evaluated cube counts follow 8 times (1+N) and 8 times P, not tree structure." /> |
24 | 24 | <meta name="twitter:image" content="https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/assets/gn-zone-iterate-hero.webp" /> |
25 | | - <meta name="twitter:image:alt" content="Four ochre cubes in a row from a Repeat zone beside a vertical stack of six cyan cubes from a For Each zone." /> |
| 25 | + <meta name="twitter:image:alt" content="Four brass cubes evenly spaced in a row from a Repeat zone beside a vertical stack of six cyan cubes from a For Each zone." /> |
26 | 26 | <style> |
27 | 27 | /* fonts are deployed by the landing build (docs/fonts/) */ |
28 | 28 | @font-face { font-family: 'Barlow Condensed'; font-weight: 600; font-display: swap; |
@@ -268,8 +268,8 @@ <h1>gn-zone-iterate</h1> |
268 | 268 | <p>Repeat Zone and For Each Element only iterate after pair_with_output. Evaluated cube counts follow 8 times (1+N) and 8 times P, not tree structure.</p> |
269 | 269 | </header> |
270 | 270 | <main id="main"> |
271 | | - <button class="detail-hero" id="heroZoom" type="button" aria-label="View full size: Four ochre cubes in a row from a Repeat zone beside a vertical stack of six cyan cubes from a For Each zone."> |
272 | | - <img src="../assets/gn-zone-iterate-hero.webp" alt="Four ochre cubes in a row from a Repeat zone beside a vertical stack of six cyan cubes from a For Each zone." width="1280" height="720" /> |
| 271 | + <button class="detail-hero" id="heroZoom" type="button" aria-label="View full size: Four brass cubes evenly spaced in a row from a Repeat zone beside a vertical stack of six cyan cubes from a For Each zone."> |
| 272 | + <img src="../assets/gn-zone-iterate-hero.webp" alt="Four brass cubes evenly spaced in a row from a Repeat zone beside a vertical stack of six cyan cubes from a For Each zone." width="1280" height="720" /> |
273 | 273 | </button> |
274 | 274 | <p class="zoom-hint">Rendered headless by the example itself — click to zoom.</p> |
275 | 275 | <div class="callout"><span class="tag">witnesses</span> Repeat 32/24 verts/faces with X-centers at k*1.2; For Each 48/36 with Z-centers at i*0.6+0.21. Unpaired evaluates empty; For Each main Geometry passthrough is 6 verts.</div> |
@@ -601,6 +601,19 @@ <h2>Source</h2> |
601 | 601 | <span class="k">return</span> <span class="s">"BLENDER_EEVEE"</span> <span class="k">if</span> bpy.app.version >= (<span class="n">5</span>, <span class="n">0</span>, <span class="n">0</span>) <span class="k">else</span> <span class="s">"BLENDER_EEVEE_NEXT"</span> |
602 | 602 |
|
603 | 603 |
|
| 604 | +<span class="k">def</span> _node_materials(ob): |
| 605 | + <span class="s">"""Materials the object's Geometry Nodes tree assigns (Set Material nodes)."""</span> |
| 606 | + out = [] |
| 607 | + <span class="k">for</span> md <span class="k">in</span> ob.modifiers: |
| 608 | + <span class="k">if</span> md.type == <span class="s">"NODES"</span> <span class="k">and</span> md.node_group <span class="k">is</span> <span class="k">not</span> <span class="k">None</span>: |
| 609 | + <span class="k">for</span> node <span class="k">in</span> md.node_group.nodes: |
| 610 | + <span class="k">if</span> node.bl_idname == <span class="s">"GeometryNodeSetMaterial"</span>: |
| 611 | + mat = node.inputs[<span class="s">"Material"</span>].default_value |
| 612 | + <span class="k">if</span> mat <span class="k">is</span> <span class="k">not</span> <span class="k">None</span> <span class="k">and</span> mat <span class="k">not</span> <span class="k">in</span> out: |
| 613 | + out.append(mat) |
| 614 | + <span class="k">return</span> out |
| 615 | + |
| 616 | + |
604 | 617 | <span class="k">def</span> render_still(rpt, fee, path, engine): |
605 | 618 | scene = bpy.context.scene |
606 | 619 |
|
@@ -640,16 +653,32 @@ <h2>Source</h2> |
640 | 653 | light(<span class="s">"Key"</span>, (-<span class="n">4.0</span>, -<span class="n">5.0</span>, <span class="n">6.0</span>), <span class="n">520.0</span>, <span class="n">5.0</span>, (<span class="n">1.0</span>, <span class="n">0.96</span>, <span class="n">0.9</span>), (<span class="n">46</span>, <span class="n">0</span>, -<span class="n">35</span>)) |
641 | 654 | light(<span class="s">"Fill"</span>, (<span class="n">5.0</span>, -<span class="n">3.5</span>, <span class="n">3.0</span>), <span class="n">160.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>)) |
642 | 655 | light(<span class="s">"Wedge"</span>, (<span class="n">2.5</span>, <span class="n">5.5</span>, <span class="n">4.0</span>), <span class="n">360.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>)) |
643 | | - light(<span class="s">"Glint"</span>, (<span class="n">0.4</span>, -<span class="n">5.2</span>, <span class="n">5.5</span>), <span class="n">700.0</span>, <span class="n">0.9</span>, (<span class="n">1.0</span>, <span class="n">0.92</span>, <span class="n">0.75</span>), (<span class="n">42</span>, <span class="n">0</span>, <span class="n">8</span>)) |
644 | | - |
| 656 | + <span class="c"># Broad, not a 0.9 m spot: the small Glint blew the top tower cube out</span> |
| 657 | + <span class="c"># to near-white cyan, the brightest thing in frame by a wide margin.</span> |
| 658 | + light(<span class="s">"Glint"</span>, (<span class="n">0.4</span>, -<span class="n">5.2</span>, <span class="n">5.5</span>), <span class="n">300.0</span>, <span class="n">3.0</span>, (<span class="n">1.0</span>, <span class="n">0.92</span>, <span class="n">0.75</span>), (<span class="n">42</span>, <span class="n">0</span>, <span class="n">8</span>)) |
| 659 | + <span class="c"># Rim from behind so the cube silhouettes separate from the dark wall.</span> |
| 660 | + light(<span class="s">"Rim"</span>, (-<span class="n">1.0</span>, <span class="n">4.5</span>, <span class="n">4.5</span>), <span class="n">260.0</span>, <span class="n">4.0</span>, (<span class="n">0.70</span>, <span class="n">0.82</span>, <span class="n">1.0</span>), (-<span class="n">50</span>, <span class="n">0</span>, <span class="n">180</span>)) |
| 661 | + |
| 662 | + <span class="c"># Presentation only: the check never reads materials. 0.85 metallic in a</span> |
| 663 | + <span class="c"># near-black world reflected near-black, and the brass read as mustard</span> |
| 664 | + <span class="c"># card. Less metal and a warmer, brighter base let the key shape it.</span> |
| 665 | + <span class="k">for</span> ob, rough, metal <span class="k">in</span> ((rpt, <span class="n">0.42</span>, <span class="n">0.55</span>), (fee, <span class="n">0.38</span>, <span class="n">0.10</span>)): |
| 666 | + <span class="k">for</span> mat <span class="k">in</span> _node_materials(ob): |
| 667 | + bsdf = mat.node_tree.nodes.get(<span class="s">"Principled BSDF"</span>) |
| 668 | + <span class="k">if</span> bsdf <span class="k">is</span> <span class="k">not</span> <span class="k">None</span>: |
| 669 | + bsdf.inputs[<span class="s">"Metallic"</span>].default_value = metal |
| 670 | + bsdf.inputs[<span class="s">"Roughness"</span>].default_value = rough |
| 671 | + |
| 672 | + <span class="c"># Centred on the pair and more frontal: from (6.6, -9.3) the repeat row</span> |
| 673 | + <span class="c"># foreshortened into a diagonal and the tower hugged the right edge.</span> |
645 | 674 | aim = bpy.data.objects.new(<span class="s">"Aim"</span>, <span class="k">None</span>) |
646 | | - aim.location = (<span class="n">0.0</span>, <span class="n">0.0</span>, <span class="n">1.50</span>) |
| 675 | + aim.location = (-<span class="n">0.10</span>, <span class="n">0.0</span>, <span class="n">1.62</span>) |
647 | 676 | aim.hide_render = <span class="k">True</span> |
648 | 677 | scene.collection.objects.link(aim) |
649 | 678 | cam_data = bpy.data.cameras.new(<span class="s">"Cam"</span>) |
650 | 679 | cam_data.lens = <span class="n">50.0</span> |
651 | 680 | cam = bpy.data.objects.new(<span class="s">"Cam"</span>, cam_data) |
652 | | - cam.location = (<span class="n">6.6</span>, -<span class="n">9.3</span>, <span class="n">3.55</span>) |
| 681 | + cam.location = (<span class="n">2.7</span>, -<span class="n">10.6</span>, <span class="n">3.1</span>) |
653 | 682 | scene.collection.objects.link(cam) |
654 | 683 | scene.camera = cam |
655 | 684 | track = cam.constraints.new(<span class="s">"TRACK_TO"</span>) |
@@ -731,7 +760,7 @@ <h2>Source</h2> |
731 | 760 | </main> |
732 | 761 | <dialog class="lightbox" id="lightbox" aria-label="Full-size render"> |
733 | 762 | <button class="lightbox-close" type="button" autofocus>Close</button> |
734 | | - <img src="../assets/gn-zone-iterate-hero.webp" alt="Four ochre cubes in a row from a Repeat zone beside a vertical stack of six cyan cubes from a For Each zone." /> |
| 763 | + <img src="../assets/gn-zone-iterate-hero.webp" alt="Four brass cubes evenly spaced in a row from a Repeat zone beside a vertical stack of six cyan cubes from a For Each zone." /> |
735 | 764 | </dialog> |
736 | 765 | <footer> |
737 | 766 | <div class="statusbar"> |
|
0 commit comments