From 2e7e2d24e420aa554b978773aae853eb4a0df261 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sun, 6 Oct 2024 17:16:23 +1100 Subject: [PATCH] Fix #5536. Trigger advanced mode by default on large models. Default to unlimited loading, but show warning. This is a very common complaint: missing elements on large models. It seems as better default is to warn the user that the model is large, but give them the option to filter prior to loading the model. --- src/bonsai/bonsai/bim/import_ifc.py | 23 ++++++++----------- src/bonsai/bonsai/bim/module/project/data.py | 7 ++++++ .../bonsai/bim/module/project/operator.py | 12 ++++------ src/bonsai/bonsai/bim/module/project/prop.py | 8 +++++++ src/bonsai/bonsai/bim/module/project/ui.py | 22 ++++++++++++++---- 5 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/bonsai/bonsai/bim/import_ifc.py b/src/bonsai/bonsai/bim/import_ifc.py index 7227f653ff..c080c79e73 100644 --- a/src/bonsai/bonsai/bim/import_ifc.py +++ b/src/bonsai/bonsai/bim/import_ifc.py @@ -186,9 +186,6 @@ class MaterialCreator: return items -IMPORTER_WARNINGS: list[str] = [] - - class IfcImporter: def __init__(self, ifc_import_settings: IfcImportSettings): self.ifc_import_settings = ifc_import_settings @@ -295,9 +292,6 @@ class IfcImporter: tool.Loader.settings.gross_context_settings = tool.Loader.create_settings(is_gross=True) def process_element_filter(self) -> None: - offset = self.ifc_import_settings.element_offset - offset_limit = offset + self.ifc_import_settings.element_limit - if self.ifc_import_settings.has_filter: self.elements = self.ifc_import_settings.elements if isinstance(self.elements, set): @@ -318,15 +312,14 @@ class IfcImporter: self.annotations -= drawing_annotations self.elements = [e for e in self.elements if not e.is_a("IfcFeatureElement") or e.is_a("IfcSurfaceFeature")] - n = len(self.elements) - self.elements = set(self.elements[offset:offset_limit]) - if n > len(self.elements): - IMPORTER_WARNINGS.append( - f"Not all elements were loaded. Only loaded {(len(self.elements))} of {n} elements (element range: {offset}-{offset_limit}). " - "You can change element range by loading project in advanced mode." - ) + if self.ifc_import_settings.element_limit_mode == "UNLIMITED": + self.elements = set(self.elements) + else: + offset = self.ifc_import_settings.element_offset + offset_limit = offset + self.ifc_import_settings.element_limit + self.elements = set(self.elements[offset:offset_limit]) - if self.ifc_import_settings.has_filter or offset or offset_limit < len(self.elements): + if self.ifc_import_settings.has_filter or self.ifc_import_settings.element_limit_mode != "UNLIMITED": self.element_types = set([ifcopenshell.util.element.get_type(e) for e in self.elements]) else: self.element_types = set(self.file.by_type("IfcTypeProduct")) @@ -1510,6 +1503,7 @@ class IfcImportSettings: self.false_origin_mode = "AUTOMATIC" self.false_origin = None self.project_north = None + self.element_limit_mode = "UNLIMITED" self.element_offset = 0 self.element_limit = 30000 self.has_filter = None @@ -1550,6 +1544,7 @@ class IfcImportSettings: settings.project_north = float(props.project_north) except: settings.project_north = 0 + settings.element_limit_mode = props.element_limit_mode settings.element_offset = props.element_offset settings.element_limit = props.element_limit return settings diff --git a/src/bonsai/bonsai/bim/module/project/data.py b/src/bonsai/bonsai/bim/module/project/data.py index 50622291d3..97f82fea76 100644 --- a/src/bonsai/bonsai/bim/module/project/data.py +++ b/src/bonsai/bonsai/bim/module/project/data.py @@ -42,6 +42,7 @@ class ProjectData: "export_schema": cls.get_export_schema(), "library_file": cls.library_file(), "last_saved": cls.last_saved(), + "total_elements": cls.total_elements(), } # After export_schema. cls.data["template_file"] = cls.template_file() @@ -106,6 +107,12 @@ class ProjectData: except: return "" + @classmethod + def total_elements(cls): + if ifc := tool.Ifc.get(): + return len(ifc.by_type("IfcElement")) + return 0 + class LinksData: linked_data = {} diff --git a/src/bonsai/bonsai/bim/module/project/operator.py b/src/bonsai/bonsai/bim/module/project/operator.py index 51c089a998..7ce93f02e8 100644 --- a/src/bonsai/bonsai/bim/module/project/operator.py +++ b/src/bonsai/bonsai/bim/module/project/operator.py @@ -772,14 +772,12 @@ class LoadProject(bpy.types.Operator, IFCFileSelector): tool.Blender.register_toolbar() tool.Project.add_recent_ifc_project(filepath.absolute()) - if not self.is_advanced: + if self.is_advanced: + pass + elif len(tool.Ifc.get().by_type("IfcElement")) > 30000: + self.report({"WARNING"}, "Warning: large model. Please review advanced settings to continue.") + else: bpy.ops.bim.load_project_elements() - if warnings := import_ifc.IMPORTER_WARNINGS: - print("\n\nLoading project finished with warnings:") - for warning in warnings: - print(f"- {warning}") - self.report({"WARNING"}, "Project was loaded with warnings. See system console for details.") - warnings.clear() if self.import_without_ifc_data: bpy.ops.bim.convert_to_blender() except: diff --git a/src/bonsai/bonsai/bim/module/project/prop.py b/src/bonsai/bonsai/bim/module/project/prop.py index 2df317ae64..7b1a7c8fac 100644 --- a/src/bonsai/bonsai/bim/module/project/prop.py +++ b/src/bonsai/bonsai/bim/module/project/prop.py @@ -199,6 +199,14 @@ class BIMProjectProperties(PropertyGroup): description="The angle (postive is anticlockwise) pointing to grid north relative to project north", default="0", ) + element_limit_mode: bpy.props.EnumProperty( + items=[ + ("UNLIMITED", "Load Everything", "Load all elements"), + ("RANGE", "Load Subset of Elements", "Only load the first N elements"), + ], + name="Element limit", + default="UNLIMITED", + ) element_offset: IntProperty(name="Element Offset", default=0) element_limit: IntProperty(name="Element Offset", default=30000) should_disable_undo_on_save: BoolProperty( diff --git a/src/bonsai/bonsai/bim/module/project/ui.py b/src/bonsai/bonsai/bim/module/project/ui.py index 96576da094..0d8446af76 100644 --- a/src/bonsai/bonsai/bim/module/project/ui.py +++ b/src/bonsai/bonsai/bim/module/project/ui.py @@ -193,11 +193,25 @@ class BIM_PT_project(Panel): row = self.layout.row() row.prop(pprops, "project_north") + if ProjectData.data["total_elements"] > 30000: + box = self.layout.box() + box.alert = True + row = box.row() + row.alignment = "CENTER" + row.label(text=f"Large Model ({ProjectData.data['total_elements']} Elements)", icon="ERROR") + row = box.row() + row.alignment = "CENTER" + row.label(text="Large models may slow down Bonsai") + row = self.layout.row() - row.label(text="Element Range") - row = self.layout.row(align=True) - row.prop(pprops, "element_offset", text="") - row.prop(pprops, "element_limit", text="") + row.prop(pprops, "element_limit_mode") + + if pprops.element_limit_mode == "RANGE": + row = self.layout.row() + row.label(text="Element Range") + row = self.layout.row(align=True) + row.prop(pprops, "element_offset", text="") + row.prop(pprops, "element_limit", text="") row = self.layout.row(align=True) row.operator("bim.load_project_elements")