From a2ff63f9ec5bfcdfa91035f88811c64d63f86c26 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Fri, 16 Feb 2024 17:44:22 +0500 Subject: [PATCH] Fix issue editing object placement that shares it's axis placement with other placements If multiple object placements were reusing the same IfcAxis2Placement then editing one of them would remove IfcAxis2Placement ignoring it's inverse references making all other object placements invalid. --- .../api/geometry/edit_object_placement.py | 2 +- .../geometry/test_edit_object_placement.py | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py index 7e2270a901..0e71411464 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py +++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/edit_object_placement.py @@ -56,7 +56,7 @@ class Usecase: if self.file.get_total_inverses(old_placement) == 1: self.settings["product"].ObjectPlacement = None old_placement.PlacementRelTo = None - ifcopenshell.util.element.remove_deep(self.file, old_placement) + ifcopenshell.util.element.remove_deep2(self.file, old_placement) new_placement.PlacementRelTo = placement_rel_to self.settings["product"].ObjectPlacement = new_placement diff --git a/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py b/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py index d840aec181..7c79450d0a 100644 --- a/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py +++ b/src/ifcopenshell-python/test/api/geometry/test_edit_object_placement.py @@ -134,6 +134,39 @@ class TestEditObjectPlacement(test.bootstrap.IFC4): assert numpy.array_equal(ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement), matrix2) assert element.ObjectPlacement != element2.ObjectPlacement + def test_changing_an_object_placement_partially_used_by_other_products(self): + ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") + ifcopenshell.api.run("unit.assign_unit", self.file) + element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") + matrix1 = numpy.array( + ( + (1.0, 0.0, 0.0, 1.0), + (0.0, 1.0, 0.0, 2.0), + (0.0, 0.0, 1.0, 3.0), + (0.0, 0.0, 0.0, 1.0), + ) + ) + matrix2 = numpy.array( + ( + (1.0, 0.0, 0.0, 4.0), + (0.0, 1.0, 0.0, 5.0), + (0.0, 0.0, 1.0, 6.0), + (0.0, 0.0, 0.0, 1.0), + ) + ) + ifcopenshell.api.run( + "geometry.edit_object_placement", self.file, product=element, matrix=matrix1.copy(), is_si=False + ) + element2.ObjectPlacement = self.file.createIfcLocalPlacement( + RelativePlacement=element.ObjectPlacement.RelativePlacement + ) + ifcopenshell.api.run( + "geometry.edit_object_placement", self.file, product=element, matrix=matrix2.copy(), is_si=False + ) + assert numpy.array_equal(ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement), matrix2) + assert numpy.array_equal(ifcopenshell.util.placement.get_local_placement(element2.ObjectPlacement), matrix1) + def test_changing_an_object_placement_shared_by_its_parent(self): ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject") ifcopenshell.api.run("unit.assign_unit", self.file)