diff --git a/src/blenderbim/blenderbim/bim/export_ifc.py b/src/blenderbim/blenderbim/bim/export_ifc.py index c72a657656..2777c58ad1 100644 --- a/src/blenderbim/blenderbim/bim/export_ifc.py +++ b/src/blenderbim/blenderbim/bim/export_ifc.py @@ -45,7 +45,6 @@ class IfcExporter: self.set_header() IfcStore.update_cache() if bpy.context.scene.BIMProjectProperties.is_authoring: - self.sync_deletions() self.sync_all_objects() self.sync_edited_objects() extension = self.ifc_export_settings.output_file.split(".")[-1].lower() @@ -87,19 +86,6 @@ class IfcExporter: self.get_application_name(), self.get_application_version() ) - def sync_deletions(self): - results = [] - for ifc_definition_id in IfcStore.deleted_ids: - try: - product = self.file.by_id(ifc_definition_id) - if hasattr(product, "GlobalId"): - results.append(product.GlobalId) - except: - continue - ifcopenshell.api.run("root.remove_product", self.file, **{"product": product}) - IfcStore.deleted_ids.clear() - return results - def sync_all_objects(self): results = [] self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(self.file) diff --git a/src/blenderbim/blenderbim/bim/ifc.py b/src/blenderbim/blenderbim/bim/ifc.py index cba91c9793..fa8cbfa8df 100644 --- a/src/blenderbim/blenderbim/bim/ifc.py +++ b/src/blenderbim/blenderbim/bim/ifc.py @@ -36,7 +36,6 @@ class IfcStore: cache_path = None id_map = {} guid_map = {} - deleted_ids = set() edited_objs = set() pset_template_path = "" pset_template_file = None @@ -63,7 +62,6 @@ class IfcStore: IfcStore.cache_path = None IfcStore.id_map = {} IfcStore.guid_map = {} - IfcStore.deleted_ids = set() IfcStore.edited_objs = set() IfcStore.pset_template_path = "" IfcStore.pset_template_file = None @@ -278,23 +276,6 @@ class IfcStore: data = {"id": element.id(), "obj": obj.name} IfcStore.commit_link_element(data) - @staticmethod - def delete_element(element): - IfcStore.deleted_ids.add(element.id()) - if IfcStore.history: - data = {"id": element.id()} - IfcStore.history[-1]["operations"].append( - {"rollback": IfcStore.rollback_delete_element, "commit": IfcStore.commit_delete_element, "data": data} - ) - - @staticmethod - def rollback_delete_element(data): - IfcStore.deleted_ids.remove(data["id"]) - - @staticmethod - def commit_delete_element(data): - IfcStore.deleted_ids.add(data["id"]) - @staticmethod def link_element(element, obj): existing_obj = IfcStore.id_map.get(element.id(), None) diff --git a/src/blenderbim/blenderbim/bim/module/geometry/operator.py b/src/blenderbim/blenderbim/bim/module/geometry/operator.py index 6db28d7258..647739d467 100644 --- a/src/blenderbim/blenderbim/bim/module/geometry/operator.py +++ b/src/blenderbim/blenderbim/bim/module/geometry/operator.py @@ -250,6 +250,20 @@ class UpdateRepresentation(bpy.types.Operator, Operator): obj.data.BIMMeshProperties.ifc_definition_id = int(new_representation.id()) obj.data.name = f"{old_representation.ContextOfItems.id()}/{new_representation.id()}" + + # TODO: In simple scenarios, a type has a ShapeRepresentation of ID + # 123. This is then mapped through mapped representations by + # occurrences, with no cartesian transformation. In this case, the mesh + # data is 100% shared and therefore all have the same mesh name + # referencing ID 123. (i.e. the local origins are shared). However, in + # complex scenarios, occurrences may have their own cartesian + # transformation (via MappingTarget). This will mean that occurrences + # will not share the same mesh data and will instead reference a + # different ShapeRepresentation ID. In this scenario, we have to + # propagate the obj.data back to the type itself and all sibling + # occurrences and accommodate their individual cartesian + # transformations. + core.remove_representation(tool.Ifc, tool.Geometry, obj=obj, representation=old_representation) if obj.data.BIMMeshProperties.ifc_parameters: core.get_representation_ifc_parameters(tool.Geometry, obj=obj) @@ -352,7 +366,6 @@ class OverrideDeleteTrait: return if element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING": return blenderbim.core.drawing.remove_drawing(tool.Ifc, tool.Drawing, drawing=element) - IfcStore.delete_element(element) if obj.users_collection and obj.users_collection[0].name == obj.name: parent = ifcopenshell.util.element.get_aggregate(element) if not parent: @@ -379,6 +392,7 @@ class OverrideDeleteTrait: self.delete_opening_element(rel.RelatedOpeningElement) for port in ifcopenshell.util.system.get_ports(element): self.remove_port(port) + ifcopenshell.api.run("root.remove_product", tool.Ifc.get(), product=element) def delete_opening_element(self, element): bpy.ops.bim.remove_opening(opening_id=element.id()) @@ -661,7 +675,7 @@ class OverrideJoin(bpy.types.Operator, Operator): continue element = tool.Ifc.get_entity(obj) if element: - tool.Ifc.delete(element) + ifcopenshell.api.run("root.remove_product", tool.Ifc.get(), product=element) bpy.ops.object.join() bpy.ops.bim.update_representation(obj=self.target.name, ifc_representation_class="") elif representation.RepresentationType == "SweptSolid": @@ -699,7 +713,7 @@ class OverrideJoin(bpy.types.Operator, Operator): tool.Ifc.get().createIfcDirection([float(n) for n in position[:, 0][:3]]), ) items.append(copied_item) - tool.Ifc.delete(element) + ifcopenshell.api.run("root.remove_product", tool.Ifc.get(), product=element) representation.Items = items bpy.ops.object.join() core.switch_representation( @@ -719,7 +733,7 @@ class OverrideJoin(bpy.types.Operator, Operator): continue element = tool.Ifc.get_entity(obj) if element: - tool.Ifc.delete(element) + ifcopenshell.api.run("root.remove_product", tool.Ifc.get(), product=element) bpy.ops.object.join() diff --git a/src/blenderbim/blenderbim/core/drawing.py b/src/blenderbim/blenderbim/core/drawing.py index 037ef0db14..7da2d59288 100644 --- a/src/blenderbim/blenderbim/core/drawing.py +++ b/src/blenderbim/blenderbim/core/drawing.py @@ -347,11 +347,9 @@ def sync_references(ifc, collector, drawing_tool, drawing=None): should_create_annotation = False if annotation: - if ifc.is_deleted(annotation): + if reference_obj and (ifc.is_moved(reference_obj) or ifc.is_edited(reference_obj)): should_delete_existing_annotation = True - elif reference_obj and (ifc.is_moved(reference_obj) or ifc.is_edited(reference_obj)): - should_delete_existing_annotation = True - elif not reference_obj and ifc.is_deleted(reference_element): + elif not reference_obj: should_delete_existing_annotation = True if reference_obj and (should_delete_existing_annotation or not annotation): diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index eed8325419..73724f9235 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -376,13 +376,11 @@ class Ifc: def get_object(cls, entity): pass def get_path(cls): pass def get_schema(cls): pass - def is_deleted(cls, element): pass def is_edited(cls, obj): pass def is_moved(cls, obj): pass def link(cls, element, obj): pass def schema(cls): pass def edit(cls, obj): pass - def delete(cls, element): pass def resolve_uri(cls, uri): pass def run(cls, command, **kwargs): pass def set(cls, ifc): pass diff --git a/src/blenderbim/blenderbim/tool/drawing.py b/src/blenderbim/blenderbim/tool/drawing.py index 382dc6e323..9f004b2edb 100644 --- a/src/blenderbim/blenderbim/tool/drawing.py +++ b/src/blenderbim/blenderbim/tool/drawing.py @@ -149,7 +149,7 @@ class Drawing(blenderbim.core.tool.Drawing): @classmethod def delete_drawing_elements(cls, elements): for element in elements: - tool.Ifc.delete(element) + ifcopenshell.api.run("root.remove_product", tool.Ifc.get(), product=element) obj = tool.Ifc.get_object(element) if obj: obj_data = obj.data diff --git a/src/blenderbim/blenderbim/tool/ifc.py b/src/blenderbim/blenderbim/tool/ifc.py index 4f73034b6f..616540edaf 100644 --- a/src/blenderbim/blenderbim/tool/ifc.py +++ b/src/blenderbim/blenderbim/tool/ifc.py @@ -51,10 +51,6 @@ class Ifc(blenderbim.core.tool.Ifc): checksum = obj.BIMMaterialProperties.shading_checksum return checksum != repr(np.array(obj.diffuse_color).tobytes()) - @classmethod - def is_deleted(cls, element): - return element.id() in IfcStore.deleted_ids - @classmethod def is_edited(cls, obj): return list(obj.scale) != [1.0, 1.0, 1.0] or obj in IfcStore.edited_objs @@ -100,10 +96,6 @@ class Ifc(blenderbim.core.tool.Ifc): def edit(cls, obj): IfcStore.edited_objs.add(obj) - @classmethod - def delete(cls, element): - IfcStore.delete_element(element) - @classmethod def resolve_uri(cls, uri): if os.path.isabs(uri): diff --git a/src/blenderbim/test/tool/test_drawing.py b/src/blenderbim/test/tool/test_drawing.py index 92d02fadda..6392594800 100644 --- a/src/blenderbim/test/tool/test_drawing.py +++ b/src/blenderbim/test/tool/test_drawing.py @@ -61,6 +61,8 @@ class TestCreateCamera(NewFile): class TestCreateSvgSheet(NewFile): def test_run(self): ifc = ifcopenshell.file() + ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") + tool.Ifc.set(ifc) document = ifc.createIfcDocumentInformation( Identification="X", Name="FOOBAR", @@ -87,12 +89,16 @@ class TestDeleteDrawingElements(NewFile): collection = bpy.data.collections.new("Collection") bpy.context.scene.collection.children.link(collection) collection.objects.link(obj) - element = ifc.createIfcAnnotation() + element = ifc.createIfcAnnotation(GlobalId=ifcopenshell.guid.new()) tool.Ifc.link(element, obj) element_id = element.id() subject.delete_drawing_elements([element]) - assert element_id in IfcStore.deleted_ids + try: + ifc.by_id(element_id) + assert False + except: + pass assert not bpy.data.objects.get("Object")