IFC5 Pre-Alpha Hello Wall example
Introduction
Hello Wall in the Viewer
The hello-wall.ifcx from IFC5 development repository on GitHub is a model with a Space (My_Space) and a Wall (Wall) with two Windows (Window and Window_001). The model has changed
The tree of Hello Wall
Some Key Features and their illustration with extracts from Hello Wall
Extract from hello-wall.ifcx
{
"def": "def",
"type": "UsdGeom:Xform",
"name": "My_Project",
"inherits": [
"</N14adb22bd47448a28e8f6d4c067c1953>"]
},
{
"def": "class",
"type": "UsdGeom:Xform",
"name": "N14adb22bd47448a28e8f6d4c067c1953",
"children": [
{
"def": "def",
"name": "My_Site",
"inherits": [
"</Ne0834921e09540f088743c6bd1ec699e>"]
}
]
},
{
"def": "over",
"name": "N14adb22bd47448a28e8f6d4c067c1953",
"attributes": {
"ifc5:class": {
"code": "IfcProject",
"uri": "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/IfcProject"
}
}
},
Making extracts more legible
The hello-wall uses in the name identifiers strings that are partly GUIDs. To make things simpler to read, we have replaced these identifiers by the corresponding def name with '_class' added at the end.
{
"def": "def",
"type": "UsdGeom:Xform",
"name": "My_Project",
"inherits": [
"</My_Project_class>"]
},
{
"def": "class",
"type": "UsdGeom:Xform",
"name": "My_Project_class",
"children": [
{
"def": "def",
"name": "My_Site",
"inherits": [
"</My_Site_class>"]
}
]
},
{
"def": "over",
"name": "My_Project_class",
"attributes": {
"ifc5:class": {
"code": "IfcProject",
"uri": "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/IfcProject"
}
}
},
Def, Class and Over
Objects are set as a def (e.g. My_Project, My_Site) but must inherit from a class.
Attributes can be attached to a class via an over
An over can also add children to a class
Simplified parenting relationships
In IFC5, There is a consolidation of parenting relationships: a child is a child, whether issued from an IfcRelAggregates or IfcRelContainedInSpatialStructure. The Window is not under Storey as a sibling of the Wall but under the Wall as a child
{
"def": "class",
"type": "UsdGeom:Xform",
"name": "Wall_class",
"children": [
...
{
"def": "def",
"name": "Window",
"inherits": [
"</Window_class>"]
},
{
"def": "def",
"name": "Window_001",
"inherits": [
"</Window_001_class>"]
}
]
},
A class can inherit from another class that acts as a type
A class can inherit from another class: both instances of Windows, namely Window and Window_001 inherit from classes Window_class and Window_001_class that inherit from a class that acts as a type.
The class that acts a type is the one named Window_Type_class in the example below. It has a void and a body as children. It has also standard properties such as IsExternal, which is set to 1 (i.e. True), meaning that all windows of this type are external.
It is worth noting that the class named Window_Type_class for convenience has the ifc5:class code IfcWindow and not IfcWindowType. The class for the Window can inherit from another class, which could possiblty inherit from yet another class without changing the ifc5:class code. This is way simpler than in IFC<5 where 'standard objects' (e.g. an IfcWindow) and 'type' objects' (e.g. an IfcWindowType) have distinct properties and behaviours.
{
"def": "class",
"type": "UsdGeom:Xform",
"comment": "this is the instance of Window",
"name": "Window_class",
"inherits": [
"</Window_Type_class>"]
},
{
"def": "class",
"type": "UsdGeom:Xform",
"name": "Window_001_class",
"comment":"instance of Window_001",
"inherits": [
"</Window_Type_class>"]
},
{
"def": "class",
"type": "UsdGeom:Xform",
"name": "Window_Type_class",
"children": [
{
"def": "def",
"type": "UsdGeom:Mesh",
"name": "Void",
"inherits": [
"</Window_Type_class_Void>"]
},
{
"def": "def",
"type": "UsdGeom:Mesh",
"name": "Body",
"inherits": [
"</Window_Type_class_Body>"]
}
]
},
{
"def": "over",
"name": "Window_Type_class",
"attributes": {
"ifc5:class": {
"code": "IfcWindow",
"uri": "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3/class/IfcWindow"
}
}
},
{
"def": "over",
"name": "Window_Type_class",
"attributes": {
"ifc5:properties": {
"IsExternal": 1
}
}
},
Space Boundaries become objects
Hereunder, the space 'My_Space' inherits from the class 'My_Space_class' which has as children:
- a Body
- a Space Boundary for each object that would be a RelatedBuildingElement in an IfcRelSpaceBoundary relationship in IFC<5. The json hereunder only shows the Boundary_Wall for the wall, but there is also one for Window and Window_001.
There is also an over on the Boundary_Wall_clas which documents the relationship between the Boundary_Wall_class of the Boundary_Wall and the Wall_class of the corresponding Wall.
{
"def": "class",
"type": "UsdGeom:Xform",
"name": "My_Space_class",
"children": [
{
"def": "def",
"type": "UsdGeom:Mesh",
"name": "Body",
"inherits": [
"</My_Space_class_Body>"]
},
{
"def": "def",
"name": "Boundary_Wall",
"inherits": [
"</Boundary_Wall_class>"]
},
...
]
},
{
"def": "class",
"type": "UsdGeom:Xform",
"name": "Boundary_Wall_class",
"children": [
{
"def": "def",
"type": "UsdGeom:Mesh",
"name": "Body",
"inherits": [
"</Boundary_Wall_class_Body>"]
}
]
},
{
"def": "over",
"name": "Boundary_Wall_class",
"attributes": {
"ifc5:spaceboundary": {
"relatedElement": {
"ref": "</Wall_class>"
}
}
}
},
{
"def": "class",
"type": "UsdGeom:Mesh",
"name": "Boundary_Wall_class_Body"
},
The base representation geometry is the mesh
{
"def": "over",
"name": "Boundary_Wall_class_Body",
"attributes": {
"UsdGeom:Mesh": {
"faceVertexIndices": [3,0,1,3,1,2],
"points": [
[10,-2.3841858e-08,0],
[0,-2.3841858e-08,0],
[0,-2.3841858e-08,3],
[10,-2.3841858e-08,3]
]
}
}
},
Placement and alignment use simple transform matrix
In IFC, each product (object which may have a representation) has a defined IfcLocalPlacement in 2-D or 3-D.
In IFC5 a 4-dimensional matrix in a projective space is used. The matrix can then consolidate the translation, rotation and scaling operations.
Hereunder, as an example, we have the transform of Window_class and Window_001_class which are the two instances of windows, sharing the same type and asociated body geometry, but not the same placement. The transformation hereunder are solely geometric translations (no rotation, no scaling).
{
"def": "over",
"name": "Window_class",
"attributes": {
"xformOp": {
"transform": [
[1,0,0,0],
[0,1,0,0],
[0,0,1,0],
[1.76767492294312,0,1,1]
]
}
}
},
{
"def": "over",
"name": "Window_001_class",
"attributes": {
"xformOp": {
"transform": [
[1,0,0,0],
[0,1,0,0],
[0,0,1,0],
[4.94660663604736,0,1,1]
]
}
}
},
Composition - Add a third window
Composition enables to add information on an existing model. For instance, we can add a third window by:
- adding an over on the My_Wall with an extra window child Window_002 which inherits from Window_002_class.
- the latter inherits from Window_Type_class as is the case for Window_class and Window_001_class.
- as for the other two instances, a transform must be provided with an over on class Window_002_class
{
"def": "over",
"name": "Wall_class",
"children": [
{
"def": "def",
"name": "Window_002",
"inherits": [
"</Window_002_class>"]
}
]
},
{
"def": "class",
"type": "UsdGeom:Xform",
"comment": "this is the instance of Window",
"name": "Window_002_class",
"inherits": [
"</Window_Type_class>"]
},
{
"def": "over",
"name": "Window_002_class",
"attributes": {
"xformOp": {
"transform": [
[1,0,0,0],
[0,1,0,0],
[0,0,1,0],
[6.9466066,-0.03,1,1]
]
}
}
}
This is not complete as we need to add the a corresponding space boundary with:
- adding an over on the My_Space_class with an extra window child Boundary_Window_002 which inherits from a Boundary_Window_002_class.
- a Boundary_Window_002_class with a child Body that inherits from a class Boundary_Window_002_class_Body.
- a over on the Boundary_Window_002_class to make the link with the corresponding Window_002_class
- a Boundary_Window_002_class_Body
- an over on the Boundary_Window_002_class_Body with the mesh geometry of the Boundary.
{
"def": "over",
"name": "My_Space_class",
"children": [
{
"def": "def",
"name": "Boundary_Window_002",
"inherits": [
"</Boundary_Window_002_class>"
]
}
]
},
{
"def": "class",
"type": "UsdGeom:Xform",
"name": "Boundary_Window_002_class",
"children": [
{
"def": "def",
"type": "UsdGeom:Mesh",
"name": "Body",
"inherits": [
"</Boundary_Window_002_class_Body>"
]
}
]
},
{
"def": "over",
"name": "Boundary_Window_002_class",
"attributes": {
"ifc5:spaceboundary": {
"relatedElement": {
"ref": "</Window_002_class>"
}
}
}
},
{
"def": "class",
"type": "UsdGeom:Mesh",
"name": "Boundary_Window_002_class_Body"
},
{
"def": "over",
"name": "Boundary_Window_002_class_Body",
"attributes": {
"UsdGeom:Mesh": {
"faceVertexIndices": [2,0,1,2,3,0],
"points": [
[6.9466066,0,1],
[6.9466066,0,2.2],
[7.8466066,0,2.2],
[7.8466066,0,1]
]
}
}
}
We then have a displayed model built from two .ifcx files with the viewer(version 'v1' / early january 2025):
Composition - Add a second building with a rotation
We can add a second building on the site with a simple over.
As an complementary illustration we add a translation of (x=10,y=0,z=0,w=1) and a rotation of 90° using the values from the example of Transformation in a projective space.
[
{
"def": "over",
"name": "My_Site_class",
"children": [
{
"def": "def",
"name": "Brand_New_Building",
"inherits": [
"</Brand_New_Building_class>"]
}
]
},
{
"def": "class",
"type": "UsdGeom:Xform",
"comment": "this is the instance of the Building",
"name": "Brand_New_Building_class",
"inherits": [
"</My_Building_class>"]
},
{
"def": "over",
"name": "Brand_New_Building_class",
"attributes": {
"xformOp": {
"transform":[
[6.123233995736766e-17, -1.0, 0.0, 0.0],
[1.0, 6.123233995736766e-17, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[10.0, 0.0, 0.0, 1.0]
]
}
}
}
]