EXPRESS
Introduction
Let's take a look a very basic EXPRESS data model.
SCHEMA Family;
ENTITY Person
name: STRING;
END_ENTITY;
We have defined a custom schema called Family
. We have a Person
class within this schema. The person has one attribute: name
. The name is represented as a string.
Schema
Family
Class Name
Person
Class Attribute
Name
Window Example
Let's take a look at our previous example, the window:
ENTITY IfcWindow
SUBTYPE OF (IfcBuildingElement);
OverallHeight : OPTIONAL IfcPositiveLengthMeasure;
OverallWidth : OPTIONAL IfcPositiveLengthMeasure;
END_ENTITY;
We can see that we each "object" (window, wall, door, roof, etc.) is an ENTITY
. Again, notice how we use the following format to specify an "object":
ENTITY { NAME }
// content goes here
END_ENTITY;
Here's a list of some common building elements. These are defined in IFC2x Edition 3 Technical Corrigendum 1 schema, SCHEMA IFC2X3;
. Again, notice how each building element ("object") is its own ENTITY
.

Let's go back to our window. This is a Window
class defined using the EXPRESS data model format.
SCHEMA IFC2X3;
ENTITY IfcWindow
SUBTYPE OF (IfcBuildingElement);
OverallHeight : OPTIONAL IfcPositiveLengthMeasure;
OverallWidth : OPTIONAL IfcPositiveLengthMeasure;
END_ENTITY;
Take a look at line 5 and 6. We can see that we have two attributes:
Overall Height
Overall Width
Missing Attributes?
Let's continue with our Window example. We saw that the windows has two attrbitues. However, according to the documentation, we're missing some attributes:

We can verify this by looking at the STEP-file. This has clearly more than two attributes:
#13067= IFCWINDOW('2cXV28XOjE6f6irgi0CO$D',#42,'M_Fixed:0915 x 1830mm:353953',$,'M_Fixed:0915 x 1830mm',#35337,#13061,'353953',1830.,914.999999999999);
We have 10 different attributes. Notice that we don't understand what any of these attributes mean.
Attribute
Value
#1
2cXV28XOjE6f6irgi0CO$D
#2
#42
#3
M_Fixed:0915 x 1830mm:353953
#4
$
#5
M_Fixed:0915 x 1830mm:353953
#6
#35337
#7
#13061
#8
353953
#9
1830.
#10
914.999999999999999
Let's dive deep into EXPRESS
How does this work? How can we have more than two attributes?
SCHEMA IFC2X3;
ENTITY IfcWindow
SUBTYPE OF (IfcBuildingElement);
OverallHeight : OPTIONAL IfcPositiveLengthMeasure;
OverallWidth : OPTIONAL IfcPositiveLengthMeasure;
END_ENTITY;
Well, the answer lies within the EXPRESS definition. Take a close look at the 4th line above. We can see that IfcWindow
is an subtype of an IfcBuildingElement
. Here's the EXPRESS data model forIfcBuildingElement
:
SCHEMA IFC2X3;
ENTITY IfcBuildingElement
ABSTRACT SUPERTYPE OF (ONEOF
(IfcBeam
,IfcBuildingElementComponent
,IfcBuildingElementProxy
,IfcColumn
,IfcCovering
,IfcCurtainWall
,IfcDoor
,IfcFooting
,IfcMember
,IfcPile
,IfcPlate
,IfcRailing
,IfcRamp
,IfcRampFlight
,IfcRoof
,IfcSlab
,IfcStair
,IfcStairFlight
,IfcWall
,IfcWindow))
SUBTYPE OF (IfcElement);
END_ENTITY;
Notice how the IfcBuildingElement
itself is a subtype of IfcElement
(see line 25 above). Let's continue down the rabbit hole...
ENTITY IfcElement
ABSTRACT SUPERTYPE OF (ONEOF
(IfcBuildingElement
,IfcDistributionElement
,IfcElectricalElement
,IfcElementAssembly
,IfcElementComponent
,IfcEquipmentElement
,IfcFeatureElement
,IfcFurnishingElement
,IfcTransportElement
,IfcVirtualElement))
SUBTYPE OF (IfcProduct);
Tag : OPTIONAL IfcIdentifier;
INVERSE
HasStructuralMember : SET [0:?] OF IfcRelConnectsStructuralElement FOR RelatingElement;
FillsVoids : SET [0:1] OF IfcRelFillsElement FOR RelatedBuildingElement;
ConnectedTo : SET [0:?] OF IfcRelConnectsElements FOR RelatingElement;
HasCoverings : SET [0:?] OF IfcRelCoversBldgElements FOR RelatingBuildingElement;
HasProjections : SET [0:?] OF IfcRelProjectsElement FOR RelatingElement;
ReferencedInStructures : SET [0:?] OF IfcRelReferencedInSpatialStructure FOR RelatedElements;
HasPorts : SET [0:?] OF IfcRelConnectsPortToElement FOR RelatedElement;
HasOpenings : SET [0:?] OF IfcRelVoidsElement FOR RelatingBuildingElement;
IsConnectionRealization : SET [0:?] OF IfcRelConnectsWithRealizingElements FOR RealizingElements;
ProvidesBoundaries : SET [0:?] OF IfcRelSpaceBoundary FOR RelatedBuildingElement;
ConnectedFrom : SET [0:?] OF IfcRelConnectsElements FOR RelatedElement;
ContainedInStructure : SET [0:1] OF IfcRelContainedInSpatialStructure FOR RelatedElements;
END_ENTITY;
Again, notice how our IfcElement
is a subtype of IfcProduct
(see line 13 above). Let's continue...
ENTITY IfcProduct
ABSTRACT SUPERTYPE OF (ONEOF
(IfcAnnotation
,IfcElement
,IfcGrid
,IfcPort
,IfcProxy
,IfcSpatialStructureElement
,IfcStructuralActivity
,IfcStructuralItem))
SUBTYPE OF (IfcObject);
ObjectPlacement : OPTIONAL IfcObjectPlacement;
Representation : OPTIONAL IfcProductRepresentation;
INVERSE
ReferencedBy : SET [0:?] OF IfcRelAssignsToProduct FOR RelatingProduct;
WHERE
WR1 : (EXISTS(Representation) AND EXISTS(ObjectPlacement))
OR (EXISTS(Representation) AND
(NOT('IFC2X3.IFCPRODUCTDEFINITIONSHAPE' IN TYPEOF(Representation))))
OR (NOT(EXISTS(Representation)));
END_ENTITY;
Our IfcProduct
is a subtype of IfcObject
(see line 11 above).
ENTITY IfcObject
ABSTRACT SUPERTYPE OF (ONEOF
(IfcActor
,IfcControl
,IfcGroup
,IfcProcess
,IfcProduct
,IfcProject
,IfcResource))
SUBTYPE OF (IfcObjectDefinition);
ObjectType : OPTIONAL IfcLabel;
INVERSE
IsDefinedBy : SET [0:?] OF IfcRelDefines FOR RelatedObjects;
WHERE
WR1 : SIZEOF(QUERY(temp <* IsDefinedBy | 'IFC2X3.IFCRELDEFINESBYTYPE' IN TYPEOF(temp))) <= 1;
END_ENTITY;
Our IfcObject
is a subtype of IfcObjectDefinition
(see line 10 above). Let's continue...
ENTITY IfcObjectDefinition
ABSTRACT SUPERTYPE OF (ONEOF
(IfcObject
,IfcTypeObject))
SUBTYPE OF (IfcRoot);
INVERSE
HasAssignments : SET [0:?] OF IfcRelAssigns FOR RelatedObjects;
IsDecomposedBy : SET [0:?] OF IfcRelDecomposes FOR RelatingObject;
Decomposes : SET [0:1] OF IfcRelDecomposes FOR RelatedObjects;
HasAssociations : SET [0:?] OF IfcRelAssociates FOR RelatedObjects;
END_ENTITY;
Our IfcObjectDefinition
is a subtype of IfcRoot
(see line 5 above). We are almost done...
ENTITY IfcRoot
ABSTRACT SUPERTYPE OF (ONEOF
(IfcObjectDefinition
,IfcPropertyDefinition
,IfcRelationship));
GlobalId : IfcGloballyUniqueId;
OwnerHistory : IfcOwnerHistory;
Name : OPTIONAL IfcLabel;
Description : OPTIONAL IfcText;
UNIQUE
UR1 : GlobalId;
END_ENTITY;
Finally, we have reached the end!
Inheritance
We call this behaivor inheritance.
IfcWindow
IfcBuildingElement
IfcProduct
IfcObject
IfcObjectDefinition
IfcRoot
Let's flip this "graph". This will make things a bit easier to explain.
IfcRoot
IfcObjectDefinition
IfcObject
IfcProduct
IfcBuildingElement
IfcWindow
We can see that IfcRoot
has four different attributes; GlobalId, OwnerHistory, Name, Description. The IfcObjectDefinition
will inherit these attributes. This means that the IfcWindow
will inherit these attributes.
The IfcWindow
will inherit all attributes from its parent entities.
Summary
If we use inheritance, we can see what each attribute in the STEP-file actually mean:
#13067= IFCWINDOW('2cXV28XOjE6f6irgi0CO$D',#42,'M_Fixed:0915 x 1830mm:353953',$,'M_Fixed:0915 x 1830mm',#35337,#13061,'353953',1830.,914.999999999999);
Inhertited from
Attribute
Value
IfcRoot
GlobalId
2cXV28XOjE6f6irgi0CO$D
IfcRoot
Own
#42
IfcRoot
Name
M_Fixed:0915 x 1830mm:353953
IfcRoot
Description
$
IfcObject
ObectType
M_Fixed:0915 x 1830mm:353953
IfcProduct
ObectPlacement
#35337
IfcProduct
Representation
#13061
IfcElement
Tag
353953
IfcWindow
OverallHeight
1830.
IfcWindow
OverallWidth
914.999999999999999
Or, we can simply look at the inheritance graph in the documentation:

Editor's note:
I know that this can hard to understand. Please, take a good look at this article. Read it agian, think and reflect about the content.
Last updated