From 644f32d11c7eb8613737a7105eeb7b9b5e868968 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Thu, 8 Aug 2024 16:52:52 +0500 Subject: [PATCH] Fix errors appending assets when projects are using georeferencing #5110 --- .../ifcopenshell/api/project/append_asset.py | 10 +++++ .../test/api/project/test_append_asset.py | 38 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py b/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py index 08bd45197f..b62a677905 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py +++ b/src/ifcopenshell-python/ifcopenshell/api/project/append_asset.py @@ -17,11 +17,14 @@ # along with IfcOpenShell. If not, see . import ifcopenshell +import ifcopenshell.api.geometry import ifcopenshell.api.type import ifcopenshell.api.project import ifcopenshell.api.context import ifcopenshell.api.owner.settings import ifcopenshell.util.element +import ifcopenshell.util.geolocation +import ifcopenshell.util.placement from typing import Optional, Any, Union @@ -206,6 +209,13 @@ class Usecase: element = self.add_element(self.settings["element"]) self.reuse_existing_contexts() + placement = element.ObjectPlacement + if placement is not None: + matrix = ifcopenshell.util.placement.get_local_placement(placement) + matrix = ifcopenshell.util.geolocation.auto_local2global(self.settings["library"], matrix) + matrix = ifcopenshell.util.geolocation.auto_global2local(self.file, matrix) + ifcopenshell.api.geometry.edit_object_placement(self.file, element, matrix, is_si=False) + element_type = ifcopenshell.util.element.get_type(self.settings["element"]) if element_type: ifcopenshell.api.owner.settings.factory_reset() diff --git a/src/ifcopenshell-python/test/api/project/test_append_asset.py b/src/ifcopenshell-python/test/api/project/test_append_asset.py index b4aceceed6..7de3457320 100644 --- a/src/ifcopenshell-python/test/api/project/test_append_asset.py +++ b/src/ifcopenshell-python/test/api/project/test_append_asset.py @@ -17,6 +17,8 @@ # along with IfcOpenShell. If not, see . import test.bootstrap +import ifcopenshell.api.geometry +import ifcopenshell.api.georeference import ifcopenshell.api.pset import ifcopenshell.api.root import ifcopenshell.api.type @@ -27,6 +29,8 @@ import ifcopenshell.api.context import ifcopenshell.api.project import ifcopenshell.api.material import ifcopenshell.util.element +import ifcopenshell.util.placement +import numpy as np class TestAppendAssetIFC2X3(test.bootstrap.IFC2X3): @@ -370,6 +374,40 @@ class TestAppendAssetIFC2X3(test.bootstrap.IFC2X3): ifcopenshell.api.project.append_asset(self.file, library=library, element=element) assert self.file.by_type("IfcWall")[0].HasOpenings[0].RelatedOpeningElement.is_a("IfcOpeningElement") + def test_append_a_product_when_projects_have_georeference(self): + ifc_file = ifcopenshell.file() + ifcopenshell.api.root.create_entity(ifc_file, ifc_class="IfcProject") + ifcopenshell.api.context.add_context(ifc_file, "Model") + ifcopenshell.api.georeference.add_georeferencing(ifc_file) + ifcopenshell.api.georeference.edit_georeferencing( + ifc_file, coordinate_operation={"Eastings": 3.0, "Northings": 23.0} + ) + + library = ifcopenshell.file.from_string(ifc_file.to_string()) + ifcopenshell.api.georeference.edit_georeferencing( + library, coordinate_operation={"Eastings": 29, "Northings": 42} + ) + element = ifcopenshell.api.root.create_entity(library, ifc_class="IfcWall") + matrix = np.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), + ) + ) + ifcopenshell.api.geometry.edit_object_placement(library, element, matrix) + new = ifcopenshell.api.project.append_asset(ifc_file, library=library, element=element) + resulting_matrix = np.array( + ( + (1.0, 0.0, 0.0, 27.0), + (0.0, 1.0, 0.0, 21.0), + (0.0, 0.0, 1.0, 3.0), + (0.0, 0.0, 0.0, 1.0), + ) + ) + assert np.array_equal(ifcopenshell.util.placement.get_local_placement(new.ObjectPlacement), resulting_matrix) + class TestAppendAssetIFC4(test.bootstrap.IFC4, TestAppendAssetIFC2X3): # NOTE: breaks in IFC2X3 since IfcProfileDef doesn't have "HasProperties" inverse in ifc2x3