From 816efc8810e50ffac15daae575d2699ff71d3a99 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Fri, 16 Jun 2023 13:24:26 +1000 Subject: [PATCH] Fetch pset and qto names via pset data instead of real time to prevent UI lag on larger models. --- .../blenderbim/bim/module/pset/data.py | 33 +++++++++++++++++ .../blenderbim/bim/module/pset/prop.py | 35 ++++++------------- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/pset/data.py b/src/blenderbim/blenderbim/bim/module/pset/data.py index 4e763fe276..f30f298dc7 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/data.py +++ b/src/blenderbim/blenderbim/bim/module/pset/data.py @@ -18,7 +18,9 @@ import bpy import ifcopenshell +import ifcopenshell.util.doc import blenderbim.tool as tool +import blenderbim.bim.schema # TODO: Should this cache belong here? Dunno. Maybe. @@ -67,6 +69,8 @@ class ObjectPsetsData(Data): cls.data = { "psets": cls.psetqtos(tool.Ifc.get_entity(bpy.context.active_object), psets_only=True), "inherited_psets": cls.inherited_psets(), + "pset_name": cls.pset_name(), + "qto_name": cls.qto_name(), } cls.is_loaded = True @@ -79,6 +83,35 @@ class ObjectPsetsData(Data): if element_type: return cls.psetqtos(element_type) + @classmethod + def pset_name(cls): + obj = bpy.context.active_object + element = tool.Ifc.get_entity(obj) + if not element: + return [] + psets = blenderbim.bim.schema.ifc.psetqto.get_applicable(element.is_a(), pset_only=True) + psetnames = cls.format_pset_enum(psets) + assigned_names = ifcopenshell.util.element.get_psets(element, psets_only=True).keys() + return [p for p in psetnames if p[0] not in assigned_names] + + @classmethod + def qto_name(cls): + obj = bpy.context.active_object + element = tool.Ifc.get_entity(obj) + if not element: + return [] + qtos = blenderbim.bim.schema.ifc.psetqto.get_applicable(element.is_a(), qto_only=True) + return cls.format_pset_enum(qtos) + + @classmethod + def format_pset_enum(cls, psets): + enum_items = [] + version = tool.Ifc.get_schema() + for pset in psets: + doc = ifcopenshell.util.doc.get_property_set_doc(version, pset.Name) or {} + enum_items.append((pset.Name, pset.Name, doc.get("description", ""))) + return enum_items + class ObjectQtosData(Data): data = {} diff --git a/src/blenderbim/blenderbim/bim/module/pset/prop.py b/src/blenderbim/blenderbim/bim/module/pset/prop.py index e3a97e466b..d60828a560 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/prop.py +++ b/src/blenderbim/blenderbim/bim/module/pset/prop.py @@ -22,7 +22,7 @@ import ifcopenshell import ifcopenshell.util.element import blenderbim.tool as tool from blenderbim.bim.prop import Attribute, StrProperty -from blenderbim.bim.module.pset.data import AddEditCustomPropertiesData +from blenderbim.bim.module.pset.data import AddEditCustomPropertiesData, ObjectPsetsData from blenderbim.bim.ifc import IfcStore from bpy.types import PropertyGroup from bpy.props import ( @@ -57,18 +57,10 @@ def blender_formatted_enum_from_psets(psets): return enum_items -def get_pset_names(self, context): - global psetnames - obj = context.active_object - if not obj.BIMObjectProperties.ifc_definition_id: - return [] - element = IfcStore.get_file().by_id(obj.BIMObjectProperties.ifc_definition_id) - ifc_class = element.is_a() - if ifc_class not in psetnames: - psets = blenderbim.bim.schema.ifc.psetqto.get_applicable(ifc_class, pset_only=True) - psetnames[ifc_class] = blender_formatted_enum_from_psets(psets) - assigned_names = ifcopenshell.util.element.get_psets(element, psets_only=True).keys() - return [p for p in psetnames[ifc_class] if p[0] not in assigned_names] +def get_pset_name(self, context): + if not ObjectPsetsData.is_loaded: + ObjectPsetsData.load() + return ObjectPsetsData.data["pset_name"] def get_material_pset_names(self, context): @@ -157,15 +149,10 @@ def get_work_schedule_pset_names(self, context): return psetnames[ifc_class] -def get_qto_names(self, context): - global qtonames - if "/" in context.active_object.name: - ifc_class = context.active_object.name.split("/")[0] - if ifc_class not in qtonames: - psets = blenderbim.bim.schema.ifc.psetqto.get_applicable(ifc_class, qto_only=True) - qtonames[ifc_class] = blender_formatted_enum_from_psets(psets) - return qtonames[ifc_class] - return [] +def get_qto_name(self, context): + if not ObjectPsetsData.is_loaded: + ObjectPsetsData.load() + return ObjectPsetsData.data["qto_name"] def get_template_type(self, context): @@ -197,8 +184,8 @@ class PsetProperties(PropertyGroup): active_pset_name: StringProperty(name="Pset Name") active_pset_type: StringProperty(name="Active Pset Type") properties: CollectionProperty(name="Properties", type=IfcProperty) - pset_name: EnumProperty(items=get_pset_names, name="Pset Name") - qto_name: EnumProperty(items=get_qto_names, name="Qto Name") + pset_name: EnumProperty(items=get_pset_name, name="Pset Name") + qto_name: EnumProperty(items=get_qto_name, name="Qto Name") class MaterialPsetProperties(PropertyGroup):