Skip to content

fix(rules): allow BMesh ownership transfer; make the handoff sites leak-proof - #438

Merged
TMHSDigital merged 1 commit into
mainfrom
fix/bmesh-ownership
Oct 5, 2026
Merged

TMHSDigital merged 1 commit into
mainfrom
fix/bmesh-ownership

Conversation

@TMHSDigital

Copy link
Copy Markdown
Owner

Closes #401.

What changed

  • rules/always-free-bmesh.mdc adds a section, "Ownership transfer is allowed, if exactly one owner frees". A builder may return a BMesh, or hand it to a finisher that frees it. Until then, it must free the BMesh on every failure path. claude/blender-rules.md is regenerated.
  • examples/custom-normals-shade/custom_normals_shade.py: the three builders that hand their BMesh to finish_mesh() now wrap the build in try: … except BaseException: bm.free(); raise. Success still hands off.
  • showcase/traffic-cones/traffic_cones.py: the 4 callers of cone_bm()/board_bm() free the returned BMesh in finally.

Evidence

Live run on local Blender 5.2.1: old (main) and new copies of each script ran under a wrapper. The wrapper hashes every mesh's vertex coordinates, faces and corner normals after the script exits.

Script Old New
custom_normals_shade exit 0, 13 meshes, a5089c84039204e0 exit 0, 13 meshes, a5089c84039204e0
traffic_cones exit 0, 5 meshes, af13cd9d4a3f5e68 exit 0, 5 meshes, af13cd9d4a3f5e68

The stdout of each pair differs only in glTF exporter timestamps.

Local checks: check_example_rules.py passes, and build_claude_rules.py produces no diff.

Inspection only: the failure paths (an exception between bmesh.new() and the handoff) were not triggered live.

🤖 Generated with Claude Code

…ak-proof

always-free-bmesh called `return bm` and builder hand-offs wrong, yet
the codebase relies on both: traffic-cones' cone_bm()/board_bm() return
a BMesh the caller frees, and custom-normals-shade builds a BMesh and
hands it to finish_mesh(), which frees it in finally. The rule now
allows transfer when every path has exactly one owner that frees, and
names what stays wrong (an owner-less path).

The sites themselves had owner-less paths: the four traffic-cones
callers freed outside finally, and the three custom-normals builders
could raise between bmesh.new() and the hand-off. Callers now free in
finally; builders free on failure (except BaseException: free; raise)
and hand off on success.

Closes #401

Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added rules examples Runnable smoke-gated examples under examples/ showcase Budget-conformance props under showcase/ labels Oct 5, 2026
@TMHSDigital

Copy link
Copy Markdown
Owner Author

CI evidence before merge: all checks pass ( 13 pass ). Blender Smoke on PR head: Blender 5.2.2 LTS / Blender 4.5.14 LTS. Summaries (happy path; falsifiers) per leg: 143 passed, 1 skipped, 0 failed;143 passed, 0 skipped, 0 failed;141 passed, 3 skipped, 0 failed;136 passed, 7 skipped, 0 failed;

@TMHSDigital
TMHSDigital merged commit 6d9c75a into main Oct 5, 2026
13 checks passed
@TMHSDigital
TMHSDigital deleted the fix/bmesh-ownership branch October 5, 2026 02:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

examples Runnable smoke-gated examples under examples/ rules showcase Budget-conformance props under showcase/

Projects

None yet

Development

Successfully merging this pull request may close these issues.

showcase: hay-bale leaks a bmesh via 'finally: pass'; always-free-bmesh rule disagrees with builder/ownership-transfer code

1 participant