mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Filtered imports is now much faster and works with omitted aggregates
This commit is contained in:
@@ -224,6 +224,8 @@ class IfcImporter:
|
||||
self.profile_code("Create project")
|
||||
self.create_spatial_hierarchy()
|
||||
self.profile_code("Create spatial hierarchy")
|
||||
self.process_element_filter()
|
||||
self.profile_code("Process element filter")
|
||||
self.create_aggregates()
|
||||
self.profile_code("Create aggregates")
|
||||
self.create_aggregate_tree()
|
||||
@@ -234,8 +236,6 @@ class IfcImporter:
|
||||
self.profile_code("Create materials")
|
||||
self.create_styles()
|
||||
self.profile_code("Create styles")
|
||||
self.process_element_filter()
|
||||
self.profile_code("Process element filter")
|
||||
self.parse_native_elements()
|
||||
self.profile_code("Parsing native elements")
|
||||
self.create_grids()
|
||||
@@ -290,16 +290,20 @@ class IfcImporter:
|
||||
return abs(coords[0]) > limit or abs(coords[1]) > limit or abs(coords[2]) > limit
|
||||
|
||||
def process_element_filter(self):
|
||||
if not self.ifc_import_settings.ifc_selector:
|
||||
if self.ifc_import_settings.ifc_import_filter == "NONE" or not self.ifc_import_settings.ifc_selector:
|
||||
self.elements = self.file.by_type("IfcElement")
|
||||
return
|
||||
|
||||
selector = ifcopenshell.util.selector.Selector()
|
||||
elements = selector.parse(self.file, self.ifc_import_settings.ifc_selector)
|
||||
if self.ifc_import_settings.ifc_import_filter == "WHITELIST":
|
||||
self.filter_mode = "WHITELIST"
|
||||
self.include_elements = set(elements)
|
||||
self.elements = self.include_elements
|
||||
elif self.ifc_import_settings.ifc_import_filter == "BLACKLIST":
|
||||
self.exclude_elements = set(elements)
|
||||
self.filter_mode = "BLACKLIST"
|
||||
self.exclude_elements = set(elements)
|
||||
self.elements = [e for e in self.file.by_type("IfcElement") if e not in self.exclude_elements]
|
||||
|
||||
def parse_native_elements(self):
|
||||
if self.filter_mode == "WHITELIST":
|
||||
@@ -637,16 +641,8 @@ class IfcImporter:
|
||||
def create_empty_and_2d_elements(self):
|
||||
curve_products = []
|
||||
|
||||
if self.filter_mode == "WHITELIST":
|
||||
self.elements = self.include_elements
|
||||
elif self.filter_mode == "BLACKLIST":
|
||||
self.elements = [e for e in self.file.by_type("IfcElement") if e not in self.exclude_elements]
|
||||
else:
|
||||
self.elements = self.file.by_type("IfcElement")
|
||||
|
||||
for element in self.elements:
|
||||
if element.id() in self.added_data:
|
||||
continue
|
||||
unadded_data = set([e.id() for e in self.elements]) - set(self.added_data)
|
||||
for element in unadded_data:
|
||||
if element.is_a("IfcPort"):
|
||||
continue
|
||||
if not element.Representation:
|
||||
@@ -1038,9 +1034,17 @@ class IfcImporter:
|
||||
self.add_related_objects(collection, rel_aggregate.RelatedObjects)
|
||||
|
||||
def create_aggregates(self):
|
||||
rel_aggregates = [a for a in self.file.by_type("IfcRelAggregates") if a.RelatingObject.is_a("IfcElement")]
|
||||
for rel_aggregate in rel_aggregates:
|
||||
self.create_aggregate(rel_aggregate)
|
||||
if self.filter_mode in ["WHITELIST", "BLACKLIST"]:
|
||||
rel_aggregates = [e.IsDecomposedBy[0].RelatingObject for e in self.elements if e.IsDecomposedBy]
|
||||
else:
|
||||
rel_aggregates = [a for a in self.file.by_type("IfcRelAggregates") if a.RelatingObject.is_a("IfcElement")]
|
||||
if len(rel_aggregates) > 10000:
|
||||
# More than 10,000 collections makes Blender unhappy
|
||||
print("Falling back to SPATIAL_DECOMPOSITION collection mode")
|
||||
self.ifc_import_settings.collection_mode = "SPATIAL_DECOMPOSITION"
|
||||
else:
|
||||
for rel_aggregate in rel_aggregates:
|
||||
self.create_aggregate(rel_aggregate)
|
||||
|
||||
def create_aggregate_tree(self):
|
||||
for aggregate in self.aggregates.values():
|
||||
@@ -1191,8 +1195,15 @@ class IfcImporter:
|
||||
):
|
||||
bpy.data.objects.remove(self.spatial_structure_elements[global_id]["blender_obj"])
|
||||
collection = self.spatial_structure_elements[global_id]["blender"]
|
||||
elif self.ifc_import_settings.collection_mode == "SPATIAL_DECOMPOSITION":
|
||||
# TODO: refactor this to a more holistic collection mode feature
|
||||
return self.place_object_in_spatial_tree(element.Decomposes[0].RelatingObject, obj)
|
||||
else:
|
||||
collection = self.aggregates[element.Decomposes[0].RelatingObject.GlobalId]["blender"]
|
||||
aggregate = element.Decomposes[0].RelatingObject
|
||||
aggregate_data = self.aggregates.get(aggregate.GlobalId)
|
||||
if not aggregate_data:
|
||||
return self.place_object_in_spatial_tree(aggregate, obj)
|
||||
collection = aggregate_data["blender"]
|
||||
if collection:
|
||||
collection.objects.link(obj)
|
||||
else:
|
||||
@@ -1472,6 +1483,7 @@ class IfcImportSettings:
|
||||
self.model_offset_coordinates = (0, 0, 0)
|
||||
self.ifc_import_filter = "NONE"
|
||||
self.ifc_selector = ""
|
||||
self.collection_mode = "DECOMPOSITION"
|
||||
|
||||
@staticmethod
|
||||
def factory(context, input_file, logger):
|
||||
|
||||
@@ -3,7 +3,9 @@ def get_primitive_type(attribute_or_data_type):
|
||||
data_type = str(attribute_or_data_type.type_of_attribute())
|
||||
else:
|
||||
data_type = str(attribute_or_data_type)
|
||||
if data_type.find("<list") == 0:
|
||||
if data_type.find("<type") == 0:
|
||||
return get_primitive_type(data_type[data_type[1:].find("<")+1:])
|
||||
elif data_type.find("<list") == 0:
|
||||
return ("list", get_primitive_type(data_type[data_type[1:].find("<")+1:]))
|
||||
elif data_type.find("<set") == 0:
|
||||
return ("set", get_primitive_type(data_type[data_type[1:].find("<")+1:]))
|
||||
|
||||
Reference in New Issue
Block a user