diff --git a/src/ifcopenshell-python/ifcopenshell/util/selector.py b/src/ifcopenshell-python/ifcopenshell/util/selector.py index 9889e8c373..bed118ac70 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/selector.py +++ b/src/ifcopenshell-python/ifcopenshell/util/selector.py @@ -18,6 +18,7 @@ import re import lark +import ifcopenshell.api import ifcopenshell.util import ifcopenshell.util.fm import ifcopenshell.util.unit @@ -357,7 +358,19 @@ def set_element_value( elif key == "classification": element = ifcopenshell.util.classification.get_references(element) elif key in ("x", "y", "z", "easting", "northing", "elevation") and hasattr(element, "ObjectPlacement"): - return + # TODO: add support + if key in ("easting", "northing", "elevation"): + return + + placement = getattr(element, "ObjectPlacement", None) + if not placement: + return + matrix = ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement) + coord_i = "xyz".index(key) + matrix[coord_i][3] = float(value) if value else 0.0 + ifcopenshell.api.run( + "geometry.edit_object_placement", ifc_file, product=element, matrix=matrix, is_si=False + ) elif isinstance(element, ifcopenshell.entity_instance): if key == "Name" and element.is_a("IfcMaterialLayerSet"): key = "LayerSetName" # This oddity in the IFC spec is annoying so we account for it. diff --git a/src/ifcopenshell-python/test/util/test_selector.py b/src/ifcopenshell-python/test/util/test_selector.py index ff312bec61..51c449e633 100644 --- a/src/ifcopenshell-python/test/util/test_selector.py +++ b/src/ifcopenshell-python/test/util/test_selector.py @@ -267,6 +267,19 @@ class TestFilterElements(test.bootstrap.IFC4): assert new_set == original_set +class TestSetElementValue(test.bootstrap.IFC4): + def test_set_xyz_coordinates(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") + ifcopenshell.api.run("geometry.edit_object_placement", self.file, product=element, is_si=False) + for coord, value in zip("xyz", ("5", "10", "15")): + subject.set_element_value(self.file, element, coord, value) + matrix = np.eye(4) + matrix[:, 3] = (5, 10, 15, 1) + assert np.array_equal(ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement), matrix) + + class TestSelector(test.bootstrap.IFC4): def test_selecting_by_class(self): element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")