diff --git a/src/bonsai/bonsai/bim/module/model/workspace.py b/src/bonsai/bonsai/bim/module/model/workspace.py index 668f5d3abb..2a227d0029 100644 --- a/src/bonsai/bonsai/bim/module/model/workspace.py +++ b/src/bonsai/bonsai/bim/module/model/workspace.py @@ -960,6 +960,13 @@ class EditObjectUI: op_text = "Add Void" if ui_context != "TOOL_HEADER" else "" op_icon = custom_icon_previews["ADD_VOID"].icon_id row = cls.layout.row(align=True) if ui_context != "TOOL_HEADER" else row + op = row.operator("bim.add_element", text=op_text, icon_value=op_icon) + op.ifc_product = "IfcFeatureElement" + op.ifc_class = "IfcOpeningElement" + op.skip_dialog = True + if ui_context != "TOOL_HEADER": + row.label(text="", icon="EVENT_SHIFT") + row.label(text="", icon="EVENT_O") if AuthoringData.data["is_voidable_element"]: if AuthoringData.data["has_visible_openings"]: @@ -1342,8 +1349,12 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator): bpy.ops.bim.add_boundary() def hotkey_S_O(self): - if len(bpy.context.selected_objects) == 2: + if len(bpy.context.selected_objects) > 1: bpy.ops.bim.add_opening() + else: + bpy.ops.bim.add_element( + "INVOKE_DEFAULT", ifc_product="IfcFeatureElement", ifc_class="IfcOpeningElement", skip_dialog=True + ) def hotkey_S_L(self): if AuthoringData.data["active_class"] in ("IfcOpeningElement",): diff --git a/src/bonsai/bonsai/bim/module/root/operator.py b/src/bonsai/bonsai/bim/module/root/operator.py index f4ac9dafc2..c204200a94 100644 --- a/src/bonsai/bonsai/bim/module/root/operator.py +++ b/src/bonsai/bonsai/bim/module/root/operator.py @@ -360,6 +360,7 @@ class AddElement(bpy.types.Operator, tool.Ifc.Operator): is_specific_tool: bpy.props.BoolProperty(default=False, options={"SKIP_SAVE"}) ifc_product: bpy.props.StringProperty(options={"SKIP_SAVE"}) ifc_class: bpy.props.StringProperty(options={"SKIP_SAVE"}) + skip_dialog: bpy.props.BoolProperty(default=False, options={"SKIP_SAVE"}) def invoke(self, context, event): return IfcStore.execute_ifc_operator(self, context, event, method="INVOKE") @@ -380,6 +381,8 @@ class AddElement(bpy.types.Operator, tool.Ifc.Operator): props.ifc_product = self.ifc_product if self.ifc_class: props.ifc_class = self.ifc_class + if self.skip_dialog: + return self.execute(context) return context.window_manager.invoke_props_dialog(self) def _execute(self, context): diff --git a/src/bonsai/bonsai/bim/module/root/prop.py b/src/bonsai/bonsai/bim/module/root/prop.py index e2d6cea330..5a9d4f9119 100644 --- a/src/bonsai/bonsai/bim/module/root/prop.py +++ b/src/bonsai/bonsai/bim/module/root/prop.py @@ -190,6 +190,7 @@ class BIMRootProperties(PropertyGroup): if TYPE_CHECKING: contexts: str + name: str description: str ifc_product: str ifc_class: str diff --git a/src/bonsai/bonsai/bim/module/void/operator.py b/src/bonsai/bonsai/bim/module/void/operator.py index 3274b974d7..dfa82de6a7 100644 --- a/src/bonsai/bonsai/bim/module/void/operator.py +++ b/src/bonsai/bonsai/bim/module/void/operator.py @@ -32,14 +32,16 @@ class AddOpening(bpy.types.Operator, tool.Ifc.Operator): bl_label = "Apply Opening" bl_options = {"REGISTER", "UNDO"} bl_description = ( - "Apply an Opening object on an Element. " - "The Element and the Opening to be applied should be selected. The order of selection is not important" + "Apply opening objects to an Element.\n\n" + "The Element and the openings to be applied should be selected. The order of selection is not important.\n" + "Opening can be just a Blender mesh object." ) @classmethod def poll(cls, context): if len(context.selected_objects) < 2: cls.poll_message_set("Select openings and a target element") + return False return True def _execute(self, context): diff --git a/src/bonsai/bonsai/bim/module/void/ui.py b/src/bonsai/bonsai/bim/module/void/ui.py index 66701510e3..bf22127762 100644 --- a/src/bonsai/bonsai/bim/module/void/ui.py +++ b/src/bonsai/bonsai/bim/module/void/ui.py @@ -52,9 +52,8 @@ class BIM_PT_voids(Panel): if not VoidsData.is_loaded: VoidsData.load() - if len(context.selected_objects) >= 2: - row = self.layout.row(align=True) - op = row.operator("bim.add_opening", icon="ADD", text="Add Opening") + row = self.layout.row(align=True) + op = row.operator("bim.add_opening", icon="ADD", text="Add Opening") if VoidsData.data["active_opening"]: row = self.layout.row()