bim.clone_opening - always show in opening's ui

Otherwise it was hidden until user guesses that 2 objects need to be selected for it to appear.
Also, not sure if it's useful operator anymore - it seems just duplicating an opening and then adding it does the same thing.
This commit is contained in:
Andrej730
2025-01-16 17:13:46 +05:00
parent a383f60915
commit eef04fb91c
2 changed files with 41 additions and 25 deletions
+21 -12
View File
@@ -26,6 +26,7 @@ import numpy as np
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.geometry
import ifcopenshell.api.void
import ifcopenshell.geom
import ifcopenshell.util.shape
import ifcopenshell.util.element
@@ -1097,20 +1098,28 @@ class EditOpenings(Operator, tool.Ifc.Operator):
class CloneOpening(Operator, tool.Ifc.Operator):
bl_idname = "bim.clone_opening"
bl_label = "Clone Opening"
bl_description = "Clone the selected Opening and assign to the selected Element"
bl_description = "Clone the active Opening object and assign to the selected Element"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
objects = bpy.context.selected_objects
@classmethod
def poll(cls, context):
if len(context.selected_objects) != 2:
cls.poll_message_set("Exactly 2 objects must be selected.")
return False
return True
for obj in objects:
entity = tool.Ifc.get_entity(obj)
if entity.is_a() == "IfcWall":
wall = entity
continue
if entity.is_a() == "IfcOpeningElement":
opening = entity
continue
def _execute(self, context):
# NOTE: Operator displayed in UI only with IfcOpeningElement being active.
ifc_file = tool.Ifc.get()
objects = bpy.context.selected_objects
opening_obj = context.active_object
assert opening_obj
opening = tool.Ifc.get_entity(opening_obj)
assert opening and opening.is_a("IfcOpeningElement")
voided_obj = next(o for o in objects if o != opening_obj)
voided_element = tool.Ifc.get_entity(voided_obj)
assert voided_element
opening_placement = opening.ObjectPlacement
opening_representation = opening.Representation
@@ -1118,7 +1127,7 @@ class CloneOpening(Operator, tool.Ifc.Operator):
new_opening = ifcopenshell.api.run("root.create_entity", tool.Ifc.get(), ifc_class="IfcOpeningElement")
new_opening.Representation = opening_representation
ifcopenshell.api.run("void.add_opening", tool.Ifc.get(), opening=new_opening, element=wall)
ifcopenshell.api.void.add_opening(ifc_file, opening=new_opening, element=voided_element)
new_opening.ObjectPlacement = opening_placement
return {"FINISHED"}
+20 -13
View File
@@ -217,8 +217,18 @@ class CableTool(BimTool):
def add_layout_hotkey_operator(
layout: bpy.types.UILayout, text: str, hotkey: str, description: Union[str, None], ui_context: str = ""
layout: bpy.types.UILayout,
text: str,
hotkey: str,
description: Union[str, None],
ui_context: str = "",
*,
operator: str = "bim.hotkey",
) -> bpy.types.OperatorProperties:
"""
:param operator: Operator to display in UI. Displaying the specific operator in UI can be useful
to provide poll error messages.
"""
parts = hotkey.split("_") if hotkey else []
modifier, key = (parts + ["", ""])[:2]
@@ -227,7 +237,7 @@ def add_layout_hotkey_operator(
modifier_icon, modifier_str = MODIFIERS.get(modifier, ("NONE", ""))
row = layout.row(align=True)
op = row.operator("bim.hotkey", text=op_text, icon_value=custom_icon)
op = row.operator(operator, text=op_text, icon_value=custom_icon)
if ui_context != "TOOL_HEADER":
row.label(text="", icon=modifier_icon)
@@ -236,11 +246,12 @@ def add_layout_hotkey_operator(
hotkey_description = f"Hotkey: {modifier_str} {key}".strip()
description = "\n\n".join(filter(None, [description, hotkey_description]))
op.hotkey = hotkey
if ui_context == "TOOL_HEADER":
op.description = text + "\n" + description
else:
op.description = description
if operator == "bim.hotkey":
op.hotkey = hotkey
if ui_context == "TOOL_HEADER":
op.description = text + "\n" + description
else:
op.description = description
return op
@@ -804,12 +815,8 @@ class EditObjectUI:
op_text = "" if IS_TOOL_HEADER else "Edit Openings"
row.operator("bim.edit_openings", icon="CHECKMARK", text=op_text)
row.operator("bim.hide_openings", icon="CANCEL", text="")
if len(context.selected_objects) == 2:
row = cls.layout.row(align=True)
row.label(text="", icon="EVENT_SHIFT")
row.label(text="", icon="EVENT_L")
row = cls.layout.row(align=True) if ui_context != "TOOL_HEADER" else row
row.operator("bim.clone_opening", text="Clone Opening")
row = cls.layout.row(align=True) if ui_context != "TOOL_HEADER" else row
add_layout_hotkey_operator(row, "Clone Opening", "S_L", "", ui_context, operator="bim.clone_opening")
@classmethod
def draw_align(cls, context):