Blender assignMaterial: colour, idempotent slot, malformed colour refused #6

Merged
libby merged 2 commits from libby/blender-material-colour into main 2026-11-10 18:00:38 +00:00
Member

Gap cut from the Noka MKI harness (/opt/commons/handoff/noka-mki-brokkr-20261110/gaps.md, G2): assignMaterial took no colour, so a palette could not be set through Brokkr. Commit 78ba4ea.

What changed: assignMaterial accepts color (RGB or RGBA); it sets the Principled BSDF Base Color and the material diffuse_color. A malformed colour fails naming the field before anything is created. Assigning the same material to an object twice adds no second slot. Docs updated.

Stacking: this branch sits on libby/blender-gn-recreation (PR #5, still open), so the diff against main also shows #5. The change itself is the commit(s) named above; review them with git diff libby/blender-gn-recreation..HEAD. Merge #5 first.

Verified

  • Unit (fake bpy): python3 -I -m unittest discover -s tests -t tests in surfaces/blender: 113 tests, OK, 10 skipped (the skips need cultmesh_py / CULTLIB_PACKAGES; not run here).
  • Live, headless Blender 5.2.2 LTS: surfaces/blender/tests/live/material_colour.py, 14 of 14 checks pass (Base Color and diffuse_color set, repeat keeps one slot, omitted colour leaves colour, RGBA recolours, [1,2] / [2,0,0] / NaN / "red" refused, refusals leave colour and create no material).

Not verified

  • No Windows or Starfire run; no Blender other than 5.2.2 for this cut (the stacked GN commits record 5.2.3 runs).
  • Colour is not checked end to end in a rendered image or exported glTF in this PR; the Noka rerun with colour and export combined is reported separately.
  • The 10 skipped server tests were not run.

🤖 Generated with Claude Code

Steward pass, 2026-11-10 (head after this note): replayed as one commit on main 6995eab (it was stacked on #5, now merged); the old commit cited above (78ba4ea) and the old test count (113) are superseded. Soul pass (separate agent) held on behaviour; findings fixed: colour limits now pinned (0 and 1 accepted; 1.0000001, -1e-9, 10**400 refused; four boundary mutants killed), a huge int no longer escapes the named refusal, color() and color_rgba() share one component rule, null documented as absent. 130 unit tests and 20 daemon tests pass locally. Not run: tests/live/material_colour.py and any real bpy behaviour (Blender not installed). Brokkr has no CI.

Gap cut from the Noka MKI harness (/opt/commons/handoff/noka-mki-brokkr-20261110/gaps.md, G2): assignMaterial took no colour, so a palette could not be set through Brokkr. Commit 78ba4ea. What changed: assignMaterial accepts `color` (RGB or RGBA); it sets the Principled BSDF Base Color and the material diffuse_color. A malformed colour fails naming the field before anything is created. Assigning the same material to an object twice adds no second slot. Docs updated. Stacking: this branch sits on libby/blender-gn-recreation (PR #5, still open), so the diff against main also shows #5. The change itself is the commit(s) named above; review them with `git diff libby/blender-gn-recreation..HEAD`. Merge #5 first. Verified - Unit (fake bpy): `python3 -I -m unittest discover -s tests -t tests` in surfaces/blender: 113 tests, OK, 10 skipped (the skips need cultmesh_py / CULTLIB_PACKAGES; not run here). - Live, headless Blender 5.2.2 LTS: surfaces/blender/tests/live/material_colour.py, 14 of 14 checks pass (Base Color and diffuse_color set, repeat keeps one slot, omitted colour leaves colour, RGBA recolours, [1,2] / [2,0,0] / NaN / "red" refused, refusals leave colour and create no material). Not verified - No Windows or Starfire run; no Blender other than 5.2.2 for this cut (the stacked GN commits record 5.2.3 runs). - Colour is not checked end to end in a rendered image or exported glTF in this PR; the Noka rerun with colour and export combined is reported separately. - The 10 skipped server tests were not run. 🤖 Generated with [Claude Code](https://claude.com/claude-code) **Steward pass, 2026-11-10 (head after this note):** replayed as one commit on main 6995eab (it was stacked on #5, now merged); the old commit cited above (78ba4ea) and the old test count (113) are superseded. Soul pass (separate agent) held on behaviour; findings fixed: colour limits now pinned (0 and 1 accepted; 1.0000001, -1e-9, 10**400 refused; four boundary mutants killed), a huge int no longer escapes the named refusal, color() and color_rgba() share one component rule, null documented as absent. 130 unit tests and 20 daemon tests pass locally. Not run: tests/live/material_colour.py and any real bpy behaviour (Blender not installed). Brokkr has no CI.
Builds a ring array, boundary_step and a seeded scatter natively and through
BrokkrBlenderTarget actions on Blender 5.2.3; records the gaps.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
createNodeGroup, addNode, linkSockets, addModifier, setModifierInput (node_actions.py);
setObjectCustomProperty refuses a name that is a Geometry Nodes modifier input instead of
accepting with no effect; object snapshots carry the evaluated counts, bounds and locations.
Live proof on Blender 5.2.3: ring, boundary_step and seeded scatter rebuilt by actions only
match the native trees (66 checks).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A refused linkSockets puts back the link it displaced; snapshot positions keep local and world
bounds apart, scan instances once per capture, skip positions above 1M vertices and flag
non-finite values; Int values capped at 4096; id/key patterns use fullmatch; addModifier names
the object type it cannot take; setObjectCustomProperty refuses only a modifier input identifier.
Live: 108 checks pass on Blender 5.2.3.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Cycles and self links are refused before Blender is asked; the snapshot's instance scan stops at
100k depsgraph items and says instancesComplete=false (2000x2000 instanced grid: 22 s -> 1.4 s);
the daemon advertisement lists the scene-action and node-graph capabilities. Live: 156 checks pass
on Blender 5.2.3.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
bpy hands out a fresh wrapper per access, so id() keys made reaches() stop early and accept cycles
on chains of six or more nodes; keyed by as_pointer() with one adjacency map per call. Objects the
stopped instance scan never reached report instanceCount null. removeModifier validates its name.
Live: 158 checks pass on Blender 5.2.3.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A refused link restores the displaced link's is_muted; removeModifier no longer applies the
creation-name pattern to a lookup, so hand-made Unicode modifier names are removable; the
pattern message lists the space it allows. Live: 166 checks pass on Blender 5.2.3.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
color sets Principled Base Color and diffuse_color; a bad color fails naming the field before
anything is created. A second assign of the same material to an object adds no slot.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
libby force-pushed libby/blender-material-colour from 78ba4eaf3d to 0254fa7070 2026-11-10 17:54:54 +00:00 Compare
A huge int no longer escapes the named refusal (math.isfinite raised OverflowError);
color() and color_rgba() share unit_component(). Tests accept 0 and 1 exactly and
refuse 1.0000001, -1e-9 and 10**400; "color": null is documented as absent.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
libby merged commit 8cebec6f3c into main 2026-11-10 18:00:38 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
GameCult/Brokkr!6
No description provided.