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
2 changes: 2 additions & 0 deletions .cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@
"templates/headless-batch-script-template"
],
"examples": [
"examples/bmesh-gear",
"examples/depsgraph-export",
"examples/driver-wave",
"examples/gn-sdf-remesh",
"examples/shader-node-group",
"examples/swatch-grid",
"examples/turntable",
"examples/wave-displace"
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/blender-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,22 @@ jobs:
# on failure.
xvfb-run -a "$BLENDER" --background \
--python examples/driver-wave/driver_wave.py --

- name: Shipped example - bmesh gear (ownership + watertight topology)
run: |
set -euo pipefail
# Frame-independent check only (no render): parametric gear via bmesh with
# bm.free() in try/finally; asserts closed-form vert/edge/face counts and
# that every edge borders exactly two faces. Exits non-zero on failure.
xvfb-run -a "$BLENDER" --background \
--python examples/bmesh-gear/bmesh_gear.py --

- name: Shipped example - shader node group (interface sockets + sharing)
run: |
set -euo pipefail
# Frame-independent check only (no render): TintedGloss group declared via
# tree.interface.new_socket, instanced by two materials; asserts the sockets
# exist, the group datablock is shared (users == 2), and the per-instance
# Tint values differ. Exits non-zero on failure.
xvfb-run -a "$BLENDER" --background \
--python examples/shader-node-group/shader_node_group.py --
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,34 @@ A `driver_namespace` function driving sixteen column heights through SCRIPTED dr
Witnesses the evaluation contract: driven values appear after a view-layer update on the
evaluated copy **and** the flushed-back original, and both must match the closed form.

</td>
</tr>
<tr>
<td width="46%" valign="middle">
<a href="examples/bmesh-gear/"><img src="examples/bmesh-gear/preview.webp" alt="Bmesh gear: a machined steel 14-tooth gear at a three-quarter angle on a dark studio floor" /></a>
</td>
<td valign="middle">

### [bmesh-gear](examples/bmesh-gear/)

A 14-tooth gear built entirely with bmesh — with `bm.free()` in a `try`/`finally`, as the
ownership contract demands. Asserts the closed-form vert/edge/face counts and that the
result is watertight (every edge borders exactly two faces).

</td>
</tr>
<tr>
<td width="46%" valign="middle">
<a href="examples/shader-node-group/"><img src="examples/shader-node-group/preview.webp" alt="Shader node group: a teal sphere and a magenta sphere sharing one TintedGloss node group with different Tint parameters" /></a>
</td>
<td valign="middle">

### [shader-node-group](examples/shader-node-group/)

One reusable `TintedGloss` group declared via `tree.interface.new_socket`, instanced in two
materials with different Tint values. Witnesses the grouping contract: shared datablock
(`users == 2`), parameters on the group **node** — two spheres, one group, two colors.

</td>
</tr>
</table>
Expand Down
Binary file added docs/gallery/assets/bmesh-gear-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 added docs/gallery/assets/shader-node-group-hero.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
438 changes: 438 additions & 0 deletions docs/gallery/bmesh-gear/index.html

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions docs/gallery/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,14 @@ <h1>Examples Gallery</h1>
<div class="chips" role="toolbar" aria-label="Filter examples by topic">
<button class="chip active" data-tag="" type="button">All</button>
<button class="chip" data-tag="animation" type="button">animation</button>
<button class="chip" data-tag="bmesh" type="button">bmesh</button>
<button class="chip" data-tag="depsgraph" type="button">depsgraph</button>
<button class="chip" data-tag="drivers" type="button">drivers</button>
<button class="chip" data-tag="export" type="button">export</button>
<button class="chip" data-tag="geometry-nodes" type="button">geometry-nodes</button>
<button class="chip" data-tag="materials" type="button">materials</button>
<button class="chip" data-tag="mesh" type="button">mesh</button>
<button class="chip" data-tag="node-groups" type="button">node-groups</button>
<button class="chip" data-tag="performance" type="button">performance</button>
<button class="chip" data-tag="rendering" type="button">rendering</button>
</div>
Expand Down Expand Up @@ -252,6 +254,28 @@ <h2><a href="driver-wave/">driver-wave</a></h2>
<a class="card-link" href="driver-wave/">View example <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
<article class="card" data-tags="mesh bmesh">
<a class="card-media" href="bmesh-gear/" aria-label="bmesh-gear example detail page">
<img src="assets/bmesh-gear-hero.webp" alt="bmesh-gear — A 14-tooth gear built entirely with bmesh — profile ring, face, extrude — with bm" loading="lazy" decoding="async" />
</a>
<div class="card-body">
<h2><a href="bmesh-gear/">bmesh-gear</a></h2>
<p class="teaches">A 14-tooth gear built entirely with bmesh — profile ring, face, extrude — with bm.free() in a try/finally, exactly as the ownership contract demands.</p>
<p class="witnesses"><span class="tag">witnesses</span> Parametric bmesh topology is exactly predictable: verts, edges, and faces match their closed forms, and every edge borders exactly two faces (watertight).</p>
<a class="card-link" href="bmesh-gear/">View example <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
<article class="card" data-tags="materials node-groups">
<a class="card-media" href="shader-node-group/" aria-label="shader-node-group example detail page">
<img src="assets/shader-node-group-hero.webp" alt="shader-node-group — One reusable shader group declared via tree" loading="lazy" decoding="async" />
</a>
<div class="card-body">
<h2><a href="shader-node-group/">shader-node-group</a></h2>
<p class="teaches">One reusable shader group declared via tree.interface.new_socket, instanced in two materials with different Tint values — two spheres, one group, two colors.</p>
<p class="witnesses"><span class="tag">witnesses</span> Grouping contract: interface sockets appear on every instance, both materials share one group datablock (users == 2), and per-material parameters live on the group node, not inside the tree.</p>
<a class="card-link" href="shader-node-group/">View example <span aria-hidden="true">&rarr;</span></a>
</div>
</article>
</div>
</main>
<footer>
Expand Down
Loading
Loading