diff --git a/src/blenderbim/blenderbim/bim/export_ifc.py b/src/blenderbim/blenderbim/bim/export_ifc.py index 0ce4bd99c6..5efaefa4b1 100644 --- a/src/blenderbim/blenderbim/bim/export_ifc.py +++ b/src/blenderbim/blenderbim/bim/export_ifc.py @@ -87,7 +87,7 @@ class IfcExporter: self.get_application_name(), tool.Blender.get_blenderbim_version() ) - def sync_all_objects(self) -> list[ifcopenshell.entity_instance]: + def sync_all_objects(self, skip_unlinking=False) -> list[ifcopenshell.entity_instance]: results: list[ifcopenshell.entity_instance] = [] self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(self.file) for ifc_definition_id in list(IfcStore.id_map.keys()): @@ -97,7 +97,7 @@ class IfcExporter: continue if obj.library: continue - tool.Collector.sync(obj) + tool.Collector.sync(obj, skip_unlinking) result = self.sync_object_placement(obj) if result: results.append(result) diff --git a/src/blenderbim/blenderbim/bim/module/drawing/operator.py b/src/blenderbim/blenderbim/bim/module/drawing/operator.py index 9b575796dc..6d02ca5aa2 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/operator.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/operator.py @@ -497,7 +497,7 @@ class CreateDrawing(bpy.types.Operator): # All very hackish whilst prototyping exporter = blenderbim.bim.export_ifc.IfcExporter(None) exporter.file = tool.Ifc.get() - invalidated_elements = exporter.sync_all_objects() + invalidated_elements = exporter.sync_all_objects(skip_unlinking=True) invalidated_elements += exporter.sync_edited_objects() invalidated_guids = [e.GlobalId for e in invalidated_elements if hasattr(e, "GlobalId")] cache = IfcStore.get_cache() diff --git a/src/blenderbim/blenderbim/tool/collector.py b/src/blenderbim/blenderbim/tool/collector.py index be90f0c701..095d56ea1d 100644 --- a/src/blenderbim/blenderbim/tool/collector.py +++ b/src/blenderbim/blenderbim/tool/collector.py @@ -28,11 +28,15 @@ from typing import Union class Collector(blenderbim.core.tool.Collector): @classmethod - def sync(cls, obj: bpy.types.Object) -> None: + def sync(cls, obj: bpy.types.Object, skip_unlinking=False) -> None: """Sync object IFC state (assigned containter / aggregate) with the collection it's currently in. Then subsequently run `Collector.assign` (if state has changed) to link them to collections / unlink from anything unrelated collections. + + If `skip_unlinking` is `True` then method won't try to assign parent object + if it's already assigned in IFC saving some time. + But it has a downside not unlinking object from unrelated collections. """ # This is the reverse of assign. It reads the Blender collection and figures out its IFC hierarchy element = tool.Ifc.get_entity(obj) @@ -76,6 +80,13 @@ class Collector(blenderbim.core.tool.Collector): return parent = tool.Ifc.get_entity(parent_obj) + if skip_unlinking: + previous_parent = ifcopenshell.util.element.get_container( + element, should_get_direct=True + ) or ifcopenshell.util.element.get_aggregate(element) + if parent == previous_parent: + return + if parent: # This is lazy, but works. One of these will succeed, the other will fail silently. blenderbim.core.spatial.assign_container(