From 32d5424286d122125ec949679f194701d09ab836 Mon Sep 17 00:00:00 2001 From: Nils Petter Fremming Date: Wed, 21 Aug 2024 15:50:16 +0200 Subject: [PATCH 1/5] Initial commit --- .../src/components/RevealToolbar/FitModelsButton.tsx | 2 +- react-components/src/hooks/useCameraNavigation.tsx | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/react-components/src/components/RevealToolbar/FitModelsButton.tsx b/react-components/src/components/RevealToolbar/FitModelsButton.tsx index b25bfdd1ee8..99a3be0875e 100644 --- a/react-components/src/components/RevealToolbar/FitModelsButton.tsx +++ b/react-components/src/components/RevealToolbar/FitModelsButton.tsx @@ -13,7 +13,7 @@ export const FitModelsButton = (): ReactElement => { const { t } = useTranslation(); const updateCamera = useCallback(() => { - cameraNavigation.fitCameraToAllModels(); + cameraNavigation.fitCameraToSceneBoundingBox(); }, []); return ( diff --git a/react-components/src/hooks/useCameraNavigation.tsx b/react-components/src/hooks/useCameraNavigation.tsx index e71bc1ad24f..233fa8799ff 100644 --- a/react-components/src/hooks/useCameraNavigation.tsx +++ b/react-components/src/hooks/useCameraNavigation.tsx @@ -8,6 +8,7 @@ import { useFdmNodeCache } from '../components/CacheProvider/NodeCacheProvider'; import { Box3 } from 'three'; export type CameraNavigationActions = { + fitCameraToSceneBoundingBox: (duration?: number) => void; fitCameraToAllModels: (duration?: number) => void; fitCameraToModelNode: (revisionId: number, nodeId: number) => Promise; fitCameraToModelNodes: (revisionId: number, nodeids: number[]) => Promise; @@ -20,6 +21,10 @@ export const useCameraNavigation = (): CameraNavigationActions => { const fdmNodeCache = useFdmNodeCache(); const viewer = useReveal(); + const fitCameraToSceneBoundingBox = (duration?: number): void => { + viewer.fitCameraToSceneBoundingBox(duration); + }; + const fitCameraToAllModels = (duration?: number): void => { const models = viewer.models; if (models.length === 0) { @@ -78,6 +83,7 @@ export const useCameraNavigation = (): CameraNavigationActions => { }; return { + fitCameraToSceneBoundingBox, fitCameraToAllModels, fitCameraToInstance, fitCameraToInstances, From 715ccb45f0cb30c7fae7ea1c45af2d17f419b83c Mon Sep 17 00:00:00 2001 From: Nils Petter Fremming Date: Thu, 29 Aug 2024 15:18:14 +0200 Subject: [PATCH 2/5] Initial commit --- .../ToggleAllModelsVisibleCommand.ts | 50 +++++++++++++++++++ .../base/renderTarget/RevealRenderTarget.ts | 38 +++++++++----- .../base/utilities/geometry/Range1.ts | 2 +- .../base/utilities/geometry/Range3.ts | 12 ++++- .../architecture/base/views/GroupThreeView.ts | 13 ++++- .../concrete/axis/AxisThreeView.ts | 17 +++---- .../concrete/config/StoryBookConfig.ts | 2 + .../concrete/measurements/MeasurementTool.ts | 2 +- .../concrete/primitives/plane/PlaneView.ts | 13 +++-- .../RevealToolbar/FitModelsButton.tsx | 2 +- .../src/hooks/useCameraNavigation.tsx | 12 ++--- 11 files changed, 126 insertions(+), 37 deletions(-) create mode 100644 react-components/src/architecture/base/concreteCommands/ToggleAllModelsVisibleCommand.ts diff --git a/react-components/src/architecture/base/concreteCommands/ToggleAllModelsVisibleCommand.ts b/react-components/src/architecture/base/concreteCommands/ToggleAllModelsVisibleCommand.ts new file mode 100644 index 00000000000..a42eaeccdfb --- /dev/null +++ b/react-components/src/architecture/base/concreteCommands/ToggleAllModelsVisibleCommand.ts @@ -0,0 +1,50 @@ +/*! + * Copyright 2024 Cognite AS + */ + +import { RenderTargetCommand } from '../commands/RenderTargetCommand'; +import { type TranslateKey } from '../utilities/TranslateKey'; + +export class ToggleAllModelsVisibleCommand extends RenderTargetCommand { + public override get tooltip(): TranslateKey { + return { fallback: 'Show or hide all models' }; + } + + public override get icon(): string { + return 'EyeShow'; + } + + public override get isToggle(): boolean { + return true; + } + + public override get isChecked(): boolean { + return this.isAnyVisible(); + } + + public override get isEnabled(): boolean { + return this.renderTarget.viewer.models.length > 0; + } + + protected override invokeCore(): boolean { + const isVisible = this.isAnyVisible(); + for (const model of this.renderTarget.viewer.models) { + model.visible = !isVisible; + } + this.renderTarget.invalidate(); + return true; + } + + // ================================================== + // INSTANCE METHODS + // ================================================== + + private isAnyVisible(): boolean { + for (const model of this.renderTarget.viewer.models) { + if (model.visible) { + return true; + } + } + return false; + } +} diff --git a/react-components/src/architecture/base/renderTarget/RevealRenderTarget.ts b/react-components/src/architecture/base/renderTarget/RevealRenderTarget.ts index 5cb692006ba..03adccd915d 100644 --- a/react-components/src/architecture/base/renderTarget/RevealRenderTarget.ts +++ b/react-components/src/architecture/base/renderTarget/RevealRenderTarget.ts @@ -9,7 +9,8 @@ import { type Cognite3DViewer, type IFlexibleCameraManager, CDF_TO_VIEWER_TRANSFORMATION, - CognitePointCloudModel + CognitePointCloudModel, + CogniteCadModel } from '@cognite/reveal'; import { Vector3, @@ -136,11 +137,15 @@ export class RevealRenderTarget { return this.cameraManager.getCamera(); } - public get clippedSceneBoundingBox(): Box3 { + // ================================================== + // INSTANCE PROPERTIES: Get bounding box + // ================================================== + + public get clippedVisualSceneBoundingBox(): Box3 { if (this._clippedBoundingBox === undefined) { - return this.sceneBoundingBox; + return this.visualSceneBoundingBox; } - const boundingBox = this.sceneBoundingBox.clone(); + const boundingBox = this.visualSceneBoundingBox.clone(); boundingBox.intersect(this._clippedBoundingBox); return boundingBox; } @@ -149,6 +154,14 @@ export class RevealRenderTarget { return this.viewer.getSceneBoundingBox(); } + public get visualSceneBoundingBox(): Box3 { + return this.viewer.getVisualSceneBoundingBox(); + } + + // ================================================== + // INSTANCE METHODS + // ================================================== + public *getPointClouds(): Generator { for (const model of this.viewer.models) { if (model instanceof CognitePointCloudModel) { @@ -157,9 +170,13 @@ export class RevealRenderTarget { } } - // ================================================== - // INSTANCE METHODS - // ================================================== + public *getCadModels(): Generator { + for (const model of this.viewer.models) { + if (model instanceof CogniteCadModel) { + yield model; + } + } + } public setConfig(config: BaseRevealConfig): void { this._config = config; @@ -178,6 +195,7 @@ export class RevealRenderTarget { public onStartup(): void { this._config?.onStartup(this); + CommandsUpdater.update(this); } public dispose(): void { @@ -237,11 +255,7 @@ export class RevealRenderTarget { // ================================================== public fitView(): boolean { - const boundingBox = this.clippedSceneBoundingBox; - if (boundingBox.isEmpty()) { - return false; - } - this.viewer.fitCameraToBoundingBox(this.clippedSceneBoundingBox); + this.viewer.fitCameraToBoundingBox(this.clippedVisualSceneBoundingBox); return true; } diff --git a/react-components/src/architecture/base/utilities/geometry/Range1.ts b/react-components/src/architecture/base/utilities/geometry/Range1.ts index 7a1cc452fa8..3c5216ee05b 100644 --- a/react-components/src/architecture/base/utilities/geometry/Range1.ts +++ b/react-components/src/architecture/base/utilities/geometry/Range1.ts @@ -181,7 +181,7 @@ export class Range1 { // INSTANCE METHODS: Operations // ================================================== - public clear(): void { + public makeEmpty(): void { this._min = 0; this._max = 0; this._isEmpty = true; diff --git a/react-components/src/architecture/base/utilities/geometry/Range3.ts b/react-components/src/architecture/base/utilities/geometry/Range3.ts index 3c8964c36ae..a88dae19c88 100644 --- a/react-components/src/architecture/base/utilities/geometry/Range3.ts +++ b/react-components/src/architecture/base/utilities/geometry/Range3.ts @@ -220,8 +220,18 @@ export class Range3 { // INSTANCE METHODS: Operations // ================================================== + public makeEmpty(): void { + this.x.makeEmpty(); + this.y.makeEmpty(); + this.z.makeEmpty(); + } + public copy(box: Box3): void { - this.set(box.min, box.max); + if (box.isEmpty()) { + this.makeEmpty(); + } else { + this.set(box.min, box.max); + } } public set(min: Vector3, max: Vector3): void { diff --git a/react-components/src/architecture/base/views/GroupThreeView.ts b/react-components/src/architecture/base/views/GroupThreeView.ts index 3913af54377..519ab7bcf32 100644 --- a/react-components/src/architecture/base/views/GroupThreeView.ts +++ b/react-components/src/architecture/base/views/GroupThreeView.ts @@ -34,6 +34,7 @@ export abstract class GroupThreeView { return this.style.depthTest; } - protected override get needsUpdate(): boolean { + protected override needsUpdateCore(): boolean { const target = this.renderTarget; // Check if bounding box is different @@ -98,7 +98,7 @@ export class PlaneView extends GroupThreeView { return false; } this._sceneBoundingBox.copy(sceneBoundingBox); - this._sceneRange.copy(this._sceneBoundingBox); + this._sceneRange.copy(sceneBoundingBox); return true; } @@ -106,10 +106,13 @@ export class PlaneView extends GroupThreeView { const { domainObject, style } = this; const plane = domainObject.plane; - const sceneBoundingBox = this._sceneBoundingBox.clone(); - sceneBoundingBox.applyMatrix4(CDF_TO_VIEWER_TRANSFORMATION.clone().invert()); + if (this._sceneBoundingBox.isEmpty()) { + return; + } + const boundingBox = this._sceneBoundingBox.clone(); + boundingBox.applyMatrix4(CDF_TO_VIEWER_TRANSFORMATION.clone().invert()); const range = new Range3(); - range.copy(sceneBoundingBox); + range.copy(boundingBox); let p0: Vector3 | undefined; let p1: Vector3 | undefined; diff --git a/react-components/src/components/RevealToolbar/FitModelsButton.tsx b/react-components/src/components/RevealToolbar/FitModelsButton.tsx index 99a3be0875e..dd0d983f683 100644 --- a/react-components/src/components/RevealToolbar/FitModelsButton.tsx +++ b/react-components/src/components/RevealToolbar/FitModelsButton.tsx @@ -13,7 +13,7 @@ export const FitModelsButton = (): ReactElement => { const { t } = useTranslation(); const updateCamera = useCallback(() => { - cameraNavigation.fitCameraToSceneBoundingBox(); + cameraNavigation.fitCameraToVisualSceneBoundingBox(); }, []); return ( diff --git a/react-components/src/hooks/useCameraNavigation.tsx b/react-components/src/hooks/useCameraNavigation.tsx index 233fa8799ff..8337e8f4359 100644 --- a/react-components/src/hooks/useCameraNavigation.tsx +++ b/react-components/src/hooks/useCameraNavigation.tsx @@ -8,7 +8,7 @@ import { useFdmNodeCache } from '../components/CacheProvider/NodeCacheProvider'; import { Box3 } from 'three'; export type CameraNavigationActions = { - fitCameraToSceneBoundingBox: (duration?: number) => void; + fitCameraToVisualSceneBoundingBox: (duration?: number) => void; fitCameraToAllModels: (duration?: number) => void; fitCameraToModelNode: (revisionId: number, nodeId: number) => Promise; fitCameraToModelNodes: (revisionId: number, nodeids: number[]) => Promise; @@ -21,8 +21,8 @@ export const useCameraNavigation = (): CameraNavigationActions => { const fdmNodeCache = useFdmNodeCache(); const viewer = useReveal(); - const fitCameraToSceneBoundingBox = (duration?: number): void => { - viewer.fitCameraToSceneBoundingBox(duration); + const fitCameraToVisualSceneBoundingBox = (duration?: number): void => { + viewer.fitCameraToVisualSceneBoundingBox(duration); }; const fitCameraToAllModels = (duration?: number): void => { @@ -41,11 +41,11 @@ export const useCameraNavigation = (): CameraNavigationActions => { } const nodeBoundingBoxes = await (model as CogniteCadModel).getBoundingBoxesByNodeIds(nodeIds); - const unionedBox = nodeBoundingBoxes.reduce( + const boundingBox = nodeBoundingBoxes.reduce( (currentBox, nextBox) => currentBox.union(nextBox), new Box3() ); - viewer.cameraManager.fitCameraToBoundingBox(unionedBox); + viewer.cameraManager.fitCameraToBoundingBox(boundingBox); }; const fitCameraToModelNode = async (revisionId: number, nodeId: number): Promise => { @@ -83,7 +83,7 @@ export const useCameraNavigation = (): CameraNavigationActions => { }; return { - fitCameraToSceneBoundingBox, + fitCameraToVisualSceneBoundingBox, fitCameraToAllModels, fitCameraToInstance, fitCameraToInstances, From ab4cb8b0fd9458fdb3154c9fd69a9a45b0671646 Mon Sep 17 00:00:00 2001 From: Nils Petter Fremming Date: Thu, 29 Aug 2024 15:39:11 +0200 Subject: [PATCH 3/5] Update ToggleAllModelsVisibleCommand.ts --- .../base/concreteCommands/ToggleAllModelsVisibleCommand.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/react-components/src/architecture/base/concreteCommands/ToggleAllModelsVisibleCommand.ts b/react-components/src/architecture/base/concreteCommands/ToggleAllModelsVisibleCommand.ts index a42eaeccdfb..3e9abdccd0f 100644 --- a/react-components/src/architecture/base/concreteCommands/ToggleAllModelsVisibleCommand.ts +++ b/react-components/src/architecture/base/concreteCommands/ToggleAllModelsVisibleCommand.ts @@ -6,6 +6,10 @@ import { RenderTargetCommand } from '../commands/RenderTargetCommand'; import { type TranslateKey } from '../utilities/TranslateKey'; export class ToggleAllModelsVisibleCommand extends RenderTargetCommand { + // ================================================== + // OVERRIDES + // ================================================== + public override get tooltip(): TranslateKey { return { fallback: 'Show or hide all models' }; } From ca965dd20ac8f98bba167551455e0b6224a5f136 Mon Sep 17 00:00:00 2001 From: Nils Petter Fremming Date: Thu, 29 Aug 2024 16:21:09 +0200 Subject: [PATCH 4/5] Upgrade --- react-components/package.json | 4 ++-- react-components/yarn.lock | 23 +++++++++++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/react-components/package.json b/react-components/package.json index f0e57c6740e..850ef608549 100644 --- a/react-components/package.json +++ b/react-components/package.json @@ -30,7 +30,7 @@ }, "peerDependencies": { "@cognite/cogs.js": ">=9.84.3", - "@cognite/reveal": "4.16.1", + "@cognite/reveal": "4.17.0", "react": ">=18", "react-dom": ">=18", "styled-components": ">=5" @@ -44,7 +44,7 @@ "@cognite/cdf-i18n-utils": "^0.7.5", "@cognite/cdf-utilities": "^3.6.0", "@cognite/cogs.js": "^9.84.3", - "@cognite/reveal": "^4.16.1", + "@cognite/reveal": "^4.17.0", "@cognite/sdk": "^9.13.0", "@playwright/test": "^1.43.1", "@storybook/addon-essentials": "^8.0.9", diff --git a/react-components/yarn.lock b/react-components/yarn.lock index cd566f7d14c..5867a9e81fa 100644 --- a/react-components/yarn.lock +++ b/react-components/yarn.lock @@ -1747,7 +1747,7 @@ __metadata: "@cognite/cdf-i18n-utils": "npm:^0.7.5" "@cognite/cdf-utilities": "npm:^3.6.0" "@cognite/cogs.js": "npm:^9.84.3" - "@cognite/reveal": "npm:^4.16.1" + "@cognite/reveal": "npm:^4.17.0" "@cognite/sdk": "npm:^9.13.0" "@playwright/test": "npm:^1.43.1" "@storybook/addon-essentials": "npm:^8.0.9" @@ -1802,19 +1802,19 @@ __metadata: vitest: "npm:^1.5.3" peerDependencies: "@cognite/cogs.js": ">=9.84.3" - "@cognite/reveal": 4.16.1 + "@cognite/reveal": 4.17.0 react: ">=18" react-dom: ">=18" styled-components: ">=5" languageName: unknown linkType: soft -"@cognite/reveal@npm:^4.16.1": - version: 4.16.1 - resolution: "@cognite/reveal@npm:4.16.1" +"@cognite/reveal@npm:^4.17.0": + version: 4.17.0 + resolution: "@cognite/reveal@npm:4.17.0" dependencies: "@rajesh896/broprint.js": "npm:^2.1.1" - "@tweenjs/tween.js": "npm:^23.1.1" + "@tweenjs/tween.js": "npm:^25.0.0" assert: "npm:^2.1.0" async-mutex: "npm:^0.5.0" glslify: "npm:^7.1.1" @@ -1831,7 +1831,7 @@ __metadata: peerDependencies: "@cognite/sdk": ^7.16.0 || ^8.0.0 three: 0.166.1 - checksum: 10/9e695c51f4737a3cc84aceeac63e42c5dd9a436e8f4111611ae95a5a9789dc68f84e195ffcbbea6a30012c18186663f4ebb6dc198f2dda15c13d8ea1ef78efb3 + checksum: 10/10340201cd744cc64aca3b1d70f44b482d18967fe8d127b22346495e3913b8ba02f281d6e9418d54dbae6fdc0aecd63c7f5b2f2c80475d9d56f7ea27a5926859 languageName: node linkType: hard @@ -4897,7 +4897,14 @@ __metadata: languageName: node linkType: hard -"@tweenjs/tween.js@npm:^23.1.1, @tweenjs/tween.js@npm:~23.1.1": +"@tweenjs/tween.js@npm:^25.0.0": + version: 25.0.0 + resolution: "@tweenjs/tween.js@npm:25.0.0" + checksum: 10/0df3d2668a115dbfffde2f18f7b58fecc2d1a97a69f5f522a2437dea2e7a3fbbb08763dd5dfd8e718a6e9f24153f6c80cb0a5c4ab943dc5fd1802cda9b527c04 + languageName: node + linkType: hard + +"@tweenjs/tween.js@npm:~23.1.1": version: 23.1.2 resolution: "@tweenjs/tween.js@npm:23.1.2" checksum: 10/ca7f62b1059917ebddf1e7e9d7361b87e945bfc21b3c840dd34b1ebfe7d90d87d0dd10ebfa88e2233fe4887cf260b9e1a45134573b599c905af45853b39ae0b8 From 4f43dcbd27461efa40de8b2072f7af8c1c43ac8e Mon Sep 17 00:00:00 2001 From: Nils Petter Fremming Date: Thu, 29 Aug 2024 16:32:36 +0200 Subject: [PATCH 5/5] Bump version to 0.55.10 --- react-components/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react-components/package.json b/react-components/package.json index 850ef608549..7645de163a6 100644 --- a/react-components/package.json +++ b/react-components/package.json @@ -1,6 +1,6 @@ { "name": "@cognite/reveal-react-components", - "version": "0.55.9", + "version": "0.55.10", "exports": { ".": { "import": "./dist/index.js",