From 5d7effe72e50066e81fbef8d9c3abf5d321401ce Mon Sep 17 00:00:00 2001 From: Savelii Novikov Date: Mon, 28 Aug 2023 17:40:14 +0200 Subject: [PATCH 1/9] Added view fetching for useMappedEdgesForRevisions hook --- .../NodeCacheProvider/FdmNodeCache.ts | 46 +++++++++++++------ .../NodeCacheProvider/NodeCacheProvider.tsx | 26 +++++------ .../NodeCacheProvider/RevisionFdmNodeCache.ts | 28 +++++------ .../components/NodeCacheProvider/requests.ts | 27 +++++++---- .../src/components/NodeCacheProvider/types.ts | 2 +- .../src/hooks/useCameraNavigation.tsx | 24 ++++------ 6 files changed, 88 insertions(+), 65 deletions(-) diff --git a/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts b/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts index ccc1aaa84fe..200e93bc98e 100644 --- a/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts @@ -3,7 +3,7 @@ */ import { type Node3D, type CogniteClient, type CogniteExternalId } from '@cognite/sdk'; -import { type DmsUniqueIdentifier, type EdgeItem, type FdmSDK } from '../../utilities/FdmSDK'; +import { Source, type DmsUniqueIdentifier, type EdgeItem, type FdmSDK } from '../../utilities/FdmSDK'; import { RevisionFdmNodeCache } from './RevisionFdmNodeCache'; import { type FdmEdgeWithNode, @@ -32,7 +32,7 @@ import { import { partition } from 'lodash'; import assert from 'assert'; -import { fetchNodesForNodeIds } from './requests'; +import { fetchNodesForNodeIds, inspectNodes } from './requests'; import { type ThreeDModelMappings } from '../../hooks/types'; export class FdmNodeCache { @@ -203,8 +203,9 @@ export class FdmNodeCache { ): Promise> { const revisionIds = modelRevisionIds.map((modelRevisionId) => modelRevisionId.revisionId); const edges = await this.getEdgesForRevisions(revisionIds, this._fdmClient); + const edgesWithViews = await this.getViewsForEdges(edges, this._fdmClient); const revisionToEdgesMap = await createRevisionToEdgesMap( - edges, + edgesWithViews, modelRevisionIds, this._cdfClient ); @@ -224,6 +225,20 @@ export class FdmNodeCache { return await revisionCache.getClosestParentFdmData(treeIndex); } + private async getViewsForEdges(edges: EdgeItem[], fdmClient: FdmSDK) { + const nodeInspectionResults = await inspectNodes( + this._fdmClient, + edges.map((edge) => edge.startNode) + ); + + const dataWithViews = edges.map((edge, ind) => ({ + edge, + view: nodeInspectionResults.items[ind].inspectionResults.involvedViewsAndContainers.views[0] + })); + + return dataWithViews; + } + private async getEdgesForRevisions( revisionIds: number[], fdmClient: FdmSDK @@ -266,24 +281,24 @@ export class FdmNodeCache { } async function createRevisionToEdgesMap( - edges: FdmCadEdge[], + edgesWithViews: { edge: FdmCadEdge, view: Source}[], modelRevisionIds: ModelRevisionId[], cdfClient: CogniteClient ): Promise> { - const revisionToNodeIdsMap = createRevisionToNodeIdMap(edges); + const revisionToNodeIdsMap = createRevisionToNodeIdMap(edgesWithViews); const modelNodeIdToNodeMap = await createModelNodeIdToNodeMap( revisionToNodeIdsMap, modelRevisionIds, cdfClient ); - return edges.reduce((map, edge) => { - const edgeRevisionId = edge.properties.revisionId; + return edgesWithViews.reduce((map, edgeWithView) => { + const edgeRevisionId = edgeWithView.edge.properties.revisionId; const modelRevisionId = modelRevisionIds.find((p) => p.revisionId === edgeRevisionId); if (modelRevisionId === undefined) return map; - const value = createFdmEdgeWithNode(modelRevisionId, edge, modelNodeIdToNodeMap); + const value = createFdmEdgeWithNode(modelRevisionId, edgeWithView.edge, edgeWithView.view, modelNodeIdToNodeMap); insertEdgeIntoMapList(value, map, modelRevisionId); @@ -294,6 +309,7 @@ async function createRevisionToEdgesMap( function createFdmEdgeWithNode( modelRevisionId: ModelRevisionId, edge: FdmCadEdge, + view: Source, modelNodeIdToNodeMap: Map ): FdmEdgeWithNode { const revisionNodeIdKey = createModelNodeIdKey( @@ -305,7 +321,7 @@ function createFdmEdgeWithNode( const node = modelNodeIdToNodeMap.get(revisionNodeIdKey); assert(node !== undefined); - return { edge, node }; + return { edge, node, view}; } function insertEdgeIntoMapList( @@ -350,14 +366,16 @@ async function createModelNodeIdToNodeMap( return revisionNodeIdToNode; } -function createRevisionToNodeIdMap(edges: FdmCadEdge[]): Map { - return edges.reduce((revisionNodeIdMap, edge) => { - const nodeIdsInRevision = revisionNodeIdMap.get(edge.properties.revisionId); +function createRevisionToNodeIdMap(edgesWithViews: { edge: FdmCadEdge, view: Source}[]): Map { + return edgesWithViews.reduce((revisionNodeIdMap, edgeWithView) => { + const { revisionNodeId, revisionId} = edgeWithView.edge.properties; + + const nodeIdsInRevision = revisionNodeIdMap.get(revisionId); if (nodeIdsInRevision !== undefined) { - nodeIdsInRevision.push(edge.properties.revisionNodeId); + nodeIdsInRevision.push(revisionNodeId); } else { - revisionNodeIdMap.set(edge.properties.revisionId, [edge.properties.revisionNodeId]); + revisionNodeIdMap.set(revisionId, [revisionNodeId]); } return revisionNodeIdMap; diff --git a/react-components/src/components/NodeCacheProvider/NodeCacheProvider.tsx b/react-components/src/components/NodeCacheProvider/NodeCacheProvider.tsx index 3fe04dbd0b9..56a9eda9459 100644 --- a/react-components/src/components/NodeCacheProvider/NodeCacheProvider.tsx +++ b/react-components/src/components/NodeCacheProvider/NodeCacheProvider.tsx @@ -20,16 +20,22 @@ export type FdmNodeCacheContent = { export const FdmNodeCacheContext = createContext(undefined); -export const useMappedEdgesForRevisions = ( - modelRevisionIds: Array<{ modelId: number; revisionId: number }>, - enabled = true -): UseQueryResult => { +export const useFdmNodeCache = (): FdmNodeCacheContent => { const content = useContext(FdmNodeCacheContext); if (content === undefined) { throw Error('Must use useNodeCache inside a NodeCacheContext'); } + return content; +} + +export const useMappedEdgesForRevisions = ( + modelRevisionIds: Array<{ modelId: number; revisionId: number }>, + enabled = true +): UseQueryResult => { + const content = useFdmNodeCache(); + return useQuery( [ 'reveal', @@ -46,7 +52,7 @@ export const useFdm3dNodeData = ( revisionId: number | undefined, treeIndex: number | undefined ): UseQueryResult => { - const content = useContext(FdmNodeCacheContext); + const content = useFdmNodeCache(); const enableQuery = content !== undefined && @@ -65,10 +71,6 @@ export const useFdm3dNodeData = ( } ); - if (content === undefined) { - throw Error('Must use useNodeCache inside a NodeCacheContext'); - } - return result; }; @@ -76,14 +78,12 @@ export const useFdmAssetMappings = ( fdmAssetExternalIds: DmsUniqueIdentifier[], models: TypedReveal3DModel[] ): UseQueryResult => { - const nodeCacheContent = useContext(FdmNodeCacheContext); + const nodeCacheContent = useFdmNodeCache(); return useQuery( ['reveal', 'react-components', 'fdm-asset-mappings', fdmAssetExternalIds], async () => { - return ( - (await nodeCacheContent?.cache.getMappingsForFdmIds(fdmAssetExternalIds, models)) ?? [] - ); + return await nodeCacheContent.cache.getMappingsForFdmIds(fdmAssetExternalIds, models); }, { enabled: fdmAssetExternalIds.length > 0 && models.length > 0, diff --git a/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts b/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts index 195eba1a132..5faf4061b17 100644 --- a/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts +++ b/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts @@ -37,7 +37,6 @@ export class RevisionFdmNodeCache { private readonly _revisionId: number; private readonly _treeIndexToFdmEdges = new Map(); - private readonly _treeIndexToFdmData = new Map(); constructor( cogniteClient: CogniteClient, @@ -78,10 +77,10 @@ export class RevisionFdmNodeCache { } public async getClosestParentFdmData(searchTreeIndex: number): Promise { - const cachedFdmData = this._treeIndexToFdmData.get(searchTreeIndex); + const cachedFdmData = this._treeIndexToFdmEdges.get(searchTreeIndex); if (cachedFdmData !== undefined) { - return cachedFdmData; + return fdmEdgeWithNodeToFdm3dNodeData(cachedFdmData); } const cachedFdmEdges = this._treeIndexToFdmEdges.get(searchTreeIndex); @@ -101,12 +100,12 @@ export class RevisionFdmNodeCache { return []; } - const cachedFdmData = this._treeIndexToFdmData.get(firstMappedAncestorTreeIndex); + const cachedFdmData = this._treeIndexToFdmEdges.get(firstMappedAncestorTreeIndex); if (cachedFdmData !== undefined) { this.setCacheForNodes(ancestorsWithSameMapping, cachedFdmData); - return cachedFdmData; + return fdmEdgeWithNodeToFdm3dNodeData(cachedFdmData); } const firstMappedAncestor = ancestorsWithSameMapping.find( @@ -120,14 +119,14 @@ export class RevisionFdmNodeCache { return await this.getDataWithViewsForFdmEdges(nodeEdges, ancestorsWithSameMapping); } - private setCacheForNodes(nodes: Node3D[], nodeData: Fdm3dNodeData[]): void { + private setCacheForNodes(nodes: Node3D[], nodeData: FdmEdgeWithNode[]): void { nodes.forEach((node) => { - this._treeIndexToFdmData.set(node.treeIndex, nodeData); + this._treeIndexToFdmEdges.set(node.treeIndex, nodeData); }); } private async getDataWithViewsForFdmEdges( - nodeEdges: FdmEdgeWithNode[], + nodeEdges: Omit[], ancestorsWithSameMapping: Node3D[] ): Promise { const nodeInspectionResults = await inspectNodes( @@ -136,16 +135,15 @@ export class RevisionFdmNodeCache { ); const dataWithViews = nodeEdges.map((fdmEdgeWithNode, ind) => ({ - fdmId: fdmEdgeWithNode.edge.startNode, - view: nodeInspectionResults.items[ind].inspectionResults.involvedViewsAndContainers.views[0], - cadNode: fdmEdgeWithNode.node + ...fdmEdgeWithNode, + view: nodeInspectionResults.items[ind].inspectionResults.involvedViewsAndContainers.views[0] })); ancestorsWithSameMapping.forEach((ancestor) => - this._treeIndexToFdmData.set(ancestor.treeIndex, dataWithViews) + this._treeIndexToFdmEdges.set(ancestor.treeIndex, dataWithViews) ); - return dataWithViews; + return fdmEdgeWithNodeToFdm3dNodeData(dataWithViews); } private async getClosestParentMapping(treeIndex: number): Promise<{ @@ -241,6 +239,10 @@ export class RevisionFdmNodeCache { } } +function fdmEdgeWithNodeToFdm3dNodeData(fdmEdgeWithNode: FdmEdgeWithNode[]): Fdm3dNodeData[] { + return fdmEdgeWithNode.map((edgeData) => ({ view: edgeData.view, fdmId: edgeData.edge.startNode, cadNode: edgeData.node })); +} + function findLargestTreeIndex( edgesWithTreeIndex: Array<{ edge: FdmCadEdge; treeIndex: TreeIndex }> ): TreeIndex { diff --git a/react-components/src/components/NodeCacheProvider/requests.ts b/react-components/src/components/NodeCacheProvider/requests.ts index 42829f77a3a..162de3a0028 100644 --- a/react-components/src/components/NodeCacheProvider/requests.ts +++ b/react-components/src/components/NodeCacheProvider/requests.ts @@ -14,6 +14,7 @@ import { type InModel3dEdgeProperties, SYSTEM_3D_EDGE_SOURCE } from '../../utilities/globalDataModels'; +import { chunk } from 'lodash'; export async function fetchAncestorNodesForTreeIndex( modelId: number, @@ -83,15 +84,25 @@ export async function inspectNodes( fdmClient: FdmSDK, dataNodes: DmsUniqueIdentifier[] ): Promise { - const inspectionResult = await fdmClient.inspectInstances({ - inspectionOperations: { involvedViewsAndContainers: {} }, - items: dataNodes.map((node) => ({ - instanceType: 'node', - externalId: node.externalId, - space: node.space - })) - }); + const chunkedNodes = chunk(dataNodes, 100); + + const inspectionResult: InspectResultList = { + items: [] + }; + for (const nodesChunk of chunkedNodes) { + const chunkInspectionResults = await fdmClient.inspectInstances({ + inspectionOperations: { involvedViewsAndContainers: {} }, + items: nodesChunk.map((node) => ({ + instanceType: 'node', + externalId: node.externalId, + space: node.space + })) + }); + + inspectionResult.items.push(...chunkInspectionResults.items); + } + return inspectionResult; } diff --git a/react-components/src/components/NodeCacheProvider/types.ts b/react-components/src/components/NodeCacheProvider/types.ts index 73b8be1c8f5..434c8bbc3ce 100644 --- a/react-components/src/components/NodeCacheProvider/types.ts +++ b/react-components/src/components/NodeCacheProvider/types.ts @@ -7,7 +7,7 @@ import { type InModel3dEdgeProperties } from '../../utilities/globalDataModels'; export type Fdm3dNodeData = { fdmId: DmsUniqueIdentifier; view: Source; cadNode: Node3D }; export type FdmCadEdge = EdgeItem; -export type FdmEdgeWithNode = { edge: FdmCadEdge; node: Node3D }; +export type FdmEdgeWithNode = { edge: FdmCadEdge; node: Node3D; view: Source}; export type ModelId = number; export type RevisionId = number; diff --git a/react-components/src/hooks/useCameraNavigation.tsx b/react-components/src/hooks/useCameraNavigation.tsx index a530e9c00e8..8b8b7885851 100644 --- a/react-components/src/hooks/useCameraNavigation.tsx +++ b/react-components/src/hooks/useCameraNavigation.tsx @@ -5,7 +5,7 @@ import { type CogniteCadModel } from '@cognite/reveal'; import { useReveal } from '../components/RevealContainer/RevealContext'; import { useFdmSdk } from '../components/RevealContainer/SDKProvider'; -import { SYSTEM_3D_EDGE_SOURCE, type InModel3dEdgeProperties } from '../utilities/globalDataModels'; +import { useFdmNodeCache } from '../components/NodeCacheProvider/NodeCacheProvider'; export type CameraNavigationActions = { fitCameraToAllModels: () => void; @@ -14,8 +14,8 @@ export type CameraNavigationActions = { }; export const useCameraNavigation = (): CameraNavigationActions => { + const fdmNodeCache = useFdmNodeCache(); const viewer = useReveal(); - const fdmSDK = useFdmSdk(); const fitCameraToAllModels = (): void => { const models = viewer.models; @@ -36,28 +36,20 @@ export const useCameraNavigation = (): CameraNavigationActions => { }; const fitCameraToInstance = async (externalId: string, space: string): Promise => { - const fdmAssetMappingFilter = { - equals: { - property: ['edge', 'startNode'], - value: { externalId, space } - } - }; + const modelsRevisionIds = viewer.models.map(model => ({ modelId: model.modelId, revisionId: model.revisionId })); - const assetEdges = await fdmSDK.filterInstances( - fdmAssetMappingFilter, - 'edge', - SYSTEM_3D_EDGE_SOURCE - ); + const modelMappings = (await fdmNodeCache.cache.getMappingsForFdmIds([{ externalId, space }], modelsRevisionIds))?.[0]; - if (assetEdges.edges.length === 0) { + const nodeId = modelMappings?.mappings.get(externalId); + + if (modelMappings === undefined || nodeId === undefined) { await Promise.reject( new Error(`Could not find a connected model to instance ${externalId} in space ${space}`) ); return; } - const { revisionId, revisionNodeId } = assetEdges.edges[0].properties; - await fitCameraToModelNode(revisionId, revisionNodeId); + await fitCameraToModelNode(modelMappings.revisionId, nodeId.id); }; return { From 81fbea8cd84b58fe3db5204ac90172c78c1d7a61 Mon Sep 17 00:00:00 2001 From: Savelii Novikov Date: Wed, 30 Aug 2023 19:32:37 +0300 Subject: [PATCH 2/9] removed comment --- react-components/src/hooks/useCalculateModelsStyling.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react-components/src/hooks/useCalculateModelsStyling.tsx b/react-components/src/hooks/useCalculateModelsStyling.tsx index 902e04c88bb..6d9b747b190 100644 --- a/react-components/src/hooks/useCalculateModelsStyling.tsx +++ b/react-components/src/hooks/useCalculateModelsStyling.tsx @@ -42,7 +42,7 @@ export const useCalculateCadStyling = ( defaultResourceStyling?.cad?.mapped ); const modelInstanceStyleGroups = useCalculateInstanceStyling(models, instanceGroups); - console.log('Model instance style groups = ', modelInstanceStyleGroups); + const joinedStyleGroups = useJoinStylingGroups( models, modelsMappedStyleGroups, From 4a0d9ddffd19494cc9fd80f3e4803914262454cb Mon Sep 17 00:00:00 2001 From: Savelii Novikov Date: Wed, 30 Aug 2023 19:41:25 +0300 Subject: [PATCH 3/9] Lint fixes --- .../NodeCacheProvider/FdmNodeCache.ts | 30 ++++++++++++++----- .../NodeCacheProvider/NodeCacheProvider.tsx | 2 +- .../NodeCacheProvider/RevisionFdmNodeCache.ts | 8 +++-- .../components/NodeCacheProvider/requests.ts | 2 +- .../src/components/NodeCacheProvider/types.ts | 2 +- .../src/hooks/useCameraNavigation.tsx | 12 +++++--- 6 files changed, 39 insertions(+), 17 deletions(-) diff --git a/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts b/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts index 200e93bc98e..7faf47d4210 100644 --- a/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts @@ -3,7 +3,12 @@ */ import { type Node3D, type CogniteClient, type CogniteExternalId } from '@cognite/sdk'; -import { Source, type DmsUniqueIdentifier, type EdgeItem, type FdmSDK } from '../../utilities/FdmSDK'; +import { + type Source, + type DmsUniqueIdentifier, + type EdgeItem, + type FdmSDK +} from '../../utilities/FdmSDK'; import { RevisionFdmNodeCache } from './RevisionFdmNodeCache'; import { type FdmEdgeWithNode, @@ -203,7 +208,7 @@ export class FdmNodeCache { ): Promise> { const revisionIds = modelRevisionIds.map((modelRevisionId) => modelRevisionId.revisionId); const edges = await this.getEdgesForRevisions(revisionIds, this._fdmClient); - const edgesWithViews = await this.getViewsForEdges(edges, this._fdmClient); + const edgesWithViews = await this.getViewsForEdges(edges); const revisionToEdgesMap = await createRevisionToEdgesMap( edgesWithViews, modelRevisionIds, @@ -225,7 +230,9 @@ export class FdmNodeCache { return await revisionCache.getClosestParentFdmData(treeIndex); } - private async getViewsForEdges(edges: EdgeItem[], fdmClient: FdmSDK) { + private async getViewsForEdges( + edges: Array> + ): Promise> { const nodeInspectionResults = await inspectNodes( this._fdmClient, edges.map((edge) => edge.startNode) @@ -281,7 +288,7 @@ export class FdmNodeCache { } async function createRevisionToEdgesMap( - edgesWithViews: { edge: FdmCadEdge, view: Source}[], + edgesWithViews: Array<{ edge: FdmCadEdge; view: Source }>, modelRevisionIds: ModelRevisionId[], cdfClient: CogniteClient ): Promise> { @@ -298,7 +305,12 @@ async function createRevisionToEdgesMap( if (modelRevisionId === undefined) return map; - const value = createFdmEdgeWithNode(modelRevisionId, edgeWithView.edge, edgeWithView.view, modelNodeIdToNodeMap); + const value = createFdmEdgeWithNode( + modelRevisionId, + edgeWithView.edge, + edgeWithView.view, + modelNodeIdToNodeMap + ); insertEdgeIntoMapList(value, map, modelRevisionId); @@ -321,7 +333,7 @@ function createFdmEdgeWithNode( const node = modelNodeIdToNodeMap.get(revisionNodeIdKey); assert(node !== undefined); - return { edge, node, view}; + return { edge, node, view }; } function insertEdgeIntoMapList( @@ -366,9 +378,11 @@ async function createModelNodeIdToNodeMap( return revisionNodeIdToNode; } -function createRevisionToNodeIdMap(edgesWithViews: { edge: FdmCadEdge, view: Source}[]): Map { +function createRevisionToNodeIdMap( + edgesWithViews: Array<{ edge: FdmCadEdge; view: Source }> +): Map { return edgesWithViews.reduce((revisionNodeIdMap, edgeWithView) => { - const { revisionNodeId, revisionId} = edgeWithView.edge.properties; + const { revisionNodeId, revisionId } = edgeWithView.edge.properties; const nodeIdsInRevision = revisionNodeIdMap.get(revisionId); diff --git a/react-components/src/components/NodeCacheProvider/NodeCacheProvider.tsx b/react-components/src/components/NodeCacheProvider/NodeCacheProvider.tsx index 56a9eda9459..1db40c52933 100644 --- a/react-components/src/components/NodeCacheProvider/NodeCacheProvider.tsx +++ b/react-components/src/components/NodeCacheProvider/NodeCacheProvider.tsx @@ -28,7 +28,7 @@ export const useFdmNodeCache = (): FdmNodeCacheContent => { } return content; -} +}; export const useMappedEdgesForRevisions = ( modelRevisionIds: Array<{ modelId: number; revisionId: number }>, diff --git a/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts b/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts index 5faf4061b17..5a52f044390 100644 --- a/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts +++ b/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts @@ -126,7 +126,7 @@ export class RevisionFdmNodeCache { } private async getDataWithViewsForFdmEdges( - nodeEdges: Omit[], + nodeEdges: Array>, ancestorsWithSameMapping: Node3D[] ): Promise { const nodeInspectionResults = await inspectNodes( @@ -240,7 +240,11 @@ export class RevisionFdmNodeCache { } function fdmEdgeWithNodeToFdm3dNodeData(fdmEdgeWithNode: FdmEdgeWithNode[]): Fdm3dNodeData[] { - return fdmEdgeWithNode.map((edgeData) => ({ view: edgeData.view, fdmId: edgeData.edge.startNode, cadNode: edgeData.node })); + return fdmEdgeWithNode.map((edgeData) => ({ + view: edgeData.view, + fdmId: edgeData.edge.startNode, + cadNode: edgeData.node + })); } function findLargestTreeIndex( diff --git a/react-components/src/components/NodeCacheProvider/requests.ts b/react-components/src/components/NodeCacheProvider/requests.ts index 162de3a0028..c42775e009f 100644 --- a/react-components/src/components/NodeCacheProvider/requests.ts +++ b/react-components/src/components/NodeCacheProvider/requests.ts @@ -102,7 +102,7 @@ export async function inspectNodes( inspectionResult.items.push(...chunkInspectionResults.items); } - + return inspectionResult; } diff --git a/react-components/src/components/NodeCacheProvider/types.ts b/react-components/src/components/NodeCacheProvider/types.ts index 434c8bbc3ce..d59808b118e 100644 --- a/react-components/src/components/NodeCacheProvider/types.ts +++ b/react-components/src/components/NodeCacheProvider/types.ts @@ -7,7 +7,7 @@ import { type InModel3dEdgeProperties } from '../../utilities/globalDataModels'; export type Fdm3dNodeData = { fdmId: DmsUniqueIdentifier; view: Source; cadNode: Node3D }; export type FdmCadEdge = EdgeItem; -export type FdmEdgeWithNode = { edge: FdmCadEdge; node: Node3D; view: Source}; +export type FdmEdgeWithNode = { edge: FdmCadEdge; node: Node3D; view: Source }; export type ModelId = number; export type RevisionId = number; diff --git a/react-components/src/hooks/useCameraNavigation.tsx b/react-components/src/hooks/useCameraNavigation.tsx index 8b8b7885851..50f32ab29a5 100644 --- a/react-components/src/hooks/useCameraNavigation.tsx +++ b/react-components/src/hooks/useCameraNavigation.tsx @@ -4,8 +4,7 @@ import { type CogniteCadModel } from '@cognite/reveal'; import { useReveal } from '../components/RevealContainer/RevealContext'; -import { useFdmSdk } from '../components/RevealContainer/SDKProvider'; -import { useFdmNodeCache } from '../components/NodeCacheProvider/NodeCacheProvider'; +import { useFdmNodeCache } from '../components/NodeCacheProvider/NodeCacheProvider'; export type CameraNavigationActions = { fitCameraToAllModels: () => void; @@ -36,9 +35,14 @@ export const useCameraNavigation = (): CameraNavigationActions => { }; const fitCameraToInstance = async (externalId: string, space: string): Promise => { - const modelsRevisionIds = viewer.models.map(model => ({ modelId: model.modelId, revisionId: model.revisionId })); + const modelsRevisionIds = viewer.models.map((model) => ({ + modelId: model.modelId, + revisionId: model.revisionId + })); - const modelMappings = (await fdmNodeCache.cache.getMappingsForFdmIds([{ externalId, space }], modelsRevisionIds))?.[0]; + const modelMappings = ( + await fdmNodeCache.cache.getMappingsForFdmIds([{ externalId, space }], modelsRevisionIds) + )?.[0]; const nodeId = modelMappings?.mappings.get(externalId); From 8c687b068a1cd59170f8b0ea8df4706154fa5e03 Mon Sep 17 00:00:00 2001 From: Savelii Novikov Date: Mon, 4 Sep 2023 11:22:27 +0200 Subject: [PATCH 4/9] Minor PR fixes --- .../src/components/NodeCacheProvider/FdmNodeCache.ts | 2 +- .../src/components/NodeCacheProvider/RevisionFdmNodeCache.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts b/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts index 7faf47d4210..7688319c0b4 100644 --- a/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts @@ -231,7 +231,7 @@ export class FdmNodeCache { } private async getViewsForEdges( - edges: Array> + edges: Array ): Promise> { const nodeInspectionResults = await inspectNodes( this._fdmClient, diff --git a/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts b/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts index 5a52f044390..f282ec3cad5 100644 --- a/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts +++ b/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts @@ -126,7 +126,7 @@ export class RevisionFdmNodeCache { } private async getDataWithViewsForFdmEdges( - nodeEdges: Array>, + nodeEdges: Array<{ edge: FdmCadEdge, node: Node3D}>, ancestorsWithSameMapping: Node3D[] ): Promise { const nodeInspectionResults = await inspectNodes( From 8d0a905876b44ff0a1ee0f94e0934ddfc0f744d6 Mon Sep 17 00:00:00 2001 From: Savelii Novikov Date: Mon, 4 Sep 2023 11:24:35 +0200 Subject: [PATCH 5/9] Fixed nodeId type issue --- react-components/src/hooks/useCameraNavigation.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react-components/src/hooks/useCameraNavigation.tsx b/react-components/src/hooks/useCameraNavigation.tsx index 50f32ab29a5..0df6cd901d4 100644 --- a/react-components/src/hooks/useCameraNavigation.tsx +++ b/react-components/src/hooks/useCameraNavigation.tsx @@ -44,7 +44,7 @@ export const useCameraNavigation = (): CameraNavigationActions => { await fdmNodeCache.cache.getMappingsForFdmIds([{ externalId, space }], modelsRevisionIds) )?.[0]; - const nodeId = modelMappings?.mappings.get(externalId); + const nodeId = modelMappings?.mappings.get(externalId)?.[0]; if (modelMappings === undefined || nodeId === undefined) { await Promise.reject( From ab2d1dc630f646bf1c9f6e7715d09111322da28e Mon Sep 17 00:00:00 2001 From: Savelii Novikov Date: Mon, 4 Sep 2023 17:31:01 +0200 Subject: [PATCH 6/9] New hook added --- .../src/components/NodeCacheProvider/FdmNodeCache.ts | 2 +- .../components/NodeCacheProvider/RevisionFdmNodeCache.ts | 2 +- react-components/src/hooks/useCameraNavigation.tsx | 2 +- react-components/src/index.ts | 1 + react-components/stories/HighlightNode.stories.tsx | 6 +++--- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts b/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts index 752d42fe225..0c06b10169a 100644 --- a/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts @@ -231,7 +231,7 @@ export class FdmNodeCache { } private async getViewsForEdges( - edges: Array + edges: FdmCadEdge[] ): Promise> { const nodeInspectionResults = await inspectNodes( this._fdmClient, diff --git a/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts b/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts index 9837eb438ea..625d3ec1596 100644 --- a/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts +++ b/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts @@ -88,7 +88,7 @@ export class RevisionFdmNodeCache { } private async getDataWithViewsForFdmEdges( - nodeEdges: Array<{ edge: FdmCadEdge, node: Node3D}>, + nodeEdges: Array<{ edge: FdmCadEdge; node: Node3D }>, ancestorsWithSameMapping: Node3D[] ): Promise { const nodeInspectionResults = await inspectNodes( diff --git a/react-components/src/hooks/useCameraNavigation.tsx b/react-components/src/hooks/useCameraNavigation.tsx index 0df6cd901d4..7af9b336306 100644 --- a/react-components/src/hooks/useCameraNavigation.tsx +++ b/react-components/src/hooks/useCameraNavigation.tsx @@ -42,7 +42,7 @@ export const useCameraNavigation = (): CameraNavigationActions => { const modelMappings = ( await fdmNodeCache.cache.getMappingsForFdmIds([{ externalId, space }], modelsRevisionIds) - )?.[0]; + ).find((model) => model.mappings.size > 0); const nodeId = modelMappings?.mappings.get(externalId)?.[0]; diff --git a/react-components/src/index.ts b/react-components/src/index.ts index 810258ba771..9f757e1cb66 100644 --- a/react-components/src/index.ts +++ b/react-components/src/index.ts @@ -22,6 +22,7 @@ export { useFdmAssetMappings } from './components/NodeCacheProvider/NodeCachePro export { useClickedNodeData, type ClickedNodeData } from './hooks/useClickedNode'; export { useCameraNavigation } from './hooks/useCameraNavigation'; export { useMappedEdgesForRevisions } from './components/NodeCacheProvider/NodeCacheProvider'; +export { use3dNodeByExternalId } from './hooks/use3dNodeByExternalId'; // Higher order components export { withSuppressRevealEvents } from './higher-order-components/withSuppressRevealEvents'; diff --git a/react-components/stories/HighlightNode.stories.tsx b/react-components/stories/HighlightNode.stories.tsx index 653be9ed936..0d8e9c8aa91 100644 --- a/react-components/stories/HighlightNode.stories.tsx +++ b/react-components/stories/HighlightNode.stories.tsx @@ -7,10 +7,10 @@ import { RevealContainer, RevealToolbar, Reveal3DResources, - type AddResourceOptions, useClickedNodeData, - type FdmAssetStylingGroup, - useCameraNavigation + useCameraNavigation, + type AddResourceOptions, + type FdmAssetStylingGroup } from '../src'; import { Color } from 'three'; import { type ReactElement, useState, useEffect } from 'react'; From 63c996cbec614df5f0581264766d154dbfcbb9c3 Mon Sep 17 00:00:00 2001 From: Savelii Novikov Date: Mon, 4 Sep 2023 17:31:20 +0200 Subject: [PATCH 7/9] Missing hook file --- .../src/hooks/use3dNodeByExternalId.tsx | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 react-components/src/hooks/use3dNodeByExternalId.tsx diff --git a/react-components/src/hooks/use3dNodeByExternalId.tsx b/react-components/src/hooks/use3dNodeByExternalId.tsx new file mode 100644 index 00000000000..cacd6b8a0c0 --- /dev/null +++ b/react-components/src/hooks/use3dNodeByExternalId.tsx @@ -0,0 +1,47 @@ +/*! + * Copyright 2023 Cognite AS + */ +import { type UseQueryResult, useQuery } from '@tanstack/react-query'; +import { useFdmNodeCache } from '../components/NodeCacheProvider/NodeCacheProvider'; +import { type DmsUniqueIdentifier, useReveal } from '../index'; +import { type Node3D } from '@cognite/sdk'; + +export const use3dNodeByExternalId = ({ + externalId, + space +}: Partial): UseQueryResult => { + const viewer = useReveal(); + const fdmNodeCache = useFdmNodeCache(); + + return useQuery( + ['reveal', 'react-components', '3dNodeByExternalId', externalId, space], + async () => { + if (externalId === undefined || space === undefined) { + await Promise.reject( + new Error(`No externalId and space provided to use3dNodeByExternalId hook`) + ); + return; + } + + const modelsRevisionIds = viewer.models.map((model) => ({ + modelId: model.modelId, + revisionId: model.revisionId + })); + + const modelMappings = ( + await fdmNodeCache.cache.getMappingsForFdmIds([{ externalId, space }], modelsRevisionIds) + ).find((model) => model.mappings.size > 0); + + const node3d = modelMappings?.mappings.get(externalId)?.[0]; + + if (modelMappings === undefined || node3d === undefined) { + await Promise.reject( + new Error(`Could not find a connected model to instance ${externalId} in space ${space}`) + ); + return; + } + + return node3d; + } + ); +}; From 5751a6a7324e96b42df95cb328ca4838af9d5576 Mon Sep 17 00:00:00 2001 From: Savelii Novikov Date: Mon, 4 Sep 2023 17:52:48 +0200 Subject: [PATCH 8/9] Fixed types in styling cache --- .../NodeCacheProvider/FdmNodeCache.ts | 3 +-- .../NodeCacheProvider/NodeCacheProvider.tsx | 4 ++-- .../NodeCacheProvider/RevisionFdmNodeCache.ts | 22 ++++++------------- .../src/components/NodeCacheProvider/types.ts | 1 - react-components/src/hooks/useClickedNode.tsx | 4 ++-- 5 files changed, 12 insertions(+), 22 deletions(-) diff --git a/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts b/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts index 0c06b10169a..752820dcfa9 100644 --- a/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/NodeCacheProvider/FdmNodeCache.ts @@ -12,7 +12,6 @@ import { import { RevisionFdmNodeCache } from './RevisionFdmNodeCache'; import { type FdmEdgeWithNode, - type Fdm3dNodeData, type FdmCadEdge, type ModelRevisionKey, type RevisionId, @@ -224,7 +223,7 @@ export class FdmNodeCache { modelId: number, revisionId: number, treeIndex: number - ): Promise { + ): Promise { const revisionCache = this.getOrCreateRevisionCache(modelId, revisionId); return await revisionCache.getClosestParentFdmData(treeIndex); diff --git a/react-components/src/components/NodeCacheProvider/NodeCacheProvider.tsx b/react-components/src/components/NodeCacheProvider/NodeCacheProvider.tsx index 1db40c52933..0ec0e844bcf 100644 --- a/react-components/src/components/NodeCacheProvider/NodeCacheProvider.tsx +++ b/react-components/src/components/NodeCacheProvider/NodeCacheProvider.tsx @@ -6,7 +6,7 @@ import { type ReactElement, type ReactNode, createContext, useContext, useMemo } import { FdmNodeCache } from './FdmNodeCache'; import { type UseQueryResult, useQuery } from '@tanstack/react-query'; import { useFdmSdk, useSDK } from '../RevealContainer/SDKProvider'; -import { type ModelRevisionToEdgeMap, type Fdm3dNodeData } from './types'; +import { type FdmEdgeWithNode, type ModelRevisionToEdgeMap } from './types'; import assert from 'assert'; import { type DmsUniqueIdentifier } from '../../utilities/FdmSDK'; @@ -51,7 +51,7 @@ export const useFdm3dNodeData = ( modelId: number | undefined, revisionId: number | undefined, treeIndex: number | undefined -): UseQueryResult => { +): UseQueryResult => { const content = useFdmNodeCache(); const enableQuery = diff --git a/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts b/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts index 625d3ec1596..d10afa1d7e4 100644 --- a/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts +++ b/react-components/src/components/NodeCacheProvider/RevisionFdmNodeCache.ts @@ -4,7 +4,7 @@ import { type CogniteClient, type Node3D } from '@cognite/sdk'; import { type FdmSDK } from '../../utilities/FdmSDK'; -import { type TreeIndex, type Fdm3dNodeData, type FdmEdgeWithNode, type FdmCadEdge } from './types'; +import { type TreeIndex, type FdmEdgeWithNode, type FdmCadEdge } from './types'; import { fetchAncestorNodesForTreeIndex, @@ -38,11 +38,11 @@ export class RevisionFdmNodeCache { this._revisionId = revisionId; } - public async getClosestParentFdmData(searchTreeIndex: number): Promise { + public async getClosestParentFdmData(searchTreeIndex: number): Promise { const cachedFdmData = this._treeIndexToFdmEdges.get(searchTreeIndex); if (cachedFdmData !== undefined) { - return fdmEdgeWithNodeToFdm3dNodeData(cachedFdmData); + return cachedFdmData; } const cachedFdmEdges = this._treeIndexToFdmEdges.get(searchTreeIndex); @@ -54,7 +54,7 @@ export class RevisionFdmNodeCache { return await this.findNodeDataFromAncestors(searchTreeIndex); } - private async findNodeDataFromAncestors(treeIndex: TreeIndex): Promise { + private async findNodeDataFromAncestors(treeIndex: TreeIndex): Promise { const { edges, ancestorsWithSameMapping, firstMappedAncestorTreeIndex } = await this.getClosestParentMapping(treeIndex); @@ -67,7 +67,7 @@ export class RevisionFdmNodeCache { if (cachedFdmData !== undefined) { this.setCacheForNodes(ancestorsWithSameMapping, cachedFdmData); - return fdmEdgeWithNodeToFdm3dNodeData(cachedFdmData); + return cachedFdmData; } const firstMappedAncestor = ancestorsWithSameMapping.find( @@ -90,7 +90,7 @@ export class RevisionFdmNodeCache { private async getDataWithViewsForFdmEdges( nodeEdges: Array<{ edge: FdmCadEdge; node: Node3D }>, ancestorsWithSameMapping: Node3D[] - ): Promise { + ): Promise { const nodeInspectionResults = await inspectNodes( this._fdmClient, nodeEdges.map((edge) => edge.edge.startNode) @@ -105,7 +105,7 @@ export class RevisionFdmNodeCache { this._treeIndexToFdmEdges.set(ancestor.treeIndex, dataWithViews) ); - return fdmEdgeWithNodeToFdm3dNodeData(dataWithViews); + return dataWithViews; } private async getClosestParentMapping(treeIndex: number): Promise<{ @@ -194,14 +194,6 @@ export class RevisionFdmNodeCache { } } -function fdmEdgeWithNodeToFdm3dNodeData(fdmEdgeWithNode: FdmEdgeWithNode[]): Fdm3dNodeData[] { - return fdmEdgeWithNode.map((edgeData) => ({ - view: edgeData.view, - fdmId: edgeData.edge.startNode, - cadNode: edgeData.node - })); -} - function findLargestTreeIndex( edgesWithTreeIndex: Array<{ edge: FdmCadEdge; treeIndex: TreeIndex }> ): TreeIndex { diff --git a/react-components/src/components/NodeCacheProvider/types.ts b/react-components/src/components/NodeCacheProvider/types.ts index d59808b118e..dedd5be190a 100644 --- a/react-components/src/components/NodeCacheProvider/types.ts +++ b/react-components/src/components/NodeCacheProvider/types.ts @@ -5,7 +5,6 @@ import { type Node3D } from '@cognite/sdk'; import { type EdgeItem, type DmsUniqueIdentifier, type Source } from '../../utilities/FdmSDK'; import { type InModel3dEdgeProperties } from '../../utilities/globalDataModels'; -export type Fdm3dNodeData = { fdmId: DmsUniqueIdentifier; view: Source; cadNode: Node3D }; export type FdmCadEdge = EdgeItem; export type FdmEdgeWithNode = { edge: FdmCadEdge; node: Node3D; view: Source }; diff --git a/react-components/src/hooks/useClickedNode.tsx b/react-components/src/hooks/useClickedNode.tsx index 81591acfeef..ece10b6bd32 100644 --- a/react-components/src/hooks/useClickedNode.tsx +++ b/react-components/src/hooks/useClickedNode.tsx @@ -66,9 +66,9 @@ export const useClickedNodeData = (): ClickedNodeData | undefined => { setClickedNodeData({ intersection: cadIntersection, - fdmNode: chosenNode.fdmId, + fdmNode: chosenNode.edge.startNode, view: chosenNode.view, - cadNode: chosenNode.cadNode + cadNode: chosenNode.node }); function isWaitingForQueryResult(): boolean { From 6f5f56504f063e7686d76a5d3d2282ab85e2ebd2 Mon Sep 17 00:00:00 2001 From: Savelii Novikov Date: Tue, 5 Sep 2023 10:20:34 +0200 Subject: [PATCH 9/9] PR comments fixes --- react-components/src/hooks/use3dNodeByExternalId.tsx | 2 +- react-components/src/hooks/useClickedNode.tsx | 9 ++++++++- react-components/src/index.ts | 9 ++++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/react-components/src/hooks/use3dNodeByExternalId.tsx b/react-components/src/hooks/use3dNodeByExternalId.tsx index cacd6b8a0c0..507cfacd464 100644 --- a/react-components/src/hooks/use3dNodeByExternalId.tsx +++ b/react-components/src/hooks/use3dNodeByExternalId.tsx @@ -34,7 +34,7 @@ export const use3dNodeByExternalId = ({ const node3d = modelMappings?.mappings.get(externalId)?.[0]; - if (modelMappings === undefined || node3d === undefined) { + if (node3d === undefined) { await Promise.reject( new Error(`Could not find a connected model to instance ${externalId} in space ${space}`) ); diff --git a/react-components/src/hooks/useClickedNode.tsx b/react-components/src/hooks/useClickedNode.tsx index ece10b6bd32..50a49e46aa3 100644 --- a/react-components/src/hooks/useClickedNode.tsx +++ b/react-components/src/hooks/useClickedNode.tsx @@ -3,9 +3,16 @@ */ import { type CadIntersection, type PointerEventData } from '@cognite/reveal'; -import { useReveal, type NodeDataResult } from '../'; +import { type DmsUniqueIdentifier, type Source, useReveal } from '../'; import { useEffect, useState } from 'react'; import { useFdm3dNodeData } from '../components/NodeCacheProvider/NodeCacheProvider'; +import { type Node3D } from '@cognite/sdk'; + +export type NodeDataResult = { + fdmNode: DmsUniqueIdentifier; + view: Source; + cadNode: Node3D; +}; export type ClickedNodeData = Partial & { intersection: CadIntersection; diff --git a/react-components/src/index.ts b/react-components/src/index.ts index 9f757e1cb66..9ba183226f8 100644 --- a/react-components/src/index.ts +++ b/react-components/src/index.ts @@ -19,7 +19,11 @@ export { RevealKeepAlive } from './components/RevealKeepAlive/RevealKeepAlive'; export { useReveal } from './components/RevealContainer/RevealContext'; export { use3DModelName } from './hooks/use3DModelName'; export { useFdmAssetMappings } from './components/NodeCacheProvider/NodeCacheProvider'; -export { useClickedNodeData, type ClickedNodeData } from './hooks/useClickedNode'; +export { + useClickedNodeData, + type ClickedNodeData, + type NodeDataResult +} from './hooks/useClickedNode'; export { useCameraNavigation } from './hooks/useCameraNavigation'; export { useMappedEdgesForRevisions } from './components/NodeCacheProvider/NodeCacheProvider'; export { use3dNodeByExternalId } from './hooks/use3dNodeByExternalId'; @@ -46,8 +50,7 @@ export { export type { AddImageCollection360Options, AddResourceOptions, - AddReveal3DModelOptions, - NodeDataResult + AddReveal3DModelOptions } from './components/Reveal3DResources/types'; export type { CameraNavigationActions } from './hooks/useCameraNavigation'; export type { Source, DmsUniqueIdentifier } from './utilities/FdmSDK';