From 850a1d326bfc73288ae91d010f9ad81ff3098211 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 13 Apr 2023 21:39:26 +1000 Subject: [PATCH] Purge old code from timer-based type browser system --- .../blenderbim/bim/module/cad/prop.py | 1 - .../blenderbim/bim/module/model/__init__.py | 4 - .../blenderbim/bim/module/model/data.py | 165 +----------------- .../blenderbim/bim/module/model/prop.py | 119 +------------ .../blenderbim/bim/module/model/root.py | 5 - .../blenderbim/bim/module/model/ui.py | 53 ------ .../blenderbim/bim/module/model/workspace.py | 4 +- 7 files changed, 18 insertions(+), 333 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/cad/prop.py b/src/blenderbim/blenderbim/bim/module/cad/prop.py index 5ad09cf61d..6f760169c8 100644 --- a/src/blenderbim/blenderbim/bim/module/cad/prop.py +++ b/src/blenderbim/blenderbim/bim/module/cad/prop.py @@ -18,7 +18,6 @@ import bpy from blenderbim.bim.module.model.data import AuthoringData -from blenderbim.bim.module.model.root import ConstrTypeEntityNotFound from bpy.types import PropertyGroup from math import pi diff --git a/src/blenderbim/blenderbim/bim/module/model/__init__.py b/src/blenderbim/blenderbim/bim/module/model/__init__.py index 48cf759114..3fb2595179 100644 --- a/src/blenderbim/blenderbim/bim/module/model/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/model/__init__.py @@ -96,9 +96,6 @@ classes = ( slab.ResetVertex, slab.SetArcIndex, space.GenerateSpace, - prop.ConstrTypeInfo, - prop.ConstrClassInfo, - prop.ConstrBrowserState, prop.BIMModelProperties, prop.BIMArrayProperties, prop.BIMStairProperties, @@ -116,7 +113,6 @@ classes = ( ui.BIM_PT_railing, ui.BIM_PT_roof, ui.LaunchTypeManager, - ui.HelpConstrTypes, ui.BIM_MT_model, grid.BIM_OT_add_object, stair.BIM_OT_add_object, diff --git a/src/blenderbim/blenderbim/bim/module/model/data.py b/src/blenderbim/blenderbim/bim/module/model/data.py index 61a99eef7b..8e90bfa59e 100644 --- a/src/blenderbim/blenderbim/bim/module/model/data.py +++ b/src/blenderbim/blenderbim/bim/module/model/data.py @@ -24,8 +24,6 @@ import ifcopenshell import ifcopenshell.util.element from ifcopenshell.util.doc import get_entity_doc, get_predefined_type_doc import blenderbim.tool as tool -from blenderbim.bim.ifc import IfcStore -from blenderbim.bim.module.model.root import ConstrTypeEntityNotFound def refresh(): @@ -49,9 +47,8 @@ class AuthoringData: def load(cls): cls.is_loaded = True cls.props = bpy.context.scene.BIMModelProperties - cls.load_ifc_classes() - cls.load_relating_types() - cls.load_relating_types_browser() + cls.data["ifc_classes"] = cls.ifc_classes() + cls.data["relating_type_id"] = cls.relating_type_id() cls.data["type_class"] = cls.type_class() cls.data["type_predefined_type"] = cls.type_predefined_type() cls.data["total_types"] = cls.total_types() @@ -100,23 +97,11 @@ class AuthoringData: @classmethod def type_thumbnail(cls): - if not cls.data["relating_types_ids"]: + if not cls.data["relating_type_id"]: return 0 element = tool.Ifc.get().by_id(int(cls.props.relating_type_id)) return cls.type_thumbnails.get(element.id(), None) or 0 - @classmethod - def load_ifc_classes(cls): - cls.data["ifc_classes"] = cls.ifc_classes() - - @classmethod - def load_relating_types(cls): - cls.data["relating_types_ids"] = cls.relating_types() - - @classmethod - def load_relating_types_browser(cls): - cls.data["relating_types_ids_browser"] = cls.relating_types_browser() - @classmethod def total_types(cls): type_class = cls.props.type_class @@ -210,155 +195,23 @@ class AuthoringData: return results @classmethod - def constr_class_entities(cls, ifc_class=None): + def relating_type_id(cls): ifc_classes = cls.data["ifc_classes"] if not ifc_classes: return [] results = [] - if ifc_class is None: - ifc_class = cls.props.ifc_class + ifc_class = cls.props.ifc_class if not ifc_class and ifc_classes: ifc_class = ifc_classes[0][0] if ifc_class: elements = sorted(tool.Ifc.get().by_type(ifc_class), key=lambda s: s.Name or "Unnamed") results.extend(elements) - return results + return [ + (str(e.id()), e.Name or "Unnamed", e.Description or "") + for e in results + ] return [] - @classmethod - def relating_types(cls, ifc_class=None): - return [ - (str(e.id()), e.Name or "Unnamed", e.Description or "") - for e in cls.constr_class_entities(ifc_class=ifc_class) - ] - - @classmethod - def relating_types_browser(cls): - if cls.data["ifc_classes"]: - return cls.relating_types(ifc_class=cls.props.ifc_class_browser) - - @classmethod - def new_constr_class_info(cls, ifc_class): - if ifc_class not in cls.props.constr_classes: - cls.props.constr_classes.add().name = ifc_class - return cls.props.constr_classes[ifc_class] - - @classmethod - def assetize_constr_class(cls, ifc_class=None): - selected_ifc_class = cls.props.ifc_class - selected_relating_type_id = cls.props.relating_type_id - if ifc_class is None: - ifc_class = cls.props.ifc_class_browser - if cls.constr_class_info(ifc_class) is None: - cls.new_constr_class_info(ifc_class) - constr_class_occurrences = cls.constr_class_entities(ifc_class) - constr_classes = cls.props.constr_classes - - for constr_class_entity in constr_class_occurrences: - if ( - ifc_class not in constr_classes - or constr_class_entity.Name not in constr_classes[ifc_class].constr_types - ): - obj = tool.Ifc.get_object(constr_class_entity) - cls.assetize_object(obj, ifc_class, constr_class_entity) - cls.constr_class_info(ifc_class).fully_loaded = True - cls.props.updating = True - cls.props.ifc_class = selected_ifc_class - cls.props.relating_type_id = selected_relating_type_id - cls.props.updating = False - - @classmethod - def assetize_object(cls, obj, ifc_class, ifc_class_entity, from_selection=False): - relating_type_id = ifc_class_entity.id() - to_be_deleted = False - if obj.type == "EMPTY": - kwargs = {} - if not from_selection: - kwargs.update({"ifc_class": ifc_class, "relating_type_id": relating_type_id}) - new_obj = cls.new_relating_type(**kwargs) - if new_obj is not None: - to_be_deleted = True - obj = new_obj - obj.hide_set(True) - obj.asset_mark() - obj.asset_generate_preview() - blender33_or_above = bpy.app.version >= (3, 3, 0) - interval = 1e-4 - - def wait_for_asset_previews_generation(check_interval_seconds=interval): - if blender33_or_above and bpy.app.is_job_running("RENDER_PREVIEW"): - return check_interval_seconds - else: - if ifc_class not in cls.props.constr_classes: - cls.props.constr_classes.add().name = ifc_class - constr_class_info = cls.props.constr_classes[ifc_class] - # relating_type = cls.relating_type_name_by_id(ifc_class, relating_type_id) - if str(relating_type_id) not in constr_class_info.constr_types: - constr_class_info.constr_types.add().name = str(relating_type_id) - relating_type_info = constr_class_info.constr_types[str(relating_type_id)] - relating_type_info.object = obj - relating_type_info.icon_id = obj.preview.icon_id - - if to_be_deleted: - element = tool.Ifc.get_entity(obj) - if element: - tool.Ifc.delete(element) - tool.Ifc.unlink(obj=obj) - for collection in obj.users_collection: - collection.objects.unlink(obj) - return None - - first_interval = 0 if blender33_or_above else interval - bpy.app.timers.register(wait_for_asset_previews_generation, first_interval=first_interval) - - @classmethod - def assetize_relating_type_from_selection(cls, browser=False): - ifc_class = cls.props.ifc_class_browser if browser else cls.props.ifc_class - relating_type_id = cls.props.relating_type_id_browser if browser else cls.props.relating_type_id - constr_class_occurrences = cls.constr_class_entities(ifc_class=ifc_class) - constr_class_occurrences = [ - entity for entity in constr_class_occurrences if entity.id() == int(relating_type_id) - ] - if len(constr_class_occurrences) == 0: - raise ConstrTypeEntityNotFound() - constr_class_entity = constr_class_occurrences[0] - if (obj := tool.Ifc.get_object(constr_class_entity)) is None: - raise ConstrTypeEntityNotFound() - cls.assetize_object(obj, ifc_class, constr_class_entity, from_selection=True) - - @staticmethod - def constr_class_info(ifc_class): - props = bpy.context.scene.BIMModelProperties - return props.constr_classes[ifc_class] if ifc_class in props.constr_classes else None - - @classmethod - def new_relating_type(cls, ifc_class=None, relating_type_id=None): - if ifc_class is None: - bpy.ops.bim.add_constr_type_instance( - ifc_class=cls.props.ifc_class, relating_type_id=int(cls.props.relating_type_id) - ) - else: - cls.props.updating = True - cls.props.ifc_class = ifc_class - cls.props.relating_type_id = str(relating_type_id) - cls.props.updating = False - bpy.ops.bim.add_constr_type_instance() - return bpy.context.selected_objects[-1] - - @staticmethod - def relating_type_name_by_id(ifc_class, relating_type_id): - file = IfcStore.get_file() - try: - constr_class_entity = file.by_id(int(relating_type_id)) - except (RuntimeError, ValueError): - return None - return constr_class_entity.Name if constr_class_entity.is_a() == ifc_class else None - - @classmethod - def relating_type_id_by_name(cls, ifc_class, relating_type): - relating_types = [ct[0] for ct in cls.relating_types(ifc_class=ifc_class) if ct[1] == relating_type] - return None if len(relating_types) == 0 else relating_types[0] - class ArrayData: data = {} diff --git a/src/blenderbim/blenderbim/bim/module/model/prop.py b/src/blenderbim/blenderbim/bim/module/model/prop.py index 97e85b3b85..077fe02f85 100644 --- a/src/blenderbim/blenderbim/bim/module/model/prop.py +++ b/src/blenderbim/blenderbim/bim/module/model/prop.py @@ -21,7 +21,6 @@ import ifcopenshell import blenderbim.tool as tool from blenderbim.bim.prop import ObjProperty from blenderbim.bim.module.model.data import AuthoringData -from blenderbim.bim.module.model.root import ConstrTypeEntityNotFound from bpy.types import PropertyGroup, NodeTree from math import pi @@ -38,16 +37,10 @@ def get_type_class(self, context): return AuthoringData.data["type_class"] -def get_relating_type(self, context): +def get_relating_type_id(self, context): if not AuthoringData.is_loaded: AuthoringData.load() - return AuthoringData.data["relating_types_ids"] - - -def get_relating_type_browser(self, context): - if not AuthoringData.is_loaded: - AuthoringData.load() - return AuthoringData.data["relating_types_ids_browser"] + return AuthoringData.data["relating_type_id"] def get_type_predefined_type(self, context): @@ -56,33 +49,9 @@ def get_type_predefined_type(self, context): return AuthoringData.data["type_predefined_type"] -def update_icon_id(self, context, browser=False): - if context == "lost_context" or (context.region is not None and context.region.type != "TOOL_HEADER"): - ifc_class = self.ifc_class_browser if browser else self.ifc_class - relating_type_id = self.relating_type_id_browser if browser else self.relating_type_id - # relating_type = AuthoringData.relating_type_name_by_id(ifc_class, relating_type_id) - - if ifc_class not in self.constr_classes or relating_type_id not in self.constr_classes[ifc_class].constr_types: - try: - AuthoringData.assetize_relating_type_from_selection(browser=browser) - except ConstrTypeEntityNotFound: - return - - def set_icon(update_interval_seconds=1e-4): - if ( - ifc_class not in self.constr_classes - or relating_type_id not in self.constr_classes[ifc_class].constr_types - ): - return update_interval_seconds - else: - self.icon_id = self.constr_classes[ifc_class].constr_types[relating_type_id].icon_id - - bpy.app.timers.register(set_icon) - - def update_ifc_class(self, context): bpy.ops.bim.load_type_thumbnails(ifc_class=self.ifc_class) - AuthoringData.data["relating_types_ids"] = AuthoringData.relating_types() + AuthoringData.data["relating_type_id"] = AuthoringData.relating_types() AuthoringData.data["type_thumbnail"] = AuthoringData.type_thumbnail() @@ -95,21 +64,8 @@ def update_type_class(self, context): AuthoringData.data["type_predefined_type"] = AuthoringData.type_predefined_type() -def update_ifc_class_browser(self, context): - if context.region is not None and context.region.type != "TOOL_HEADER": - AuthoringData.load_ifc_classes() - AuthoringData.load_relating_types_browser() - if self.updating: - return - ifc_class = self.ifc_class_browser - constr_class_info = AuthoringData.constr_class_info(ifc_class) - - if constr_class_info is None or not constr_class_info.fully_loaded: - AuthoringData.assetize_constr_class(ifc_class) - - -def update_relating_type(self, context): - AuthoringData.load_relating_types() +def update_relating_type_id(self, context): + AuthoringData.data["relating_type_id"] = AuthoringData.relating_type_id() AuthoringData.data["type_thumbnail"] = AuthoringData.type_thumbnail() @@ -117,80 +73,19 @@ def update_type_page(self, context): AuthoringData.data["paginated_relating_types"] = AuthoringData.paginated_relating_types() -def update_relating_type_browser(self, context): - AuthoringData.load_relating_types_browser() - if not self.updating: - update_icon_id(self, context, browser=True) - - -def update_relating_type_by_name(self, context): - AuthoringData.load_relating_types() - relating_type_id = AuthoringData.relating_type_id_by_name(self.ifc_class, self.relating_type) - if relating_type_id is not None: - self.relating_type_id = relating_type_id - - -def get_constr_class_info(props, ifc_class): - return props.constr_classes[ifc_class] if ifc_class in props.constr_classes else None - - -def update_preview_multiple(self, context): - if context.region is not None and context.region.type != "TOOL_HEADER": - if self.preview_multiple_constr_types: - ifc_class = self.ifc_class - constr_class_info = get_constr_class_info(self, ifc_class) - if constr_class_info is None or not constr_class_info.fully_loaded: - AuthoringData.assetize_constr_class(ifc_class) - else: - update_relating_type(self, context) - - -class ConstrTypeInfo(PropertyGroup): - name: bpy.props.StringProperty(name="Construction type ID") - icon_id: bpy.props.IntProperty(name="Icon ID") - object: bpy.props.PointerProperty(name="Object", type=bpy.types.Object) - - -class ConstrClassInfo(PropertyGroup): - name: bpy.props.StringProperty(name="Construction class") - constr_types: bpy.props.CollectionProperty(type=ConstrTypeInfo) - fully_loaded: bpy.props.BoolProperty(default=False) - - -class ConstrBrowserState(PropertyGroup): - cursor_x: bpy.props.IntProperty() - cursor_y: bpy.props.IntProperty() - window_x: bpy.props.IntProperty() - window_y: bpy.props.IntProperty() - far_away_x: bpy.props.IntProperty(default=10) # lower left corner to temporarily warp the mouse - far_away_y: bpy.props.IntProperty(default=10) # useful to close popup operators - updating: bpy.props.BoolProperty() - update_delay: bpy.props.FloatProperty(default=3e-2) - - class BIMModelProperties(PropertyGroup): ifc_class: bpy.props.EnumProperty(items=get_ifc_class, name="Construction Class", update=update_ifc_class) - ifc_class_browser: bpy.props.EnumProperty( - items=get_ifc_class, name="Construction Class", update=update_ifc_class_browser - ) - relating_type: bpy.props.StringProperty(update=update_relating_type_by_name) relating_type_id: bpy.props.EnumProperty( - items=get_relating_type, name="Construction Type", update=update_relating_type - ) - relating_type_id_browser: bpy.props.EnumProperty( - items=get_relating_type_browser, name="Construction Type", update=update_relating_type_browser + items=get_relating_type_id, name="Construction Type", update=update_relating_type_id ) icon_id: bpy.props.IntProperty() - preview_multiple_constr_types: bpy.props.BoolProperty(default=False, update=update_preview_multiple) updating: bpy.props.BoolProperty(default=False) occurrence_name_style: bpy.props.EnumProperty( items=[("CLASS", "By Class", ""), ("TYPE", "By Type", ""), ("CUSTOM", "Custom", "")], name="Occurrence Name Style", ) occurrence_name_function: bpy.props.StringProperty(name="Occurrence Name Function") - getter_enum = {"ifc_class": get_ifc_class, "relating_type": get_relating_type} - constr_classes: bpy.props.CollectionProperty(type=ConstrClassInfo) - constr_browser_state: bpy.props.PointerProperty(type=ConstrBrowserState) + getter_enum = {"ifc_class": get_ifc_class, "relating_type": get_relating_type_id} extrusion_depth: bpy.props.FloatProperty(default=42.0) cardinal_point: bpy.props.EnumProperty( items=( diff --git a/src/blenderbim/blenderbim/bim/module/model/root.py b/src/blenderbim/blenderbim/bim/module/model/root.py index 43cdb1432a..a3a72e6e98 100644 --- a/src/blenderbim/blenderbim/bim/module/model/root.py +++ b/src/blenderbim/blenderbim/bim/module/model/root.py @@ -48,8 +48,3 @@ def sync_name(usecase_path, ifc_file, settings): collection.name = new_name obj.name = new_name blenderbim.bim.handler.refresh_ui_data() - - -class ConstrTypeEntityNotFound(Exception): - pass - diff --git a/src/blenderbim/blenderbim/bim/module/model/ui.py b/src/blenderbim/blenderbim/bim/module/model/ui.py index e828432cf0..65638465c0 100644 --- a/src/blenderbim/blenderbim/bim/module/model/ui.py +++ b/src/blenderbim/blenderbim/bim/module/model/ui.py @@ -137,59 +137,6 @@ class BIM_PT_authoring(Panel): row.operator("bim.align_wall", icon="ANCHOR_BOTTOM", text="Int.").align_type = "INTERIOR" -class HelpConstrTypes(Operator): - bl_idname = "bim.help_relating_types" - bl_label = "Construction Types Help" - bl_options = {"REGISTER", "UNDO"} - bl_description = "Click to read some contextual help" - - def execute(self, context): - return {"FINISHED"} - - def invoke(self, context, event): - return context.window_manager.invoke_popup(self, width=510) - - def draw(self, context): - layout = self.layout - layout.row().separator(factor=0.5) - row = layout.row() - row.alignment = "CENTER" - row.label(text="BlenderBIM Help", icon="BLENDER") - layout.row().separator(factor=0.5) - - row = layout.row().row() - row.label(text="Overview:", icon="KEYTYPE_MOVING_HOLD_VEC") - self.draw_lines(layout, self.message_summary) - layout.row().separator() - - row = layout.row().row() - row.label(text="Further support:", icon="KEYTYPE_MOVING_HOLD_VEC") - layout.row().separator(factor=0.5) - row = layout.row() - op = row.operator("bim.open_upstream", text="Homepage", icon="HOME") - op.page = "home" - op = row.operator("bim.open_upstream", text="Docs", icon="DOCUMENTS") - op.page = "docs" - op = row.operator("bim.open_upstream", text="Wiki", icon="CURRENT_FILE") - op.page = "wiki" - op = row.operator("bim.open_upstream", text="Community", icon="COMMUNITY") - op.page = "community" - layout.row().separator() - - def draw_lines(self, layout, lines): - box = layout.box() - for line in lines: - row = box.row() - row.label(text=f" {line}") - - @property - def message_summary(self): - return [ - "The Construction Type Browser allows to preview and add new instances to the model.", - "For further support, please click on the Documentation link below.", - ] - - class BIM_PT_array(bpy.types.Panel): bl_label = "IFC Array" bl_idname = "BIM_PT_array" diff --git a/src/blenderbim/blenderbim/bim/module/model/workspace.py b/src/blenderbim/blenderbim/bim/module/model/workspace.py index 54f044fc08..063a77bc3d 100644 --- a/src/blenderbim/blenderbim/bim/module/model/workspace.py +++ b/src/blenderbim/blenderbim/bim/module/model/workspace.py @@ -111,7 +111,7 @@ class BimToolUI: @classmethod def draw_create_object_interface(cls): - if not AuthoringData.data["relating_types_ids"]: + if not AuthoringData.data["relating_type_id"]: return if cls.props.ifc_class == "IfcWallType": row = cls.layout.row(align=True) @@ -301,7 +301,7 @@ class BimToolUI: prop_with_search(row, cls.props, "ifc_class", text="") row = cls.layout.row(align=True) - if AuthoringData.data["relating_types_ids"]: + if AuthoringData.data["relating_type_id"]: row.label(text="", icon="FILE_3D") prop_with_search(row, cls.props, "relating_type_id", text="") else: