From 7e94388074b9fdc36f81d60172177f62c212deb9 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Wed, 21 Aug 2024 18:50:49 +1000 Subject: [PATCH] You can select a colourscheme key via search / dropdown now rather than typing a query --- src/bonsai/bonsai/bim/module/search/data.py | 21 +++++++++++++++++++ .../bonsai/bim/module/search/operator.py | 18 +++++++++++++--- src/bonsai/bonsai/bim/module/search/prop.py | 7 +++++++ src/bonsai/bonsai/bim/module/search/ui.py | 5 ++++- src/bonsai/bonsai/bim/operator.py | 2 ++ 5 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/search/data.py b/src/bonsai/bonsai/bim/module/search/data.py index 7dffbf06fe..f1985cb802 100644 --- a/src/bonsai/bonsai/bim/module/search/data.py +++ b/src/bonsai/bonsai/bim/module/search/data.py @@ -63,6 +63,7 @@ class ColourByPropertyData: cls.is_loaded = True cls.data = {} cls.data["saved_colourschemes"] = cls.saved_colourschemes() + cls.data["colourscheme_key"] = cls.colourscheme_key() @classmethod def saved_colourschemes(cls): @@ -81,6 +82,26 @@ class ColourByPropertyData: pass return [(str(g.id()), g.Name or "Unnamed", "") for g in sorted(results, key=lambda x: x.Name or "Unnamed")] + @classmethod + def colourscheme_key(cls): + obj = bpy.context.active_object + if not obj: + return [] + element = tool.Ifc.get_entity(obj) + if not element: + return [] + keys = [a.name() for a in element.wrapped_data.declaration().as_entity().all_attributes()] + psets = ifcopenshell.util.element.get_psets(element) + for pset, properties in psets.items(): + if pset.endswith("Common"): + keys.extend([f'/.*Common/."{name}"' for name in properties.keys() if name != "id"]) + elif pset.endswith("BaseQuantities"): + keys.extend([f'/.*BaseQuantities/."{name}"' for name in properties.keys() if name != "id"]) + else: + keys.extend([f"{pset}.{name}" for name in properties.keys() if name != "id"]) + results = [(k, k, "") for k in keys] + return [("QUERY", "Custom Query", "Specify a custom query to colour by"), None] + results + class SelectSimilarData: data = {} diff --git a/src/bonsai/bonsai/bim/module/search/operator.py b/src/bonsai/bonsai/bim/module/search/operator.py index 23b1501958..c585ef9553 100644 --- a/src/bonsai/bonsai/bim/module/search/operator.py +++ b/src/bonsai/bonsai/bim/module/search/operator.py @@ -249,7 +249,7 @@ class ColourByProperty(Operator): def _execute(self, context): props = context.scene.BIMSearchProperties - query = props.colourscheme_query + query = props.colourscheme_query if props.colourscheme_key == "QUERY" else props.colourscheme_key if not query: self.report({"ERROR"}, "No Query Provided") @@ -327,7 +327,13 @@ class ColourByProperty(Operator): areas[0].spaces[0].shading.color_type = "OBJECT" props.colourscheme.clear() - for value in natsorted(colourscheme.keys()): + + if is_qualitative: + keys = natsorted(colourscheme.keys()) + else: + keys = sorted(colourscheme.keys(), key=self.sort_quantitative_key) + + for value in keys: data = colourscheme[value] new = props.colourscheme.add() new.name = str(value) @@ -335,6 +341,12 @@ class ColourByProperty(Operator): new.colour = data["colour"][0:3] return {"FINISHED"} + def sort_quantitative_key(self, value): + try: + return (0, float(value)) + except ValueError: + return (1, value) + def store_state(self, context): if areas := [a for a in context.screen.areas if a.type == "VIEW_3D"]: self.transaction_data = {"area": areas[0], "color_type": areas[0].spaces[0].shading.color_type} @@ -360,7 +372,7 @@ class SelectByProperty(Operator): def execute(self, context): props = context.scene.BIMSearchProperties - query = props.colourscheme_query + query = props.colourscheme_query if props.colourscheme_key == "QUERY" else props.colourscheme_key if not query: self.report({"ERROR"}, "No Query Provided") diff --git a/src/bonsai/bonsai/bim/module/search/prop.py b/src/bonsai/bonsai/bim/module/search/prop.py index acf4b959d3..03d06a72a1 100644 --- a/src/bonsai/bonsai/bim/module/search/prop.py +++ b/src/bonsai/bonsai/bim/module/search/prop.py @@ -41,6 +41,12 @@ def get_element_key(self, context): return SelectSimilarData.data["element_key"] +def get_colourscheme_key(self, context): + if not ColourByPropertyData.is_loaded: + ColourByPropertyData.load() + return ColourByPropertyData.data["colourscheme_key"] + + def get_saved_searches(self, context): if not SearchData.is_loaded: SearchData.load() @@ -122,6 +128,7 @@ class BIMSearchProperties(PropertyGroup): ) saved_searches: EnumProperty(items=get_saved_searches, name="Saved Searches") saved_colourschemes: EnumProperty(items=get_saved_colourschemes, name="Saved Colourschemes") + colourscheme_key: EnumProperty(items=get_colourscheme_key, name="Colourscheme Key") colourscheme_query: StringProperty(name="Colourscheme Query", default="class") palette: EnumProperty( items=[ diff --git a/src/bonsai/bonsai/bim/module/search/ui.py b/src/bonsai/bonsai/bim/module/search/ui.py index f121bbc994..718817014e 100644 --- a/src/bonsai/bonsai/bim/module/search/ui.py +++ b/src/bonsai/bonsai/bim/module/search/ui.py @@ -83,7 +83,10 @@ class BIM_PT_colour_by_property(Panel): row.operator("bim.save_colourscheme", text="", icon="EXPORT") row = self.layout.row() - row.prop(props, "colourscheme_query", text="Query") + bonsai.bim.helper.prop_with_search(self.layout, props, "colourscheme_key", text="Colour By") + if props.colourscheme_key == "QUERY": + row = self.layout.row() + row.prop(props, "colourscheme_query", text="Query") row = self.layout.row() row.prop(props, "palette") diff --git a/src/bonsai/bonsai/bim/operator.py b/src/bonsai/bonsai/bim/operator.py index ff1d2ec605..ce3e753561 100644 --- a/src/bonsai/bonsai/bim/operator.py +++ b/src/bonsai/bonsai/bim/operator.py @@ -914,6 +914,8 @@ class BIM_OT_enum_property_search(bpy.types.Operator): def add_items_regular(self, items): self.identifiers = [] for item in items: + if item is None: # Used as a separator + continue self.identifiers.append(item[0]) self.add_item(identifier=item[0], name=item[1]) if item[0] == getattr(self.data, self.prop_name):