Skip to content

Commit 83b09cf

Browse files
TMHSDigitalclaude
andcommitted
feat(skills): gpu-drawing-and-overlays skill, no-bgl rule and gpu-offscreen-draw example
bgl is gone on 5.x (find_spec('bgl') is None on 5.0.1, 5.1.2 and 5.2.1, still present on 4.5.14), and the pack had nothing on GPU drawing, so agents kept writing overlay add-ons that fail at import. - Skill gpu-drawing-and-overlays covers: - draw_handler_add/remove symmetry, and keeping the handle - builtin shader names (identical on 4.5 and 5.2; the 2D_/3D_ names are rejected on 5.2) - gpu.state replacements for the bgl state calls - POLYLINE_* shaders for wide lines - blf text (blf.size dpi argument: TypeError on 4.5 and 5.2) - GPUOffScreen headless on 5.2 via gpu.init(), which is new in 5.2; 5.1 and earlier raise in background mode - Rule no-bgl flags import bgl and bgl. calls, with a replacement table. - examples/gpu-offscreen-draw, check-only, 5.2+ (skips elsewhere through catalog min_version), reads pixels back from a GPUOffScreen: - quad coverage 1024/1024 - half-alpha red over blue gives 0.498/0.502 with blend_set('ALPHA') - a lineWidth 6 polyline draws 7 px - bgl is absent Falsifiers, verified on 5.2.1: --skip-blend exits 5, --thin-line 6, --expect-bgl 7. 4.5.14 and 5.1.2 skip with 77. Counts move to 19 skills, 10 rules, 67 examples (11 check-only). Closes #465 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
1 parent ba23e71 commit 83b09cf

19 files changed

Lines changed: 656 additions & 32 deletions

File tree

‎.cursor-plugin/plugin.json‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
"skills/depsgraph-and-evaluated-data/SKILL.md",
3838
"skills/drivers-and-app-handlers/SKILL.md",
3939
"skills/bl-info-migration/SKILL.md",
40-
"skills/vse-python/SKILL.md"
40+
"skills/vse-python/SKILL.md",
41+
"skills/gpu-drawing-and-overlays/SKILL.md"
4142
],
4243
"rules": [
4344
"rules/prefer-data-over-ops-in-loops.mdc",
@@ -48,6 +49,7 @@
4849
"rules/use-foreach-set-for-bulk-data.mdc",
4950
"rules/validate-imported-mesh-scale.mdc",
5051
"rules/no-unapplied-modifiers-on-export.mdc",
51-
"rules/use-correct-axis-rna-per-exporter.mdc"
52+
"rules/use-correct-axis-rna-per-exporter.mdc",
53+
"rules/no-bgl.mdc"
5254
]
5355
}

‎AGENTS.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ a `.cursor-plugin/plugin.json` manifest so the ecosystem drift checker
2020
classifies it as a `cursor-plugin`. This is content the AI loads when the user
2121
asks Blender questions or works on Blender add-ons in Cursor or Claude Code.
2222

23-
The content base is 18 skills, 9 rules, 3 templates, 29 snippets, 66
23+
The content base is 19 skills, 10 rules, 3 templates, 29 snippets, 66
2424
examples, and 80 showcase pieces (counts are CI-enforced across README.md, the agent docs, ROADMAP.md,
2525
`site.json` and the site templates). The full inventory tables and per-item purposes live in
2626
`CLAUDE.md`. Example anatomy and authoring rules: copy `examples/bmesh-gear/`;
@@ -32,11 +32,11 @@ in `docs/VISUAL-STYLE.md`; the canonical run prompt is
3232

3333
```
3434
Blender-Developer-Tools/
35-
skills/<skill-name>/SKILL.md # 18 skill files
36-
rules/<rule-name>.mdc # 9 rule files
35+
skills/<skill-name>/SKILL.md # 19 skill files
36+
rules/<rule-name>.mdc # 10 rule files
3737
templates/<template-name>/ # 3 starter templates
3838
snippets/<snippet-name>.py # 29 standalone Python snippets
39-
examples/<name>/ # 66 runnable smoke-gated examples (+ gallery.json)
39+
examples/<name>/ # 67 runnable smoke-gated examples (+ gallery.json)
4040
examples/gallery_framing.py # shared Layer 1 framing measurement (render path only)
4141
showcase/<name>/ # budget-conformance props (sibling of examples/)
4242
showcase/gallery.json # this tree's gallery index; merged into docs/gallery/

‎CLAUDE.md‎

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ The **Blender Developer Tools** repository is at **v0.154.0**. It packages skill
1717
## Repository Architecture
1818

1919
```
20-
skills/<skill-name>/SKILL.md - AI workflow definitions, 18 total
21-
rules/<rule-name>.mdc - Anti-pattern rules, 9 total
20+
skills/<skill-name>/SKILL.md - AI workflow definitions, 19 total
21+
rules/<rule-name>.mdc - Anti-pattern rules, 10 total
2222
templates/<template-name>/ - Starter projects, 3 total
2323
snippets/<snippet-name>.py - Standalone code patterns, 29 total
24-
examples/<name>/ - Runnable smoke-gated examples, 66 total (+ gallery.json)
24+
examples/<name>/ - Runnable smoke-gated examples, 67 total (+ gallery.json)
2525
showcase/<name>/ - Budget-conformance props, 80 pieces, each with a gallery `category` (sibling of examples/; see showcase/README.md § Categories)
2626
scripts/build_gallery.py - Regenerates docs/gallery/ from examples/gallery.json + showcase/gallery.json
2727
scripts/site/ - Vendored landing-page build (Jinja2); tokens.css is the shared palette
@@ -30,7 +30,7 @@ docs/gallery/ - Committed generated gallery pages + hero render
3030
VERSION - Source of truth for the repo version
3131
```
3232

33-
## Skills (18)
33+
## Skills (19)
3434

3535
| Skill | Purpose |
3636
| --- | --- |
@@ -52,8 +52,9 @@ VERSION - Source of truth for the repo version
5252
| vse-python | VSE timeline from Python: `.strips` vs `.sequences`, `new_effect` kwargs, 5.2 COLOR `width`/`height` bake |
5353
| extension-runtime-and-packaging | Bundled wheels, `extension_path_user` data that survives upgrades, `online_access`, `bl_ext` names, `--command extension` build in CI |
5454
| timers-modal-and-threading | `bpy.app.timers` return values and `persistent`, modal operators on `event_timer_add`, worker thread + queue + main-thread drain, no timers in `--background` |
55+
| gpu-drawing-and-overlays | `gpu` instead of the removed `bgl`: `draw_handler_add`/`remove`, builtin shader names, `gpu.state` blending and depth, `POLYLINE_*` line width, `blf` text, `GPUOffScreen` with 5.2's `gpu.init()` headless |
5556

56-
## Rules (9)
57+
## Rules (10)
5758

5859
Every rule sets `alwaysApply: false`, so the Scope column below is the rule's
5960
actual load condition, not a description: a rule enters context only when a file
@@ -70,6 +71,7 @@ matching its `globs` does. Changing a glob changes when the rule fires.
7071
| validate-imported-mesh-scale | `*.py` | glTF/FBX import then mesh work with no `transform_apply` and no unit-scale check |
7172
| no-unapplied-modifiers-on-export | `*.py` | Export with live modifiers when the export does not request evaluated geometry |
7273
| use-correct-axis-rna-per-exporter | `*.py` | `export_scene.gltf` with FBX `axis_forward`/`axis_up`, or `export_scene.fbx` with glTF `export_yup` |
74+
| no-bgl | `*.py` | `import bgl` or any `bgl.` call (removed in 5.x; the add-on fails to register) |
7375

7476
## Templates (3)
7577

@@ -109,13 +111,13 @@ AI asset pipeline track: `decimate_to_budget.py`, `convex_hull_collider.py`, `lo
109111

110112
Extensions runtime: `extension-user-data.py` (`extension_path_user` settings file and an `online_access` guard). Long-running work: `thread-queue-timer.py` (worker thread, `queue.Queue`, main-thread drain timer).
111113

112-
## Examples (66)
114+
## Examples (67)
113115

114116
Runnable scripts at `examples/<name>/`, each asserting a real API contract with
115117
deterministic checks (exit non-zero on failure) and optionally rendering a still via
116118
`--output`. All of them run headless on Blender 5.2 LTS and 4.5 LTS in `blender-smoke.yml` (5.1 on the weekly cron, the `needs-5.1` PR label, or manual dispatch);
117-
**56 of the 66 ship a render in the site gallery** at `docs/gallery/`. The other
118-
ten are **check-only**: they carry no `--output` path, no gallery entry, and no
119+
**56 of the 67 ship a render in the site gallery** at `docs/gallery/`. The other
120+
eleven are **check-only**: they carry no `--output` path, no gallery entry, and no
119121
hero asset. The criterion is whether the contract is expressible in pixels. An
120122
example is check-only when its witness is a data or state fact that no scene
121123
redesign can make visible — a datablock name, an RNA attribute's presence, a

‎CONTRIBUTING.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ The drift-check workflow enforces these on every push and PR.
288288

289289
## Aggregate Counts
290290

291-
`README.md` declares aggregate counts (e.g. "18 skills, 9 rules, 3 templates, 29 snippets, 66 examples, and 80 showcase pieces"). The `validate-counts` job in `.github/workflows/validate.yml` enforces these substrings against the filesystem on every push and PR. Showcase pieces are counted separately from examples. When you add or remove content, update the README counts in the same commit.
291+
`README.md` declares aggregate counts (e.g. "19 skills, 10 rules, 3 templates, 29 snippets, 67 examples, and 80 showcase pieces"). The `validate-counts` job in `.github/workflows/validate.yml` enforces these substrings against the filesystem on every push and PR. Showcase pieces are counted separately from examples. When you add or remove content, update the README counts in the same commit.
292292

293293
## Pull Request Process
294294

‎README.md‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
</p>
2626

2727
<p align="center">
28-
<strong>18 skills</strong> &nbsp;&bull;&nbsp; <strong>9 rules</strong> &nbsp;&bull;&nbsp; <strong>3 templates</strong> &nbsp;&bull;&nbsp; <strong>29 snippets</strong> &nbsp;&bull;&nbsp; <strong>66 examples</strong> &nbsp;&bull;&nbsp; <strong>80 showcase pieces</strong>
28+
<strong>19 skills</strong> &nbsp;&bull;&nbsp; <strong>10 rules</strong> &nbsp;&bull;&nbsp; <strong>3 templates</strong> &nbsp;&bull;&nbsp; <strong>29 snippets</strong> &nbsp;&bull;&nbsp; <strong>67 examples</strong> &nbsp;&bull;&nbsp; <strong>80 showcase pieces</strong>
2929
</p>
3030

3131
<p align="center">
@@ -44,13 +44,13 @@
4444

4545
## Overview
4646

47-
This repository ships **18 skills, 9 rules, 3 templates, 29 snippets, 66 examples, and 80 showcase pieces** for Blender Python development targeting Blender 5.2 LTS (current stable) with Blender 4.5 LTS fallback support. Blender 5.1 is prior stable.
47+
This repository ships **19 skills, 10 rules, 3 templates, 29 snippets, 67 examples, and 80 showcase pieces** for Blender Python development targeting Blender 5.2 LTS (current stable) with Blender 4.5 LTS fallback support. Blender 5.1 is prior stable.
4848

4949
The content is consumed by AI coding agents, installed as a plugin or read from a checkout. An optional second plugin registers the official [Blender Lab MCP server](https://www.blender.org/lab/mcp-server/) for live sessions (see [Live Blender session](#live-blender-session-mcp)); the server is referenced from upstream, not part of this repository, and nothing else depends on it. Cursor and Claude Code both install it as a plugin (see [Quick start](#quick-start)): Cursor loads the skills and applies `rules/*.mdc` wherever their scope globs match; Claude Code loads the skills and gets the rules through a generated `blender-rules` skill, since it does not read Cursor `.mdc` files. An agent picks a skill up when its description matches the task. Any agent that can read files in a workspace can use it the same way. There is no build step for the content — edit the Markdown and Python files directly.
5050

5151
| Layer | Role |
5252
| --- | --- |
53-
| **Skills** | Guided workflows: scaffolding, operators, panels, properties, mesh and bmesh, headless batch, slotted actions, geometry nodes, procedural materials, depsgraph queries, drivers and handlers, `bl_info` migration, video sequencer, imported-mesh cleanup, high-to-low baking, engine export presets, extension runtime and packaging, timers, modal operators and threading |
53+
| **Skills** | Guided workflows: scaffolding, operators, panels, properties, mesh and bmesh, headless batch, slotted actions, geometry nodes, procedural materials, depsgraph queries, drivers and handlers, `bl_info` migration, video sequencer, imported-mesh cleanup, high-to-low baking, engine export presets, extension runtime and packaging, timers, modal operators and threading, GPU drawing and viewport overlays |
5454
| **Rules** | Guardrails for the most common AI mistakes: ops-in-loops, bmesh leaks, legacy `bl_info` only, prop assignments, deprecated context-copy override, per-element loops over bulk mesh data, import without scale check, export without evaluated geometry, mixed glTF/FBX axis RNA |
5555
| **Templates** | A working Extensions Platform add-on starter, a headless batch script starter, and a GLB-in engine-ready asset pipeline |
5656
| **Snippets** | 29 small standalone Python files demonstrating canonical patterns, 5 to 75 lines each |
@@ -61,14 +61,14 @@ The content is consumed by AI coding agents, installed as a plugin or read from
6161

6262
Neither agent needs a clone of `main`: both install the slim `plugin-dist` build. Clone the full repository only to [run the examples or contribute](#run-the-examples-or-contribute).
6363

64-
- **Cursor** — install it as a local plugin from the slim `plugin-dist` branch, then run **Developer: Reload Window**. **Customize** lists the 18 skills and 9 rules; the rules apply by glob scope and the agent loads a skill when its description matches the task.
64+
- **Cursor** — install it as a local plugin from the slim `plugin-dist` branch, then run **Developer: Reload Window**. **Customize** lists the 19 skills and 10 rules; the rules apply by glob scope and the agent loads a skill when its description matches the task.
6565

6666
```bash
6767
git clone --branch plugin-dist --single-branch https://github.com/TMHSDigital/Blender-Developer-Tools.git ~/.cursor/plugins/local/blender-developer-tools
6868
```
6969

7070
(On Windows the folder is `%USERPROFILE%\.cursor\plugins\local\`. Cursor skips symlinks that point outside that folder, so clone or copy rather than link.) Teams can import the repository as a team marketplace instead; it carries `.cursor-plugin/marketplace.json`. The plugin already applies the rules, so there is nothing to copy. Only to scope the pack to one project without the plugin, copy `skills/*` into that project's `.cursor/skills/` and `rules/*.mdc` into `.cursor/rules/` from a checkout; copying only the rules gives you no skills.
71-
- **Claude Code** — install as a plugin, then run `/skills` to see all 18 skills plus `blender-rules`:
71+
- **Claude Code** — install as a plugin, then run `/skills` to see all 19 skills plus `blender-rules`:
7272

7373
```text
7474
/plugin marketplace add TMHSDigital/Blender-Developer-Tools@plugin-dist
@@ -129,7 +129,7 @@ Releases ship often; [CHANGELOG.md](CHANGELOG.md) lists what each one changed.
129129

130130
## Falsifiers
131131

132-
Every one of the 66 examples carries a **falsifier**: a flag that changes the
132+
Every one of the 67 examples carries a **falsifier**: a flag that changes the
133133
input so a real assertion fails. It never disables the assertion, skips the
134134
check, or short-circuits to an error — it feeds the script something the
135135
contract says must not pass, and the same check that guards the happy path
@@ -157,7 +157,7 @@ per-script exit-code model, are in
157157

158158
## Examples and showcase
159159

160-
**66 examples** in [`examples/`](examples/) are runnable, self-checking scripts: each asserts one API contract, carries a falsifier, and runs headless on Blender 5.2 LTS and 4.5 LTS in the `blender-smoke` workflow (5.1 on the weekly cron or by manual dispatch). Those whose contract is visible also render a still. **80 showcase pieces** in [`showcase/`](showcase/) exist to show the skills working together at production scale: each is a single headless script that models a game prop, then runs it through the same cleanup, bake, LOD, collider and export steps the skills teach, and fails if a measured budget (triangle counts, colliders, materials, real-world size) is missed. They are not API examples. Conventions: [`showcase/README.md`](showcase/README.md).
160+
**67 examples** in [`examples/`](examples/) are runnable, self-checking scripts: each asserts one API contract, carries a falsifier, and runs headless on Blender 5.2 LTS and 4.5 LTS in the `blender-smoke` workflow (5.1 on the weekly cron or by manual dispatch). Those whose contract is visible also render a still. **80 showcase pieces** in [`showcase/`](showcase/) exist to show the skills working together at production scale: each is a single headless script that models a game prop, then runs it through the same cleanup, bake, LOD, collider and export steps the skills teach, and fails if a measured budget (triangle counts, colliders, materials, real-world size) is missed. They are not API examples. Conventions: [`showcase/README.md`](showcase/README.md).
161161

162162
Browse both, with filters, full-size renders and each script's README, in the **[gallery](https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/)**.
163163

@@ -175,11 +175,11 @@ Browse both, with filters, full-size renders and each script's README, in the **
175175
## How content is organized
176176

177177
```
178-
skills/<name>/SKILL.md - 18 skill files, YAML frontmatter, one canonical pattern each
179-
rules/<name>.mdc - 9 rule files, anti-pattern + correction
178+
skills/<name>/SKILL.md - 19 skill files, YAML frontmatter, one canonical pattern each
179+
rules/<name>.mdc - 10 rule files, anti-pattern + correction
180180
templates/<name>/ - 3 template directories (extension-addon-template, headless-batch-script-template, ai-asset-pipeline-template)
181181
snippets/<name>.py - 29 standalone Python snippets, 5 to 75 lines each
182-
examples/<name>/ - 66 example directories: script, README with exit codes and falsifier
182+
examples/<name>/ - 67 example directories: script, README with exit codes and falsifier
183183
showcase/<name>/ - 80 showcase pieces: budget-gated game props, script and README
184184
claude/ - generated Claude Code copies of the rules (blender-rules skill + import file)
185185
```

‎ROADMAP.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
The skill, rule and example work planned for what the plugin teaches, separate from the
1010
showcase pool further down. Each item is an open issue; nothing here is pinned to a version.
1111

12-
- **New skills:** `porting-to-blender-5`, one index of every 4.x to 5.x break the pack covers ([#466](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/466)); `gpu-drawing` plus a no-`bgl` rule, since `bgl` is gone in 5.x ([#465](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/465)); teach the API contracts that shipped examples prove but no skill covers yet, such as Grease Pencil v3, the 5.x compositor, constraints and image pixels ([#456](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/456))
12+
- **New skills:** `porting-to-blender-5`, one index of every 4.x to 5.x break the pack covers ([#466](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/466)); teach the API contracts that shipped examples prove but no skill covers yet, such as Grease Pencil v3, the 5.x compositor, constraints and image pixels ([#456](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/456))
1313
- **Skill corrections:** the full Principled BSDF v2 socket rename table in `procedural-materials-and-shaders` ([#382](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/382))
1414
- **New rules:** flag the mesh-normals APIs removed in 4.1 (`use_auto_smooth`, `calc_normals_split`, `free_normals_split`) ([#379](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/379))
1515
- **Examples for skills that have none:** check-only examples for `operators`, `ui-panels`, `addon-scaffolding` and `bl-info-migration` ([#378](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/378)); a skill-to-example index and one machine-readable examples manifest with version support ([#377](https://github.com/TMHSDigital/Blender-Developer-Tools/issues/377))
@@ -38,7 +38,8 @@ derives the actual version from conventional-commit types.
3838
| AI asset pipeline: high-to-low bake | 16 | 9 | 3 | 27 | Shipped |
3939
| Extension runtime and packaging | 17 | 9 | 3 | 28 | Shipped (v0.146.0) |
4040
| Timers, modal operators and threading | 18 | 9 | 3 | 29 | Shipped (v0.147.0) |
41-
| AI asset pipeline: live-session bridge (spike) | - | - | - | - | Upcoming |
41+
| GPU drawing without `bgl` | 19 | 10 | 3 | 29 | Shipped |
42+
| Live-session bridge (opt-in `blender-live-session` plugin, upstream Blender Lab MCP) | - | - | - | - | Shipped |
4243
| Stable (1.0) | — | — | — | — | Upcoming; criteria below |
4344

4445
## What "Stable (1.0)" means

‎claude/blender-rules.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ Flag bmesh.new() calls without a paired bm.free() in a try/finally block. Blende
1111

1212
Applies to: `**/*.py`. Full rule: [`rules/always-free-bmesh.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/always-free-bmesh.mdc).
1313

14+
## no-bgl
15+
16+
Flag `import bgl` and any `bgl.` call. The `bgl` OpenGL wrapper was deprecated in 3.x and is gone in Blender 5.x (`importlib.util.find_spec('bgl')` is `None` on 5.0, 5.1 and 5.2), so an add-on that imports it fails to register. Draw with the `gpu` module, `gpu.state` and `gpu_extras.batch` instead; see the gpu-drawing-and-overlays skill.
17+
18+
Applies to: `**/*.py`. Full rule: [`rules/no-bgl.mdc`](https://github.com/TMHSDigital/Blender-Developer-Tools/blob/main/rules/no-bgl.mdc).
19+
1420
## no-unapplied-modifiers-on-export
1521

1622
Flag an export call on objects that still carry unapplied modifiers when the export arguments do not request evaluated geometry. The engine then receives the authored cage, not the modifier result.

0 commit comments

Comments
 (0)