Skip to content

Commit 31a09b5

Browse files
feat: witness Unity vs Godot glTF axis conversion on reimport
The same beacon under export_yup True vs False produces different disk POSITION and different reimported orientation. Inventory, gallery, catalog, and the engine-export-presets roadmap row ship with the example. Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 4cdaa69 commit 31a09b5

14 files changed

Lines changed: 1481 additions & 32 deletions

File tree

.cursor-plugin/plugin.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"skills": [
1717
"skills/addon-scaffolding/SKILL.md",
1818
"skills/ai-mesh-cleanup/SKILL.md",
19+
"skills/engine-export-presets/SKILL.md",
1920
"skills/operators/SKILL.md",
2021
"skills/ui-panels/SKILL.md",
2122
"skills/custom-properties/SKILL.md",
@@ -37,7 +38,8 @@
3738
"rules/prefer-temp-override-over-context-copy.mdc",
3839
"rules/use-foreach-set-for-bulk-data.mdc",
3940
"rules/validate-imported-mesh-scale.mdc",
40-
"rules/no-unapplied-modifiers-on-export.mdc"
41+
"rules/no-unapplied-modifiers-on-export.mdc",
42+
"rules/use-correct-axis-rna-per-exporter.mdc"
4143
],
4244
"snippets": [
4345
"snippets/action-ensure-channelbag-for-slot.py",
@@ -50,6 +52,9 @@
5052
"snippets/decimate_to_budget.py",
5153
"snippets/depsgraph-evaluated-mesh.py",
5254
"snippets/driver-with-custom-function.py",
55+
"snippets/export_preset_godot.py",
56+
"snippets/export_preset_unity.py",
57+
"snippets/export_preset_unreal.py",
5358
"snippets/foreach-get-vertices.py",
5459
"snippets/foreach-set-vertices.py",
5560
"snippets/gltf_draco_export.py",
@@ -83,6 +88,7 @@
8388
"examples/depsgraph-export",
8489
"examples/driver-wave",
8590
"examples/exit-pre-sidecar",
91+
"examples/export-preset-axis",
8692
"examples/gltf-export-roundtrip",
8793
"examples/gltf-skin-roundtrip",
8894
"examples/gn-bundle-roundtrip",

AGENTS.md

Lines changed: 5 additions & 5 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 14 skills, 8 rules, 2 templates, 21 snippets, and 53
23+
The content base is 15 skills, 9 rules, 2 templates, 24 snippets, and 54
2424
examples (counts are CI-enforced against README.md and the manifest). The full
2525
inventory tables and per-item purposes live in `CLAUDE.md`. Example anatomy
2626
and authoring rules: copy `examples/bmesh-gear/`; the render look is specified
@@ -31,11 +31,11 @@ in `docs/VISUAL-STYLE.md`; the canonical run prompt is
3131

3232
```
3333
Blender-Developer-Tools/
34-
skills/<skill-name>/SKILL.md # 14 skill files
35-
rules/<rule-name>.mdc # 8 rule files
34+
skills/<skill-name>/SKILL.md # 15 skill files
35+
rules/<rule-name>.mdc # 9 rule files
3636
templates/<template-name>/ # 2 starter templates
37-
snippets/<snippet-name>.py # 21 standalone Python snippets
38-
examples/<name>/ # 53 runnable smoke-gated examples (+ gallery.json)
37+
snippets/<snippet-name>.py # 24 standalone Python snippets
38+
examples/<name>/ # 54 runnable smoke-gated examples (+ gallery.json)
3939
examples/gallery_framing.py # shared Layer 1 framing measurement (render path only)
4040
scripts/build_gallery.py # generates docs/gallery/ (stdlib only)
4141
scripts/site/ # vendored landing-page build (build_site.py + template)

CLAUDE.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,24 @@ The **Blender Developer Tools** repository is at **v0.54.0**. It packages skills
1717
## Repository Architecture
1818

1919
```
20-
skills/<skill-name>/SKILL.md - AI workflow definitions, 14 total
21-
rules/<rule-name>.mdc - Anti-pattern rules, 8 total
20+
skills/<skill-name>/SKILL.md - AI workflow definitions, 15 total
21+
rules/<rule-name>.mdc - Anti-pattern rules, 9 total
2222
templates/<template-name>/ - Starter projects, 2 total
23-
snippets/<snippet-name>.py - Standalone code patterns, 21 total
24-
examples/<name>/ - Runnable smoke-gated examples, 53 total (+ gallery.json)
23+
snippets/<snippet-name>.py - Standalone code patterns, 24 total
24+
examples/<name>/ - Runnable smoke-gated examples, 54 total (+ gallery.json)
2525
scripts/build_gallery.py - Regenerates docs/gallery/ from gallery.json (stdlib only)
2626
scripts/site/ - Vendored landing-page build (Jinja2)
2727
docs/gallery/ - Committed generated gallery pages + hero renders
2828
VERSION - Source of truth for the repo version
2929
```
3030

31-
## Skills (14)
31+
## Skills (15)
3232

3333
| Skill | Purpose |
3434
| --- | --- |
3535
| addon-scaffolding | Extensions Platform manifest, file layout, register/unregister symmetry |
3636
| ai-mesh-cleanup | Ordered cleanup for imported generated meshes: units, transform apply, origin, normals, budget, collider |
37+
| engine-export-presets | Unity Y-up, Godot Z-up, and Unreal centimeter glTF/FBX presets; glTF uses export_yup, FBX uses axis_forward/axis_up |
3738
| operators | `bpy.types.Operator` lifecycle, `bl_idname`, redo, defensive context handling |
3839
| ui-panels | `bpy.types.Panel` declarative `draw()`, layout primitives, conditional UI |
3940
| custom-properties | `bpy.props` annotations, PropertyGroup, PointerProperty, storage tradeoffs |
@@ -47,7 +48,7 @@ VERSION - Source of truth for the repo version
4748
| bl-info-migration | Three-step migration from legacy `bl_info` to Extensions Platform, dual-format pattern |
4849
| vse-python | VSE timeline from Python: `.strips` vs `.sequences`, `new_effect` kwargs, 5.2 COLOR `width`/`height` bake |
4950

50-
## Rules (8)
51+
## Rules (9)
5152

5253
| Rule | Scope | What it flags |
5354
| --- | --- | --- |
@@ -59,6 +60,7 @@ VERSION - Source of truth for the repo version
5960
| use-foreach-set-for-bulk-data | `*.py` | Python loops over `mesh.vertices` setting bulk attributes one at a time |
6061
| validate-imported-mesh-scale | `*.py` | glTF/FBX import then mesh work with no `transform_apply` and no unit-scale check |
6162
| no-unapplied-modifiers-on-export | `*.py` | Export with live modifiers when the export does not request evaluated geometry |
63+
| use-correct-axis-rna-per-exporter | `*.py` | `export_scene.gltf` with FBX `axis_forward`/`axis_up`, or `export_scene.fbx` with glTF `export_yup` |
6264

6365
## Templates (2)
6466

@@ -78,17 +80,17 @@ VERSION - Source of truth for the repo version
7880
- glTF export via `bpy.ops.export_scene.gltf`
7981
- Explicit exit codes for CI integration
8082

81-
## Snippets (21)
83+
## Snippets (24)
8284

8385
Small standalone `.py` files at `snippets/<name>.py`, each 5 to 50 lines.
8486

8587
v0.1.0: canonical object creation and deletion, depsgraph evaluated mesh, bmesh load-edit-free, temp_override context, foreach_set vertex bulk write, register_classes_factory, PointerProperty binding, cross-version property delete, and the `action_ensure_channelbag_for_slot` slotted-actions bridge.
8688

8789
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'`.
8890

89-
AI asset pipeline track: `decimate_to_budget.py`, `convex_hull_collider.py`, `lod_chain.py` (helper duplicated, not imported), `gltf_draco_export.py`.
91+
AI asset pipeline track: `decimate_to_budget.py`, `convex_hull_collider.py`, `lod_chain.py` (helper duplicated, not imported), `gltf_draco_export.py`, `export_preset_unity.py`, `export_preset_godot.py`, `export_preset_unreal.py`.
9092

91-
## Examples (53)
93+
## Examples (54)
9294

9395
Runnable scripts at `examples/<name>/`, each asserting a real API contract with
9496
deterministic checks (exit non-zero on failure) and optionally rendering a still via

README.md

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
</p>
1919

2020
<p align="center">
21-
<strong>14 skills</strong> &nbsp;&bull;&nbsp; <strong>8 rules</strong> &nbsp;&bull;&nbsp; <strong>2 templates</strong> &nbsp;&bull;&nbsp; <strong>21 snippets</strong> &nbsp;&bull;&nbsp; <strong>53 examples</strong>
21+
<strong>15 skills</strong> &nbsp;&bull;&nbsp; <strong>9 rules</strong> &nbsp;&bull;&nbsp; <strong>2 templates</strong> &nbsp;&bull;&nbsp; <strong>24 snippets</strong> &nbsp;&bull;&nbsp; <strong>54 examples</strong>
2222
</p>
2323

2424
<p align="center">
@@ -36,16 +36,16 @@
3636

3737
## Overview
3838

39-
This repository ships **14 skills, 8 rules, 2 templates, 21 snippets, and 53 examples** for Blender Python development targeting Blender 5.2 LTS (current stable) with Blender 4.5 LTS fallback support. Blender 5.1 is prior stable.
39+
This repository ships **15 skills, 9 rules, 2 templates, 24 snippets, and 54 examples** for Blender Python development targeting Blender 5.2 LTS (current stable) with Blender 4.5 LTS fallback support. Blender 5.1 is prior stable.
4040

4141
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.
4242

4343
| Layer | Role |
4444
| --- | --- |
45-
| **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 |
46-
| **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 |
45+
| **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, engine export presets |
46+
| **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 |
4747
| **Templates** | A working Extensions Platform add-on starter and a headless batch script starter |
48-
| **Snippets** | 21 small standalone Python files demonstrating canonical patterns |
48+
| **Snippets** | 24 small standalone Python files demonstrating canonical patterns |
4949

5050
## Quick start
5151

@@ -627,7 +627,7 @@ portable path is `radius`.
627627
</details>
628628

629629
<details>
630-
<summary><strong>Game asset pipeline</strong> — 20 examples</summary>
630+
<summary><strong>Game asset pipeline</strong> — 21 examples</summary>
631631

632632
<table>
633633
<tr>
@@ -646,6 +646,22 @@ loop), V-flipped UVs, and per-triangle material bindings — all against the
646646
depsgraph-evaluated mesh. The exporter/importer RNA signatures are probed
647647
byte-identical on 4.5.11 and 5.1.2 and guarded against future renames.
648648

649+
</td>
650+
</tr>
651+
<tr>
652+
<td width="46%" valign="middle">
653+
<a href="examples/export-preset-axis/"><img src="examples/export-preset-axis/preview.webp" alt="Export preset axis: a radio beacon exported under Unity and Godot glTF presets and re-imported side by side on a dark studio floor - Unity standing with a glowing cap, Godot lying on its base - proving the two files have different vertex orientation" /></a>
654+
</td>
655+
<td valign="middle">
656+
657+
### [export-preset-axis](examples/export-preset-axis/)
658+
659+
The same beacon mesh under the Unity (`export_yup=True`) and Godot
660+
(`export_yup=False`) glTF presets. Re-importing each file proves the axis
661+
conversion: Unity stands, Godot lies along `-Y`. `--same-axis` exports both
662+
Y-up and the differ check exits 9. Neighbor of
663+
[`gltf-export-roundtrip`](examples/gltf-export-roundtrip/).
664+
649665
</td>
650666
</tr>
651667
<tr>
@@ -1008,15 +1024,15 @@ the duplicates, then glTF ships 24 tris / 48 positions / 8 unique.
10081024
## How content is organized
10091025

10101026
```
1011-
skills/<name>/SKILL.md - 14 skill files, YAML frontmatter, one canonical pattern each
1012-
rules/<name>.mdc - 8 rule files, anti-pattern + correction
1027+
skills/<name>/SKILL.md - 15 skill files, YAML frontmatter, one canonical pattern each
1028+
rules/<name>.mdc - 9 rule files, anti-pattern + correction
10131029
templates/<name>/ - 2 template directories (extension-addon-template, headless-batch-script-template)
1014-
snippets/<name>.py - 21 standalone Python snippets, 5 to 50 lines each
1030+
snippets/<name>.py - 24 standalone Python snippets, 5 to 50 lines each
10151031
```
10161032

10171033
## Using rules in Cursor
10181034

1019-
The `.mdc` files in `rules/` apply automatically when Cursor opens a Blender Python project, scoped by the `globs` in each rule's frontmatter. The eight rules are:
1035+
The `.mdc` files in `rules/` apply automatically when Cursor opens a Blender Python project, scoped by the `globs` in each rule's frontmatter. The nine rules are:
10201036

10211037
- `prefer-data-over-ops-in-loops`: flags `bpy.ops.*` calls inside object iteration
10221038
- `always-free-bmesh`: flags `bmesh.new()` without paired `bm.free()` in `try`/`finally`
@@ -1026,6 +1042,7 @@ The `.mdc` files in `rules/` apply automatically when Cursor opens a Blender Pyt
10261042
- `use-foreach-set-for-bulk-data`: flags Python loops over `mesh.vertices` setting `co`, normals, or other per-element bulk data
10271043
- `validate-imported-mesh-scale`: flags glTF/FBX import then mesh work with no `transform_apply` and no unit-scale check
10281044
- `no-unapplied-modifiers-on-export`: flags export of objects with live modifiers when the export does not request evaluated geometry
1045+
- `use-correct-axis-rna-per-exporter`: flags `export_scene.gltf` calls that pass FBX `axis_forward` / `axis_up`, and `export_scene.fbx` calls that pass glTF `export_yup`
10291046

10301047
Symlink or clone this repo, then point Cursor at it as a skills/rules source.
10311048

ROADMAP.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ derives the actual version from conventional-commit types.
1818
| 5.2 LTS targeting, GN modifier inputs | 12 | 6 | 2 | 17 | Shipped |
1919
| VSE COLOR strip intrinsic size (undocumented 5.2) | 13 | 6 | 2 | 17 | Shipped |
2020
| Modal operators, USD, mathutils ||||| Upcoming |
21-
| AI asset pipeline: post-generation cleanup | - | - | - | - | Upcoming |
22-
| AI asset pipeline: engine export presets | - | - | - | - | Upcoming |
21+
| AI asset pipeline: post-generation cleanup | 14 | 8 | 2 | 21 | Shipped (v0.54.0) |
22+
| AI asset pipeline: engine export presets | 15 | 9 | 2 | 24 | Shipped |
2323
| AI asset pipeline: headless template | - | - | - | - | Upcoming |
2424
| AI asset pipeline: live-session bridge (spike) | - | - | - | - | Upcoming |
2525
| Stable ||||| Upcoming |
@@ -95,10 +95,10 @@ Audit pass on v0.1.0 content: standards-version markers bumped from `1.9.1` to `
9595

9696
Provider-agnostic GLB-in / engine-ready-out. This repo does not generate meshes.
9797

98-
- **Post-generation cleanup skills** (this phase starts the family; bake/UV/atlas follow on): import and unit-scale normalization, transform apply and origin, poly-budget decimate, LOD chain, collision mesh, high-to-low bake, UV transfer and atlas packing. Phase 1: `ai-mesh-cleanup`, four snippets, two rules.
99-
- **Engine export presets.** Unity (Y-up), Godot, and Unreal (centimeter scale) glTF and FBX paths with Draco. One skill, one snippet set.
100-
- **`ai-asset-pipeline-template/`.** Third template. Headless: GLB path in; LOD set, convex collider, engine-preset export; explicit CI exit codes. Pattern: `templates/headless-batch-script-template/`. Phase 2.
101-
- **Live-session agent bridge.** Research spike, not a committed deliverable. MCP server or socket listener so an agent can execute against a running Blender instance instead of blind `--background` scripts. Built on `templates/extension-addon-template/`. Needs its own design pass.
98+
- **Post-generation cleanup skills.** Import and unit-scale normalization, transform apply and origin, poly-budget decimate, LOD chain, collision mesh. Phase 1 shipped in v0.54.0 as `ai-mesh-cleanup`, four snippets, two rules. Bake/UV/atlas follow on.
99+
- **Engine export presets.** **Delivered.** Unity (Y-up glTF), Godot (Z-up glTF, meters), Unreal (centimeter glTF bake and FBX `global_scale`). Skill `engine-export-presets`, three snippets, rule `use-correct-axis-rna-per-exporter`, witness `examples/export-preset-axis/`. Draco remains opt-in via `gltf_draco_export.py`.
100+
- **`ai-asset-pipeline-template/`.** Third template. Headless: GLB path in; LOD set, convex collider, engine-preset export; explicit CI exit codes. Pattern: `templates/headless-batch-script-template/`. Phase 3. Unpinned.
101+
- **Live-session agent bridge.** Research spike, not a committed deliverable. MCP server or socket listener so an agent can execute against a running Blender instance instead of blind `--background` scripts. Built on `templates/extension-addon-template/`. Needs its own design pass. Unpinned.
102102

103103
## Candidate pool (next content)
104104

8.08 KB
Loading
35.1 KB
Loading

0 commit comments

Comments
 (0)