diff --git a/src/blenderbim/blenderbim/bim/ifc.py b/src/blenderbim/blenderbim/bim/ifc.py index 9e1e4ec54b..aa401a46de 100644 --- a/src/blenderbim/blenderbim/bim/ifc.py +++ b/src/blenderbim/blenderbim/bim/ifc.py @@ -57,9 +57,20 @@ class IfcStore: blenderbim.bim.handler.subscribe_to(obj, "name", blenderbim.bim.handler.name_callback) @staticmethod - def unlink_element(element, obj=None): - del IfcStore.id_map[element.id()] - if hasattr(element, "GlobalId"): + def unlink_element(element=None, obj=None): + if element is None: + try: + element = IfcStore.get_file().by_id(obj.BIMObjectProperties.ifc_definition_id) + except: + pass + + if element: + del IfcStore.id_map[element.id()] + else: + del IfcStore.id_map[obj.BIMObjectProperties.ifc_definition_id] + + if element and hasattr(element, "GlobalId"): del IfcStore.guid_map[element.GlobalId] + if obj: obj.BIMObjectProperties.ifc_definition_id = 0 diff --git a/src/blenderbim/blenderbim/bim/module/root/operator.py b/src/blenderbim/blenderbim/bim/module/root/operator.py index f345282471..7dfba70978 100644 --- a/src/blenderbim/blenderbim/bim/module/root/operator.py +++ b/src/blenderbim/blenderbim/bim/module/root/operator.py @@ -5,6 +5,7 @@ import ifcopenshell.api import ifcopenshell.util.schema import ifcopenshell.util.element from ifcopenshell.api.geometry.data import Data as GeometryData +from ifcopenshell.api.void.data import Data as VoidData from blenderbim.bim.ifc import IfcStore @@ -181,6 +182,7 @@ class UnassignClass(bpy.types.Operator): if not obj.BIMObjectProperties.ifc_definition_id: continue product = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) + self.remove_voids(product, obj) IfcStore.unlink_element(product, obj) ifcopenshell.api.run("root.remove_product", self.file, **{"product": product}) if "/" in obj.name and obj.name[0:3] == "Ifc": @@ -189,6 +191,12 @@ class UnassignClass(bpy.types.Operator): bpy.data.objects.remove(obj) return {"FINISHED"} + def remove_voids(self, product, obj): + if product.id() not in VoidData.products: + VoidData.load(self.file, product.id()) + for opening_id in VoidData.products[product.id()]: + bpy.ops.bim.remove_opening(opening_id=opening_id, obj=obj.name) + class UnlinkObject(bpy.types.Operator): bl_idname = "bim.unlink_object" @@ -203,7 +211,7 @@ class UnlinkObject(bpy.types.Operator): objects = bpy.context.selected_objects for obj in objects: if obj.BIMObjectProperties.ifc_definition_id: - obj.BIMObjectProperties.ifc_definition_id = 0 + IfcStore.unlink_element(obj=obj) if "Ifc" in obj.name and "/" in obj.name: obj.name = "/".join(obj.name.split("/")[1:]) return {"FINISHED"} diff --git a/src/blenderbim/blenderbim/bim/module/void/operator.py b/src/blenderbim/blenderbim/bim/module/void/operator.py index 31785ad2dc..27a30eeae5 100644 --- a/src/blenderbim/blenderbim/bim/module/void/operator.py +++ b/src/blenderbim/blenderbim/bim/module/void/operator.py @@ -67,7 +67,7 @@ class RemoveOpening(bpy.types.Operator): if modifier.type != "BOOLEAN": continue if modifier.object and modifier.object.BIMObjectProperties.ifc_definition_id == self.opening_id: - modifier.object.BIMObjectProperties.ifc_definition_id = 0 + IfcStore.unlink_element(obj=modifier.object) if "/" in modifier.object.name and modifier.object.name[0:3] == "Ifc": modifier.object.name = "/".join(modifier.object.name.split("/")[1:]) obj.modifiers.remove(modifier) diff --git a/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py b/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py index 1a1fcd64a3..dce1c7e9f5 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py +++ b/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py @@ -22,5 +22,7 @@ class Usecase: self.file, **{"product": self.settings["product"], "representation": representation} ) ifcopenshell.api.run("geometry.remove_representation", self.file, **{"representation": representation}) + for opening in self.settings["product"].HasOpenings or []: + ifcopenshell.api.run("void.remove_opening", self.file, opening=opening.RelatedOpeningElement) # TODO: remove object placement and other relationships self.file.remove(self.settings["product"]) diff --git a/src/ifcopenshell-python/ifcopenshell/api/void/remove_opening.py b/src/ifcopenshell-python/ifcopenshell/api/void/remove_opening.py index d89d44c2e0..4b0ac52048 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/void/remove_opening.py +++ b/src/ifcopenshell-python/ifcopenshell/api/void/remove_opening.py @@ -1,3 +1,6 @@ +import ifcopenshell.api + + class Usecase: def __init__(self, file, **settings): self.file = file @@ -15,6 +18,6 @@ class Usecase: if rel.RelatingOpeningElement == self.settings["opening"]: to_remove.append(rel) break - self.file.remove(self.settings["opening"]) + ifcopenshell.api.run("root.remove_product", self.file, product=self.settings["opening"]) for element in to_remove: self.file.remove(element)