mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
5b79cefee2
Spatial.get_root_element walks aggregate / nest / filled-void / voided-element chains and core.assign_container assigns the container to whatever the walk returns. For an IfcDoor the filled-void hop redirects to the IfcOpeningElement, then voided-element to the host wall, so a user who selects a door and runs bim.assign_container ends up targeting the wall — and silently no-ops on the door if the wall is already in the target storey. Per IFC4 / IFC4.3 (IfcDoor, IfcWindow): the spatial containment of a filling is defined independently of the filling relationship. Major exporters (Revit, ArchiCAD, Tekla, Allplan) emit independent ContainedInStructure on doors / windows accordingly. Drop the filled-void / voided-element hops from the walk; aggregate and nest remain — those are true sub-part relationships where the parent legitimately owns the container. New TestGetRootElement in test/tool pins the new contract (filling resolves to itself) plus the retained aggregate / nest / loose-element paths so a future PR that re-adds either hop is caught. Two new TestAssignContainer cases in test/core pin filling-to-self through the core layer and per-element can_contain filtering. Generated with the assistance of an AI coding tool.