Skip to content

Commit ffa9d30

Browse files
feat: add damped-track-aim smoke-gated example
Teach Object.constraints.new('DAMPED_TRACK') with evaluated aim checks so headless scripts stop reaching for constraint ops and TRACK_TO. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 5ca7a7c commit ffa9d30

12 files changed

Lines changed: 1020 additions & 36 deletions

File tree

.cursor-plugin/plugin.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"examples/bmesh-gear",
6363
"examples/compositor-glare",
6464
"examples/curve-bevel-arc",
65+
"examples/damped-track-aim",
6566
"examples/depsgraph-export",
6667
"examples/driver-wave",
6768
"examples/gn-instance-grid",

.github/workflows/blender-smoke.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,13 @@ jobs:
243243
# pixels with it off. Exits non-zero on failure.
244244
xvfb-run -a "$BLENDER" --background \
245245
--python examples/compositor-glare/compositor_glare.py --
246+
247+
- name: Shipped example - damped-track aim (DAMPED_TRACK data API)
248+
run: |
249+
set -euo pipefail
250+
# Frame-independent check only (no render): twelve needles aim at an
251+
# emissive core via Object.constraints.new('DAMPED_TRACK') on TRACK_Z;
252+
# asserts one unmuted constraint per needle and evaluated local +Z
253+
# aligns toward the core (dot ≥ 0.998). Exits non-zero on failure.
254+
xvfb-run -a "$BLENDER" --background \
255+
--python examples/damped-track-aim/damped_track_aim.py --

AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ The content base (counts are CI-enforced against README.md and the manifest):
2727
- 2 templates: `extension-addon-template` for Extensions Platform add-ons,
2828
and `headless-batch-script-template` for unattended batch jobs.
2929
- 17 snippets covering canonical patterns.
30-
- 13 examples under `examples/<name>/`: runnable scripts that assert a real
30+
- 14 examples under `examples/<name>/`: runnable scripts that assert a real
3131
API contract with deterministic checks, exit non-zero on failure, and
3232
optionally render a still via `--output`. Each is executed headless on
3333
Blender 4.5 LTS and 5.1 by `blender-smoke.yml`; its render ships in the
@@ -41,7 +41,7 @@ Blender-Developer-Tools/
4141
rules/<rule-name>.mdc # 6 rule files
4242
templates/<template-name>/ # 2 starter templates
4343
snippets/<snippet-name>.py # 17 standalone Python snippets
44-
examples/<name>/ # 13 runnable smoke-gated examples (+ gallery.json)
44+
examples/<name>/ # 14 runnable smoke-gated examples (+ gallery.json)
4545
scripts/build_gallery.py # generates docs/gallery/ (stdlib only)
4646
scripts/site/ # vendored landing-page build (build_site.py + template)
4747
docs/gallery/ # committed generated gallery pages + hero assets

CLAUDE.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ skills/<skill-name>/SKILL.md - AI workflow definitions, 12 total
1919
rules/<rule-name>.mdc - Anti-pattern rules, 6 total
2020
templates/<template-name>/ - Starter projects, 2 total
2121
snippets/<snippet-name>.py - Standalone code patterns, 17 total
22-
examples/<name>/ - Runnable smoke-gated examples, 13 total (+ gallery.json)
22+
examples/<name>/ - Runnable smoke-gated examples, 14 total (+ gallery.json)
2323
scripts/build_gallery.py - Regenerates docs/gallery/ from gallery.json (stdlib only)
2424
scripts/site/ - Vendored landing-page build (Jinja2)
2525
docs/gallery/ - Committed generated gallery pages + hero renders
@@ -80,11 +80,11 @@ v0.1.0: canonical object creation and deletion, depsgraph evaluated mesh, bmesh
8080

8181
v0.2.0: Principled BSDF material, driver-with-custom-function via `driver_namespace`, application handler registration, shader node group with cross-version `interface` API, `foreach_get` bulk vertex read, version-branch skeleton, and USD export with `evaluation_mode='RENDER'`.
8282

83-
## Examples (13)
83+
## Examples (14)
8484

8585
Runnable scripts at `examples/<name>/`, each asserting a real API contract with
8686
deterministic checks (exit non-zero on failure) and optionally rendering a still via
87-
`--output`. All thirteen run headless on Blender 4.5 LTS and 5.1 in `blender-smoke.yml`;
87+
`--output`. All fourteen run headless on Blender 4.5 LTS and 5.1 in `blender-smoke.yml`;
8888
their renders ship in the site gallery at `docs/gallery/`. `examples/gallery.json` is the
8989
gallery's source of truth. When authoring a new one, copy the anatomy of
9090
`examples/bmesh-gear/` (script structure, README shape, dark-studio render recipe) and

README.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717
</p>
1818

1919
<p align="center">
20-
<strong>12 skills</strong> &nbsp;&bull;&nbsp; <strong>6 rules</strong> &nbsp;&bull;&nbsp; <strong>2 templates</strong> &nbsp;&bull;&nbsp; <strong>17 snippets</strong> &nbsp;&bull;&nbsp; <strong>13 examples</strong>
20+
<strong>12 skills</strong> &nbsp;&bull;&nbsp; <strong>6 rules</strong> &nbsp;&bull;&nbsp; <strong>2 templates</strong> &nbsp;&bull;&nbsp; <strong>17 snippets</strong> &nbsp;&bull;&nbsp; <strong>14 examples</strong>
2121
</p>
2222

2323
---
2424

2525
## Overview
2626

27-
This repository ships **12 skills, 6 rules, 2 templates, 17 snippets, and 13 runnable examples** for Blender Python development targeting Blender 5.1 (current stable) with Blender 4.5 LTS fallback support.
27+
This repository ships **12 skills, 6 rules, 2 templates, 17 snippets, and 14 runnable examples** for Blender Python development targeting Blender 5.1 (current stable) with Blender 4.5 LTS fallback support.
2828

2929
The content is consumed by AI coding agents (Cursor, Claude Code, any MCP-capable client) when working on Blender add-ons, geometry nodes scripts, batch pipelines, or animation tooling. There is no build step. Edit the markdown and Python files directly.
3030

@@ -233,6 +233,21 @@ node fed by `Render Layers`, wired via `scene.compositing_node_group` on 5.x and
233233
`scene.node_tree` on 4.x. Witnesses with pixels that the halo falls off strictly with
234234
the compositor on and is exactly zero with it off — and that EEVEE has no `use_bloom`.
235235

236+
</td>
237+
</tr>
238+
<tr>
239+
<td width="46%" valign="middle">
240+
<a href="examples/damped-track-aim/"><img src="examples/damped-track-aim/preview.webp" alt="Damped Track aim: twelve metallic needles in a ring around a cyan emissive core, each tip constrained to point at the core on a dark studio floor" /></a>
241+
</td>
242+
<td valign="middle">
243+
244+
### [damped-track-aim](examples/damped-track-aim/)
245+
246+
Aim constraints via the data API — `Object.constraints.new('DAMPED_TRACK')` with
247+
`target` and `TRACK_Z`, not `bpy.ops.object.constraint_add` in a headless loop.
248+
Asserts twelve unmuted Damped Track constraints and evaluated local `+Z` alignment
249+
toward the core (dot ≥ 0.998).
250+
236251
</td>
237252
</tr>
238253
</table>
13.7 KB
Loading

0 commit comments

Comments
 (0)