This article describes how to migrate between different major versions of Reveal and from the old
Migrating from Reveal 1.x
There are some important differences between version 1 and version 2 of
@cognite/reveal which might require changes in the build configuration and code. The most important changes are:
- The node styling/filtering API has been reworked and will require changes. See below for more information.
- ThreeJS and @types/three is included in the package, so it's no longer necessary to include this in the application you are using Reveal from if you are not using ThreeJS directly.
Cognite3DViewer.getIntersectionFromPixelis now async.
Migrating to the new node styling API
Before reading this chapter it's recommended to read through the introduction to the new styling and filtering API.
In the 2.0 of release of Reveal, the filtering and styling API changed drastically - breaking existing functionality. Migrating to version 2 will most likely require code changes, but these should often be quite limited and lead to a simplification of the code base along with an increase in filtering- and styling performance.
In previous versions of Reveal, styling was done by a set of functions for explicitly applying styling to a node identified by a tree index (and optionally all its children).
- Visibility -
- Color override -
- Ghost nodes -
- Highlighting -
This allowed flexible styling of nodes, but required many individual calls to update each node, causing degraded performance. The new API instead requires a set of styles which nodes are assigned to. It is preferable not to have too many styles - both in terms of performance and to avoid a cluttered view for the end user.
The previous styling options maps quite directly to the new API. Visibility is controlled by
color override by
NodeAppearance.color and ghost mode by
NodeAppearance.renderGhosted. However, there is no
direct mapping between what was previously called 'selection' or 'highlighting', this is now a combination of
NodeAppearance.outlineColor. This means that the new API
introduces additional flexibility - e.g. an object can have an outline, but not be rendered in front of other objects. For
convenience, the new API comes with a set of default styles available through
A commonly used functionality is to apply a default style to all nodes and to style a few selected nodes with a different
style to make them stand out. Before, this could be achieved using a
apply the default styling, and a combination of the different per-node styling functions mentioned above to style the
nodes that should stand out. In Reveal 2, this is replaced by
Cognite3DModel.setDefaultNodeAppearance which is a style that will be applied to any node that is not styled by another styled set.
Using TreeIndexNodeCollection to migrate existing filtering logic
In general, it is recommended to use the specialized
NodeCollection-implementations for best performance. However,
it is possible to use
TreeIndexNodeCollection as a migration step and simple use cases. This allows the use of previously implemented logic for
populating the set based on some application specific logic.
As an example, consider an application that has some logic for only showing objects that are part of the 'EA'-function. In previous versions this could be achieved by doing:
Now, the same can be implemented using:
Note that the styling is set up before any nodes actually are fetched and that the set is populated asynchronously.
This example could easily have been migrated using
TreeIndexNodeCollection, but in
other cases this might not be as straight forward as shown.
A note on
applyToAllChildren to style all descendants of a node
In previous versions, all styling functions accepted an optional
When this was
true, Reveal would apply the styling to all descendants. When migrating
to the new version, adding the root tree index of the subtree to
TreeIndexNodeCollection will not have
the same result. When you also have a
subtreeSize available, use
new NumericRange(treeIndex, subtreeSize) to add the full subtree. If you don't know the
Cognite3DModel.getSubtreeIndices() can be used to get the full range of tree indices.
This section describes how to migrate from
@cognite/3d-viewer to Reveal version 1. It doesn't take into account changes
between Reveal versions 1 and 2.
@cognite/3d-viewer is an older version of Reveal that has similar functionality to this package. However, some important differences caused us to switch the package name to
@cognite/3d-viewerdownloads all geometry when a model is loaded. This causes higher initial loading time, but potentially increases the performance once the data has been loaded. It also limits the size of the models that can be loaded. The new version,
@cognite/reveal, is based on "streaming geometry" which downloads necessary geometry within a budget as the camera moved. This enables support for very complex 3D models and reduces the initial loading time.
@cognite/3d-viewersupports styling 3D nodes by node ID. In
@cognite/revealthe recommended approach is to use tree indices instead. See Styling nodes for more information. For an introduction to the differences between these concepts, see Concepts. The new component supports mapping between the two identifiers when necessary.
@cognite/3d-viewersupports photogrammetry models through textures while
@cognite/revealsupports photogrammetry through point clouds. This is due to the heavy processing load textures places on processing.
@cognite/revealsupports styling a 3D node and all it's children in one operation. In
@cognite/3d-viewerit's necessary to iterate over all children and manually apply the same change to all nodes.
@cognite/revealsupports point cloud models. This is not supported in
@cognite/revealrequires new output file formats. See Preparing models below for details.
The APIs are very similar and the functionality provided in
@cognite/reveal should feel familiar. There are several operations supported in
@cognite/3d-viewer which isn't supported by
@cognite/reveal, but these have been replaced by alternatives that should provide similar functionality.
@cognite/3d-viewer, there are several functions for manipulating the styling of 3D nodes. These functions identify nodes by their node IDs. In
@cognite/reveal similar functions exist, but these identify the nodes by their tree indices. It's therefor necessary to migrate to the new functions.
Cognite3DModel.setNodeColor(nodeId, r, g, b)has been replaced by
setNodeColorByTreeIndex(treeIndex, r, g, b, applyToChildren?)
Cognite3DModel.resetNodeColor(nodeId)has been replaced by
Cognite3DModel.getNodeColor(nodeId)is no longer supported
Cognite3DModel.resetAllNodeColors()has been added to the API
The new functions identify nodes by tree index rather than node ID. It also supports applying the same color to all children of the identified node. Note that the functions identifying nodes by node ID will work, but will be slower and use is not recommended.
Cognite3DModel.selectNode(nodeId)has been replaced by
Cognite3DModel.deselectNode(nodeId)has been replaced by
Cognite3DModel.deselectAllNodes()works equally in both components
The new functions identify nodes by tree index rather than node ID. It also supports selecting/highlighting all children of the identified node. Note that the functions identifying nodes by node ID will work, but will be slower and use is not recommended.
Controlling node visibility
Cognite3DModel.showNode(nodeId)has been replaced by
Cognite3DModel.hideNode(nodeId)has been replaced by
Cognite3DModel.showAllNodes()works equally in both components
Cognite3DModel.hideAllNodes(makeGray?)doesn't support setting
The new functions identify nodes by tree index rather than node ID. It also supports showing/hiding all children of the identified node. Note that the functions identifying nodes by node ID will work, but will be slower and use is not recommended.
Node visitor functions
Reveal has functions for iterating over nodes, either all nodes in a 3D model or a subtree of a parent node. Notice that all functions are async, and the action that you pass is not applied immediately. A single model can have millions of nodes. That's why the iteration functions call the passed action step by step. You can see it in action in our node visiting example where colors are applied gradually to nodes.
Cognite3DModel.iterateNodes(action: (nodeId, treeIndex) => void): Promise<boolean>has been replaced by
iterateNodesByTreeIndex(action: (treeIndex) => void): Promise<void>. Returns promise which resolves once iteration has done.
Cognite3DModel.iterateSubtree(nodeId, action: (nodeId, treeIndex) => void, treeIndex?, subtreeSize?)has been replaced by
iterateSubtreeByTreeIndex(treeIndex, action: (treeIndex) => void): Promise<number>. Returns promise which resolves once iteration has done.
Accessing node information and mapping between node IDs and tree indices
Reveal supports accessing information about 3D nodes through the Cognite SDK. However, the SDK identifies nodes by node ID, not tree index. It might be necessary to map between the two concepts. The following functions provide such functionality:
Note that the operation requires communication with CDF servers and should be kept at a minimum. It's recommended to use the functions that accepts a list of nodes to map whenever possible. Batching requests is recommended to achieve the best performance.
Access to node information such as name, bounding box and properties/attributes is done through the 3D revision API, specifically:
list3DNodesfor retrieving a set of nodes using a filter
list3DNodeAncestorsfor retrieving ancestors of a specific node
retrieve3DNodesfor retrieving a set of nodes identified by their node ids
The API for accessing node information has not changed
@cognite/3d-viewer, but since Reveal now uses tree indices explicit mapping tree index to node ID is necessary.
Working with asset mappings
Ray picking and intersection for handling click events
Cognite3dViewer.getIntersectionFromPixel optionally accepts a
model-argument to restrict the result to a single model. Support for this has been removed
getIntersectionFromPixel would return a struct with both
treeIndex. Now this has been changed to only include
There are a few other noticeable changes from
@cognite/3d-viewersupports local caching to reduce the time to load previously opened 3D models. Currently, this is not supported by
@cognite/reveal, but the need for such functionality is reduced by adding streaming capabilities.
Cognite3DViewer.addModel(...)will always return a
@cognite/revealthis function might also return a
CognitePointCloudModel. To explicitly add a CAD model or point cloud model use
Cognite3DViewer.loadCameraFromModel(...)] has been added for loading camera settings from CDF when available.
- Due to the way
@cognite/revealstreams data, the
OnProgressDatais no longer exported, and the
addModelfunction no longer accepts an
onProgressparameter. Because of this the
Cognite3DViewer.addModelhas been deprecated. To monitor loading activity, use the
onLoading-callback provided as an option when constructing
Cognite3DViewer.getCamera()can now be used to access the
THREE.Cameraof the viewer. Note that this camera shouldn't be modified.
Cognite3DViewer.addModelno longer supports options
onComplete. Point clouds currently don't support
- Textures are not supported by
@cognite/reveal. Models can be loaded, but textures are not applied to the geometry.
@cognite/revealsupports several anti-alias techniques which might improve visual quality at some performance cost. To use these new modes, see the
antiAliasingHint-option provided in the
@cognite/reveal requires new output file formats which means that 3D models that have been converted before June 2020 might need reconversion. To determine if a model needs reconversion, the listModelRevisionOutputs API endpoint can be used with URL parameter
format=reveal-directory. This can be done using the SDK, e.g.:
Or by using
curl (requires a Cognite API key or access token):
APIKEY must be set in the environment variables. If the model isn't compatible the response will be an empty list, i.e.
If the model isn't compatible with
@cognite/reveal, it must be reprocessed. This can be done by uploading a new revision in Cognite Data Fusion. When uploading a new revision, asset mappings must be recreated. If the node hierarchy in the new revision is identical to the previous model node IDs should be identical and the asset mappings can be copied from one revision to the other by using the get3DMappings and create3DMappings API endpoints.
Another alternative is to use the experimental 'reprocess' endpoint which generates new model outputs for a 3D model and is less intrusive than uploading a new revision. Since this endpoint is experimental it's not publicly exposed in the API yet. Please contact email@example.com if you want to explore this option.
TypeError: e.applyMatrix4 is not a function
If you experience
TypeError: e.applyMatrix4 is not a function after migrating from
@cognite/reveal, the problem is usually caused by missing or
To fix this issue, install or update ThreeJS using the
three-package. This should match the version