````
See [````app/css/style.css````](https://github.com/xeokit/xeokit-bim-viewer/blob/master/app/css/style.css) for how we've
styled these elements.
Also
see [````dist/xeokit-bim-viewer.css````](https://github.com/xeokit/xeokit-bim-viewer/blob/master/dist/xeokit-bim-viewer.css)
for the CSS styles that BIMViewer applies to the elements it creates internally.
## Configuring the Viewer
With our viewer created, let's
use [````BIMViewer#setConfigs()````](https://xeokit.github.io/xeokit-bim-viewer/docs/class/src/BIMViewer.js~BIMViewer.html#instance-method-setConfigs)
to configure it.
We'll just set the canvas background color to white:
````javascript
myBIMViewer.setConfigs({
"backgroundColor": [1.0, 1.0, 1.0]
});
````
See [Viewer Configurations](#viewer-configurations) for the list of available configurations.
## Querying Projects, Models and Objects
With our viewer created and configured, let's find out what content is available.
### Getting Info on Available Projects
Let's query what projects are available.
````javascript
myBIMViewer.getProjectsInfo((projectsInfo) => {
console.log(JSON.stringify(projectsInfo, null, "\t"));
});
````
Internally, the viewer will
call [````Server#getProjects()````](https://xeokit.github.io/xeokit-bim-viewer/docs/class/src/server/Server.js~Server.html#instance-method-getProjects)
to get the projects info.
As described earlier in [Model Database](#model-database), the projects info is the JSON
in [````./app/data/projects/index.json````](https://github.com/xeokit/xeokit-bim-viewer/tree/master/app/data/projects/index.json)
. We'll just log that info to the console.
The projects info will look similar to:
````json
{
"projects": [
{
"id": "Duplex",
"name": "Duplex"
},
{
"id": "Schependomlaan",
"name": "Schependomlaan"
},
{
"id": "WestRiversideHospital",
"name": "West Riverside Hospital"
}
]
}
````
### Getting Info on a Project
Now we know what projects are available, we'll get info on one of those projects.
````javascript
myBIMViewer.getProjectInfo("WestRiversideHospital", (projectInfo) => {
console.log(JSON.stringify(projectInfo, null, "\t"));
});
````
Internally, the viewer will
call [````Server#getProject()````](https://xeokit.github.io/xeokit-bim-viewer/docs/class/src/server/Server.js~Server.html#instance-method-getProject)
to get that project info. Like before, we'll just log it to the console.
The project info will be the contents
of [````./app/data/projects/WestRiversideHospital/index.json````](https://github.com/xeokit/xeokit-bim-viewer/tree/master/app/data/projects/WestRiversideHospital/index.json)
.
The project info will be similar to:
````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": {
"backgroundColor": [
0.9,
0.9,
1.0
],
"saoEnabled": true
},
"viewerContent": {
"modelsLoaded": [
"structure",
"architectural"
]
},
"viewerState": {
"tabOpen": "models"
}
}
````
In this project info, we have:
* **````id````** - ID of the project,
* **````name````** - human-readable name of the project,
* **````models````** - info on each model in this project,
* **````viewerConfigs````** - configurations for the viewer to apply when loading the project,
* **````viewerContent````** - which models the viewer should immediately load when loading the project, and
* **````viewerState````** - how the viewer should set up its UI after loading the project.
When we later load the project in section [Loading a Project](#loading_a_project), the viewer is going to pass
the ````viewerConfigs````
to [````BIMViewer#setConfigs()````](https://xeokit.github.io/xeokit-sdk/docs/class/src/BIMViewer.js~BIMViewer.html#instance-method-setConfigs)
, which we described earlier in [Configuring the Viewer](#configuring-the-viewer).
In the ````viewerConfigs```` we're enabling the viewer's Scalable Ambient Obscurance effect, which will create ambient
shadows in the crevices of our models. This is an expensive effect for the viewer to render, so we've disabled it for
the "electrical" model, which contains many long, thin wire objects that don't show the SAO effect well.
### Getting Info on an Object
Let's attempt to get some info on an object within one of our project's models.
We say "attempt" because it's up to
the [````Server````](https://xeokit.github.io/xeokit-bim-viewer/docs/class/src/server/Server.js~Server.html) to try to
find that info for us, which might not exist.
Internally, the viewer will
call [````Server#getObjectInfo()````](https://xeokit.github.io/xeokit-bim-viewer/docs/class/src/server/Server.js~Server.html#instance-method-getObjectInfo)
, which will attempt to load that object info from a file.
If you were to substitute ````Server```` with your own implementation, your implementation might get that info from a
data store, such as a relational database, populated with metadata for all the objects in your project's models, keyed
to their IDs.
We'll go ahead and assume that our ````Server```` has info an an object.
````javascript
myViewer.getObjectInfo("WestRiversideHospital", "architectural", "2HaS6zNOX8xOGjmaNi_r6b",
(objectInfo) => {
console.log(JSON.stringify(objectInfo, null, "\t"));
},
(errMsg) => {
console.log("Oops! There was an error getting info for this object: " + errMsg);
});
````
If the object does not exist in the specified project and model, the method will invoke its error callback.
Our file system database does happen to have info for that object, stored
in [````./app/data/projects/WestRiversideHospital/models/architectural/objects/2HaS6zNOX8xOGjmaNi_r6b.json````](https://github.com/xeokit/xeokit-bim-viewer/tree/master/app/data/projects/WestRiversideHospital/models/architectural/objects/2HaS6zNOX8xOGjmaNi_r6b.json)
.
Since our object info exists, we'll get a result similar to this:
````json
{
"id": "2HaS6zNOX8xOGjmaNi_r6b",
"projectId": "WestRiversideHospital",
"modelId": "architectural",
"name": "Basic Wall:Exterior - Metal Panel on Mtl. Stud:187578",
"type": "IfcWall",
"parent": "2hExBg8jj4NRG6zzD0RZML"
}
````
> By now, you've probably noticed that our file system database is structured to
> support [RESTful](https://en.wikipedia.org/wiki/Representational_state_transfer) URIs, which
> our [````Server````](https://xeokit.github.io/xeokit-bim-viewer/docs/class/src/server/Server.js~Server.html) constructs
> from the project, model and object IDs we supplied to the viewer's query methods.
## Loading Projects and Models
Let's now load some of the projects and models that we queried in the previous section.
### Loading a Project
Let's start by loading the project we just queried info on.
````javascript
myBIMViewer.loadProject("WestRiversideHospital",
() => {
console.log("Nice! The project loaded successfully.");
},
(errMsg) => {
console.log("Oops! There was an error loading this project: " + errMsg);
});
````
If that succeeds, the viewer will now have two models loaded, ````"architectural"```` and ````"structure"````, since
those are specified in the project info's ````viewerContent````.
The viewer will also enable Scalable Ambient Obscurance, since that's specified by the ````saoEnabled```` property in
the ````viewerConfigs````. The viewer will also set various other configs on itself, as specified in that section.
The viewer will also open its "Models" tab, thanks to the ````tabOpen```` property in the project
info's ````viewerState```` section.
We can confirm that the two models are loaded by querying the IDs of the models that are currently loaded in the viewer:
````javascript
const modelIds = myBIMViewer.getModelLoadedIds();
console.log(modelIds);
````
The result would be:
````json
[
"architectural",
"structure"
]
````
### Loading a Model
With our project loaded, let's load another of its models.
We could start by getting the IDs of all the models in our project, just to make sure the model is available:
````javascript
const modelIds = myBIMViewer.getModelIds();
console.log(modelIds);
````
The result would be:
````json
[
"architectural",
"structure",
"electrical"
]
````
To load the model:
````javascript
myBIMViewer.loadModel("electrical",
() => {
console.log("Nice! The model loaded successfully.");
},
(errMsg) => {
console.log("Oops! There was an error loading this model: " + errMsg);
});
````
If we no longer need that model, we can unload it again:
````javascript
myBIMViewer.unloadModel("electrical");
````
When we no longer need the project, unload like so:
````javascript
myBIMViewer.unloadProject();
````
Note that we can only load one project at a time.
## Controlling Viewer State
[````BIMViewer````](https://xeokit.github.io/xeokit-bim-viewer/docs/class/src/BIMViewer.js~BIMViewer.html) has various
methods with which we can programmatically control the state of its UI.
Let's take a quick look at some of these methods to get an idea of what sort of UI state we can control with them. This
won't be an exhaustive guide - see the ````BIMViewer```` class documentation for the complete list.
Having loaded a couple of models in the previous section, let's open the viewer's Objects tab, which contains a tree
view of the containment hierarchy of the objects within those models:
````javascript
myBIMViewer.openTab("objects");
````
To confirm which tab is currently open:
````javascript
const tabId = myBIMViewer.getOpenTab();
console.log("Currently open tab: '" + tabId + "'"); // "objects"
````
Now let's arrange the camera to fit an object in view:
````javascript
myBIMViewer.flyToObject("1fOVjSd7T40PyRtVEklS6X", () => { /* Done */
});
````
TODO: Complete this section once API methods are finalized
## Saving and Loading BCF Viewpoints
[Bim Collaborative Format](https://en.wikipedia.org/wiki/BIM_Collaboration_Format) (BCF) is a format for managing issues
on a BIM project. A BCF record captures the visual state of a BIM viewer, which includes the camera position, the
visibility and selected states of the objects, and any section planes that are currently active.
A BCF record saved from one BIM viewer can be loaded into another viewer, to synchronize the visual states of both
viewers.
Note that BCF viewpoints do not record which models are currently loaded. It's assumed that both the source and target
viewers have the same models loaded.
Use
the [````BIMViewer#saveBCFViewpoint()````](https://xeokit.github.io/xeokit-bim-viewer/docs/class/src/BIMViewer.js~BIMViewer.html#instance-method-saveBCFViewpoint)
to save a JSON BCF record of the current view:
````javascript
const viewpoint = bimViewer.saveBCFViewpoint({
// Options - see BIMViewer#saveBCFViewpoint() documentation for details
});
````
Our viewpoint JSON will look similar to below. Before saving this viewpoint, we've hidden one object, selected another
object, and created section plane to slice our model. The viewpoint also contains a PNG snapshot of the viewer's canvas,
which we've truncated here for brevity.
````
{
perspective_camera: {
camera_view_point: { x: 0.0, y: 0.0, z: 0.0 },
camera_direction: { x: 1.0, y: 1.0, z: 2.0 },
camera_up_vector: { x: 0.0, y: 0.0, z: 1.0 },
field_of_view: 90.0
},
lines: [],
clipping_planes: [{
location: { x: 0.5, y: 0.5, z: 0.5 },
direction: { x: 1.0, y: 0.0, z: 0.0 }
}],
bitmaps: [],
snapshot: {
snapshot_type: png,
snapshot_data: "data:image/png;base64,......"
},
components: {
visibility: {
default_visibility: false,
exceptions: [{
ifc_guid: 4$cshxZO9AJBebsni$z9Yk,
originating_system: xeokit.io,
authoring_tool_id: xeokit/v1.0
}]
},
selection: [{
ifc_guid: "4$cshxZO9AJBebsni$z9Yk",
}]
}
}
````
Use
the [````BIMViewer#loadBCFViewpoint()````](https://xeokit.github.io/xeokit-bim-viewer/docs/class/src/BIMViewer.js~BIMViewer.html#instance-method-loadBCFViewpoint)
to load a JSON BCF record:
````javascript
bimViewer.loadBCFViewpoint(viewpoint, {
// Options - see BIMViewer#loadBCFViewpoint() documentation for details
});
````
# Customizing Viewer Style
The [````app/index.html````](https://github.com/xeokit/xeokit-bim-viewer/blob/master/app/index.html) file for the
standalone viewer contains CSS rules for the various viewer elements, which you can modify as required.
## Modal Busy Dialog
The viewer displays a modal dialog box whenever we load a model. The dialog box has a backdrop element, which overlays
the viewer. Whenever the dialog becomes visible, the backdrop will block interaction events on the viewer's UI.
Within our [````app/index.html````](https://github.com/xeokit/xeokit-bim-viewer/blob/master/app/index.html) page, the
main ````