Viewing IFC using ifc2gltf and GLTFLoader

Introduction


In this tutorial, we'll view an IFC 4.3 model in the browser using a xeokit Viewer . To optimize performance, we'll first convert the IFC model to glTF and metadata JSON files. The import process consists of two steps:

  1. Use ifc2gltf to convert IFC into glTF and JSON metadata files.
  2. Use GLTFLoader to load the glTF and JSON metadata files into a xeokit Viewer on a webpage.

This process also 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 glTF 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 ifc2gltf



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 metadata 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. View the glTF and Metadata Files


Now we'll create a Web page containing a xeokit Viewer that views our converted model.

HTML

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 ifc2gltf</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 Ifc2gltfManifestParams for the model. This file was output by ifc2gltf.

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

13. Use convertIfc2gltfManifest to convert the Ifc2gltfManifestParams into a ModelChunksManifestParams

                        const modelChunksManifest = xeokit.ifc2gltf2xgf.convertIfc2gltfManifest(ifc2gltfManifest);

14. Create a ModelChunksLoader , equipped with a GLTFLoader and MetaModelLoader .

                        const modelChunksLoader = new xeokit.modelchunksloader.ModelChunksLoader({
                            sceneModelLoader: new xeokit.gltf.GLTFLoader(),
                            dataModelLoader: new xeokit.metamodel.MetaModelReader()
                        });

15. Use the ModelChunksLoader to load the glTF and JSON files listed in the ModelChunksManifestParams. The ModelChunksLoader will use GLTFLoader to load each glTF file into the SceneModel, and loadMetaModel to load each JSON MetaModelParams file into the DataModel.

                        modelChunksLoader.load({
                            modelChunksManifest,
                            baseDir: "../../models/KarhumakiBridge/ifc2gltf/",
                            sceneModel,
                            dataModel
                        }).then(() => { // glTF and JSON files loaded

16. 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);
                        });
                    });
            });
    });