From 949a2bb3477b6d044a8ca35f4e0c44fb3005bedd Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sat, 8 Jul 2023 17:03:06 +1000 Subject: [PATCH] Start mocking up our own property "tabs" with the intention to use this new tab system instead of Blender property tabs Blender property tabs are hardcoded and we cannot customise them. IFC data only "somewhat" maps to Blender property tabs, and some things fail to map causing user confusion. For example material and styles are very confusing. Also scene and object properties are crazy overpopulated (see how many times IFCArchitect bulk collapses things). And this also causes things to be spread out and lost (e.g. some random panels in viewport N menu). This should give us a lot more control to organise panels exactly how we want them. --- src/blenderbim/blenderbim/bim/__init__.py | 3 ++ src/blenderbim/blenderbim/bim/handler.py | 7 +++ .../blenderbim/bim/module/brick/ui.py | 5 ++ src/blenderbim/blenderbim/bim/prop.py | 18 +++++++ src/blenderbim/blenderbim/bim/ui.py | 53 +++++++++++++++++-- 5 files changed, 81 insertions(+), 5 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/__init__.py b/src/blenderbim/blenderbim/bim/__init__.py index 5aff9b10da..bfece71d73 100644 --- a/src/blenderbim/blenderbim/bim/__init__.py +++ b/src/blenderbim/blenderbim/bim/__init__.py @@ -106,6 +106,7 @@ classes = [ prop.ObjProperty, prop.Attribute, prop.ModuleVisibility, + prop.BIMAreaProperties, prop.BIMProperties, prop.IfcParameter, prop.PsetQto, @@ -119,6 +120,7 @@ classes = [ ui.BIM_UL_topics, ui.BIM_ADDON_preferences, # Scene panel groups + ui.BIM_PT_root, ui.BIM_PT_project_info, ui.BIM_PT_project_setup, ui.BIM_PT_collaboration, @@ -159,6 +161,7 @@ def register(): bpy.app.handlers.load_post.append(handler.loadIfcStore) bpy.app.handlers.save_post.append(handler.ensureIfcExported) bpy.types.Scene.BIMProperties = bpy.props.PointerProperty(type=prop.BIMProperties) + bpy.types.Screen.BIMAreaProperties = bpy.props.CollectionProperty(type=prop.BIMAreaProperties) bpy.types.Collection.BIMCollectionProperties = bpy.props.PointerProperty(type=prop.BIMCollectionProperties) bpy.types.Object.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) bpy.types.Material.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) diff --git a/src/blenderbim/blenderbim/bim/handler.py b/src/blenderbim/blenderbim/bim/handler.py index 85f05eacab..bcf5990eb2 100644 --- a/src/blenderbim/blenderbim/bim/handler.py +++ b/src/blenderbim/blenderbim/bim/handler.py @@ -316,8 +316,15 @@ def setDefaultProperties(scene): "SCENE_PT_rigid_body_world", "SCENE_PT_audio", "SCENE_PT_keying_sets", + "SCENE_PT_custom_props", ]: try: bpy.utils.unregister_class(getattr(bpy.types, panel)) except: pass + + # https://blender.stackexchange.com/questions/140644/how-can-make-the-state-of-a-boolean-property-relative-to-the-3d-view-area + for screen in bpy.data.screens: + screen.BIMAreaProperties.clear() + for i in range(20): # 20 is an arbitrary value of split areas + screen.BIMAreaProperties.add() diff --git a/src/blenderbim/blenderbim/bim/module/brick/ui.py b/src/blenderbim/blenderbim/bim/module/brick/ui.py index 78f956f26f..008f53b4cd 100644 --- a/src/blenderbim/blenderbim/bim/module/brick/ui.py +++ b/src/blenderbim/blenderbim/bim/module/brick/ui.py @@ -30,6 +30,11 @@ class BIM_PT_brickschema(Panel): bl_region_type = "WINDOW" bl_context = "scene" + @classmethod + def poll(cls, context): + aprops = context.screen.BIMAreaProperties[context.screen.areas[:].index(context.area)] + return aprops.tab == "OTHER" + def draw(self, context): if not BrickschemaData.is_loaded: BrickschemaData.load() diff --git a/src/blenderbim/blenderbim/bim/prop.py b/src/blenderbim/blenderbim/bim/prop.py index 08e2c7d059..d192394b69 100644 --- a/src/blenderbim/blenderbim/bim/prop.py +++ b/src/blenderbim/blenderbim/bim/prop.py @@ -335,6 +335,24 @@ class ModuleVisibility(PropertyGroup): is_visible: BoolProperty(name="Value", default=True, update=update_is_visible) +class BIMAreaProperties(PropertyGroup): + tab: EnumProperty( + default="PROJECT", + items=[ + ("PROJECT", "Project Overview", "", "VIEW3D", 1), + ("OBJECT", "Object Information", "", "FILE_3D", 2), + ("MATERIALS", "Materials and Styles", "", "MATERIAL", 3), + ("DRAWINGS", "Drawings and Documents", "", "DOCUMENTS", 4), + ("SERVICES", "Services and Systems", "", "NETWORK_DRIVE", 5), + ("STRUCTURE", "Structural Analysis", "", "EDITMODE_HLT", 6), + ("SCHEDULING", "Construction Scheduling", "", "NLA", 7), + ("FM", "Facility Management", "", "PACKAGE", 8), + ("OTHER", "Other Properties", "", "COLLAPSEMENU", 9), + ], + name="Tab", + ) + + class BIMProperties(PropertyGroup): ui_preset: EnumProperty( name="UI Preset", diff --git a/src/blenderbim/blenderbim/bim/ui.py b/src/blenderbim/blenderbim/bim/ui.py index c0ef075f35..fa45fef756 100644 --- a/src/blenderbim/blenderbim/bim/ui.py +++ b/src/blenderbim/blenderbim/bim/ui.py @@ -281,12 +281,30 @@ def ifc_units(self, context): # Scene panel groups +class BIM_PT_root(Panel): + bl_label = "BlenderBIM Add-on" + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "scene" + bl_order = 0 + bl_options = {"HIDE_HEADER"} + + def draw(self, context): + aprops = context.screen.BIMAreaProperties[context.screen.areas[:].index(context.area)] + self.layout.prop(aprops, "tab", text="") + + class BIM_PT_project_info(Panel): bl_label = "IFC Project Info" bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "scene" + @classmethod + def poll(cls, context): + aprops = context.screen.BIMAreaProperties[context.screen.areas[:].index(context.area)] + return aprops.tab == "PROJECT" + def draw(self, context): pass @@ -298,6 +316,11 @@ class BIM_PT_project_setup(Panel): bl_context = "scene" bl_options = {"DEFAULT_CLOSED"} + @classmethod + def poll(cls, context): + aprops = context.screen.BIMAreaProperties[context.screen.areas[:].index(context.area)] + return aprops.tab == "PROJECT" + def draw(self, context): pass @@ -309,6 +332,11 @@ class BIM_PT_collaboration(Panel): bl_context = "scene" bl_options = {"DEFAULT_CLOSED"} + @classmethod + def poll(cls, context): + aprops = context.screen.BIMAreaProperties[context.screen.areas[:].index(context.area)] + return aprops.tab == "OTHER" + def draw(self, context): pass @@ -322,7 +350,8 @@ class BIM_PT_selection(Panel): @classmethod def poll(cls, context): - return tool.Ifc.get() + aprops = context.screen.BIMAreaProperties[context.screen.areas[:].index(context.area)] + return aprops.tab == "PROJECT" and tool.Ifc.get() def draw(self, context): pass @@ -337,7 +366,8 @@ class BIM_PT_geometry(Panel): @classmethod def poll(cls, context): - return tool.Ifc.get() + aprops = context.screen.BIMAreaProperties[context.screen.areas[:].index(context.area)] + return aprops.tab == "PROJECT" and tool.Ifc.get() def draw(self, context): pass @@ -352,7 +382,8 @@ class BIM_PT_4D5D(Panel): @classmethod def poll(cls, context): - return tool.Ifc.get() + aprops = context.screen.BIMAreaProperties[context.screen.areas[:].index(context.area)] + return aprops.tab == "SCHEDULING" and tool.Ifc.get() def draw(self, context): pass @@ -367,7 +398,8 @@ class BIM_PT_structural(Panel): @classmethod def poll(cls, context): - return tool.Ifc.get() + aprops = context.screen.BIMAreaProperties[context.screen.areas[:].index(context.area)] + return aprops.tab == "STRUCTURE" and tool.Ifc.get() def draw(self, context): pass @@ -382,7 +414,8 @@ class BIM_PT_services(Panel): @classmethod def poll(cls, context): - return tool.Ifc.get() + aprops = context.screen.BIMAreaProperties[context.screen.areas[:].index(context.area)] + return aprops.tab == "SERVICES" and tool.Ifc.get() def draw(self, context): pass @@ -395,6 +428,11 @@ class BIM_PT_quality_control(Panel): bl_context = "scene" bl_options = {"DEFAULT_CLOSED"} + @classmethod + def poll(cls, context): + aprops = context.screen.BIMAreaProperties[context.screen.areas[:].index(context.area)] + return aprops.tab == "OTHER" + def draw(self, context): pass @@ -406,6 +444,11 @@ class BIM_PT_integrations(Panel): bl_context = "scene" bl_options = {"DEFAULT_CLOSED"} + @classmethod + def poll(cls, context): + aprops = context.screen.BIMAreaProperties[context.screen.areas[:].index(context.area)] + return aprops.tab == "OTHER" + def draw(self, context): pass