diff --git a/documentation/docs/components/LiveCodeSnippet.tsx b/documentation/docs/components/LiveCodeSnippet.tsx index 479a9dfdfd6..968eb81c17b 100644 --- a/documentation/docs/components/LiveCodeSnippet.tsx +++ b/documentation/docs/components/LiveCodeSnippet.tsx @@ -38,6 +38,12 @@ export function LiveCodeSnippet(props: LiveCodeSnippetProps) { return ( { const fullCode = ` // make these things to be available in live-editor diff --git a/documentation/docs/examples/cad-save-viewerstate.mdx b/documentation/docs/examples/cad-save-viewerstate.mdx index 32c77a74079..89285fd29d9 100644 --- a/documentation/docs/examples/cad-save-viewerstate.mdx +++ b/documentation/docs/examples/cad-save-viewerstate.mdx @@ -1,150 +1,155 @@ ---- -id: cad-save-viewerstate -title: Saving viewer state -description: Demo shows how to save viewerstate of 3d models from CDF with Cognite3DViewer. ---- -import { DemoWrapper } from '@site/docs/components/DemoWrapper'; - -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](./cad-styling.mdx). - - - -## Getting the viewer state -In the example below we apply some filter to our loaded model using the `NodeCollectionBase` type from [Styling Cad models](./cad-styling.mdx). -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. - -```js runnable -const allPipes = new PropertyFilterNodeCollection(sdk, model); -allPipes.executeFilter({'PDMS': {'Type': 'PIPE'}}); -model.setDefaultNodeAppearance(DefaultNodeAppearance.Ghosted); -model.assignStyledNodeCollection(allPipes, { renderGhosted: false, color: [40, 200, 20] } ); - -console.log(JSON.stringify(viewer.getViewState(), null, 2)); -``` - -## 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'`. - -:::note -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. -::: - -```js runnable - -const myState = { - "camera": { - "position": { - "x": 165.603, - "y": 41.649, - "z": -10.940 - }, - "target": { - "x": 130.537, - "y": 49.138, - "z": -119.095 - } - }, - "models": [ - { - "defaultNodeAppearance": { - "renderGhosted": true - }, - "modelId": 3356984403684032, - "revisionId": 6664823881595566, - "styledSets": [ - { - "token": "PropertyFilterNodeCollection", - "state": { - "PDMS": { - "Type": "PIPE" - } - }, - "options": { - "requestPartitions": 1 - }, - "appearance": { - "renderGhosted": false, - "color": [ - 200, - 40, - 20 - ] - } - } - ] - } - ] -}; - -viewer.setViewState(myState); -``` - -## Serializing and deserializing custom node colletions -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 `NodeCollectionBase`. -The output of `serialize` is of type `SerializedNodeCollection` and contains a `token` which is used to recreate -the `NodeCollectionBase` during deserialization, and a `state` object which contains the data needed to restore -the `NodeCollectionBase`. It is up to the application developer to fill this state object with any nessesary -data needed to recreate the state of the `NodeCollectionBase`. 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 `NodeCollectionBase` during -deserialization. This is done by calling the free-function `registerCustomNodeCollectionType` with the same `token` -defined by the custom `NodeCollectionBase` and a lambda function which instantiates and restore the state of -the `NodeCollectionBase`. The lambda function has two parameters: the `descriptor` containing the state and -options which should be applied to the `NodeCollectionBase` and the context containing an instance of -the [CogniteClient from the Cognite SDK](https://docs.cognite.com/dev/guides/sdk/js/) and the `Cognite3DModel` -which the `NodeCollectionBase` 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 `NodeCollectionBase` can be seen below. -For more information on creating a custom `NodeCollectionBase`, see [create custom node collections](cad-styling-custom). -```jsx -// MyNodeCollection.ts - -import { NodeCollectionBase, registerCustomNodeCollectionType } from '@cognite/reveal'; - -class MyNodeCollection extends NodeCollectionBase { - - isLoading = false; - private _indexSet: IndexSet; - - constructor(model: Cognite3DModel) { - // token used for serialization / deserialization - super('MyNodeCollection'); - - this._indexSet = new IndexSet(); - for (let i = 0; i < model.nodeCount / 2; i++) { - this._indexSet.add(i); - } - } - - getIndexSet() { - return this._indexSet; - } - - serialize(): SerializedNodeCollection { - return { token: this.classToken, state: this._indexSet.toRangeArray()} - } - - clear() { - this._indexSet.clear(); - this.notifyChanged(); - } -}; - -// Register deserializer for type -registerCustomNodeCollectionType('MyNodeCollection', (descriptor, context) => { - return Promise.resolve(new MyNodeCollection(context.model)); -}); -``` +--- +id: cad-save-viewerstate +title: Saving viewer state +description: Demo shows how to save viewerstate of 3d models from CDF with Cognite3DViewer. +--- +import { DemoWrapper } from '@site/docs/components/DemoWrapper'; + +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](./cad-styling.mdx). + + + +## Getting the viewer state +In the example below we apply some filter to our loaded model using the `NodeCollectionBase` type from [Styling Cad models](./cad-styling.mdx). +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. + +```js runnable +const allPipes = new PropertyFilterNodeCollection(sdk, model); +allPipes.executeFilter({'PDMS': {'Type': 'PIPE'}}); +model.setDefaultNodeAppearance(DefaultNodeAppearance.Ghosted); +model.assignStyledNodeCollection(allPipes, { renderGhosted: false, color: [40, 200, 20] } ); + +console.log(JSON.stringify(viewer.getViewState(), null, 2)); +``` + +## 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'`. + +:::note +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. +::: + +```js runnable + +const myState = { + "camera": { + "position": { + "x": 165.603, + "y": 41.649, + "z": -10.940 + }, + "target": { + "x": 130.537, + "y": 49.138, + "z": -119.095 + } + }, + "models": [ + { + "defaultNodeAppearance": { + "renderGhosted": true + }, + "modelId": 3356984403684032, + "revisionId": 6664823881595566, + "styledSets": [ + { + "token": "PropertyFilterNodeCollection", + "state": { + "PDMS": { + "Type": "PIPE" + } + }, + "options": { + "requestPartitions": 1 + }, + "appearance": { + "renderGhosted": false, + "color": [ + 200, + 40, + 20 + ] + } + } + ] + } + ] +}; + +viewer.setViewState(myState); +``` + +## 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 `NodeCollectionBase`. +The output of `serialize` is of type `SerializedNodeCollection` and contains a `token` which is used to recreate +the `NodeCollectionBase` during deserialization, and a `state` object which contains the data needed to restore +the `NodeCollectionBase`. It is up to the application developer to fill this state object with any nessesary +data needed to recreate the state of the `NodeCollectionBase`. 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 `NodeCollectionBase` during +deserialization. This is done by calling the free-function `registerCustomNodeCollectionType` with the same `token` +defined by the custom `NodeCollectionBase` and a lambda function which instantiates and restore the state of +the `NodeCollectionBase`. The lambda function has two parameters: the `descriptor` containing the state and +options which should be applied to the `NodeCollectionBase` and the context containing an instance of +the [CogniteClient from the Cognite SDK](https://docs.cognite.com/dev/guides/sdk/js/) and the `Cognite3DModel` +which the `NodeCollectionBase` 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 `NodeCollectionBase` can be seen below. +For more information on creating a custom `NodeCollectionBase`, see [create custom node collections](cad-styling-custom). + +```js +// import { IndexSet, NodeCollectionBase, registerCustomNodeCollectionType } from '@cognite/reveal'; + +class MyNodeCollection extends NodeCollectionBase { + + 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 +registerCustomNodeCollectionType( + 'MyNodeCollection', + (descriptor, context) => { + return Promise.resolve(new MyNodeCollection(context.model)); + } +); +``` diff --git a/documentation/docs/examples/cad-styling-custom.mdx b/documentation/docs/examples/cad-styling-custom.mdx index b2e59e6baf1..97e55127ca5 100644 --- a/documentation/docs/examples/cad-styling-custom.mdx +++ b/documentation/docs/examples/cad-styling-custom.mdx @@ -17,12 +17,8 @@ be incrementally updated to avoid blocking the viewer. # Simple, static node collection ```js runnable - // import { NodeCollectionBase, DefaultNodeAppearance } from '@cognite/reveal'; -// Note! ES6 classes are not supported in this documentation, but -// the example below corresponds to the following: -/* class MyNodeCollection extends NodeCollectionBase { isLoading = false; @@ -43,27 +39,11 @@ class MyNodeCollection extends NodeCollectionBase { this._indexSet.clear(); this.notifyChanged(); } - - serialize() { throw new Error('Not supported'); } -}; +} const myNodes = new MyNodeCollection(model); model.setDefaultNodeAppearance(DefaultNodeAppearance.Ghosted); model.assignStyledNodeCollection(myNodes, { renderGhosted: false, color: [40, 200, 20] } ); -*/ - -const mySet = new NodeCollectionBase(); -mySet.getIndexSet = () => { - const indexSet = new IndexSet(); - for (let i = 0; i < model.nodeCount; i += 10) { - indexSet.add(i); - } - return indexSet; -}; -mySet.clear = () => { throw new Error('Not supported'); } - -model.setDefaultNodeAppearance(DefaultNodeAppearance.Ghosted); -model.assignStyledNodeCollection(mySet, { renderGhosted: false, color: [40, 200, 20] } ); ``` See also [guide on (de)serializing node collections](cad-save-viewerstate#serializing-and-deserializing-custom-node-colletions). diff --git a/documentation/package.json b/documentation/package.json index 2d8c7276ef9..d636825a13b 100644 --- a/documentation/package.json +++ b/documentation/package.json @@ -32,6 +32,7 @@ "npm-to-yarn": "^1.0.1", "react": "^16.8.4", "react-dom": "^16.8.4", + "react-live": "maksnester/react-live#mn/disable-transpilation-options-dist", "styled-components": "^5.1.1", "three": "0.125.2" }, diff --git a/documentation/yarn.lock b/documentation/yarn.lock index 2ebbdb8ea85..72817db63d2 100644 --- a/documentation/yarn.lock +++ b/documentation/yarn.lock @@ -1109,7 +1109,12 @@ dependencies: commander "^2.15.1" -"@cognite/potree-core@1.2.0", "@cognite/potree-core@^1.1.6": +"@cognite/potree-core@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@cognite/potree-core/-/potree-core-1.2.1.tgz#f979e3de0c8fba7fb6dfcec07e016e75a859fcf8" + integrity sha512-OzVE9R/cZ9YWOQXtej9rE9fEIRO/P3rKH02tz+qhDt7avIjNCWBvrAnOg9nLyXvkIBDQhy4r1SatJ8oT8Gfxpg== + +"@cognite/potree-core@^1.1.6": version "1.2.0" resolved "https://registry.yarnpkg.com/@cognite/potree-core/-/potree-core-1.2.0.tgz#29d42606e2dd4b4ef0ad82c97c0a23ca94f0ff65" integrity sha512-DoRe/U/12LjW09iR1VVK1WFTi/ZIeQw7k9yGHzMC4jhVgKuGiz0n8YkcQGZo4+KLULzvEW8zXz6Wqfo7BakVHA== @@ -1146,18 +1151,6 @@ version "0.0.0" uid "" -"@cognite/sdk-core@>=1": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@cognite/sdk-core/-/sdk-core-2.1.2.tgz#fd456988cb6b5921fd2f5b1366c531e5d8d4ef1f" - integrity sha512-L+nJzKBoRjkDPVuI33i4Xn5gHttPsGoOYWqAHkH/sy9FuI+d1l2rIg3Vuwr5ZryD3Gb9snXcDCCq9QsT9D3lEw== - dependencies: - "@azure/msal-browser" "^2.11.0" - cross-fetch "^3.0.4" - is-buffer "^2.0.5" - lodash "^4.17.11" - query-string "^5.1.1" - url "^0.11.0" - "@cognite/sdk-core@^1.0.0", "@cognite/sdk-core@^1.2.0": version "1.2.2" resolved "https://registry.yarnpkg.com/@cognite/sdk-core/-/sdk-core-1.2.2.tgz#be6378ffee45c5da6d0186ce97246eb19a9d9dd4" @@ -1875,6 +1868,13 @@ resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== +"@types/buble@^0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@types/buble/-/buble-0.20.0.tgz#8c076a500bb297a3955bd832ae4a1ec5ccf25753" + integrity sha512-tS+DwolzYtDuayJspUABudwjeF8t0mGzchixMDcxN9Vn96IL23AFCsZVoX3gbPkYbZnvD3W+nWCtB/HyxUaeXg== + dependencies: + magic-string "^0.25.0" + "@types/glob@^7.1.1": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" @@ -3893,6 +3893,11 @@ core-js@^2.4.1, core-js@^2.6.5: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== +core-js@^3.14.0: + version "3.15.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.15.0.tgz#db9554ebce0b6fd90dc9b1f2465c841d2d055044" + integrity sha512-GUbtPllXMYRzIgHNZ4dTYTcUemls2cni83Q4Q/TrFONHfhcg9oEGOtaGHfb0cpzec60P96UKPvMkjX1jET8rUw== + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -7852,7 +7857,7 @@ lunr@^2.3.9: resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== -magic-string@^0.25.1, magic-string@^0.25.2: +magic-string@^0.25.0, magic-string@^0.25.1, magic-string@^0.25.2: version "0.25.7" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== @@ -10113,6 +10118,11 @@ prism-react-renderer@^1.0.1, prism-react-renderer@^1.1.0: resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.2.0.tgz#5ad4f90c3e447069426c8a53a0eafde60909cdf4" integrity sha512-GHqzxLYImx1iKN1jJURcuRoA/0ygCcNhfGw1IT8nPIMzarmKQ3Nc+JcG0gi8JXQzuh0C5ShE4npMIoqNin40hg== +prism-react-renderer@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.2.1.tgz#392460acf63540960e5e3caa699d851264e99b89" + integrity sha512-w23ch4f75V1Tnz8DajsYKvY5lF7H1+WvzvLUcF0paFxkTHSp42RS0H5CttdN2Q8RR3DRGZ9v5xD/h3n8C8kGmg== + prismjs@^1.20.0: version "1.23.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.23.0.tgz#d3b3967f7d72440690497652a9d40ff046067f33" @@ -10502,6 +10512,19 @@ react-live@^2.2.1: react-simple-code-editor "^0.10.0" unescape "^1.0.1" +react-live@maksnester/react-live#mn/disable-transpilation-options-dist: + version "2.2.3" + resolved "https://codeload.github.com/maksnester/react-live/tar.gz/9e12a71a142123887e88dd406c203cd1f66d7bbc" + dependencies: + "@types/buble" "^0.20.0" + buble "0.19.6" + core-js "^3.14.0" + dom-iterator "^1.0.0" + prism-react-renderer "^1.2.1" + prop-types "^15.7.2" + react-simple-code-editor "^0.11.0" + unescape "^1.0.1" + react-loadable-ssr-addon@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/react-loadable-ssr-addon/-/react-loadable-ssr-addon-0.3.0.tgz#ae9b2d3b11721930f8d8255476d288c0e9f9290f" @@ -10562,6 +10585,11 @@ react-simple-code-editor@^0.10.0: resolved "https://registry.yarnpkg.com/react-simple-code-editor/-/react-simple-code-editor-0.10.0.tgz#73e7ac550a928069715482aeb33ccba36efe2373" integrity sha512-bL5W5mAxSW6+cLwqqVWY47Silqgy2DKDTR4hDBrLrUqC5BXc29YVx17l2IZk5v36VcDEq1Bszu2oHm1qBwKqBA== +react-simple-code-editor@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/react-simple-code-editor/-/react-simple-code-editor-0.11.0.tgz#bb57c7c29b570f2ab229872599eac184f5bc673c" + integrity sha512-xGfX7wAzspl113ocfKQAR8lWPhavGWHL3xSzNLeseDRHysT+jzRBi/ExdUqevSMos+7ZtdfeuBOXtgk9HTwsrw== + react-textarea-autosize@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.2.tgz#4f9374d357b0a6f6469956726722549124a1b2db" diff --git a/viewer/src/public/migration/Cognite3DModel.ts b/viewer/src/public/migration/Cognite3DModel.ts index e9de2f1c44e..3673d05f13d 100644 --- a/viewer/src/public/migration/Cognite3DModel.ts +++ b/viewer/src/public/migration/Cognite3DModel.ts @@ -78,7 +78,7 @@ export class Cognite3DModel extends THREE.Object3D implements CogniteModelBase { /** * Sets the default appearance for nodes that are not styled using - * {@link addStyledNodeCollection}. Updating the default style can be an + * {@link assignStyledNodeCollection}. Updating the default style can be an * expensive operation, so use with care. * * @param appearance Default node appearance. @@ -89,7 +89,7 @@ export class Cognite3DModel extends THREE.Object3D implements CogniteModelBase { /** * Gets the default appearance for nodes that are not styled using - * {@link addStyledNodeCollection}. + * {@link assignStyledNodeCollection}. */ getDefaultNodeAppearance(): NodeAppearance { return this.cadNode.defaultNodeAppearance; @@ -110,7 +110,7 @@ export class Cognite3DModel extends THREE.Object3D implements CogniteModelBase { * the sets were added, i.e. styled sets added late can overwrite styled sets added * early. * - * If the {@link nodeCollection} provided already has an assigned style, this style will + * If the `nodeCollection` provided already has an assigned style, this style will * be replaced with style provided. * * @param nodeCollection Dynamic set of nodes to apply the provided appearance to.