diff --git a/src/bonsai/bonsai/bim/module/model/__init__.py b/src/bonsai/bonsai/bim/module/model/__init__.py index df181799bd..cb18de504c 100644 --- a/src/bonsai/bonsai/bim/module/model/__init__.py +++ b/src/bonsai/bonsai/bim/module/model/__init__.py @@ -63,6 +63,7 @@ classes = ( product.EnableAddType, product.LoadTypeThumbnails, product.MirrorElements, + product.SetActiveType, workspace.Hotkey, workspace.BIM_MT_add_representation_item, wall.AlignWall, diff --git a/src/bonsai/bonsai/bim/module/model/data.py b/src/bonsai/bonsai/bim/module/model/data.py index 7d391fbd8f..168aa4f4a2 100644 --- a/src/bonsai/bonsai/bim/module/model/data.py +++ b/src/bonsai/bonsai/bim/module/model/data.py @@ -57,6 +57,7 @@ class AuthoringData: cls.data["ifc_element_type"] = cls.ifc_element_type cls.data["ifc_classes"] = cls.ifc_classes() cls.data["relating_type_id"] = cls.relating_type_id() # only after .ifc_classes() + cls.data["relating_type_name"] = cls.relating_type_name() # only after .relating_type_id() cls.data["predefined_type"] = cls.predefined_type() # only after .relating_type_id() cls.data["type_class"] = cls.type_class() @@ -325,6 +326,11 @@ class AuthoringData: return [(str(e.id()), e.Name or "Unnamed", e.Description or "") for e in results] return [] + @classmethod + def relating_type_name(cls): + if relating_type_id := cls.props.relating_type_id: + return tool.Ifc.get().by_id(int(relating_type_id)).Name or "Unnamed" + @classmethod def predefined_type(cls): relating_type_id = tool.Blender.get_enum_safe(cls.props, "relating_type_id") diff --git a/src/bonsai/bonsai/bim/module/model/product.py b/src/bonsai/bonsai/bim/module/model/product.py index 220d246e88..61dccea5b3 100644 --- a/src/bonsai/bonsai/bim/module/model/product.py +++ b/src/bonsai/bonsai/bim/module/model/product.py @@ -312,6 +312,18 @@ class ChangeTypePage(bpy.types.Operator, tool.Ifc.Operator): return {"FINISHED"} +class SetActiveType(bpy.types.Operator, tool.Ifc.Operator): + bl_idname = "bim.set_active_type" + bl_label = "Set Active Type" + bl_options = {"REGISTER"} + relating_type: bpy.props.IntProperty() + + def _execute(self, context): + props = context.scene.BIMModelProperties + props.relating_type_id = str(self.relating_type) + context.window.screen = context.window.screen # Closes the type manager popup + + class AlignProduct(bpy.types.Operator): bl_idname = "bim.align_product" bl_label = "Align Product" diff --git a/src/bonsai/bonsai/bim/module/model/prop.py b/src/bonsai/bonsai/bim/module/model/prop.py index 07b7be06a8..fa7817042e 100644 --- a/src/bonsai/bonsai/bim/module/model/prop.py +++ b/src/bonsai/bonsai/bim/module/model/prop.py @@ -86,6 +86,7 @@ def update_type_class(self, context): def update_relating_type_id(self, context): AuthoringData.data["relating_type_id"] = AuthoringData.relating_type_id() + AuthoringData.data["relating_type_name"] = AuthoringData.relating_type_name() AuthoringData.data["type_thumbnail"] = AuthoringData.type_thumbnail() AuthoringData.data["predefined_type"] = AuthoringData.predefined_type() @@ -172,9 +173,7 @@ class BIMModelProperties(PropertyGroup): rl3: bpy.props.FloatProperty(name="RL", default=1, subtype="DISTANCE", description="Z offset for space calculation") x_angle: bpy.props.FloatProperty(name="X Angle", default=0, subtype="ANGLE", min=-pi / 180 * 89, max=pi / 180 * 89) type_page: bpy.props.IntProperty(name="Type Page", default=1, update=update_type_page) - # fmt: off - type_template: bpy.props.EnumProperty(items=get_type_template, name="Type Template", default=0) - # fmt: on + type_template: bpy.props.EnumProperty(items=get_type_template, name="Type Template", default=0, options=set()) type_class: bpy.props.EnumProperty(items=get_type_class, name="IFC Class", update=update_type_class) type_predefined_type: bpy.props.EnumProperty(items=get_type_predefined_type, name="Predefined Type", default=None) type_name: bpy.props.StringProperty(name="Name", default="TYPEX") diff --git a/src/bonsai/bonsai/bim/module/model/ui.py b/src/bonsai/bonsai/bim/module/model/ui.py index e154b84fc2..272f139ccc 100644 --- a/src/bonsai/bonsai/bim/module/model/ui.py +++ b/src/bonsai/bonsai/bim/module/model/ui.py @@ -70,7 +70,9 @@ class LaunchTypeManager(bpy.types.Operator): if ifc_class is not None: props.type_class = ifc_class bpy.ops.bim.load_type_thumbnails(ifc_class=ifc_class, offset=0, limit=9) - return context.window_manager.invoke_popup(self, width=550) + return context.window_manager.invoke_props_dialog( + self, width=550, title="Type Manager", confirm_text="Add Type" + ) def draw(self, context): props = context.scene.BIMModelProperties @@ -124,16 +126,26 @@ class LaunchTypeManager(bpy.types.Operator): row = box.row() row.alignment = "CENTER" - row.label(text=relating_type["name"], icon="FILE_3D") + op = row.operator("bim.set_active_type", text=relating_type["name"], icon="FILE_3D", emboss=False) + op.relating_type = relating_type["id"] row = box.row() row.alignment = "CENTER" - row.label(text=relating_type["description"]) + op = row.operator("bim.set_active_type", text=relating_type["description"], emboss=False) + op.relating_type = relating_type["id"] - row = box.row() if relating_type["icon_id"]: - row.template_icon(icon_value=relating_type["icon_id"], scale=4) + # Yep, that's EXACTLY how it's done. And I'm proud of it. + row1 = box.row() + row1.ui_units_y = 0.01 + row1.template_icon(icon_value=relating_type["icon_id"], scale=4) + row2 = box.column(align=True) + row2.operator("bim.set_active_type", text="", emboss=False).relating_type = relating_type["id"] + row2.operator("bim.set_active_type", text="", emboss=False).relating_type = relating_type["id"] + row2.operator("bim.set_active_type", text="", emboss=False).relating_type = relating_type["id"] + row2.operator("bim.set_active_type", text="", emboss=False).relating_type = relating_type["id"] else: + row = box.row() op = box.operator("bim.load_type_thumbnails", text="Load Thumbnails", icon="FILE_REFRESH") op.ifc_class = props.type_class diff --git a/src/bonsai/bonsai/bim/module/model/workspace.py b/src/bonsai/bonsai/bim/module/model/workspace.py index eb54f99dfa..552450fd63 100644 --- a/src/bonsai/bonsai/bim/module/model/workspace.py +++ b/src/bonsai/bonsai/bim/module/model/workspace.py @@ -431,11 +431,12 @@ class CreateObjectUI: row = cls.layout.row(align=True) if ui_context != "TOOL_HEADER" else row prop_with_search(row, cls.props, "ifc_class", text="Type Class" if ui_context != "TOOL_HEADER" else "") if AuthoringData.data["relating_type_id"]: - row = cls.layout.row(align=True) if ui_context != "TOOL_HEADER" else row - prop_with_search( - row, cls.props, "relating_type_id", text="Relating Type" if ui_context != "TOOL_HEADER" else "" + row = cls.layout.row(align=True) + row.operator( + "bim.launch_type_manager", + icon=tool.Blender.TYPE_MANAGER_ICON, + text="Type: " + AuthoringData.data["relating_type_name"], ) - row.operator("bim.launch_type_manager", icon=tool.Blender.TYPE_MANAGER_ICON, text="") row = cls.layout.row(align=True) if ui_context != "TOOL_HEADER" else row add_layout_hotkey_operator(row, "Add", "S_A", bpy.ops.bim.add_constr_type_instance.__doc__, ui_context) row = cls.layout.row(align=True) if ui_context != "TOOL_HEADER" else row