# Ifc Core Entity Hierarchy

> Use when navigating or authoring the IFC entity inheritance tree, choosing which entity to instantiate, generating IFC GlobalId values, or deciding between a type object and an occurrence. Prevents instantiating abstract supertypes, regenerating GUIDs on every export, confusing IfcTypeObject with IfcObject, and misusing IfcBuildingElementProxy as a placeholder. Covers IfcRoot and its four attributes, the IfcObjectDefinition to IfcBuiltElement object chain, the 22-character compressed IFC GUID, the type versus occurrence model, the PredefinedType enumeration pattern, and the IFC4.3 IfcBuildingElement to IfcBuiltElement rename. Keywords: IfcRoot, IfcBuiltElement, IfcBuildingElement, GlobalId, IfcGloballyUniqueId, IFC GUID, IfcObjectDefinition, IfcObject, IfcProduct, IfcElement, IfcTypeObject, IfcTypeProduct, IfcElementType, IfcRelDefinesByType, PredefinedType, IfcBuildingElementProxy, abstract entity, type vs occurrence, which IFC entity do I use, GUID keeps changing, cannot instantiate abstract entity, IFC ent

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

---


# IFC Entity Hierarchy

The IFC schema is a deep single-inheritance tree. Every meaningful object,
relationship, and property definition descends from one abstract root,
`IfcRoot`. This skill covers the identity backbone, the object inheritance
chain down to concrete construction elements, the type versus occurrence
model, and the IFC GUID. Verified against the IFC 4.3.2 specification
(ISO 16739-1:2024) with IFC4 and IFC2x3 deltas noted inline.

Applies to IFC2x3, IFC4, IFC4.3. Read the version annotations: one hard
file-breaking rename (`IfcBuildingElement` to `IfcBuiltElement`) sits inside
this hierarchy.

## Quick Reference

### IfcRoot: the identity backbone

`IfcRoot` is abstract. Every entity needing independent identity, ownership
tracking, and a human label derives from it. ALWAYS place a valid `GlobalId`
as the first positional attribute of every rooted instance.

| # | Attribute | Type | Cardinality | Notes |
|---|-----------|------|-------------|-------|
| 1 | `GlobalId` | `IfcGloballyUniqueId` | required | 22-char compressed GUID. UNIQUE within the file. |
| 2 | `OwnerHistory` | `IfcOwnerHistory` | optional | Optional in IFC4 and IFC4.3. Mandatory in IFC2x3. |
| 3 | `Name` | `IfcLabel` | optional | Some subtypes promote it to required via a WHERE rule. |
| 4 | `Description` | `IfcText` | optional | Free-text comment. |

`IfcRoot` has exactly three direct subtypes. This three-way split is the
schema's top-level conceptual division:

| Subtype | Role |
|---------|------|
| `IfcObjectDefinition` | Semantically treated things or processes (types and occurrences). |
| `IfcRelationship` | Objectified relationships between objects. |
| `IfcPropertyDefinition` | Property and property-set definitions. |

This skill covers the `IfcObjectDefinition` branch. See `ifc-core-relationships`
for `IfcRelationship` and `ifc-syntax-property-sets` for `IfcPropertyDefinition`.

### The object chain

```
IfcRoot                    abstract  : identity (GlobalId, OwnerHistory, Name, Description)
  IfcObjectDefinition      abstract  : objects, types, contexts
    IfcObject              abstract  : an occurrence; adds ObjectType
      IfcProduct           abstract  : adds ObjectPlacement, Representation
        IfcElement         abstract  : a physical component; adds Tag
          IfcBuiltElement  IFC4.3 CONCRETE  /  IfcBuildingElement IFC2x3+IFC4 abstract
            IfcWall, IfcSlab, IfcBeam, IfcColumn, IfcDoor, IfcWindow, ...  concrete
```

Resources and details are in `references/methods.md`. Direct subtype counts
(IFC4.3, verified): `IfcObjectDefinition` has 3, `IfcObject` has 6,
`IfcProduct` has 8, `IfcElement` has 11, `IfcBuiltElement` has 30.

### Abstract entities: NEVER instantiate

NEVER write an instance of an abstract entity into an IFC file. Instantiate a
concrete leaf instead. Abstract entities in this hierarchy:

`IfcRoot`, `IfcObjectDefinition`, `IfcObject`, `IfcProduct`, `IfcElement`,
`IfcTypeObject`, `IfcTypeProduct`, `IfcElementType`, and `IfcBuildingElement`
(IFC2x3 and IFC4 only).

Concrete entities you DO instantiate: `IfcWall`, `IfcSlab`, `IfcBeam`,
`IfcColumn`, `IfcDoor`, `IfcWindow`, `IfcWallType`, `IfcBuildingElementProxy`,
and (IFC4.3 only) `IfcBuiltElement` itself.

### Critical version rename

| Aspect | IFC2x3, IFC4 | IFC4.3 |
|--------|--------------|--------|
| Entity name | `IfcBuildingElement` | `IfcBuiltElement` |
| Abstract? | abstract (never instantiated) | non-abstract (may be instantiated) |

The IFC4.3 CHANGE note: "The entity has been renamed from IfcBuildingElement
and made non abstract." The old name `IfcBuildingElement` returns HTTP 404 in
the IFC4.3 lexical documentation. ALWAYS pick the entity name by target
version: `IfcBuildingElement` for IFC2x3 and IFC4, `IfcBuiltElement` for
IFC4.3. This rename does NOT affect the concrete leaves (`IfcWall`, `IfcSlab`
and the rest keep their names across all three versions).

## Decision Trees

### Which entity should I instantiate?

```
Need to represent a thing in an IFC file?
|
+- Is it a physical construction component (wall, slab, beam, door)?
|    |
|    +- Yes : does a specific concrete entity exist for it?
|    |    +- Yes -> instantiate that concrete entity (IfcWall, IfcSlab, ...)
|    |    +- No, semantics genuinely unknown -> IfcBuildingElementProxy
|    |
|    +- No : continue
|
+- Is it the shared definition reused by many occurrences (a product type)?
|    -> instantiate the matching *Type entity (IfcWallType, IfcDoorType, ...)
|
+- Is it spatial (project, site, building, storey, space)?
|    -> see ifc-core-spatial-structure
|
+- Is it a relationship between objects?
     -> see ifc-core-relationships
```

NEVER instantiate `IfcElement`, `IfcProduct`, `IfcObject`, or
`IfcBuiltElement` (in IFC2x3/IFC4 named `IfcBuildingElement`) to mean "some
generic element". Instantiate the concrete leaf. The one exception:
`IfcBuiltElement` is itself instantiable in IFC4.3, but ONLY when no concrete
subtype fits and the element is still a primary construction component.

### Type object or occurrence?

```
Does this data describe one physically placed instance, or a shared template?
|
+- One physical instance, placed somewhere, with its own geometry transform
|    -> an OCCURRENCE : an IfcObject subtype (IfcWall, IfcDoor, ...)
|    -> carries ObjectPlacement and Representation
|
+- A reusable definition shared by many instances (catalogue product)
     -> a TYPE : an IfcTypeObject subtype (IfcWallType, IfcDoorType, ...)
     -> carries HasPropertySets and RepresentationMaps, NOT ObjectPlacement
     -> link to occurrences with one IfcRelDefinesByType
```

ALWAYS keep geometry-placement data on the occurrence. NEVER put
`ObjectPlacement` on a type: `IfcTypeProduct` has no `ObjectPlacement`
attribute. Type geometry is reusable and lives in `RepresentationMaps`.

When the same property name exists on both the type and the occurrence, the
OCCURRENCE value wins. The type provides the default, the occurrence overrides
it. See `references/methods.md` for the resolution order.

### Concrete entity or IfcBuildingElementProxy?

```
The semantic class of this construction element is...
|
+- Known and a concrete entity exists -> use that concrete entity. STOP.
|
+- Genuinely unknown or unclassifiable, but it is a real construction element
|    -> IfcBuildingElementProxy with PredefinedType = USERDEFINED
|       and ObjectType set to your own term
|
+- A spatial placeholder or a provision for a future void/space
     -> IFC4.3 : use IfcVirtualElement. NEVER IfcBuildingElementProxy.
     -> IFC2x3/IFC4 : a proxy was tolerated; prefer a concrete entity anyway.
```

`IfcBuildingElementProxy` is an escape hatch, not a default. Reaching for it
when a concrete entity exists produces a model that downstream tools cannot
classify, cost, or analyse.

## Patterns

### Pattern: generate a stable GlobalId

`GlobalId` is of defined type `IfcGloballyUniqueId`: a `STRING` of fixed
length 22 that encodes a 128-bit GUID. The encoding is a custom base64 over
the 64-symbol alphabet `0-9 A-Z a-z _ $`. It is NOT RFC 4648 base64.
Because the first character holds only 2 bits, the first character is ALWAYS
one of `0`, `1`, `2`, `3`.

Example: the hex GUID `f70dd363-bfe3-495d-84a0-2c02dcb7d4d2` compresses to the
22-character form `3t3TDZl_D9NOIWB0BSjzJI`.

ALWAYS generate the `GlobalId` once, when the logical object is first created,
and persist it. The GUID identifies the same logical object across file
versions and edit sessions. NEVER regenerate `GlobalId` on every export:
round-trip identity, model diffing, and issue tracking all depend on its
stability. See `references/anti-patterns.md` for the failure this causes.

### Pattern: walk or build the object chain

Every concrete element inherits four attribute blocks. For `IfcWall` the full
positional order in a STEP physical file is:

```
#21=IFCWALL(
  '3t3TDZl_D9NOIWB0BSjzJI',  /* 1 GlobalId      from IfcRoot    */
  #5,                        /* 2 OwnerHistory  from IfcRoot    */
  'Wall-001',                /* 3 Name          from IfcRoot    */
  $,                         /* 4 Description   from IfcRoot    */
  $,                         /* 5 ObjectType    from IfcObject  */
  #18,                       /* 6 ObjectPlacement from IfcProduct */
  #19,                       /* 7 Representation  from IfcProduct */
  'A-101',                   /* 8 Tag           from IfcElement */
  .SOLIDWALL.                /* 9 PredefinedType from IfcWall   */
);
```

When reading, climb the inheritance chain to know which attribute index means
what. When authoring, ALWAYS emit attributes in declared order and use `$` for
an unset optional. See `references/examples.md` for more instances.

### Pattern: pair a type with its occurrences

A type object holds data common to many occurrences. One `IfcWallType` is
shared by many `IfcWall` occurrences. The link is one `IfcRelDefinesByType`
instance (1-to-N): `RelatingType` points to the type, `RelatedObjects` is the
SET of occurrences.

```
/* #20 : an IfcWallType type     (see ifc-syntax-building-elements) */
/* #21, #22 : two IfcWall occurrences sharing that type            */
#30=IFCRELDEFINESBYTYPE(
  '1Hkj5pQ9X8x9bq0d6FZ7yA',  /* GlobalId                      */
  #5,                        /* OwnerHistory                  */
  $,                         /* Name                          */
  $,                         /* Description                   */
  (#21,#22),                 /* RelatedObjects : the occurrences */
  #20                        /* RelatingType   : the type        */
);
```

`IfcRelDefinesByType` has exactly 6 positional attributes: the 4 from
`IfcRoot`, then `RelatedObjects` (`SET [1:?] OF IfcObject`), then
`RelatingType` (`IfcTypeObject`). NEVER place a type object inside
`RelatedObjects`: that slot accepts occurrences only. Type objects receive
their property sets directly via `HasPropertySets`, not via a relationship.

### Pattern: set PredefinedType and ObjectType

Concrete element entities and their type entities carry a `PredefinedType`
enumeration that sub-classifies them (for `IfcWall` the enum is
`IfcWallTypeEnum`). Every such enum ends with two reserved values:

- `NOTDEFINED` : no specialization is asserted.
- `USERDEFINED` : the specialization is named by a separate label attribute.

ALWAYS pair `PredefinedType = USERDEFINED` with the `ObjectType` label on an
occurrence (`IfcObject.ObjectType`). When `PredefinedType` is any concrete
enum value, leave `ObjectType` unset (`$`). NEVER set `PredefinedType` to a
value that is not in that entity's enumeration: it is a schema violation.

`IfcWallTypeEnum` values (IFC4.3, verified): `ELEMENTEDWALL`, `MOVABLE`,
`PARAPET`, `PARTITIONING`, `PLUMBINGWALL`, `POLYGONAL`, `RETAININGWALL`,
`SHEAR`, `SOLIDWALL`, `STANDARD`, `WAVEWALL`, `USERDEFINED`, `NOTDEFINED`.
Other element entities have their own enums; verify per entity.

### Pattern: the proxy escape hatch

`IfcBuildingElementProxy` is a concrete subtype of `IfcBuiltElement` (IFC4.3)
or `IfcBuildingElement` (IFC2x3, IFC4). Use it ONLY for a genuine construction
element with no matching concrete entity.

```
#40=IFCBUILDINGELEMENTPROXY(
  '2k7sB$Qe9X8x9bq0d6FZ7y',  /* GlobalId        */
  #5,                        /* OwnerHistory    */
  'Acoustic baffle',         /* Name            */
  $,                         /* Description     */
  'AcousticBaffle',          /* ObjectType : the USERDEFINED term */
  #38,                       /* ObjectPlacement */
  #39,                       /* Representation  */
  $,                         /* Tag             */
  .USERDEFINED.              /* PredefinedType : IfcBuildingElementProxyTypeEnum */
);
```

`IfcBuildingElementProxyTypeEnum` values: `COMPLEX`, `ELEMENT`, `PARTIAL`
(all three "shall no longer be used"), `PROVISIONFORSPACE`, `PROVISIONFORVOID`
(both deprecated as of IFC4.3.0.0), `USERDEFINED`, `NOTDEFINED`.

IFC4.3 CHANGE note: "IfcBuildingElementProxy should no longer be used as
spatial placeholders or provisions. Use IfcVirtualElement instead." In IFC4.3,
NEVER use a proxy as a placeholder, a provision-for-void, or a
provision-for-space: use `IfcVirtualElement`.

## Anti-Patterns

Full detail with the failure mechanism is in `references/anti-patterns.md`.
The five that matter most:

- Instantiating an abstract entity (`IfcElement`, `IfcProduct`,
  `IfcBuildingElement`). The file fails schema validation.
- Regenerating `GlobalId` on every export. Breaks model diffing and
  issue-tracking continuity.
- Using `IfcBuildingElement` against an IFC4.3 schema, or `IfcBuiltElement`
  against IFC2x3/IFC4. Wrong-version entity name, file rejected.
- Putting `ObjectPlacement` or `Representation` on a type object. Those
  attributes do not exist on `IfcTypeProduct`.
- Using `IfcBuildingElementProxy` where a concrete entity exists, or as a
  placeholder in IFC4.3.

## Reference Links

### This skill

- `references/methods.md` : full attribute signatures for `IfcRoot`,
  `IfcObjectDefinition`, `IfcObject`, `IfcProduct`, `IfcElement`,
  `IfcBuiltElement`, `IfcTypeObject`, `IfcTypeProduct`, `IfcElementType`,
  `IfcRelDefinesByType`, `IfcBuildingElementProxy`, `IfcGloballyUniqueId`.
- `references/examples.md` : verified STEP physical file instances.
- `references/anti-patterns.md` : failure modes and their root causes.

### Related skills

- `ifc-core-data-model` : the four-layer schema architecture this tree sits in.
- `ifc-core-relationships` : the `IfcRelationship` branch and the objectified
  relationship pattern.
- `ifc-core-spatial-structure` : `IfcProject`, `IfcContext`, the spatial branch.
- `ifc-syntax-building-elements` : full attribute lists of the concrete leaves.
- `ifc-core-version-evolution` : the complete cross-version rename ledger.

### Official sources

- IfcRoot: https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcRoot.htm
- IfcGloballyUniqueId: https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcGloballyUniqueId.htm
- IfcBuiltElement: https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcBuiltElement.htm
- IfcTypeProduct: https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcTypeProduct.htm
- IfcRelDefinesByType: https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcRelDefinesByType.htm

