mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
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:
@@ -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(
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user