Viewing IFC using xeoconvert and XGFLoader

Introduction


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

  1. Use xeoconvert with option --pipeline ifc2xgf to convert IFC into XGF and JSON DataModelParams files.
  2. Use XGFLoader and DataModelParamsLoader to load the XGF and JSON DataModelParams files into a xeokit Viewer in a webpage.

Example IFC Model


For this tutorial, we'll use the IfcOpenHouse4 Bridge IFC model (source: http://drumbeat.cs.hut.fi/ifc/).

Below is the final result— the model loaded from XGF and DataModelParams JSON files into a xeokit Viewer. In the following steps, we'll walk through the process of achieving this.

Click to load
Placeholder image

Viewing XGF using XGFLoader



Step 1. Convert IFC into XGF and DataModelParams Files


The first step is to convert our IFC file into a set of intermediate XGF geometry and JSON DataModelParams files. We'll use the xeoconvert CLI tool to do this conversion step:

npm xeoconvert --pipeline ifc2xgf --ifc IfcOpenHouse4.ifc --xgf model.xgf --datamodel model.json

The parameters we provided the tool are:

  • --pipeline selects the conversion pipeline, ifc2xgf
  • --ifc path to source IFC file
  • --xkt path to target XKT file
  • --datamodel path to target DataModelParams file (optional)

Step 2. View the XGF and DataModelParams 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>Viewing XGF using XGFLoader</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 an XKTLoader to load .xkt files

const xgfLoader = new xeokit.xgf.XGFLoader();

3. Create a Scene to hold geometry and materials

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

4. Create a Data to hold semantic data

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

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

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

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

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

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

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

8. Arrange the View's Camera

view.camera.eye = [-6.01, 4.85, 9.11];
view.camera.look = [3.93, -2.65, -12.51];
view.camera.up = [0.12, 0.95, -0.27];

9. Add a CameraControl to interactively control the View's Camera with keyboard, mouse and touch input

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

10. Create a SceneModel to hold our model's geometry and materials

const sceneModel = scene.createModel({
    id: "demoModel"
});

11. Ignore the DemHelper

const demoHelper = new DemoHelper({
    viewer,
    data
});
demoHelper.init()
    .then(() => {

12. Create a DataModel to hold semantic data for our model

        const dataModel = data.createModel({
            id: "demoModel"
        });
        if (sceneModel instanceof xeokit.core.SDKError) {
            console.error(`Error creating SceneModel: ${sceneModel.message}`);
        } else {

13. Use XGFLoader to load a glTF model into our SceneModel and DataModel

            fetch("../../models/IfcOpenHouse4/ifc2xgf/model.xgf").then(response => {
                response
                    .arrayBuffer()
                    .then(fileData => {
                    xgfLoader.load({
                        fileData,
                        sceneModel,
                        dataModel
                    }).then(() => {

14. Build the SceneModel and DataModel. The Scene and SceneModel will now contain a SceneObject for each displayable object in our model. The Data and DataModel will contain a DataObject for each IFC element in the model. Each SceneObject will have a corresponding DataObject with the same ID, to attach semantic meaning. The View will contain a ViewObject corresponding to each SceneObject, through which the appearance of the object can be controlled in the View.

                        dataModel.build();
                        sceneModel.build();
                        demoHelper.finished();
                    }).catch(message => {
                        console.error(`Error loading XGF: ${message}`);
                    });
                });
            });
        }
    });