A _layer of ViewObjects within a View.

ViewLayers allow users to group and segregate ViewObjects based on their roles or aspects in a scene, simplifying interaction and focusing operations on specific object groups.

ViewLayers group ViewObjects based on the layerId of the corresponding SceneObject.

See @xeokit/sdk/viewer for more info.


Automatic vs. Manual ViewLayers

  • Automatic ViewLayers - Created automatically on-the-fly as SceneObjects with layerIds are created and destroyed. Ensures a dynamic and self-managing system where layers appear and disappear based on the existence of relevant objects.

  • Manual ViewLayers - Requires user's manual creation and destruction of ViewLayers. ViewLayers persist even after objects are destroyed.


Automatic ViewLayers

ViewLayers are useful for separating different types of objects, such as models and environment objects. A common use case is to create separate layers for models and environment objects like the ground or skybox. This allows focusing on model objects for operations like highlighting, hiding, or interacting, without affecting background objects.

Create a Viewer:

import {Viewer} from "@xeokit/sdk/viewer";

const myViewer = new Viewer({
id: "myViewer"
});

Create a View, with autoLayers set true:

const view1 = myViewer.createView({
id: "myView",
elementId: "myView1",
autoLayers: true // <<----------- Default
});

view1.camera.eye = [-3.933, 2.855, 27.018];
view1.camera.look = [4.400, 3.724, 8.899];
view1.camera.up = [-0.018, 0.999, 0.039];

Next, create a SceneModel with four SceneObjects. The first two SceneObjects will represent a skybox and a ground plane, while the other two will represent a building foundation and walls.

The skybox and ground plane SceneObjects will assign their ViewObjects to the "environment" ViewLayer, and the building foundation and walls will assign theirs to the "model" ViewLayer.

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

// (calls to SceneModel createGeometry and
// createLayerMesh omitted for brevity)

sceneModel.createObject({
id: "ground",
meshIds: ["groundMesh}],
layerId: "environment"
});

sceneModel.createObject({
id: "skyBox",
meshIds: ["skyBoxMesh}],
layerId: "environment"
});

sceneModel.createObject({
id: "houseFoundation",
meshIds: ["myMesh}],
layerId: "model"
});

sceneModel.createObject({
id: "houseWalls",
meshIds: ["myMesh}],
layerId: "model"
});

Our View now has an "environment" ViewLayer, which contains ViewObjects for the skybox and ground plane, and a "model" ViewLayer, which contains ViewObjects for the house foundation and walls.

We can now focus our updates on the ViewObjects in each ViewLayer.

const environmentLayer = view1.layers["environment"];
environmentLayer.setObjectsVisible(environmentLayer.objectIds, true);

const modelLayer = view1.layers["model"];
modelLayer.setObjectsSelected(modelLayer.objectIds, true);

Manual ViewLayers

Create a Viewer:

import {Viewer} from "@xeokit/sdk/viewer";

const myViewer = new Viewer({
id: "myViewer"
});

Create a View with autoLayers set false.

This will prevent the View from creating ViewLayers automatically.

const view1 = myViewer.createView({
id: "myView",
elementId: "myCanvas1",
autoLayers: false // <<----------- Override default
});

view1.camera.eye = [-3.933, 2.855, 27.018];
view1.camera.look = [4.400, 3.724, 8.899];
view1.camera.up = [-0.018, 0.999, 0.039];

Create a "model" ViewLayer, but this time don't create an "environment" ViewLayer:

const modelViewLayer = view1.createLayer({
id: "model",
visible: true
});

As in the previous example, we'll now create a SceneModel containing two model SceneObjects representing a building foundation and walls, along with two environmental ViewerObjects representing a skybox and ground plane.

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

// (calls to SceneModel createGeometry and
// createLayerMesh omitted for brevity)

sceneModel.createObject({
id: "ground",
meshIds: ["groundMesh}],
layerId: "environment"
});

sceneModel.createObject({
id: "skyBox",
meshIds: ["skyBoxMesh}],
layerId: "environment"
});

sceneModel.createObject({
id: "houseFoundation",
meshIds: ["myMesh}],
layerId: "model"
});

sceneModel.createObject({
id: "houseWalls",
meshIds: ["myMesh}],
layerId: "model"
});

This time, however, our View has created ViewObjects only for the "model" SceneObjects, while ignoring the "environment" SceneObjects.

From this View's perspective, the "environment" SceneObjects don't exist because no "environment" ViewLayer exists.

const modelLayer = view1.layers["model"];
modelLayer.setObjectsVisible(modelLayer.objectIds, true);

Loading a model into a ViewLayer

Create a Viewer:

import {Viewer} from "@xeokit/sdk/viewer";
import {DotBIMLoader} from "@xeokit/sdk/formats/dotbim";

const myViewer = new Viewer({
id: "myViewer"
});

Create a View, with autoLayers set true:


const view1 = myViewer.createView({
id: "myView",
elementId: "myView1",
autoLayers: true // <<----------- Default
});

view1.camera.eye = [-3.933, 2.855, 27.018];
view1.camera.look = [4.400, 3.724, 8.899];
view1.camera.up = [-0.018, 0.999, 0.039];

Create a SceneModel, with layerId "environmental", and create some environmental objects in it.

const environentSceneModel = myViewer.scene.createModel({
id: "myModel",
layerId: "environment"
});

//...

environentSceneModel.createObject({
id: "ground",
meshIds: ["groundMesh}]
});

environentSceneModel.createObject({
id: "skyBox",
meshIds: ["skyBoxMesh}]
});

Create a second SceneModel, with layerId "model", and load a BIM model into it.

const modelSceneModel = myViewer.scene.createModel({
id: "myModel2",
layerId: "model",
});

fetch(`model.bim`)
.then(response => {
response
.json()
.then(fileData => {
DotBIMLoader({
fileData,
modelSceneModel
})
.then(()=>{
// Loaded
})
.catch(err => {
console.error(err);
});
}).catch(err => {
console.error(err);
});
}).catch(err => {
console.error(err);
});

All our model objects are now in the "model" ViewLayer, and all our environmental objects are in the "environment" ViewLayer.

Let's show all the model objects, and hide all the environmental objects:

const modelLayer = view1.layers["model"];
modelLayer.setObjectsVisible(modelLayer.objectIds, true);

const environmentLayer = view1.layers["environmentLayer"];
environmentLayer.setObjectsVisible(environmentLayer.objectIds, false);

Constructors

  • Parameters

    • options: {
          autoDestroy?: boolean;
          id: string;
          renderMode?: number;
          view: View;
          viewer: Viewer;
      }

    Returns ViewLayer

Properties

_colorizedObjectIds: string[]
_highlightedObjectIds: string[]
_numColorizedObjects: number
_numHighlightedObjects: number
_numObjects: number
_numOpacityObjects: number
_numSelectedObjects: number
_numVisibleObjects: number
_numXRayedObjects: number
_objectIds: string[]
_opacityObjectIds: string[]
_renderModes: number[]
_selectedObjectIds: string[]
_visibleObjectIds: string[]
_xrayedObjectIds: string[]
colorizedObjects: { [key: string]: ViewObject }

Map of currently colorized ViewObjects in this ViewLayer.

Each ViewObject is mapped here by ViewObject.id.

destroyed: boolean = false

True if this ViewLayer has been destroyed.

gammaOutput: boolean
highlightedObjects: { [key: string]: ViewObject }

Map of currently highlighted ViewObjects in this ViewLayer.

A ViewObject is highlighted when ViewObject.highlighted is true.

Each ViewObject is mapped here by ViewObject.id.

id: string

ID of this ViewLayer, unique within the View.

This ViewLayer is mapped by this ID in View.layers.

objects: { [key: string]: ViewObject }

Map of the all ViewObjects in this ViewLayer.

These are the ViewObjects for which SceneObject.layerId has the same value as the ViewLayer.id.

Each ViewObject is mapped here by ViewObject.id.

The ViewLayer automatically ensures that there is a ViewObject here for each scene!SceneObjectRendererProxy in the Viewer

opacityObjects: { [key: string]: ViewObject }

Map of ViewObjects in this ViewLayer whose opacity has been updated.

Each ViewObject is mapped here by ViewObject.id.

selectedObjects: { [key: string]: ViewObject }

Map of currently selected ViewObjects in this ViewLayer.

A ViewObject is selected when ViewObject.selected is true.

Each ViewObject is mapped here by ViewObject.id.

view: View

The View to which this ViewLayer belongs.

viewer: Viewer

The Viewer to which this ViewLayer belongs.

visibleObjects: { [key: string]: ViewObject }

Map of the currently visible ViewObjects in this ViewLayer.

A ViewObject is visible when ViewObject.visible is true.

Each ViewObject is mapped here by ViewObject.id.

xrayedObjects: { [key: string]: ViewObject }

Map of currently x-rayed ViewObjects in this ViewLayer.

A ViewObject is x-rayed when ViewObject.xrayed is true.

Each ViewObject is mapped here by ViewObject.id.

Accessors

Methods

  • Sets the clippability of the given ViewObjects in this ViewLayer.

    • Updates ViewObject.clippable on the Objects with the given IDs.
    • Enables or disables the ability to pick the given Objects with View.pick.

    Parameters

    • objectIds: string[]

      Array of ViewObject.id values.

    • clippable: boolean

      Whether or not to set clippable.

    Returns boolean

    True if any ViewObjects were updated, else false if all updates were redundant and not applied.

  • Sets the pickability of the given ViewObjects in this ViewLayer.

    • Updates ViewObject.pickable on the Objects with the given IDs.
    • Enables or disables the ability to pick the given Objects with View.pick.

    Parameters

    • objectIds: string[]

      Array of ViewObject.id values.

    • pickable: boolean

      Whether or not to set pickable.

    Returns boolean

    True if any ViewObjects were updated, else false if all updates were redundant and not applied.