diff --git a/src/ifcopenshell-python/ifcopenshell/api/nest/assign_object.py b/src/ifcopenshell-python/ifcopenshell/api/nest/assign_object.py index d3432b617f..579d0e7a11 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/nest/assign_object.py +++ b/src/ifcopenshell-python/ifcopenshell/api/nest/assign_object.py @@ -19,7 +19,9 @@ from typing import Union import ifcopenshell +import ifcopenshell.api.aggregate import ifcopenshell.api.owner +import ifcopenshell.api.spatial import ifcopenshell.guid import ifcopenshell.util.element @@ -137,7 +139,10 @@ def assign_object( if not objects_to_change: return is_nested_by - # NOTE: An object can both be nested and assigned to a container or an aggregate. + # Can be either only nested, aggregated, or contained at the same time. + possibly_contained = [o for o in objects_without_nests if hasattr(o, "ContainedInStructure")] + ifcopenshell.api.spatial.unassign_container(file, products=possibly_contained) + ifcopenshell.api.aggregate.unassign_object(file, products=objects_without_nests) # unassign elements from previous nests for nests in previous_nests_rels: diff --git a/src/ifcopenshell-python/test/api/nest/test_assign_object.py b/src/ifcopenshell-python/test/api/nest/test_assign_object.py index 88f8d0bb90..c83f796ac0 100644 --- a/src/ifcopenshell-python/test/api/nest/test_assign_object.py +++ b/src/ifcopenshell-python/test/api/nest/test_assign_object.py @@ -18,8 +18,10 @@ import pytest +import ifcopenshell.api.aggregate import ifcopenshell.api.nest import ifcopenshell.api.root +import ifcopenshell.api.spatial import ifcopenshell.util.element import test.bootstrap @@ -82,6 +84,24 @@ class TestAssignObject(test.bootstrap.IFC4): ifcopenshell.api.nest.assign_object(self.file, related_objects=subelements[2:3], relating_object=element2) assert rel.RelatedObjects == tuple(subelements[:2] + subelements[3:]) + def test_nesting_removes_spatial_containment(self): + element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall") + subelement = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall") + storey = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcBuildingStorey") + ifcopenshell.api.spatial.assign_container(self.file, products=[subelement], relating_structure=storey) + assert ifcopenshell.util.element.get_container(subelement) == storey + ifcopenshell.api.nest.assign_object(self.file, related_objects=[subelement], relating_object=element) + assert ifcopenshell.util.element.get_container(subelement) is None + + def test_nesting_removes_aggregate(self): + element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall") + subelement = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall") + assembly = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcElementAssembly") + ifcopenshell.api.aggregate.assign_object(self.file, products=[subelement], relating_object=assembly) + assert ifcopenshell.util.element.get_aggregate(subelement) == assembly + ifcopenshell.api.nest.assign_object(self.file, related_objects=[subelement], relating_object=element) + assert ifcopenshell.util.element.get_aggregate(subelement) is None + class TestAssignObjectIFC2X3(test.bootstrap.IFC2X3, TestAssignObject): pass