feat(blender): extension set live in the GUI; MCP acceptance 9/9, probe made safe-mode compliant
This commit is contained in:
@@ -201,10 +201,10 @@ _As of 2026-09-27 ~0900 PT._
|
||||
add-ons (`stacks/blender/extensions.lock`) built by `scripts/blender-extensions sync` into
|
||||
`fv-ml1:/tank/blender-extensions/5.2/system` (LIVE), mounted read-only as the System repo;
|
||||
`fleet_extensions.py` enables them (GUI startup timer; `blender-run --extensions`). Headless
|
||||
acceptance 8/9 (CAD Sketcher sketching is GUI-only). **⚠ The stack deploy that wires the GUI
|
||||
and the hook (`deploy-stack.sh fv-ml1 blender`) was DENIED by the permission classifier on
|
||||
2026-09-28 and awaits Prime**; until it runs, `blender-run --extensions` fails cleanly (mount
|
||||
error) and the MCP acceptance is not done. SurfacePsycho's eval() is patched to literal_eval.
|
||||
acceptance 8/9 (CAD Sketcher sketching is GUI-only); **MCP 9/9 after Prime ran the deploy himself
|
||||
(1505; the classifier had refused mine)**. SurfacePsycho's eval() is patched to literal_eval
|
||||
(held under MCP). Open: agent-drawn CAD Sketcher geometry (its stateful ops want point picks),
|
||||
and MeasureIt overlays not seen in MCP screenshots. GUI left DOWN.
|
||||
|
||||
### Zigbee2MQTT on esh-docker-vm (2026-09-27, Prime go-ahead; ha-dev request)
|
||||
|
||||
|
||||
@@ -70,11 +70,9 @@ def dims(o):
|
||||
return "x".join(str(round(d * 1000, 3)) for d in world_extent(o)) + " mm (world)"
|
||||
|
||||
|
||||
def run(name, fn):
|
||||
try:
|
||||
fn(name)
|
||||
except Exception as ex:
|
||||
report(name, False, "raised " + type(ex).__name__ + ": " + str(ex))
|
||||
def raised(name, ex):
|
||||
# repr, not type(ex).__name__: safe mode refuses dunder attributes.
|
||||
report(name, False, "raised " + repr(ex)[:300])
|
||||
|
||||
|
||||
# 1. 3D-Print Toolbox: clean non-manifold on a cube with one face deleted.
|
||||
@@ -221,17 +219,39 @@ def t_cad_sketcher(name):
|
||||
"sketch objects " + str(len(sketches)))
|
||||
|
||||
|
||||
for n, f in (
|
||||
("print3d_toolbox clean_non_manifold", t_print3d),
|
||||
("bool_tool boolean_auto_difference", t_booltool),
|
||||
("looptools circle", t_looptools),
|
||||
("measureit addsegment", t_measureit),
|
||||
("surfacepsycho bezier patch + STEP export", t_surfacepsycho),
|
||||
("step_importer import_scene.step", t_step_import),
|
||||
("ThreeMF_io export + import", t_threemf),
|
||||
("CAD_Sketcher sketch + solve", t_cad_sketcher),
|
||||
):
|
||||
run(n, f)
|
||||
# Each test is called by name: safe mode refuses calling a function held in a variable.
|
||||
try:
|
||||
t_print3d("print3d_toolbox clean_non_manifold")
|
||||
except Exception as ex:
|
||||
raised("print3d_toolbox clean_non_manifold", ex)
|
||||
try:
|
||||
t_booltool("bool_tool boolean_auto_difference")
|
||||
except Exception as ex:
|
||||
raised("bool_tool boolean_auto_difference", ex)
|
||||
try:
|
||||
t_looptools("looptools circle")
|
||||
except Exception as ex:
|
||||
raised("looptools circle", ex)
|
||||
try:
|
||||
t_measureit("measureit addsegment")
|
||||
except Exception as ex:
|
||||
raised("measureit addsegment", ex)
|
||||
try:
|
||||
t_surfacepsycho("surfacepsycho bezier patch + STEP export")
|
||||
except Exception as ex:
|
||||
raised("surfacepsycho bezier patch + STEP export", ex)
|
||||
try:
|
||||
t_step_import("step_importer import_scene.step")
|
||||
except Exception as ex:
|
||||
raised("step_importer import_scene.step", ex)
|
||||
try:
|
||||
t_threemf("ThreeMF_io export + import")
|
||||
except Exception as ex:
|
||||
raised("ThreeMF_io export + import", ex)
|
||||
try:
|
||||
t_cad_sketcher("CAD_Sketcher sketch + solve")
|
||||
except Exception as ex:
|
||||
raised("CAD_Sketcher sketch + solve", ex)
|
||||
|
||||
failed = [r[0] for r in results if not r[1]]
|
||||
print("SUMMARY " + TAG + ": " + str(len(results) - len(failed)) + "/" + str(len(results)) + " passed")
|
||||
|
||||
@@ -230,4 +230,25 @@ z = 0, area 399.999982 mm² against 400. Extruded 2 mm, it gave a valid 799.9999
|
||||
real NURBS surface reaches the kernel, not triangles, and millimetres hold across the hop. That is
|
||||
one run of a flat bilinear patch; curved and trimmed patches are untested.
|
||||
|
||||
**MCP (GUI) path:** pending the stack deploy that mounts the repo and hook into the GUI container.
|
||||
**MCP (GUI) path, 2026-09-28 1506 (after Prime ran the deploy):** the hook log read
|
||||
`enabled 8/8`, `hardened: surfacepsycho ... literal_eval`, `online access: False`. Through
|
||||
`scripts/blender-mcp` → `execute_blender_code` under safe mode, the probe passed **9 of 9**,
|
||||
including CAD Sketcher (a sketch on the XY origin plane, then a full solve), because the GUI has
|
||||
the workspace tool that `-b` lacks. The eval patch held under MCP: the code payload was refused
|
||||
(`ValueError: malformed node`) and the literal `{3, 5}` was accepted.
|
||||
- **CAD Sketcher sketch, re-solved headless:** the MCP-made sketch was saved
|
||||
(`cad-sketch-mcp.blend`), then `blender-run --cpu --extensions` opened it and
|
||||
`view3d.slvs_solve(all=True)` returned FINISHED. Authoring is in the GUI; re-solving works in batch.
|
||||
- **Not solved yet:** drawing CAD Sketcher geometry from code. `slvs_add_rectangle` with
|
||||
`p1_fallback`/`p2_fallback` and `wait_for_input=False` raised
|
||||
`'NoneType' object has no attribute 'co'`. Its drawing ops are stateful and expect point picks,
|
||||
and its Python entity API is out of reach under safe mode. Sketches work; agent-drawn profiles
|
||||
need more work.
|
||||
- **Not confirmed:** MeasureIt overlays in `get_viewport_screenshot`. The segment was created and
|
||||
`measureit.runopengl` returned FINISHED, but two screenshots (a top view with a 20 mm edge
|
||||
dimension) showed no dimension.
|
||||
- `blender-run --extensions` (the real wrapper, `--cpu`) ran the same probe at 8 of 9, the one
|
||||
miss being CAD Sketcher for the headless reason above.
|
||||
|
||||
Safe-mode note for probe authors: safe mode refuses calling a function held in a variable and
|
||||
any dunder attribute (`type(ex).__name__`). The probe calls each test by name and uses `repr(ex)`.
|
||||
|
||||
Reference in New Issue
Block a user