Saving viewer state
Reveal supports saving the camera state and styled filters that have been applied to the loaded model(s). This functionality can help support sharing links and local storage of a given view. Internally the input to a given filter is stored and is replayed when restoring the view. This usually means that substantially less data needs to be serialized in order to share the given state of the viewer. The serialized JSON blob also keeps information about styling/filtering of the model by storing all styled sets.
Getting the viewer state
In the example below we apply some filter to our loaded model using the NodeCollection
type from Styling CAD models.
Then we can call the viewer.getViewState()
function which return a serialized JSON blob containing the view state.
Depending on the application, the view state can be additionally transformed into e.g. a URL parameter and transferred through a link.
In the example below, we keep simply print it to the developer console.
Setting the viewer state
Restoring the viewer state is simply a matter of feeding back the JSON blob retrieved from const myState = viewer.getViewState()
into viewer.setViewState(myState)
.
In the example below, a previously stored state is applied which applies a red color to nodes that have an attribute 'PDMS.Type'
.
Setting the viewer state assumes that model has already been loaded. An error will be thrown if a given state is loaded for a model which does not exist.
Serializing and deserializing custom node collections
When working with styled custom node collections, the Reveal viewer needs to know how to serialize and deserialize the set.
Serialization is handled through the abstract method serialize
which needs to be implemented when extending NodeCollection
.
The output of serialize
is of type SerializedNodeCollection
and contains a token
which is used to recreate
the NodeCollection
during deserialization, and a state
object which contains the data needed to restore
the NodeCollection
. It is up to the application developer to fill this state object with any nessesary
data needed to recreate the state of the NodeCollection
. An optional options
object can also be supplied
containing any metadata for loading data (e.g. the number of API calls to fetch the needed data in parallel).
The contents returned from serialize
is contained in the result of getViewState
.
In addition to serialization, Reveal also needs to know how to recreate the custom NodeCollection
during
deserialization. This is done by calling the free-function registerNodeCollectionType
with the same token
defined by the custom NodeCollection
and a lambda function which instantiates and restore the state of
the NodeCollection
. The lambda function has two parameters: the descriptor
containing the state and
options which should be applied to the NodeCollection
and the context containing an instance of
the CogniteClient from the Cognite SDK and the CogniteCadModel
which the NodeCollection
was originally applied to. It is up to the application developer how and if they
want to use the context and/or descriptor, but it is provided as a convinience.
An example of a simple custom NodeCollection
can be seen below.
For more information on creating a custom NodeCollection
, see create custom node collections.
// import { IndexSet, NodeCollection, registerNodeCollectionType } from '@cognite/reveal';
class MyNodeCollection extends NodeCollection {
isLoading = false;
_indexSet = new IndexSet();
constructor(model) {
// token used for serialization / deserialization
super('MyNodeCollection');
for (let i = 0; i < model.nodeCount / 2; i++) {
this._indexSet.add(i);
}
}
getIndexSet() {
return this._indexSet;
}
serialize() {
return {
token: this.classToken,
state: this._indexSet.toRangeArray()
}
}
clear() {
this._indexSet.clear();
this.notifyChanged();
}
}
// Register deserializer for type
registerNodeCollectionType(
'MyNodeCollection',
(descriptor, context) => {
return Promise.resolve(new MyNodeCollection(context.model));
}
);