# xeokit-bim-viewer **Repository Path**: zoudmbean/xeokit-bim-viewer ## Basic Information - **Project Name**: xeokit-bim-viewer - **Description**: xeokit-bim-viewer is an open source 2D/3D BIM viewer that runs in the browser and loads models from your file system. - **Primary Language**: JavaScript - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-04-14 - **Last Updated**: 2024-06-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # xeokit-bim-viewer [](https://badge.fury.io/js/%40xeokit%2Fxeokit-bim-viewer) [](https://www.jsdelivr.com/package/npm/@xeokit/xeokit-bim-viewer) [](https://xeokit.github.io/xeokit-bim-viewer/app/index.html?projectId=OTCConferenceCenter&tab=storeys) * [Run demo](https://xeokit.github.io/xeokit-bim-viewer/app/index.html?projectId=OTCConferenceCenter&tab=storeys) --- **[xeokit-bim-viewer](https://github.com/xeokit/xeokit-bim-viewer)** is an open source 2D/3D BIM viewer that runs in the browser and loads models from your file system. The viewer is built on **[xeokit](http://xeokit.io)**, and is bundled as part of the **[xeokit SDK](http://xeokit.io)**. The viewer is developed by [xeolabs](http://xeolabs.com) and [OpenProject](https://www.openproject.org/), and is integrated within [OpenProject BIM 10.4](https://www.openproject.org/openproject-bim-10-4/) and later. The viewer can be used as a stand-alone JavaScript application. In combination with open source CLI model conversion tools, it represents a low-cost, high-performance way to get your IFC models on the Web, that allows you the freedom to convert and host your models on your own server or GitHub repository. To view your models with this viewer: 1. Fork the [xeokit-bim-viewer](https://github.com/xeokit/xeokit-bim-viewer) repository on GitHub. 1. Convert your IFC STEP files using [open source CLI tools](https://www.notion.so/xeokit/Viewing-an-IFC-Model-with-xeokit-c373e48bc4094ff5b6e5c5700ff580ee) . 3. Add your converted models to your fork's data directory. 4. Serve your fork using [GitHub Pages](https://pages.github.com/). Then users can view your models in their browsers, with URLs like this: [````https://xeokit.github.io/xeokit-bim-viewer/app/index.html?projectId=OTCConferenceCenter&tab=storeys````](https://xeokit.github.io/xeokit-bim-viewer/app/index.html?projectId=OTCConferenceCenter&tab=storeys) Read the documentation below to get started. --- * [Releases / Changelog](https://github.com/xeokit/xeokit-bim-viewer/releases) * [Source Code](https://github.com/xeokit/xeokit-bim-viewer) * [API Docs](https://xeokit.github.io/xeokit-bim-viewer/docs) * [xeokit SDK](http://xeokit.io) --- # Contents - [Features](#features) - [Demos](#demos) - [License](#license) - [The Viewer Application](#the-viewer-application) - [Model Database](#model-database) - [Viewer Configurations](#viewer-configurations) * [Viewer States](#viewer-states) - [Deploying XKT V7 and Earlier](#deploying-xkt-v7-and-earlier) - [Support for Multi-Part (Split) Models](#support-for-multi-part--split--models) - [Split Model with Separate Metadata Files](#split-model-with-separate-metadata-files) - [Programming API](#programming-api) * [Creating a Viewer](#creating-a-viewer) * [Configuring the Viewer](#configuring-the-viewer) * [Querying Projects, Models and Objects](#querying-projects--models-and-objects) + [Getting Info on Available Projects](#getting-info-on-available-projects) + [Getting Info on a Project](#getting-info-on-a-project) + [Getting Info on an Object](#getting-info-on-an-object) * [Loading Projects and Models](#loading-projects-and-models) + [Loading a Project](#loading-a-project) + [Loading a Model](#loading-a-model) * [Controlling Viewer State](#controlling-viewer-state) * [Saving and Loading BCF Viewpoints](#saving-and-loading-bcf-viewpoints) - [Customizing Viewer Style](#customizing-viewer-style) * [Modal Busy Dialog](#modal-busy-dialog) * [Tooltips](#tooltips) * [Customizing Appearances of IFC Types](#customizing-appearances-of-ifc-types) * [Localizing a Viewer](#localizing-a-viewer) - [xeokit Components Used in the Viewer](#xeokit-components-used-in-the-viewer) - [Building the Viewer](#building-the-viewer) * [Installing from NPM](#installing-from-npm) * [Building the Binary](#building-the-binary) * [Building the Documentation](#building-the-documentation) --- # Features * Uses [xeokit](https://xeokit.io) for efficient model loading and rendering. * Works in all major browsers, including mobile. * Can load models from the file system. * Loads multiple models. * Saves and loads BCF viewpoints. * 3D and 2D viewing modes. * Interactively X-ray, highlight, show, hide and section objects. * Tree views of structure, layers and storeys. * Full-precision geometry. * Point clouds. * Supports IFC2x3 and IFC4. * Customize viewer appearance with your own CSS. * Localization support. * JavaScript programming API for all viewer functions. # Demos Click the links below to run some demos. | Live Demo | Model Source | |---|---| | [Double-Precision Model](https://xeokit.github.io/xeokit-bim-viewer/app/index.html?projectId=MAP) | [BIMData](https://bimdata.io) | | [Point Cloud](https://xeokit.github.io/xeokit-bim-viewer/app/index.html?projectId=MAPPointCloud)| [BIMData](https://bimdata.io) | | [OTC Conference Center](https://xeokit.github.io/xeokit-bim-viewer/app/index.html?projectId=OTCConferenceCenter&tab=storeys) | [Details](http://openifcmodel.cs.auckland.ac.nz/Model/Details/301) | | [Revit Sample Project](https://xeokit.github.io/xeokit-bim-viewer/app/index.html?projectId=RevitSamples&tab=models) | [Details](https://knowledge.autodesk.com/support/revit-products/getting-started/caas/CloudHelp/cloudhelp/2020/ENU/Revit-GetStarted/files/GUID-61EF2F22-3A1F-4317-B925-1E85F138BE88-htm.html) | | [Holter Tower](https://xeokit.github.io/xeokit-bim-viewer/app/index.html?projectId=HolterTower&tab=storeys)| [Details](http://openifcmodel.cs.auckland.ac.nz/Model/Details/316) | | [West Riverside Hospital](https://xeokit.github.io/xeokit-bim-viewer/app/index.html?projectId=WestRiversideHospital&tab=models)| [Details](http://openifcmodel.cs.auckland.ac.nz/Model/Details/308) | | [Schependomlaan](https://xeokit.github.io/xeokit-bim-viewer/app/index.html?projectId=Schependomlaan&tab=storeys)| [Details](https://github.com/openBIMstandards/DataSetSchependomlaan) | | [Schependomlaan Ground Floor](https://xeokit.github.io/xeokit-bim-viewer/app/index.html?projectId=Schependomlaan_selectedStorey&tab=storeys)| [Details](https://github.com/openBIMstandards/DataSetSchependomlaan) | | [Duplex](https://xeokit.github.io/xeokit-bim-viewer/app/index.html?projectId=Duplex&tab=storeys)| [Details](http://openifcmodel.cs.auckland.ac.nz/Model/Details/274) | # License xeokit-bim-viewer is bundled within the [xeokit SDK](http://xeokit.io), which is licensed under the AGPL3. See our [Pricing](https://xeokit.io/index.html#pricing) page for custom licensing options. # The Viewer Application The [````./app/index.html````](https://github.com/xeokit/xeokit-bim-viewer/tree/master/app/index.html) page provides a ready-to-use instance of xeokit-bim-viewer. We'll just call it *viewer* from now on. The viewer loads projects and models from the [````./app/data/projects````](https://github.com/xeokit/xeokit-bim-viewer/tree/master/app/data/projects) directory. To view a project, load the viewer with the project's ID on the URL: [````https://xeokit.github.io/xeokit-bim-viewer/app/index.html?projectId=WestRiversideHospital````](https://xeokit.github.io/xeokit-bim-viewer/app/index.html?projectId=WestRiversideHospital) # Model Database > **This section shows how to add your own models to the viewer application. These instructions rely on the most > recent versions of XKT (V8 or later) and the conversion tools, which you can learn about in *[Viewing an IFC Model with xeokit](https://www.notion.so/xeokit/Viewing-an-IFC-Model-with-xeokit-c373e48bc4094ff5b6e5c5700ff580ee)* .** Let's examine the structure of the [````./app/data/projects````](https://github.com/xeokit/xeokit-bim-viewer/tree/master/app/data) directory, where the viewer keeps its projects and models. Shown below is a portion of the ````./app/data/projects```` directory. We'll describe it from the root directory downwards. Within the root, we have a directory for each project, along with a manifest of the projects in ````index.json````. Within a project directory, we have a directory for each model in the project, along with a manifest of the models in ````index.json````. Within a model directory, we have the ````.XKT```` file which contains the model's geometry and metadata. ```` .app/data/projects │ ├── index.json │ ├── Duplex │ │ │ ├── index.json │ │ │ └── models │ └── design │ └── geometry.xkt │ └── WestRiversideHospital │ ├── index.json │ └── models ├── architecture │ └── geometry.xkt ├── structure │ └── geometry.xkt └── electrical └── geometry.xkt ```` The ````index.json```` at the root of ````./app/data/projects```` is shown below. Within this file, the ````id```` of each project matches the name of that project's subdirectory. ````json { "projects": [ { "id": "Duplex", "name": "Duplex" }, { "id": "WestRiversideHospital", "name": "West Riverside Hospital" } //.. ] } ```` The ````index.json```` for the "WestRiversideHospital" project is shown below. Within this file, the ````id```` of each model matches the name of that model's subdirectory. Each model's ````name```` is the human-readable name that's displayed in the viewers Models tab. ````json { "id": "WestRiversideHospital", "name": "West Riverside Hospital Project", "models": [ { "id": "architectural", "name": "Hospital Architecture" }, { "id": "structure", "name": "Hospital Structure" }, { "id": "electrical", "name": "Hospital Electrical", "saoEnabled": false } ], "viewerConfigs": { "backgroundColor": [ 0.9, 0.9, 1.0 ] }, "viewerContent": { "modelsLoaded": [ "structure", "architectural" ] }, "viewerState": { "tabOpen": "models" } } ```` The optional ````viewerConfigs```` section specifies configurations for the viewer to set on itself as it loads the project. See the complete list of available viewer configurations in [Viewer Configurations](#viewer-configurations). The optional ````viewerContent```` array specifies IDs of models that the viewer will load initially, right after it's applied the configurations. The optional ````viewerState```` section specifies how the viewer should set up the initial state of its UI, right after its loaded the initial models. See the complete list of available viewer states in [Viewer States](#viewer-states). The ````geometry.xkt```` file for each model is created from an IFC file using open source CLI tools. Learn how to create those files in *[Viewing an IFC Model with xeokit](https://www.notion.so/xeokit/Viewing-an-IFC-Model-with-xeokit-c373e48bc4094ff5b6e5c5700ff580ee)* . # Viewer Configurations The table below lists the complete set of available configurations. Think of these as user preferences. These may be provided to the viewer within project info files, as described in [Model Database](#model-database), or set programmatically on the viewer with [````BIMViewer#setConfigs()````](https://xeokit.github.io/xeokit-bim-viewer/docs/class/src/BIMViewer.js~BIMViewer.html#instance-method-setConfigs) , as described in [Configuring the Viewer](#configuring-the-viewer). | Property | Type | Range | Default Value | Description | |:-----------------------|:--------|:-----------------------|:----------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | "backgroundColor" | Array | | ````[1.0,1.0,1.0]```` | Canvas background color | | "cameraNear" | Number | ````[0.01-0.1]```` | ````0.05```` | Distance to the near clipping plane | | "cameraFar" | Number | ````[1-100000000]```` | ````3000.0```` | Distance to the far clipping plane | | "smartPivot" | Boolean | | ````true```` | Enables a better pivot-orbiting experience when click-dragging on empty space in camera orbit mode. | | "saoEnabled" | Boolean | | ````true```` | Whether or not to enable Scalable Ambient Obscurance (SAO) | | "saoBias" | Number | ````[0.0...10.0]```` | ````0.5```` | SAO bias | | "saoIntensity" | Number | ````[0.0...200.0]```` | ````100.0```` | SAO intensity factor | | "saoScale" | Number | ````[0.0...1000.0]```` | ````500.0```` | SAO scale factor | | "saoKernelRadius" | Number | ````[0.0...200.0]```` | ````100.0```` | The maximum area that SAO takes into account when checking for possible occlusion | | "saoBlur" | Boolean | | ````true```` | Whether Guassian blur is enabled for SAO | | "edgesEnabled" | Boolean | | ````true```` | Whether or not to enhance edges on objects | | "pbrEnabled" | Boolean | | ````false```` | Whether or not to enable Physically Based rendering (PBR) | | "viewFitFOV" | Number | ````[10.0...70.0]```` | ````30```` | When fitting objects to view, this is the amount in degrees of how much they should fit the user's field of view | | "viewFitDuration" | Number | ````[0..5]```` | ````0.5```` | When fitting objects to view with an animated transition, this is the duration of the transition in seconds | | "perspectiveFOV" | Number | ````[10.0...70.0]```` | ````55```` | When in perspective projection, this is the field of view, in degrees, that the user sees | | "objectColors" | Object | | ````undefined```` | A map of custom attributes for various IFC types | | "externalMetadata" | Boolean | | ````false```` | Whether to load a metadata.json file with each geometry.xkt file | | "xrayPickable" | Boolean | | ````false```` | Whether we can interact with X-rayed objects using mouse/touch input | | "selectedGlowThrough" | Boolean | | ````true```` | Whether selected objects appear to "glow through" other objects | | "highlightGlowThrough" | Boolean | | ````true```` | Whether highlighted objects appear to "glow through" other objects | | "dtxEnabled" | Boolean | | ````false```` | Whether to enable xeokit's data texture-based (DTX) scene representation and rendering mode. This has a lower memory footprint than the standard vertex buffer object-based (VBO) mode, and loads fast, but may be slower on low-spec GPUs. | | "showSpaces" | Boolean | | ````false```` | Whether to enable the visibility of IfcSpace elements. When this is ````false````, then even though we can instruct BIMViewer to make IfcSpaces visible in the tree view or context menus, they will remain invisible. This config is also dynamically controlled by the "Show IfcSpaces" tool in the toolbar. | ## Viewer States In [Model Database](#model-database) we saw how a project can specify directives for how the viewer should set up the initial state of its UI, right after the project has loaded. The table below lists the available directives. These can also be set on the viewer using [````BIMViewer#setViewerState()````](https://xeokit.github.io/xeokit-bim-viewer/docs/class/src/BIMViewer.js~BIMViewer.html#instance-method-setViewerState) . So far, we have: | Property | Type | Range | Default Value | Description | |:----------------------|:------------------|:----------------------|:------------------|:----------------------------------| | "focusObject" | String | | | ID of object to focus on | | "tabOpen" | String | "objects", "classes" or "storeys" | | Which explorer tab to open | | "expandObjectsTree" | Number | [0..*] | 0 | How deep to expand the "objects" tree | | "expandClassesTree" | Number | [0..*] | 0 | How deep to expand the "classes" tree | | "expandStoreysTree" | Number | [0..*] | 0 | How deep to expand the "storeys" tree | | "setCamera" | { eye: Number[], look: Number[], up: Number[] } | | 0 | Camera position | # Deploying XKT V7 and Earlier > **This section describes how to deploy models that use older versions of XKT that don't combine geometry and metadata. For those older versions, > we need a little extra plumbing to deploy an additional JSON metadata file for each model.** The previous section described how to deploy models that used XKT V8 and later. The XKT V8+ format combines geometry and metadata into the same XKT file, and was introduced in the [xeokit v1.9 release](https://www.notion.so/xeokit/What-s-New-in-xeokit-1-9-b7503ca7647e43e4b9c76e1505fa4484). XKT versions prior to V8 only contained geometry, and needed to be accompanied by a JSON file that contained the model's IFC metadata. In this section, we'll describe how to deploy models that use XKT versions prior to V8. Let's imagine that we want to deploy the Duplex and West Riverside Hospital projects, using XKT V7. For each model within our database, we'll deploy a ````geometry.xkt````, which is an XKT V7 file containing the model's geometry, and a ````metadata.json ````, containing IFC metadata for the model. We'll just assume that you've got those files already, and are not ready to convert their original IFC files into XKT V8+. Here's our database files again, this time with XKT V7 and accompanying metadata files: ```` .app/data/projects │ ├── index.json │ ├── Duplex │ │ │ ├── index.json │ │ │ └── models │ └── design │ ├── geometry.xkt │ └── metadata.json │ └── WestRiversideHospital │ ├── index.json │ └── models ├── architecture │ ├── geometry.xkt │ └── metadata.json ├── structure │ ├── geometry.xkt │ └── metadata.json └── electrical ├── geometry.xkt └── metadata.json ```` To make BIMViewer load both the ````geometry.xkt```` and ````metadata.json```` files for each model, we need to add a new ````externalMetadata: true```` configuration to the ````viewerConfigs```` in the project's ````index.json```` file: ````json { "id": "WestRiversideHospital", "name": "West Riverside Hospital", "models": [ { "id": "architectural", "name": "Hospital Architecture" }, { "id": "structure", "name": "Hospital Structure" }, { "id": "electrical", "name": "Hospital Electrical", "saoEnabled": false } ], "viewerConfigs": { "externalMetadata": true, // <<------------ ADD THIS "backgroundColor": [ 0.9, 0.9, 1.0 ] }, "viewerContent": { "modelsLoaded": [ "structure", "architectural" ] }, "viewerState": { "tabOpen": "models" } } ```` # Support for Multi-Part (Split) Models Since xeokit-bim-viewer 2.4, we can deploy models that are split into multiple XKT files (with optional external JSON metadadata files). The `ifc2gltf` tool from Creoox, which converts IFC files into glTF geometry and JSON metadata files, has the option to split its output into multiple pairs of glTF and JSON files, accompanied by a JSON manifest that lists the files. To integrate with that option, the `convert2xkt` tool, which converts glTF geometry and JSON metadata files into XKT files, also has the option to batch-convert the glTF+JSON files in the manifest, in one invocation. When we use this option, convert2xkt will output a bunch of XKT files, along with a JSON manifest file that lists those XKT files. This feature extends BIMViewer with the option to load models comprised of multiple XKT files, combining the XKT files into a single tree view for each model, and enabling the unloading of the model to unload all its XKT files in one shot. In other words, instead of having a separate model and tree view for each XKT, we can now group a bunch of XKT files together to behave as one model in BIMViewer. Learn more about the conversion of IFC models into multiple XKT files in [this tutorial](https://www.notion.so/xeokit/Importing-Huge-IFC-Models-as-Multiple-XKT-Files-165fc022e94742cf966ee50003572259). To show how to deploy one of these multi-XKT models in BIMViewer, let's examine the Karhumaki project. --- * [Load the Karhumaki Project in BIMViewer](https://xeokit.io/demo.html?projectId=Karhumaki) --- ```` .app/data/projects │ ├── index.json │ └── Karhumaki │ ├── index.json │ └── models └── KarhumakiBridge ├── manifest.json ├── model.xkt ├── model_1.xkt ├── model_2.xkt ├── model_3.xkt ├── model_4.xkt ├── model_5.xkt ├── model_6.xkt ├── model_7.xkt ├── model_8.xkt └── model_9.xkt ```` The `manifest.json` XKT manifest looks like this: ````json { "xktFiles": [ "model.xkt", "model_1.xkt", "model_2.xkt", "model_3.xkt", "model_4.xkt", "model_5.xkt", "model_6.xkt", "model_7.xkt", "model_8.xkt", "model_9.xkt" ] } ```` The ````index.json```` for the "Karhumaki" project is shown below. Within this file, as usual, the ````id```` of each model matches the name of that model's subdirectory. Each model's ````name```` is the human-readable name that's displayed in the viewers Models tab. To indicate that the model is a multi-part model, with multiple XKTs, the model entry gets a ````manifest```` property containing the file name of our `manifest.json` file. In `viewerContent`, we specify that our multipart model gets loaded immediately, as soon as the project is loaded. ````json { "id": "Karhumaki", "name": "Karhumaki", "models": [ { "id": "Karhumaki-Bridge", "name": "Karhumaki Bridge", "manifest": "manifest.json" } ], "viewerConfigs": { "backgroundColor": [ 0.9, 0.9, 1.0 ] }, "viewerContent": { "modelsLoaded": [ "Karhumaki-Bridge" ] }, "viewerState": { "tabOpen": "models" } } ```` # Split Model with Separate Metadata Files In recent versions of xeokit, we combine the geometry and metadata into the XKT files, for simplicity within the pipeline, as we've done in the example above. In older versions of XKT, as mentioned above, we would have the metadata in separate JSON files, so that each XKT file would have the geometry, and would be accompanied by a JSON file containing its IFC metadata. BIMViewer, and the rest of the xeokit SDK, remains backwardly compatible with this XKT+JSON separation. The split-model loading feature also remains backwardly-compatible, as demonstrated in the "WestRiversideHospital_Combined" example project, described below. --- * [Load the WestRiversideHospital_Combined Project in BIMViewer](https://xeokit.io/demo.html?projectId=WestRiversideHospital_Combined) --- We have our separated XKT and JSON metadata files in the `models` directory: ```` .app/data/projects │ ├── index.json │ └── WestRiversideHospital_Combined ├── index.json │ └── models │ └── WestRiversideHospital ├── architectural.json ├── architectural.xkt ├── electrical.json ├── electrical.xkt ├── fireAlarms.json ├── fireAlarms.xkt ├── manifest.json ├── mechanical.json ├── mechanical.xkt ├── plumbing.json ├── plumbing.xkt ├── sprinklers.json ├── sprinklers.xkt ├── structure.json └── structure.xkt ```` The `manifest.json` XKT manifest looks as below. Notice the additional `metaModelFiles` property, which lists the JSON files that comprise the metamodel for the "WestRiversideHospital" model: ```` { "xktFiles": [ "architectural.xkt", "electrical.xkt", "fireAlarms.xkt", "mechanical.xkt", "plumbing.xkt", "sprinklers.xkt", "structure.xkt" ], "metaModelFiles": [ "architectural.json", "electrical.json", "fireAlarms.json", "mechanical.json", "plumbing.json", "sprinklers.json", "structure.json" ] } ```` Finally, the ````index.json```` for the "WestRiversideHospital_Combined" project is shown below. Within this file, as before, the ````id```` of each model matches the name of that model's subdirectory, and Each model's ````name```` is the human-readable name that's displayed in the viewers Models tab. As before, to indicate that the model is a multi-part model, with multiple XKTs, the model entry gets a ````manifest```` property containing the file name of our `manifest.json` file. In `viewerContent`, we specify that our multipart model gets loaded immediately, as soon as the project is loaded. ````json { "id": "WestRiversideHospital_Combined", "name": "West Riverside Hospital", "models": [ { "id": "WestRiversideHospital", "name": "West Riverside Hospital", "saoEnabled": true, "manifest": "manifest.json" } ], "viewerConfigs": { "backgroundColor": [0.9, 0.9, 1.0], "externalMetadata": true }, "viewerContent": { "modelsLoaded": [ "WestRiversideHospital" ] }, "viewerState": { "viewCubeEnabled": true, "threeDEnabled": true, "tabOpen": "models" } } ```` # Programming API > **This section goes deeper into the viewer, describing how to instantiate a viewer, and how to use its JavaScript programming API.** The viewer is implemented by the JavaScript [````BIMViewer````](https://xeokit.github.io/xeokit-bim-viewer/docs/class/src/BIMViewer.js~BIMViewer.html) class, which provides a complete set of methods to programmatically control it. Using these methods, we can: * create and configure a viewer, * query what models are available, * load projects and models, * interact with the 3D view, * save and load BCF viewpoints, * control the various viewer tools, and * drive the state of the viewer's UI. ## Creating a Viewer In the example below, we'll create a [````BIMViewer````](https://xeokit.github.io/xeokit-bim-viewer/docs/class/src/BIMViewer.js~BIMViewer.html), with a [````Server````](https://xeokit.github.io/xeokit-bim-viewer/docs/class/src/server/Server.js~Server.html) through which it will load projects and models from the file system. We'll configure the ````Server```` to load that data from the [````./app/data````](https://github.com/xeokit/xeokit-bim-viewer/tree/master/app/data) directory. We'll also configure our ````BimViewer```` with DOM elements to hold the four parts of its UI, which are: 1. the 3D canvas, 2. the explorer panel containing the tree views, 3. the toolbar, 4. the NavCube, and 4. the "backdrop" element, which covers everything in the UI to prevent interaction whenever the viewer is busy loading a model. ````javascript const server = new Server({ dataDir: "./data" }); const myBIMViewer = new BIMViewer(server, { canvasElement: document.getElementById("myCanvas"), // The 3D WebGL canvas explorerElement: document.getElementById("myExplorer"), // Container for the explorer panel toolbarElement: document.getElementById("myToolbar"), // Container for the toolbar navCubeCanvasElement: document.getElementById("myNavCubeCanvas"), // Canvas for the NavCube busyModelBackdropElement: document.querySelector(".xeokit-busy-modal-backdrop") // Busy modal dialog backdrop element }); ```` Configuring the ````BIMViewer```` with separate places in the document to locate its parts allows us to integrate them more flexibly into our web page. In our [````app/index.html````](https://github.com/xeokit/xeokit-bim-viewer/blob/master/app/index.html) page, the HTML elements look like this: ````html