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
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -568,15 +568,16 @@ and that a `Set Material` node carries the material through the remesh.
</tr>
<tr>
<td width="46%" valign="middle">
<a href="examples/gn-instance-grid/"><img src="examples/gn-instance-grid/preview.webp" alt="GN instance grid: nine lime-green cubes in a 3x3 grid on a dark studio floor, instanced via Geometry Nodes Instance on Points" /></a>
<a href="examples/gn-instance-grid/"><img src="examples/gn-instance-grid/preview.webp" alt="GN instance grid: a cobalt-blue 3x3 macropad whose nine cream keycaps are instanced onto a Geometry Nodes Mesh Grid, one orange accent key picked out by a position-field Set Material" /></a>
</td>
<td valign="middle">

### [gn-instance-grid](examples/gn-instance-grid/)

A generative Geometry Nodes tree — Mesh Grid → Instance on Points → Realize Instances —
attached as a `NODES` modifier with no Group Input. Asserts evaluated topology is
verts = 72, faces = 54, and `Set Material` carries the lime accent.
A generative Geometry Nodes tree — Mesh Grid → Instance on Points (a modeled keycap via
`Object Info`) → Realize Instances — attached as a `NODES` modifier with no Group Input.
Asserts evaluated topology is verts = faces = 1089 (9 keycaps × 121), and a position-field
`Set Material` lands the orange accent on exactly one keycap.

</td>
</tr>
Expand Down
Binary file added docs/gallery/asset-sheets/gn-instance-grid.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/gn-instance-grid-hero.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.
597 changes: 480 additions & 117 deletions docs/gallery/gn-instance-grid/index.html

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/gallery/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -442,12 +442,12 @@ <h2><a href="temp-override-join/">temp-override-join</a></h2>
</article>
<article class="card" data-tags="geometry-nodes instancing">
<a class="card-media" href="gn-instance-grid/" tabindex="-1" aria-hidden="true">
<img src="assets/gn-instance-grid-hero.webp" alt="A three-by-three grid of green instanced cubes, each sitting on a node of a faint source-grid lattice on a dark floor." loading="lazy" decoding="async" />
<img src="assets/gn-instance-grid-hero.webp" alt="A cobalt-blue macropad with a brass knob and a glowing OLED meter, its three-by-three key field of cream keycaps instanced by Geometry Nodes, with one orange accent key at the front right." loading="lazy" decoding="async" />
</a>
<div class="card-body">
<h2><a href="gn-instance-grid/">gn-instance-grid</a></h2>
<p class="teaches">A generative Geometry Nodes tree — Mesh Grid → Instance on Points → Realize Instances → Set Shade Smooth — attached as a NODES modifier with no Group Input geometry.</p>
<p class="witnesses"><span class="tag">witnesses</span> Realized instances produce closed-form topology (72 verts, 54 faces), Set Material carries Lime, and the corner instance center sits at its closed-form grid coordinate.</p>
<p class="teaches">A generative Geometry Nodes tree — Mesh Grid → Instance on Points (a modeled keycap via Object Info) → Realize Instances → Set Shade Smooth → Set Material — attached as a NODES modifier with no Group Input geometry.</p>
<p class="witnesses"><span class="tag">witnesses</span> Realized instances produce closed-form topology (9 keycaps × 121 = 1089 verts, 1089 faces), Set Material carries the keycap plastic, a position-field Set Material lands the accent on exactly one keycap, and the corner keycap sits at its closed-form grid coordinate.</p>
<a class="card-link" href="gn-instance-grid/">View example<span class="sr-only"> gn-instance-grid</span> <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
Expand Down
6 changes: 3 additions & 3 deletions examples/gallery.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,9 @@
{
"name": "gn-instance-grid",
"dir": "examples/gn-instance-grid",
"teaches": "A generative Geometry Nodes tree — Mesh Grid → Instance on Points → Realize Instances → Set Shade Smooth — attached as a NODES modifier with no Group Input geometry.",
"alt": "A three-by-three grid of green instanced cubes, each sitting on a node of a faint source-grid lattice on a dark floor.",
"witnessesFix": "Realized instances produce closed-form topology (72 verts, 54 faces), Set Material carries Lime, and the corner instance center sits at its closed-form grid coordinate.",
"teaches": "A generative Geometry Nodes tree — Mesh Grid → Instance on Points (a modeled keycap via Object Info) → Realize Instances → Set Shade Smooth → Set Material — attached as a NODES modifier with no Group Input geometry.",
"alt": "A cobalt-blue macropad with a brass knob and a glowing OLED meter, its three-by-three key field of cream keycaps instanced by Geometry Nodes, with one orange accent key at the front right.",
"witnessesFix": "Realized instances produce closed-form topology (9 keycaps × 121 = 1089 verts, 1089 faces), Set Material carries the keycap plastic, a position-field Set Material lands the accent on exactly one keycap, and the corner keycap sits at its closed-form grid coordinate.",
"hero": "docs/gallery/assets/gn-instance-grid-hero.webp",
"preview": "examples/gn-instance-grid/preview.webp",
"tags": [
Expand Down
46 changes: 33 additions & 13 deletions examples/gn-instance-grid/README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,42 @@
# GN Instance Grid

A runnable example that builds a generative Geometry Nodes tree — Mesh Grid →
Instance on Points → Realize Instances → Transform → Set Shade Smooth — and
attaches it as a `NODES` modifier, following the
Instance on Points → Realize Instances → Transform → Set Shade Smooth → Set
Material — and attaches it as a `NODES` modifier, following the
[`geometry-nodes-python`](../../skills/geometry-nodes-python/SKILL.md) skill. The
tree has no Group Input: the grid and cube primitives live inside the node group.
tree has no Group Input: the grid lives inside the node group, and the instance
is a modeled DSA-profile keycap read in through an `Object Info` node (original
transform space). The realized grid is the key field of a 3x3 macropad.

**What it witnesses:** instancing is not free geometry until you realize it. The
check asserts the closed-form evaluated topology — verts = grid points × cube
verts (3 × 3 × 8 = 72), faces = 9 × 6 — that a `Set Material` node carries the
lime accent, and that the corner instance center sits at its closed-form grid
coordinate. If Realize Instances is omitted, the evaluated mesh is empty and the
counts fail.
check asserts the closed-form evaluated topology — verts = grid points × keycap
verts (9 × 121 = 1089), faces = 9 × 121 = 1089 — where the keycap counts come
from its construction parameters (six rounded-rectangle rings of
4 × (4 + 1) = 20 verts, plus the dish centre; five ring-to-ring quad bands, a
20-triangle dish fan and one bottom n-gon), not from measuring the mesh. It
also asserts that the (+x, +y) corner cell holds exactly one keycap, centred on
its closed-form grid point with its foot at the Transform lift, that `Set
Material` carries `Keycap.PBT`, and that a second `Set Material`, selected by a
per-face position field, puts `Keycap.Accent` on exactly one keycap at the
front-right grid point. If Realize Instances is bypassed, the evaluated mesh is
empty and the count gate fails.

**What the render shows:** nine identical keycaps, one per grid point, seated on
switch housings in the recessed well of an anodized case, and the one orange
"enter" key the position-field selection picked out. The count gate is numeric:
an unrealized grid renders the same keycaps, because the renderer draws
instances either way. What does show is the grid itself — `--one-cell` renders
a single keycap in the centre of an empty well — and where the accent
selection landed. The knob, OLED, case and switch housings are render-only
staging built in bmesh; only the key field comes from the tree.

## Run

```bash
# Cheap correctness check (no render) — the CI check:
blender --background --python gn_instance_grid.py --

# Falsifier: 1×1 grid. Must exit non-zero (corner instance missing).
# Falsifier: 1×1 grid. Must exit non-zero (4: eight keycaps missing).
blender --background --python gn_instance_grid.py -- --one-cell

# Also render a still (EEVEE on a GPU host; use --engine cycles on GPU-less hosts):
Expand All @@ -38,11 +55,14 @@ against it.
| 1 | Uncaught exception (FATAL wrapper) |
| 2 | argparse / usage |
| 3 | Carrier vertex count ≠ 1 |
| 4 | Corner instance vert count ≠ 8 (`--one-cell` lands here) |
| 5 | Evaluated topology ≠ 72 verts / 54 faces |
| 6 | Set Material did not carry Lime |
| 7 | Corner instance center off the closed-form grid point |
| 4 | Evaluated topology ≠ 1089 verts / 1089 faces (`--one-cell` lands here) |
| 5 | Corner grid cell does not hold exactly one keycap (121 verts) |
| 6 | Set Material did not carry `Keycap.PBT` and `Keycap.Accent` |
| 7 | Corner keycap off its closed-form grid point or lift |
| 8 | `--output` produced no file |
| 9 | Accent selection did not cover exactly one keycap at the front-right point |
| 10 | Render path: Layer 1 framing violation (`gallery_framing`) |
| 11 | Render path: asset-quality floor violation (`gallery_asset_quality`) |

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