From 847f0890e0536129bc5c54c1a4d131fc17b96e32 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 23 Nov 2023 14:59:26 +1100 Subject: [PATCH] Fix #3691. Add toggle for power users to disable the BIM toolbar if an IFC isn't loaded. --- src/blenderbim/blenderbim/bim/handler.py | 3 + src/blenderbim/blenderbim/bim/helper.py | 11 +++- .../blenderbim/bim/module/model/workspace.py | 1 - .../blenderbim/bim/module/project/operator.py | 2 + src/blenderbim/blenderbim/bim/ui.py | 3 + src/blenderbim/blenderbim/tool/blender.py | 59 ++++++++++++++++++- 6 files changed, 75 insertions(+), 4 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/handler.py b/src/blenderbim/blenderbim/bim/handler.py index a2d54c47c2..729ba5071f 100644 --- a/src/blenderbim/blenderbim/bim/handler.py +++ b/src/blenderbim/blenderbim/bim/handler.py @@ -356,6 +356,9 @@ def load_post(scene): ifcopenshell.api.owner.settings.get_application = get_application AuthoringData.type_thumbnails = {} + if not bpy.context.preferences.addons["blenderbim"].preferences.should_setup_toolbar: + tool.Blender.unregister_toolbar() + if bpy.context.preferences.addons["blenderbim"].preferences.should_setup_workspace: if "BIM" in bpy.data.workspaces: bpy.context.window.workspace = bpy.data.workspaces["BIM"] diff --git a/src/blenderbim/blenderbim/bim/helper.py b/src/blenderbim/blenderbim/bim/helper.py index 96b1d3ddda..22b5f9f4e6 100644 --- a/src/blenderbim/blenderbim/bim/helper.py +++ b/src/blenderbim/blenderbim/bim/helper.py @@ -87,8 +87,15 @@ def import_attributes(ifc_class, props, data, callback=None): # A more elegant attribute importer signature, intended to supersede import_attributes def import_attributes2(element, props, callback=None): - for attribute in element.wrapped_data.declaration().as_entity().all_attributes(): - import_attribute(attribute, props, element.get_info(), callback=callback) + if isinstance(element, str): + attributes = tool.Ifc.schema().declaration_by_name(element).as_entity().all_attributes() + info = {a.name(): None for a in attributes} + info["type"] = element + else: + attributes = element.wrapped_data.declaration().as_entity().all_attributes() + info = element.get_info() + for attribute in attributes: + import_attribute(attribute, props, info, callback=callback) def import_attribute(attribute, props, data, callback=None): diff --git a/src/blenderbim/blenderbim/bim/module/model/workspace.py b/src/blenderbim/blenderbim/bim/module/model/workspace.py index 03c76396a6..1fd3ef4ebe 100644 --- a/src/blenderbim/blenderbim/bim/module/model/workspace.py +++ b/src/blenderbim/blenderbim/bim/module/model/workspace.py @@ -434,7 +434,6 @@ class BimToolUI: row.label(text="", icon="EVENT_SHIFT") row.label(text="", icon="EVENT_L") row.operator("bim.clone_opening", text="Clone Opening") - cls.layout.row(align=True).label(text="Align") add_layout_hotkey_operator(cls.layout, "Align Exterior", "S_X", "") diff --git a/src/blenderbim/blenderbim/bim/module/project/operator.py b/src/blenderbim/blenderbim/bim/module/project/operator.py index 872d5b918a..7b1385bd39 100644 --- a/src/blenderbim/blenderbim/bim/module/project/operator.py +++ b/src/blenderbim/blenderbim/bim/module/project/operator.py @@ -106,6 +106,7 @@ class CreateProject(bpy.types.Operator): for obj in bpy.data.objects: bpy.data.objects.remove(obj) core.create_project(tool.Ifc, tool.Project, schema=props.export_schema, template=template) + tool.Blender.register_toolbar() def rollback(self, data): IfcStore.file = None @@ -651,6 +652,7 @@ class LoadProject(bpy.types.Operator, IFCFileSelector): context.scene.BIMProperties.ifc_file = self.get_filepath() context.scene.BIMProjectProperties.is_loading = True context.scene.BIMProjectProperties.total_elements = len(tool.Ifc.get().by_type("IfcElement")) + tool.Blender.register_toolbar() if not self.is_advanced: bpy.ops.bim.load_project_elements() return {"FINISHED"} diff --git a/src/blenderbim/blenderbim/bim/ui.py b/src/blenderbim/blenderbim/bim/ui.py index f1d8301db8..ee896d24dc 100644 --- a/src/blenderbim/blenderbim/bim/ui.py +++ b/src/blenderbim/blenderbim/bim/ui.py @@ -138,6 +138,7 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences): openlca_port: IntProperty(name="OpenLCA IPC Port", default=8080) should_hide_empty_props: BoolProperty(name="Should Hide Empty Properties", default=True) should_setup_workspace: BoolProperty(name="Should Setup Workspace Layout for BIM", default=True) + should_setup_toolbar: BoolProperty(name="Always Show Toolbar In 3D Viewport", default=True, description="If disabled, the toolbar will only load when an IFC model is active") should_play_chaching_sound: BoolProperty( name="Should Make A Cha-Ching Sound When Project Costs Updates", default=False ) @@ -218,6 +219,8 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences): row = layout.row() row.prop(self, "should_setup_workspace") row = layout.row() + row.prop(self, "should_setup_toolbar") + row = layout.row() row.prop(self, "should_play_chaching_sound") row = layout.row() row.prop(self, "lock_grids_on_import") diff --git a/src/blenderbim/blenderbim/tool/blender.py b/src/blenderbim/blenderbim/tool/blender.py index 59b79b9e57..18a09ab0db 100644 --- a/src/blenderbim/blenderbim/tool/blender.py +++ b/src/blenderbim/blenderbim/tool/blender.py @@ -202,7 +202,6 @@ class Blender: @classmethod def copy_node_graph(cls, material_to, material_from): - # https://projects.blender.org/blender/blender/issues/108763 if bpy.app.version >= (4, 0): print( @@ -643,3 +642,61 @@ class Blender: if blenderbim.bim.last_commit_hash != "8888888": version += f"-{blenderbim.bim.last_commit_hash[:7]}" return version + + @classmethod + def register_toolbar(cls): + import blenderbim.bim.module.model.workspace as ws_model + import blenderbim.bim.module.drawing.workspace as ws_drawing + import blenderbim.bim.module.spatial.workspace as ws_spatial + import blenderbim.bim.module.structural.workspace as ws_structural + import blenderbim.bim.module.covering.workspace as ws_covering + + if bpy.app.background: + return + + try: + bpy.utils.register_tool(ws_model.WallTool, after={"builtin.transform"}, separator=True, group=False) + bpy.utils.register_tool(ws_model.SlabTool, after={"bim.wall_tool"}, separator=False, group=False) + bpy.utils.register_tool(ws_model.DoorTool, after={"bim.slab_tool"}, separator=False, group=False) + bpy.utils.register_tool(ws_model.WindowTool, after={"bim.door_tool"}, separator=False, group=False) + bpy.utils.register_tool(ws_model.ColumnTool, after={"bim.window_tool"}, separator=False, group=False) + bpy.utils.register_tool(ws_model.BeamTool, after={"bim.column_tool"}, separator=False, group=False) + bpy.utils.register_tool(ws_model.DuctTool, after={"bim.beam_tool"}, separator=False, group=False) + bpy.utils.register_tool(ws_model.PipeTool, after={"bim.duct_tool"}, separator=False, group=False) + bpy.utils.register_tool(ws_model.BimTool, after={"bim.pipe_tool"}, separator=False, group=False) + bpy.utils.register_tool(ws_drawing.AnnotationTool, after={"bim.bim_tool"}, separator=True, group=False) + bpy.utils.register_tool(ws_spatial.SpatialTool, after={"bim.annotation_tool"}, separator=False, group=False) + bpy.utils.register_tool( + ws_structural.StructuralTool, after={"bim.spatial_tool"}, separator=False, group=False + ) + bpy.utils.register_tool(ws_covering.CoveringTool, after={"bim.structural_tool"}, separator=False, group=False) + except: + pass + + @classmethod + def unregister_toolbar(cls): + import blenderbim.bim.module.model.workspace as ws_model + import blenderbim.bim.module.drawing.workspace as ws_drawing + import blenderbim.bim.module.spatial.workspace as ws_spatial + import blenderbim.bim.module.structural.workspace as ws_structural + import blenderbim.bim.module.covering.workspace as ws_covering + + if bpy.app.background: + return + + try: + bpy.utils.unregister_tool(ws_model.WallTool) + bpy.utils.unregister_tool(ws_model.SlabTool) + bpy.utils.unregister_tool(ws_model.DoorTool) + bpy.utils.unregister_tool(ws_model.WindowTool) + bpy.utils.unregister_tool(ws_model.ColumnTool) + bpy.utils.unregister_tool(ws_model.BeamTool) + bpy.utils.unregister_tool(ws_model.DuctTool) + bpy.utils.unregister_tool(ws_model.PipeTool) + bpy.utils.unregister_tool(ws_model.BimTool) + bpy.utils.unregister_tool(ws_drawing.AnnotationTool) + bpy.utils.unregister_tool(ws_spatial.SpatialTool) + bpy.utils.unregister_tool(ws_structural.StructuralTool) + bpy.utils.unregister_tool(ws_covering.CoveringTool) + except: + pass