mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-06 07:51:47 +00:00
Wire array panel buttons to triad lifecycle
Two bugs in BIM_PT_array: 1. The "is this layer in edit mode" predicate compared a BoolProperty against an int (props.is_editing == i). Python evaluates False == 0 as True, so layer 0 always rendered the per-layer edit form even when no edit was active — clicking validate/cancel then dispatched against a phantom edit state. Switched to props.editing_item_index == i, which defaults to -1 and matches exactly one layer when an edit is active. 2. The panel's CHECKMARK and CANCEL buttons called bim.edit_array / bim.disable_editing_array, a parallel lifecycle that only cleared editing_item_index. Entering edit mode via the viewport gizmo (bim.enable_editing_array, the triad enter) sets is_editing=True and hides array children; the legacy panel exit unwound neither — so committing or cancelling from the panel left is_editing=True with children hidden, and the viewport gizmo thought the edit was still in progress. Re-bound both panel buttons to the canonical triad operators (bim.finish_editing_array / bim.cancel_editing_array), which _ArrayEditMixin already owns and which the viewport gizmo group already uses. Panel and gizmo now share one exit path. The three now-unreachable operators are deleted with their registration entries: EditArray (bim.edit_array), DisableEditingArray (bim.disable_editing_array), and EnableEditingArrayItem (bim.enable_editing_array_item, never called from any UI). The two test/tool/test_model.py sites that drove bim.edit_array as a commit step are switched to bim.finish_editing_array. External scripts or user keymaps bound to bim.edit_array / bim.disable_editing_array will need to update — the replacements are bim.finish_editing_array and bim.cancel_editing_array, both taking no parameters (the layer is read from props.editing_item_index). Partly generated with the assistance of an AI coding tool.
This commit is contained in:
@@ -51,10 +51,7 @@ from . import (
|
||||
classes = (
|
||||
array.AddArray,
|
||||
array.CancelEditingArray,
|
||||
array.DisableEditingArray,
|
||||
array.EditArray,
|
||||
array.EnableEditingArray,
|
||||
array.EnableEditingArrayItem,
|
||||
array.FinishEditingArray,
|
||||
array.ApplyArray,
|
||||
array.RegenerateArray,
|
||||
|
||||
@@ -157,108 +157,6 @@ class AddArray(bpy.types.Operator, tool.Ifc.Operator):
|
||||
tool.Array.constrain_children_to_parent(element)
|
||||
|
||||
|
||||
class DisableEditingArray(bpy.types.Operator):
|
||||
bl_idname = "bim.disable_editing_array"
|
||||
bl_label = "Disable Editing Array"
|
||||
bl_description = "Cancel editing this array without saving changes"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
obj = context.active_object
|
||||
assert obj
|
||||
tool.Model.get_array_props(obj).editing_item_index = -1
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class EnableEditingArrayItem(bpy.types.Operator):
|
||||
"""Per-item array layer editing: hydrates props from one BBIM_Array layer.
|
||||
|
||||
The element-wide ``bim.enable_editing_array`` (parametric edit lifecycle) coexists with
|
||||
this operator. They target different state: ``is_editing`` for the edit lifecycle,
|
||||
``editing_item_index`` for the per-item panel UI."""
|
||||
|
||||
bl_idname = "bim.enable_editing_array_item"
|
||||
bl_label = "Enable Editing Array Item"
|
||||
bl_description = "Edit this array layer"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
item: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
obj = context.active_object
|
||||
assert obj
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
props = tool.Model.get_array_props(obj)
|
||||
|
||||
relating_obj = props.relating_array_object
|
||||
|
||||
if relating_obj:
|
||||
element = tool.Ifc.get_entity(relating_obj)
|
||||
parent_globalid = ifcopenshell.util.element.get_pset(element, "BBIM_Array", "Parent")
|
||||
parent_element = tool.Ifc.get().by_guid(parent_globalid)
|
||||
data = json.loads(ifcopenshell.util.element.get_pset(parent_element, "BBIM_Array", "Data"))[self.item]
|
||||
else:
|
||||
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Array", "Data"))[self.item]
|
||||
props.count = data["count"]
|
||||
si_conversion = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
props.x = data["x"] * si_conversion
|
||||
props.y = data["y"] * si_conversion
|
||||
props.z = data["z"] * si_conversion
|
||||
props.use_local_space = data.get("use_local_space", False)
|
||||
props.method = data.get("method", "OFFSET")
|
||||
props.per_child_opening = data.get("per_child_opening", data.get("mirror_to_host", True))
|
||||
|
||||
props.editing_item_index = self.item
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class EditArray(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.edit_array"
|
||||
bl_label = "Edit Array"
|
||||
bl_description = "Save changes to this array layer"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
item: bpy.props.IntProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
obj = context.active_object
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
props = tool.Model.get_array_props(obj)
|
||||
si_conversion = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
|
||||
pset = ifcopenshell.util.element.get_pset(element, "BBIM_Array")
|
||||
data = json.loads(pset["Data"])
|
||||
data[self.item] = {
|
||||
"children": data[self.item]["children"],
|
||||
"count": props.count,
|
||||
"x": props.x / si_conversion,
|
||||
"y": props.y / si_conversion,
|
||||
"z": props.z / si_conversion,
|
||||
"use_local_space": props.use_local_space,
|
||||
"method": props.method,
|
||||
"per_child_opening": props.per_child_opening,
|
||||
}
|
||||
|
||||
props.editing_item_index = -1
|
||||
|
||||
try:
|
||||
parent_element = tool.Ifc.get().by_guid(pset["Parent"])
|
||||
parent = tool.Ifc.get_object(parent_element)
|
||||
except:
|
||||
return {"FINISHED"}
|
||||
|
||||
tool.Array.remove_constraints(parent_element)
|
||||
# Conditional wipe-and-rebuild — only when the parent's geometry
|
||||
# differs from the children's. See ``_parent_geometry_changed`` for
|
||||
# the bbox-dim heuristic and its known false-negative case.
|
||||
if _parent_geometry_changed(parent, data):
|
||||
_wipe_array_children(data)
|
||||
tool.Model.regenerate_array(parent, data)
|
||||
tool.Array.set_children_lock_state(element, self.item, True)
|
||||
tool.Array.constrain_children_to_parent(element)
|
||||
|
||||
# clears the relating_array_object so it doesn't show again next time
|
||||
props.relating_array_object = None
|
||||
|
||||
|
||||
class _ArrayEditMixin(ParametricEditMixinBase):
|
||||
"""Array edit lifecycle scoped to one layer at a time.
|
||||
|
||||
|
||||
@@ -238,11 +238,11 @@ class BIM_PT_array(bpy.types.Panel):
|
||||
|
||||
for i, array in enumerate(ArrayData.data["parameters"]["data_dict"]):
|
||||
box = self.layout.box()
|
||||
if props.is_editing == i:
|
||||
if props.editing_item_index == i:
|
||||
row = box.row(align=True)
|
||||
row.prop(props, "count", icon="MOD_ARRAY")
|
||||
row.operator("bim.edit_array", icon="CHECKMARK", text="").item = i
|
||||
row.operator("bim.disable_editing_array", icon="CANCEL", text="")
|
||||
row.operator("bim.finish_editing_array", icon="CHECKMARK", text="")
|
||||
row.operator("bim.cancel_editing_array", icon="CANCEL", text="")
|
||||
row = box.row(align=True)
|
||||
row.prop(props, "method")
|
||||
row = box.row(align=True)
|
||||
|
||||
@@ -605,7 +605,7 @@ class TestUsingArrays(NewFile):
|
||||
props.count = 4
|
||||
props.x = 4
|
||||
props.sync_children = sync_children
|
||||
bpy.ops.bim.edit_array(item=0)
|
||||
bpy.ops.bim.finish_editing_array()
|
||||
|
||||
if add_second_layer:
|
||||
bpy.ops.bim.add_array()
|
||||
@@ -614,7 +614,7 @@ class TestUsingArrays(NewFile):
|
||||
props.count = 3
|
||||
props.y = 4
|
||||
props.sync_children = sync_children
|
||||
bpy.ops.bim.edit_array(item=1)
|
||||
bpy.ops.bim.finish_editing_array()
|
||||
|
||||
def test_remove_array_last_to_first(self):
|
||||
self.setup_array(add_second_layer=True)
|
||||
|
||||
Reference in New Issue
Block a user