From e6ac012f571dcdb9f4d1acad9fb203dd89b9c01e Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sun, 9 Jun 2024 16:55:19 +1000 Subject: [PATCH] Loading IFCs now also uses tool.Collector.assign instead of implementing the logic twice --- src/blenderbim/blenderbim/bim/import_ifc.py | 74 +++------------------ src/blenderbim/blenderbim/tool/collector.py | 10 +-- 2 files changed, 16 insertions(+), 68 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/import_ifc.py b/src/blenderbim/blenderbim/bim/import_ifc.py index 62177902b5..1061ee3b83 100644 --- a/src/blenderbim/blenderbim/bim/import_ifc.py +++ b/src/blenderbim/blenderbim/bim/import_ifc.py @@ -218,7 +218,6 @@ class IfcImporter: self.gross_elements: set[ifcopenshell.entity_instance] = set() self.element_types: set[ifcopenshell.entity_instance] = set() self.spatial_elements: set[ifcopenshell.entity_instance] = set() - self.type_collection: bpy.types.Collection = None self.type_products = {} self.meshes = {} self.mesh_shapes = {} @@ -263,8 +262,6 @@ class IfcImporter: self.profile_code("Create project") self.process_element_filter() self.profile_code("Process element filter") - self.create_collections() - self.profile_code("Create collections") self.create_materials() self.profile_code("Create materials") self.create_styles() @@ -805,16 +802,9 @@ class IfcImporter: if bpy.context.preferences.addons["blenderbim"].preferences.lock_grids_on_import: grid_obj.lock_location = (True, True, True) grid_obj.lock_rotation = (True, True, True) - collection = bpy.data.collections.new(tool.Loader.get_name(grid)) - u_axes = bpy.data.collections.new("UAxes") - collection.children.link(u_axes) - v_axes = bpy.data.collections.new("VAxes") - collection.children.link(v_axes) self.create_grid_axes(grid.UAxes, grid_obj, grid_placement) self.create_grid_axes(grid.VAxes, grid_obj, grid_placement) if grid.WAxes: - w_axes = bpy.data.collections.new("WAxes") - collection.children.link(w_axes) self.create_grid_axes(grid.WAxes, grid_obj) def create_grid_axes(self, axes, grid_obj, grid_placement): @@ -1048,14 +1038,6 @@ class IfcImporter: self.profile_code("Merging by material") def create_structural_items(self): - # Create structural collections - self.structural_member_collection = bpy.data.collections.new("Members") - self.structural_connection_collection = bpy.data.collections.new("Connections") - self.structural_collection = bpy.data.collections.new("StructuralItems") - self.structural_collection.children.link(self.structural_member_collection) - self.structural_collection.children.link(self.structural_connection_collection) - self.project["blender"].children.link(self.structural_collection) - self.create_generic_elements(set(self.file.by_type("IfcStructuralCurveMember"))) self.create_generic_elements(set(self.file.by_type("IfcStructuralCurveConnection"))) self.create_generic_elements(set(self.file.by_type("IfcStructuralSurfaceMember"))) @@ -1513,10 +1495,10 @@ class IfcImporter: # Occurs when reloading a project pass project_collection = bpy.context.view_layer.layer_collection.children[self.project["blender"].name] - types_collection = project_collection.children[self.type_collection.name] - types_collection.hide_viewport = False - for obj in types_collection.collection.objects: # turn off all objects inside Types collection. - obj.hide_set(True) + if types_collection := project_collection.children.get("IfcTypeProduct"): + types_collection.hide_viewport = False + for obj in types_collection.collection.objects: # turn off all objects inside Types collection. + obj.hide_set(True) def clean_mesh(self): obj = None @@ -1530,18 +1512,19 @@ class IfcImporter: if not last_obj: return - # temporarily unhide types collection to make sure all objects will be cleaned + # Temporarily unhide types collection to make sure all objects will be cleaned project_collection = bpy.context.view_layer.layer_collection.children[self.project["blender"].name] - types_collection = project_collection.children[self.type_collection.name] - types_collection.hide_viewport = False - bpy.context.view_layer.objects.active = last_obj + if types_collection := project_collection.children.get("IfcTypeProduct"): + types_collection.hide_viewport = False + bpy.context.view_layer.objects.active = last_obj bpy.ops.object.editmode_toggle() bpy.ops.mesh.tris_convert_to_quads() bpy.ops.mesh.normals_make_consistent() bpy.ops.object.editmode_toggle() - types_collection.hide_viewport = True + if types_collection: + types_collection.hide_viewport = True bpy.context.view_layer.objects.active = last_obj IfcStore.edited_objs.clear() @@ -1606,14 +1589,6 @@ class IfcImporter: self.project["blender"].BIMCollectionProperties.obj = obj obj.BIMObjectProperties.collection = self.collections[project.GlobalId] = self.project["blender"] - def create_collections(self) -> None: - for element in self.spatial_elements: - collection = bpy.data.collections.new(tool.Loader.get_name(element)) - self.collections[element.GlobalId] = collection - self.project["blender"].children.link(collection) - tool.Loader.create_project_collection("Views") - self.type_collection = tool.Loader.create_project_collection("Types") - def create_materials(self) -> None: for material in self.file.by_type("IfcMaterial"): self.create_material(material) @@ -1670,34 +1645,7 @@ class IfcImporter: def place_objects_in_collections(self) -> None: for ifc_definition_id, obj in self.added_data.items(): if isinstance(obj, bpy.types.Object): - self.place_object_in_collection(self.file.by_id(ifc_definition_id), obj) - - def place_object_in_collection(self, element: ifcopenshell.entity_instance, obj: bpy.types.Object) -> None: - if element.is_a("IfcProject"): - return - elif element.is_a("IfcGridAxis"): - return - elif element.GlobalId in self.collections: - collection = self.collections[element.GlobalId] - collection.BIMCollectionProperties.obj = obj - obj.BIMObjectProperties.collection = collection - collection.name = obj.name - return collection.objects.link(obj) - elif element.is_a("IfcTypeObject"): - return self.type_collection.objects.link(obj) - elif element.is_a("IfcStructuralMember"): - return self.structural_member_collection.objects.link(obj) - elif element.is_a("IfcStructuralConnection"): - return self.structural_connection_collection.objects.link(obj) - elif container := ifcopenshell.util.element.get_container(element): - self.collections[container.GlobalId].objects.link(obj) - elif element.is_a("IfcAnnotation"): - group = self.get_drawing_group(element) - if group: - return self.collections[group.GlobalId].objects.link(obj) - else: - self.ifc_import_settings.logger.warning("Warning: this object is outside the spatial hierarchy %s", element) - bpy.context.scene.collection.objects.link(obj) + tool.Collector.assign(obj) def is_curve_annotation(self, element): object_type = element.ObjectType diff --git a/src/blenderbim/blenderbim/tool/collector.py b/src/blenderbim/blenderbim/tool/collector.py index 425a40ecf2..35ed097380 100644 --- a/src/blenderbim/blenderbim/tool/collector.py +++ b/src/blenderbim/blenderbim/tool/collector.py @@ -18,8 +18,6 @@ import bpy import blenderbim.core.tool -import blenderbim.core.spatial -import blenderbim.core.aggregate import blenderbim.tool as tool import ifcopenshell.util.element @@ -27,8 +25,7 @@ import ifcopenshell.util.element class Collector(blenderbim.core.tool.Collector): @classmethod def assign(cls, obj: bpy.types.Object) -> None: - """link object and it's owned collection to the proper collection - and unlink them from any other""" + """Links an object to an appropriate Blender collection.""" element = tool.Ifc.get_entity(obj) if element.is_a("IfcGridAxis"): @@ -59,7 +56,10 @@ class Collector(blenderbim.core.tool.Collector): project_obj.BIMObjectProperties.collection.children.link(collection) elif container := ifcopenshell.util.element.get_container(element): container_obj = tool.Ifc.get_object(container) - container_obj.BIMObjectProperties.collection.objects.link(obj) + if not (collection := container_obj.BIMObjectProperties.collection): + cls.assign(container_obj) + collection = container_obj.BIMObjectProperties.collection + collection.objects.link(obj) elif element.is_a("IfcAnnotation"): if element.ObjectType == "DRAWING": if collection := cls._create_own_collection(obj):