Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(react-components): add fetching of the view for mapped equipment hook #3654

Merged
merged 33 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
5d7effe
Added view fetching for useMappedEdgesForRevisions hook
Savokr Aug 28, 2023
81fbea8
removed comment
Savokr Aug 30, 2023
6beb392
Merge branch 'master' into savokr/add-view-fetching-for-mapped-nodes
Savokr Aug 30, 2023
4a0d9dd
Lint fixes
Savokr Aug 30, 2023
394a799
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Aug 31, 2023
5622e8e
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Aug 31, 2023
41322a2
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Aug 31, 2023
fae4aca
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Aug 31, 2023
d4fa06a
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Aug 31, 2023
0434004
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Sep 1, 2023
2efbca5
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Sep 1, 2023
e0b7a3f
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Sep 4, 2023
8c687b0
Minor PR fixes
Savokr Sep 4, 2023
2a9783a
Merge branch 'master' into savokr/add-view-fetching-for-mapped-nodes
Savokr Sep 4, 2023
8d0a905
Fixed nodeId type issue
Savokr Sep 4, 2023
defc72b
Merge branch 'savokr/add-view-fetching-for-mapped-nodes' of https://g…
Savokr Sep 4, 2023
82b1427
Merge master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Sep 4, 2023
f62e415
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Sep 4, 2023
ad29158
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Sep 4, 2023
c691385
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Sep 4, 2023
ad8486b
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Sep 4, 2023
a2e365e
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Sep 4, 2023
164b395
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Sep 4, 2023
200cd90
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Sep 4, 2023
ab2d1dc
New hook added
Savokr Sep 4, 2023
63c996c
Missing hook file
Savokr Sep 4, 2023
5751a6a
Fixed types in styling cache
Savokr Sep 4, 2023
7383222
Merge branch 'savokr/add-view-fetching-for-mapped-nodes' of https://g…
Savokr Sep 4, 2023
fe116f9
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Sep 5, 2023
a9bc884
Merge refs/heads/master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Sep 5, 2023
6f5f565
PR comments fixes
Savokr Sep 5, 2023
7fb2c88
Merge branch 'savokr/add-view-fetching-for-mapped-nodes' of https://g…
Savokr Sep 5, 2023
cb42e91
Merge master into savokr/add-view-fetching-for-mapped-nodes
cognite-bulldozer[bot] Sep 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 46 additions & 14 deletions react-components/src/components/NodeCacheProvider/FdmNodeCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
*/

import { type Node3D, type CogniteClient, type CogniteExternalId } from '@cognite/sdk';
import { 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,
Expand Down Expand Up @@ -32,7 +37,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 {
Expand Down Expand Up @@ -203,8 +208,9 @@ export class FdmNodeCache {
): Promise<Map<ModelRevisionKey, FdmEdgeWithNode[]>> {
const revisionIds = modelRevisionIds.map((modelRevisionId) => modelRevisionId.revisionId);
const edges = await this.getEdgesForRevisions(revisionIds, this._fdmClient);
const edgesWithViews = await this.getViewsForEdges(edges);
const revisionToEdgesMap = await createRevisionToEdgesMap(
edges,
edgesWithViews,
modelRevisionIds,
this._cdfClient
);
Expand All @@ -224,6 +230,22 @@ export class FdmNodeCache {
return await revisionCache.getClosestParentFdmData(treeIndex);
}

private async getViewsForEdges(
edges: Array<EdgeItem<InModel3dEdgeProperties>>
Savokr marked this conversation as resolved.
Show resolved Hide resolved
): Promise<Array<{ edge: FdmCadEdge; view: Source }>> {
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
Expand Down Expand Up @@ -266,24 +288,29 @@ export class FdmNodeCache {
}

async function createRevisionToEdgesMap(
edges: FdmCadEdge[],
edgesWithViews: Array<{ edge: FdmCadEdge; view: Source }>,
modelRevisionIds: ModelRevisionId[],
cdfClient: CogniteClient
): Promise<Map<ModelRevisionKey, FdmEdgeWithNode[]>> {
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);

Expand All @@ -294,6 +321,7 @@ async function createRevisionToEdgesMap(
function createFdmEdgeWithNode(
modelRevisionId: ModelRevisionId,
edge: FdmCadEdge,
view: Source,
modelNodeIdToNodeMap: Map<ModelNodeIdKey, Node3D>
): FdmEdgeWithNode {
const revisionNodeIdKey = createModelNodeIdKey(
Expand All @@ -305,7 +333,7 @@ function createFdmEdgeWithNode(
const node = modelNodeIdToNodeMap.get(revisionNodeIdKey);
assert(node !== undefined);

return { edge, node };
return { edge, node, view };
}

function insertEdgeIntoMapList(
Expand Down Expand Up @@ -350,14 +378,18 @@ async function createModelNodeIdToNodeMap(
return revisionNodeIdToNode;
}

function createRevisionToNodeIdMap(edges: FdmCadEdge[]): Map<RevisionId, NodeId[]> {
return edges.reduce((revisionNodeIdMap, edge) => {
const nodeIdsInRevision = revisionNodeIdMap.get(edge.properties.revisionId);
function createRevisionToNodeIdMap(
edgesWithViews: Array<{ edge: FdmCadEdge; view: Source }>
): Map<RevisionId, NodeId[]> {
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,22 @@ export type FdmNodeCacheContent = {

export const FdmNodeCacheContext = createContext<FdmNodeCacheContent | undefined>(undefined);

export const useMappedEdgesForRevisions = (
modelRevisionIds: Array<{ modelId: number; revisionId: number }>,
enabled = true
): UseQueryResult<ModelRevisionToEdgeMap> => {
export const useFdmNodeCache = (): FdmNodeCacheContent => {
Savokr marked this conversation as resolved.
Show resolved Hide resolved
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<ModelRevisionToEdgeMap> => {
const content = useFdmNodeCache();

return useQuery(
[
'reveal',
Expand All @@ -46,7 +52,7 @@ export const useFdm3dNodeData = (
revisionId: number | undefined,
treeIndex: number | undefined
): UseQueryResult<Fdm3dNodeData[]> => {
const content = useContext(FdmNodeCacheContext);
const content = useFdmNodeCache();

const enableQuery =
content !== undefined &&
Expand All @@ -65,25 +71,19 @@ export const useFdm3dNodeData = (
}
);

if (content === undefined) {
throw Error('Must use useNodeCache inside a NodeCacheContext');
}

return result;
};

export const useFdmAssetMappings = (
fdmAssetExternalIds: DmsUniqueIdentifier[],
models: TypedReveal3DModel[]
): UseQueryResult<ThreeDModelMappings[]> => {
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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export class RevisionFdmNodeCache {
private readonly _revisionId: number;

private readonly _treeIndexToFdmEdges = new Map<TreeIndex, FdmEdgeWithNode[]>();
private readonly _treeIndexToFdmData = new Map<TreeIndex, Fdm3dNodeData[]>();

constructor(
cogniteClient: CogniteClient,
Expand All @@ -40,10 +39,10 @@ export class RevisionFdmNodeCache {
}

public async getClosestParentFdmData(searchTreeIndex: number): Promise<Fdm3dNodeData[]> {
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);
Expand All @@ -63,12 +62,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(
Expand All @@ -82,14 +81,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: Array<Omit<FdmEdgeWithNode, 'view'>>,
Savokr marked this conversation as resolved.
Show resolved Hide resolved
ancestorsWithSameMapping: Node3D[]
): Promise<Fdm3dNodeData[]> {
const nodeInspectionResults = await inspectNodes(
Expand All @@ -98,16 +97,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<{
Expand Down Expand Up @@ -196,6 +194,14 @@ 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 {
Expand Down
27 changes: 19 additions & 8 deletions react-components/src/components/NodeCacheProvider/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
type InModel3dEdgeProperties,
SYSTEM_3D_EDGE_SOURCE
} from '../../utilities/globalDataModels';
import { chunk } from 'lodash';

export async function fetchAncestorNodesForTreeIndex(
modelId: number,
Expand Down Expand Up @@ -83,14 +84,24 @@ export async function inspectNodes(
fdmClient: FdmSDK,
dataNodes: DmsUniqueIdentifier[]
): Promise<InspectResultList> {
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({
haakonflatval-cognite marked this conversation as resolved.
Show resolved Hide resolved
inspectionOperations: { involvedViewsAndContainers: {} },
items: nodesChunk.map((node) => ({
instanceType: 'node',
externalId: node.externalId,
space: node.space
}))
});

inspectionResult.items.push(...chunkInspectionResults.items);
}

return inspectionResult;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { type InModel3dEdgeProperties } from '../../utilities/globalDataModels';

export type Fdm3dNodeData = { fdmId: DmsUniqueIdentifier; view: Source; cadNode: Node3D };
export type FdmCadEdge = EdgeItem<InModel3dEdgeProperties>;
export type FdmEdgeWithNode = { edge: FdmCadEdge; node: Node3D };
export type FdmEdgeWithNode = { edge: FdmCadEdge; node: Node3D; view: Source };
Savokr marked this conversation as resolved.
Show resolved Hide resolved

export type ModelId = number;
export type RevisionId = number;
Expand Down
30 changes: 13 additions & 17 deletions react-components/src/hooks/useCameraNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,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;
Expand All @@ -14,8 +13,8 @@ export type CameraNavigationActions = {
};

export const useCameraNavigation = (): CameraNavigationActions => {
const fdmNodeCache = useFdmNodeCache();
const viewer = useReveal();
const fdmSDK = useFdmSdk();

const fitCameraToAllModels = (): void => {
const models = viewer.models;
Expand All @@ -36,28 +35,25 @@ export const useCameraNavigation = (): CameraNavigationActions => {
};

const fitCameraToInstance = async (externalId: string, space: string): Promise<void> => {
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<InModel3dEdgeProperties>(
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) {
Savokr marked this conversation as resolved.
Show resolved Hide resolved
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 {
Expand Down
Loading