| name | ifc-impl-spatial-decomposition |
| description | Use when authoring an IFC file and you must build the spatial breakdown tree and place every physical element into it, or when a wall, slab, or door does not show up in a viewer because it has no storey. Prevents orphan elements, double containment, placing elements with IfcRelAggregates instead of IfcRelContainedInSpatialStructure, and reversing the Relating and Related roles. Covers the top-down build order, IfcRelAggregates wiring, single-container placement, IfcRelReferencedInSpatialStructure for multi-storey elements, the IFC4.3 IfcFacility and IfcFacilityPart tree, and the orphan-check verification step. Keywords: IfcRelAggregates, IfcRelContainedInSpatialStructure, IfcRelReferencedInSpatialStructure, IfcProject, IfcSite, IfcBuilding, IfcBuildingStorey, IfcSpace, IfcFacility, IfcFacilityPart, spatial decomposition, spatial breakdown, build the spatial tree, place element in storey, orphan element, element not in viewer, wall has no storey, element missing from model, how do I add a wall to a storey, multi-storey element, stair spanning floors.
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires IFC IFC2x3, IFC4, IFC4.3. |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
ifc-impl-spatial-decomposition
This skill is the write-side workflow for the IFC spatial structure. It teaches
the exact order of operations to build the spatial breakdown tree, place every
physical element into it, and verify that no element is left orphaned.
For the structure itself (what the tree is, the entity hierarchy, WHERE rules)
see ifc-core-spatial-structure. For failure recovery see
ifc-errors-spatial-structure. For the overall file-authoring sequence see
ifc-impl-authoring-file.
ALWAYS build the spatial tree before placing any element. An element placed
into a node that does not yet exist cannot be wired, and an element with no
container is an orphan that the buildingSMART validation service and most
viewers reject.
Quick Reference
The decomposition workflow (7 steps, in order)
1. Create IfcProject the context root, NOT a spatial node
2. Create the spatial nodes top-down Site, Building/Facility, Storey, Space
3. Wire the tree with IfcRelAggregates one relationship per parent node
4. Create the physical elements IfcWall, IfcSlab, IfcDoor, ...
5. Place each element IfcRelContainedInSpatialStructure,
exactly one container per element
6. Reference spanning elements IfcRelReferencedInSpatialStructure,
for elements reaching extra nodes
7. Verify every element has exactly one
container; every node reaches the
project; no orphans
The two wiring relationships : NEVER confuse them
| Relationship | Wires | Relating role | Related role |
|---|
IfcRelAggregates | spatial node to spatial node (the tree) | RelatingObject : the parent node (1) | RelatedObjects : SET [1:?] of child nodes |
IfcRelContainedInSpatialStructure | physical element into one spatial node | RelatingStructure : the containing node | RelatedElements : SET [1:?] of IfcProduct |
IfcRelReferencedInSpatialStructure | physical element to extra nodes (non-tree) | RelatingStructure : the referencing node | RelatedElements : SET [1:?] of IfcSpatialReferenceSelect |
Hard rules
- ALWAYS create a node before any relationship that points at it. STEP entity
order in the file does not matter, but the node instance must exist.
- ALWAYS wire each spatial node to its parent with
IfcRelAggregates. This is
rule WR41 on IfcSpatialStructureElement, verbatim : "All spatial structure
elements shall be associated (using the IfcRelAggregates relationship) with
another spatial structure element, or with IfcProject."
- ALWAYS place each physical element into exactly one node with
IfcRelContainedInSpatialStructure. IfcElement.ContainedInStructure is
SET [0:1] : the schema permits zero or one container, never two.
- NEVER use
IfcRelAggregates to place a physical element into a storey. It
builds the tree of spatial nodes only. Placing a wall this way makes the
wall a child node of the tree, not contained content.
- NEVER use
IfcRelContainedInSpatialStructure to nest a spatial node inside
another. Rule WR31 forbids it, 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."
- NEVER reverse
Relating and Related. Putting the storey in
RelatedElements and the wall in RelatingStructure produces a
schema-valid but meaningless model.
- NEVER aggregate anything above
IfcProject. IfcProject.NoDecomposition
requires IfcProject.Decomposes to be empty : the project is the apex.
Decision Trees
Which spatial node contains this element?
What kind of physical element?
|
+-- Terrain, landscaping, fencing, site utility --> contain in IfcSite
+-- Element belonging to the whole building --> contain in IfcBuilding
| (foundation slab spanning the footprint,
| a site-wide vertical shaft)
+-- Normal wall, slab, beam, column, door, window --> contain in IfcBuildingStorey
+-- Furniture, equipment, sanitary item in a room --> contain in IfcSpace
|
+-- Element spans several storeys (tall column,
multi-storey curtain wall, a stair)
--> contain in ONE storey, reference the rest
with IfcRelReferencedInSpatialStructure
Default rule : when in doubt, contain a physical element in the
IfcBuildingStorey. Storey-level containment is what viewers, schedules, and
quantity take-off tools expect.
Contain or reference?
Does the element belong to exactly one spatial node?
|
+-- Yes --> one IfcRelContainedInSpatialStructure. Done.
|
+-- No, it physically reaches several nodes
--> pick the PRIMARY node (where the element starts, or its base level)
1. one IfcRelContainedInSpatialStructure into the primary node
2. one IfcRelReferencedInSpatialStructure per additional node
NEVER add a second IfcRelContainedInSpatialStructure : containment is
single by schema (SET [0:1]).
Which version's tree am I building?
Target IFC version?
|
+-- IFC2x3 --> IfcProject > IfcSite > IfcBuilding > IfcBuildingStorey > IfcSpace
| CompositionType is MANDATORY on every node.
| OwnerHistory is MANDATORY on every rooted instance.
|
+-- IFC4 --> same five-level tree as IFC2x3.
| CompositionType and OwnerHistory became OPTIONAL.
|
+-- IFC4.3 --> IfcProject > IfcSite > IfcFacility-subtype
> storey-slot > IfcSpace.
For buildings : IfcBuilding (a subtype of IfcFacility) and
IfcBuildingStorey (still a direct subtype of
IfcSpatialStructureElement).
For infrastructure : IfcBridge / IfcRoad / IfcRailway /
IfcMarineFacility and an IfcFacilityPart subtype
(IfcBridgePart / IfcRoadPart / IfcRailwayPart /
IfcMarinePart / IfcFacilityPartCommon).
Patterns
Pattern : build the tree top-down
ALWAYS create the tree in this order so every relationship target exists:
- Create
IfcProject. Give it Name, UnitsInContext, and
RepresentationContexts. It is the context root, not a spatial node.
- Create
IfcSite, then IfcBuilding, then each IfcBuildingStorey, then
each IfcSpace. Set CompositionType to .ELEMENT. on each ordinary node.
- Wire the levels with one
IfcRelAggregates per parent :
IfcProject --aggregates--> IfcSite
IfcSite --aggregates--> IfcBuilding
IfcBuilding --aggregates--> all its IfcBuildingStorey nodes
- each
IfcBuildingStorey --aggregates--> its IfcSpace nodes (if any)
- In each
IfcRelAggregates, the parent is the single RelatingObject and
the children fill the RelatedObjects set. One relationship instance can
carry many children, so all storeys of one building share one
IfcRelAggregates.
See references/examples.md for a complete verified STEP fragment.
Pattern : place a physical element
After the tree exists, place each physical element with one
IfcRelContainedInSpatialStructure :
RelatingStructure = the chosen spatial node (usually the storey).
RelatedElements = the set of products to place there.
One relationship instance can place many elements at once, so all walls of one
storey share a single IfcRelContainedInSpatialStructure. Prefer one
containment relationship per spatial node, not one per element : it is fewer
instances and the same semantics.
Pattern : multi-storey element
A stair, a tall column, or a multi-storey curtain wall physically belongs to
more than one storey. Model it once, reference it elsewhere:
- Choose the PRIMARY storey (the base level the element starts on).
- One
IfcRelContainedInSpatialStructure puts the element in that storey.
- One
IfcRelReferencedInSpatialStructure per additional storey the element
reaches. Its RelatingStructure is the extra storey, its RelatedElements
set holds the element.
IfcRelReferencedInSpatialStructure is non-hierarchical : an element may be
referenced by several nodes while it is contained by exactly one. NEVER model
the spanning element with two containments.
Pattern : IFC4.3 facility tree
In IFC4.3 the building-only chain generalises to facilities. IfcBuilding is a
subtype of the abstract IfcFacility. An infrastructure project uses
IfcBridge, IfcRoad, IfcRailway, or IfcMarineFacility in the same tree
slot as IfcBuilding. The storey slot is filled by IfcBuildingStorey for
buildings, or by an IfcFacilityPart subtype for infrastructure
(IfcBridgePart, IfcRoadPart, IfcRailwayPart, IfcMarinePart,
IfcFacilityPartCommon). IfcFacilityPart carries UsageType
(IfcFacilityUsageEnum) to declare how the facility is subdivided.
The wiring is unchanged : every node still attaches to its parent with
IfcRelAggregates and obeys WR41, and physical elements are still placed with
IfcRelContainedInSpatialStructure.
Pattern : verify no orphan elements
Run this check after step 5 of the workflow, before writing the file out:
For every IfcElement occurrence in the model:
count its IfcRelContainedInSpatialStructure links
(the inverse attribute IfcElement.ContainedInStructure)
|
+-- count == 1 --> OK
+-- count == 0 --> ORPHAN. Add an IfcRelContainedInSpatialStructure.
+-- count > 1 --> schema-invalid (ContainedInStructure is SET [0:1]).
Remove the extra containment relationships.
For every spatial node:
walk Decomposes upward via IfcRelAggregates
|
+-- reaches IfcProject --> OK
+-- does not reach it --> DETACHED node. Add the missing
IfcRelAggregates to its parent.
A node detached from the project and an element with no container are the two
failures the buildingSMART validation service reports most for this area. See
ifc-errors-spatial-structure for the full error catalogue.
Version Matrix
| Aspect | IFC2x3 | IFC4 | IFC4.3 |
|---|
| Tree levels | Project, Site, Building, Storey, Space | same | Project, Site, Facility-subtype, storey-slot, Space |
CompositionType | mandatory on every node | optional | optional |
IfcRoot.OwnerHistory | mandatory | optional | optional |
| Building entity | IfcBuilding under IfcSpatialStructureElement | same | IfcBuilding is a subtype of IfcFacility |
| Infrastructure facilities | not available | not available | IfcBridge, IfcRoad, IfcRailway, IfcMarineFacility |
IfcRelReferencedInSpatialStructure RelatedElements type | SET OF IfcProduct | SET OF IfcProduct | SET OF IfcSpatialReferenceSelect |
| Tree wiring relationship | IfcRelAggregates | IfcRelAggregates | IfcRelAggregates |
| Element placement relationship | IfcRelContainedInSpatialStructure | same | same |
Reference Links
references/methods.md : entity and attribute signatures for the three
decomposition relationships and the spatial nodes, WHERE rules WR31 / WR41 /
NoSelfReference, per-version notes, source URLs.
references/examples.md : verified STEP fragments for the full tree, element
placement, multi-storey reference, the IFC4.3 facility tree, and the
orphan-check procedure.
references/anti-patterns.md : the spatial-decomposition mistakes that break
files, and why each one fails.
Related skills : ifc-core-spatial-structure, ifc-core-relationships,
ifc-errors-spatial-structure, ifc-impl-authoring-file,
ifc-syntax-building-elements.
Authoritative sources (see SOURCES.md) :