From 1590e8c0e73b1e213be3edb6f1dab0b59bcb50a8 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Wed, 5 Oct 2022 16:39:10 +1100 Subject: [PATCH] Openings locations are fixed relative to slab profile editing --- src/blenderbim/blenderbim/bim/ifc.py | 6 +++++- src/blenderbim/blenderbim/bim/module/model/slab.py | 10 +++++++--- src/blenderbim/blenderbim/bim/module/model/wall.py | 8 +++++--- src/blenderbim/blenderbim/bim/module/void/operator.py | 3 +++ src/blenderbim/blenderbim/tool/collector.py | 2 +- src/blenderbim/test/tool/test_collector.py | 9 +++++++++ 6 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/ifc.py b/src/blenderbim/blenderbim/bim/ifc.py index 6d0b7a35d4..7aa4ae0b06 100644 --- a/src/blenderbim/blenderbim/bim/ifc.py +++ b/src/blenderbim/blenderbim/bim/ifc.py @@ -281,7 +281,11 @@ class IfcStore: if existing_obj == obj: return elif existing_obj: - IfcStore.unlink_element(obj=existing_obj) + try: + existing_obj.name + IfcStore.unlink_element(obj=existing_obj) + except: + pass IfcStore.id_map[element.id()] = obj if hasattr(element, "GlobalId"): IfcStore.guid_map[element.GlobalId] = obj diff --git a/src/blenderbim/blenderbim/bim/module/model/slab.py b/src/blenderbim/blenderbim/bim/module/model/slab.py index 4f6b9b8ac1..c9fcea578c 100644 --- a/src/blenderbim/blenderbim/bim/module/model/slab.py +++ b/src/blenderbim/blenderbim/bim/module/model/slab.py @@ -165,11 +165,14 @@ class DumbSlabGenerator: obj = bpy.data.objects.new(tool.Model.generate_occurrence_name(self.relating_type, ifc_class), mesh) if link_to_scene: - obj.location = self.location + matrix_world = Matrix() + matrix_world.col[3] = self.location.to_4d() if self.collection_obj and self.collection_obj.BIMObjectProperties.ifc_definition_id: - obj.location[2] = self.collection_obj.location[2] - self.depth + matrix_world[2][3] = self.collection_obj.location[2] - self.depth else: - obj.location[2] -= self.depth + matrix_world[2][3] -= self.depth + obj.matrix_world = matrix_world + bpy.context.view_layer.update() self.collection.objects.link(obj) element = blenderbim.core.root.assign_class( @@ -183,6 +186,7 @@ class DumbSlabGenerator: ) ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=self.relating_type) + blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj) representation = ifcopenshell.api.run( "geometry.add_slab_representation", tool.Ifc.get(), context=self.body_context, depth=self.depth ) diff --git a/src/blenderbim/blenderbim/bim/module/model/wall.py b/src/blenderbim/blenderbim/bim/module/model/wall.py index afc1542b9f..31919b66a1 100644 --- a/src/blenderbim/blenderbim/bim/module/model/wall.py +++ b/src/blenderbim/blenderbim/bim/module/model/wall.py @@ -532,10 +532,11 @@ class DumbWallGenerator: mesh = bpy.data.meshes.new("Dummy") obj = bpy.data.objects.new(tool.Model.generate_occurrence_name(self.relating_type, ifc_class), mesh) if link_to_scene: - obj.location = self.location - obj.rotation_euler[2] = self.rotation + matrix_world = Matrix.Rotation(self.rotation, 4, "Z") + matrix_world.col[3] = self.location.to_4d() if self.collection_obj and self.collection_obj.BIMObjectProperties.ifc_definition_id: - obj.location[2] = self.collection_obj.location[2] + matrix_world[2][3] = self.collection_obj.location[2] + obj.matrix_world = matrix_world bpy.context.view_layer.update() self.collection.objects.link(obj) @@ -559,6 +560,7 @@ class DumbWallGenerator: ifcopenshell.api.run( "geometry.assign_representation", tool.Ifc.get(), product=element, representation=representation ) + blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj) representation = ifcopenshell.api.run( "geometry.add_wall_representation", tool.Ifc.get(), diff --git a/src/blenderbim/blenderbim/bim/module/void/operator.py b/src/blenderbim/blenderbim/bim/module/void/operator.py index fb6d2fecf7..c96e364cf1 100644 --- a/src/blenderbim/blenderbim/bim/module/void/operator.py +++ b/src/blenderbim/blenderbim/bim/module/void/operator.py @@ -49,6 +49,9 @@ class AddOpening(bpy.types.Operator, tool.Ifc.Operator): if not obj1.data or not hasattr(obj1.data, "BIMMeshProperties"): return {"FINISHED"} + if tool.Ifc.is_moved(obj1): + blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj1) + has_visible_openings = False for opening in [r.RelatedOpeningElement for r in element1.HasOpenings]: if tool.Ifc.get_object(opening): diff --git a/src/blenderbim/blenderbim/tool/collector.py b/src/blenderbim/blenderbim/tool/collector.py index 1467301269..a2be00654f 100644 --- a/src/blenderbim/blenderbim/tool/collector.py +++ b/src/blenderbim/blenderbim/tool/collector.py @@ -29,7 +29,7 @@ class Collector(blenderbim.core.tool.Collector): # This is the reverse of assign. It reads the Blender collection and figures out its IFC hierarchy element = tool.Ifc.get_entity(obj) - if element.is_a("IfcProject") or element.is_a("IfcGridAxis"): + if element.is_a("IfcProject") or element.is_a("IfcGridAxis") or element.is_a("IfcOpeningElement"): return if not obj.users_collection: diff --git a/src/blenderbim/test/tool/test_collector.py b/src/blenderbim/test/tool/test_collector.py index f4faca34f7..14cce7e99b 100644 --- a/src/blenderbim/test/tool/test_collector.py +++ b/src/blenderbim/test/tool/test_collector.py @@ -306,3 +306,12 @@ class TestSync(NewFile): col.objects.link(obj) subject.sync(obj) assert ifcopenshell.util.element.get_aggregate(element).is_a("IfcBuilding") + + def test_openings_are_never_contained(self): + bpy.ops.bim.create_project() + obj = bpy.data.objects.new("Object", None) + element = tool.Ifc.get().createIfcOpeningElement() + tool.Ifc.link(element, obj) + bpy.data.collections.get("IfcSite/My Site").objects.link(obj) + subject.sync(obj) + assert ifcopenshell.util.element.get_container(element) is None