mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 14:23:53 +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:
committed by
Thomas Krijnen
parent
95ad96c25e
commit
645054aa6a
@@ -51,10 +51,7 @@ from . import (
|
|||||||
classes = (
|
classes = (
|
||||||
array.AddArray,
|
array.AddArray,
|
||||||
array.CancelEditingArray,
|
array.CancelEditingArray,
|
||||||
array.DisableEditingArray,
|
|
||||||
array.EditArray,
|
|
||||||
array.EnableEditingArray,
|
array.EnableEditingArray,
|
||||||
array.EnableEditingArrayItem,
|
|
||||||
array.FinishEditingArray,
|
array.FinishEditingArray,
|
||||||
array.ApplyArray,
|
array.ApplyArray,
|
||||||
array.RegenerateArray,
|
array.RegenerateArray,
|
||||||
|
|||||||
@@ -157,108 +157,6 @@ class AddArray(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
tool.Array.constrain_children_to_parent(element)
|
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):
|
class _ArrayEditMixin(ParametricEditMixinBase):
|
||||||
"""Array edit lifecycle scoped to one layer at a time.
|
"""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"]):
|
for i, array in enumerate(ArrayData.data["parameters"]["data_dict"]):
|
||||||
box = self.layout.box()
|
box = self.layout.box()
|
||||||
if props.is_editing == i:
|
if props.editing_item_index == i:
|
||||||
row = box.row(align=True)
|
row = box.row(align=True)
|
||||||
row.prop(props, "count", icon="MOD_ARRAY")
|
row.prop(props, "count", icon="MOD_ARRAY")
|
||||||
row.operator("bim.edit_array", icon="CHECKMARK", text="").item = i
|
row.operator("bim.finish_editing_array", icon="CHECKMARK", text="")
|
||||||
row.operator("bim.disable_editing_array", icon="CANCEL", text="")
|
row.operator("bim.cancel_editing_array", icon="CANCEL", text="")
|
||||||
row = box.row(align=True)
|
row = box.row(align=True)
|
||||||
row.prop(props, "method")
|
row.prop(props, "method")
|
||||||
row = box.row(align=True)
|
row = box.row(align=True)
|
||||||
|
|||||||
@@ -605,7 +605,7 @@ class TestUsingArrays(NewFile):
|
|||||||
props.count = 4
|
props.count = 4
|
||||||
props.x = 4
|
props.x = 4
|
||||||
props.sync_children = sync_children
|
props.sync_children = sync_children
|
||||||
bpy.ops.bim.edit_array(item=0)
|
bpy.ops.bim.finish_editing_array()
|
||||||
|
|
||||||
if add_second_layer:
|
if add_second_layer:
|
||||||
bpy.ops.bim.add_array()
|
bpy.ops.bim.add_array()
|
||||||
@@ -614,7 +614,7 @@ class TestUsingArrays(NewFile):
|
|||||||
props.count = 3
|
props.count = 3
|
||||||
props.y = 4
|
props.y = 4
|
||||||
props.sync_children = sync_children
|
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):
|
def test_remove_array_last_to_first(self):
|
||||||
self.setup_array(add_second_layer=True)
|
self.setup_array(add_second_layer=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user