# Ifc Core Spatial Structure

> Use when building, reading, or fixing the IFC spatial structure : the mandatory Project to Site to Building to Storey to Space containment tree, or its IFC4.3 facility variant. Prevents orphan elements, double containment, mixing IfcRelAggregates with IfcRelContainedInSpatialStructure, and treating IfcProject as a spatial node. Covers IfcProject and IfcContext, IfcSpatialStructureElement, the decomposition chain, CompositionType, containment versus reference, the WR41 and WR31 rules, and the IFC4.3 IfcFacility restructuring. Keywords: IfcProject, IfcSite, IfcBuilding, IfcBuildingStorey, IfcSpace, IfcSpatialStructureElement, IfcRelAggregates, IfcRelContainedInSpatialStructure, IfcRelReferencedInSpatialStructure, IfcFacility, IfcFacilityPart, CompositionType, spatial tree, spatial hierarchy, WR41, WR31, orphan element, element not in viewer, element has no storey, wall not showing up, where does my wall go, how do I structure an IFC project, building storeys.

- Skill: `impertio-studio/ifc-core-spatial-structure` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add impertio-studio/ifc-core-spatial-structure`
- Raw SKILL.md: https://api.skillmd.com/api/skills/impertio-studio/ifc-core-spatial-structure/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: Impertio-Studio (https://skillmd.com/u/impertio-studio)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/impertio-studio/ifc-core-spatial-structure

---


# ifc-core-spatial-structure

The spatial structure is the mandatory skeleton of every IFC model. It is a
single acyclic tree, rooted at `IfcProject`, that locates every physical element
in space. ALWAYS build the spatial tree before placing any element. An element
with no place in this tree is an orphan and is rejected by the buildingSMART
validation service and by most viewers.

This skill teaches the spatial tree itself. For the relationship machinery in
general see `ifc-core-relationships`; for write-side workflow see
`ifc-impl-spatial-decomposition`; for failure recovery see
`ifc-errors-spatial-structure`.

## Quick Reference

### The spatial tree (IFC2x3, IFC4)

```
IfcProject                          context root, NOT a spatial element
   |  IfcRelAggregates
   v
IfcSite                             spatial structure element
   |  IfcRelAggregates
   v
IfcBuilding                         spatial structure element
   |  IfcRelAggregates
   v
IfcBuildingStorey                   spatial structure element
   |  IfcRelAggregates
   v
IfcSpace                            spatial structure element (optional leaf)
   ^
   |  IfcRelContainedInSpatialStructure
   +---- physical IfcElement (IfcWall, IfcDoor, IfcSlab, ...)
```

### Core entities

| Entity | Role | Versions |
|--------|------|----------|
| `IfcProject` | Context root. Owns units and representation contexts. NOT spatial. | all |
| `IfcSpatialElement` | Abstract base for all spatial things. Adds `LongName`. | IFC4, IFC4.3 |
| `IfcSpatialStructureElement` | Abstract base for the tree nodes. Adds `CompositionType`. | all |
| `IfcSite` | Site node. Direct subtype of `IfcSpatialStructureElement`. | all |
| `IfcBuilding` | Building node. | all |
| `IfcBuildingStorey` | Storey node. Direct subtype of `IfcSpatialStructureElement`. | all |
| `IfcSpace` | Space node. The usual leaf of the tree. | all |
| `IfcFacility` / `IfcFacilityPart` | IFC4.3 generalisation of building / storey. | IFC4.3 only |

### The two wiring relationships : NEVER confuse them

| Relationship | Purpose | NEVER |
|--------------|---------|-------|
| `IfcRelAggregates` | Builds the spatial TREE (parent spatial node to child spatial node). Also used for element assemblies. | NEVER use it to place a physical element into a storey. |
| `IfcRelContainedInSpatialStructure` | Places a physical `IfcElement` INTO exactly one spatial node. | NEVER use it to nest one spatial node inside another (WR31). |

### Hard rules

- ALWAYS attach every spatial structure element to a parent spatial node or to
  `IfcProject` using `IfcRelAggregates`. This is rule WR41, verbatim : "All
  spatial structure elements shall be associated (using the IfcRelAggregates
  relationship) with another spatial structure element, or with IfcProject."
- ALWAYS contain every physical element in exactly one spatial node via
  `IfcRelContainedInSpatialStructure`. `IfcElement.ContainedInStructure` is
  `SET [0:1]`, so double containment is impossible by schema; zero containment
  is an orphan and a validation failure.
- NEVER aggregate anything above `IfcProject`. `IfcProject.NoDecomposition`
  requires `IfcObjectDefinition.Decomposes` to be empty : the project is the
  apex.
- NEVER place a spatial structure element in
  `IfcRelContainedInSpatialStructure.RelatedElements`. Rule WR31, verbatim :
  "The relationship object shall not be used to include other spatial structure
  elements into a spatial structure element. The hierarchy of the spatial
  structure is defined using IfcRelAggregates."
- ALWAYS set `IfcRelContainedInSpatialStructure.RelatingStructure` to the
  containing node and `RelatedElements` to the contained products. Reversing
  Relating and Related produces a structurally valid but meaningless model.

## Decision Trees

### Which relationship do I use?

```
Connecting two things in the spatial model?
|
+-- Both are spatial nodes (Site, Building, Storey, Space, Facility)?
|   --> IfcRelAggregates   (parent = RelatingObject, children = RelatedObjects)
|
+-- One is a physical element, the other a spatial node?
|   --> IfcRelContainedInSpatialStructure
|       (node = RelatingStructure, elements = RelatedElements)
|
+-- A physical element belongs primarily to one node but also spans others?
    --> IfcRelContainedInSpatialStructure for the primary node
        PLUS IfcRelReferencedInSpatialStructure for each extra node
```

### Which spatial node contains this element?

```
What kind of element?
|
+-- Terrain, landscaping, site-wide utility   --> contain in IfcSite
+-- Element belonging to the whole building   --> contain in IfcBuilding
+-- Normal wall, slab, column, door, window   --> contain in IfcBuildingStorey
+-- Furniture, equipment inside a room        --> contain in IfcSpace
|
+-- Element spans several storeys (a tall column, a multi-storey
    curtain wall, a stair)
    --> contain in ONE storey, reference the others with
        IfcRelReferencedInSpatialStructure
```

Default rule : when in doubt, contain a physical element in the
`IfcBuildingStorey`. Storey-level containment is what viewers and quantity
take-off tools expect.

### Which spatial model for which IFC version?

```
Target IFC version?
|
+-- IFC2x3  --> Project > Site > Building > BuildingStorey > Space
|              IfcSpatialStructureElement is a direct subtype of IfcProduct.
|              CompositionType is MANDATORY. OwnerHistory is MANDATORY.
|
+-- IFC4    --> same tree as IFC2x3.
|              IfcSpatialElement is inserted as the new abstract base.
|              CompositionType and OwnerHistory became OPTIONAL.
|
+-- IFC4.3  --> Project > Site > IfcFacility > IfcFacilityPart > Space,
               where IfcBuilding IS-A IfcFacility and IfcBuildingStorey is
               still a direct subtype of IfcSpatialStructureElement.
               Use IfcBuilding / IfcBuildingStorey for buildings;
               use IfcBridge, IfcRoad, IfcRailway, IfcMarineFacility and
               their *Part siblings for infrastructure.
```

## Patterns

### Pattern : build the tree top-down

ALWAYS create `IfcProject` first, then `IfcSite`, `IfcBuilding`,
`IfcBuildingStorey`, then wire each parent to its children with one
`IfcRelAggregates` per level. `IfcProject` carries the units and representation
contexts the whole model depends on. See `references/examples.md` for a
complete verified STEP fragment.

### Pattern : contain a physical element

After the tree exists, place each physical element with one
`IfcRelContainedInSpatialStructure` whose `RelatingStructure` is the chosen node
(usually the storey) and whose `RelatedElements` lists the products. One
relationship instance can carry many elements in its `RelatedElements` set.

### Pattern : element spanning two storeys

A stair, a tall column, or a multi-storey curtain wall is contained in exactly
ONE storey (its primary home) and referenced in every other storey it reaches
with `IfcRelReferencedInSpatialStructure`. The reference relationship is
non-hierarchical : an element may be referenced by several nodes, while it is
contained by exactly one.

### Pattern : IFC4.3 facility tree

In IFC4.3 the building-only chain generalises. `IfcBuilding` is a subtype of
`IfcFacility`, and infrastructure projects use `IfcBridge`, `IfcRoad`,
`IfcRailway`, or `IfcMarineFacility` in the same tree slot. The storey-level
slot is filled by `IfcBuildingStorey` for buildings or by an `IfcFacilityPart`
subtype (`IfcRoadPart`, `IfcBridgePart`, `IfcRailwayPart`, `IfcMarinePart`,
`IfcFacilityPartCommon`) for infrastructure. The wiring is unchanged : every
node still attaches with `IfcRelAggregates` and obeys WR41.

### Pattern : CompositionType

`CompositionType` (`IfcElementCompositionEnum`) declares whether a node is a
whole, an aggregate, or a fragment. ALWAYS set it to `.ELEMENT.` for an ordinary
self-contained node. Use `.COMPLEX.` for a node that aggregates like nodes (a
building complex) and `.PARTIAL.` for a fragment of a larger node. In IFC2x3
this attribute is mandatory; in IFC4 and IFC4.3 it is optional but setting it
remains best practice.

## Version Matrix

| Aspect | IFC2x3 | IFC4 | IFC4.3 |
|--------|--------|------|--------|
| Abstract base of tree nodes | `IfcSpatialStructureElement` directly under `IfcProduct` | `IfcSpatialElement` inserted as new base | `IfcSpatialElement` base |
| `CompositionType` | mandatory | optional | optional |
| `IfcRoot.OwnerHistory` | mandatory | optional | optional |
| Building / storey slot | `IfcBuilding`, `IfcBuildingStorey` | same | `IfcBuilding` IS-A `IfcFacility`; `IfcFacility` / `IfcFacilityPart` for infrastructure |
| `IfcSpace` interior flag | `InteriorOrExteriorSpace` attribute | `PredefinedType` plus `Pset_SpaceCommon.IsExternal` | same as IFC4 |

## Reference Links

- `references/methods.md` : full entity and attribute signatures, WHERE rules,
  per-version notes, source URLs.
- `references/examples.md` : verified STEP fragments for the full tree,
  containment, cross-storey reference, and the IFC4.3 facility tree.
- `references/anti-patterns.md` : the common spatial-structure mistakes and why
  each one fails.

Related skills : `ifc-core-relationships`, `ifc-core-entity-hierarchy`,
`ifc-impl-spatial-decomposition`, `ifc-errors-spatial-structure`,
`ifc-syntax-building-elements`.

Authoritative sources (see `SOURCES.md`) :
- IFC 4.3.2 specification : https://ifc43-docs.standards.buildingsmart.org/
- IFC 4 ADD2 TC1 specification :
  https://standards.buildingsmart.org/IFC/RELEASE/IFC4/ADD2_TC1/HTML/
- IFC 2x3 TC1 specification :
  https://standards.buildingsmart.org/IFC/RELEASE/IFC2x3/TC1/HTML/

