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.
This commit is contained in:
Dion Moult
2024-10-06 17:16:23 +11:00
parent c10056611b
commit 2e7e2d24e4
5 changed files with 47 additions and 25 deletions
+9 -14
View File
@@ -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
@@ -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 = {}
@@ -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:
@@ -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(
+18 -4
View File
@@ -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")