Compare commits

...

1 Commits

Author SHA1 Message Date
Petru Conduraru 04db09f90a Bonsai: fix DirectProfileEdit crash exiting edit mode (#7624)
Exiting a slab DirectProfileEdit raised
`AttributeError: 'OverrideModeSetObject' object has no attribute 'edited_objs'`.
DirectProfileEdit's fallback paths called bpy.ops.bim.override_mode_set_object()
bare, which runs in EXEC context and dispatches straight to the operator's
_execute(); but edited_objs / unchanged_objs_with_openings are only
initialised in _invoke(), so _execute iterated a never-set attribute and
crashed. Every other call site of this operator already passes
"INVOKE_DEFAULT"; only DirectProfileEdit's four fallbacks missed it.

Pass "INVOKE_DEFAULT" at all four sites so _invoke runs first, matching the
rest of the codebase.

Verified: the bare-call path reproduces the exact AttributeError; the
invoke path initialises edited_objs before execute() runs and completes
cleanly. All override_mode_set_object call sites in the file now
consistently use INVOKE_DEFAULT; the operators still register, and
core test_geometry.py passes (14).

Generated with the assistance of an AI coding tool.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:42:18 +03:00
@@ -2814,7 +2814,7 @@ class DirectProfileEdit(bpy.types.Operator, tool.Ifc.Operator):
return self.exit_element_edit_mode(context, obj, element)
# For other edit modes, use standard operator
return bpy.ops.bim.override_mode_set_object()
return bpy.ops.bim.override_mode_set_object("INVOKE_DEFAULT")
def exit_item_edit_mode(self, context, obj):
"""Exit from representation item editing."""
@@ -2825,7 +2825,7 @@ class DirectProfileEdit(bpy.types.Operator, tool.Ifc.Operator):
item = tool.Geometry.get_active_representation(obj)
if not item:
return bpy.ops.bim.override_mode_set_object()
return bpy.ops.bim.override_mode_set_object("INVOKE_DEFAULT")
# Fix vertex order for annotation items
props = tool.Geometry.get_geometry_props()
@@ -2939,7 +2939,7 @@ class DirectProfileEdit(bpy.types.Operator, tool.Ifc.Operator):
# Fallback
else:
return bpy.ops.bim.override_mode_set_object()
return bpy.ops.bim.override_mode_set_object("INVOKE_DEFAULT")
except Exception as e:
self.report({"ERROR"}, f"Failed to save item changes: {str(e)}")
@@ -2966,7 +2966,7 @@ class DirectProfileEdit(bpy.types.Operator, tool.Ifc.Operator):
return {"CANCELLED"}
# Fallback to standard operator
return bpy.ops.bim.override_mode_set_object()
return bpy.ops.bim.override_mode_set_object("INVOKE_DEFAULT")
def handle_enter_edit_mode(self, context):
"""Handle entering edit mode from object mode."""