Viewing IFC using ifc2gltf, ifc2gltf2xgf and XGFLoader
Introduction
In this tutorial, we'll load an IFC 4.3 model into a xeokit Viewer
@xeokit/sdk / viewer / Viewer / Class Viewer 3D model viewer.
- Use
ifc2gltf
to convert the IFC into glTF and JSON metadata (intermediate format). - Use
ifc2gltf2xkt
to convert the glTF and JSON into XGF and a JSON data model (final format). - Use
XGFLoader
to load the XGF and JSON data model into a xeokit Viewer on a webpage.
This process splits the model into multiple files, improving memory stability in the converter tools and Viewer by allowing incremental loading and deallocation.
Example IFC Model
For this tutorial, we'll use the Karhumaki Bridge IFC model (source: http://drumbeat.cs.hut.fi/ifc/
).
Below is the final result— the model loaded from XGF and JSON files into a xeokit Viewer. In the following steps, we'll walk through the process of achieving this.

Importing IFC Converted by ifc2gltf2xgf
Step 1. Convert IFC into glTF and Metadata Files
The first step is to convert our IFC file into a set of intermediate glTF geometry and JSON metadata files. We'll use
the ifc2gltf
CLI tool to do this conversion step:
ifc2gltfcxconverter -i Karhumaki-Bridge.ifc -o model.glb -m model.json -s 100
The parameters we provided the tool are:
-i
specifies the IFC file to convert-o
specifies the name to prefix on each output glTF file-m
specifies the name to prefix on each JSON metamodel file-s
specifies the maximum number of megabytes in each glTF file - smaller value means more output files, lower value means less files
The files output by @xeokit/sdk / metamodel / MetaModelParams / Interface MetaModelParams Legacy metadata model parameters.ifc2gltf
are listed below. Each of the JSON files follows the schema defined
by MetaModelParams
.
├── model.glb.manifest.json
├── model_1.glb
├── model_1.json
├── model_2.glb
├── model_2.json
├── model_3.glb
├── model_3.json
├── model_4.glb
├── model_4.json
├── model_5.glb
├── model_5.json
├── model_6.glb
├── model_6.json
├── model_7.glb
├── model_7.json
├── model_8.glb
├── model_8.json
├── model_9.glb
├── model_9.json
├── model.glb
└── model.json
The @xeokit/sdk / ifc2gltf2xgf / Ifc2gltfManifestParams / Class Ifc2gltfManifestParams Defines the format the glTF file manifests output by ifc2gltf.model.glb.manifest.json
manifest looks like below. This manifest follows the schema defined by Ifc2gltfManifestParams
{
"inputFile": "Karhumaki-Bridge.ifc",
"converterApplication": "ifc2gltfcxconverter",
"converterApplicationVersion": "2.8.6",
"conversionDate": "2023-09-08 03:01:39",
"gltfOutFiles": [
"model.glb",
"model_1.glb",
"model_2.glb",
"model_3.glb",
"model_4.glb",
"model_5.glb",
"model_6.glb",
"model_7.glb",
"model_8.glb",
"model_9.glb"
],
"metadataOutFiles": [
"model.json",
"model_1.json",
"model_2.json",
"model_3.json",
"model_4.json",
"model_5.json",
"model_6.json",
"model_7.json",
"model_8.json",
"model_9.json"
]
}
Step 2. Convert glTF and Metadata to XGF and DataModel Files
The next step is to convert our set of intermediate glTF geometry and JSON metamodel files into the final set of XGF and data model files.
We'll use the ifc2gltf2xgf
CLI tool to do this conversion step:
node ifc2gltf2xgf -i model.glb.manifest.json -o model.xgf.manifest.json
The parameters we provided the tool are:
-i
specifies the glTF+Metadata manifest file to convert-o
specifies the XGF+DataModel manifest file to output
The files output by @xeokit/sdk / data / DataModelParams / Interface DataModelParams Parameters used to define a DataModel.ifc2gltf2xgf
are listed below. Each of the JSON files follows the schema defined
by DataModelParams
.
├── model.xgf.manifest.json
├── model_1.xgf
├── model_1.datamodel.json
├── model_2.xgf
├── model_2.datamodel.json
├── model_3.xgf
├── model_3.datamodel.json
├── model_4.xgf
├── model_4.datamodel.json
├── model_5.xgf
├── model_5.datamodel.json
├── model_6.xgf
├── model_6.datamodel.json
├── model_7.xgf
├── model_7.datamodel.json
├── model_8.xgf
├── model_8.datamodel.json
├── model_9.xgf
├── model_9.datamodel.json
├── model.xgf
└── model.datamodel.json
The @xeokit/sdk / core / ModelChunksManifestParams / Interface ModelChunksManifestParamsmodel.xgf.manifest.json
manifest looks like below. This manifest follows the schema defined by ModelChunksManifestParams
{
"sceneModelMIMEType": "arraybuffer",
"sceneModelFiles": [
"model.xgf",
"model_1.xgf",
"model_2.xgf",
"model_3.xgf",
"model_4.xgf",
"model_5.xgf",
"model_6.xgf",
"model_7.xgf",
"model_8.xgf",
"model_9.xgf"
],
"dataModelFiles": [
"model.datamodel.json",
"model_1.datamodel.json",
"model_2.datamodel.json",
"model_3.datamodel.json",
"model_4.datamodel.json",
"model_5.datamodel.json",
"model_6.datamodel.json",
"model_7.datamodel.json",
"model_8.datamodel.json",
"model_9.datamodel.json"
]
}
Step 3. View the XGF and DataModel Files
Now we'll create a Web page containing a xeokit Viewer
@xeokit/sdk / viewer / Viewer / Class Viewer 3D model viewer.
HTML
First, create an HTML page in index.html
that contains a canvas element:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Importing IFC Converted by ifc2gltf2xgf</title>
<style>
body {
background-color: white;
overflow: hidden;
margin: 0;
user-select: none;
}
#demoCanvas {
width: 100%;
height: 100%;
position: absolute;
background: white;
border: 0;
}
</style>
</head>
<body>
<canvas id="demoCanvas"></canvas>
</body>
<script type="module" src="./index.js"></script>
</html>
JavaScript
Then create JavaScript in @xeokit/sdk / viewer / Viewer / Class Viewer 3D model viewer.index.js
to create the Viewer
The steps in the JavaScript are as follows.
1. Import the SDK from a bundle built for these examples
import * as xeokit from "../../js/xeokit-demo-bundle.js";
import {DemoHelper} from "../../js/DemoHelper.js";
2. Create a Scene
@xeokit/sdk / scene / Scene / Class Scene Container of model geometry and materials.
const scene = new xeokit.scene.Scene();
3. Create a Data
@xeokit/sdk / data / Data / Class Data Container of model semantic data.
const data = new xeokit.data.Data();
4. Create a WebGLRenderer
@xeokit/sdk / webglrenderer / WebGLRenderer / Class WebGLRenderer WebGL rendering strategy for a Viewer.
const renderer = new xeokit.webglrenderer.WebGLRenderer({});
5. Create a Viewer
@xeokit/sdk / viewer / Viewer / Class Viewer 3D model viewer.
const viewer = new xeokit.viewer.Viewer({
id: "demoViewer",
scene,
renderer
});
6. Give the Viewer a single View
@xeokit/sdk / viewer / View / Class View An independent view within a Viewer, with its own canvas, Camera and object visual states.
const view = viewer.createView({
id: "demoView",
elementId: "demoCanvas"
});
7. Arrange the View's Camera
@xeokit/sdk / viewer / Camera / Class Camera Controls the viewpoint and projection for a View.
view.camera.eye=[-31.63254701136148, 63.84407843065014, -97.64896735426231];
view.camera.look=[-69.51194533142663, 31.241318427077932, -62.52887630516256];
view.camera.up=[-0.3913972432760181, 0.8456487936816226, 0.3628860919086728];
8. Add a CameraControl
@xeokit/sdk / cameracontrol / CameraControl / Class CameraControl Mouse and touch controller for a Viewer's Camera.
new xeokit.cameracontrol.CameraControl(view, {});
9. Create a SceneModel
@xeokit/sdk / scene / SceneModel / Class SceneModel Contains a model's geometry and materials.
const sceneModel = scene.createModel({
id: "demoModel"
});
10. Ignore the DemHelper
const demoHelper = new DemoHelper({
viewer,
data
});
demoHelper.init()
.then(() => {
11. Create a DataModel
@xeokit/sdk / data / DataModel / Class DataModel Contains a model's semantic data, as an entity-relationship graph.
const dataModel = data.createModel({
id: "demoModel"
});
12. Fetch the ModelChunksManifestParams
@xeokit/sdk / core / ModelChunksManifestParams / Interface ModelChunksManifestParams
fetch(`../../models/KarhumakiBridge/ifc2gltf2xgf/model.manifest.json`)
.then(response => {
response
.json()
.then(modelChunksManifest => {
13. Create a ModelChunksLoader
@xeokit/sdk / modelchunksloader / ModelChunksLoader / Class ModelChunksLoader Loads a SceneModel and/or DataModel from a set of chunk files. @xeokit/sdk / xgf / XGFLoader / Class XGFLoader Loads an XGF file into a SceneModel and/or a DataModel. @xeokit/sdk / data / DataModelParamsLoader / Class DataModelParamsLoader Reads DataModelParams into a DataModel.
const modelChunksLoader = new xeokit.modelchunksloader.ModelChunksLoader({
sceneModelLoader: new xeokit.xgf.XGFLoader(),
dataModelLoader: new xeokit.data.DataModelReader()
});
14. Use the ModelChunksLoader to load the glTF and JSON files listed in the ModelChunksManifestParams. The ModelChunksLoader will use XGFLoader to load each XGF file into the SceneModel, and DataModelParamsLoader to load each JSON DataModelParams
@xeokit/sdk / data / DataModelParams / Interface DataModelParams Parameters used to define a DataModel.
modelChunksLoader.load({
modelChunksManifest,
baseDir: "../../models/KarhumakiBridge/ifc2gltf2xgf/",
sceneModel,
dataModel
}).then(() => { // XGF and JSON files loaded
15. Build the SceneModel and DataModel. The Karhumaki Bridge
@xeokit/sdk / cityjsontypes_1_1_3 / Bridge / Variable Bridge This CityJSON type represents a bridge, which can have attributes such as length, height, and type of bridge.
sceneModel.build();
dataModel.build();
demoHelper.finished();
}).catch(e=>{
console.error(e);
});
});
});
});