Viewing IFC using ifc2gltf, ifc2gltf2xgf and XGFLoader

Introduction


In this tutorial, we'll load an IFC 4.3 model into a xeokit Viewer . To optimize performance, we'll first convert the IFC model to XGF, xeokit's native compressed format. The whole process consists of three steps:

  1. Use ifc2gltf to convert the IFC into glTF and JSON metadata (intermediate format).
  2. Use ifc2gltf2xkt to convert the glTF and JSON into XGF and a JSON data model (final format).
  3. 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.

Click to load
Placeholder image

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 ifc2gltf are listed below. Each of the JSON files follows the schema defined by MetaModelParams , which is xeokit's legacy format for semantic model data.

.
├── 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 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 ifc2gltf2xgf are listed below. Each of the JSON files follows the schema defined by DataModelParams , which is xeokit's new and more expressive entity-relationship graph format for semantic model data.

.
├── 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 model.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 and view our converted model with it.

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 index.js to create the Viewer and view our converted model.

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 to hold geometry and materials

const scene = new xeokit.scene.Scene();

3. Create a Data to hold semantic data

const data = new xeokit.data.Data();

4. Create a WebGLRenderer to use the browser's WebGL graphics API for rendering

const renderer = new xeokit.webglrenderer.WebGLRenderer({});

5. Create a Viewer that will use the WebGLRenderer to draw the Scene

const viewer = new xeokit.viewer.Viewer({
    id: "demoViewer",
    scene,
    renderer
});

6. Give the Viewer a single View to render the Scene in our HTML canvas element

const view = viewer.createView({
    id: "demoView",
    elementId: "demoCanvas"
});

7. Arrange the View's Camera

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 to interactively control the View's Camera with keyboard, mouse and touch input

new xeokit.cameracontrol.CameraControl(view, {});

9. Create a SceneModel to hold our 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 to hold semantic data for our model

        const dataModel = data.createModel({
            id: "demoModel"
        });

12. Fetch the ModelChunksManifestParams for the model. This file was output by ifc2gltf2xgf.

        fetch(`../../models/KarhumakiBridge/ifc2gltf2xgf/model.manifest.json`)
            .then(response => {
                response
                    .json()
                    .then(modelChunksManifest => {

13. Create a ModelChunksLoader , equipped with an XGFLoader and a DataModelParamsLoader .

                        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 file into the 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 model now appears in our Viewer.

                            sceneModel.build();
                            dataModel.build();
                            demoHelper.finished();
                        }).catch(e=>{
                            console.error(e);
                        });
                    });
            });
    });