Fix bug where related openings are not deleted when you delete a product

This commit is contained in:
Dion Moult
2021-05-12 22:20:58 +10:00
parent 35ceba2e88
commit beb813cb21
5 changed files with 30 additions and 6 deletions
+14 -3
View File
@@ -57,9 +57,20 @@ class IfcStore:
blenderbim.bim.handler.subscribe_to(obj, "name", blenderbim.bim.handler.name_callback) blenderbim.bim.handler.subscribe_to(obj, "name", blenderbim.bim.handler.name_callback)
@staticmethod @staticmethod
def unlink_element(element, obj=None): def unlink_element(element=None, obj=None):
del IfcStore.id_map[element.id()] if element is None:
if hasattr(element, "GlobalId"): 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] del IfcStore.guid_map[element.GlobalId]
if obj: if obj:
obj.BIMObjectProperties.ifc_definition_id = 0 obj.BIMObjectProperties.ifc_definition_id = 0
@@ -5,6 +5,7 @@ import ifcopenshell.api
import ifcopenshell.util.schema import ifcopenshell.util.schema
import ifcopenshell.util.element import ifcopenshell.util.element
from ifcopenshell.api.geometry.data import Data as GeometryData from ifcopenshell.api.geometry.data import Data as GeometryData
from ifcopenshell.api.void.data import Data as VoidData
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
@@ -181,6 +182,7 @@ class UnassignClass(bpy.types.Operator):
if not obj.BIMObjectProperties.ifc_definition_id: if not obj.BIMObjectProperties.ifc_definition_id:
continue continue
product = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) product = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
self.remove_voids(product, obj)
IfcStore.unlink_element(product, obj) IfcStore.unlink_element(product, obj)
ifcopenshell.api.run("root.remove_product", self.file, **{"product": product}) ifcopenshell.api.run("root.remove_product", self.file, **{"product": product})
if "/" in obj.name and obj.name[0:3] == "Ifc": if "/" in obj.name and obj.name[0:3] == "Ifc":
@@ -189,6 +191,12 @@ class UnassignClass(bpy.types.Operator):
bpy.data.objects.remove(obj) bpy.data.objects.remove(obj)
return {"FINISHED"} 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): class UnlinkObject(bpy.types.Operator):
bl_idname = "bim.unlink_object" bl_idname = "bim.unlink_object"
@@ -203,7 +211,7 @@ class UnlinkObject(bpy.types.Operator):
objects = bpy.context.selected_objects objects = bpy.context.selected_objects
for obj in objects: for obj in objects:
if obj.BIMObjectProperties.ifc_definition_id: 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: if "Ifc" in obj.name and "/" in obj.name:
obj.name = "/".join(obj.name.split("/")[1:]) obj.name = "/".join(obj.name.split("/")[1:])
return {"FINISHED"} return {"FINISHED"}
@@ -67,7 +67,7 @@ class RemoveOpening(bpy.types.Operator):
if modifier.type != "BOOLEAN": if modifier.type != "BOOLEAN":
continue continue
if modifier.object and modifier.object.BIMObjectProperties.ifc_definition_id == self.opening_id: 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": if "/" in modifier.object.name and modifier.object.name[0:3] == "Ifc":
modifier.object.name = "/".join(modifier.object.name.split("/")[1:]) modifier.object.name = "/".join(modifier.object.name.split("/")[1:])
obj.modifiers.remove(modifier) obj.modifiers.remove(modifier)
@@ -22,5 +22,7 @@ class Usecase:
self.file, **{"product": self.settings["product"], "representation": representation} self.file, **{"product": self.settings["product"], "representation": representation}
) )
ifcopenshell.api.run("geometry.remove_representation", self.file, **{"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 # TODO: remove object placement and other relationships
self.file.remove(self.settings["product"]) self.file.remove(self.settings["product"])
@@ -1,3 +1,6 @@
import ifcopenshell.api
class Usecase: class Usecase:
def __init__(self, file, **settings): def __init__(self, file, **settings):
self.file = file self.file = file
@@ -15,6 +18,6 @@ class Usecase:
if rel.RelatingOpeningElement == self.settings["opening"]: if rel.RelatingOpeningElement == self.settings["opening"]:
to_remove.append(rel) to_remove.append(rel)
break break
self.file.remove(self.settings["opening"]) ifcopenshell.api.run("root.remove_product", self.file, product=self.settings["opening"])
for element in to_remove: for element in to_remove:
self.file.remove(element) self.file.remove(element)