From 2d4785faac65b4cb6e287542445a563f03585366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Mon, 19 Aug 2024 08:12:40 +0200 Subject: [PATCH 01/32] feat(react-components): WIP CoreDM queries --- .../CacheProvider/RevisionFdmNodeCache.ts | 5 +- .../src/data-providers/Fdm3dDataProvider.ts | 5 +- react-components/src/data-providers/FdmSDK.ts | 40 ++-- .../core-dm-provider/CoreDm3dDataProvider.ts | 163 ++++++++++++++++ .../core-dm-provider/Duplex3dDataProvider.ts | 76 ++++++++ .../cogniteAssetSourceWithProperties.ts | 33 ++++ .../core-dm-provider/dataModels.ts | 155 +++++++++++++++ .../filterNodesByMappedTo3d.ts | 105 +++++++++++ .../core-dm-provider/getDMSModels.ts | 42 +++++ .../core-dm-provider/getDMSRevision.ts | 71 +++++++ .../getEdgeConnected3dInstances.ts | 80 ++++++++ .../getFdmConnectionsForNodeIds.ts | 178 ++++++++++++++++++ .../getModelIdFromExternalId.ts | 4 + .../core-dm-provider/listMappedFdmNodes.ts | 131 +++++++++++++ .../LegacyFdm3dDataProvider.ts | 11 +- .../createMappedEquipmentQuery.ts | 10 +- .../filterNodesByMappedTo3d.ts | 27 +-- .../getEdgeConnected3dInstances.ts | 7 +- .../getFdmConnectionsForNodeIds.ts | 8 +- .../legacy-fdm-provider/listMappedFdmNodes.ts | 3 +- .../src/data-providers/mergeQueryResult.ts | 11 ++ .../src/data-providers/queryNodesAndEdges.ts | 93 +++++++++ .../utils/getDirectRelationProperties.ts | 16 ++ .../src/utilities/executeParallel.ts | 27 +++ 24 files changed, 1242 insertions(+), 59 deletions(-) create mode 100644 react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts create mode 100644 react-components/src/data-providers/core-dm-provider/Duplex3dDataProvider.ts create mode 100644 react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts create mode 100644 react-components/src/data-providers/core-dm-provider/dataModels.ts create mode 100644 react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts create mode 100644 react-components/src/data-providers/core-dm-provider/getDMSModels.ts create mode 100644 react-components/src/data-providers/core-dm-provider/getDMSRevision.ts create mode 100644 react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts create mode 100644 react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts create mode 100644 react-components/src/data-providers/core-dm-provider/getModelIdFromExternalId.ts create mode 100644 react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts create mode 100644 react-components/src/data-providers/mergeQueryResult.ts create mode 100644 react-components/src/data-providers/queryNodesAndEdges.ts create mode 100644 react-components/src/data-providers/utils/getDirectRelationProperties.ts create mode 100644 react-components/src/utilities/executeParallel.ts diff --git a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts index 2c191905e5e..531c5366fcb 100644 --- a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts @@ -226,6 +226,7 @@ export class RevisionFdmNodeCache { const firstMappedAncestorTreeIndex = findLargestTreeIndex( connectionsWithCorrespondingTreeIndex ); + return getAncestorDataForTreeIndex( firstMappedAncestorTreeIndex, connectionsWithCorrespondingTreeIndex, @@ -272,10 +273,10 @@ export class RevisionFdmNodeCache { return []; } - const ancestorMappings = await this._fdm3dDataProvider.getFdmConnectionsForNodeIds( + const ancestorMappings = await this._fdm3dDataProvider.getFdmConnectionsForNodes( modelInstances, this._revisionId, - ancestors.map((a) => a.id) + ancestors ); return ancestorMappings; diff --git a/react-components/src/data-providers/Fdm3dDataProvider.ts b/react-components/src/data-providers/Fdm3dDataProvider.ts index 065050068e2..c2de79e9449 100644 --- a/react-components/src/data-providers/Fdm3dDataProvider.ts +++ b/react-components/src/data-providers/Fdm3dDataProvider.ts @@ -12,6 +12,7 @@ import { type AddModelOptions } from '@cognite/reveal'; import { type InstancesWithView } from '../query/useSearchMappedEquipmentFDM'; import { type FdmCadConnection } from '../components/CacheProvider/types'; import { type TaggedAddResourceOptions } from '../components/Reveal3DResources/types'; +import { Node3D } from '@cognite/sdk'; export type Fdm3dDataProvider = { is3dView: (view: ViewItem) => boolean; @@ -20,10 +21,10 @@ export type Fdm3dDataProvider = { getEdgeConnected3dInstances: (instance: DmsUniqueIdentifier) => Promise; - getFdmConnectionsForNodeIds: ( + getFdmConnectionsForNodes: ( models: DmsUniqueIdentifier[], revisionId: number, - nodeIds: number[] + nodes: Node3D[] ) => Promise; listMappedFdmNodes: ( diff --git a/react-components/src/data-providers/FdmSDK.ts b/react-components/src/data-providers/FdmSDK.ts index d226992aae0..44fcc97682a 100644 --- a/react-components/src/data-providers/FdmSDK.ts +++ b/react-components/src/data-providers/FdmSDK.ts @@ -2,13 +2,14 @@ * Copyright 2023 Cognite AS */ -import { type CogniteClient } from '@cognite/sdk'; +import { QueryRequest, TableExpressionFilterDefinition, type CogniteClient } from '@cognite/sdk'; import { type FdmPropertyType } from '../components/Reveal3DResources/types'; +import { queryNodesAndEdges, QueryResult, SelectSourceWithParams } from './queryNodesAndEdges'; type InstanceType = 'node' | 'edge'; type EdgeDirection = 'source' | 'destination'; -export type InstanceFilter = Record; +export type InstanceFilter = TableExpressionFilterDefinition; type ViewPropertyReference = any; export type ExternalId = string; @@ -99,7 +100,7 @@ export type NodeItem> = { externalId: string; createdTime: number; lastUpdatedTime: number; - deletedTime: number; + deletedTime?: number; properties: FdmPropertyType; }; @@ -110,7 +111,7 @@ export type FdmNode> = { externalId: string; createdTime: number; lastUpdatedTime: number; - deletedTime: number; + deletedTime: number | undefined; properties: PropertyType; }; @@ -148,13 +149,6 @@ export type InspectResultList = { }>; }; -type SelectKey = keyof T['select']; - -export type QueryResult = { - items: Record, NodeItem[] | EdgeItem[]>; - nextCursor: Record, string> | undefined; -}; - export type ExternalIdsResultList = { items: Array>; typing?: Record< @@ -529,12 +523,26 @@ export class FdmSDK { throw new Error(`Failed to fetch instances. Status: ${result.status}`); } - public async queryNodesAndEdges(query: T): Promise> { - const result = await this._sdk.post(this._queryEndpoint, { data: query }); - if (result.status === 200) { - return { items: result.data.items, nextCursor: result.data.nextCursor }; + public async queryAllNodesAndEdges< + TQueryRequest extends QueryRequest, + TypedSelectSources extends SelectSourceWithParams = SelectSourceWithParams + >(query: TQueryRequest): Promise> { + let result = await queryNodesAndEdges(query, this._sdk); + let items = result.items; + while (result.nextCursor !== undefined) { + const newQuery = { ...query, cursor: result.nextCursor }; + result = await queryNodesAndEdges(newQuery, this._sdk); + items = mergeQueryResults(items, result.items); } - throw new Error(`Failed to fetch instances. Status: ${result.status}`); + + return { items }; + } + + public async queryNodesAndEdges< + TQueryRequest extends QueryRequest, + TypedSelectSources extends SelectSourceWithParams = SelectSourceWithParams + >(query: TQueryRequest): Promise> { + return queryNodesAndEdges(query, this._sdk); } public async listDataModels(): Promise { diff --git a/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts b/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts new file mode 100644 index 00000000000..93eabe3bcd1 --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts @@ -0,0 +1,163 @@ +import { AddModelOptions, isDefaultCameraManager } from '@cognite/reveal'; +import { FdmCadConnection } from '../../components/CacheProvider/types'; +import { Fdm3dDataProvider } from '../Fdm3dDataProvider'; +import { DmsUniqueIdentifier, FdmSDK, InstanceFilter, NodeItem, Source, ViewItem } from '../FdmSDK'; +import { InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; +import { TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; +import { COGNITE_3D_OBJECT_SOURCE } from './dataModels'; +import { getDMSModels } from './getDMSModels'; +import { getEdgeConnected3dInstances } from './getEdgeConnected3dInstances'; +import { getFdmConnectionsForNodes } from './getFdmConnectionsForNodeIds'; +import { Node3D } from '@cognite/sdk'; +import { getDMSRevision } from './getDMSRevision'; +import assert from 'assert'; +import { listAllMappedFdmNodes, listMappedFdmNodes } from './listMappedFdmNodes'; +import { isDefined } from '../../utilities/isDefined'; +import { executeParallel } from '../../utilities/executeParallel'; +import { zip } from 'lodash'; + +const MAX_PARALLEL_QUERIES = 2; + +export class CoreDm3dFdm3dDataProvider implements Fdm3dDataProvider { + readonly _fdmSdk: FdmSDK; + + readonly _relevant3dSpaces: DmsUniqueIdentifier[]; + + readonly _revisionIdToDMSIdentifier = new Map(); + readonly _modelIdToDMSIdentifier = new Map(); + + constructor(relevant3dSpaces: DmsUniqueIdentifier[], fdmSdk: FdmSDK) { + this._fdmSdk = fdmSdk; + this._relevant3dSpaces = relevant3dSpaces; + } + + is3dView(view: ViewItem): boolean { + return view.implements.some( + (type) => + type.externalId === COGNITE_3D_OBJECT_SOURCE.externalId && + type.space === COGNITE_3D_OBJECT_SOURCE.space && + type.version === COGNITE_3D_OBJECT_SOURCE.version + ); + } + + async getDMSModels(modelId: number): Promise { + const cachedModels = this._modelIdToDMSIdentifier.get(modelId); + if (cachedModels !== undefined) { + return cachedModels; + } + + const models = await getDMSModels(modelId, this._fdmSdk); + + this._modelIdToDMSIdentifier.set(modelId, models); + return models; + } + + private async getDMSRevision( + modelRef: DmsUniqueIdentifier, + revisionId: number + ): Promise { + let revisionRef = this._revisionIdToDMSIdentifier.get(revisionId); + + if (revisionRef === undefined) { + const revisionResult = await getDMSRevision(modelRef, revisionId, this._fdmSdk); + + this._revisionIdToDMSIdentifier.set(revisionId, revisionResult); + revisionRef = revisionResult; + } + + if (revisionRef === undefined) { + throw Error(`No revision with id ${revisionId} found`); + } + + return revisionRef; + } + + private async getDMSModelsForIds( + modelIds: number[] + ): Promise<(DmsUniqueIdentifier | undefined)[]> { + return ( + await executeParallel( + modelIds.map((id) => () => this.getDMSModels(id)), + MAX_PARALLEL_QUERIES + ) + ).flat(); + } + + private async getDMSRevisionsForRevisionIdsAndModelRefs( + modelRefs: (DmsUniqueIdentifier | undefined)[], + revisionIds: number[] + ): Promise { + return ( + await executeParallel( + revisionIds.map( + (revisionId, ind) => () => + modelRefs[ind] === undefined + ? Promise.resolve(undefined) + : this.getDMSRevision(modelRefs[ind], revisionId) + ), + MAX_PARALLEL_QUERIES + ) + ).filter(isDefined); + } + + getEdgeConnected3dInstances(instance: DmsUniqueIdentifier): Promise { + return getEdgeConnected3dInstances(instance, this._fdmSdk); + } + + async getFdmConnectionsForNodes( + models: DmsUniqueIdentifier[], + revisionId: number, + nodes: Node3D[] + ): Promise { + if (models.length !== 1) { + throw new Error(`Expected 1 model, got ${models.length}`); + } + + const model = models[0]; + + const revisionRef = await this.getDMSRevision(model, revisionId); + + return getFdmConnectionsForNodes(model, revisionRef, revisionId, nodes, this._fdmSdk); + } + + async listMappedFdmNodes( + models: AddModelOptions[], + sourcesToSearch: Source[], + instanceFilter: InstanceFilter | undefined, + limit: number + ): Promise { + const modelRefs = await this.getDMSModelsForIds(models.map((model) => model.modelId)); + + const revisionRefs = await this.getDMSRevisionsForRevisionIdsAndModelRefs( + modelRefs, + models.map((model) => model.revisionId) + ); + + return listMappedFdmNodes(revisionRefs, sourcesToSearch, instanceFilter, limit, this._fdmSdk); + } + + async listAllMappedFdmNodes( + models: AddModelOptions[], + sourcesToSearch: Source[], + instanceFilter: InstanceFilter | undefined + ): Promise { + const modelRefs = await this.getDMSModelsForIds(models.map((model) => model.modelId)); + + const revisionRefs = await this.getDMSRevisionsForRevisionIdsAndModelRefs( + modelRefs, + models.map((model) => model.revisionId) + ); + + return listAllMappedFdmNodes(revisionRefs, sourcesToSearch, instanceFilter, this._fdmSdk); + } + + filterNodesByMappedTo3d( + nodes: InstancesWithView[], + models: AddModelOptions[], + spacesToSearch: string[] + ): Promise {} + + getCadModelsForInstance(instance: DmsUniqueIdentifier): Promise {} + + getCadConnectionsForRevisions(revisions: number[]): Promise {} +} diff --git a/react-components/src/data-providers/core-dm-provider/Duplex3dDataProvider.ts b/react-components/src/data-providers/core-dm-provider/Duplex3dDataProvider.ts new file mode 100644 index 00000000000..055cd117827 --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/Duplex3dDataProvider.ts @@ -0,0 +1,76 @@ +import { AddModelOptions } from '@cognite/reveal'; +import { FdmCadConnection } from '../../components/CacheProvider/types'; +import { Fdm3dDataProvider } from '../Fdm3dDataProvider'; +import { DmsUniqueIdentifier, FdmSDK, InstanceFilter, NodeItem, Source, ViewItem } from '../FdmSDK'; +import { InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; +import { TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; +import { CoreDm3dFdm3dDataProvider } from './CoreDm3dDataProvider'; +import { LegacyFdm3dDataProvider } from '../legacy-fdm-provider/LegacyFdm3dDataProvider'; +import { Node3D } from '@cognite/sdk'; + +// TODO - re-evaluate if this class is actually necessary... +export class Duplex3dDataProvider implements Fdm3dDataProvider { + readonly _fdmSdk: FdmSDK; + + readonly _dataProvider: Fdm3dDataProvider; + + constructor(isMaja: boolean, relevant3dSpaces: DmsUniqueIdentifier[], fdmSdk: FdmSDK) { + this._fdmSdk = fdmSdk; + this._dataProvider = isMaja + ? new CoreDm3dFdm3dDataProvider(relevant3dSpaces, fdmSdk) + : new LegacyFdm3dDataProvider(fdmSdk); + } + + is3dView(view: ViewItem): boolean { + return this._dataProvider.is3dView(view); + } + + getDMSModels(modelId: number): Promise { + return this._dataProvider.getDMSModels(modelId); + } + + getEdgeConnected3dInstances(instance: DmsUniqueIdentifier): Promise { + return this._dataProvider.getEdgeConnected3dInstances(instance); + } + + getFdmConnectionsForNodes( + models: DmsUniqueIdentifier[], + revisionId: number, + nodes: Node3D[] + ): Promise { + return this._dataProvider.getFdmConnectionsForNodes(models, revisionId, nodes); + } + + listMappedFdmNodes( + models: AddModelOptions[], + sourcesToSearch: Source[], + instancesFilter: InstanceFilter | undefined, + limit: number + ): Promise { + return this._dataProvider.listMappedFdmNodes(models, sourcesToSearch, instancesFilter, limit); + } + + listAllMappedFdmNodes( + models: AddModelOptions[], + sourcesToSearch: Source[], + instanceFilter: InstanceFilter | undefined + ): Promise { + return this._dataProvider.listAllMappedFdmNodes(models, sourcesToSearch, instanceFilter); + } + + filterNodesByMappedTo3d( + nodes: InstancesWithView[], + models: AddModelOptions[], + spacesToSearch: string[] + ): Promise { + return this._dataProvider.filterNodesByMappedTo3d(nodes, models, spacesToSearch); + } + + getCadModelsForInstance(instance: DmsUniqueIdentifier): Promise { + return this._dataProvider.getCadModelsForInstance(instance); + } + + getCadConnectionsForRevisions(revisions: number[]): Promise { + return this._dataProvider.getCadConnectionsForRevisions(revisions); + } +} diff --git a/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts new file mode 100644 index 00000000000..18d17edc1d1 --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts @@ -0,0 +1,33 @@ +import { SourceSelectorV3 } from '@cognite/sdk/dist/src'; +import { COGNITE_ASSET_SOURCE } from './dataModels'; + +export const cogniteAssetSourceWithProperties = [ + { + source: COGNITE_ASSET_SOURCE, + properties: [ + 'object3D', + 'name', + 'description', + 'tags', + 'aliases', + 'sourceId', + 'sourceContext', + 'source', + 'sourceCreatedTime', + 'sourceUpdatedTime', + 'sourceCreatedUser', + 'sourceUpdatedUser', + 'parent', + 'root', + 'path', + 'lastPathMaterializationTime', + 'equipment', + 'assetClass', + 'type', + 'files', + 'children', + 'activities', + 'timeSeries' + ] + } +] as const satisfies SourceSelectorV3; diff --git a/react-components/src/data-providers/core-dm-provider/dataModels.ts b/react-components/src/data-providers/core-dm-provider/dataModels.ts new file mode 100644 index 00000000000..8b5bc7163d7 --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/dataModels.ts @@ -0,0 +1,155 @@ +import { DateRange, Timestamp, ViewReference } from '@cognite/sdk'; +import { DmsUniqueIdentifier, Source } from '../FdmSDK'; + +export const CORE_DM_SPACE = 'cdf_cdm_experimental'; + +export const SYSTEM_SPACE_3D_MODEL_TYPE = 'CogniteModel3D'; +export const SYSTEM_SPACE_3D_MODEL_VERSION = '1'; + +export const COGNITE_3D_OBJECT_SOURCE = { + externalId: 'CogniteObject3D', + space: CORE_DM_SPACE, + version: 'v1', + type: 'view' +} as const satisfies ViewReference; + +export const COGNITE_3D_MODEL_SOURCE = { + externalId: 'Cognite3DModel', + space: CORE_DM_SPACE, + version: 'v1', + type: 'view' +} as const satisfies ViewReference; + +export const COGNITE_CAD_MODEL_SOURCE = { + externalId: 'CogniteCADModel', + space: CORE_DM_SPACE, + version: 'v1', + type: 'view' +} as const satisfies ViewReference; + +export const COGNITE_CAD_REVISION_SOURCE = { + externalId: 'CogniteCADRevision', + space: CORE_DM_SPACE, + version: 'v1', + type: 'view' +} as const satisfies ViewReference; + +export const COGNITE_CAD_NODE_SOURCE = { + externalId: 'CogniteCADNode', + space: CORE_DM_SPACE, + version: 'v1', + type: 'view' +} as const satisfies ViewReference; + +export const COGNITE_ASSET_SOURCE = { + externalId: 'CogniteAsset', + space: CORE_DM_SPACE, + version: 'v1', + type: 'view' +} as const satisfies ViewReference; + +export const COGNITE_VISUALIZABLE_SOURCE = { + externalId: 'CogniteVisualizable', + space: CORE_DM_SPACE, + version: 'v1', + type: 'view' +} as const satisfies ViewReference; + +export const COGNITE_POINT_CLOUD_VOLUME = { + externalId: 'CognitePointCloudVolume', + space: CORE_DM_SPACE, + version: 'v1', + type: 'view' +} as const satisfies ViewReference; + +export enum Cognite3DModel_type { + CAD = 'CAD', + PointCloud = 'PointCloud', + Image360 = 'Image360' +} + +export type Cognite3DModelProperties = { + name: string; + description: string; + tags: string[]; + aliases: string[]; + type: Cognite3DModel_type; + thumbnail: object; +}; + +export enum Cognite3DRevision_status { + Queued = 'Queued', + Processing = 'Processing', + Done = 'Done', + Failed = 'Failed' +} + +export enum Cognite3DRevision_type { + CAD = 'CAD', + PointCloud = 'PointCloud', + Image360 = 'Image360' +} + +export type CogniteAssetProperties = { + object3D: DmsUniqueIdentifier; + name: string; + description: string; + tags: string[]; + aliases: string[]; + sourceId: string; + sourceContext: string; + source: DmsUniqueIdentifier; + sourceCreatedTime: Timestamp; + sourceUpdatedTime: Timestamp; + sourceCreatedUser: string; + sourceUpdatedUser: string; + parent: DmsUniqueIdentifier; + root: DmsUniqueIdentifier; + path: DmsUniqueIdentifier[]; + lastPathMaterializationTime: Timestamp; + equipment: DmsUniqueIdentifier; + assetClass: DmsUniqueIdentifier; + type: DmsUniqueIdentifier; + files: DmsUniqueIdentifier[]; + children: DmsUniqueIdentifier[]; + activities: DmsUniqueIdentifier[]; + timeSeries: DmsUniqueIdentifier[]; +}; + +export type CogniteCADRevisionProperties = { + status: Cognite3DRevision_status; + publish: boolean; + type: Cognite3DRevision_type; + model3D: DmsUniqueIdentifier; + revisionId: number; +}; + +export type CogniteCADNodeProperties = { + name: string; + description: string; + tags: string[]; + aliases: string[]; + object3D: DmsUniqueIdentifier; + model3D: DmsUniqueIdentifier; + cadNodeReference: string; + revisions: DmsUniqueIdentifier[]; + treeIndexes: number[]; + subTreeSizes: number[]; +}; + +export type Cognite3DObjectProperties = { + name: string; + description: string; + tags: string[]; + aliases: string[]; + xMin: number; + xMax: number; + yMin: number; + yMax: number; + zMin: number; + zMax: number; + asset: DmsUniqueIdentifier[]; + cadNodes: DmsUniqueIdentifier[]; + images360: DmsUniqueIdentifier[]; + pointCloudVolumes: DmsUniqueIdentifier[]; +}; diff --git a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts new file mode 100644 index 00000000000..fdd77be08c1 --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts @@ -0,0 +1,105 @@ +import { AddModelOptions } from '@cognite/reveal'; +import { InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; +import { QueryRequest, QueryTableExpressionV3 } from '@cognite/sdk/dist/src'; +import { getDirectRelationProperties } from '../utils/getDirectRelationProperties'; +import { COGNITE_3D_OBJECT_SOURCE, COGNITE_VISUALIZABLE_SOURCE } from './dataModels'; +import { cogniteAssetSourceWithProperties } from './cogniteAssetSourceWithProperties'; +import { DmsUniqueIdentifier } from '../FdmSDK'; + +export function filterNodesByMappedTo3d( + nodes: InstancesWithView[], + revisionRefs: DmsUniqueIdentifier[], + spacesToSearch: string[] +): Promise { + const initialExternalIds = nodes.flatMap((node) => + node.instances.map((instance) => instance.externalId) + ); + + const directlyMappedIds = nodes.flatMap((node) => + node.instances.map(getDirectRelationProperties) + ); + + const parameters = { initialExternalIds, directlyMappedIds, revisionRefs }; + + const query = { + ...checkEquipmentFilter, + parameters + }; +} + +const checkEquipmentFilter: QueryRequest = { + with: { + initial_nodes: { + nodes: { + filter: { + and: [ + { + in: { + property: ['node', 'externalId'], + values: { parameter: 'initialExternalIds' } + } + }, + { + hasData: [COGNITE_VISUALIZABLE_SOURCE] + } + ] + } + } + }, + directly_referenced_nodes: { + nodes: { + filter: { + and: [ + { + in: { + property: ['node', 'externalId'], + values: { parameter: 'directlyMappedIds' } + } + }, + { + hasData: [COGNITE_VISUALIZABLE_SOURCE] + } + ] + } + } + }, + indirectly_referenced_nodes: { + edges: { + from: 'initial_nodes', + direction: 'outwards', + nodeFilter: { + hasData: [COGNITE_VISUALIZABLE_SOURCE] + } + } + }, + initial_nodes_object_3ds: getObject3dRelation('initial_nodes'), + initial_nodes_assets: getAssetRelation('initial_nodes_object_3ds'), + direct_nodes_object_3ds: getObject3dRelation('directly_referenced_nodes'), + direct_nodes_assets: getAssetRelation('direct_nodes_object_3ds'), + indirect_nodes_object_3ds: getObject3dRelation('indirectly_referenced_nodes'), + indirect_nodes_assets: getAssetRelation('indirect_nodes_object_3ds') + }, + select: { + initial_nodes_assets: { sources: cogniteAssetSourceWithProperties }, + direct_nodes_assets: { sources: cogniteAssetSourceWithProperties }, + indirect_nodes_assets: { sources: cogniteAssetSourceWithProperties } + } +}; // as const satisfies Omit; + +function getObject3dRelation(visualizableTableName: string): QueryTableExpressionV3 { + return { + nodes: { + from: visualizableTableName, + through: { source: COGNITE_VISUALIZABLE_SOURCE, identifier: 'object3d' } + } + }; +} + +function getAssetRelation(object3dTableName: string): QueryTableExpressionV3 { + return { + nodes: { + from: object3dTableName, + through: { source: COGNITE_3D_OBJECT_SOURCE, identifier: 'assets' } + } + }; +} diff --git a/react-components/src/data-providers/core-dm-provider/getDMSModels.ts b/react-components/src/data-providers/core-dm-provider/getDMSModels.ts new file mode 100644 index 00000000000..4451ee8b0d2 --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/getDMSModels.ts @@ -0,0 +1,42 @@ +import { QueryRequest } from '@cognite/sdk/dist/src'; +import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; +import { Cognite3DModelProperties, COGNITE_3D_MODEL_SOURCE } from './dataModels'; + +export async function getDMSModels( + modelId: number, + fdmSdk: FdmSDK +): Promise { + const modelName = `cog_3d_model_${modelId}`; + + const query = { + select: { + models: { + sources: [ + { + source: COGNITE_3D_MODEL_SOURCE, + properties: ['name', 'description', 'tags', 'aliases', 'type', 'thumbnail'] + } + ] + } + }, + with: { + models: { + nodes: { + filter: { + and: [ + { equals: { property: ['node', 'externalId'], value: modelName } }, + { hasData: [COGNITE_3D_MODEL_SOURCE] } + ] + } + } + } + } + } as const satisfies Omit; + + const result = await fdmSdk.queryNodesAndEdges< + typeof query, + [{ source: typeof COGNITE_3D_MODEL_SOURCE; properties: Cognite3DModelProperties }] + >(query); + + return result.items.models; +} diff --git a/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts new file mode 100644 index 00000000000..ce2e4c1f5d6 --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts @@ -0,0 +1,71 @@ +import { QueryRequest } from '@cognite/sdk/dist/src'; +import { DmsUniqueIdentifier, FdmSDK, NodeItem } from '../FdmSDK'; +import { COGNITE_CAD_REVISION_SOURCE, CogniteCADRevisionProperties } from './dataModels'; + +export async function getDMSRevision( + model: DmsUniqueIdentifier, + revisionId: number, + fdmSdk: FdmSDK +): Promise> { + const query = { + ...cadConnectionQuery, + parameters: { modelReference: model, revisionId } + } as const satisfies QueryRequest; + + const result = await fdmSdk.queryNodesAndEdges< + typeof cadConnectionQuery, + [{ source: typeof COGNITE_CAD_REVISION_SOURCE; properties: CogniteCADRevisionProperties }] + >(query); + + if (result.items.revision.length === 0) { + throw new Error( + `No revision found for ID ${revisionId} on model ${model.space}, ${model.externalId}` + ); + } + + return result.items.revision[0]; +} + +const cadConnectionQuery = { + with: { + revision: { + nodes: { + filter: { + and: [ + { + equals: { + property: [ + COGNITE_CAD_REVISION_SOURCE.space, + COGNITE_CAD_REVISION_SOURCE.externalId, + 'model3D' + ], + value: { parameter: 'modelReference' } + } + }, + { + in: { + property: [ + COGNITE_CAD_REVISION_SOURCE.space, + COGNITE_CAD_REVISION_SOURCE.externalId, + 'revisionId' + ], + values: { parameter: 'nodeIds' } + } + } + ] + } + }, + limit: 1 + } + }, + select: { + revision: { + sources: [ + { + source: COGNITE_CAD_REVISION_SOURCE, + properties: ['status', 'publish', 'type', 'model3D', 'revisionId'] + } + ] + } + } +} as const satisfies Omit; diff --git a/react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts b/react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts new file mode 100644 index 00000000000..f6e36201d00 --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts @@ -0,0 +1,80 @@ +import { QueryRequest } from '@cognite/sdk/dist/src'; +import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; +import { + Cognite3DObjectProperties, + COGNITE_3D_OBJECT_SOURCE, + COGNITE_VISUALIZABLE_SOURCE +} from './dataModels'; + +export async function getEdgeConnected3dInstances( + instance: DmsUniqueIdentifier, + fdmSdk: FdmSDK +): Promise { + const query = { + ...related3dEdgesQuery, + parameters: { instanceExternalId: instance.externalId, instanceSpace: instance.space } + } as const satisfies QueryRequest; + + const result = await fdmSdk.queryNodesAndEdges< + typeof related3dEdgesQuery, + [{ source: typeof COGNITE_3D_OBJECT_SOURCE; properties: Cognite3DObjectProperties }] + >(query); + + return result.items.connected_objects_with_3d; +} + +const related3dEdgesQuery = { + with: { + start_instance: { + nodes: { + filter: { + and: [ + { + equals: { + property: ['node', 'externalId'], + value: { parameter: 'instanceExternalId' } + } + }, + { + equals: { + property: ['node', 'space'], + value: { parameter: 'instanceSpace' } + } + } + ] + } + }, + limit: 1 + }, + start_to_object_edges: { + edges: { + from: 'start_instance', + maxDistance: 1, + direction: 'outwards' + }, + limit: 1000 + }, + objects_connected_with_3d: { + nodes: { + from: 'start_to_object_edges', + chainTo: 'destination', + filter: { + exists: { property: ['CogniteVisualizable', 'object3D'] } + } + } + }, + object_3ds: { + nodes: { + from: 'objects_connected_with_3d', + through: { view: COGNITE_VISUALIZABLE_SOURCE, identifier: 'object3D' } + }, + limit: 1000 + } + }, + select: { + start_instance: {}, + start_to_object_edges: {}, + connected_objects_with_3d: {}, + object_3ds: {} + } +} as const satisfies Omit; diff --git a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts new file mode 100644 index 00000000000..74a4bb57e4a --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts @@ -0,0 +1,178 @@ +import { Node3D, QueryRequest } from '@cognite/sdk'; +import { FdmCadConnection, FdmKey } from '../../components/CacheProvider/types'; +import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; +import { + Cognite3DObjectProperties, + COGNITE_3D_OBJECT_SOURCE, + COGNITE_ASSET_SOURCE, + COGNITE_CAD_NODE_SOURCE, + CogniteAssetProperties, + CogniteCADNodeProperties +} from './dataModels'; +import { getModelIdFromExternalId } from './getModelIdFromExternalId'; + +export async function getFdmConnectionsForNodes( + model: DmsUniqueIdentifier, + revisionRef: DmsUniqueIdentifier, + revisionId: number, + nodes: Node3D[], + fdmSdk: FdmSDK +): Promise { + const treeIndexes = nodes.map((node) => node.treeIndex); + const treeIndexSet = new Set(treeIndexes); + + const treeIndexToNodeIdMap = new Map(nodes.map((node) => [node.treeIndex, node.id])); + + const relevantCadNodeRefToObject3dRef = new Map(); + const treeIndexToCadNodeMap = new Map(); + + const query = { + ...cadConnectionQuery, + parameters: { modelReference: model, treeIndexes, revisionRef } + }; + + const modelId = getModelIdFromExternalId(model.externalId); + + const result = await fdmSdk.queryNodesAndEdges< + typeof query, + [ + { source: typeof COGNITE_ASSET_SOURCE; properties: CogniteAssetProperties }, + { source: typeof COGNITE_CAD_NODE_SOURCE; properties: CogniteCADNodeProperties }, + { source: typeof COGNITE_3D_OBJECT_SOURCE; properties: Cognite3DObjectProperties } + ] + >(query); + + result.items.cad_nodes.forEach((cadNode) => { + const props = cadNode.properties.cdf_cdm_experimental['CogniteCADNode/v1']; + const revisionIndex = props.revisions.findIndex((id) => id === revisionRef); + + const treeIndex = props.treeIndexes[revisionIndex]; + const relevant = treeIndexSet.has(treeIndex); + + if (relevant) { + relevantCadNodeRefToObject3dRef.set(toFdmKey(cadNode), toFdmKey(props.object3D)); + treeIndexToCadNodeMap.set(treeIndex, toFdmKey(cadNode)); + } + }); + + const relevantObjects3D = result.items.objects_3d.filter((object3D) => { + return ( + object3D.properties.cdf_cdm_experimental['CogniteObject3D/v1'] + .cadNodes as DmsUniqueIdentifier[] + ).some((cadNodeId) => relevantCadNodeRefToObject3dRef.has(toFdmKey(cadNodeId))); + }); + + const relevantObjectToAssetsMap = new Map( + relevantObjects3D.map((obj) => [ + toFdmKey(obj), + obj.properties.cdf_cdm_experimental['CogniteObject3D/v1'].asset + ]) + ); + + const connections = new Array(); + + [...treeIndexToCadNodeMap.entries()].forEach(([treeIndex, nodeRefKey]) => { + const object3dKey = relevantCadNodeRefToObject3dRef.get(nodeRefKey); + if (object3dKey === undefined) { + // Should not happen + return; + } + const assets = relevantObjectToAssetsMap.get(object3dKey); + + const nodeId = treeIndexToNodeIdMap.get(treeIndex); + + if (assets === undefined || nodeId === undefined) { + // Should not happen + return; + } + + assets.forEach((asset) => connections.push({ modelId, revisionId, nodeId, instance: asset })); + }); + + return connections; +} + +const cadConnectionQuery = { + with: { + cad_nodes: { + nodes: { + filter: { + and: [ + { + equals: { + property: [ + COGNITE_CAD_NODE_SOURCE.space, + COGNITE_CAD_NODE_SOURCE.externalId, + 'model3D' + ], + value: { parameter: 'modelReference' } + } + }, + { + containsAny: { + property: [ + COGNITE_CAD_NODE_SOURCE.space, + COGNITE_CAD_NODE_SOURCE.externalId, + 'treeIndexes' + ], + values: { parameter: 'treeIndexes' } + } + }, + { + containsAny: { + property: [ + COGNITE_CAD_NODE_SOURCE.space, + COGNITE_CAD_NODE_SOURCE.externalId, + 'revisions' + ], + values: { parameter: 'revisionRef' } + } + } + ] + } + } + }, + objects_3d: { + nodes: { + from: 'cad_nodes', + through: { source: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' } + } + }, + assets: { + nodes: { + from: 'objects_3d', + through: { source: COGNITE_3D_OBJECT_SOURCE, identifier: 'asset' }, + direction: 'outwards' + } + } + }, + select: { + cad_nodes: { + sources: [ + { + source: COGNITE_CAD_NODE_SOURCE, + properties: [ + 'name', + 'description', + 'tags', + 'aliases', + 'object3D', + 'model3D', + 'cadNodeReference', + 'revisions', + 'treeIndexes', + 'subTreeSizes' + ] + } + ] + }, + assets: {}, + objects_3d: { + sources: [{ source: COGNITE_3D_OBJECT_SOURCE, properties: ['name', 'asset', 'cadNodes'] }] + } + } +} as const satisfies Omit; + +function toFdmKey(dmsId: DmsUniqueIdentifier): FdmKey { + return `${dmsId.space}/${dmsId.externalId}`; +} diff --git a/react-components/src/data-providers/core-dm-provider/getModelIdFromExternalId.ts b/react-components/src/data-providers/core-dm-provider/getModelIdFromExternalId.ts new file mode 100644 index 00000000000..3e564f1bb9d --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/getModelIdFromExternalId.ts @@ -0,0 +1,4 @@ +export function getModelIdFromExternalId(externalId: string) { + // The externalId should be on the form `cog_3d_model_${modelId}` + return Number(externalId.slice('cog_3d_model_'.length)); +} diff --git a/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts b/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts new file mode 100644 index 00000000000..3482d66dd59 --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts @@ -0,0 +1,131 @@ +import { + DmsUniqueIdentifier, + FdmSDK, + InstanceFilter, + makeSureNonEmptyFilterForRequest, + NodeItem, + Source +} from '../FdmSDK'; +import { QueryRequest } from '@cognite/sdk'; +import { + COGNITE_3D_OBJECT_SOURCE, + COGNITE_ASSET_SOURCE, + COGNITE_CAD_NODE_SOURCE, + COGNITE_POINT_CLOUD_VOLUME, + CogniteAssetProperties +} from './dataModels'; +import { cogniteAssetSourceWithProperties } from './cogniteAssetSourceWithProperties'; + +export async function listAllMappedFdmNodes( + revisionRefs: DmsUniqueIdentifier[], + sourcesToSearch: Source[], + instancesFilter: InstanceFilter | undefined, + fdmSdk: FdmSDK +): Promise { + const filter = makeSureNonEmptyFilterForRequest(instancesFilter); + + const rawQuery = createRawQuery(sourcesToSearch, filter, 10000); + + const query = { + ...rawQuery, + parameters: { revisionRefs } + }; + + const queryResult = await fdmSdk.queryAllNodesAndEdges< + typeof query, + [{ source: typeof COGNITE_ASSET_SOURCE; properties: CogniteAssetProperties }] + >(query); + + return queryResult.items.cad_assets.concat(queryResult.items.pointcloud_assets); +} + +export async function listMappedFdmNodes( + revisionRefs: DmsUniqueIdentifier[], + sourcesToSearch: Source[], + instancesFilter: InstanceFilter | undefined, + limit: number, + fdmSdk: FdmSDK +): Promise { + const filter = makeSureNonEmptyFilterForRequest(instancesFilter); + + const rawQuery = createRawQuery(sourcesToSearch, filter, limit); + + const query = { + ...rawQuery, + parameters: { revisionRefs } + }; + + const queryResult = await fdmSdk.queryNodesAndEdges< + typeof query, + [{ source: typeof COGNITE_ASSET_SOURCE; properties: CogniteAssetProperties }] + >(query); + + return queryResult.items.cad_assets.concat(queryResult.items.pointcloud_assets); +} + +const containsRevisionFilter: InstanceFilter = { + containsAny: { + property: [COGNITE_CAD_NODE_SOURCE.space, COGNITE_CAD_NODE_SOURCE.externalId, 'revisions'], + values: { parameter: 'revisionRefs' } + } +} as const; + +function createRawQuery( + sourcesToSearch: Source[], + filter: InstanceFilter | undefined, + limit: number +) { + return { + with: { + cad_nodes: { + nodes: { + filter: containsRevisionFilter + }, + limit + }, + cad_object_3d: { + nodes: { + from: 'cad_nodes', + through: { source: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' } + } + }, + cad_assets: { + nodes: { + from: 'cad_object_3d', + through: { source: COGNITE_3D_OBJECT_SOURCE, identifier: 'asset' }, + filter + } + }, + pointcloud_volumes: { + nodes: { + filter: containsRevisionFilter + }, + limit + }, + pointcloud_object_3d: { + nodes: { + from: 'pointcloud_volumes', + through: { source: COGNITE_POINT_CLOUD_VOLUME, identifier: 'object3D' } + } + }, + pointcloud_assets: { + nodes: { + from: 'cad_object_3d', + through: { source: COGNITE_3D_OBJECT_SOURCE, identifier: 'asset' }, + filter + } + } + }, + select: { + cad_assets: { + sources: [ + ...cogniteAssetSourceWithProperties, + ...sourcesToSearch.map((source) => ({ source, properties: ['*'] })) + ] + }, + pointcloud_assets: { + sources: cogniteAssetSourceWithProperties + } + } + } as const satisfies Omit; +} diff --git a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts index c56e1315a94..a9ae2aa0bf4 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts @@ -15,12 +15,13 @@ import { import { type InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; import { type TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; import { getEdgeConnected3dInstances } from './getEdgeConnected3dInstances'; -import { getFdmConnectionsForNodeIds } from './getFdmConnectionsForNodeIds'; +import { getFdmConnectionsForNodes } from './getFdmConnectionsForNodeIds'; import { getDMSModels } from './getDMSModels'; import { listAllMappedFdmNodes, listMappedFdmNodes } from './listMappedFdmNodes'; import { filterNodesByMappedTo3d } from './filterNodesByMappedTo3d'; import { getCadModelsForFdmInstance } from './getCadModelsForFdmInstance'; import { getCadConnectionsForRevision } from './getCadConnectionsForRevision'; +import { Node3D } from '@cognite/sdk/dist/src'; export class LegacyFdm3dDataProvider implements Fdm3dDataProvider { readonly _fdmSdk: FdmSDK; @@ -38,15 +39,15 @@ export class LegacyFdm3dDataProvider implements Fdm3dDataProvider { } async getEdgeConnected3dInstances(instance: DmsUniqueIdentifier): Promise { - return await getEdgeConnected3dInstances(this._fdmSdk, instance); + return await getEdgeConnected3dInstances(instance, this._fdmSdk); } - async getFdmConnectionsForNodeIds( + async getFdmConnectionsForNodes( models: DmsUniqueIdentifier[], revisionId: number, - nodeIds: number[] + nodes: Node3D[] ): Promise { - return await getFdmConnectionsForNodeIds(this._fdmSdk, models, revisionId, nodeIds); + return await getFdmConnectionsForNodes(this._fdmSdk, models, revisionId, nodes); } async listMappedFdmNodes( diff --git a/react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts b/react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts index 73dfe12fad1..db6586290f0 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts @@ -2,13 +2,9 @@ * Copyright 2024 Cognite AS */ import { type AddModelOptions } from '@cognite/reveal'; -import { - makeSureNonEmptyFilterForRequest, - type InstanceFilter, - type Query, - type Source -} from '../FdmSDK'; +import { makeSureNonEmptyFilterForRequest, type InstanceFilter, type Source } from '../FdmSDK'; import { SYSTEM_3D_EDGE_SOURCE } from './dataModels'; +import { QueryRequest } from '@cognite/sdk'; export function createMappedEquipmentQuery( models: AddModelOptions[], @@ -16,7 +12,7 @@ export function createMappedEquipmentQuery( instanceFilter: InstanceFilter | undefined, limit: number = 10000, cursors?: Record -): Query { +): QueryRequest { instanceFilter = makeSureNonEmptyFilterForRequest(instanceFilter); return { diff --git a/react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts index 161e0b0d3bd..35bc8284393 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts @@ -9,12 +9,13 @@ import { type ExternalId, type FdmSDK, type NodeItem, - type Query, type Source } from '../FdmSDK'; import { SYSTEM_3D_EDGE_SOURCE, SYSTEM_SPACE_3D_SCHEMA } from './dataModels'; import { getDMSModels } from './getDMSModels'; import { type FdmKey } from '../../components/CacheProvider/types'; +import { QueryRequest } from '@cognite/sdk/dist/src'; +import { getDirectRelationProperties } from '../utils/getDirectRelationProperties'; export async function filterNodesByMappedTo3d( fdmSdk: FdmSDK, @@ -29,7 +30,7 @@ export async function filterNodesByMappedTo3d( return nodesWithViews; } - const directlyMappedNodes = nodes.map((node) => getDirectRelationProperties(node)).flat(); + const directlyMappedNodes = nodes.flatMap((node) => getDirectRelationProperties(node)); const mappedEquipmentQuery = createCheckMappedEquipmentQuery( nodes, @@ -37,7 +38,8 @@ export async function filterNodesByMappedTo3d( models, views ); - const queryResult = await fdmSdk.queryNodesAndEdges(mappedEquipmentQuery); + const queryResult = + await fdmSdk.queryNodesAndEdges(mappedEquipmentQuery); const { mappedEquipmentFirstLevelMap, equipmentSecondLevelMap } = await createMappedEquipmentMaps( fdmSdk, @@ -69,7 +71,7 @@ function createCheckMappedEquipmentQuery( models: AddModelOptions[], views: Source[], limit: number = 1000 -): Query { +) { return { with: { mapped_nodes: { @@ -108,7 +110,7 @@ function createCheckMappedEquipmentQuery( sources: views.map((view) => ({ source: view, properties: [] })) } } - }; + } as const satisfies Omit; } async function createMappedEquipmentMaps( @@ -213,18 +215,3 @@ function checkInstanceWithMappedEquipmentMaps( return false; } - -function getDirectRelationProperties(searchResultNode: NodeItem): DmsUniqueIdentifier[] { - const directRelations: DmsUniqueIdentifier[] = []; - const nodeProperties = searchResultNode.properties; - - Object.keys(nodeProperties).forEach((propertyKey) => { - const { space, externalId } = nodeProperties[propertyKey] as any; - - if (space !== undefined && externalId !== undefined) { - directRelations.push({ space, externalId }); - } - }); - - return directRelations; -} diff --git a/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts b/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts index 4ea8c044b6d..f1d8643fb1f 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts @@ -3,10 +3,11 @@ */ import { SYSTEM_3D_EDGE_SOURCE } from './dataModels'; import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; +import { QueryRequest } from '@cognite/sdk/dist/src'; export async function getEdgeConnected3dInstances( - fdmSdk: FdmSDK, - instance: DmsUniqueIdentifier + instance: DmsUniqueIdentifier, + fdmSdk: FdmSDK ): Promise { const nodesResult = await fdmSdk.queryNodesAndEdges({ ...related3dEdgesQuery, @@ -90,4 +91,4 @@ const related3dEdgesQuery = { edges_of_3d_type: {}, nodes_with_3d_connection: {} } -} as const; +} as const satisfies Omit; diff --git a/react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts b/react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts index ad3bd5206c5..46bf733634c 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts @@ -1,18 +1,20 @@ /*! * Copyright 2024 Cognite AS */ -import { type CogniteInternalId } from '@cognite/sdk/dist/src'; +import { Node3D } from '@cognite/sdk'; import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { type FdmCadConnection } from '../../components/CacheProvider/types'; import { type InModel3dEdgeProperties, SYSTEM_3D_EDGE_SOURCE } from './dataModels'; import { fdmEdgesToCadConnections } from './fdmEdgesToCadConnections'; -export async function getFdmConnectionsForNodeIds( +export async function getFdmConnectionsForNodes( fdmClient: FdmSDK, models: DmsUniqueIdentifier[], revisionId: number, - nodeIds: CogniteInternalId[] + nodes: Node3D[] ): Promise { + const nodeIds = nodes.map((node) => node.id); + const filter = { and: [ { diff --git a/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts b/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts index 57f1369875d..3648326a424 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts @@ -12,6 +12,7 @@ import { import { createMappedEquipmentQuery } from './createMappedEquipmentQuery'; import { chunk, isEqual } from 'lodash'; import { removeEmptyProperties } from '../../utilities/removeEmptyProperties'; +import { QueryRequest } from '@cognite/sdk/dist/src'; export async function listMappedFdmNodes( fdmSdk: FdmSDK, @@ -68,7 +69,7 @@ function createChunkedMappedEquipmentQueries( views: Source[], limit: number = 10000, cursors?: Record -): Query[] { +): QueryRequest[] { const viewChunks = chunk(views, 10); return viewChunks.map((viewChunk) => createMappedEquipmentQuery(models, viewChunk, undefined, limit, cursors) diff --git a/react-components/src/data-providers/mergeQueryResult.ts b/react-components/src/data-providers/mergeQueryResult.ts new file mode 100644 index 00000000000..5c82aa86694 --- /dev/null +++ b/react-components/src/data-providers/mergeQueryResult.ts @@ -0,0 +1,11 @@ +function mergeQueryResults>(dst: T, src: T): T { + [...Object.keys(src)].forEach((key0) => { + if (!(key0 in dst)) { + Object.assign(dst, key0, []); + } + + dst[key0].push(...src[key0]); + }); + + return dst; +} diff --git a/react-components/src/data-providers/queryNodesAndEdges.ts b/react-components/src/data-providers/queryNodesAndEdges.ts new file mode 100644 index 00000000000..e0b5e6c9e3e --- /dev/null +++ b/react-components/src/data-providers/queryNodesAndEdges.ts @@ -0,0 +1,93 @@ +import type { + EdgeDefinition, + NodeDefinition, + NodeOrEdge, + CogniteClient, + QueryRequest +} from '@cognite/sdk'; + +// This function should be removed once the SDK is updated to include the function +export async function queryNodesAndEdges< + TQueryRequest extends QueryRequest, + TypedSelectSources extends SelectSourceWithParams = SelectSourceWithParams +>( + query: TQueryRequest, + sdk: CogniteClient +): Promise> { + const response = await sdk.instances.query(query); + return response as QueryResult; +} + +type SELECT = 'select'; +type WITH = 'with'; +type LIMIT = 'limit'; +type NODES = 'nodes'; +type EDGES = 'edges'; +type PROPERTIES = 'properties'; +type SOURCES = 'sources'; +type SOURCE = 'source'; +type SPACE = 'space'; +type EXTERNALID = 'externalId'; +type VERSION = 'version'; +type ALLPROPERTIES = '*'; + +export type InstanceType< + TQueryRequest extends QueryRequest, + SelectKey extends keyof TQueryRequest[SELECT] +> = + Exclude extends NODES + ? Omit + : Exclude extends EDGES + ? Omit + : Omit; + +export type TypedSourceProperty< + SelectSource extends NonNullable< + QueryRequest[SELECT][keyof QueryRequest[SELECT]][SOURCES] + >[number], + TypedSelectSourcePropertyMap extends SelectSourceWithParams = SelectSourceWithParams +> = Extract>[PROPERTIES]; + +export type SelectSourceWithParams = Array<{ + source: { + type: string; + space: string; + externalId: string; + version: string; + }; + properties: Record; +}>; + +export type QueryResult< + TQueryRequest extends QueryRequest, + TSelectSourceWithParams extends SelectSourceWithParams = SelectSourceWithParams +> = { + items: { + [SELECT_KEY in keyof TQueryRequest[SELECT]]: Array< + InstanceType & { + properties: { + [SELECT_SOURCE in NonNullable< + TQueryRequest[SELECT][SELECT_KEY][SOURCES] + >[number] as SELECT_SOURCE[SOURCE][SPACE]]: { + [SELECT_SOURCE_VAR in SELECT_SOURCE as `${SELECT_SOURCE_VAR[SOURCE][EXTERNALID]}/${SELECT_SOURCE_VAR[SOURCE][VERSION]}`]: SELECT_SOURCE_VAR[PROPERTIES][0] extends ALLPROPERTIES + ? Record + : { + [SELECT_SOURCE_PROPERTY in SELECT_SOURCE_VAR[PROPERTIES][number]]: TypedSourceProperty< + SELECT_SOURCE_VAR, + TSelectSourceWithParams + >[SELECT_SOURCE_PROPERTY] extends never + ? unknown + : TypedSourceProperty< + SELECT_SOURCE_VAR, + TSelectSourceWithParams + >[SELECT_SOURCE_PROPERTY]; + }; + }; + }; + } + >; + }; + nextCursor?: { + [SELECT_SOURCE_KEY in keyof TQueryRequest[SELECT]]: string; + }; +}; diff --git a/react-components/src/data-providers/utils/getDirectRelationProperties.ts b/react-components/src/data-providers/utils/getDirectRelationProperties.ts new file mode 100644 index 00000000000..24075ee73b8 --- /dev/null +++ b/react-components/src/data-providers/utils/getDirectRelationProperties.ts @@ -0,0 +1,16 @@ +import { DmsUniqueIdentifier, NodeItem } from '../FdmSDK'; + +export function getDirectRelationProperties(searchResultNode: NodeItem): DmsUniqueIdentifier[] { + const directRelations: DmsUniqueIdentifier[] = []; + const nodeProperties = searchResultNode.properties; + + Object.keys(nodeProperties).forEach((propertyKey) => { + const { space, externalId } = nodeProperties[propertyKey] as any; + + if (space !== undefined && externalId !== undefined) { + directRelations.push({ space, externalId }); + } + }); + + return directRelations; +} diff --git a/react-components/src/utilities/executeParallel.ts b/react-components/src/utilities/executeParallel.ts new file mode 100644 index 00000000000..570121ef886 --- /dev/null +++ b/react-components/src/utilities/executeParallel.ts @@ -0,0 +1,27 @@ +export async function executeParallel( + callbacks: Array<() => Promise>, + maxParallel: number +): Promise> { + const resultArray = new Array(callbacks.length).fill(undefined); + + let nextCallback = 0; + + const resultFillingCallbacks = callbacks.map( + (callback, ind) => () => callback().then((value) => (resultArray[ind] = value)) + ); + + async function scheduleNext(): Promise { + if (nextCallback >= resultArray.length) { + return; + } + + nextCallback++; + + await resultFillingCallbacks[nextCallback](); + return scheduleNext(); + } + + const scheduleChains = new Array(maxParallel).fill(0).map(() => scheduleNext()); + await Promise.all(scheduleChains); + return resultArray; +} From ed7844fe478ad4aca19662b26942837e17d56754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Mon, 19 Aug 2024 16:02:56 +0200 Subject: [PATCH 02/32] feat: implement filterNodesByMappedTo3d --- react-components/src/data-providers/FdmSDK.ts | 8 +- .../core-dm-provider/CoreDm3dDataProvider.ts | 18 +- .../cogniteCadNodeSourceWithProperties.ts | 20 ++ .../cogniteObject3dSourceWithProperties.ts | 24 +++ .../core-dm-provider/dataModels.ts | 4 +- .../filterNodesByMappedTo3d.ts | 198 ++++++++++++++++-- .../getCadModelsForInstance.ts | 8 + .../getFdmConnectionsForNodeIds.ts | 4 - .../core-dm-provider/listMappedFdmNodes.ts | 4 +- .../{ => utils}/mergeQueryResult.ts | 0 .../{ => utils}/queryNodesAndEdges.ts | 0 .../src/data-providers/utils/toFdmKey.ts | 6 + .../src/data-providers/utils/typeUtils.ts | 6 + 13 files changed, 269 insertions(+), 31 deletions(-) create mode 100644 react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts create mode 100644 react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts create mode 100644 react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts rename react-components/src/data-providers/{ => utils}/mergeQueryResult.ts (100%) rename react-components/src/data-providers/{ => utils}/queryNodesAndEdges.ts (100%) create mode 100644 react-components/src/data-providers/utils/toFdmKey.ts create mode 100644 react-components/src/data-providers/utils/typeUtils.ts diff --git a/react-components/src/data-providers/FdmSDK.ts b/react-components/src/data-providers/FdmSDK.ts index 44fcc97682a..ff1e812410b 100644 --- a/react-components/src/data-providers/FdmSDK.ts +++ b/react-components/src/data-providers/FdmSDK.ts @@ -4,7 +4,11 @@ import { QueryRequest, TableExpressionFilterDefinition, type CogniteClient } from '@cognite/sdk'; import { type FdmPropertyType } from '../components/Reveal3DResources/types'; -import { queryNodesAndEdges, QueryResult, SelectSourceWithParams } from './queryNodesAndEdges'; +import { + queryNodesAndEdges, + QueryResult, + SelectSourceWithParams +} from './utils/queryNodesAndEdges'; type InstanceType = 'node' | 'edge'; type EdgeDirection = 'source' | 'destination'; @@ -194,7 +198,6 @@ export class FdmSDK { private readonly _listEndpoint: string; private readonly _inspectEndpoint: string; private readonly _searchEndpoint: string; - private readonly _queryEndpoint: string; private readonly _listViewsEndpoint: string; private readonly _viewsByIdEndpoint: string; private readonly _listDataModelsEndpoint: string; @@ -209,7 +212,6 @@ export class FdmSDK { const viewsBaseUrl = `${baseUrl}/api/v1/projects/${project}/models/views`; this._listEndpoint = `${instancesBaseUrl}/list`; - this._queryEndpoint = `${instancesBaseUrl}/query`; this._byIdsEndpoint = `${instancesBaseUrl}/byids`; this._inspectEndpoint = `${instancesBaseUrl}/inspect`; this._searchEndpoint = `${instancesBaseUrl}/search`; diff --git a/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts b/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts index 93eabe3bcd1..faa037e3969 100644 --- a/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts +++ b/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts @@ -1,4 +1,4 @@ -import { AddModelOptions, isDefaultCameraManager } from '@cognite/reveal'; +import { AddModelOptions } from '@cognite/reveal'; import { FdmCadConnection } from '../../components/CacheProvider/types'; import { Fdm3dDataProvider } from '../Fdm3dDataProvider'; import { DmsUniqueIdentifier, FdmSDK, InstanceFilter, NodeItem, Source, ViewItem } from '../FdmSDK'; @@ -10,11 +10,10 @@ import { getEdgeConnected3dInstances } from './getEdgeConnected3dInstances'; import { getFdmConnectionsForNodes } from './getFdmConnectionsForNodeIds'; import { Node3D } from '@cognite/sdk'; import { getDMSRevision } from './getDMSRevision'; -import assert from 'assert'; import { listAllMappedFdmNodes, listMappedFdmNodes } from './listMappedFdmNodes'; import { isDefined } from '../../utilities/isDefined'; import { executeParallel } from '../../utilities/executeParallel'; -import { zip } from 'lodash'; +import { filterNodesByMappedTo3d } from './filterNodesByMappedTo3d'; const MAX_PARALLEL_QUERIES = 2; @@ -151,11 +150,20 @@ export class CoreDm3dFdm3dDataProvider implements Fdm3dDataProvider { return listAllMappedFdmNodes(revisionRefs, sourcesToSearch, instanceFilter, this._fdmSdk); } - filterNodesByMappedTo3d( + async filterNodesByMappedTo3d( nodes: InstancesWithView[], models: AddModelOptions[], spacesToSearch: string[] - ): Promise {} + ): Promise { + const modelRefs = await this.getDMSModelsForIds(models.map((model) => model.modelId)); + + const revisionRefs = await this.getDMSRevisionsForRevisionIdsAndModelRefs( + modelRefs, + models.map((model) => model.revisionId) + ); + + return filterNodesByMappedTo3d(nodes, revisionRefs, spacesToSearch, this._fdmSdk); + } getCadModelsForInstance(instance: DmsUniqueIdentifier): Promise {} diff --git a/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts new file mode 100644 index 00000000000..2a858922f20 --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts @@ -0,0 +1,20 @@ +import { SourceSelectorV3 } from '@cognite/sdk/dist/src'; +import { COGNITE_CAD_NODE_SOURCE } from './dataModels'; + +export const cogniteCadNodeSourceWithPRoperties = [ + { + source: COGNITE_CAD_NODE_SOURCE, + properties: [ + 'name', + 'description', + 'tags', + 'aliases', + 'object3D', + 'model3D', + 'cadNodeReference', + 'revisions', + 'treeIndexes', + 'subTreeSizes' + ] + } +] as const satisfies SourceSelectorV3; diff --git a/react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts new file mode 100644 index 00000000000..7b33ec31577 --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts @@ -0,0 +1,24 @@ +import { SourceSelectorV3 } from '@cognite/sdk/dist/src'; +import { COGNITE_3D_OBJECT_SOURCE } from './dataModels'; + +export const cogniteObject3dSourceWithProperties = [ + { + source: COGNITE_3D_OBJECT_SOURCE, + properties: [ + 'name', + 'description', + 'tags', + 'aliases', + 'xMin', + 'xMax', + 'yMin', + 'yMax', + 'zMin', + 'zMax', + 'asset', + 'cadNodes', + 'images360', + 'pointCloudVolumes' + ] + } +] as const satisfies SourceSelectorV3; diff --git a/react-components/src/data-providers/core-dm-provider/dataModels.ts b/react-components/src/data-providers/core-dm-provider/dataModels.ts index 8b5bc7163d7..0a6cbb87014 100644 --- a/react-components/src/data-providers/core-dm-provider/dataModels.ts +++ b/react-components/src/data-providers/core-dm-provider/dataModels.ts @@ -1,4 +1,4 @@ -import { DateRange, Timestamp, ViewReference } from '@cognite/sdk'; +import { Timestamp, ViewReference } from '@cognite/sdk'; import { DmsUniqueIdentifier, Source } from '../FdmSDK'; export const CORE_DM_SPACE = 'cdf_cdm_experimental'; @@ -55,7 +55,7 @@ export const COGNITE_VISUALIZABLE_SOURCE = { type: 'view' } as const satisfies ViewReference; -export const COGNITE_POINT_CLOUD_VOLUME = { +export const COGNITE_POINT_CLOUD_VOLUME_SOURCE = { externalId: 'CognitePointCloudVolume', space: CORE_DM_SPACE, version: 'v1', diff --git a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts index fdd77be08c1..bbc0be467b5 100644 --- a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts +++ b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts @@ -1,16 +1,97 @@ import { AddModelOptions } from '@cognite/reveal'; import { InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; -import { QueryRequest, QueryTableExpressionV3 } from '@cognite/sdk/dist/src'; +import { QueryRequest, QueryTableExpressionV3, SourceSelectorV3 } from '@cognite/sdk/dist/src'; import { getDirectRelationProperties } from '../utils/getDirectRelationProperties'; -import { COGNITE_3D_OBJECT_SOURCE, COGNITE_VISUALIZABLE_SOURCE } from './dataModels'; -import { cogniteAssetSourceWithProperties } from './cogniteAssetSourceWithProperties'; -import { DmsUniqueIdentifier } from '../FdmSDK'; +import { + Cognite3DObjectProperties, + COGNITE_3D_OBJECT_SOURCE, + COGNITE_CAD_NODE_SOURCE, + COGNITE_POINT_CLOUD_VOLUME_SOURCE, + COGNITE_VISUALIZABLE_SOURCE +} from './dataModels'; +import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; +import { cogniteObject3dSourceWithProperties } from './cogniteObject3dSourceWithProperties'; +import { FdmKey } from '../../components/CacheProvider/types'; +import { toFdmKey } from '../utils/toFdmKey'; +import { ArrayElement, PromiseType } from '../utils/typeUtils'; +import { head } from 'lodash'; -export function filterNodesByMappedTo3d( +export async function filterNodesByMappedTo3d( nodes: InstancesWithView[], revisionRefs: DmsUniqueIdentifier[], - spacesToSearch: string[] + spacesToSearch: string[], + fdmSdk: FdmSDK ): Promise { + const connectionData = await fetchConnectionData(nodes, revisionRefs, fdmSdk); + + const assetKeys: Set = createRelevantAssetKeySet(connectionData); + + return nodes.map((viewWithNodes) => ({ + view: viewWithNodes.view, + instances: viewWithNodes.instances.filter((instance) => assetKeys.has(toFdmKey(instance))) + })); +} + +function createRelevantAssetKeySet( + connectionData: PromiseType> +): Set { + const cadNodeSet = new Set( + new Array() + .concat(connectionData.items.initial_nodes_cad_nodes) + .concat(connectionData.items.direct_nodes_cad_nodes) + .concat(connectionData.items.indirect_nodes_cad_nodes) + .map(toFdmKey) + ); + + const pointCloudNodeSet = new Set( + new Array() + .concat(connectionData.items.initial_nodes_point_cloud_volumes) + .concat(connectionData.items.direct_nodes_point_cloud_volumes) + .concat(connectionData.items.indirect_nodes_point_cloud_volumes) + .map(toFdmKey) + ); + + const relevantObject3Ds = new Array< + ArrayElement + >() + .concat(connectionData.items.initial_nodes_object_3ds) + .concat(connectionData.items.direct_nodes_object_3ds) + .concat(connectionData.items.indirect_nodes_object_3ds) + .filter((object3d) => { + const props = object3d.properties.cdf_cdm_experimental['CogniteObject3D/v1']; + return ( + props.cadNodes.some((node) => cadNodeSet.has(toFdmKey(node))) || + props.pointCloudVolumes.some((node) => pointCloudNodeSet.has(toFdmKey(node))) + ); + }); + + const relevantAssetKeySet = relevantObject3Ds.reduce((acc, object3D) => { + // Assume at most one connected asset + const firstAsset = head(object3D.properties.cdf_cdm_experimental['CogniteObject3D/v1'].asset); + if (firstAsset === undefined) { + return acc; + } + acc.add(toFdmKey(firstAsset)); + return acc; + }, new Set()); + + // Append relevant edge start nodes directly to previous set + connectionData.items.indirectly_referenced_edges.reduce((acc, edge) => { + if (relevantAssetKeySet.has(toFdmKey(edge.endNode))) { + acc.add(toFdmKey(edge.startNode)); + } + + return acc; + }, relevantAssetKeySet); + + return relevantAssetKeySet; +} + +async function fetchConnectionData( + nodes: InstancesWithView[], + revisionRefs: DmsUniqueIdentifier[], + fdmSdk: FdmSDK +) { const initialExternalIds = nodes.flatMap((node) => node.instances.map((instance) => instance.externalId) ); @@ -25,9 +106,35 @@ export function filterNodesByMappedTo3d( ...checkEquipmentFilter, parameters }; + + return fdmSdk.queryAllNodesAndEdges< + typeof query, + [ + { source: typeof COGNITE_3D_OBJECT_SOURCE; properties: Cognite3DObjectProperties }, + { source: typeof COGNITE_CAD_NODE_SOURCE; properties: { object3D: DmsUniqueIdentifier } }, + { + source: typeof COGNITE_POINT_CLOUD_VOLUME_SOURCE; + properties: { object3D: DmsUniqueIdentifier }; + } + ] + >(query); } -const checkEquipmentFilter: QueryRequest = { +const pointCloudVolumeSourceWithProperties = [ + { + source: COGNITE_POINT_CLOUD_VOLUME_SOURCE, + properties: ['object3D'] + } +] as const satisfies SourceSelectorV3; + +const cadNodeSourceWithProperties = [ + { + source: COGNITE_CAD_NODE_SOURCE, + properties: ['object3D'] + } +] as const satisfies SourceSelectorV3; + +const checkEquipmentFilter = { with: { initial_nodes: { nodes: { @@ -63,7 +170,7 @@ const checkEquipmentFilter: QueryRequest = { } } }, - indirectly_referenced_nodes: { + indirectly_referenced_edges: { edges: { from: 'initial_nodes', direction: 'outwards', @@ -72,19 +179,80 @@ const checkEquipmentFilter: QueryRequest = { } } }, + indirectly_referenced_nodes: { + nodes: { + from: 'indirectly_referenced_edges' + } + }, initial_nodes_object_3ds: getObject3dRelation('initial_nodes'), - initial_nodes_assets: getAssetRelation('initial_nodes_object_3ds'), + initial_nodes_cad_nodes: getRevisionsCadNodeFromObject3D('initial_nodes_object_3ds'), + initial_nodes_point_cloud_volumes: getRevisionsPointCloudVolumes('initial_nodes_object_3ds'), direct_nodes_object_3ds: getObject3dRelation('directly_referenced_nodes'), - direct_nodes_assets: getAssetRelation('direct_nodes_object_3ds'), + direct_nodes_cad_nodes: getRevisionsCadNodeFromObject3D('direct_nodes_object_3ds'), + direct_nodes_point_cloud_volumes: getRevisionsPointCloudVolumes('direct_nodes_object_3ds'), indirect_nodes_object_3ds: getObject3dRelation('indirectly_referenced_nodes'), - indirect_nodes_assets: getAssetRelation('indirect_nodes_object_3ds') + indirect_nodes_cad_nodes: getRevisionsCadNodeFromObject3D('indirect_nodes_object_3ds'), + indirect_nodes_point_cloud_volumes: getRevisionsPointCloudVolumes('indirect_nodes_object_3ds') }, select: { - initial_nodes_assets: { sources: cogniteAssetSourceWithProperties }, - direct_nodes_assets: { sources: cogniteAssetSourceWithProperties }, - indirect_nodes_assets: { sources: cogniteAssetSourceWithProperties } + indirectly_referenced_edges: {}, + initial_nodes_object_3ds: { sources: cogniteObject3dSourceWithProperties }, + initial_nodes_cad_nodes: { + sources: cadNodeSourceWithProperties + }, + initial_nodes_point_cloud_volumes: { sources: pointCloudVolumeSourceWithProperties }, + direct_nodes_object_3ds: { sources: cogniteObject3dSourceWithProperties }, + direct_nodes_cad_nodes: { + sources: cadNodeSourceWithProperties + }, + direct_nodes_point_cloud_volumes: { sources: pointCloudVolumeSourceWithProperties }, + indirect_nodes_object_3ds: { sources: cogniteObject3dSourceWithProperties }, + indirect_nodes_cad_nodes: { + sources: cadNodeSourceWithProperties + }, + indirect_nodes_point_cloud_volumes: { + sources: pointCloudVolumeSourceWithProperties + } } -}; // as const satisfies Omit; +} as const satisfies Omit; + +function getRevisionsCadNodeFromObject3D(object3dTableName: string): QueryTableExpressionV3 { + return { + nodes: { + from: object3dTableName, + through: { source: COGNITE_3D_OBJECT_SOURCE, identifier: 'cadNodes' }, + filter: { + containsAny: { + property: [ + COGNITE_CAD_NODE_SOURCE.space, + COGNITE_CAD_NODE_SOURCE.externalId, + 'revisions' + ], + values: { parameter: 'revisionRefs' } + } + } + } + }; +} + +function getRevisionsPointCloudVolumes(object3dTableName: string): QueryTableExpressionV3 { + return { + nodes: { + from: object3dTableName, + through: { source: COGNITE_3D_OBJECT_SOURCE, identifier: 'pointCloudVolumes' }, + filter: { + containsAny: { + property: [ + COGNITE_POINT_CLOUD_VOLUME_SOURCE.space, + COGNITE_POINT_CLOUD_VOLUME_SOURCE.externalId, + 'revisions' + ], + values: { parameter: 'revisionRefs' } + } + } + } + }; +} function getObject3dRelation(visualizableTableName: string): QueryTableExpressionV3 { return { diff --git a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts new file mode 100644 index 00000000000..d61bc6ce446 --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts @@ -0,0 +1,8 @@ +import { TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; +import { DmsUniqueIdentifier } from '../FdmSDK'; + +export async function getCadModelsForInstance( + instance: DmsUniqueIdentifier +): Promise { + return []; +} diff --git a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts index 74a4bb57e4a..b421a69ef1e 100644 --- a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts +++ b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts @@ -172,7 +172,3 @@ const cadConnectionQuery = { } } } as const satisfies Omit; - -function toFdmKey(dmsId: DmsUniqueIdentifier): FdmKey { - return `${dmsId.space}/${dmsId.externalId}`; -} diff --git a/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts b/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts index 3482d66dd59..4d74dc97f54 100644 --- a/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts +++ b/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts @@ -11,7 +11,7 @@ import { COGNITE_3D_OBJECT_SOURCE, COGNITE_ASSET_SOURCE, COGNITE_CAD_NODE_SOURCE, - COGNITE_POINT_CLOUD_VOLUME, + COGNITE_POINT_CLOUD_VOLUME_SOURCE, CogniteAssetProperties } from './dataModels'; import { cogniteAssetSourceWithProperties } from './cogniteAssetSourceWithProperties'; @@ -105,7 +105,7 @@ function createRawQuery( pointcloud_object_3d: { nodes: { from: 'pointcloud_volumes', - through: { source: COGNITE_POINT_CLOUD_VOLUME, identifier: 'object3D' } + through: { source: COGNITE_POINT_CLOUD_VOLUME_SOURCE, identifier: 'object3D' } } }, pointcloud_assets: { diff --git a/react-components/src/data-providers/mergeQueryResult.ts b/react-components/src/data-providers/utils/mergeQueryResult.ts similarity index 100% rename from react-components/src/data-providers/mergeQueryResult.ts rename to react-components/src/data-providers/utils/mergeQueryResult.ts diff --git a/react-components/src/data-providers/queryNodesAndEdges.ts b/react-components/src/data-providers/utils/queryNodesAndEdges.ts similarity index 100% rename from react-components/src/data-providers/queryNodesAndEdges.ts rename to react-components/src/data-providers/utils/queryNodesAndEdges.ts diff --git a/react-components/src/data-providers/utils/toFdmKey.ts b/react-components/src/data-providers/utils/toFdmKey.ts new file mode 100644 index 00000000000..6a67b8c42ba --- /dev/null +++ b/react-components/src/data-providers/utils/toFdmKey.ts @@ -0,0 +1,6 @@ +import { FdmKey } from '../../components/CacheProvider/types'; +import { DmsUniqueIdentifier } from '../FdmSDK'; + +export function toFdmKey(dmsId: DmsUniqueIdentifier): FdmKey { + return `${dmsId.space}/${dmsId.externalId}`; +} diff --git a/react-components/src/data-providers/utils/typeUtils.ts b/react-components/src/data-providers/utils/typeUtils.ts new file mode 100644 index 00000000000..a53a5b0841c --- /dev/null +++ b/react-components/src/data-providers/utils/typeUtils.ts @@ -0,0 +1,6 @@ +// From https://stackoverflow.com/questions/41253310/typescript-retrieve-element-type-information-from-array-type +export type ArrayElement = + ArrayType extends readonly (infer ElementType)[] ? ElementType : never; + +export type PromiseType> = + PromiseType extends Promise ? ElementType : never; From cffafb7fbc6785cdb2c6356cbb6de655c83d9889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Tue, 20 Aug 2024 11:29:31 +0200 Subject: [PATCH 03/32] chore: finish last two requests --- .../AssetMappingAndNode3DCache.ts | 8 +- .../AssetMappingPerNodeIdCache.ts | 13 +- .../components/CacheProvider/FdmNodeCache.ts | 82 +++++----- .../CacheProvider/Node3DPerNodeIdCache.ts | 8 +- .../CacheProvider/RevisionFdmNodeCache.ts | 2 +- .../CacheProvider/idAndKeyTranslation.ts | 28 ++-- .../src/components/CacheProvider/requests.ts | 1 + .../src/components/CacheProvider/types.ts | 6 +- .../src/components/CacheProvider/utils.ts | 4 +- .../src/data-providers/Fdm3dDataProvider.ts | 2 +- .../core-dm-provider/CoreDm3dDataProvider.ts | 25 +++- .../core-dm-provider/Duplex3dDataProvider.ts | 4 +- .../getCadConnectionsForRevisions.ts | 141 ++++++++++++++++++ .../getCadModelsForInstance.ts | 65 +++++++- .../getCdfIdFromExternalId.ts | 9 ++ .../getFdmConnectionsForNodeIds.ts | 11 +- .../getModelIdFromExternalId.ts | 4 - .../LegacyFdm3dDataProvider.ts | 6 +- .../getCadConnectionsForRevision.ts | 7 +- .../stories/CadStylingCache.stories.tsx | 20 +-- .../utilities/getAddModelOptionsFromUrl.ts | 4 +- 21 files changed, 350 insertions(+), 100 deletions(-) create mode 100644 react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts create mode 100644 react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts delete mode 100644 react-components/src/data-providers/core-dm-provider/getModelIdFromExternalId.ts diff --git a/react-components/src/components/CacheProvider/AssetMappingAndNode3DCache.ts b/react-components/src/components/CacheProvider/AssetMappingAndNode3DCache.ts index e0f36c22c81..80c553249a0 100644 --- a/react-components/src/components/CacheProvider/AssetMappingAndNode3DCache.ts +++ b/react-components/src/components/CacheProvider/AssetMappingAndNode3DCache.ts @@ -9,7 +9,7 @@ import { type CogniteInternalId } from '@cognite/sdk'; import { - type ModelNodeIdKey, + type ModelTreeIndexKey, type AssetId, type ModelId, type RevisionId, @@ -195,7 +195,7 @@ export class AssetMappingAndNode3DCache { private async getItemCacheResult( type: string, - key: ModelNodeIdKey | ModelAssetIdKey + key: ModelTreeIndexKey | ModelAssetIdKey ): Promise { return type === 'nodeIds' ? await this.nodeIdsToAssetMappingCache.getNodeIdsToAssetMappingCacheItem(key) @@ -204,7 +204,7 @@ export class AssetMappingAndNode3DCache { private setItemCacheResult( type: string, - key: ModelNodeIdKey | ModelAssetIdKey, + key: ModelTreeIndexKey | ModelAssetIdKey, item: AssetMapping[] | undefined ): void { const value = Promise.resolve(item ?? []); @@ -238,7 +238,7 @@ export class AssetMappingAndNode3DCache { const keyAssetId: ModelAssetIdKey = modelRevisionNodesAssetsToKey(modelId, revisionId, [ item.assetId ]); - const keyNodeId: ModelNodeIdKey = modelRevisionNodesAssetsToKey(modelId, revisionId, [ + const keyNodeId: ModelTreeIndexKey = modelRevisionNodesAssetsToKey(modelId, revisionId, [ item.nodeId ]); await this.assetIdsToAssetMappingCache.setAssetMappingsCacheItem(keyAssetId, item); diff --git a/react-components/src/components/CacheProvider/AssetMappingPerNodeIdCache.ts b/react-components/src/components/CacheProvider/AssetMappingPerNodeIdCache.ts index 67299645b11..80a9088015a 100644 --- a/react-components/src/components/CacheProvider/AssetMappingPerNodeIdCache.ts +++ b/react-components/src/components/CacheProvider/AssetMappingPerNodeIdCache.ts @@ -2,26 +2,29 @@ * Copyright 2024 Cognite AS */ import { type AssetMapping3D } from '@cognite/sdk/dist/src'; -import { type ModelNodeIdKey } from './types'; +import { type ModelTreeIndexKey } from './types'; import { type AssetMapping } from './AssetMappingAndNode3DCache'; export class AssetMappingPerNodeIdCache { - private readonly _nodeIdsToAssetMappings = new Map>(); + private readonly _nodeIdsToAssetMappings = new Map>(); public setNodeIdsToAssetMappingCacheItem( - key: ModelNodeIdKey, + key: ModelTreeIndexKey, item: Promise>> ): void { this._nodeIdsToAssetMappings.set(key, Promise.resolve(item)); } public async getNodeIdsToAssetMappingCacheItem( - key: ModelNodeIdKey + key: ModelTreeIndexKey ): Promise { return await this._nodeIdsToAssetMappings.get(key); } - public async setAssetMappingsCacheItem(key: ModelNodeIdKey, item: AssetMapping): Promise { + public async setAssetMappingsCacheItem( + key: ModelTreeIndexKey, + item: AssetMapping + ): Promise { const currentAssetMappings = this.getNodeIdsToAssetMappingCacheItem(key); this.setNodeIdsToAssetMappingCacheItem( key, diff --git a/react-components/src/components/CacheProvider/FdmNodeCache.ts b/react-components/src/components/CacheProvider/FdmNodeCache.ts index 2132d33b899..7a3023abcd9 100644 --- a/react-components/src/components/CacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/FdmNodeCache.ts @@ -10,17 +10,17 @@ import { type FdmCadConnection, type ModelRevisionKey, type RevisionId, - type NodeId, - type ModelNodeIdKey, + type ModelTreeIndexKey, type ModelRevisionToConnectionMap, type ModelRevisionId, type FdmKey, - type FdmNodeDataPromises + type FdmNodeDataPromises, + type TreeIndex } from './types'; import { createFdmKey, - createModelNodeIdKey, + createModelTreeIndexKey, createModelRevisionKey, revisionKeyToIds } from './idAndKeyTranslation'; @@ -28,7 +28,7 @@ import { import { partition } from 'lodash'; import assert from 'assert'; -import { fetchNodesForNodeIds, inspectNodes } from './requests'; +import { fetchNodesForNodeIds, inspectNodes, treeIndexesToNodeIds } from './requests'; import { type ThreeDModelFdmMappings } from '../../hooks/types'; import { type Fdm3dDataProvider } from '../../data-providers/Fdm3dDataProvider'; @@ -239,8 +239,8 @@ export class FdmNodeCache { modelRevisionIds: ModelRevisionId[], fetchViews: boolean ): Promise> { - const revisionIds = modelRevisionIds.map((modelRevisionId) => modelRevisionId.revisionId); - const connections = await this._fdm3dDataProvider.getCadConnectionsForRevisions(revisionIds); + const connections = + await this._fdm3dDataProvider.getCadConnectionsForRevisions(modelRevisionIds); const connectionsWithOptionalViews = fetchViews ? await this.getViewsForConnections(connections) @@ -311,9 +311,9 @@ async function createRevisionToConnectionsMap( modelRevisionIds: ModelRevisionId[], cdfClient: CogniteClient ): Promise> { - const revisionToNodeIdsMap = createRevisionToNodeIdMap(connectionsWithView); - const modelNodeIdToNodeMap = await createModelNodeIdToNodeMap( - revisionToNodeIdsMap, + const revisionToTreeIndexMap = createRevisionToTreeIndexMap(connectionsWithView); + const modelTreeIndexToNodeMap = await createModelTreeIndexToNodeMap( + revisionToTreeIndexMap, modelRevisionIds, cdfClient ); @@ -326,7 +326,7 @@ async function createRevisionToConnectionsMap( const value = createFdmConnectionWithNode( modelRevisionId, - modelNodeIdToNodeMap, + modelTreeIndexToNodeMap, connectionWithView.connection, connectionWithView.view ); @@ -339,17 +339,17 @@ async function createRevisionToConnectionsMap( function createFdmConnectionWithNode( modelRevisionId: ModelRevisionId, - modelNodeIdToNodeMap: Map, + modelTreeIndexToNodeMap: Map, connection: FdmCadConnection, view?: Source ): FdmConnectionWithNode { - const revisionNodeIdKey = createModelNodeIdKey( + const revisionTreeIndexKey = createModelTreeIndexKey( modelRevisionId.modelId, modelRevisionId.revisionId, - connection.nodeId + connection.treeIndex ); - const node = modelNodeIdToNodeMap.get(revisionNodeIdKey); + const node = modelTreeIndexToNodeMap.get(revisionTreeIndexKey); assert(node !== undefined); return { connection, cadNode: node, view }; @@ -374,45 +374,49 @@ function insertConnectionIntoMapList( } } -async function createModelNodeIdToNodeMap( - revisionToNodeIdsMap: Map, +async function createModelTreeIndexToNodeMap( + revisionToTreeIndicesMap: Map, modelRevisionIds: ModelRevisionId[], cdfClient: CogniteClient -): Promise> { - const revisionNodeIdToNode = new Map(); +): Promise> { + const revisionTreeIndexToNode = new Map(); - const nodePromises = [...revisionToNodeIdsMap.entries()].map(async ([revisionId, nodeIds]) => { - const modelId = modelRevisionIds.find((p) => p.revisionId === revisionId)?.modelId; - assert(modelId !== undefined); + const nodePromises = [...revisionToTreeIndicesMap.entries()].map( + async ([revisionId, treeIndices]) => { + const modelId = modelRevisionIds.find((p) => p.revisionId === revisionId)?.modelId; + assert(modelId !== undefined); - const nodes = await fetchNodesForNodeIds(modelId, revisionId, nodeIds, cdfClient); - nodeIds.forEach((nodeId, ind) => { - const modelNodeIdKey = createModelNodeIdKey(modelId, revisionId, nodeId); - revisionNodeIdToNode.set(modelNodeIdKey, nodes[ind]); - }); - }); + const nodeIds = await treeIndexesToNodeIds(modelId, revisionId, treeIndices, cdfClient); + const nodes = await fetchNodesForNodeIds(modelId, revisionId, nodeIds, cdfClient); + + nodes.forEach((node) => { + const modelTreeIndexKey = createModelTreeIndexKey(modelId, revisionId, node.treeIndex); + revisionTreeIndexToNode.set(modelTreeIndexKey, node); + }); + } + ); await Promise.all(nodePromises); - return revisionNodeIdToNode; + return revisionTreeIndexToNode; } -function createRevisionToNodeIdMap( +function createRevisionToTreeIndexMap( connections: Array<{ connection: FdmCadConnection; view?: Source }> -): Map { - return connections.reduce((revisionNodeIdMap, connectionWithView) => { - const { nodeId, revisionId } = connectionWithView.connection; +): Map { + return connections.reduce((revisionTreeIndexMap, connectionWithView) => { + const { treeIndex, revisionId } = connectionWithView.connection; - const nodeIdsInRevision = revisionNodeIdMap.get(revisionId); + const treeIndicesInRevision = revisionTreeIndexMap.get(revisionId); - if (nodeIdsInRevision !== undefined) { - nodeIdsInRevision.push(nodeId); + if (treeIndicesInRevision !== undefined) { + treeIndicesInRevision.push(treeIndex); } else { - revisionNodeIdMap.set(revisionId, [nodeId]); + revisionTreeIndexMap.set(revisionId, [treeIndex]); } - return revisionNodeIdMap; - }, new Map()); + return revisionTreeIndexMap; + }, new Map()); } function intersectWithFdmKeySet( diff --git a/react-components/src/components/CacheProvider/Node3DPerNodeIdCache.ts b/react-components/src/components/CacheProvider/Node3DPerNodeIdCache.ts index 62d8cc53f30..9d8c95e5913 100644 --- a/react-components/src/components/CacheProvider/Node3DPerNodeIdCache.ts +++ b/react-components/src/components/CacheProvider/Node3DPerNodeIdCache.ts @@ -6,7 +6,7 @@ import { type ChunkInCacheTypes, type ModelId, type RevisionId, - type ModelNodeIdKey + type ModelTreeIndexKey } from './types'; import { modelRevisionNodesAssetsToKey } from './utils'; import { fetchNodesForNodeIds } from './requests'; @@ -14,7 +14,7 @@ import { fetchNodesForNodeIds } from './requests'; export class Node3DPerNodeIdCache { private readonly _sdk: CogniteClient; - private readonly _nodeIdsToNode3D = new Map>(); + private readonly _nodeIdsToNode3D = new Map>(); constructor(sdk: CogniteClient) { this._sdk = sdk; @@ -71,11 +71,11 @@ export class Node3DPerNodeIdCache { return allNodes; } - public async getNodeIdToNode3DCacheItem(key: ModelNodeIdKey): Promise { + public async getNodeIdToNode3DCacheItem(key: ModelTreeIndexKey): Promise { return await this._nodeIdsToNode3D.get(key); } - public setNodeIdToNode3DCacheItem(key: ModelNodeIdKey, item: Promise): void { + public setNodeIdToNode3DCacheItem(key: ModelTreeIndexKey, item: Promise): void { this._nodeIdsToNode3D.set(key, Promise.resolve(item)); } } diff --git a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts index 531c5366fcb..c6233332b17 100644 --- a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts @@ -239,7 +239,7 @@ export class RevisionFdmNodeCache { nodes: Node3D[] ): Array<{ connection: FdmCadConnection; treeIndex: TreeIndex }> { return mappingConnections.reduce((acc, connection) => { - const nodeInConnection = nodes.find((node) => node.id === connection.nodeId); + const nodeInConnection = nodes.find((node) => node.treeIndex === connection.treeIndex); if (nodeInConnection !== undefined) { acc.push({ diff --git a/react-components/src/components/CacheProvider/idAndKeyTranslation.ts b/react-components/src/components/CacheProvider/idAndKeyTranslation.ts index a2cc425c9b2..ab66e6b34df 100644 --- a/react-components/src/components/CacheProvider/idAndKeyTranslation.ts +++ b/react-components/src/components/CacheProvider/idAndKeyTranslation.ts @@ -2,27 +2,35 @@ * Copyright 2023 Cognite AS */ -import { type FdmKey, type ModelNodeIdKey, type ModelRevisionKey } from './types'; +import { ExternalId, Space } from '../../data-providers/FdmSDK'; +import { + type FdmKey, + type ModelTreeIndexKey, + type ModelRevisionKey, + TreeIndex, + RevisionId, + ModelId +} from './types'; import { split } from 'lodash'; -export function createModelRevisionKey(modelId: number, revisionId: number): ModelRevisionKey { +export function createModelRevisionKey(modelId: ModelId, revisionId: RevisionId): ModelRevisionKey { return `${modelId}/${revisionId}`; } -export function revisionKeyToIds(revisionKey: ModelRevisionKey): [number, number] { +export function revisionKeyToIds(revisionKey: ModelRevisionKey): [ModelId, RevisionId] { const components = split(revisionKey, '/'); return [Number(components[0]), Number(components[1])]; } -export function createModelNodeIdKey( - modelId: number, - revisionId: number, - nodeId: number -): ModelNodeIdKey { - return `${modelId}/${revisionId}/${nodeId}`; +export function createModelTreeIndexKey( + modelId: ModelId, + revisionId: RevisionId, + treeIndex: TreeIndex +): ModelTreeIndexKey { + return `${modelId}/${revisionId}/${treeIndex}`; } -export function createFdmKey(spaceId: string, externalId: string): FdmKey { +export function createFdmKey(spaceId: Space, externalId: ExternalId): FdmKey { return `${spaceId}/${externalId}`; } diff --git a/react-components/src/components/CacheProvider/requests.ts b/react-components/src/components/CacheProvider/requests.ts index 439298ede92..0b0d975177a 100644 --- a/react-components/src/components/CacheProvider/requests.ts +++ b/react-components/src/components/CacheProvider/requests.ts @@ -9,6 +9,7 @@ import { type InspectResultList } from '../../data-providers/FdmSDK'; import { chunk } from 'lodash'; +import { ModelId, RevisionId, TreeIndex } from './types'; export async function fetchAncestorNodesForTreeIndex( modelId: number, diff --git a/react-components/src/components/CacheProvider/types.ts b/react-components/src/components/CacheProvider/types.ts index f41eb2d28b6..bdd077d1c4d 100644 --- a/react-components/src/components/CacheProvider/types.ts +++ b/react-components/src/components/CacheProvider/types.ts @@ -16,7 +16,7 @@ export type FdmCadConnection = { instance: DmsUniqueIdentifier; modelId: number; revisionId: number; - nodeId: number; + treeIndex: number; }; export type FdmConnectionWithNode = { connection: FdmCadConnection; @@ -45,8 +45,8 @@ export type AncestorQueryResult = { export type ModelId = number; export type RevisionId = number; -export type TreeIndex = number; export type NodeId = number; +export type TreeIndex = number; export type AssetId = number; export type FdmId = DmsUniqueIdentifier; @@ -54,7 +54,7 @@ export type ModelRevisionId = { modelId: number; revisionId: number }; export type ModelRevisionKey = `${ModelId}/${RevisionId}`; export type FdmKey = `${string}/${string}`; -export type ModelNodeIdKey = `${ModelId}/${RevisionId}/${NodeId}`; +export type ModelTreeIndexKey = `${ModelId}/${RevisionId}/${TreeIndex}`; export type ModelAssetIdKey = `${ModelId}/${RevisionId}/${AssetId}`; export type ModelRevisionToConnectionMap = Map; diff --git a/react-components/src/components/CacheProvider/utils.ts b/react-components/src/components/CacheProvider/utils.ts index 4b12ee628e7..ae6941e0b7b 100644 --- a/react-components/src/components/CacheProvider/utils.ts +++ b/react-components/src/components/CacheProvider/utils.ts @@ -15,7 +15,7 @@ import { type ModelId, type ModelRevisionKey, type RevisionId, - type ModelNodeIdKey + type ModelTreeIndexKey } from './types'; export function modelRevisionToKey(modelId: ModelId, revisionId: RevisionId): ModelRevisionKey { @@ -26,7 +26,7 @@ export function modelRevisionNodesAssetsToKey( modelId: ModelId, revisionId: RevisionId, ids: number[] -): ModelNodeIdKey { +): ModelTreeIndexKey { const idsSerialized = ids.reduce((a, b) => a + b, 0); return `${modelId}/${revisionId}/${idsSerialized}`; } diff --git a/react-components/src/data-providers/Fdm3dDataProvider.ts b/react-components/src/data-providers/Fdm3dDataProvider.ts index c2de79e9449..b9b12f9ca09 100644 --- a/react-components/src/data-providers/Fdm3dDataProvider.ts +++ b/react-components/src/data-providers/Fdm3dDataProvider.ts @@ -48,5 +48,5 @@ export type Fdm3dDataProvider = { getCadModelsForInstance: (instance: DmsUniqueIdentifier) => Promise; - getCadConnectionsForRevisions: (revisions: number[]) => Promise; + getCadConnectionsForRevisions: (modelOptions: AddModelOptions[]) => Promise; }; diff --git a/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts b/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts index faa037e3969..551405a0ecd 100644 --- a/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts +++ b/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts @@ -14,6 +14,9 @@ import { listAllMappedFdmNodes, listMappedFdmNodes } from './listMappedFdmNodes' import { isDefined } from '../../utilities/isDefined'; import { executeParallel } from '../../utilities/executeParallel'; import { filterNodesByMappedTo3d } from './filterNodesByMappedTo3d'; +import { getCadModelsForInstance } from './getCadModelsForInstance'; +import { getCadConnectionsForRevisions } from './getCadConnectionsForRevisions'; +import { zip } from 'lodash'; const MAX_PARALLEL_QUERIES = 2; @@ -165,7 +168,25 @@ export class CoreDm3dFdm3dDataProvider implements Fdm3dDataProvider { return filterNodesByMappedTo3d(nodes, revisionRefs, spacesToSearch, this._fdmSdk); } - getCadModelsForInstance(instance: DmsUniqueIdentifier): Promise {} + getCadModelsForInstance(instance: DmsUniqueIdentifier): Promise { + return getCadModelsForInstance(instance, this._fdmSdk); + } + + async getCadConnectionsForRevisions( + modelOptions: AddModelOptions[] + ): Promise { + const modelRefs = await this.getDMSModelsForIds(modelOptions.map((model) => model.modelId)); + + const revisionRefs = await this.getDMSRevisionsForRevisionIdsAndModelRefs( + modelRefs, + modelOptions.map((model) => model.revisionId) + ); - getCadConnectionsForRevisions(revisions: number[]): Promise {} + const modelRevisions = zip(modelRefs, revisionRefs).filter( + (modelRevision): modelRevision is [DmsUniqueIdentifier, DmsUniqueIdentifier] => + isDefined(modelRevision[0]) && isDefined(modelRevision[1]) + ); + + return getCadConnectionsForRevisions(modelRevisions, this._fdmSdk); + } } diff --git a/react-components/src/data-providers/core-dm-provider/Duplex3dDataProvider.ts b/react-components/src/data-providers/core-dm-provider/Duplex3dDataProvider.ts index 055cd117827..697b458ecf0 100644 --- a/react-components/src/data-providers/core-dm-provider/Duplex3dDataProvider.ts +++ b/react-components/src/data-providers/core-dm-provider/Duplex3dDataProvider.ts @@ -70,7 +70,7 @@ export class Duplex3dDataProvider implements Fdm3dDataProvider { return this._dataProvider.getCadModelsForInstance(instance); } - getCadConnectionsForRevisions(revisions: number[]): Promise { - return this._dataProvider.getCadConnectionsForRevisions(revisions); + getCadConnectionsForRevisions(modelOptions: AddModelOptions[]): Promise { + return this._dataProvider.getCadConnectionsForRevisions(modelOptions); } } diff --git a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts new file mode 100644 index 00000000000..2b23058b184 --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts @@ -0,0 +1,141 @@ +import { QueryRequest } from '@cognite/sdk/dist/src'; +import { FdmCadConnection, FdmKey } from '../../components/CacheProvider/types'; +import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; +import { + Cognite3DObjectProperties, + COGNITE_3D_OBJECT_SOURCE, + COGNITE_CAD_NODE_SOURCE, + CogniteCADNodeProperties +} from './dataModels'; +import { cogniteObject3dSourceWithProperties } from './cogniteObject3dSourceWithProperties'; +import { cogniteCadNodeSourceWithPRoperties } from './cogniteCadNodeSourceWithProperties'; +import { getModelIdFromExternalId, getRevisionIdFromExternalId } from './getCdfIdFromExternalId'; +import { toFdmKey } from '../utils/toFdmKey'; +import { PromiseType } from '../utils/typeUtils'; +import { isDefined } from '../../utilities/isDefined'; + +export async function getCadConnectionsForRevisions( + modelRevisions: [DmsUniqueIdentifier, DmsUniqueIdentifier][], + fdmSdk: FdmSDK +): Promise { + const results = await getModelConnectionResults(modelRevisions, fdmSdk); + + const cadNodeToModelMap = createNodeToModelMap(modelRevisions, results.items.cad_nodes); + + return results.items.object_3ds.flatMap((obj) => { + const props = obj.properties.cdf_cdm_experimental['CogniteObject3D/v1']; + + return props.cadNodes + .map((cadNode) => { + const modelObj = cadNodeToModelMap.get(toFdmKey(cadNode)); + if (modelObj === undefined) { + return undefined; + } + return { ...modelObj, instance: obj }; + }) + .filter(isDefined); + }); +} + +function getModelConnectionResults( + modelRevisions: [DmsUniqueIdentifier, DmsUniqueIdentifier][], + fdmSdk: FdmSDK +) { + const parameters = { + modelRefs: modelRevisions.map(([modelRef, _revisionRef]) => modelRef), + revisionRefs: modelRevisions.map(([_modelRef, revisionRef]) => revisionRef) + }; + + const query = { + ...cadConnectionsQuery, + parameters + }; + + return fdmSdk.queryAllNodesAndEdges< + typeof query, + [ + { source: typeof COGNITE_3D_OBJECT_SOURCE; properties: Cognite3DObjectProperties }, + { source: typeof COGNITE_CAD_NODE_SOURCE; properties: CogniteCADNodeProperties } + ] + >(query); +} + +function createNodeToModelMap( + modelRevisions: [DmsUniqueIdentifier, DmsUniqueIdentifier][], + cadNodes: PromiseType>['items']['cad_nodes'] +): Map> { + return cadNodes.reduce((nodeMap, cadNode) => { + const props = cadNode.properties.cdf_cdm_experimental['CogniteCADNode/v1']; + const modelRevisionPair = modelRevisions.find( + ([modelRef, _revisionRef]) => + props.model3D.externalId === modelRef.externalId && props.model3D.space === modelRef.space + ); + if (modelRevisionPair === undefined) { + return nodeMap; + } + + const revisionIndex = props.revisions.findIndex( + (propRevision) => + modelRevisionPair[1].externalId === propRevision.externalId && + modelRevisionPair[1].space === propRevision.space + ); + + if (revisionIndex === -1) { + return nodeMap; + } + + const modelId = getModelIdFromExternalId(props.model3D.externalId); + const revisionId = getRevisionIdFromExternalId(props.revisions[revisionIndex].externalId); + + nodeMap.set(toFdmKey(cadNode), { + modelId, + revisionId, + treeIndex: props.treeIndexes[revisionIndex] + }); + + return nodeMap; + }, new Map>()); +} + +const cadConnectionsQuery = { + with: { + cad_nodes: { + nodes: { + filter: { + and: [ + { + in: { + property: [ + COGNITE_CAD_NODE_SOURCE.space, + COGNITE_CAD_NODE_SOURCE.externalId, + 'model3D' + ], + values: { parameter: 'modelRefs' } + } + }, + { + containsAny: { + property: [ + COGNITE_CAD_NODE_SOURCE.space, + COGNITE_CAD_NODE_SOURCE.externalId, + 'revisions' + ], + values: { parameter: 'revisionRefs' } + } + } + ] + } + } + }, + object_3ds: { + nodes: { + from: 'cad_nodes', + through: { source: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' } + } + } + }, + select: { + cad_nodes: { sources: cogniteCadNodeSourceWithPRoperties }, + object_3ds: { sources: cogniteObject3dSourceWithProperties } + } +} as const satisfies Omit; diff --git a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts index d61bc6ce446..6e0612a38e9 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts @@ -1,8 +1,67 @@ +import { QueryRequest } from '@cognite/sdk/dist/src'; import { TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; -import { DmsUniqueIdentifier } from '../FdmSDK'; +import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; +import { + COGNITE_3D_OBJECT_SOURCE, + COGNITE_CAD_NODE_SOURCE, + COGNITE_VISUALIZABLE_SOURCE, + CogniteCADNodeProperties +} from './dataModels'; +import { cogniteCadNodeSourceWithPRoperties } from './cogniteCadNodeSourceWithProperties'; +import { getModelIdFromExternalId, getRevisionIdFromExternalId } from './getCdfIdFromExternalId'; export async function getCadModelsForInstance( - instance: DmsUniqueIdentifier + instance: DmsUniqueIdentifier, + fdmSdk: FdmSDK ): Promise { - return []; + const parameters = { instanceIds: [instance] }; + + const query = { + ...cadModelsForInstanceQuery, + parameters + }; + + const results = await fdmSdk.queryAllNodesAndEdges< + typeof query, + [{ source: typeof COGNITE_CAD_NODE_SOURCE; properties: CogniteCADNodeProperties }] + >(query); + + return results.items.cad_nodes.flatMap((cadNode) => { + const props = cadNode.properties.cdf_cdm_experimental['CogniteCADNode/v1']; + return props.revisions.map((revision) => ({ + type: 'cad', + addOptions: { + modelId: getModelIdFromExternalId(props.model3D.externalId), + revisionId: getRevisionIdFromExternalId(revision.externalId) + } + })); + }); } + +const cadModelsForInstanceQuery = { + with: { + object_3ds: { + nodes: { + filter: { + containsAny: { + property: [ + COGNITE_VISUALIZABLE_SOURCE.space, + COGNITE_VISUALIZABLE_SOURCE.externalId, + 'object3D' + ], + values: { parameter: 'instanceId' } + } + } + } + }, + cad_nodes: { + nodes: { + from: 'object_3ds', + through: { source: COGNITE_3D_OBJECT_SOURCE, identifier: 'cadNodes' } + } + } + }, + select: { + cad_nodes: { sources: cogniteCadNodeSourceWithPRoperties } + } +} as const satisfies Omit; diff --git a/react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts b/react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts new file mode 100644 index 00000000000..0917935451b --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts @@ -0,0 +1,9 @@ +export function getModelIdFromExternalId(externalId: string) { + // The externalId should be on the form `cog_3d_model_${modelId}` + return Number(externalId.slice('cog_3d_model_'.length)); +} + +export function getRevisionIdFromExternalId(externalId: string) { + // The externalId should be on the form `cog_3d_revision_${modelId}` + return Number(externalId.slice('cog_3d_revision_'.length)); +} diff --git a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts index b421a69ef1e..c7281b9eba5 100644 --- a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts +++ b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts @@ -9,7 +9,8 @@ import { CogniteAssetProperties, CogniteCADNodeProperties } from './dataModels'; -import { getModelIdFromExternalId } from './getModelIdFromExternalId'; +import { getModelIdFromExternalId } from './getCdfIdFromExternalId'; +import { toFdmKey } from '../utils/toFdmKey'; export async function getFdmConnectionsForNodes( model: DmsUniqueIdentifier, @@ -79,14 +80,14 @@ export async function getFdmConnectionsForNodes( } const assets = relevantObjectToAssetsMap.get(object3dKey); - const nodeId = treeIndexToNodeIdMap.get(treeIndex); - - if (assets === undefined || nodeId === undefined) { + if (assets === undefined) { // Should not happen return; } - assets.forEach((asset) => connections.push({ modelId, revisionId, nodeId, instance: asset })); + assets.forEach((asset) => + connections.push({ modelId, revisionId, treeIndex, instance: asset }) + ); }); return connections; diff --git a/react-components/src/data-providers/core-dm-provider/getModelIdFromExternalId.ts b/react-components/src/data-providers/core-dm-provider/getModelIdFromExternalId.ts deleted file mode 100644 index 3e564f1bb9d..00000000000 --- a/react-components/src/data-providers/core-dm-provider/getModelIdFromExternalId.ts +++ /dev/null @@ -1,4 +0,0 @@ -export function getModelIdFromExternalId(externalId: string) { - // The externalId should be on the form `cog_3d_model_${modelId}` - return Number(externalId.slice('cog_3d_model_'.length)); -} diff --git a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts index a9ae2aa0bf4..232a9082b32 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts @@ -80,7 +80,9 @@ export class LegacyFdm3dDataProvider implements Fdm3dDataProvider { return await getCadModelsForFdmInstance(this._fdmSdk, instance); } - async getCadConnectionsForRevisions(revisions: number[]): Promise { - return await getCadConnectionsForRevision(revisions, this._fdmSdk); + async getCadConnectionsForRevisions( + modelOptions: AddModelOptions[] + ): Promise { + return await getCadConnectionsForRevision(modelOptions, this._fdmSdk); } } diff --git a/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts b/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts index 8496224cebf..5e06ab372ee 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts @@ -1,6 +1,7 @@ /*! * Copyright 2024 Cognite AS */ +import { AddModelOptions } from '@cognite/reveal'; import { type FdmCadConnection } from '../../components/CacheProvider/types'; import { type FdmSDK } from '../FdmSDK'; import { @@ -11,10 +12,12 @@ import { import { fdmEdgesToCadConnections } from './fdmEdgesToCadConnections'; export async function getCadConnectionsForRevision( - revisionIds: number[], + modelOptions: AddModelOptions[], fdmClient: FdmSDK ): Promise { - if (revisionIds.length === 0) return []; + if (modelOptions.length === 0) return []; + + const revisionIds = modelOptions.map((model) => model.revisionId); const versionedPropertiesKey = `${SYSTEM_3D_EDGE_SOURCE.externalId}/${SYSTEM_3D_EDGE_SOURCE.version}`; const filter = { diff --git a/react-components/stories/CadStylingCache.stories.tsx b/react-components/stories/CadStylingCache.stories.tsx index 804e3aa2493..191026c40d5 100644 --- a/react-components/stories/CadStylingCache.stories.tsx +++ b/react-components/stories/CadStylingCache.stories.tsx @@ -9,11 +9,12 @@ import { type NodeStylingGroup, RevealCanvas, useReveal, - RevealContext + RevealContext, + TreeIndexStylingGroup } from '../src'; import { Color, Matrix4, Vector3 } from 'three'; import { createSdkByUrlToken } from './utilities/createSdkByUrlToken'; -import { type CogniteCadModel, DefaultNodeAppearance } from '@cognite/reveal'; +import { type CogniteCadModel, DefaultNodeAppearance, IndexSet } from '@cognite/reveal'; import { useEffect, useMemo, useState, type JSX } from 'react'; import { useMappedEdgesForRevisions } from '../src/components/CacheProvider/NodeCacheProvider'; @@ -55,7 +56,7 @@ const Models = ({ addModelOptions }: CogniteCadModelProps): JSX.Element => { const { data } = useMappedEdgesForRevisions([platformModelOptions]); - const nodeIds = useMemo( + const treeIndices = useMemo( () => data ?.get(`${platformModelOptions.modelId}/${platformModelOptions.revisionId}`) @@ -65,18 +66,19 @@ const Models = ({ addModelOptions }: CogniteCadModelProps): JSX.Element => { useEffect(() => { const callback = (): void => { - if (platformStyling === undefined || nodeIds === undefined) return; + if (platformStyling === undefined || treeIndices === undefined) return; setPlatformStyling((prev): CadModelStyling | undefined => { if (prev?.groups === undefined) return prev; - const newNodeIds = getRandomSubset(nodeIds, nodeIds.length * 0.8); + const newTreeIndices = getRandomSubset(treeIndices, treeIndices.length * 0.4); + const indexSet = new IndexSet(newTreeIndices); return { groups: [ ...prev.groups, { - nodeIds: newNodeIds.slice(0, newNodeIds.length / 2), + treeIndexSet: indexSet, style: { color: new Color().setFromVector3( new Vector3(Math.random(), Math.random(), Math.random()) @@ -97,10 +99,10 @@ const Models = ({ addModelOptions }: CogniteCadModelProps): JSX.Element => { }, [viewer, platformStyling, setPlatformStyling]); useEffect(() => { - if (nodeIds === undefined) return; + if (treeIndices === undefined) return; - const stylingGroupRed: NodeStylingGroup = { - nodeIds: nodeIds.slice(0, nodeIds.length), + const stylingGroupRed: TreeIndexStylingGroup = { + treeIndexSet: new IndexSet(treeIndices), style: { color: new Color('red'), renderInFront: true diff --git a/react-components/stories/utilities/getAddModelOptionsFromUrl.ts b/react-components/stories/utilities/getAddModelOptionsFromUrl.ts index 9c1b4d7686f..a2ec110e27c 100644 --- a/react-components/stories/utilities/getAddModelOptionsFromUrl.ts +++ b/react-components/stories/utilities/getAddModelOptionsFromUrl.ts @@ -16,8 +16,8 @@ export function getAddModelOptionsFromUrl(localModelUrlFallback: string): AddMod } return { - modelId: -1, - revisionId: -1, + modelId: 3544114490298106, + revisionId: 6405404576933316, localPath: modelUrl ?? localModelUrlFallback }; } From 6b0210a70527efa99e07e4ece87ffcac454fb517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Wed, 21 Aug 2024 10:08:22 +0200 Subject: [PATCH 04/32] chore: I'm so sorry --- .../concrete/observations/network.ts | 7 +- .../CacheProvider/idAndKeyTranslation.ts | 8 +- .../src/components/CacheProvider/requests.ts | 43 +- .../src/components/CacheProvider/utils.ts | 6 + .../components/RevealCanvas/SDKProvider.tsx | 2 +- .../components/RevealToolbar/SceneList.tsx | 2 +- .../RevealToolbar/SelectSceneButton.tsx | 2 +- .../src/components/RuleBasedOutputs/types.ts | 2 +- .../src/components/SceneContainer/Queries.tsx | 219 -------- .../SceneContainer/SceneFdmTypes.tsx | 4 +- .../src/data-providers/Fdm3dDataProvider.ts | 2 +- react-components/src/data-providers/FdmSDK.ts | 21 +- .../core-dm-provider/CoreDm3dDataProvider.ts | 67 ++- .../core-dm-provider/Duplex3dDataProvider.ts | 76 --- .../cogniteAssetSourceWithProperties.ts | 5 +- .../cogniteCadNodeSourceWithProperties.ts | 5 +- .../cogniteObject3dSourceWithProperties.ts | 5 +- .../core-dm-provider/dataModels.ts | 7 +- .../filterNodesByMappedTo3d.ts | 61 ++- .../getCadConnectionsForRevisions.ts | 43 +- .../getCadModelsForInstance.ts | 15 +- .../getCdfIdFromExternalId.ts | 10 +- .../core-dm-provider/getDMSModels.ts | 9 +- .../core-dm-provider/getDMSRevision.ts | 9 +- .../getEdgeConnected3dInstances.ts | 11 +- .../getFdmConnectionsForNodeIds.ts | 30 +- .../core-dm-provider/listMappedFdmNodes.ts | 31 +- .../LegacyFdm3dDataProvider.ts | 16 +- .../createMappedEquipmentQuery.ts | 2 +- .../fdmEdgesToCadConnections.ts | 97 +++- .../filterNodesByMappedTo3d.ts | 19 +- .../getCadConnectionsForRevision.ts | 8 +- .../getCadModelsForFdmInstance.ts | 25 +- .../getEdgeConnected3dInstances.ts | 2 +- .../getFdmConnectionsForNodeIds.ts | 5 +- .../legacy-fdm-provider/listMappedFdmNodes.ts | 10 +- .../utils/getDirectRelationProperties.ts | 5 +- .../data-providers/utils/mergeQueryResult.ts | 6 +- .../utils/queryNodesAndEdges.ts | 3 + .../src/data-providers/utils/toFdmKey.ts | 7 +- .../src/data-providers/utils/typeUtils.ts | 6 +- react-components/src/hooks/types.ts | 54 -- .../src/hooks/useGroundPlaneFromScene.tsx | 2 +- .../hooks/useReveal3dResourcesFromScene.ts | 4 +- .../src/hooks/useSceneDefaultCamera.tsx | 2 +- .../src/hooks/useSkyboxFromScene.tsx | 2 +- react-components/src/index.ts | 2 +- react-components/src/query/use3dScenes.tsx | 470 ------------------ react-components/src/query/useSceneConfig.ts | 228 --------- .../src/utilities/executeParallel.ts | 11 +- .../stories/CadStylingCache.stories.tsx | 3 +- 51 files changed, 417 insertions(+), 1274 deletions(-) delete mode 100644 react-components/src/components/SceneContainer/Queries.tsx delete mode 100644 react-components/src/data-providers/core-dm-provider/Duplex3dDataProvider.ts delete mode 100644 react-components/src/query/use3dScenes.tsx delete mode 100644 react-components/src/query/useSceneConfig.ts diff --git a/react-components/src/architecture/concrete/observations/network.ts b/react-components/src/architecture/concrete/observations/network.ts index 09460c77bcd..73095878e49 100644 --- a/react-components/src/architecture/concrete/observations/network.ts +++ b/react-components/src/architecture/concrete/observations/network.ts @@ -5,18 +5,15 @@ import { chunk } from 'lodash'; import { type CreateInstanceItem, type DmsUniqueIdentifier, - type FdmSDK, - type InstanceFilter + type FdmSDK } from '../../../data-providers/FdmSDK'; import { type ObservationFdmNode, OBSERVATION_SOURCE, type ObservationProperties } from './models'; import { v4 as uuid } from 'uuid'; export async function fetchObservations(fdmSdk: FdmSDK): Promise { - const observationsFilter: InstanceFilter = {}; - const observationResult = await fdmSdk.filterAllInstances( - observationsFilter, + undefined, 'node', OBSERVATION_SOURCE ); diff --git a/react-components/src/components/CacheProvider/idAndKeyTranslation.ts b/react-components/src/components/CacheProvider/idAndKeyTranslation.ts index ab66e6b34df..0a56049c768 100644 --- a/react-components/src/components/CacheProvider/idAndKeyTranslation.ts +++ b/react-components/src/components/CacheProvider/idAndKeyTranslation.ts @@ -2,14 +2,14 @@ * Copyright 2023 Cognite AS */ -import { ExternalId, Space } from '../../data-providers/FdmSDK'; +import { type ExternalId, type Space } from '../../data-providers/FdmSDK'; import { type FdmKey, type ModelTreeIndexKey, type ModelRevisionKey, - TreeIndex, - RevisionId, - ModelId + type TreeIndex, + type RevisionId, + type ModelId } from './types'; import { split } from 'lodash'; diff --git a/react-components/src/components/CacheProvider/requests.ts b/react-components/src/components/CacheProvider/requests.ts index 0b0d975177a..b292a36ce40 100644 --- a/react-components/src/components/CacheProvider/requests.ts +++ b/react-components/src/components/CacheProvider/requests.ts @@ -9,12 +9,12 @@ import { type InspectResultList } from '../../data-providers/FdmSDK'; import { chunk } from 'lodash'; -import { ModelId, RevisionId, TreeIndex } from './types'; +import { type ModelId, type NodeId, type RevisionId, type TreeIndex } from './types'; export async function fetchAncestorNodesForTreeIndex( - modelId: number, - revisionId: number, - treeIndex: number, + modelId: ModelId, + revisionId: RevisionId, + treeIndex: TreeIndex, cogniteClient: CogniteClient ): Promise { const nodeId = await treeIndexesToNodeIds(modelId, revisionId, [treeIndex], cogniteClient); @@ -55,15 +55,15 @@ export async function inspectNodes( } export async function treeIndexesToNodeIds( - modelId: number, - revisionId: number, - treeIndexes: number[], + modelId: ModelId, + revisionId: RevisionId, + treeIndexes: TreeIndex[], cogniteClient: CogniteClient -): Promise { +): Promise { const outputsUrl = `${cogniteClient.getBaseUrl()}/api/v1/projects/${ cogniteClient.project }/3d/models/${modelId}/revisions/${revisionId}/nodes/internalids/bytreeindices`; - const response = await cogniteClient.post<{ items: number[] }>(outputsUrl, { + const response = await cogniteClient.post<{ items: NodeId[] }>(outputsUrl, { data: { items: treeIndexes } }); if (response.status === 200) { @@ -73,10 +73,29 @@ export async function treeIndexesToNodeIds( } } +export async function nodeIdsToTreeIndices( + modelId: ModelId, + revisionId: RevisionId, + nodeIds: NodeId[], + cogniteClient: CogniteClient +): Promise { + const outputsUrl = `${cogniteClient.getBaseUrl()}/api/v1/projects/${ + cogniteClient.project + }/3d/models/${modelId}/revisions/${revisionId}/nodes/treeindices/byinternalids`; + const response = await cogniteClient.post<{ items: TreeIndex[] }>(outputsUrl, { + data: { items: nodeIds } + }); + if (response.status === 200) { + return response.data.items; + } else { + throw new Error(`nodeId-treeIndex translation failed for nodeIds ${nodeIds.join(',')}`); + } +} + export async function fetchNodesForNodeIds( - modelId: number, - revisionId: number, - nodeIds: number[], + modelId: ModelId, + revisionId: RevisionId, + nodeIds: NodeId[], cogniteClient: CogniteClient ): Promise { if (nodeIds.length === 0) { diff --git a/react-components/src/components/CacheProvider/utils.ts b/react-components/src/components/CacheProvider/utils.ts index ae6941e0b7b..09790bd94b2 100644 --- a/react-components/src/components/CacheProvider/utils.ts +++ b/react-components/src/components/CacheProvider/utils.ts @@ -22,6 +22,12 @@ export function modelRevisionToKey(modelId: ModelId, revisionId: RevisionId): Mo return `${modelId}/${revisionId}`; } +export function modelRevisionKeyToModelRevision(key: ModelRevisionKey): [ModelId, RevisionId] { + const [modelId, revisionId] = key.split('/'); + + return [Number(modelId), Number(revisionId)]; +} + export function modelRevisionNodesAssetsToKey( modelId: ModelId, revisionId: RevisionId, diff --git a/react-components/src/components/RevealCanvas/SDKProvider.tsx b/react-components/src/components/RevealCanvas/SDKProvider.tsx index c4ff4889fff..10e0e504f74 100644 --- a/react-components/src/components/RevealCanvas/SDKProvider.tsx +++ b/react-components/src/components/RevealCanvas/SDKProvider.tsx @@ -17,7 +17,7 @@ type Props = { sdk: CogniteClient; children: any }; export function SDKProvider({ sdk, children }: Props): React.ReactElement { const fdmSdk = useMemo(() => new FdmSDK(sdk), [sdk]); - const fdm3dDataProvider = new LegacyFdm3dDataProvider(fdmSdk); + const fdm3dDataProvider = new LegacyFdm3dDataProvider(fdmSdk, sdk); const content = useMemo(() => ({ fdmSdk, fdm3dDataProvider }), [fdmSdk, fdm3dDataProvider]); return ( diff --git a/react-components/src/components/RevealToolbar/SceneList.tsx b/react-components/src/components/RevealToolbar/SceneList.tsx index 676114abcf2..a510f7dd1e6 100644 --- a/react-components/src/components/RevealToolbar/SceneList.tsx +++ b/react-components/src/components/RevealToolbar/SceneList.tsx @@ -4,7 +4,7 @@ import { type ReactElement } from 'react'; import { Menu } from '@cognite/cogs.js'; -import { use3dScenes } from '../../query/use3dScenes'; +import { use3dScenes } from '../../hooks/scenes/use3dScenes'; import { type DmsUniqueIdentifier } from '../../data-providers/FdmSDK'; export type SceneWithName = DmsUniqueIdentifier & { name: string }; diff --git a/react-components/src/components/RevealToolbar/SelectSceneButton.tsx b/react-components/src/components/RevealToolbar/SelectSceneButton.tsx index 5da90c56ea8..6e94e3ba8b0 100644 --- a/react-components/src/components/RevealToolbar/SelectSceneButton.tsx +++ b/react-components/src/components/RevealToolbar/SelectSceneButton.tsx @@ -4,7 +4,7 @@ import { useCallback, useState, type ReactElement } from 'react'; import { Button, Dropdown, Menu, Tooltip as CogsTooltip } from '@cognite/cogs.js'; -import { use3dScenes } from '../../query/use3dScenes'; +import { use3dScenes } from '../../hooks/scenes/use3dScenes'; import { useTranslation } from '../i18n/I18n'; import { type DmsUniqueIdentifier } from '../../data-providers/FdmSDK'; import { SceneList, type SceneWithName } from './SceneList'; diff --git a/react-components/src/components/RuleBasedOutputs/types.ts b/react-components/src/components/RuleBasedOutputs/types.ts index 4bdd4311c03..85e2f0b5d48 100644 --- a/react-components/src/components/RuleBasedOutputs/types.ts +++ b/react-components/src/components/RuleBasedOutputs/types.ts @@ -254,7 +254,7 @@ export type NodeItem> = { externalId: string; createdTime: number; lastUpdatedTime: number; - deletedTime: number; + deletedTime?: number; properties: FdmPropertyType; }; diff --git a/react-components/src/components/SceneContainer/Queries.tsx b/react-components/src/components/SceneContainer/Queries.tsx deleted file mode 100644 index 1bbdc68f1fe..00000000000 --- a/react-components/src/components/SceneContainer/Queries.tsx +++ /dev/null @@ -1,219 +0,0 @@ -/*! - * Copyright 2023 Cognite AS - */ - -import { type Query } from '../../data-providers/FdmSDK'; - -export function createGetSceneQuery(sceneExternalId: string, sceneSpaceId: string): Query { - return { - with: { - myScene: { - nodes: { - filter: { - and: [ - { - equals: { - property: ['node', 'space'], - value: sceneSpaceId - } - }, - { - equals: { - property: ['node', 'externalId'], - value: sceneExternalId - } - } - ] - } - }, - limit: 1 - }, - sceneModels: { - edges: { - from: 'myScene', - maxDistance: 1, - direction: 'outwards', - filter: { - equals: { - property: ['edge', 'type'], - value: { - space: 'scene', - externalId: 'SceneConfiguration.model3ds' - } - } - } - }, - limit: 100 - }, - image360CollectionsEdges: { - edges: { - from: 'myScene', - maxDistance: 1, - direction: 'outwards', - filter: { - equals: { - property: ['edge', 'type'], - value: { - space: 'scene', - externalId: 'SceneConfiguration.images360Collections' - } - } - } - }, - limit: 100 - }, - skybox: { - nodes: { - from: 'myScene', - through: { - view: { - type: 'view', - space: 'scene', - externalId: 'SceneConfiguration', - version: 'v1' - }, - identifier: 'skybox' - }, - direction: 'outwards' - } - }, - groundPlaneEdges: { - edges: { - from: 'myScene', - maxDistance: 1, - direction: 'outwards', - filter: { - equals: { - property: ['edge', 'type'], - value: { - space: 'scene', - externalId: 'SceneConfiguration.texturedGroundPlanes' - } - } - } - }, - limit: 100 - }, - groundPlanes: { - nodes: { - from: 'groundPlaneEdges', - chainTo: 'destination' - }, - limit: 100 - } - }, - select: { - myScene: { - sources: [ - { - source: { - type: 'view', - space: 'scene', - externalId: 'SceneConfiguration', - version: 'v1' - }, - properties: ['*'] - } - ] - }, - sceneModels: { - sources: [ - { - source: { - type: 'view', - space: 'scene', - externalId: 'RevisionProperties', - version: 'v1' - }, - properties: [ - 'revisionId', - 'translationX', - 'translationY', - 'translationZ', - 'eulerRotationX', - 'eulerRotationY', - 'eulerRotationZ', - 'scaleX', - 'scaleY', - 'scaleZ' - ] - } - ] - }, - image360CollectionsEdges: { - sources: [ - { - source: { - type: 'view', - space: 'scene', - externalId: 'Image360CollectionProperties', - version: 'v1' - }, - properties: [ - 'image360CollectionExternalId', - 'image360CollectionSpace', - 'translationX', - 'translationY', - 'translationZ', - 'eulerRotationX', - 'eulerRotationY', - 'eulerRotationZ', - 'scaleX', - 'scaleY', - 'scaleZ' - ] - } - ] - }, - skybox: { - sources: [ - { - source: { - type: 'view', - space: 'scene', - externalId: 'EnvironmentMap', - version: 'v1' - }, - properties: ['label', 'file', 'isSpherical'] - } - ] - }, - groundPlaneEdges: { - sources: [ - { - source: { - type: 'view', - space: 'cdf_3d_schema', - externalId: 'Transformation3d', - version: 'v1' - }, - properties: [ - 'translationX', - 'translationY', - 'translationZ', - 'eulerRotationX', - 'eulerRotationY', - 'eulerRotationZ', - 'scaleX', - 'scaleY', - 'scaleZ' - ] - } - ] - }, - groundPlanes: { - sources: [ - { - source: { - type: 'view', - space: 'scene', - externalId: 'TexturedPlane', - version: 'v1' - }, - properties: ['*'] - } - ] - } - } - }; -} diff --git a/react-components/src/components/SceneContainer/SceneFdmTypes.tsx b/react-components/src/components/SceneContainer/SceneFdmTypes.tsx index 45f4733277b..0fd5c678734 100644 --- a/react-components/src/components/SceneContainer/SceneFdmTypes.tsx +++ b/react-components/src/components/SceneContainer/SceneFdmTypes.tsx @@ -35,8 +35,8 @@ export type SceneResponse = { sceneModels: SceneModelsResponse[]; image360CollectionsEdges: Image360CollectionsResponse[]; }; - nextCursor: { - scene: string; + nextCursor?: { + myScene: string; skybox: string; }; }; diff --git a/react-components/src/data-providers/Fdm3dDataProvider.ts b/react-components/src/data-providers/Fdm3dDataProvider.ts index b9b12f9ca09..7f222021d2e 100644 --- a/react-components/src/data-providers/Fdm3dDataProvider.ts +++ b/react-components/src/data-providers/Fdm3dDataProvider.ts @@ -12,7 +12,7 @@ import { type AddModelOptions } from '@cognite/reveal'; import { type InstancesWithView } from '../query/useSearchMappedEquipmentFDM'; import { type FdmCadConnection } from '../components/CacheProvider/types'; import { type TaggedAddResourceOptions } from '../components/Reveal3DResources/types'; -import { Node3D } from '@cognite/sdk'; +import { type Node3D } from '@cognite/sdk'; export type Fdm3dDataProvider = { is3dView: (view: ViewItem) => boolean; diff --git a/react-components/src/data-providers/FdmSDK.ts b/react-components/src/data-providers/FdmSDK.ts index ff1e812410b..a663db9ebe4 100644 --- a/react-components/src/data-providers/FdmSDK.ts +++ b/react-components/src/data-providers/FdmSDK.ts @@ -2,13 +2,18 @@ * Copyright 2023 Cognite AS */ -import { QueryRequest, TableExpressionFilterDefinition, type CogniteClient } from '@cognite/sdk'; +import { + type QueryRequest, + type TableExpressionFilterDefinition, + type CogniteClient +} from '@cognite/sdk'; import { type FdmPropertyType } from '../components/Reveal3DResources/types'; import { queryNodesAndEdges, - QueryResult, - SelectSourceWithParams + type QueryResult, + type SelectSourceWithParams } from './utils/queryNodesAndEdges'; +import { mergeQueryResults } from './utils/mergeQueryResult'; type InstanceType = 'node' | 'edge'; type EdgeDirection = 'source' | 'destination'; @@ -115,7 +120,7 @@ export type FdmNode> = { externalId: string; createdTime: number; lastUpdatedTime: number; - deletedTime: number | undefined; + deletedTime?: number; properties: PropertyType; }; @@ -375,21 +380,21 @@ export class FdmSDK { // eslint-disable-next-line no-dupe-class-members public async filterAllInstances>( - filter: InstanceFilter, + filter: InstanceFilter | undefined, instanceType: InstanceType, source: Source ): Promise<{ instances: Array | FdmNode> }>; // eslint-disable-next-line no-dupe-class-members public async filterAllInstances>( - filter: InstanceFilter, + filter: InstanceFilter | undefined, instanceType: 'edge', source: Source ): Promise<{ instances: Array> }>; // eslint-disable-next-line no-dupe-class-members public async filterAllInstances>( - filter: InstanceFilter, + filter: InstanceFilter | undefined, instanceType: 'node', source: Source ): Promise<{ instances: Array> }>; @@ -544,7 +549,7 @@ export class FdmSDK { TQueryRequest extends QueryRequest, TypedSelectSources extends SelectSourceWithParams = SelectSourceWithParams >(query: TQueryRequest): Promise> { - return queryNodesAndEdges(query, this._sdk); + return await queryNodesAndEdges(query, this._sdk); } public async listDataModels(): Promise { diff --git a/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts b/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts index 551405a0ecd..48584c281c0 100644 --- a/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts +++ b/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts @@ -1,14 +1,24 @@ -import { AddModelOptions } from '@cognite/reveal'; -import { FdmCadConnection } from '../../components/CacheProvider/types'; -import { Fdm3dDataProvider } from '../Fdm3dDataProvider'; -import { DmsUniqueIdentifier, FdmSDK, InstanceFilter, NodeItem, Source, ViewItem } from '../FdmSDK'; -import { InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; -import { TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; +/*! + * Copyright 2024 Cognite AS + */ +import { type AddModelOptions } from '@cognite/reveal'; +import { type FdmCadConnection } from '../../components/CacheProvider/types'; +import { type Fdm3dDataProvider } from '../Fdm3dDataProvider'; +import { + type DmsUniqueIdentifier, + type FdmSDK, + type InstanceFilter, + type NodeItem, + type Source, + type ViewItem +} from '../FdmSDK'; +import { type InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; +import { type TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; import { COGNITE_3D_OBJECT_SOURCE } from './dataModels'; import { getDMSModels } from './getDMSModels'; import { getEdgeConnected3dInstances } from './getEdgeConnected3dInstances'; import { getFdmConnectionsForNodes } from './getFdmConnectionsForNodeIds'; -import { Node3D } from '@cognite/sdk'; +import { type Node3D } from '@cognite/sdk'; import { getDMSRevision } from './getDMSRevision'; import { listAllMappedFdmNodes, listMappedFdmNodes } from './listMappedFdmNodes'; import { isDefined } from '../../utilities/isDefined'; @@ -76,34 +86,33 @@ export class CoreDm3dFdm3dDataProvider implements Fdm3dDataProvider { private async getDMSModelsForIds( modelIds: number[] - ): Promise<(DmsUniqueIdentifier | undefined)[]> { + ): Promise> { return ( await executeParallel( - modelIds.map((id) => () => this.getDMSModels(id)), + modelIds.map((id) => async () => await this.getDMSModels(id)), MAX_PARALLEL_QUERIES ) ).flat(); } private async getDMSRevisionsForRevisionIdsAndModelRefs( - modelRefs: (DmsUniqueIdentifier | undefined)[], + modelRefs: Array, revisionIds: number[] ): Promise { return ( await executeParallel( - revisionIds.map( - (revisionId, ind) => () => - modelRefs[ind] === undefined - ? Promise.resolve(undefined) - : this.getDMSRevision(modelRefs[ind], revisionId) - ), + revisionIds.map((revisionId, ind) => async () => { + return modelRefs[ind] === undefined + ? undefined + : await this.getDMSRevision(modelRefs[ind], revisionId); + }), MAX_PARALLEL_QUERIES ) ).filter(isDefined); } - getEdgeConnected3dInstances(instance: DmsUniqueIdentifier): Promise { - return getEdgeConnected3dInstances(instance, this._fdmSdk); + async getEdgeConnected3dInstances(instance: DmsUniqueIdentifier): Promise { + return await getEdgeConnected3dInstances(instance, this._fdmSdk); } async getFdmConnectionsForNodes( @@ -119,7 +128,7 @@ export class CoreDm3dFdm3dDataProvider implements Fdm3dDataProvider { const revisionRef = await this.getDMSRevision(model, revisionId); - return getFdmConnectionsForNodes(model, revisionRef, revisionId, nodes, this._fdmSdk); + return await getFdmConnectionsForNodes(model, revisionRef, revisionId, nodes, this._fdmSdk); } async listMappedFdmNodes( @@ -135,7 +144,13 @@ export class CoreDm3dFdm3dDataProvider implements Fdm3dDataProvider { models.map((model) => model.revisionId) ); - return listMappedFdmNodes(revisionRefs, sourcesToSearch, instanceFilter, limit, this._fdmSdk); + return await listMappedFdmNodes( + revisionRefs, + sourcesToSearch, + instanceFilter, + limit, + this._fdmSdk + ); } async listAllMappedFdmNodes( @@ -150,7 +165,7 @@ export class CoreDm3dFdm3dDataProvider implements Fdm3dDataProvider { models.map((model) => model.revisionId) ); - return listAllMappedFdmNodes(revisionRefs, sourcesToSearch, instanceFilter, this._fdmSdk); + return await listAllMappedFdmNodes(revisionRefs, sourcesToSearch, instanceFilter, this._fdmSdk); } async filterNodesByMappedTo3d( @@ -165,11 +180,13 @@ export class CoreDm3dFdm3dDataProvider implements Fdm3dDataProvider { models.map((model) => model.revisionId) ); - return filterNodesByMappedTo3d(nodes, revisionRefs, spacesToSearch, this._fdmSdk); + return await filterNodesByMappedTo3d(nodes, revisionRefs, spacesToSearch, this._fdmSdk); } - getCadModelsForInstance(instance: DmsUniqueIdentifier): Promise { - return getCadModelsForInstance(instance, this._fdmSdk); + async getCadModelsForInstance( + instance: DmsUniqueIdentifier + ): Promise { + return await getCadModelsForInstance(instance, this._fdmSdk); } async getCadConnectionsForRevisions( @@ -187,6 +204,6 @@ export class CoreDm3dFdm3dDataProvider implements Fdm3dDataProvider { isDefined(modelRevision[0]) && isDefined(modelRevision[1]) ); - return getCadConnectionsForRevisions(modelRevisions, this._fdmSdk); + return await getCadConnectionsForRevisions(modelRevisions, this._fdmSdk); } } diff --git a/react-components/src/data-providers/core-dm-provider/Duplex3dDataProvider.ts b/react-components/src/data-providers/core-dm-provider/Duplex3dDataProvider.ts deleted file mode 100644 index 697b458ecf0..00000000000 --- a/react-components/src/data-providers/core-dm-provider/Duplex3dDataProvider.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { AddModelOptions } from '@cognite/reveal'; -import { FdmCadConnection } from '../../components/CacheProvider/types'; -import { Fdm3dDataProvider } from '../Fdm3dDataProvider'; -import { DmsUniqueIdentifier, FdmSDK, InstanceFilter, NodeItem, Source, ViewItem } from '../FdmSDK'; -import { InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; -import { TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; -import { CoreDm3dFdm3dDataProvider } from './CoreDm3dDataProvider'; -import { LegacyFdm3dDataProvider } from '../legacy-fdm-provider/LegacyFdm3dDataProvider'; -import { Node3D } from '@cognite/sdk'; - -// TODO - re-evaluate if this class is actually necessary... -export class Duplex3dDataProvider implements Fdm3dDataProvider { - readonly _fdmSdk: FdmSDK; - - readonly _dataProvider: Fdm3dDataProvider; - - constructor(isMaja: boolean, relevant3dSpaces: DmsUniqueIdentifier[], fdmSdk: FdmSDK) { - this._fdmSdk = fdmSdk; - this._dataProvider = isMaja - ? new CoreDm3dFdm3dDataProvider(relevant3dSpaces, fdmSdk) - : new LegacyFdm3dDataProvider(fdmSdk); - } - - is3dView(view: ViewItem): boolean { - return this._dataProvider.is3dView(view); - } - - getDMSModels(modelId: number): Promise { - return this._dataProvider.getDMSModels(modelId); - } - - getEdgeConnected3dInstances(instance: DmsUniqueIdentifier): Promise { - return this._dataProvider.getEdgeConnected3dInstances(instance); - } - - getFdmConnectionsForNodes( - models: DmsUniqueIdentifier[], - revisionId: number, - nodes: Node3D[] - ): Promise { - return this._dataProvider.getFdmConnectionsForNodes(models, revisionId, nodes); - } - - listMappedFdmNodes( - models: AddModelOptions[], - sourcesToSearch: Source[], - instancesFilter: InstanceFilter | undefined, - limit: number - ): Promise { - return this._dataProvider.listMappedFdmNodes(models, sourcesToSearch, instancesFilter, limit); - } - - listAllMappedFdmNodes( - models: AddModelOptions[], - sourcesToSearch: Source[], - instanceFilter: InstanceFilter | undefined - ): Promise { - return this._dataProvider.listAllMappedFdmNodes(models, sourcesToSearch, instanceFilter); - } - - filterNodesByMappedTo3d( - nodes: InstancesWithView[], - models: AddModelOptions[], - spacesToSearch: string[] - ): Promise { - return this._dataProvider.filterNodesByMappedTo3d(nodes, models, spacesToSearch); - } - - getCadModelsForInstance(instance: DmsUniqueIdentifier): Promise { - return this._dataProvider.getCadModelsForInstance(instance); - } - - getCadConnectionsForRevisions(modelOptions: AddModelOptions[]): Promise { - return this._dataProvider.getCadConnectionsForRevisions(modelOptions); - } -} diff --git a/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts index 18d17edc1d1..7a94853d5e5 100644 --- a/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts +++ b/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts @@ -1,4 +1,7 @@ -import { SourceSelectorV3 } from '@cognite/sdk/dist/src'; +/*! + * Copyright 2024 Cognite AS + */ +import { type SourceSelectorV3 } from '@cognite/sdk/dist/src'; import { COGNITE_ASSET_SOURCE } from './dataModels'; export const cogniteAssetSourceWithProperties = [ diff --git a/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts index 2a858922f20..fd6eed0ef25 100644 --- a/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts +++ b/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts @@ -1,4 +1,7 @@ -import { SourceSelectorV3 } from '@cognite/sdk/dist/src'; +/*! + * Copyright 2024 Cognite AS + */ +import { type SourceSelectorV3 } from '@cognite/sdk/dist/src'; import { COGNITE_CAD_NODE_SOURCE } from './dataModels'; export const cogniteCadNodeSourceWithPRoperties = [ diff --git a/react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts index 7b33ec31577..64caf0f441f 100644 --- a/react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts +++ b/react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts @@ -1,4 +1,7 @@ -import { SourceSelectorV3 } from '@cognite/sdk/dist/src'; +/*! + * Copyright 2024 Cognite AS + */ +import { type SourceSelectorV3 } from '@cognite/sdk/dist/src'; import { COGNITE_3D_OBJECT_SOURCE } from './dataModels'; export const cogniteObject3dSourceWithProperties = [ diff --git a/react-components/src/data-providers/core-dm-provider/dataModels.ts b/react-components/src/data-providers/core-dm-provider/dataModels.ts index 0a6cbb87014..7c8bd64e08d 100644 --- a/react-components/src/data-providers/core-dm-provider/dataModels.ts +++ b/react-components/src/data-providers/core-dm-provider/dataModels.ts @@ -1,5 +1,8 @@ -import { Timestamp, ViewReference } from '@cognite/sdk'; -import { DmsUniqueIdentifier, Source } from '../FdmSDK'; +/*! + * Copyright 2024 Cognite AS + */ +import { type Timestamp, type ViewReference } from '@cognite/sdk'; +import { type DmsUniqueIdentifier } from '../FdmSDK'; export const CORE_DM_SPACE = 'cdf_cdm_experimental'; diff --git a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts index bbc0be467b5..78b655ba02b 100644 --- a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts +++ b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts @@ -1,25 +1,32 @@ -import { AddModelOptions } from '@cognite/reveal'; -import { InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; -import { QueryRequest, QueryTableExpressionV3, SourceSelectorV3 } from '@cognite/sdk/dist/src'; +/*! + * Copyright 2024 Cognite AS + */ +import { type InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; +import { + type QueryRequest, + type QueryTableExpressionV3, + type SourceSelectorV3 +} from '@cognite/sdk/dist/src'; import { getDirectRelationProperties } from '../utils/getDirectRelationProperties'; import { - Cognite3DObjectProperties, + type Cognite3DObjectProperties, COGNITE_3D_OBJECT_SOURCE, COGNITE_CAD_NODE_SOURCE, COGNITE_POINT_CLOUD_VOLUME_SOURCE, COGNITE_VISUALIZABLE_SOURCE } from './dataModels'; -import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; +import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { cogniteObject3dSourceWithProperties } from './cogniteObject3dSourceWithProperties'; -import { FdmKey } from '../../components/CacheProvider/types'; +import { type FdmKey } from '../../components/CacheProvider/types'; import { toFdmKey } from '../utils/toFdmKey'; -import { ArrayElement, PromiseType } from '../utils/typeUtils'; +import { type ArrayElement, type PromiseType } from '../utils/typeUtils'; import { head } from 'lodash'; +import { type QueryResult } from '../utils/queryNodesAndEdges'; export async function filterNodesByMappedTo3d( nodes: InstancesWithView[], revisionRefs: DmsUniqueIdentifier[], - spacesToSearch: string[], + _spacesToSearch: string[], fdmSdk: FdmSDK ): Promise { const connectionData = await fetchConnectionData(nodes, revisionRefs, fdmSdk); @@ -87,11 +94,20 @@ function createRelevantAssetKeySet( return relevantAssetKeySet; } +type SelectSourcesType = [ + { source: typeof COGNITE_3D_OBJECT_SOURCE; properties: Cognite3DObjectProperties }, + { source: typeof COGNITE_CAD_NODE_SOURCE; properties: { object3D: DmsUniqueIdentifier } }, + { + source: typeof COGNITE_POINT_CLOUD_VOLUME_SOURCE; + properties: { object3D: DmsUniqueIdentifier }; + } +]; + async function fetchConnectionData( nodes: InstancesWithView[], revisionRefs: DmsUniqueIdentifier[], fdmSdk: FdmSDK -) { +): Promise> { const initialExternalIds = nodes.flatMap((node) => node.instances.map((instance) => instance.externalId) ); @@ -107,17 +123,7 @@ async function fetchConnectionData( parameters }; - return fdmSdk.queryAllNodesAndEdges< - typeof query, - [ - { source: typeof COGNITE_3D_OBJECT_SOURCE; properties: Cognite3DObjectProperties }, - { source: typeof COGNITE_CAD_NODE_SOURCE; properties: { object3D: DmsUniqueIdentifier } }, - { - source: typeof COGNITE_POINT_CLOUD_VOLUME_SOURCE; - properties: { object3D: DmsUniqueIdentifier }; - } - ] - >(query); + return await fdmSdk.queryAllNodesAndEdges(query); } const pointCloudVolumeSourceWithProperties = [ @@ -220,7 +226,7 @@ function getRevisionsCadNodeFromObject3D(object3dTableName: string): QueryTableE return { nodes: { from: object3dTableName, - through: { source: COGNITE_3D_OBJECT_SOURCE, identifier: 'cadNodes' }, + through: { view: COGNITE_3D_OBJECT_SOURCE, identifier: 'cadNodes' }, filter: { containsAny: { property: [ @@ -239,7 +245,7 @@ function getRevisionsPointCloudVolumes(object3dTableName: string): QueryTableExp return { nodes: { from: object3dTableName, - through: { source: COGNITE_3D_OBJECT_SOURCE, identifier: 'pointCloudVolumes' }, + through: { view: COGNITE_3D_OBJECT_SOURCE, identifier: 'pointCloudVolumes' }, filter: { containsAny: { property: [ @@ -258,16 +264,7 @@ function getObject3dRelation(visualizableTableName: string): QueryTableExpressio return { nodes: { from: visualizableTableName, - through: { source: COGNITE_VISUALIZABLE_SOURCE, identifier: 'object3d' } - } - }; -} - -function getAssetRelation(object3dTableName: string): QueryTableExpressionV3 { - return { - nodes: { - from: object3dTableName, - through: { source: COGNITE_3D_OBJECT_SOURCE, identifier: 'assets' } + through: { view: COGNITE_VISUALIZABLE_SOURCE, identifier: 'object3d' } } }; } diff --git a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts index 2b23058b184..c72452979d3 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts @@ -1,21 +1,25 @@ -import { QueryRequest } from '@cognite/sdk/dist/src'; -import { FdmCadConnection, FdmKey } from '../../components/CacheProvider/types'; -import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; +/*! + * Copyright 2024 Cognite AS + */ +import { type QueryRequest } from '@cognite/sdk/dist/src'; +import { type FdmCadConnection, type FdmKey } from '../../components/CacheProvider/types'; +import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { - Cognite3DObjectProperties, - COGNITE_3D_OBJECT_SOURCE, + type Cognite3DObjectProperties, + type COGNITE_3D_OBJECT_SOURCE, COGNITE_CAD_NODE_SOURCE, - CogniteCADNodeProperties + type CogniteCADNodeProperties } from './dataModels'; import { cogniteObject3dSourceWithProperties } from './cogniteObject3dSourceWithProperties'; import { cogniteCadNodeSourceWithPRoperties } from './cogniteCadNodeSourceWithProperties'; import { getModelIdFromExternalId, getRevisionIdFromExternalId } from './getCdfIdFromExternalId'; import { toFdmKey } from '../utils/toFdmKey'; -import { PromiseType } from '../utils/typeUtils'; +import { type PromiseType } from '../utils/typeUtils'; import { isDefined } from '../../utilities/isDefined'; +import { type QueryResult } from '../utils/queryNodesAndEdges'; export async function getCadConnectionsForRevisions( - modelRevisions: [DmsUniqueIdentifier, DmsUniqueIdentifier][], + modelRevisions: Array<[DmsUniqueIdentifier, DmsUniqueIdentifier]>, fdmSdk: FdmSDK ): Promise { const results = await getModelConnectionResults(modelRevisions, fdmSdk); @@ -37,10 +41,15 @@ export async function getCadConnectionsForRevisions( }); } -function getModelConnectionResults( - modelRevisions: [DmsUniqueIdentifier, DmsUniqueIdentifier][], +type SourcesSelectType = [ + { source: typeof COGNITE_3D_OBJECT_SOURCE; properties: Cognite3DObjectProperties }, + { source: typeof COGNITE_CAD_NODE_SOURCE; properties: CogniteCADNodeProperties } +]; + +async function getModelConnectionResults( + modelRevisions: Array<[DmsUniqueIdentifier, DmsUniqueIdentifier]>, fdmSdk: FdmSDK -) { +): Promise> { const parameters = { modelRefs: modelRevisions.map(([modelRef, _revisionRef]) => modelRef), revisionRefs: modelRevisions.map(([_modelRef, revisionRef]) => revisionRef) @@ -51,17 +60,11 @@ function getModelConnectionResults( parameters }; - return fdmSdk.queryAllNodesAndEdges< - typeof query, - [ - { source: typeof COGNITE_3D_OBJECT_SOURCE; properties: Cognite3DObjectProperties }, - { source: typeof COGNITE_CAD_NODE_SOURCE; properties: CogniteCADNodeProperties } - ] - >(query); + return await fdmSdk.queryAllNodesAndEdges(query); } function createNodeToModelMap( - modelRevisions: [DmsUniqueIdentifier, DmsUniqueIdentifier][], + modelRevisions: Array<[DmsUniqueIdentifier, DmsUniqueIdentifier]>, cadNodes: PromiseType>['items']['cad_nodes'] ): Map> { return cadNodes.reduce((nodeMap, cadNode) => { @@ -130,7 +133,7 @@ const cadConnectionsQuery = { object_3ds: { nodes: { from: 'cad_nodes', - through: { source: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' } + through: { view: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' } } } }, diff --git a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts index 6e0612a38e9..60cad243f7e 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts @@ -1,11 +1,14 @@ -import { QueryRequest } from '@cognite/sdk/dist/src'; -import { TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; -import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; +/*! + * Copyright 2024 Cognite AS + */ +import { type QueryRequest } from '@cognite/sdk/dist/src'; +import { type TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; +import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { COGNITE_3D_OBJECT_SOURCE, - COGNITE_CAD_NODE_SOURCE, + type COGNITE_CAD_NODE_SOURCE, COGNITE_VISUALIZABLE_SOURCE, - CogniteCADNodeProperties + type CogniteCADNodeProperties } from './dataModels'; import { cogniteCadNodeSourceWithPRoperties } from './cogniteCadNodeSourceWithProperties'; import { getModelIdFromExternalId, getRevisionIdFromExternalId } from './getCdfIdFromExternalId'; @@ -57,7 +60,7 @@ const cadModelsForInstanceQuery = { cad_nodes: { nodes: { from: 'object_3ds', - through: { source: COGNITE_3D_OBJECT_SOURCE, identifier: 'cadNodes' } + through: { view: COGNITE_3D_OBJECT_SOURCE, identifier: 'cadNodes' } } } }, diff --git a/react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts b/react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts index 0917935451b..bbc57c8a526 100644 --- a/react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts +++ b/react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts @@ -1,9 +1,15 @@ -export function getModelIdFromExternalId(externalId: string) { +/*! + * Copyright 2024 Cognite AS + */ + +import { type ModelId, type RevisionId } from '../../components/CacheProvider/types'; + +export function getModelIdFromExternalId(externalId: string): ModelId { // The externalId should be on the form `cog_3d_model_${modelId}` return Number(externalId.slice('cog_3d_model_'.length)); } -export function getRevisionIdFromExternalId(externalId: string) { +export function getRevisionIdFromExternalId(externalId: string): RevisionId { // The externalId should be on the form `cog_3d_revision_${modelId}` return Number(externalId.slice('cog_3d_revision_'.length)); } diff --git a/react-components/src/data-providers/core-dm-provider/getDMSModels.ts b/react-components/src/data-providers/core-dm-provider/getDMSModels.ts index 4451ee8b0d2..efd5546a004 100644 --- a/react-components/src/data-providers/core-dm-provider/getDMSModels.ts +++ b/react-components/src/data-providers/core-dm-provider/getDMSModels.ts @@ -1,6 +1,9 @@ -import { QueryRequest } from '@cognite/sdk/dist/src'; -import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; -import { Cognite3DModelProperties, COGNITE_3D_MODEL_SOURCE } from './dataModels'; +/*! + * Copyright 2024 Cognite AS + */ +import { type QueryRequest } from '@cognite/sdk/dist/src'; +import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; +import { type Cognite3DModelProperties, COGNITE_3D_MODEL_SOURCE } from './dataModels'; export async function getDMSModels( modelId: number, diff --git a/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts index ce2e4c1f5d6..9c060e52df0 100644 --- a/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts +++ b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts @@ -1,6 +1,9 @@ -import { QueryRequest } from '@cognite/sdk/dist/src'; -import { DmsUniqueIdentifier, FdmSDK, NodeItem } from '../FdmSDK'; -import { COGNITE_CAD_REVISION_SOURCE, CogniteCADRevisionProperties } from './dataModels'; +/*! + * Copyright 2024 Cognite AS + */ +import { type QueryRequest } from '@cognite/sdk/dist/src'; +import { type DmsUniqueIdentifier, type FdmSDK, type NodeItem } from '../FdmSDK'; +import { COGNITE_CAD_REVISION_SOURCE, type CogniteCADRevisionProperties } from './dataModels'; export async function getDMSRevision( model: DmsUniqueIdentifier, diff --git a/react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts b/react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts index f6e36201d00..bc874ab1b05 100644 --- a/react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts +++ b/react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts @@ -1,8 +1,11 @@ -import { QueryRequest } from '@cognite/sdk/dist/src'; -import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; +/*! + * Copyright 2024 Cognite AS + */ +import { type QueryRequest } from '@cognite/sdk/dist/src'; +import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { - Cognite3DObjectProperties, - COGNITE_3D_OBJECT_SOURCE, + type Cognite3DObjectProperties, + type COGNITE_3D_OBJECT_SOURCE, COGNITE_VISUALIZABLE_SOURCE } from './dataModels'; diff --git a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts index c7281b9eba5..8bcec4446cf 100644 --- a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts +++ b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts @@ -1,13 +1,16 @@ -import { Node3D, QueryRequest } from '@cognite/sdk'; -import { FdmCadConnection, FdmKey } from '../../components/CacheProvider/types'; -import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; +/*! + * Copyright 2024 Cognite AS + */ +import { type Node3D, type QueryRequest } from '@cognite/sdk'; +import { type FdmCadConnection, type FdmKey } from '../../components/CacheProvider/types'; +import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { - Cognite3DObjectProperties, + type Cognite3DObjectProperties, COGNITE_3D_OBJECT_SOURCE, - COGNITE_ASSET_SOURCE, + type COGNITE_ASSET_SOURCE, COGNITE_CAD_NODE_SOURCE, - CogniteAssetProperties, - CogniteCADNodeProperties + type CogniteAssetProperties, + type CogniteCADNodeProperties } from './dataModels'; import { getModelIdFromExternalId } from './getCdfIdFromExternalId'; import { toFdmKey } from '../utils/toFdmKey'; @@ -22,8 +25,6 @@ export async function getFdmConnectionsForNodes( const treeIndexes = nodes.map((node) => node.treeIndex); const treeIndexSet = new Set(treeIndexes); - const treeIndexToNodeIdMap = new Map(nodes.map((node) => [node.treeIndex, node.id])); - const relevantCadNodeRefToObject3dRef = new Map(); const treeIndexToCadNodeMap = new Map(); @@ -57,10 +58,9 @@ export async function getFdmConnectionsForNodes( }); const relevantObjects3D = result.items.objects_3d.filter((object3D) => { - return ( - object3D.properties.cdf_cdm_experimental['CogniteObject3D/v1'] - .cadNodes as DmsUniqueIdentifier[] - ).some((cadNodeId) => relevantCadNodeRefToObject3dRef.has(toFdmKey(cadNodeId))); + return object3D.properties.cdf_cdm_experimental['CogniteObject3D/v1'].cadNodes.some( + (cadNodeId) => relevantCadNodeRefToObject3dRef.has(toFdmKey(cadNodeId)) + ); }); const relevantObjectToAssetsMap = new Map( @@ -136,13 +136,13 @@ const cadConnectionQuery = { objects_3d: { nodes: { from: 'cad_nodes', - through: { source: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' } + through: { view: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' } } }, assets: { nodes: { from: 'objects_3d', - through: { source: COGNITE_3D_OBJECT_SOURCE, identifier: 'asset' }, + through: { view: COGNITE_3D_OBJECT_SOURCE, identifier: 'asset' }, direction: 'outwards' } } diff --git a/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts b/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts index 4d74dc97f54..ef52ce24eef 100644 --- a/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts +++ b/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts @@ -1,18 +1,21 @@ +/*! + * Copyright 2024 Cognite AS + */ import { - DmsUniqueIdentifier, - FdmSDK, - InstanceFilter, + type DmsUniqueIdentifier, + type FdmSDK, + type InstanceFilter, makeSureNonEmptyFilterForRequest, - NodeItem, - Source + type NodeItem, + type Source } from '../FdmSDK'; -import { QueryRequest } from '@cognite/sdk'; +import { type QueryRequest } from '@cognite/sdk'; import { COGNITE_3D_OBJECT_SOURCE, - COGNITE_ASSET_SOURCE, + type COGNITE_ASSET_SOURCE, COGNITE_CAD_NODE_SOURCE, COGNITE_POINT_CLOUD_VOLUME_SOURCE, - CogniteAssetProperties + type CogniteAssetProperties } from './dataModels'; import { cogniteAssetSourceWithProperties } from './cogniteAssetSourceWithProperties'; @@ -74,7 +77,9 @@ function createRawQuery( sourcesToSearch: Source[], filter: InstanceFilter | undefined, limit: number -) { +): QueryRequest { + // This return value throws away useful type information about the result, but I haven't found a way to + // make the full type easily expressible return { with: { cad_nodes: { @@ -86,13 +91,13 @@ function createRawQuery( cad_object_3d: { nodes: { from: 'cad_nodes', - through: { source: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' } + through: { view: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' } } }, cad_assets: { nodes: { from: 'cad_object_3d', - through: { source: COGNITE_3D_OBJECT_SOURCE, identifier: 'asset' }, + through: { view: COGNITE_3D_OBJECT_SOURCE, identifier: 'asset' }, filter } }, @@ -105,13 +110,13 @@ function createRawQuery( pointcloud_object_3d: { nodes: { from: 'pointcloud_volumes', - through: { source: COGNITE_POINT_CLOUD_VOLUME_SOURCE, identifier: 'object3D' } + through: { view: COGNITE_POINT_CLOUD_VOLUME_SOURCE, identifier: 'object3D' } } }, pointcloud_assets: { nodes: { from: 'cad_object_3d', - through: { source: COGNITE_3D_OBJECT_SOURCE, identifier: 'asset' }, + through: { view: COGNITE_3D_OBJECT_SOURCE, identifier: 'asset' }, filter } } diff --git a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts index 232a9082b32..a171844cfa9 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts @@ -21,13 +21,15 @@ import { listAllMappedFdmNodes, listMappedFdmNodes } from './listMappedFdmNodes' import { filterNodesByMappedTo3d } from './filterNodesByMappedTo3d'; import { getCadModelsForFdmInstance } from './getCadModelsForFdmInstance'; import { getCadConnectionsForRevision } from './getCadConnectionsForRevision'; -import { Node3D } from '@cognite/sdk/dist/src'; +import { type CogniteClient, type Node3D } from '@cognite/sdk/dist/src'; export class LegacyFdm3dDataProvider implements Fdm3dDataProvider { readonly _fdmSdk: FdmSDK; + readonly _cogniteClient: CogniteClient; - constructor(fdmSdk: FdmSDK) { + constructor(fdmSdk: FdmSDK, cogniteClient: CogniteClient) { this._fdmSdk = fdmSdk; + this._cogniteClient = cogniteClient; } is3dView(view: ViewItem): boolean { @@ -47,7 +49,13 @@ export class LegacyFdm3dDataProvider implements Fdm3dDataProvider { revisionId: number, nodes: Node3D[] ): Promise { - return await getFdmConnectionsForNodes(this._fdmSdk, models, revisionId, nodes); + return await getFdmConnectionsForNodes( + this._fdmSdk, + this._cogniteClient, + models, + revisionId, + nodes + ); } async listMappedFdmNodes( @@ -83,6 +91,6 @@ export class LegacyFdm3dDataProvider implements Fdm3dDataProvider { async getCadConnectionsForRevisions( modelOptions: AddModelOptions[] ): Promise { - return await getCadConnectionsForRevision(modelOptions, this._fdmSdk); + return await getCadConnectionsForRevision(modelOptions, this._fdmSdk, this._cogniteClient); } } diff --git a/react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts b/react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts index db6586290f0..12cc1897b0a 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts @@ -4,7 +4,7 @@ import { type AddModelOptions } from '@cognite/reveal'; import { makeSureNonEmptyFilterForRequest, type InstanceFilter, type Source } from '../FdmSDK'; import { SYSTEM_3D_EDGE_SOURCE } from './dataModels'; -import { QueryRequest } from '@cognite/sdk'; +import { type QueryRequest } from '@cognite/sdk'; export function createMappedEquipmentQuery( models: AddModelOptions[], diff --git a/react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts b/react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts index c6009087191..b6e9f0f29e1 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts @@ -1,17 +1,96 @@ /*! * Copyright 2024 Cognite AS */ -import { type FdmCadConnection } from '../../components/CacheProvider/types'; -import { type EdgeItem } from '../FdmSDK'; +import { type CogniteClient } from '@cognite/sdk/dist/src'; +import { nodeIdsToTreeIndices } from '../../components/CacheProvider/requests'; +import { + type ModelId, + type ModelRevisionKey, + type NodeId, + type RevisionId, + type FdmCadConnection +} from '../../components/CacheProvider/types'; +import { type DmsUniqueIdentifier, type EdgeItem } from '../FdmSDK'; import { type InModel3dEdgeProperties } from './dataModels'; +import { + modelRevisionKeyToModelRevision, + modelRevisionToKey +} from '../../components/CacheProvider/utils'; +import { executeParallel } from '../../utilities/executeParallel'; +import { isDefined } from '../../utilities/isDefined'; -export function fdmEdgesToCadConnections( +const MAX_PARALLEL_QUERIES = 2; + +type NodeIdConnection = { + modelId: ModelId; + revisionId: RevisionId; + nodeId: NodeId; + instance: DmsUniqueIdentifier; +}; + +export async function fdmEdgesToCadConnections( + edges: Array>, + cogniteClient: CogniteClient +): Promise { + const nodeIdConnectionsMap = createModelToNodeIdConnectionsMap(edges); + + const results = await executeParallel( + [...nodeIdConnectionsMap.entries()].map( + ([modelRevisionKey, connectionList]) => + async () => + await getTreeIndexConnectionsForNodeIdConnections( + modelRevisionKey, + connectionList, + cogniteClient + ) + ), + MAX_PARALLEL_QUERIES + ); + + return results.flat().filter(isDefined); +} + +function createModelToNodeIdConnectionsMap( edges: Array> -): FdmCadConnection[] { - return edges.map((instance) => ({ - nodeId: instance.properties.revisionNodeId, - revisionId: instance.properties.revisionId, - modelId: Number(instance.endNode.externalId), - instance: instance.startNode +): Map { + return edges.reduce((connectionMap, edge) => { + const modelId = Number(edge.endNode.externalId); + const revisionKey = modelRevisionToKey(modelId, edge.properties.revisionId); + + const connectionObject = { + nodeId: edge.properties.revisionNodeId, + revisionId: edge.properties.revisionId, + modelId, + instance: edge.startNode + }; + + const objectList = connectionMap.get(revisionKey); + if (objectList === undefined) { + connectionMap.set(revisionKey, [connectionObject]); + } else { + objectList.push(connectionObject); + } + return connectionMap; + }, new Map()); +} + +async function getTreeIndexConnectionsForNodeIdConnections( + modelRevisionKey: ModelRevisionKey, + connectionList: NodeIdConnection[], + cogniteClient: CogniteClient +): Promise { + const [modelId, revisionId] = modelRevisionKeyToModelRevision(modelRevisionKey); + const treeIndices = await nodeIdsToTreeIndices( + modelId, + revisionId, + connectionList.map((connection) => connection.nodeId), + cogniteClient + ); + + return connectionList.map((connection, ind) => ({ + modelId: connection.modelId, + revisionId: connection.revisionId, + treeIndex: treeIndices[ind], + instance: connection.instance })); } diff --git a/react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts index 35bc8284393..441df873907 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts @@ -11,10 +11,14 @@ import { type NodeItem, type Source } from '../FdmSDK'; -import { SYSTEM_3D_EDGE_SOURCE, SYSTEM_SPACE_3D_SCHEMA } from './dataModels'; +import { + type InModel3dEdgeProperties, + SYSTEM_3D_EDGE_SOURCE, + SYSTEM_SPACE_3D_SCHEMA +} from './dataModels'; import { getDMSModels } from './getDMSModels'; import { type FdmKey } from '../../components/CacheProvider/types'; -import { QueryRequest } from '@cognite/sdk/dist/src'; +import { type QueryRequest } from '@cognite/sdk/dist/src'; import { getDirectRelationProperties } from '../utils/getDirectRelationProperties'; export async function filterNodesByMappedTo3d( @@ -38,12 +42,14 @@ export async function filterNodesByMappedTo3d( models, views ); - const queryResult = - await fdmSdk.queryNodesAndEdges(mappedEquipmentQuery); + const queryResult = await fdmSdk.queryNodesAndEdges< + typeof mappedEquipmentQuery, + [{ source: typeof SYSTEM_3D_EDGE_SOURCE; properties: InModel3dEdgeProperties }] + >(mappedEquipmentQuery); const { mappedEquipmentFirstLevelMap, equipmentSecondLevelMap } = await createMappedEquipmentMaps( fdmSdk, - queryResult.items.mapped_edges as EdgeItem[], + queryResult.items.mapped_edges, models, spacesToSearch ); @@ -65,6 +71,7 @@ export async function filterNodesByMappedTo3d( return filteredSearchResults; } +/* eslint-disable @typescript-eslint/explicit-function-return-type */ function createCheckMappedEquipmentQuery( instances: NodeItem[], directlyMappedNodes: DmsUniqueIdentifier[], @@ -104,7 +111,7 @@ function createCheckMappedEquipmentQuery( }, select: { mapped_edges: { - sources: [{ source: SYSTEM_3D_EDGE_SOURCE, properties: [] }] + sources: [{ source: SYSTEM_3D_EDGE_SOURCE, properties: ['revisionId', 'revisionNodeId'] }] }, mapped_nodes: { sources: views.map((view) => ({ source: view, properties: [] })) diff --git a/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts b/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts index 5e06ab372ee..dfaea8dc8a5 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts @@ -1,7 +1,7 @@ /*! * Copyright 2024 Cognite AS */ -import { AddModelOptions } from '@cognite/reveal'; +import { type AddModelOptions } from '@cognite/reveal'; import { type FdmCadConnection } from '../../components/CacheProvider/types'; import { type FdmSDK } from '../FdmSDK'; import { @@ -10,10 +10,12 @@ import { SYSTEM_SPACE_3D_SCHEMA } from './dataModels'; import { fdmEdgesToCadConnections } from './fdmEdgesToCadConnections'; +import { type CogniteClient } from '@cognite/sdk/dist/src'; export async function getCadConnectionsForRevision( modelOptions: AddModelOptions[], - fdmClient: FdmSDK + fdmClient: FdmSDK, + cogniteClient: CogniteClient ): Promise { if (modelOptions.length === 0) return []; @@ -31,5 +33,5 @@ export async function getCadConnectionsForRevision( 'edge', SYSTEM_3D_EDGE_SOURCE ); - return fdmEdgesToCadConnections(mappings.instances); + return await fdmEdgesToCadConnections(mappings.instances, cogniteClient); } diff --git a/react-components/src/data-providers/legacy-fdm-provider/getCadModelsForFdmInstance.ts b/react-components/src/data-providers/legacy-fdm-provider/getCadModelsForFdmInstance.ts index 6ef01ee9b70..d2101a1bc95 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/getCadModelsForFdmInstance.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/getCadModelsForFdmInstance.ts @@ -2,24 +2,25 @@ * Copyright 2024 Cognite AS */ import { type TaggedAddCadResourceOptions } from '../../components/Reveal3DResources/types'; -import { type DmsUniqueIdentifier, type EdgeItem, type FdmSDK } from '../FdmSDK'; +import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { type InModel3dEdgeProperties, SYSTEM_3D_EDGE_SOURCE } from './dataModels'; import { isDefined } from '../../utilities/isDefined'; - -type ModelForInstancesResponse = { - model_edges: Array>>>; -}; +import { type QueryRequest } from '@cognite/sdk/dist/src'; export async function getCadModelsForFdmInstance( sdk: FdmSDK, instance: DmsUniqueIdentifier ): Promise { + const query = { + ...modelsForInstanceQuery, + parameters: { instanceExternalId: instance.externalId, instanceSpace: instance.space } + }; const result = ( - await sdk.queryNodesAndEdges({ - ...modelsForInstanceQuery, - parameters: { instanceExternalId: instance.externalId, instanceSpace: instance.space } - }) - ).items as ModelForInstancesResponse; + await sdk.queryNodesAndEdges< + typeof query, + [{ source: typeof SYSTEM_3D_EDGE_SOURCE; properties: InModel3dEdgeProperties }] + >(query) + ).items; const modelAndRevisionIds = result.model_edges .map((edge) => { @@ -80,7 +81,7 @@ const modelsForInstanceQuery = { }, select: { model_edges: { - sources: [{ source: SYSTEM_3D_EDGE_SOURCE, properties: [] }] + sources: [{ source: SYSTEM_3D_EDGE_SOURCE, properties: ['revisionId', 'revisionNodeId'] }] } } -} as const; +} as const satisfies Omit; diff --git a/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts b/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts index f1d8643fb1f..b2aa696d134 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts @@ -3,7 +3,7 @@ */ import { SYSTEM_3D_EDGE_SOURCE } from './dataModels'; import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; -import { QueryRequest } from '@cognite/sdk/dist/src'; +import { type QueryRequest } from '@cognite/sdk/dist/src'; export async function getEdgeConnected3dInstances( instance: DmsUniqueIdentifier, diff --git a/react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts b/react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts index 46bf733634c..9250547102c 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts @@ -1,7 +1,7 @@ /*! * Copyright 2024 Cognite AS */ -import { Node3D } from '@cognite/sdk'; +import { type CogniteClient, type Node3D } from '@cognite/sdk'; import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { type FdmCadConnection } from '../../components/CacheProvider/types'; import { type InModel3dEdgeProperties, SYSTEM_3D_EDGE_SOURCE } from './dataModels'; @@ -9,6 +9,7 @@ import { fdmEdgesToCadConnections } from './fdmEdgesToCadConnections'; export async function getFdmConnectionsForNodes( fdmClient: FdmSDK, + cogniteClient: CogniteClient, models: DmsUniqueIdentifier[], revisionId: number, nodes: Node3D[] @@ -55,5 +56,5 @@ export async function getFdmConnectionsForNodes( SYSTEM_3D_EDGE_SOURCE ); - return fdmEdgesToCadConnections(results.instances); + return await fdmEdgesToCadConnections(results.instances, cogniteClient); } diff --git a/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts b/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts index 3648326a424..8f057f306ff 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts @@ -2,17 +2,11 @@ * Copyright 2024 Cognite AS */ import { type AddModelOptions } from '@cognite/reveal'; -import { - type FdmSDK, - type InstanceFilter, - type NodeItem, - type Query, - type Source -} from '../FdmSDK'; +import { type FdmSDK, type InstanceFilter, type NodeItem, type Source } from '../FdmSDK'; import { createMappedEquipmentQuery } from './createMappedEquipmentQuery'; import { chunk, isEqual } from 'lodash'; import { removeEmptyProperties } from '../../utilities/removeEmptyProperties'; -import { QueryRequest } from '@cognite/sdk/dist/src'; +import { type QueryRequest } from '@cognite/sdk/dist/src'; export async function listMappedFdmNodes( fdmSdk: FdmSDK, diff --git a/react-components/src/data-providers/utils/getDirectRelationProperties.ts b/react-components/src/data-providers/utils/getDirectRelationProperties.ts index 24075ee73b8..a2ea3942dea 100644 --- a/react-components/src/data-providers/utils/getDirectRelationProperties.ts +++ b/react-components/src/data-providers/utils/getDirectRelationProperties.ts @@ -1,4 +1,7 @@ -import { DmsUniqueIdentifier, NodeItem } from '../FdmSDK'; +/*! + * Copyright 2024 Cognite AS + */ +import { type DmsUniqueIdentifier, type NodeItem } from '../FdmSDK'; export function getDirectRelationProperties(searchResultNode: NodeItem): DmsUniqueIdentifier[] { const directRelations: DmsUniqueIdentifier[] = []; diff --git a/react-components/src/data-providers/utils/mergeQueryResult.ts b/react-components/src/data-providers/utils/mergeQueryResult.ts index 5c82aa86694..41a8f348bf7 100644 --- a/react-components/src/data-providers/utils/mergeQueryResult.ts +++ b/react-components/src/data-providers/utils/mergeQueryResult.ts @@ -1,4 +1,8 @@ -function mergeQueryResults>(dst: T, src: T): T { +/*! + * Copyright 2024 Cognite AS + */ + +export function mergeQueryResults>(dst: T, src: T): T { [...Object.keys(src)].forEach((key0) => { if (!(key0 in dst)) { Object.assign(dst, key0, []); diff --git a/react-components/src/data-providers/utils/queryNodesAndEdges.ts b/react-components/src/data-providers/utils/queryNodesAndEdges.ts index e0b5e6c9e3e..18d36e7f2bb 100644 --- a/react-components/src/data-providers/utils/queryNodesAndEdges.ts +++ b/react-components/src/data-providers/utils/queryNodesAndEdges.ts @@ -1,3 +1,6 @@ +/*! + * Copyright 2024 Cognite AS + */ import type { EdgeDefinition, NodeDefinition, diff --git a/react-components/src/data-providers/utils/toFdmKey.ts b/react-components/src/data-providers/utils/toFdmKey.ts index 6a67b8c42ba..5593449d90f 100644 --- a/react-components/src/data-providers/utils/toFdmKey.ts +++ b/react-components/src/data-providers/utils/toFdmKey.ts @@ -1,5 +1,8 @@ -import { FdmKey } from '../../components/CacheProvider/types'; -import { DmsUniqueIdentifier } from '../FdmSDK'; +/*! + * Copyright 2024 Cognite AS + */ +import { type FdmKey } from '../../components/CacheProvider/types'; +import { type DmsUniqueIdentifier } from '../FdmSDK'; export function toFdmKey(dmsId: DmsUniqueIdentifier): FdmKey { return `${dmsId.space}/${dmsId.externalId}`; diff --git a/react-components/src/data-providers/utils/typeUtils.ts b/react-components/src/data-providers/utils/typeUtils.ts index a53a5b0841c..16fb54e2c19 100644 --- a/react-components/src/data-providers/utils/typeUtils.ts +++ b/react-components/src/data-providers/utils/typeUtils.ts @@ -1,6 +1,8 @@ -// From https://stackoverflow.com/questions/41253310/typescript-retrieve-element-type-information-from-array-type +/*! + * Copyright 2024 Cognite AS + */ export type ArrayElement = - ArrayType extends readonly (infer ElementType)[] ? ElementType : never; + ArrayType extends ReadonlyArray ? ElementType : never; export type PromiseType> = PromiseType extends Promise ? ElementType : never; diff --git a/react-components/src/hooks/types.ts b/react-components/src/hooks/types.ts index 1355160bcba..4f5cae91408 100644 --- a/react-components/src/hooks/types.ts +++ b/react-components/src/hooks/types.ts @@ -2,7 +2,6 @@ * Copyright 2023 Cognite AS */ import { type Node3D, type CogniteExternalId, type Asset } from '@cognite/sdk'; -import { type DmsUniqueIdentifier } from '../data-providers/FdmSDK'; import { type AssetAnnotationImage360Info } from '@cognite/reveal'; export type ThreeDModelFdmMappings = { @@ -50,59 +49,6 @@ export type Reveal360AnnotationAssetData = { assetAnnotationImage360Info: AssetAnnotationImage360Info; }; -export type Transformation3d = { - translationX: number; - translationY: number; - translationZ: number; - eulerRotationX: number; - eulerRotationY: number; - eulerRotationZ: number; - scaleX: number; - scaleY: number; - scaleZ: number; -}; - -export type SceneModelsProperties = Transformation3d & { - revisionId: number; -}; - -export type SceneConfigurationProperties = { - name: string; - skybox?: DmsUniqueIdentifier; - cameraTranslationX: number; - cameraTranslationY: number; - cameraTranslationZ: number; - cameraEulerRotationX: number; - cameraEulerRotationY: number; - cameraEulerRotationZ: number; - cameraTargetX?: number; - cameraTargetY?: number; - cameraTargetZ?: number; -}; - -export type SkyboxProperties = { - label: string; - isSpherical: boolean; - file: string; -}; - -export type GroundPlaneProperties = { - file: string; - label: string; - wrapping: string; - repeatU?: number; - repeatV?: number; -}; - -export type Cdf3dRevisionProperties = Transformation3d & { - revisionId: number; -}; - -export type Cdf3dImage360CollectionProperties = Transformation3d & { - image360CollectionExternalId: string; - image360CollectionSpace: string; -}; - export type PointCloudAnnotationMappedAssetData = { annotationId: number; asset: Asset; diff --git a/react-components/src/hooks/useGroundPlaneFromScene.tsx b/react-components/src/hooks/useGroundPlaneFromScene.tsx index fbf6650efd8..a5a4b3cb78a 100644 --- a/react-components/src/hooks/useGroundPlaneFromScene.tsx +++ b/react-components/src/hooks/useGroundPlaneFromScene.tsx @@ -3,7 +3,7 @@ */ import { useEffect } from 'react'; -import { useSceneConfig } from '../query/useSceneConfig'; +import { useSceneConfig } from './scenes/useSceneConfig'; import { DoubleSide, Mesh, diff --git a/react-components/src/hooks/useReveal3dResourcesFromScene.ts b/react-components/src/hooks/useReveal3dResourcesFromScene.ts index 882226ff24c..265f9201bbf 100644 --- a/react-components/src/hooks/useReveal3dResourcesFromScene.ts +++ b/react-components/src/hooks/useReveal3dResourcesFromScene.ts @@ -2,7 +2,7 @@ * Copyright 2023 Cognite AS */ -import { useSceneConfig } from '../query/useSceneConfig'; +import { useSceneConfig } from './scenes/useSceneConfig'; import { type CogniteClient } from '@cognite/sdk'; import { type AddResourceOptions, @@ -10,8 +10,8 @@ import { } from '../components/Reveal3DResources/types'; import { CDF_TO_VIEWER_TRANSFORMATION, type AddModelOptions } from '@cognite/reveal'; import { useEffect, useState } from 'react'; -import { type Transformation3d } from './types'; import { Euler, MathUtils, Matrix4 } from 'three'; +import { type Transformation3d } from './scenes/types'; export type UseSyncSceneConfigWithViewerProps = { sdk: CogniteClient; diff --git a/react-components/src/hooks/useSceneDefaultCamera.tsx b/react-components/src/hooks/useSceneDefaultCamera.tsx index b24a62cc084..e5458eef2cc 100644 --- a/react-components/src/hooks/useSceneDefaultCamera.tsx +++ b/react-components/src/hooks/useSceneDefaultCamera.tsx @@ -3,7 +3,7 @@ */ import { useMemo } from 'react'; -import { useSceneConfig } from '../query/useSceneConfig'; +import { useSceneConfig } from './scenes/useSceneConfig'; import { Vector3, Quaternion, Euler, MathUtils, Matrix4 } from 'three'; import { CDF_TO_VIEWER_TRANSFORMATION } from '@cognite/reveal'; import { type SceneConfiguration } from '../components/SceneContainer/sceneTypes'; diff --git a/react-components/src/hooks/useSkyboxFromScene.tsx b/react-components/src/hooks/useSkyboxFromScene.tsx index 78a087d46c5..ef6a017ef86 100644 --- a/react-components/src/hooks/useSkyboxFromScene.tsx +++ b/react-components/src/hooks/useSkyboxFromScene.tsx @@ -3,7 +3,7 @@ */ import { useEffect } from 'react'; -import { useSceneConfig } from '../query/useSceneConfig'; +import { useSceneConfig } from './scenes/useSceneConfig'; import * as THREE from 'three'; import { useQuery } from '@tanstack/react-query'; import { useSDK } from '../components/RevealCanvas/SDKProvider'; diff --git a/react-components/src/index.ts b/react-components/src/index.ts index 4d153a24734..ecf53d2ec6d 100644 --- a/react-components/src/index.ts +++ b/react-components/src/index.ts @@ -51,7 +51,7 @@ export { useIsDraggingOnViewer } from './hooks/useIsDraggingOnViewer'; // Queries export { use3DModelName } from './query/use3DModelName'; -export { use3dScenes } from './query/use3dScenes'; +export { use3dScenes } from './hooks/scenes/use3dScenes'; export { use3dRelatedEdgeConnections } from './query/use3dRelatedEdgeConnections'; export { use3dRelatedDirectConnections } from './query/use3dRelatedDirectConnections'; export { use3dNodeByExternalId } from './query/use3dNodeByExternalId'; diff --git a/react-components/src/query/use3dScenes.tsx b/react-components/src/query/use3dScenes.tsx deleted file mode 100644 index e1024e353fb..00000000000 --- a/react-components/src/query/use3dScenes.tsx +++ /dev/null @@ -1,470 +0,0 @@ -/*! - * Copyright 2023 Cognite AS - */ - -import { type QueryFunction, useQuery, type UseQueryResult } from '@tanstack/react-query'; -import { useSDK } from '../components/RevealCanvas/SDKProvider'; -import { type CogniteClient } from '@cognite/sdk'; -import { useMemo } from 'react'; -import { type EdgeItem, FdmSDK, type Query, type NodeItem } from '../data-providers/FdmSDK'; -import { - type SceneConfigurationProperties, - type Cdf3dRevisionProperties, - type Transformation3d, - type Cdf3dImage360CollectionProperties, - type GroundPlaneProperties, - type SkyboxProperties -} from '../hooks/types'; -import { Euler, MathUtils, Matrix4 } from 'three'; -import { CDF_TO_VIEWER_TRANSFORMATION } from '@cognite/reveal'; -import { type GroundPlane, type Skybox } from '../components/SceneContainer/sceneTypes'; -import { - type AddCadResourceOptions, - type AddPointCloudResourceOptions, - type AddImage360CollectionDatamodelsOptions -} from '../components/Reveal3DResources/types'; - -export type Space = string; -export type ExternalId = string; - -export type SceneData = { - name: string; - cameraTranslationX: number; - cameraTranslationY: number; - cameraTranslationZ: number; - cameraEulerRotationX: number; - cameraEulerRotationY: number; - cameraEulerRotationZ: number; - cadModelOptions: Array; - image360CollectionOptions: AddImage360CollectionDatamodelsOptions[]; - groundPlanes: GroundPlane[]; - skybox?: Skybox; -}; - -type Use3dScenesQueryResult = { - scenes: Array>; - sceneModels: Array>>>; - scene360Collections: Array< - EdgeItem>> - >; - sceneGroundPlanes: Array>; - sceneGroundPlaneEdges: Array>>>; - sceneSkybox: Array>; -}; - -export const use3dScenes = ( - userSdk?: CogniteClient -): UseQueryResult>> => { - const sdk = useSDK(userSdk); - - const fdmSdk = useMemo(() => new FdmSDK(sdk), [sdk]); - - const queryFunction: QueryFunction>> = async () => { - const scenesQuery = createGetScenesQuery(); - - try { - const queryResult = (await fdmSdk.queryNodesAndEdges(scenesQuery)) - .items as Use3dScenesQueryResult; - - const scenesMap = createMapOfScenes(queryResult.scenes, queryResult.sceneSkybox); - populateSceneMapWithModels(queryResult.sceneModels, scenesMap); - populateSceneMapWith360Images(queryResult.scene360Collections, scenesMap); - populateSceneMapWithGroundplanes( - queryResult.sceneGroundPlanes, - queryResult.sceneGroundPlaneEdges, - scenesMap - ); - - return scenesMap; - } catch (error) { - console.warn("Scene space doesn't exist or has no scenes with 3D models"); - return {}; - } - }; - - return useQuery>>({ - queryKey: ['reveal-react-components', 'cdf', '3d', 'scenes'], - queryFn: queryFunction - }); -}; - -function createMapOfScenes( - scenes: Array>, - skyboxes: Array> -): Record> { - return scenes.reduce( - ( - acc: Record>, - scene: NodeItem - ) => { - const { space, externalId } = scene; - const properties = Object.values(Object.values(scene.properties)[0])[0]; - if (acc[space] === undefined) { - acc[space] = {}; - } - if (acc[space][externalId] === undefined) { - let skyboxObject: SkyboxProperties | undefined; - const skyboxIdentifier = properties.skybox; - if (skyboxIdentifier !== undefined) { - const connectedSkybox = skyboxes.find( - (skybox) => - skybox.externalId === skyboxIdentifier.externalId && - skybox.space === skyboxIdentifier.space - ); - if (connectedSkybox !== undefined) { - const skyboxProperties = Object.values(Object.values(connectedSkybox.properties)[0])[0]; - skyboxObject = skyboxProperties; - } - } - - acc[space][externalId] = { - name: properties.name, - cameraTranslationX: properties.cameraTranslationX, - cameraTranslationY: properties.cameraTranslationY, - cameraTranslationZ: properties.cameraTranslationZ, - cameraEulerRotationX: properties.cameraEulerRotationX, - cameraEulerRotationY: properties.cameraEulerRotationY, - cameraEulerRotationZ: properties.cameraEulerRotationZ, - cadModelOptions: [], - image360CollectionOptions: [], - groundPlanes: [], - skybox: skyboxObject - }; - } - - return acc; - }, - {} - ); -} - -function populateSceneMapWithModels( - scene360Images: Array>>>, - scenesMap: Record> -): void { - scene360Images.forEach((edge) => { - const { space, externalId } = edge.startNode; - - const properties = Object.values(Object.values(edge.properties)[0])[0]; - - const newModelId = Number(edge.endNode.externalId); - const newModelRevisionId = Number(properties?.revisionId); - - if (isNaN(newModelId) || isNaN(newModelRevisionId)) { - return; - } - - if (scenesMap[space]?.[externalId] === undefined) { - return; - } - - const transform = createTransformFromEdge(properties); - const newModel = { - modelId: newModelId, - revisionId: newModelRevisionId, - transformation: transform - }; - - scenesMap[space]?.[externalId].cadModelOptions.push(newModel); - }); -} - -function populateSceneMapWith360Images( - scene360Images: Array< - EdgeItem>> - >, - scenesMap: Record> -): void { - scene360Images.forEach((edge) => { - const { space, externalId } = edge.startNode; - - if (scenesMap[space]?.[externalId] === undefined) { - return; - } - - const properties = Object.values(Object.values(edge.properties)[0])[0]; - const transform = createTransformFromEdge(properties); - const newImage360Collection: AddImage360CollectionDatamodelsOptions = { - externalId: properties.image360CollectionExternalId, - space: properties.image360CollectionSpace, - transform - }; - - scenesMap[space]?.[externalId].image360CollectionOptions.push(newImage360Collection); - }); -} - -function populateSceneMapWithGroundplanes( - sceneGroundPlanes: Array>, - sceneGroundPlaneEdges: Array>>>, - scenesMap: Record> -): void { - sceneGroundPlaneEdges.forEach((edge) => { - const { space, externalId } = edge.startNode; - - const mappedGroundPlane = sceneGroundPlanes.find( - (groundPlane) => - groundPlane.externalId === edge.endNode.externalId && - groundPlane.space === edge.endNode.space - ); - - if (scenesMap[space]?.[externalId] === undefined || mappedGroundPlane === undefined) { - return; - } - - const groundPlaneEdgeProperties = Object.values(Object.values(edge.properties)[0])[0]; - const groundPlaneProperties = Object.values(Object.values(mappedGroundPlane.properties)[0])[0]; - - const groundPlane: GroundPlane = { - label: groundPlaneProperties.label, - file: groundPlaneProperties.file, - wrapping: groundPlaneProperties.wrapping, - repeatU: groundPlaneProperties.repeatU ?? 1, - repeatV: groundPlaneProperties.repeatV ?? 1, - ...groundPlaneEdgeProperties // Transformation3d - }; - - scenesMap[space]?.[externalId].groundPlanes.push(groundPlane); - }); -} - -function createTransformFromEdge(properties: Transformation3d): Matrix4 { - const transform = new Matrix4(); - - transform.makeRotationFromEuler( - new Euler( - MathUtils.degToRad(properties.eulerRotationX), - MathUtils.degToRad(properties.eulerRotationY), - MathUtils.degToRad(properties.eulerRotationZ) - ) - ); - - fixModelScale(properties); - - const scaleMatrix = new Matrix4().makeScale( - properties.scaleX, - properties.scaleY, - properties.scaleZ - ); - transform.multiply(scaleMatrix); - - const translation = new Matrix4().makeTranslation( - properties.translationX, - properties.translationY, - properties.translationZ - ); - transform.premultiply(translation); - - transform.premultiply(CDF_TO_VIEWER_TRANSFORMATION); - - return transform; -} - -function fixModelScale(modelProps: Transformation3d): Transformation3d { - if (modelProps.scaleX === 0) { - modelProps.scaleX = 1; - } - if (modelProps.scaleY === 0) { - modelProps.scaleY = 1; - } - if (modelProps.scaleZ === 0) { - modelProps.scaleZ = 1; - } - - return modelProps; -} - -function createGetScenesQuery(limit: number = 100): Query { - return { - with: { - scenes: { - nodes: { - filter: { - hasData: [ - { - type: 'view', - space: 'scene', - externalId: 'SceneConfiguration', - version: 'v1' - } - ] - } - }, - limit - }, - sceneModels: { - edges: { - from: 'scenes', - maxDistance: 1, - direction: 'outwards', - filter: { - equals: { - property: ['edge', 'type'], - value: { - space: 'scene', - externalId: 'SceneConfiguration.model3ds' - } - } - } - }, - limit - }, - scene360Collections: { - edges: { - from: 'scenes', - maxDistance: 1, - direction: 'outwards', - filter: { - equals: { - property: ['edge', 'type'], - value: { - space: 'scene', - externalId: 'SceneConfiguration.images360Collections' - } - } - } - }, - limit - }, - sceneSkybox: { - nodes: { - from: 'scenes', - through: { - view: { - type: 'view', - space: 'scene', - externalId: 'SceneConfiguration', - version: 'v1' - }, - identifier: 'skybox' - }, - direction: 'outwards' - }, - limit - }, - sceneGroundPlaneEdges: { - edges: { - from: 'scenes', - maxDistance: 1, - direction: 'outwards', - filter: { - equals: { - property: ['edge', 'type'], - value: { - space: 'scene', - externalId: 'SceneConfiguration.texturedGroundPlanes' - } - } - } - }, - limit - }, - sceneGroundPlanes: { - nodes: { - from: 'sceneGroundPlaneEdges', - chainTo: 'destination' - }, - limit - } - }, - select: { - scenes: { - sources: [ - { - source: { - type: 'view', - space: 'scene', - externalId: 'SceneConfiguration', - version: 'v1' - }, - properties: [ - 'name', - 'skybox', - 'cameraTranslationX', - 'cameraTranslationY', - 'cameraTranslationZ', - 'cameraEulerRotationX', - 'cameraEulerRotationY', - 'cameraEulerRotationZ' - ] - } - ] - }, - sceneModels: { - sources: [ - { - source: { - type: 'view', - space: 'scene', - externalId: 'RevisionProperties', - version: 'v1' - }, - properties: ['*'] - } - ] - }, - scene360Collections: { - sources: [ - { - source: { - type: 'view', - space: 'scene', - externalId: 'Image360CollectionProperties', - version: 'v1' - }, - properties: ['*'] - } - ] - }, - sceneSkybox: { - sources: [ - { - source: { - type: 'view', - space: 'scene', - externalId: 'EnvironmentMap', - version: 'v1' - }, - properties: ['label', 'file', 'isSpherical'] - } - ] - }, - sceneGroundPlaneEdges: { - sources: [ - { - source: { - type: 'view', - space: 'cdf_3d_schema', - externalId: 'Transformation3d', - version: 'v1' - }, - properties: [ - 'translationX', - 'translationY', - 'translationZ', - 'eulerRotationX', - 'eulerRotationY', - 'eulerRotationZ', - 'scaleX', - 'scaleY', - 'scaleZ' - ] - } - ] - }, - sceneGroundPlanes: { - sources: [ - { - source: { - type: 'view', - space: 'scene', - externalId: 'TexturedPlane', - version: 'v1' - }, - properties: ['*'] - } - ] - } - } - }; -} diff --git a/react-components/src/query/useSceneConfig.ts b/react-components/src/query/useSceneConfig.ts deleted file mode 100644 index a0e5245a37f..00000000000 --- a/react-components/src/query/useSceneConfig.ts +++ /dev/null @@ -1,228 +0,0 @@ -/*! - * Copyright 2023 Cognite AS - */ -import { createGetSceneQuery } from '../components/SceneContainer/Queries'; -import { - type GroundPlaneProperties, - type Transformation3d, - type SceneResponse, - type SkyboxProperties, - type SceneModelsProperties, - type Scene360ImageCollectionsProperties -} from '../components/SceneContainer/SceneFdmTypes'; -import { useQuery, type UseQueryResult } from '@tanstack/react-query'; -import { - type CadOrPointCloudModel, - type GroundPlane, - type Image360Collection, - type Scene, - type Skybox -} from '../components/SceneContainer/sceneTypes'; -import { useFdmSdk } from '../components/RevealCanvas/SDKProvider'; -import { type Source, type FdmSDK } from '../data-providers/FdmSDK'; -import { type SceneConfigurationProperties } from '../hooks/types'; -import { fdmViewsExist } from '../utilities/fdmViewsExist'; - -const DefaultScene: Scene = { - sceneConfiguration: { - name: '', - cameraTranslationX: 0, - cameraTranslationY: 0, - cameraTranslationZ: 0, - cameraEulerRotationX: 0, - cameraEulerRotationY: 0, - cameraEulerRotationZ: 0 - }, - skybox: undefined, - groundPlanes: [], - sceneModels: [], - image360Collections: [] -}; - -export const useSceneConfig = ( - sceneExternalId: string | undefined, - sceneSpaceExternalId: string | undefined -): UseQueryResult => { - const fdmSdk = useFdmSdk(); - return useQuery({ - queryKey: [ - 'reveal', - 'react-components', - 'sync-scene-config', - sceneExternalId, - sceneSpaceExternalId - ], - queryFn: async () => { - if (sceneExternalId === undefined || sceneSpaceExternalId === undefined) { - return null; - } - - const isSceneEnabledInProject = await sceneViewsExist(fdmSdk); - - if (!isSceneEnabledInProject) { - return DefaultScene; - } - - const getSceneQuery = createGetSceneQuery(sceneExternalId, sceneSpaceExternalId); - const queryResult = await fdmSdk.queryNodesAndEdges({ - ...getSceneQuery - }); - - const sceneResponse = queryResult as any as SceneResponse; - const SceneConfigurationProperties = extractProperties( - sceneResponse.items.myScene[0]?.properties - ); - - const scene: Scene = { - sceneConfiguration: { - name: SceneConfigurationProperties.name, - cameraTranslationX: SceneConfigurationProperties.cameraTranslationX, - cameraTranslationY: SceneConfigurationProperties.cameraTranslationY, - cameraTranslationZ: SceneConfigurationProperties.cameraTranslationZ, - cameraEulerRotationX: SceneConfigurationProperties.cameraEulerRotationX, - cameraEulerRotationY: SceneConfigurationProperties.cameraEulerRotationY, - cameraEulerRotationZ: SceneConfigurationProperties.cameraEulerRotationZ, - cameraTargetX: SceneConfigurationProperties.cameraTargetX, - cameraTargetY: SceneConfigurationProperties.cameraTargetY, - cameraTargetZ: SceneConfigurationProperties.cameraTargetZ - }, - skybox: getSkybox(sceneResponse), - groundPlanes: getGroundPlanes(sceneResponse), - sceneModels: getSceneModels(sceneResponse), - image360Collections: getImageCollections(sceneResponse) - }; - return scene; - }, - staleTime: Infinity - }); -}; - -async function sceneViewsExist(fdmSdk: FdmSDK): Promise { - const neededViews: Source[] = [ - { - type: 'view', - space: 'scene', - externalId: 'SceneConfiguration', - version: 'v1' - }, - { - type: 'view', - space: 'scene', - externalId: 'RevisionProperties', - version: 'v1' - }, - { - type: 'view', - space: 'scene', - externalId: 'Image360CollectionProperties', - version: 'v1' - }, - { - type: 'view', - space: 'scene', - externalId: 'EnvironmentMap', - version: 'v1' - }, - { - type: 'view', - space: 'scene', - externalId: 'TexturedPlane', - version: 'v1' - } - ]; - - return await fdmViewsExist(fdmSdk, neededViews); -} - -function extractProperties(object: Record>): T { - const firstKey = Object.keys(object)[0]; - const secondKey = Object.keys(object[firstKey])[0]; - return object[firstKey][secondKey]; -} - -function getSceneModels(sceneResponse: SceneResponse): CadOrPointCloudModel[] { - const models: CadOrPointCloudModel[] = []; - if (sceneResponse.items.sceneModels.length > 0) { - const sceneModels = sceneResponse.items.sceneModels; - sceneModels.forEach((sceneModel) => { - const sceneModelProperties = extractProperties(sceneModel.properties); - if (!isNaN(Number(sceneModel.endNode.externalId))) { - const model: CadOrPointCloudModel = { - modelId: Number(sceneModel.endNode.externalId), - ...sceneModelProperties - }; - - models.push(model); - } - }); - } - return models; -} - -function getImageCollections(sceneResponse: SceneResponse): Image360Collection[] { - const imageCollections: Image360Collection[] = []; - if (sceneResponse.items.image360CollectionsEdges.length > 0) { - const sceneModels = sceneResponse.items.image360CollectionsEdges; - sceneModels.forEach((sceneModel) => { - const imageCollectionProperties = extractProperties( - sceneModel.properties - ); - const collection: Image360Collection = { - ...imageCollectionProperties - }; - - imageCollections.push(collection); - }); - } - return imageCollections; -} - -function getGroundPlanes(sceneResponse: SceneResponse): GroundPlane[] { - const groundPlanes: GroundPlane[] = []; - if (sceneResponse.items.groundPlanes.length > 0) { - const groundPlaneResponse = sceneResponse.items.groundPlanes; - const groundPlaneEdgeResponse = sceneResponse.items.groundPlaneEdges; - - // Match groundplanes with their edges - groundPlaneEdgeResponse.forEach((groundPlaneEdge) => { - const mappedGroundPlane = groundPlaneResponse.find( - (groundPlane) => - groundPlane.externalId === groundPlaneEdge.endNode.externalId && - groundPlane.space === groundPlaneEdge.endNode.space - ); - - if (mappedGroundPlane !== undefined) { - const { label, file, wrapping, repeatU, repeatV } = - extractProperties(mappedGroundPlane.properties); - const groundPlaneEdgeProperties = extractProperties( - groundPlaneEdge.properties - ); - const groundPlane: GroundPlane = { - label, - file, - wrapping, - repeatU: repeatU ?? 1, - repeatV: repeatV ?? 1, - ...groundPlaneEdgeProperties - }; - groundPlanes.push(groundPlane); - } - }); - } - return groundPlanes; -} - -function getSkybox(sceneResponse: SceneResponse): Skybox | undefined { - if (sceneResponse.items.skybox.length === 0) { - return undefined; - } - - const { label, isSpherical, file } = extractProperties( - sceneResponse.items.skybox[0].properties - ); - return { - label, - isSpherical, - file - }; -} diff --git a/react-components/src/utilities/executeParallel.ts b/react-components/src/utilities/executeParallel.ts index 570121ef886..ab2a7dbc468 100644 --- a/react-components/src/utilities/executeParallel.ts +++ b/react-components/src/utilities/executeParallel.ts @@ -1,3 +1,6 @@ +/*! + * Copyright 2024 Cognite AS + */ export async function executeParallel( callbacks: Array<() => Promise>, maxParallel: number @@ -7,7 +10,7 @@ export async function executeParallel( let nextCallback = 0; const resultFillingCallbacks = callbacks.map( - (callback, ind) => () => callback().then((value) => (resultArray[ind] = value)) + (callback, ind) => async () => await callback().then((value) => (resultArray[ind] = value)) ); async function scheduleNext(): Promise { @@ -18,10 +21,12 @@ export async function executeParallel( nextCallback++; await resultFillingCallbacks[nextCallback](); - return scheduleNext(); + await scheduleNext(); } - const scheduleChains = new Array(maxParallel).fill(0).map(() => scheduleNext()); + const scheduleChains = new Array(maxParallel).fill(0).map(async () => { + await scheduleNext(); + }); await Promise.all(scheduleChains); return resultArray; } diff --git a/react-components/stories/CadStylingCache.stories.tsx b/react-components/stories/CadStylingCache.stories.tsx index 191026c40d5..db9c2868aee 100644 --- a/react-components/stories/CadStylingCache.stories.tsx +++ b/react-components/stories/CadStylingCache.stories.tsx @@ -6,11 +6,10 @@ import { CadModelContainer, type CadModelStyling, type CogniteCadModelProps, - type NodeStylingGroup, RevealCanvas, useReveal, RevealContext, - TreeIndexStylingGroup + type TreeIndexStylingGroup } from '../src'; import { Color, Matrix4, Vector3 } from 'three'; import { createSdkByUrlToken } from './utilities/createSdkByUrlToken'; From 4a981b0ab402cd23cb7a3f698e51ce96d7edd4a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Wed, 21 Aug 2024 10:34:18 +0200 Subject: [PATCH 05/32] chore: add missing files --- .../src/hooks/scenes/sceneQuery.ts | 128 ++++++ react-components/src/hooks/scenes/types.ts | 165 +++++++ .../src/hooks/scenes/use3dScenes.tsx | 418 ++++++++++++++++++ .../src/hooks/scenes/useSceneConfig.ts | 221 +++++++++ 4 files changed, 932 insertions(+) create mode 100644 react-components/src/hooks/scenes/sceneQuery.ts create mode 100644 react-components/src/hooks/scenes/types.ts create mode 100644 react-components/src/hooks/scenes/use3dScenes.tsx create mode 100644 react-components/src/hooks/scenes/useSceneConfig.ts diff --git a/react-components/src/hooks/scenes/sceneQuery.ts b/react-components/src/hooks/scenes/sceneQuery.ts new file mode 100644 index 00000000000..64fcb76dd80 --- /dev/null +++ b/react-components/src/hooks/scenes/sceneQuery.ts @@ -0,0 +1,128 @@ +/*! + * Copyright 2023 Cognite AS + */ + +import { type QueryRequest } from '@cognite/sdk'; +import { + environmentMapSourceWithProperties, + groundPlaneSourceWithProperties, + image360CollectionSourceWithProperties, + revisionSourceWithProperties, + SCENE_SOURCE, + sceneSourceWithProperties, + transformationSourceWithProperties +} from '../../hooks/scenes/types'; + +export const sceneQuery = { + with: { + myScene: { + nodes: { + filter: { + and: [ + { + equals: { + property: ['node', 'space'], + value: { parameter: 'sceneSpace' } + } + }, + { + equals: { + property: ['node', 'externalId'], + value: { parameter: 'sceneExternalId' } + } + } + ] + } + }, + limit: 1 + }, + sceneModels: { + edges: { + from: 'myScene', + maxDistance: 1, + direction: 'outwards', + filter: { + equals: { + property: ['edge', 'type'], + value: { + space: 'scene', + externalId: 'SceneConfiguration.model3ds' + } + } + } + }, + limit: 100 + }, + image360CollectionsEdges: { + edges: { + from: 'myScene', + maxDistance: 1, + direction: 'outwards', + filter: { + equals: { + property: ['edge', 'type'], + value: { + space: 'scene', + externalId: 'SceneConfiguration.images360Collections' + } + } + } + }, + limit: 100 + }, + skybox: { + nodes: { + from: 'myScene', + through: { + view: SCENE_SOURCE, + identifier: 'skybox' + }, + direction: 'outwards' + } + }, + groundPlaneEdges: { + edges: { + from: 'myScene', + maxDistance: 1, + direction: 'outwards', + filter: { + equals: { + property: ['edge', 'type'], + value: { + space: 'scene', + externalId: 'SceneConfiguration.texturedGroundPlanes' + } + } + } + }, + limit: 100 + }, + groundPlanes: { + nodes: { + from: 'groundPlaneEdges', + chainTo: 'destination' + }, + limit: 100 + } + }, + select: { + myScene: { + sources: sceneSourceWithProperties + }, + sceneModels: { + sources: revisionSourceWithProperties + }, + image360CollectionsEdges: { + sources: image360CollectionSourceWithProperties + }, + skybox: { + sources: environmentMapSourceWithProperties + }, + groundPlaneEdges: { + sources: transformationSourceWithProperties + }, + groundPlanes: { + sources: groundPlaneSourceWithProperties + } + } +} as const satisfies Omit; diff --git a/react-components/src/hooks/scenes/types.ts b/react-components/src/hooks/scenes/types.ts new file mode 100644 index 00000000000..72b304b5852 --- /dev/null +++ b/react-components/src/hooks/scenes/types.ts @@ -0,0 +1,165 @@ +/*! + * Copyright 2024 Cognite AS + */ +import { type SourceSelectorV3 } from '@cognite/sdk/dist/src'; +import { type DmsUniqueIdentifier } from '../../data-providers/FdmSDK'; + +export type Transformation3d = { + translationX: number; + translationY: number; + translationZ: number; + eulerRotationX: number; + eulerRotationY: number; + eulerRotationZ: number; + scaleX: number; + scaleY: number; + scaleZ: number; +}; + +export type SceneModelsProperties = Transformation3d & { + revisionId: number; +}; + +export type SceneConfigurationProperties = { + name: string; + skybox?: DmsUniqueIdentifier; + cameraTranslationX: number; + cameraTranslationY: number; + cameraTranslationZ: number; + cameraEulerRotationX: number; + cameraEulerRotationY: number; + cameraEulerRotationZ: number; + cameraTargetX?: number; + cameraTargetY?: number; + cameraTargetZ?: number; +}; + +export type SkyboxProperties = { + label: string; + isSpherical: boolean; + file: string; +}; + +export type GroundPlaneProperties = { + file: string; + label: string; + wrapping: string; + repeatU?: number; + repeatV?: number; +}; + +export type Cdf3dRevisionProperties = Transformation3d & { + revisionId: number; +}; + +export type Cdf3dImage360CollectionProperties = Transformation3d & { + image360CollectionExternalId: string; + image360CollectionSpace: string; +}; + +export const SCENE_SOURCE = { + type: 'view', + space: 'scene', + externalId: 'SceneConfiguration', + version: 'v1' +} as const; + +export const TRANSFORMATION_SOURCE = { + type: 'view', + space: 'cdf_3d_schema', + externalId: 'Transformation3d', + version: 'v1' +} as const; + +export const ENVIRONMENT_MAP_SOURCE = { + type: 'view', + space: 'scene', + externalId: 'EnvironmentMap', + version: 'v1' +} as const; + +export const IMAGE_360_COLLECTION_SOURCE = { + type: 'view', + space: 'scene', + externalId: 'Image360CollectionProperties', + version: 'v1' +} as const; + +export const REVISION_SOURCE = { + type: 'view', + space: 'scene', + externalId: 'RevisionProperties', + version: 'v1' +} as const; + +export const GROUND_PLANE_SOURCE = { + type: 'view', + space: 'scene', + externalId: 'TexturedPlane', + version: 'v1' +} as const; + +export const groundPlaneSourceWithProperties = [ + { + source: GROUND_PLANE_SOURCE, + properties: ['file', 'label', 'wrapping', 'repeatU', 'repeatV'] + } +] as const satisfies SourceSelectorV3; + +export const transformationSourceWithProperties = [ + { + source: TRANSFORMATION_SOURCE, + properties: [ + 'translationX', + 'translationY', + 'translationZ', + 'eulerRotationX', + 'eulerRotationY', + 'eulerRotationZ', + 'scaleX', + 'scaleY', + 'scaleZ' + ] + } +] as const satisfies SourceSelectorV3; + +export const sceneSourceWithProperties = [ + { + source: SCENE_SOURCE, + properties: [ + 'name', + 'skybox', + 'cameraTranslationX', + 'cameraTranslationY', + 'cameraTranslationZ', + 'cameraEulerRotationX', + 'cameraEulerRotationY', + 'cameraEulerRotationZ' + ] + } +] as const satisfies SourceSelectorV3; + +export const revisionSourceWithProperties = [ + { + source: REVISION_SOURCE, + properties: ['revisionId', ...transformationSourceWithProperties[0].properties] + } +] as const satisfies SourceSelectorV3; + +export const image360CollectionSourceWithProperties = [ + { + source: IMAGE_360_COLLECTION_SOURCE, + properties: [ + 'image360CollectionExternalId', + 'image360CollectionSpace', + ...transformationSourceWithProperties[0].properties + ] + } +] as const satisfies SourceSelectorV3; + +export const environmentMapSourceWithProperties = [ + { + source: ENVIRONMENT_MAP_SOURCE, + properties: ['label', 'file', 'isSpherical'] + } +] as const satisfies SourceSelectorV3; diff --git a/react-components/src/hooks/scenes/use3dScenes.tsx b/react-components/src/hooks/scenes/use3dScenes.tsx new file mode 100644 index 00000000000..c0bc9db9c50 --- /dev/null +++ b/react-components/src/hooks/scenes/use3dScenes.tsx @@ -0,0 +1,418 @@ +/*! + * Copyright 2023 Cognite AS + */ + +import { type QueryFunction, useQuery, type UseQueryResult } from '@tanstack/react-query'; +import { useSDK } from '../../components/RevealCanvas/SDKProvider'; +import { type QueryRequest, type CogniteClient } from '@cognite/sdk'; +import { useMemo } from 'react'; +import { type EdgeItem, FdmSDK, type NodeItem } from '../../data-providers/FdmSDK'; +import { Euler, MathUtils, Matrix4 } from 'three'; +import { CDF_TO_VIEWER_TRANSFORMATION } from '@cognite/reveal'; +import { type GroundPlane, type Skybox } from '../../components/SceneContainer/sceneTypes'; +import { + type AddCadResourceOptions, + type AddPointCloudResourceOptions, + type AddImage360CollectionDatamodelsOptions +} from '../../components/Reveal3DResources/types'; +import { + type Cdf3dImage360CollectionProperties, + type Cdf3dRevisionProperties, + type ENVIRONMENT_MAP_SOURCE, + environmentMapSourceWithProperties, + type GROUND_PLANE_SOURCE, + type GroundPlaneProperties, + groundPlaneSourceWithProperties, + image360CollectionSourceWithProperties, + type IMAGE_360_COLLECTION_SOURCE, + type REVISION_SOURCE, + revisionSourceWithProperties, + type SCENE_SOURCE, + type SceneConfigurationProperties, + sceneSourceWithProperties, + type SkyboxProperties, + type Transformation3d, + type TRANSFORMATION_SOURCE, + transformationSourceWithProperties +} from './types'; + +export type Space = string; +export type ExternalId = string; + +export type SceneData = { + name: string; + cameraTranslationX: number; + cameraTranslationY: number; + cameraTranslationZ: number; + cameraEulerRotationX: number; + cameraEulerRotationY: number; + cameraEulerRotationZ: number; + cadModelOptions: Array; + image360CollectionOptions: AddImage360CollectionDatamodelsOptions[]; + groundPlanes: GroundPlane[]; + skybox?: Skybox; +}; + +type Use3dScenesQueryResult = { + scenes: Array>; + sceneModels: Array>>>; + scene360Collections: Array< + EdgeItem>> + >; + sceneGroundPlanes: Array>; + sceneGroundPlaneEdges: Array>>>; + sceneSkybox: Array>; +}; + +export const use3dScenes = ( + userSdk?: CogniteClient +): UseQueryResult>> => { + const sdk = useSDK(userSdk); + + const fdmSdk = useMemo(() => new FdmSDK(sdk), [sdk]); + + const queryFunction: QueryFunction>> = async () => { + const scenesQuery = createGetScenesQuery(); + + try { + const queryResult: Use3dScenesQueryResult = ( + await fdmSdk.queryNodesAndEdges< + typeof scenesQuery, + [ + { source: typeof SCENE_SOURCE; properties: SceneConfigurationProperties }, + { source: typeof TRANSFORMATION_SOURCE; properties: Transformation3d }, + { source: typeof ENVIRONMENT_MAP_SOURCE; properties: SkyboxProperties }, + { + source: typeof IMAGE_360_COLLECTION_SOURCE; + properties: Cdf3dImage360CollectionProperties; + }, + { source: typeof REVISION_SOURCE; properties: Cdf3dRevisionProperties }, + { source: typeof GROUND_PLANE_SOURCE; properties: GroundPlaneProperties } + ] + >(scenesQuery) + ).items; + + const scenesMap = createMapOfScenes(queryResult.scenes, queryResult.sceneSkybox); + populateSceneMapWithModels(queryResult.sceneModels, scenesMap); + populateSceneMapWith360Images(queryResult.scene360Collections, scenesMap); + populateSceneMapWithGroundplanes( + queryResult.sceneGroundPlanes, + queryResult.sceneGroundPlaneEdges, + scenesMap + ); + + return scenesMap; + } catch (error) { + console.warn("Scene space doesn't exist or has no scenes with 3D models"); + return {}; + } + }; + + return useQuery>>({ + queryKey: ['reveal-react-components', 'cdf', '3d', 'scenes'], + queryFn: queryFunction + }); +}; + +function createMapOfScenes( + scenes: Array>, + skyboxes: Array> +): Record> { + return scenes.reduce( + ( + acc: Record>, + scene: NodeItem + ) => { + const { space, externalId } = scene; + const properties = Object.values(Object.values(scene.properties)[0])[0]; + if (acc[space] === undefined) { + acc[space] = {}; + } + if (acc[space][externalId] === undefined) { + let skyboxObject: SkyboxProperties | undefined; + const skyboxIdentifier = properties.skybox; + if (skyboxIdentifier !== undefined) { + const connectedSkybox = skyboxes.find( + (skybox) => + skybox.externalId === skyboxIdentifier.externalId && + skybox.space === skyboxIdentifier.space + ); + if (connectedSkybox !== undefined) { + const skyboxProperties = Object.values(Object.values(connectedSkybox.properties)[0])[0]; + skyboxObject = skyboxProperties; + } + } + + acc[space][externalId] = { + name: properties.name, + cameraTranslationX: properties.cameraTranslationX, + cameraTranslationY: properties.cameraTranslationY, + cameraTranslationZ: properties.cameraTranslationZ, + cameraEulerRotationX: properties.cameraEulerRotationX, + cameraEulerRotationY: properties.cameraEulerRotationY, + cameraEulerRotationZ: properties.cameraEulerRotationZ, + cadModelOptions: [], + image360CollectionOptions: [], + groundPlanes: [], + skybox: skyboxObject + }; + } + + return acc; + }, + {} + ); +} + +function populateSceneMapWithModels( + scene360Images: Array>>>, + scenesMap: Record> +): void { + scene360Images.forEach((edge) => { + const { space, externalId } = edge.startNode; + + const properties = Object.values(Object.values(edge.properties)[0])[0]; + + const newModelId = Number(edge.endNode.externalId); + const newModelRevisionId = Number(properties?.revisionId); + + if (isNaN(newModelId) || isNaN(newModelRevisionId)) { + return; + } + + if (scenesMap[space]?.[externalId] === undefined) { + return; + } + + const transform = createTransformFromEdge(properties); + const newModel = { + modelId: newModelId, + revisionId: newModelRevisionId, + transformation: transform + }; + + scenesMap[space]?.[externalId].cadModelOptions.push(newModel); + }); +} + +function populateSceneMapWith360Images( + scene360Images: Array< + EdgeItem>> + >, + scenesMap: Record> +): void { + scene360Images.forEach((edge) => { + const { space, externalId } = edge.startNode; + + if (scenesMap[space]?.[externalId] === undefined) { + return; + } + + const properties = Object.values(Object.values(edge.properties)[0])[0]; + const transform = createTransformFromEdge(properties); + const newImage360Collection: AddImage360CollectionDatamodelsOptions = { + externalId: properties.image360CollectionExternalId, + space: properties.image360CollectionSpace, + transform + }; + + scenesMap[space]?.[externalId].image360CollectionOptions.push(newImage360Collection); + }); +} + +function populateSceneMapWithGroundplanes( + sceneGroundPlanes: Array>, + sceneGroundPlaneEdges: Array>>>, + scenesMap: Record> +): void { + sceneGroundPlaneEdges.forEach((edge) => { + const { space, externalId } = edge.startNode; + + const mappedGroundPlane = sceneGroundPlanes.find( + (groundPlane) => + groundPlane.externalId === edge.endNode.externalId && + groundPlane.space === edge.endNode.space + ); + + if (scenesMap[space]?.[externalId] === undefined || mappedGroundPlane === undefined) { + return; + } + + const groundPlaneEdgeProperties = Object.values(Object.values(edge.properties)[0])[0]; + const groundPlaneProperties = Object.values(Object.values(mappedGroundPlane.properties)[0])[0]; + + const groundPlane: GroundPlane = { + label: groundPlaneProperties.label, + file: groundPlaneProperties.file, + wrapping: groundPlaneProperties.wrapping, + repeatU: groundPlaneProperties.repeatU ?? 1, + repeatV: groundPlaneProperties.repeatV ?? 1, + ...groundPlaneEdgeProperties // Transformation3d + }; + + scenesMap[space]?.[externalId].groundPlanes.push(groundPlane); + }); +} + +function createTransformFromEdge(properties: Transformation3d): Matrix4 { + const transform = new Matrix4(); + + transform.makeRotationFromEuler( + new Euler( + MathUtils.degToRad(properties.eulerRotationX), + MathUtils.degToRad(properties.eulerRotationY), + MathUtils.degToRad(properties.eulerRotationZ) + ) + ); + + fixModelScale(properties); + + const scaleMatrix = new Matrix4().makeScale( + properties.scaleX, + properties.scaleY, + properties.scaleZ + ); + transform.multiply(scaleMatrix); + + const translation = new Matrix4().makeTranslation( + properties.translationX, + properties.translationY, + properties.translationZ + ); + transform.premultiply(translation); + + transform.premultiply(CDF_TO_VIEWER_TRANSFORMATION); + + return transform; +} + +function fixModelScale(modelProps: Transformation3d): Transformation3d { + if (modelProps.scaleX === 0) { + modelProps.scaleX = 1; + } + if (modelProps.scaleY === 0) { + modelProps.scaleY = 1; + } + if (modelProps.scaleZ === 0) { + modelProps.scaleZ = 1; + } + + return modelProps; +} + +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +function createGetScenesQuery(limit: number = 100) { + return { + with: { + scenes: { + nodes: { + filter: { + hasData: [ + { + type: 'view', + space: 'scene', + externalId: 'SceneConfiguration', + version: 'v1' + } + ] + } + }, + limit + }, + sceneModels: { + edges: { + from: 'scenes', + maxDistance: 1, + direction: 'outwards', + filter: { + equals: { + property: ['edge', 'type'], + value: { + space: 'scene', + externalId: 'SceneConfiguration.model3ds' + } + } + } + }, + limit + }, + scene360Collections: { + edges: { + from: 'scenes', + maxDistance: 1, + direction: 'outwards', + filter: { + equals: { + property: ['edge', 'type'], + value: { + space: 'scene', + externalId: 'SceneConfiguration.images360Collections' + } + } + } + }, + limit + }, + sceneSkybox: { + nodes: { + from: 'scenes', + through: { + view: { + type: 'view', + space: 'scene', + externalId: 'SceneConfiguration', + version: 'v1' + }, + identifier: 'skybox' + }, + direction: 'outwards' + }, + limit + }, + sceneGroundPlaneEdges: { + edges: { + from: 'scenes', + maxDistance: 1, + direction: 'outwards', + filter: { + equals: { + property: ['edge', 'type'], + value: { + space: 'scene', + externalId: 'SceneConfiguration.texturedGroundPlanes' + } + } + } + }, + limit + }, + sceneGroundPlanes: { + nodes: { + from: 'sceneGroundPlaneEdges', + chainTo: 'destination' + }, + limit + } + }, + select: { + scenes: { + sources: sceneSourceWithProperties + }, + sceneModels: { + sources: revisionSourceWithProperties + }, + scene360Collections: { + sources: image360CollectionSourceWithProperties + }, + sceneSkybox: { + sources: environmentMapSourceWithProperties + }, + sceneGroundPlaneEdges: { + sources: transformationSourceWithProperties + }, + sceneGroundPlanes: { + sources: groundPlaneSourceWithProperties + } + } + } as const satisfies Omit; +} diff --git a/react-components/src/hooks/scenes/useSceneConfig.ts b/react-components/src/hooks/scenes/useSceneConfig.ts new file mode 100644 index 00000000000..5dbfea67061 --- /dev/null +++ b/react-components/src/hooks/scenes/useSceneConfig.ts @@ -0,0 +1,221 @@ +/*! + * Copyright 2023 Cognite AS + */ +import { sceneQuery } from './sceneQuery'; +import { + type GroundPlaneProperties, + type Transformation3d, + type SceneResponse, + type SkyboxProperties, + type SceneModelsProperties, + type Scene360ImageCollectionsProperties +} from '../../components/SceneContainer/SceneFdmTypes'; +import { useQuery, type UseQueryResult } from '@tanstack/react-query'; +import { + type CadOrPointCloudModel, + type GroundPlane, + type Image360Collection, + type Scene, + type Skybox +} from '../../components/SceneContainer/sceneTypes'; +import { useFdmSdk } from '../../components/RevealCanvas/SDKProvider'; +import { type Source, type FdmSDK } from '../../data-providers/FdmSDK'; +import { fdmViewsExist } from '../../utilities/fdmViewsExist'; +import { + type Cdf3dImage360CollectionProperties, + ENVIRONMENT_MAP_SOURCE, + GROUND_PLANE_SOURCE, + IMAGE_360_COLLECTION_SOURCE, + REVISION_SOURCE, + SCENE_SOURCE, + type SceneConfigurationProperties, + type TRANSFORMATION_SOURCE +} from './types'; + +const DefaultScene: Scene = { + sceneConfiguration: { + name: '', + cameraTranslationX: 0, + cameraTranslationY: 0, + cameraTranslationZ: 0, + cameraEulerRotationX: 0, + cameraEulerRotationY: 0, + cameraEulerRotationZ: 0 + }, + skybox: undefined, + groundPlanes: [], + sceneModels: [], + image360Collections: [] +}; + +export const useSceneConfig = ( + sceneExternalId: string | undefined, + sceneSpace: string | undefined +): UseQueryResult => { + const fdmSdk = useFdmSdk(); + return useQuery({ + queryKey: ['reveal', 'react-components', 'sync-scene-config', sceneExternalId, sceneSpace], + queryFn: async () => { + if (sceneExternalId === undefined || sceneSpace === undefined) { + return null; + } + + const isSceneEnabledInProject = await sceneViewsExist(fdmSdk); + + if (!isSceneEnabledInProject) { + return DefaultScene; + } + + const query = { + ...sceneQuery, + parameters: { sceneExternalId, sceneSpace } + }; + + const queryResult = await fdmSdk.queryNodesAndEdges< + typeof query, + [ + { source: typeof SCENE_SOURCE; properties: SceneConfigurationProperties }, + { source: typeof ENVIRONMENT_MAP_SOURCE; properties: SkyboxProperties }, + { source: typeof GROUND_PLANE_SOURCE; properties: GroundPlaneProperties }, + { source: typeof TRANSFORMATION_SOURCE; properties: Transformation3d }, + { source: typeof REVISION_SOURCE; properties: SceneModelsProperties }, + { + source: typeof IMAGE_360_COLLECTION_SOURCE; + properties: Scene360ImageCollectionsProperties; + } + ] + >(query); + + const sceneResponse = queryResult; + const SceneConfigurationProperties = extractProperties( + sceneResponse.items.myScene[0]?.properties + ); + + const scene: Scene = { + sceneConfiguration: { + name: SceneConfigurationProperties.name, + cameraTranslationX: SceneConfigurationProperties.cameraTranslationX, + cameraTranslationY: SceneConfigurationProperties.cameraTranslationY, + cameraTranslationZ: SceneConfigurationProperties.cameraTranslationZ, + cameraEulerRotationX: SceneConfigurationProperties.cameraEulerRotationX, + cameraEulerRotationY: SceneConfigurationProperties.cameraEulerRotationY, + cameraEulerRotationZ: SceneConfigurationProperties.cameraEulerRotationZ, + cameraTargetX: SceneConfigurationProperties.cameraTargetX, + cameraTargetY: SceneConfigurationProperties.cameraTargetY, + cameraTargetZ: SceneConfigurationProperties.cameraTargetZ + }, + skybox: getSkybox(sceneResponse), + groundPlanes: getGroundPlanes(sceneResponse), + sceneModels: getSceneModels(sceneResponse), + image360Collections: getImageCollections(sceneResponse) + }; + return scene; + }, + staleTime: Infinity + }); +}; + +async function sceneViewsExist(fdmSdk: FdmSDK): Promise { + const neededViews: Source[] = [ + SCENE_SOURCE, + REVISION_SOURCE, + IMAGE_360_COLLECTION_SOURCE, + ENVIRONMENT_MAP_SOURCE, + GROUND_PLANE_SOURCE + ]; + + return await fdmViewsExist(fdmSdk, neededViews); +} + +function extractProperties(object: Record>): T { + const firstKey = Object.keys(object)[0]; + const secondKey = Object.keys(object[firstKey])[0]; + return object[firstKey][secondKey]; +} + +function getSceneModels(sceneResponse: SceneResponse): CadOrPointCloudModel[] { + const models: CadOrPointCloudModel[] = []; + if (sceneResponse.items.sceneModels.length > 0) { + const sceneModels = sceneResponse.items.sceneModels; + sceneModels.forEach((sceneModel) => { + const sceneModelProperties = extractProperties(sceneModel.properties); + if (!isNaN(Number(sceneModel.endNode.externalId))) { + const model: CadOrPointCloudModel = { + modelId: Number(sceneModel.endNode.externalId), + ...sceneModelProperties + }; + + models.push(model); + } + }); + } + return models; +} + +function getImageCollections(sceneResponse: SceneResponse): Image360Collection[] { + const imageCollections: Image360Collection[] = []; + if (sceneResponse.items.image360CollectionsEdges.length > 0) { + const sceneModels = sceneResponse.items.image360CollectionsEdges; + sceneModels.forEach((sceneModel) => { + const imageCollectionProperties = extractProperties( + sceneModel.properties + ); + const collection: Image360Collection = { + ...imageCollectionProperties + }; + + imageCollections.push(collection); + }); + } + return imageCollections; +} + +function getGroundPlanes(sceneResponse: SceneResponse): GroundPlane[] { + const groundPlanes: GroundPlane[] = []; + if (sceneResponse.items.groundPlanes.length > 0) { + const groundPlaneResponse = sceneResponse.items.groundPlanes; + const groundPlaneEdgeResponse = sceneResponse.items.groundPlaneEdges; + + // Match groundplanes with their edges + groundPlaneEdgeResponse.forEach((groundPlaneEdge) => { + const mappedGroundPlane = groundPlaneResponse.find( + (groundPlane) => + groundPlane.externalId === groundPlaneEdge.endNode.externalId && + groundPlane.space === groundPlaneEdge.endNode.space + ); + + if (mappedGroundPlane !== undefined) { + const { label, file, wrapping, repeatU, repeatV } = + extractProperties(mappedGroundPlane.properties); + const groundPlaneEdgeProperties = extractProperties( + groundPlaneEdge.properties + ); + const groundPlane: GroundPlane = { + label, + file, + wrapping, + repeatU: repeatU ?? 1, + repeatV: repeatV ?? 1, + ...groundPlaneEdgeProperties + }; + groundPlanes.push(groundPlane); + } + }); + } + return groundPlanes; +} + +function getSkybox(sceneResponse: SceneResponse): Skybox | undefined { + if (sceneResponse.items.skybox.length === 0) { + return undefined; + } + + const { label, isSpherical, file } = extractProperties( + sceneResponse.items.skybox[0].properties + ); + return { + label, + isSpherical, + file + }; +} From 4dca9ead893c5129ec43369ed459d6800e158265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Wed, 21 Aug 2024 10:44:56 +0200 Subject: [PATCH 06/32] chore: fix remaining field misname --- react-components/stories/CadStylingCache.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react-components/stories/CadStylingCache.stories.tsx b/react-components/stories/CadStylingCache.stories.tsx index db9c2868aee..fdda78c3187 100644 --- a/react-components/stories/CadStylingCache.stories.tsx +++ b/react-components/stories/CadStylingCache.stories.tsx @@ -59,7 +59,7 @@ const Models = ({ addModelOptions }: CogniteCadModelProps): JSX.Element => { () => data ?.get(`${platformModelOptions.modelId}/${platformModelOptions.revisionId}`) - ?.map((edgeWithNode) => edgeWithNode.connection.nodeId), + ?.map((edgeWithNode) => edgeWithNode.connection.treeIndex), [data] ); From 0ca4c71f4ff883e46913a57af77c0ba48e20912f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 22 Aug 2024 10:53:50 +0200 Subject: [PATCH 07/32] chore: fix executeParallel --- react-components/src/utilities/executeParallel.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/react-components/src/utilities/executeParallel.ts b/react-components/src/utilities/executeParallel.ts index ab2a7dbc468..45306070101 100644 --- a/react-components/src/utilities/executeParallel.ts +++ b/react-components/src/utilities/executeParallel.ts @@ -18,15 +18,17 @@ export async function executeParallel( return; } + const relevantCallback = nextCallback; nextCallback++; - await resultFillingCallbacks[nextCallback](); + await resultFillingCallbacks[relevantCallback](); await scheduleNext(); } const scheduleChains = new Array(maxParallel).fill(0).map(async () => { await scheduleNext(); }); + await Promise.all(scheduleChains); return resultArray; } From 7fda23a7999d27ff887e312587b4ba1f15b320d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 22 Aug 2024 10:54:10 +0200 Subject: [PATCH 08/32] chore: correct import path --- .../legacy-fdm-provider/getEdgeConnected3dInstances.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts b/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts index b2aa696d134..989f4cc4a10 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts @@ -3,7 +3,7 @@ */ import { SYSTEM_3D_EDGE_SOURCE } from './dataModels'; import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; -import { type QueryRequest } from '@cognite/sdk/dist/src'; +import { type QueryRequest } from '@cognite/sdk'; export async function getEdgeConnected3dInstances( instance: DmsUniqueIdentifier, From 2e74a2c9fedc36c6b7b43cf282eb45d480b47107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 22 Aug 2024 11:01:23 +0200 Subject: [PATCH 09/32] chore: make sure nodeId-treeIndex queries are chunked --- .../src/components/CacheProvider/requests.ts | 26 ++++++++++---- .../fdmEdgesToCadConnections.ts | 35 ++++++++++++------- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/react-components/src/components/CacheProvider/requests.ts b/react-components/src/components/CacheProvider/requests.ts index b292a36ce40..2f27440ffd0 100644 --- a/react-components/src/components/CacheProvider/requests.ts +++ b/react-components/src/components/CacheProvider/requests.ts @@ -63,14 +63,26 @@ export async function treeIndexesToNodeIds( const outputsUrl = `${cogniteClient.getBaseUrl()}/api/v1/projects/${ cogniteClient.project }/3d/models/${modelId}/revisions/${revisionId}/nodes/internalids/bytreeindices`; - const response = await cogniteClient.post<{ items: NodeId[] }>(outputsUrl, { - data: { items: treeIndexes } - }); - if (response.status === 200) { - return response.data.items; - } else { - throw Error(`treeIndex-nodeId translation failed for treeIndexes ${treeIndexes.join(',')}`); + + const treeIndexChunks = chunk(treeIndexes, 1000); + + const nodeIds: NodeId[] = []; + + for (const treeIndexChunk of treeIndexChunks) { + const response = await cogniteClient.post<{ items: NodeId[] }>(outputsUrl, { + data: { items: treeIndexChunk } + }); + + if (response.status === 200) { + nodeIds.push(...response.data.items); + } else { + throw Error( + `treeIndex-nodeId translation failed for treeIndexes ${treeIndexChunk.join(',')}` + ); + } } + + return nodeIds; } export async function nodeIdsToTreeIndices( diff --git a/react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts b/react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts index b6e9f0f29e1..ce93b4b2646 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts @@ -18,6 +18,7 @@ import { } from '../../components/CacheProvider/utils'; import { executeParallel } from '../../utilities/executeParallel'; import { isDefined } from '../../utilities/isDefined'; +import { chunk } from 'lodash'; const MAX_PARALLEL_QUERIES = 2; @@ -80,17 +81,27 @@ async function getTreeIndexConnectionsForNodeIdConnections( cogniteClient: CogniteClient ): Promise { const [modelId, revisionId] = modelRevisionKeyToModelRevision(modelRevisionKey); - const treeIndices = await nodeIdsToTreeIndices( - modelId, - revisionId, - connectionList.map((connection) => connection.nodeId), - cogniteClient - ); + const connectionChunks = chunk(connectionList, 1000); + + const connectionResult: FdmCadConnection[] = []; + + for (const connectionChunk of connectionChunks) { + const treeIndices = await nodeIdsToTreeIndices( + modelId, + revisionId, + connectionChunk.map((connection) => connection.nodeId), + cogniteClient + ); + + const cadConnections = connectionChunk.map((connection, ind) => ({ + modelId: connection.modelId, + revisionId: connection.revisionId, + treeIndex: treeIndices[ind], + instance: connection.instance + })); + + connectionResult.push(...cadConnections); + } - return connectionList.map((connection, ind) => ({ - modelId: connection.modelId, - revisionId: connection.revisionId, - treeIndex: treeIndices[ind], - instance: connection.instance - })); + return connectionResult; } From 9bbaefd4c40cbfcdbf95d1852851f4cee72605c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 22 Aug 2024 11:02:18 +0200 Subject: [PATCH 10/32] chore: include initialAssetMappingsData in the useSearchMappedAssetMappings query --- .../src/query/useSearchMappedEquipmentAssetMappings.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/react-components/src/query/useSearchMappedEquipmentAssetMappings.tsx b/react-components/src/query/useSearchMappedEquipmentAssetMappings.tsx index 658ec82b311..a7003e560f4 100644 --- a/react-components/src/query/useSearchMappedEquipmentAssetMappings.tsx +++ b/react-components/src/query/useSearchMappedEquipmentAssetMappings.tsx @@ -57,7 +57,8 @@ export const useSearchMappedEquipmentAssetMappings = ( 'react-components', 'search-mapped-asset-mappings', query, - ...models.map((model) => [model.modelId, model.revisionId]) + ...models.map((model) => [model.modelId, model.revisionId]), + initialAssetMappings.data?.pages.length ?? 0 ], queryFn: async ({ pageParam }: { pageParam: string | undefined }) => { if (initialAssetMappings.data === undefined) { From 93bb349b957785a3ac3afa5d83960849f4ddf35e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 22 Aug 2024 11:07:37 +0200 Subject: [PATCH 11/32] chore: add executeParallel test --- .../utilities/executeParallel.test.ts | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 react-components/tests/unit-tests/utilities/executeParallel.test.ts diff --git a/react-components/tests/unit-tests/utilities/executeParallel.test.ts b/react-components/tests/unit-tests/utilities/executeParallel.test.ts new file mode 100644 index 00000000000..56171ca1861 --- /dev/null +++ b/react-components/tests/unit-tests/utilities/executeParallel.test.ts @@ -0,0 +1,47 @@ +import { describe, expect, test } from 'vitest'; +import { executeParallel } from '../../../src/utilities/executeParallel'; +import { delay } from 'lodash'; + +describe(executeParallel.name, () => { + test('one call finishes', async () => { + const result = await executeParallel([() => Promise.resolve(0)], 1); + + expect(result).toEqual([0]); + }); + + test('one call with multiple parallel finishes', async () => { + const result = await executeParallel([() => Promise.resolve(0)], 3); + + expect(result).toEqual([0]); + }); + + test('two calls with one parallel finishes', async () => { + const results = await executeParallel([() => Promise.resolve(0), () => Promise.resolve(1)], 1); + + expect(results).toEqual([0, 1]); + }); + + test('three calls with two parallel finishes', async () => { + const results = await executeParallel( + [() => Promise.resolve(0), () => Promise.resolve(1), () => Promise.resolve(2)], + 2 + ); + + expect(results).toEqual([0, 1, 2]); + }); + + test('two calls with three parallel finishes', async () => { + const results = await executeParallel([() => Promise.resolve(0), () => Promise.resolve(1)], 3); + + expect(results).toEqual([0, 1]); + }); + + test('two calls with delay in first resolves with results in right order', async () => { + const results = await executeParallel( + [() => new Promise((resolve) => delay(() => resolve(0), 200)), () => Promise.resolve(1)], + 2 + ); + + expect(results).toEqual([0, 1]); + }); +}); From e26c1b52c41ba7f2d160cc5e7ba9f1e4e90c4bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 22 Aug 2024 12:12:01 +0200 Subject: [PATCH 12/32] chore: fix scene camera request --- react-components/src/hooks/scenes/types.ts | 5 ++++- .../src/hooks/scenes/useSceneConfig.ts | 22 +++++++++---------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/react-components/src/hooks/scenes/types.ts b/react-components/src/hooks/scenes/types.ts index 72b304b5852..0395b06acdb 100644 --- a/react-components/src/hooks/scenes/types.ts +++ b/react-components/src/hooks/scenes/types.ts @@ -134,7 +134,10 @@ export const sceneSourceWithProperties = [ 'cameraTranslationZ', 'cameraEulerRotationX', 'cameraEulerRotationY', - 'cameraEulerRotationZ' + 'cameraEulerRotationZ', + 'cameraTargetX', + 'cameraTargetY', + 'cameraTargetZ' ] } ] as const satisfies SourceSelectorV3; diff --git a/react-components/src/hooks/scenes/useSceneConfig.ts b/react-components/src/hooks/scenes/useSceneConfig.ts index 5dbfea67061..c0a8df03670 100644 --- a/react-components/src/hooks/scenes/useSceneConfig.ts +++ b/react-components/src/hooks/scenes/useSceneConfig.ts @@ -87,22 +87,22 @@ export const useSceneConfig = ( >(query); const sceneResponse = queryResult; - const SceneConfigurationProperties = extractProperties( + const sceneConfigurationProperties = extractProperties( sceneResponse.items.myScene[0]?.properties ); const scene: Scene = { sceneConfiguration: { - name: SceneConfigurationProperties.name, - cameraTranslationX: SceneConfigurationProperties.cameraTranslationX, - cameraTranslationY: SceneConfigurationProperties.cameraTranslationY, - cameraTranslationZ: SceneConfigurationProperties.cameraTranslationZ, - cameraEulerRotationX: SceneConfigurationProperties.cameraEulerRotationX, - cameraEulerRotationY: SceneConfigurationProperties.cameraEulerRotationY, - cameraEulerRotationZ: SceneConfigurationProperties.cameraEulerRotationZ, - cameraTargetX: SceneConfigurationProperties.cameraTargetX, - cameraTargetY: SceneConfigurationProperties.cameraTargetY, - cameraTargetZ: SceneConfigurationProperties.cameraTargetZ + name: sceneConfigurationProperties.name, + cameraTranslationX: sceneConfigurationProperties.cameraTranslationX, + cameraTranslationY: sceneConfigurationProperties.cameraTranslationY, + cameraTranslationZ: sceneConfigurationProperties.cameraTranslationZ, + cameraEulerRotationX: sceneConfigurationProperties.cameraEulerRotationX, + cameraEulerRotationY: sceneConfigurationProperties.cameraEulerRotationY, + cameraEulerRotationZ: sceneConfigurationProperties.cameraEulerRotationZ, + cameraTargetX: sceneConfigurationProperties.cameraTargetX, + cameraTargetY: sceneConfigurationProperties.cameraTargetY, + cameraTargetZ: sceneConfigurationProperties.cameraTargetZ }, skybox: getSkybox(sceneResponse), groundPlanes: getGroundPlanes(sceneResponse), From b7e86bed85d11e8e3852d8e98165547f714281d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 22 Aug 2024 14:13:19 +0200 Subject: [PATCH 13/32] feat: add flag in RevealContext to enable CoreDM queries --- .../src/components/RevealCanvas/SDKProvider.tsx | 10 +++++++--- .../src/components/RevealContext/RevealContext.tsx | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/react-components/src/components/RevealCanvas/SDKProvider.tsx b/react-components/src/components/RevealCanvas/SDKProvider.tsx index 10e0e504f74..ce04f9a9481 100644 --- a/react-components/src/components/RevealCanvas/SDKProvider.tsx +++ b/react-components/src/components/RevealCanvas/SDKProvider.tsx @@ -7,17 +7,21 @@ import { FdmSdkContext } from './FdmDataProviderContext'; import { FdmSDK } from '../../data-providers/FdmSDK'; import { LegacyFdm3dDataProvider } from '../../data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider'; import { type Fdm3dDataProvider } from '../../data-providers/Fdm3dDataProvider'; +import { CoreDm3dFdm3dDataProvider } from '../../data-providers/core-dm-provider/CoreDm3dDataProvider'; const SdkContext = createContext(null); SdkContext.displayName = 'CogniteSdkProvider'; FdmSdkContext.displayName = 'FdmSdkProvider'; -type Props = { sdk: CogniteClient; children: any }; +type Props = { sdk: CogniteClient; useCoreDm?: boolean; children: any }; -export function SDKProvider({ sdk, children }: Props): React.ReactElement { +export function SDKProvider({ sdk, children, useCoreDm }: Props): React.ReactElement { const fdmSdk = useMemo(() => new FdmSDK(sdk), [sdk]); - const fdm3dDataProvider = new LegacyFdm3dDataProvider(fdmSdk, sdk); + const fdm3dDataProvider = + useCoreDm ?? false + ? new CoreDm3dFdm3dDataProvider([], fdmSdk) + : new LegacyFdm3dDataProvider(fdmSdk, sdk); const content = useMemo(() => ({ fdmSdk, fdm3dDataProvider }), [fdmSdk, fdm3dDataProvider]); return ( diff --git a/react-components/src/components/RevealContext/RevealContext.tsx b/react-components/src/components/RevealContext/RevealContext.tsx index fbc6361497c..680eb100024 100644 --- a/react-components/src/components/RevealContext/RevealContext.tsx +++ b/react-components/src/components/RevealContext/RevealContext.tsx @@ -23,6 +23,7 @@ export type RevealContextProps = { sdk: CogniteClient; appLanguage?: string; children?: ReactNode; + useCoreDm?: boolean; viewerOptions?: Pick< Cognite3DViewerOptions, | 'antiAliasingHint' @@ -46,7 +47,7 @@ export const RevealContext = (props: RevealContextProps): ReactElement => { if (viewer === null) return <>; return ( - + From 54c57ccc437ec098a08b2b98ca6007d317a7a169 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Fri, 23 Aug 2024 08:25:31 +0200 Subject: [PATCH 14/32] fix: fix some datamodels/queries --- react-components/src/data-providers/FdmSDK.ts | 4 ++-- .../core-dm-provider/dataModels.ts | 14 ++++++-------- .../filterNodesByMappedTo3d.ts | 16 +++++++--------- .../getCadConnectionsForRevisions.ts | 12 +++++++----- .../getCadModelsForInstance.ts | 5 +++-- .../core-dm-provider/getDMSModels.ts | 10 ++++++---- .../core-dm-provider/getDMSRevision.ts | 19 ++++++++++++------- .../getFdmConnectionsForNodeIds.ts | 18 ++++++++++-------- .../core-dm-provider/listMappedFdmNodes.ts | 5 +++-- 9 files changed, 56 insertions(+), 47 deletions(-) diff --git a/react-components/src/data-providers/FdmSDK.ts b/react-components/src/data-providers/FdmSDK.ts index a663db9ebe4..a21493c1fea 100644 --- a/react-components/src/data-providers/FdmSDK.ts +++ b/react-components/src/data-providers/FdmSDK.ts @@ -536,8 +536,8 @@ export class FdmSDK { >(query: TQueryRequest): Promise> { let result = await queryNodesAndEdges(query, this._sdk); let items = result.items; - while (result.nextCursor !== undefined) { - const newQuery = { ...query, cursor: result.nextCursor }; + while (result.nextCursor !== undefined && Object.keys(result.nextCursor).length !== 0) { + const newQuery = { ...query, cursors: result.nextCursor }; result = await queryNodesAndEdges(newQuery, this._sdk); items = mergeQueryResults(items, result.items); } diff --git a/react-components/src/data-providers/core-dm-provider/dataModels.ts b/react-components/src/data-providers/core-dm-provider/dataModels.ts index 7c8bd64e08d..28d5ab00ab1 100644 --- a/react-components/src/data-providers/core-dm-provider/dataModels.ts +++ b/react-components/src/data-providers/core-dm-provider/dataModels.ts @@ -4,13 +4,11 @@ import { type Timestamp, type ViewReference } from '@cognite/sdk'; import { type DmsUniqueIdentifier } from '../FdmSDK'; -export const CORE_DM_SPACE = 'cdf_cdm_experimental'; - -export const SYSTEM_SPACE_3D_MODEL_TYPE = 'CogniteModel3D'; -export const SYSTEM_SPACE_3D_MODEL_VERSION = '1'; +export const CORE_DM_SPACE = 'cdf_cdm' as const; +export const CORE_DM_3D_CONTAINER_SPACE = 'cdf_cdm_3d' as const; export const COGNITE_3D_OBJECT_SOURCE = { - externalId: 'CogniteObject3D', + externalId: 'Cognite3DObject', space: CORE_DM_SPACE, version: 'v1', type: 'view' @@ -23,8 +21,8 @@ export const COGNITE_3D_MODEL_SOURCE = { type: 'view' } as const satisfies ViewReference; -export const COGNITE_CAD_MODEL_SOURCE = { - externalId: 'CogniteCADModel', +export const COGNITE_3D_REVISION_SOURCE = { + externalId: 'Cognite3DRevision', space: CORE_DM_SPACE, version: 'v1', type: 'view' @@ -121,7 +119,7 @@ export type CogniteAssetProperties = { export type CogniteCADRevisionProperties = { status: Cognite3DRevision_status; - publish: boolean; + published: boolean; type: Cognite3DRevision_type; model3D: DmsUniqueIdentifier; revisionId: number; diff --git a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts index 78b655ba02b..6bfd0651cab 100644 --- a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts +++ b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts @@ -13,7 +13,9 @@ import { COGNITE_3D_OBJECT_SOURCE, COGNITE_CAD_NODE_SOURCE, COGNITE_POINT_CLOUD_VOLUME_SOURCE, - COGNITE_VISUALIZABLE_SOURCE + COGNITE_VISUALIZABLE_SOURCE, + CORE_DM_3D_CONTAINER_SPACE, + CORE_DM_SPACE } from './dataModels'; import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { cogniteObject3dSourceWithProperties } from './cogniteObject3dSourceWithProperties'; @@ -65,7 +67,7 @@ function createRelevantAssetKeySet( .concat(connectionData.items.direct_nodes_object_3ds) .concat(connectionData.items.indirect_nodes_object_3ds) .filter((object3d) => { - const props = object3d.properties.cdf_cdm_experimental['CogniteObject3D/v1']; + const props = object3d.properties[CORE_DM_SPACE]['Cognite3DObject/v1']; return ( props.cadNodes.some((node) => cadNodeSet.has(toFdmKey(node))) || props.pointCloudVolumes.some((node) => pointCloudNodeSet.has(toFdmKey(node))) @@ -74,7 +76,7 @@ function createRelevantAssetKeySet( const relevantAssetKeySet = relevantObject3Ds.reduce((acc, object3D) => { // Assume at most one connected asset - const firstAsset = head(object3D.properties.cdf_cdm_experimental['CogniteObject3D/v1'].asset); + const firstAsset = head(object3D.properties[CORE_DM_SPACE]['Cognite3DObject/v1'].asset); if (firstAsset === undefined) { return acc; } @@ -229,11 +231,7 @@ function getRevisionsCadNodeFromObject3D(object3dTableName: string): QueryTableE through: { view: COGNITE_3D_OBJECT_SOURCE, identifier: 'cadNodes' }, filter: { containsAny: { - property: [ - COGNITE_CAD_NODE_SOURCE.space, - COGNITE_CAD_NODE_SOURCE.externalId, - 'revisions' - ], + property: [CORE_DM_3D_CONTAINER_SPACE, COGNITE_CAD_NODE_SOURCE.externalId, 'revisions'], values: { parameter: 'revisionRefs' } } } @@ -249,7 +247,7 @@ function getRevisionsPointCloudVolumes(object3dTableName: string): QueryTableExp filter: { containsAny: { property: [ - COGNITE_POINT_CLOUD_VOLUME_SOURCE.space, + CORE_DM_3D_CONTAINER_SPACE, COGNITE_POINT_CLOUD_VOLUME_SOURCE.externalId, 'revisions' ], diff --git a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts index c72452979d3..28a9d619aa9 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts @@ -8,7 +8,9 @@ import { type Cognite3DObjectProperties, type COGNITE_3D_OBJECT_SOURCE, COGNITE_CAD_NODE_SOURCE, - type CogniteCADNodeProperties + type CogniteCADNodeProperties, + CORE_DM_3D_CONTAINER_SPACE, + CORE_DM_SPACE } from './dataModels'; import { cogniteObject3dSourceWithProperties } from './cogniteObject3dSourceWithProperties'; import { cogniteCadNodeSourceWithPRoperties } from './cogniteCadNodeSourceWithProperties'; @@ -27,7 +29,7 @@ export async function getCadConnectionsForRevisions( const cadNodeToModelMap = createNodeToModelMap(modelRevisions, results.items.cad_nodes); return results.items.object_3ds.flatMap((obj) => { - const props = obj.properties.cdf_cdm_experimental['CogniteObject3D/v1']; + const props = obj.properties[CORE_DM_SPACE]['Cognite3DObject/v1']; return props.cadNodes .map((cadNode) => { @@ -68,7 +70,7 @@ function createNodeToModelMap( cadNodes: PromiseType>['items']['cad_nodes'] ): Map> { return cadNodes.reduce((nodeMap, cadNode) => { - const props = cadNode.properties.cdf_cdm_experimental['CogniteCADNode/v1']; + const props = cadNode.properties[CORE_DM_SPACE]['CogniteCADNode/v1']; const modelRevisionPair = modelRevisions.find( ([modelRef, _revisionRef]) => props.model3D.externalId === modelRef.externalId && props.model3D.space === modelRef.space @@ -109,7 +111,7 @@ const cadConnectionsQuery = { { in: { property: [ - COGNITE_CAD_NODE_SOURCE.space, + CORE_DM_3D_CONTAINER_SPACE, COGNITE_CAD_NODE_SOURCE.externalId, 'model3D' ], @@ -119,7 +121,7 @@ const cadConnectionsQuery = { { containsAny: { property: [ - COGNITE_CAD_NODE_SOURCE.space, + CORE_DM_3D_CONTAINER_SPACE, COGNITE_CAD_NODE_SOURCE.externalId, 'revisions' ], diff --git a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts index 60cad243f7e..05a5752a80b 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts @@ -8,7 +8,8 @@ import { COGNITE_3D_OBJECT_SOURCE, type COGNITE_CAD_NODE_SOURCE, COGNITE_VISUALIZABLE_SOURCE, - type CogniteCADNodeProperties + type CogniteCADNodeProperties, + CORE_DM_SPACE } from './dataModels'; import { cogniteCadNodeSourceWithPRoperties } from './cogniteCadNodeSourceWithProperties'; import { getModelIdFromExternalId, getRevisionIdFromExternalId } from './getCdfIdFromExternalId'; @@ -30,7 +31,7 @@ export async function getCadModelsForInstance( >(query); return results.items.cad_nodes.flatMap((cadNode) => { - const props = cadNode.properties.cdf_cdm_experimental['CogniteCADNode/v1']; + const props = cadNode.properties[CORE_DM_SPACE]['CogniteCADNode/v1']; return props.revisions.map((revision) => ({ type: 'cad', addOptions: { diff --git a/react-components/src/data-providers/core-dm-provider/getDMSModels.ts b/react-components/src/data-providers/core-dm-provider/getDMSModels.ts index efd5546a004..bbaf39586d7 100644 --- a/react-components/src/data-providers/core-dm-provider/getDMSModels.ts +++ b/react-components/src/data-providers/core-dm-provider/getDMSModels.ts @@ -26,10 +26,12 @@ export async function getDMSModels( models: { nodes: { filter: { - and: [ - { equals: { property: ['node', 'externalId'], value: modelName } }, - { hasData: [COGNITE_3D_MODEL_SOURCE] } - ] + // and: [ + // { + equals: { property: ['node', 'externalId'], value: modelName } + // } + /* { hasData: [COGNITE_3D_MODEL_SOURCE] } */ + // ] } } } diff --git a/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts index 9c060e52df0..0e06458dbba 100644 --- a/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts +++ b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts @@ -3,7 +3,12 @@ */ import { type QueryRequest } from '@cognite/sdk/dist/src'; import { type DmsUniqueIdentifier, type FdmSDK, type NodeItem } from '../FdmSDK'; -import { COGNITE_CAD_REVISION_SOURCE, type CogniteCADRevisionProperties } from './dataModels'; +import { + COGNITE_3D_REVISION_SOURCE, + COGNITE_CAD_REVISION_SOURCE, + CORE_DM_3D_CONTAINER_SPACE, + type CogniteCADRevisionProperties +} from './dataModels'; export async function getDMSRevision( model: DmsUniqueIdentifier, @@ -12,7 +17,7 @@ export async function getDMSRevision( ): Promise> { const query = { ...cadConnectionQuery, - parameters: { modelReference: model, revisionId } + parameters: { modelReference: { space: model.space, externalId: model.externalId }, revisionId } } as const satisfies QueryRequest; const result = await fdmSdk.queryNodesAndEdges< @@ -38,8 +43,8 @@ const cadConnectionQuery = { { equals: { property: [ - COGNITE_CAD_REVISION_SOURCE.space, - COGNITE_CAD_REVISION_SOURCE.externalId, + CORE_DM_3D_CONTAINER_SPACE, + COGNITE_3D_REVISION_SOURCE.externalId, 'model3D' ], value: { parameter: 'modelReference' } @@ -48,11 +53,11 @@ const cadConnectionQuery = { { in: { property: [ - COGNITE_CAD_REVISION_SOURCE.space, + CORE_DM_3D_CONTAINER_SPACE, COGNITE_CAD_REVISION_SOURCE.externalId, 'revisionId' ], - values: { parameter: 'nodeIds' } + values: { parameter: 'revisionId' } } } ] @@ -66,7 +71,7 @@ const cadConnectionQuery = { sources: [ { source: COGNITE_CAD_REVISION_SOURCE, - properties: ['status', 'publish', 'type', 'model3D', 'revisionId'] + properties: ['status', 'published', 'type', 'model3D', 'revisionId'] } ] } diff --git a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts index 8bcec4446cf..642be8efe93 100644 --- a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts +++ b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts @@ -10,7 +10,9 @@ import { type COGNITE_ASSET_SOURCE, COGNITE_CAD_NODE_SOURCE, type CogniteAssetProperties, - type CogniteCADNodeProperties + type CogniteCADNodeProperties, + CORE_DM_3D_CONTAINER_SPACE, + CORE_DM_SPACE } from './dataModels'; import { getModelIdFromExternalId } from './getCdfIdFromExternalId'; import { toFdmKey } from '../utils/toFdmKey'; @@ -45,7 +47,7 @@ export async function getFdmConnectionsForNodes( >(query); result.items.cad_nodes.forEach((cadNode) => { - const props = cadNode.properties.cdf_cdm_experimental['CogniteCADNode/v1']; + const props = cadNode.properties[CORE_DM_SPACE]['CogniteCADNode/v1']; const revisionIndex = props.revisions.findIndex((id) => id === revisionRef); const treeIndex = props.treeIndexes[revisionIndex]; @@ -58,15 +60,15 @@ export async function getFdmConnectionsForNodes( }); const relevantObjects3D = result.items.objects_3d.filter((object3D) => { - return object3D.properties.cdf_cdm_experimental['CogniteObject3D/v1'].cadNodes.some( - (cadNodeId) => relevantCadNodeRefToObject3dRef.has(toFdmKey(cadNodeId)) + return object3D.properties[CORE_DM_SPACE]['Cognite3DObject/v1'].cadNodes.some((cadNodeId) => + relevantCadNodeRefToObject3dRef.has(toFdmKey(cadNodeId)) ); }); const relevantObjectToAssetsMap = new Map( relevantObjects3D.map((obj) => [ toFdmKey(obj), - obj.properties.cdf_cdm_experimental['CogniteObject3D/v1'].asset + obj.properties[CORE_DM_SPACE]['Cognite3DObject/v1'].asset ]) ); @@ -102,7 +104,7 @@ const cadConnectionQuery = { { equals: { property: [ - COGNITE_CAD_NODE_SOURCE.space, + CORE_DM_3D_CONTAINER_SPACE, COGNITE_CAD_NODE_SOURCE.externalId, 'model3D' ], @@ -112,7 +114,7 @@ const cadConnectionQuery = { { containsAny: { property: [ - COGNITE_CAD_NODE_SOURCE.space, + CORE_DM_3D_CONTAINER_SPACE, COGNITE_CAD_NODE_SOURCE.externalId, 'treeIndexes' ], @@ -122,7 +124,7 @@ const cadConnectionQuery = { { containsAny: { property: [ - COGNITE_CAD_NODE_SOURCE.space, + CORE_DM_3D_CONTAINER_SPACE, COGNITE_CAD_NODE_SOURCE.externalId, 'revisions' ], diff --git a/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts b/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts index ef52ce24eef..a83435028c8 100644 --- a/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts +++ b/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts @@ -15,7 +15,8 @@ import { type COGNITE_ASSET_SOURCE, COGNITE_CAD_NODE_SOURCE, COGNITE_POINT_CLOUD_VOLUME_SOURCE, - type CogniteAssetProperties + type CogniteAssetProperties, + CORE_DM_3D_CONTAINER_SPACE } from './dataModels'; import { cogniteAssetSourceWithProperties } from './cogniteAssetSourceWithProperties'; @@ -68,7 +69,7 @@ export async function listMappedFdmNodes( const containsRevisionFilter: InstanceFilter = { containsAny: { - property: [COGNITE_CAD_NODE_SOURCE.space, COGNITE_CAD_NODE_SOURCE.externalId, 'revisions'], + property: [CORE_DM_3D_CONTAINER_SPACE, COGNITE_CAD_NODE_SOURCE.externalId, 'revisions'], values: { parameter: 'revisionRefs' } } } as const; From 1b95a2991b2ec18fad9be827d98ab13fd8408b3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Fri, 23 Aug 2024 14:07:02 +0200 Subject: [PATCH 15/32] chore: further corrections --- .../cogniteCadNodeSourceWithProperties.ts | 2 +- .../getCadConnectionsForRevisions.ts | 4 +-- .../getCadModelsForInstance.ts | 4 +-- .../core-dm-provider/getDMSModels.ts | 12 ++++----- .../core-dm-provider/getDMSRevision.ts | 4 +-- .../getFdmConnectionsForNodeIds.ts | 25 ++++++------------- 6 files changed, 20 insertions(+), 31 deletions(-) diff --git a/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts index fd6eed0ef25..cd25532bdb3 100644 --- a/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts +++ b/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts @@ -4,7 +4,7 @@ import { type SourceSelectorV3 } from '@cognite/sdk/dist/src'; import { COGNITE_CAD_NODE_SOURCE } from './dataModels'; -export const cogniteCadNodeSourceWithPRoperties = [ +export const cogniteCadNodeSourceWithProperties = [ { source: COGNITE_CAD_NODE_SOURCE, properties: [ diff --git a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts index 28a9d619aa9..beaf0803cac 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts @@ -13,7 +13,7 @@ import { CORE_DM_SPACE } from './dataModels'; import { cogniteObject3dSourceWithProperties } from './cogniteObject3dSourceWithProperties'; -import { cogniteCadNodeSourceWithPRoperties } from './cogniteCadNodeSourceWithProperties'; +import { cogniteCadNodeSourceWithProperties } from './cogniteCadNodeSourceWithProperties'; import { getModelIdFromExternalId, getRevisionIdFromExternalId } from './getCdfIdFromExternalId'; import { toFdmKey } from '../utils/toFdmKey'; import { type PromiseType } from '../utils/typeUtils'; @@ -140,7 +140,7 @@ const cadConnectionsQuery = { } }, select: { - cad_nodes: { sources: cogniteCadNodeSourceWithPRoperties }, + cad_nodes: { sources: cogniteCadNodeSourceWithProperties }, object_3ds: { sources: cogniteObject3dSourceWithProperties } } } as const satisfies Omit; diff --git a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts index 05a5752a80b..460ed7eff7b 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts @@ -11,7 +11,7 @@ import { type CogniteCADNodeProperties, CORE_DM_SPACE } from './dataModels'; -import { cogniteCadNodeSourceWithPRoperties } from './cogniteCadNodeSourceWithProperties'; +import { cogniteCadNodeSourceWithProperties } from './cogniteCadNodeSourceWithProperties'; import { getModelIdFromExternalId, getRevisionIdFromExternalId } from './getCdfIdFromExternalId'; export async function getCadModelsForInstance( @@ -66,6 +66,6 @@ const cadModelsForInstanceQuery = { } }, select: { - cad_nodes: { sources: cogniteCadNodeSourceWithPRoperties } + cad_nodes: { sources: cogniteCadNodeSourceWithProperties } } } as const satisfies Omit; diff --git a/react-components/src/data-providers/core-dm-provider/getDMSModels.ts b/react-components/src/data-providers/core-dm-provider/getDMSModels.ts index bbaf39586d7..6c873e2ce32 100644 --- a/react-components/src/data-providers/core-dm-provider/getDMSModels.ts +++ b/react-components/src/data-providers/core-dm-provider/getDMSModels.ts @@ -26,12 +26,12 @@ export async function getDMSModels( models: { nodes: { filter: { - // and: [ - // { - equals: { property: ['node', 'externalId'], value: modelName } - // } - /* { hasData: [COGNITE_3D_MODEL_SOURCE] } */ - // ] + and: [ + { + equals: { property: ['node', 'externalId'], value: modelName } + }, + { hasData: [COGNITE_3D_MODEL_SOURCE] } + ] } } } diff --git a/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts index 0e06458dbba..3c741ab4521 100644 --- a/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts +++ b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts @@ -51,13 +51,13 @@ const cadConnectionQuery = { } }, { - in: { + equals: { property: [ CORE_DM_3D_CONTAINER_SPACE, COGNITE_CAD_REVISION_SOURCE.externalId, 'revisionId' ], - values: { parameter: 'revisionId' } + value: { parameter: 'revisionId' } } } ] diff --git a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts index 642be8efe93..81760b7386e 100644 --- a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts +++ b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts @@ -16,6 +16,7 @@ import { } from './dataModels'; import { getModelIdFromExternalId } from './getCdfIdFromExternalId'; import { toFdmKey } from '../utils/toFdmKey'; +import { cogniteCadNodeSourceWithProperties } from './cogniteCadNodeSourceWithProperties'; export async function getFdmConnectionsForNodes( model: DmsUniqueIdentifier, @@ -32,7 +33,11 @@ export async function getFdmConnectionsForNodes( const query = { ...cadConnectionQuery, - parameters: { modelReference: model, treeIndexes, revisionRef } + parameters: { + modelReference: { externalId: model.externalId, space: model.space }, + treeIndexes, + revisionRef: { externalId: revisionRef.externalId, space: revisionRef.space } + } }; const modelId = getModelIdFromExternalId(model.externalId); @@ -151,23 +156,7 @@ const cadConnectionQuery = { }, select: { cad_nodes: { - sources: [ - { - source: COGNITE_CAD_NODE_SOURCE, - properties: [ - 'name', - 'description', - 'tags', - 'aliases', - 'object3D', - 'model3D', - 'cadNodeReference', - 'revisions', - 'treeIndexes', - 'subTreeSizes' - ] - } - ] + sources: cogniteCadNodeSourceWithProperties }, assets: {}, objects_3d: { From 7a4e0c821ea867c9e9b352cf2701030d41ce4951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Mon, 26 Aug 2024 10:34:28 +0200 Subject: [PATCH 16/32] chore: made some more fixes --- .../core-dm-provider/CoreDm3dDataProvider.ts | 3 +- .../cogniteAssetSourceWithProperties.ts | 2 +- .../core-dm-provider/dataModels.ts | 6 ++- .../getCadConnectionsForRevisions.ts | 24 ++++++---- .../core-dm-provider/getDMSRevision.ts | 3 +- .../getFdmConnectionsForNodeIds.ts | 44 ++++++++----------- .../core-dm-provider/listMappedFdmNodes.ts | 11 ++--- .../src/query/useSearchMappedEquipmentFDM.tsx | 5 ++- 8 files changed, 55 insertions(+), 43 deletions(-) diff --git a/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts b/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts index 48584c281c0..dee1c2c756a 100644 --- a/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts +++ b/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts @@ -27,6 +27,7 @@ import { filterNodesByMappedTo3d } from './filterNodesByMappedTo3d'; import { getCadModelsForInstance } from './getCadModelsForInstance'; import { getCadConnectionsForRevisions } from './getCadConnectionsForRevisions'; import { zip } from 'lodash'; +import { restrictToDmsId } from './restrictToDmsId'; const MAX_PARALLEL_QUERIES = 2; @@ -81,7 +82,7 @@ export class CoreDm3dFdm3dDataProvider implements Fdm3dDataProvider { throw Error(`No revision with id ${revisionId} found`); } - return revisionRef; + return restrictToDmsId(revisionRef); } private async getDMSModelsForIds( diff --git a/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts index 7a94853d5e5..659ca9b722e 100644 --- a/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts +++ b/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts @@ -23,7 +23,7 @@ export const cogniteAssetSourceWithProperties = [ 'parent', 'root', 'path', - 'lastPathMaterializationTime', + 'pathLastUpdatedTime', 'equipment', 'assetClass', 'type', diff --git a/react-components/src/data-providers/core-dm-provider/dataModels.ts b/react-components/src/data-providers/core-dm-provider/dataModels.ts index 28d5ab00ab1..2b6375959ae 100644 --- a/react-components/src/data-providers/core-dm-provider/dataModels.ts +++ b/react-components/src/data-providers/core-dm-provider/dataModels.ts @@ -107,7 +107,7 @@ export type CogniteAssetProperties = { parent: DmsUniqueIdentifier; root: DmsUniqueIdentifier; path: DmsUniqueIdentifier[]; - lastPathMaterializationTime: Timestamp; + pathLastUpdatedTime: Timestamp; equipment: DmsUniqueIdentifier; assetClass: DmsUniqueIdentifier; type: DmsUniqueIdentifier; @@ -117,6 +117,10 @@ export type CogniteAssetProperties = { timeSeries: DmsUniqueIdentifier[]; }; +export type CogniteVisualizableProperties = { + object3D: DmsUniqueIdentifier; +}; + export type CogniteCADRevisionProperties = { status: Cognite3DRevision_status; published: boolean; diff --git a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts index beaf0803cac..9aeb2c9e919 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts @@ -6,7 +6,7 @@ import { type FdmCadConnection, type FdmKey } from '../../components/CacheProvid import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { type Cognite3DObjectProperties, - type COGNITE_3D_OBJECT_SOURCE, + COGNITE_3D_OBJECT_SOURCE, COGNITE_CAD_NODE_SOURCE, type CogniteCADNodeProperties, CORE_DM_3D_CONTAINER_SPACE, @@ -19,6 +19,7 @@ import { toFdmKey } from '../utils/toFdmKey'; import { type PromiseType } from '../utils/typeUtils'; import { isDefined } from '../../utilities/isDefined'; import { type QueryResult } from '../utils/queryNodesAndEdges'; +import { restrictToDmsId } from './restrictToDmsId'; export async function getCadConnectionsForRevisions( modelRevisions: Array<[DmsUniqueIdentifier, DmsUniqueIdentifier]>, @@ -28,9 +29,9 @@ export async function getCadConnectionsForRevisions( const cadNodeToModelMap = createNodeToModelMap(modelRevisions, results.items.cad_nodes); - return results.items.object_3ds.flatMap((obj) => { - const props = obj.properties[CORE_DM_SPACE]['Cognite3DObject/v1']; + const returnResult = results.items.object_3ds.flatMap((obj) => { + const props = obj.properties[CORE_DM_SPACE]['Cognite3DObject/v1']; return props.cadNodes .map((cadNode) => { const modelObj = cadNodeToModelMap.get(toFdmKey(cadNode)); @@ -41,6 +42,7 @@ export async function getCadConnectionsForRevisions( }) .filter(isDefined); }); + return returnResult; } type SourcesSelectType = [ @@ -53,8 +55,8 @@ async function getModelConnectionResults( fdmSdk: FdmSDK ): Promise> { const parameters = { - modelRefs: modelRevisions.map(([modelRef, _revisionRef]) => modelRef), - revisionRefs: modelRevisions.map(([_modelRef, revisionRef]) => revisionRef) + modelRefs: modelRevisions.map(([modelRef, _revisionRef]) => restrictToDmsId(modelRef)), + revisionRefs: modelRevisions.map(([_modelRef, revisionRef]) => restrictToDmsId(revisionRef)) }; const query = { @@ -130,13 +132,19 @@ const cadConnectionsQuery = { } ] } - } + }, + limit: 10000 }, object_3ds: { nodes: { from: 'cad_nodes', - through: { view: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' } - } + through: { view: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' }, + direction: 'outwards', + filter: { + hasData: [COGNITE_3D_OBJECT_SOURCE] + } + }, + limit: 10000 } }, select: { diff --git a/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts index 3c741ab4521..d230d5afb8d 100644 --- a/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts +++ b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts @@ -9,6 +9,7 @@ import { CORE_DM_3D_CONTAINER_SPACE, type CogniteCADRevisionProperties } from './dataModels'; +import { restrictToDmsId } from './restrictToDmsId'; export async function getDMSRevision( model: DmsUniqueIdentifier, @@ -17,7 +18,7 @@ export async function getDMSRevision( ): Promise> { const query = { ...cadConnectionQuery, - parameters: { modelReference: { space: model.space, externalId: model.externalId }, revisionId } + parameters: { modelReference: restrictToDmsId(model), revisionId } } as const satisfies QueryRequest; const result = await fdmSdk.queryNodesAndEdges< diff --git a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts index 81760b7386e..696dfd22508 100644 --- a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts +++ b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts @@ -7,16 +7,19 @@ import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { type Cognite3DObjectProperties, COGNITE_3D_OBJECT_SOURCE, - type COGNITE_ASSET_SOURCE, + COGNITE_ASSET_SOURCE, COGNITE_CAD_NODE_SOURCE, + COGNITE_VISUALIZABLE_SOURCE, type CogniteAssetProperties, type CogniteCADNodeProperties, + CogniteVisualizableProperties, CORE_DM_3D_CONTAINER_SPACE, CORE_DM_SPACE } from './dataModels'; import { getModelIdFromExternalId } from './getCdfIdFromExternalId'; import { toFdmKey } from '../utils/toFdmKey'; import { cogniteCadNodeSourceWithProperties } from './cogniteCadNodeSourceWithProperties'; +import { restrictToDmsId } from './restrictToDmsId'; export async function getFdmConnectionsForNodes( model: DmsUniqueIdentifier, @@ -34,9 +37,9 @@ export async function getFdmConnectionsForNodes( const query = { ...cadConnectionQuery, parameters: { - modelReference: { externalId: model.externalId, space: model.space }, + modelReference: restrictToDmsId(model), treeIndexes, - revisionRef: { externalId: revisionRef.externalId, space: revisionRef.space } + revisionRefs: [restrictToDmsId(revisionRef)] } }; @@ -46,6 +49,7 @@ export async function getFdmConnectionsForNodes( typeof query, [ { source: typeof COGNITE_ASSET_SOURCE; properties: CogniteAssetProperties }, + { source: typeof COGNITE_VISUALIZABLE_SOURCE; properties: CogniteVisualizableProperties }, { source: typeof COGNITE_CAD_NODE_SOURCE; properties: CogniteCADNodeProperties }, { source: typeof COGNITE_3D_OBJECT_SOURCE; properties: Cognite3DObjectProperties } ] @@ -64,16 +68,10 @@ export async function getFdmConnectionsForNodes( } }); - const relevantObjects3D = result.items.objects_3d.filter((object3D) => { - return object3D.properties[CORE_DM_SPACE]['Cognite3DObject/v1'].cadNodes.some((cadNodeId) => - relevantCadNodeRefToObject3dRef.has(toFdmKey(cadNodeId)) - ); - }); - - const relevantObjectToAssetsMap = new Map( - relevantObjects3D.map((obj) => [ - toFdmKey(obj), - obj.properties[CORE_DM_SPACE]['Cognite3DObject/v1'].asset + const relevantObjectToAssetsMap = new Map( + result.items.assets.map((asset) => [ + toFdmKey(asset.properties.cdf_cdm['CogniteVisualizable/v1'].object3D), + asset ]) ); @@ -85,16 +83,14 @@ export async function getFdmConnectionsForNodes( // Should not happen return; } - const assets = relevantObjectToAssetsMap.get(object3dKey); + const asset = relevantObjectToAssetsMap.get(object3dKey); - if (assets === undefined) { + if (asset === undefined) { // Should not happen return; } - assets.forEach((asset) => - connections.push({ modelId, revisionId, treeIndex, instance: asset }) - ); + connections.push({ modelId, revisionId, treeIndex, instance: asset }); }); return connections; @@ -133,7 +129,7 @@ const cadConnectionQuery = { COGNITE_CAD_NODE_SOURCE.externalId, 'revisions' ], - values: { parameter: 'revisionRef' } + values: { parameter: 'revisionRefs' } } } ] @@ -149,8 +145,8 @@ const cadConnectionQuery = { assets: { nodes: { from: 'objects_3d', - through: { view: COGNITE_3D_OBJECT_SOURCE, identifier: 'asset' }, - direction: 'outwards' + through: { view: COGNITE_ASSET_SOURCE, identifier: 'object3D' }, + direction: 'inwards' } } }, @@ -158,9 +154,7 @@ const cadConnectionQuery = { cad_nodes: { sources: cogniteCadNodeSourceWithProperties }, - assets: {}, - objects_3d: { - sources: [{ source: COGNITE_3D_OBJECT_SOURCE, properties: ['name', 'asset', 'cadNodes'] }] - } + assets: { sources: [{ source: COGNITE_VISUALIZABLE_SOURCE, properties: ['object3D'] }] }, + objects_3d: {} } } as const satisfies Omit; diff --git a/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts b/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts index a83435028c8..7c9c45f6f41 100644 --- a/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts +++ b/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts @@ -11,8 +11,7 @@ import { } from '../FdmSDK'; import { type QueryRequest } from '@cognite/sdk'; import { - COGNITE_3D_OBJECT_SOURCE, - type COGNITE_ASSET_SOURCE, + COGNITE_ASSET_SOURCE, COGNITE_CAD_NODE_SOURCE, COGNITE_POINT_CLOUD_VOLUME_SOURCE, type CogniteAssetProperties, @@ -98,7 +97,8 @@ function createRawQuery( cad_assets: { nodes: { from: 'cad_object_3d', - through: { view: COGNITE_3D_OBJECT_SOURCE, identifier: 'asset' }, + through: { view: COGNITE_ASSET_SOURCE, identifier: 'object3D' }, + direction: 'inwards', filter } }, @@ -116,8 +116,9 @@ function createRawQuery( }, pointcloud_assets: { nodes: { - from: 'cad_object_3d', - through: { view: COGNITE_3D_OBJECT_SOURCE, identifier: 'asset' }, + from: 'pointcloud_object_3d', + through: { view: COGNITE_ASSET_SOURCE, identifier: 'object3D' }, + direction: 'inwards', filter } } diff --git a/react-components/src/query/useSearchMappedEquipmentFDM.tsx b/react-components/src/query/useSearchMappedEquipmentFDM.tsx index 45da5749830..5f9af8c5e93 100644 --- a/react-components/src/query/useSearchMappedEquipmentFDM.tsx +++ b/react-components/src/query/useSearchMappedEquipmentFDM.tsx @@ -40,12 +40,15 @@ export const useSearchMappedEquipmentFDM = ( return useQuery({ queryKey: ['reveal', 'react-components', 'search-mapped-fdm', query, models, viewsToSearch], queryFn: async () => { - if (models.length === 0 || viewsToSearch.length === 0) { + if (models.length === 0) { return []; } const sources = await createSourcesFromViews(viewsToSearch, fdmSdk); const chunkedSources = chunk(sources, 10); + if (chunkedSources.length === 0) { + chunkedSources.push([]); + } const queryResults: InstancesWithView[] = []; From 9c78c266fd691183cff0d947a65d6da286b7f827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Wed, 28 Aug 2024 13:18:48 +0200 Subject: [PATCH 17/32] fix: more fixes --- .../components/CacheProvider/FdmNodeCache.ts | 20 +-- .../CacheProvider/RevisionFdmNodeCache.ts | 29 ++-- .../src/components/CacheProvider/types.ts | 4 +- react-components/src/data-providers/FdmSDK.ts | 4 +- .../core-dm-provider/dataModels.ts | 8 +- .../filterNodesByMappedTo3d.ts | 4 +- .../getCadConnectionsForRevisions.ts | 151 +++++++++++------- .../getCdfIdFromExternalId.ts | 5 +- .../getEdgeConnected3dInstances.ts | 12 +- .../core-dm-provider/listMappedFdmNodes.ts | 6 +- react-components/src/hooks/useClickedNode.tsx | 2 +- .../useSearchMappedEquipmentAssetMappings.tsx | 3 +- .../src/query/useSearchMappedEquipmentFDM.tsx | 79 ++++----- 13 files changed, 190 insertions(+), 137 deletions(-) diff --git a/react-components/src/components/CacheProvider/FdmNodeCache.ts b/react-components/src/components/CacheProvider/FdmNodeCache.ts index 7a3023abcd9..45dcc03955e 100644 --- a/react-components/src/components/CacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/FdmNodeCache.ts @@ -269,7 +269,7 @@ export class FdmNodeCache { private async getViewsForConnections( connections: FdmCadConnection[] - ): Promise> { + ): Promise> { const nodeInspectionResults = await inspectNodes( this._fdmClient, connections.map((connection) => connection.instance) @@ -277,7 +277,7 @@ export class FdmNodeCache { const dataWithViews = connections.map((connection, ind) => ({ connection, - view: nodeInspectionResults.items[ind].inspectionResults.involvedViews[0] + views: nodeInspectionResults.items[ind].inspectionResults.involvedViews })); return dataWithViews; @@ -307,19 +307,19 @@ export class FdmNodeCache { } async function createRevisionToConnectionsMap( - connectionsWithView: Array<{ connection: FdmCadConnection; view?: Source }>, + connectionsWithViews: Array<{ connection: FdmCadConnection; views?: Source[] }>, modelRevisionIds: ModelRevisionId[], cdfClient: CogniteClient ): Promise> { - const revisionToTreeIndexMap = createRevisionToTreeIndexMap(connectionsWithView); + const revisionToTreeIndexMap = createRevisionToTreeIndexMap(connectionsWithViews); const modelTreeIndexToNodeMap = await createModelTreeIndexToNodeMap( revisionToTreeIndexMap, modelRevisionIds, cdfClient ); - return connectionsWithView.reduce((map, connectionWithView) => { - const connectionRevisionId = connectionWithView.connection.revisionId; + return connectionsWithViews.reduce((map, connectionWithViews) => { + const connectionRevisionId = connectionWithViews.connection.revisionId; const modelRevisionId = modelRevisionIds.find((p) => p.revisionId === connectionRevisionId); if (modelRevisionId === undefined) return map; @@ -327,8 +327,8 @@ async function createRevisionToConnectionsMap( const value = createFdmConnectionWithNode( modelRevisionId, modelTreeIndexToNodeMap, - connectionWithView.connection, - connectionWithView.view + connectionWithViews.connection, + connectionWithViews.views ); insertConnectionIntoMapList(value, map, modelRevisionId); @@ -341,7 +341,7 @@ function createFdmConnectionWithNode( modelRevisionId: ModelRevisionId, modelTreeIndexToNodeMap: Map, connection: FdmCadConnection, - view?: Source + views?: Source[] ): FdmConnectionWithNode { const revisionTreeIndexKey = createModelTreeIndexKey( modelRevisionId.modelId, @@ -352,7 +352,7 @@ function createFdmConnectionWithNode( const node = modelTreeIndexToNodeMap.get(revisionTreeIndexKey); assert(node !== undefined); - return { connection, cadNode: node, view }; + return { connection, cadNode: node, views }; } function insertConnectionIntoMapList( diff --git a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts index ebf3c3477e3..6493ce2d97c 100644 --- a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts @@ -81,9 +81,9 @@ export class RevisionFdmNodeCache { private async assertOrFetchViewsForNodeData( searchTreeIndex: number, cachedFdmData: FdmConnectionWithNode[] - ): Promise { - if (checkDefinedView(cachedFdmData)) { - return cachedFdmData.map((data) => data.view); + ): Promise { + if (checkDefinedViews(cachedFdmData)) { + return cachedFdmData.map((data) => data.views); } const cadNode = cachedFdmData[0].cadNode; @@ -123,7 +123,7 @@ export class RevisionFdmNodeCache { private async getViewsPromiseFromDataPromises( cadAndConnectionsPromise: Promise, ancestorDataPromise: Promise - ): Promise { + ): Promise { const cadAndConnections = await cadAndConnectionsPromise; const { ancestorsWithSameMapping } = await ancestorDataPromise; const ancestorTreeIndexes = ancestorsWithSameMapping.map((ancestor) => ancestor.treeIndex); @@ -137,9 +137,9 @@ export class RevisionFdmNodeCache { ? this._treeIndexToFdmConnections.get(cachedTreeIndexesDescending[0]) : undefined; - if (checkDefinedView(cachedNodeData)) { + if (checkDefinedViews(cachedNodeData)) { this.setCacheDataForTreeIndices(ancestorTreeIndexes, cachedNodeData); - return cachedNodeData.map((data) => data.view); + return cachedNodeData.map((data) => data.views); } return await this.getAndCacheViewsPromiseForNodeData(cadAndConnections, ancestorTreeIndexes); @@ -180,7 +180,7 @@ export class RevisionFdmNodeCache { private async getAndCacheViewsPromiseForNodeData( cadAndFdmIds: CadNodeWithConnections | undefined, ancestorIndicesWithSameMapping: TreeIndex[] - ): Promise { + ): Promise { if (cadAndFdmIds === undefined) { this.setCacheDataForTreeIndices(ancestorIndicesWithSameMapping, []); return undefined; @@ -191,14 +191,12 @@ export class RevisionFdmNodeCache { cadAndFdmIds.connections.map((connection) => connection.instance) ); - const views = nodeInspectionResults.items.map( - (item) => item.inspectionResults.involvedViews[0] - ); + const views = nodeInspectionResults.items.map((item) => item.inspectionResults.involvedViews); const dataWithViews = cadAndFdmIds.connections.map((connection, ind) => ({ connection, cadNode: cadAndFdmIds.cadNode, - view: nodeInspectionResults.items[ind].inspectionResults.involvedViews[0] + view: views[ind] })); this.setCacheDataForTreeIndices(ancestorIndicesWithSameMapping, dataWithViews); @@ -290,7 +288,7 @@ export class RevisionFdmNodeCache { public async fetchViewsForAllConnections(): Promise { const allConnectionsWithoutView = this.getAllConnections().filter( - (connection) => connection.view === undefined + (connection) => connection.views === undefined || connection.views.length === 0 ); if (allConnectionsWithoutView.length === 0) { @@ -323,7 +321,7 @@ export class RevisionFdmNodeCache { ); if (presentConnection !== undefined) { - presentConnection.view = connection.view; + presentConnection.views = connection.views; return; } @@ -359,12 +357,13 @@ function getAncestorDataForTreeIndex( }; } -export function checkDefinedView( +export function checkDefinedViews( connections?: FdmConnectionWithNode[] ): connections is Array> { if (connections === undefined) return false; return connections?.every( - (connection): connection is Required => connection.view !== undefined + (connection): connection is Required => + connection.views !== undefined && connection.views.length > 0 ); } diff --git a/react-components/src/components/CacheProvider/types.ts b/react-components/src/components/CacheProvider/types.ts index bdd077d1c4d..673720938e2 100644 --- a/react-components/src/components/CacheProvider/types.ts +++ b/react-components/src/components/CacheProvider/types.ts @@ -21,14 +21,14 @@ export type FdmCadConnection = { export type FdmConnectionWithNode = { connection: FdmCadConnection; cadNode: Node3D; - view?: Source; + views?: Source[]; }; export type CadNodeWithFdmIds = { cadNode: Node3D; fdmIds: DmsUniqueIdentifier[] }; export type CadNodeWithConnections = { cadNode: Node3D; connections: FdmCadConnection[] }; export type FdmNodeDataPromises = { cadAndFdmNodesPromise: Promise; - viewsPromise: Promise; + viewsPromise: Promise; }; export type ModelRevisionAssetNodesResult = { diff --git a/react-components/src/data-providers/FdmSDK.ts b/react-components/src/data-providers/FdmSDK.ts index a21493c1fea..628cdb0de6a 100644 --- a/react-components/src/data-providers/FdmSDK.ts +++ b/react-components/src/data-providers/FdmSDK.ts @@ -553,7 +553,9 @@ export class FdmSDK { } public async listDataModels(): Promise { - const result = await this._sdk.get(this._listDataModelsEndpoint, { params: { limit: 1000 } }); + const result = await this._sdk.get(this._listDataModelsEndpoint, { + params: { limit: 1000, includeGlobal: true } + }); if (result.status === 200) { return result.data; } diff --git a/react-components/src/data-providers/core-dm-provider/dataModels.ts b/react-components/src/data-providers/core-dm-provider/dataModels.ts index 2b6375959ae..b7d61d0cce0 100644 --- a/react-components/src/data-providers/core-dm-provider/dataModels.ts +++ b/react-components/src/data-providers/core-dm-provider/dataModels.ts @@ -153,8 +153,8 @@ export type Cognite3DObjectProperties = { yMax: number; zMin: number; zMax: number; - asset: DmsUniqueIdentifier[]; - cadNodes: DmsUniqueIdentifier[]; - images360: DmsUniqueIdentifier[]; - pointCloudVolumes: DmsUniqueIdentifier[]; + asset?: DmsUniqueIdentifier[] | undefined; + cadNodes?: DmsUniqueIdentifier[] | undefined; + images360?: DmsUniqueIdentifier[] | undefined; + pointCloudVolumes?: DmsUniqueIdentifier[] | undefined; }; diff --git a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts index 6bfd0651cab..08d6d535063 100644 --- a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts +++ b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts @@ -69,8 +69,8 @@ function createRelevantAssetKeySet( .filter((object3d) => { const props = object3d.properties[CORE_DM_SPACE]['Cognite3DObject/v1']; return ( - props.cadNodes.some((node) => cadNodeSet.has(toFdmKey(node))) || - props.pointCloudVolumes.some((node) => pointCloudNodeSet.has(toFdmKey(node))) + props.cadNodes?.some((node) => cadNodeSet.has(toFdmKey(node))) || + props.pointCloudVolumes?.some((node) => pointCloudNodeSet.has(toFdmKey(node))) ); }); diff --git a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts index 9aeb2c9e919..b9bd9752194 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts @@ -3,11 +3,12 @@ */ import { type QueryRequest } from '@cognite/sdk/dist/src'; import { type FdmCadConnection, type FdmKey } from '../../components/CacheProvider/types'; -import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; +import { FdmNode, NodeItem, type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { - type Cognite3DObjectProperties, COGNITE_3D_OBJECT_SOURCE, + COGNITE_ASSET_SOURCE, COGNITE_CAD_NODE_SOURCE, + CogniteAssetProperties, type CogniteCADNodeProperties, CORE_DM_3D_CONTAINER_SPACE, CORE_DM_SPACE @@ -20,34 +21,103 @@ import { type PromiseType } from '../utils/typeUtils'; import { isDefined } from '../../utilities/isDefined'; import { type QueryResult } from '../utils/queryNodesAndEdges'; import { restrictToDmsId } from './restrictToDmsId'; +import { cogniteAssetSourceWithProperties } from './cogniteAssetSourceWithProperties'; export async function getCadConnectionsForRevisions( modelRevisions: Array<[DmsUniqueIdentifier, DmsUniqueIdentifier]>, fdmSdk: FdmSDK ): Promise { const results = await getModelConnectionResults(modelRevisions, fdmSdk); + const object3dToAssetMap = createObject3dToAssetMap(results.items.assets); + const cadNodeToModelMap = createCadNodeToObject3dMap(results.items.cad_nodes); - const cadNodeToModelMap = createNodeToModelMap(modelRevisions, results.items.cad_nodes); + const returnResult = results.items.cad_nodes + .map((cadNode) => { + const props = cadNode.properties[CORE_DM_SPACE]['CogniteCADNode/v1']; + const object3dKey = cadNodeToModelMap.get(toFdmKey(cadNode)); + if (object3dKey === undefined) { + return undefined; + } + + const connectedAsset = object3dToAssetMap.get(object3dKey); + + if (connectedAsset === undefined) { + return undefined; + } + + const modelIdRevisionIdTreeIndex = getModelAndTreeIndex(modelRevisions, props); + + if (modelIdRevisionIdTreeIndex === undefined) { + return undefined; + } + + return { + ...modelIdRevisionIdTreeIndex, + instance: restrictToDmsId(connectedAsset) + }; + }) + .filter(isDefined); - const returnResult = results.items.object_3ds.flatMap((obj) => { - const props = obj.properties[CORE_DM_SPACE]['Cognite3DObject/v1']; - return props.cadNodes - .map((cadNode) => { - const modelObj = cadNodeToModelMap.get(toFdmKey(cadNode)); - if (modelObj === undefined) { - return undefined; - } - return { ...modelObj, instance: obj }; - }) - .filter(isDefined); - }); return returnResult; } +function createObject3dToAssetMap>( + assets: T[] +): Map { + return new Map( + assets.map((asset) => [ + toFdmKey(asset.properties[CORE_DM_SPACE]?.['CogniteAsset/v1'].object3D), + asset + ]) + ); +} + +function createCadNodeToObject3dMap( + cadNodes: PromiseType>['items']['cad_nodes'] +): Map { + return new Map( + cadNodes.map((cadNode) => [ + toFdmKey(cadNode), + toFdmKey(cadNode.properties.cdf_cdm['CogniteCADNode/v1'].object3D) + ]) + ); +} + +function getModelAndTreeIndex( + modelRevisions: Array<[DmsUniqueIdentifier, DmsUniqueIdentifier]>, + cadNodeProps: CogniteCADNodeProperties +): { modelId: number; revisionId: number; treeIndex: number } | undefined { + const modelRevisionPair = modelRevisions.find( + ([modelRef, _revisionRef]) => + cadNodeProps.model3D.externalId === modelRef.externalId && + cadNodeProps.model3D.space === modelRef.space + ); + + if (modelRevisionPair === undefined) { + return undefined; + } + + const revisionIndex = cadNodeProps.revisions.findIndex( + (propRevision) => + modelRevisionPair[1].externalId === propRevision.externalId && + modelRevisionPair[1].space === propRevision.space + ); + + if (revisionIndex === -1) { + return undefined; + } + + const modelId = getModelIdFromExternalId(cadNodeProps.model3D.externalId); + const revisionId = getRevisionIdFromExternalId(cadNodeProps.revisions[revisionIndex].externalId); + const treeIndex = cadNodeProps.treeIndexes[revisionIndex]; + + return { modelId, revisionId, treeIndex }; +} + type SourcesSelectType = [ - { source: typeof COGNITE_3D_OBJECT_SOURCE; properties: Cognite3DObjectProperties }, - { source: typeof COGNITE_CAD_NODE_SOURCE; properties: CogniteCADNodeProperties } + { source: typeof COGNITE_CAD_NODE_SOURCE; properties: CogniteCADNodeProperties }, + { source: typeof COGNITE_ASSET_SOURCE; properties: CogniteAssetProperties } ]; async function getModelConnectionResults( @@ -67,43 +137,6 @@ async function getModelConnectionResults( return await fdmSdk.queryAllNodesAndEdges(query); } -function createNodeToModelMap( - modelRevisions: Array<[DmsUniqueIdentifier, DmsUniqueIdentifier]>, - cadNodes: PromiseType>['items']['cad_nodes'] -): Map> { - return cadNodes.reduce((nodeMap, cadNode) => { - const props = cadNode.properties[CORE_DM_SPACE]['CogniteCADNode/v1']; - const modelRevisionPair = modelRevisions.find( - ([modelRef, _revisionRef]) => - props.model3D.externalId === modelRef.externalId && props.model3D.space === modelRef.space - ); - if (modelRevisionPair === undefined) { - return nodeMap; - } - - const revisionIndex = props.revisions.findIndex( - (propRevision) => - modelRevisionPair[1].externalId === propRevision.externalId && - modelRevisionPair[1].space === propRevision.space - ); - - if (revisionIndex === -1) { - return nodeMap; - } - - const modelId = getModelIdFromExternalId(props.model3D.externalId); - const revisionId = getRevisionIdFromExternalId(props.revisions[revisionIndex].externalId); - - nodeMap.set(toFdmKey(cadNode), { - modelId, - revisionId, - treeIndex: props.treeIndexes[revisionIndex] - }); - - return nodeMap; - }, new Map>()); -} - const cadConnectionsQuery = { with: { cad_nodes: { @@ -145,10 +178,18 @@ const cadConnectionsQuery = { } }, limit: 10000 + }, + assets: { + nodes: { + from: 'object_3ds', + through: { view: COGNITE_ASSET_SOURCE, identifier: 'object3D' }, + direction: 'inwards' + }, + limit: 10000 } }, select: { cad_nodes: { sources: cogniteCadNodeSourceWithProperties }, - object_3ds: { sources: cogniteObject3dSourceWithProperties } + assets: { sources: cogniteAssetSourceWithProperties } } } as const satisfies Omit; diff --git a/react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts b/react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts index bbc57c8a526..4aa32552777 100644 --- a/react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts +++ b/react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts @@ -10,6 +10,7 @@ export function getModelIdFromExternalId(externalId: string): ModelId { } export function getRevisionIdFromExternalId(externalId: string): RevisionId { - // The externalId should be on the form `cog_3d_revision_${modelId}` - return Number(externalId.slice('cog_3d_revision_'.length)); + // The externalId should be on the form `revision_${modelId}_${revisionId}` + const [_prefix, _modelId, revisionId] = externalId.split('_'); + return Number(revisionId); } diff --git a/react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts b/react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts index bc874ab1b05..fb09de51db9 100644 --- a/react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts +++ b/react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts @@ -23,7 +23,7 @@ export async function getEdgeConnected3dInstances( [{ source: typeof COGNITE_3D_OBJECT_SOURCE; properties: Cognite3DObjectProperties }] >(query); - return result.items.connected_objects_with_3d; + return result.items.objects_connected_with_3d; } const related3dEdgesQuery = { @@ -62,7 +62,13 @@ const related3dEdgesQuery = { from: 'start_to_object_edges', chainTo: 'destination', filter: { - exists: { property: ['CogniteVisualizable', 'object3D'] } + exists: { + property: [ + COGNITE_VISUALIZABLE_SOURCE.space, + COGNITE_VISUALIZABLE_SOURCE.externalId, + 'object3D' + ] + } } } }, @@ -77,7 +83,7 @@ const related3dEdgesQuery = { select: { start_instance: {}, start_to_object_edges: {}, - connected_objects_with_3d: {}, + objects_connected_with_3d: {}, object_3ds: {} } } as const satisfies Omit; diff --git a/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts b/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts index 7c9c45f6f41..157a4d3de79 100644 --- a/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts +++ b/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts @@ -91,7 +91,8 @@ function createRawQuery( cad_object_3d: { nodes: { from: 'cad_nodes', - through: { view: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' } + through: { view: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' }, + direction: 'outwards' } }, cad_assets: { @@ -111,7 +112,8 @@ function createRawQuery( pointcloud_object_3d: { nodes: { from: 'pointcloud_volumes', - through: { view: COGNITE_POINT_CLOUD_VOLUME_SOURCE, identifier: 'object3D' } + through: { view: COGNITE_POINT_CLOUD_VOLUME_SOURCE, identifier: 'object3D' }, + direction: 'outwards' } }, pointcloud_assets: { diff --git a/react-components/src/hooks/useClickedNode.tsx b/react-components/src/hooks/useClickedNode.tsx index 690ec1d2c60..64b63d2ee03 100644 --- a/react-components/src/hooks/useClickedNode.tsx +++ b/react-components/src/hooks/useClickedNode.tsx @@ -27,7 +27,7 @@ export type AssetMappingDataResult = { export type FdmNodeDataResult = { fdmNodes: DmsUniqueIdentifier[]; cadNode: Node3D; - views?: Source[]; + views?: Source[][]; }; export type ClickedNodeData = { diff --git a/react-components/src/query/useSearchMappedEquipmentAssetMappings.tsx b/react-components/src/query/useSearchMappedEquipmentAssetMappings.tsx index 53c4ad87efb..34244a5159a 100644 --- a/react-components/src/query/useSearchMappedEquipmentAssetMappings.tsx +++ b/react-components/src/query/useSearchMappedEquipmentAssetMappings.tsx @@ -54,8 +54,7 @@ export const useSearchMappedEquipmentAssetMappings = ( 'react-components', 'search-mapped-asset-mappings', query, - ...models.map((model) => [model.modelId, model.revisionId]), - initialAssetMappings.data?.pages.length ?? 0 + ...models.map((model) => [model.modelId, model.revisionId]) ], queryFn: async ({ pageParam }: { pageParam: string | undefined }) => { if (query === '' || assetMappingList === undefined) { diff --git a/react-components/src/query/useSearchMappedEquipmentFDM.tsx b/react-components/src/query/useSearchMappedEquipmentFDM.tsx index 5f9af8c5e93..33ec2b69767 100644 --- a/react-components/src/query/useSearchMappedEquipmentFDM.tsx +++ b/react-components/src/query/useSearchMappedEquipmentFDM.tsx @@ -43,7 +43,6 @@ export const useSearchMappedEquipmentFDM = ( if (models.length === 0) { return []; } - const sources = await createSourcesFromViews(viewsToSearch, fdmSdk); const chunkedSources = chunk(sources, 10); if (chunkedSources.length === 0) { @@ -53,19 +52,19 @@ export const useSearchMappedEquipmentFDM = ( const queryResults: InstancesWithView[] = []; for (const sourceChunk of chunkedSources) { - queryResults.push( - ...(await searchNodesWithViewsAndModels( - query, - spacesToSearch, - sourceChunk, - models, - instancesFilter, - fdmSdk, - fdmDataProvider, - limit - )) + const chunkResult = await searchNodesWithViewsAndModels( + query, + spacesToSearch, + sourceChunk, + models, + instancesFilter, + fdmSdk, + fdmDataProvider, + limit ); + queryResults.push(...chunkResult); } + return queryResults; }, staleTime: Infinity @@ -89,7 +88,6 @@ const searchNodesWithViewsAndModels = async ( instancesFilter, limit ); - const transformedResults = convertQueryNodeItemsToSearchResultsWithViews(nodeItems); const combinedWithOtherViews = sourcesToSearch.map((view) => ({ @@ -141,8 +139,8 @@ function convertQueryNodeItemsToSearchResultsWithViews( return queryItems.reduce((acc, fdmNode) => { const cleanedNode = removeEmptyProperties(fdmNode); - Object.keys(cleanedNode.properties).forEach((space) => { - const currentSpaceProperties = cleanedNode.properties[space]; + Object.keys(cleanedNode.properties).forEach((nodeViewSpace) => { + const currentSpaceProperties = cleanedNode.properties[nodeViewSpace]; const fdmNodeView = Object.keys(currentSpaceProperties) .find((key) => !isEqual(currentSpaceProperties[key], {})) @@ -158,13 +156,13 @@ function convertQueryNodeItemsToSearchResultsWithViews( const currentSearchResultWithView = acc.find( (searchResultsWithView) => searchResultsWithView.view.externalId === fdmNodeViewExternalId && - searchResultsWithView.view.space === space + searchResultsWithView.view.space === nodeViewSpace ); if (currentSearchResultWithView === undefined) { acc.push({ view: { - space: cleanedNode.space, + space: nodeViewSpace, externalId: fdmNodeViewExternalId, version: fdmNodeViewVersion, type: 'view' @@ -185,26 +183,31 @@ async function createSourcesFromViews( viewsToSearch: DmsUniqueIdentifier[], fdmSdk: FdmSDK ): Promise { - const dataModelResult = await fdmSdk.listDataModels(); - const viewToVersionMap = new Map( - dataModelResult.items.flatMap((dataModel: any) => { - return dataModel.views.map( - (view: Source) => [`${view.space}/${view.externalId}`, view.version] as const - ); - }) - ); + try { + const dataModelResult = await fdmSdk.listDataModels(); + const viewToVersionMap = new Map( + dataModelResult.items.flatMap((dataModel: { views: Source[] }) => { + return dataModel.views.map( + (view: Source) => [`${view.space}/${view.externalId}`, view.version] as const + ); + }) + ); - return viewsToSearch.map((view) => { - const version = viewToVersionMap.get(`${view.space}/${view.externalId}`); - if (version === undefined) { - throw Error( - `Could not find version for view with space/externalId ${view.space}/${view.externalId}` - ); - } - return { - ...view, - type: 'view' as const, - version - }; - }); + return viewsToSearch.map((view) => { + const version = viewToVersionMap.get(`${view.space}/${view.externalId}`); + if (version === undefined) { + throw Error( + `Could not find version for view with space/externalId ${view.space}/${view.externalId}` + ); + } + return { + ...view, + type: 'view' as const, + version + }; + }); + } catch (e) { + console.error('Error when fetching sources from views', e); + throw e; + } } From 4450164f52f0b8a6c0c41d799fc8ac5425ec6f05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Wed, 28 Aug 2024 14:21:01 +0200 Subject: [PATCH 18/32] chore: add missing files --- .../cogniteCadRevisionSourceWithProperties.ts | 12 ++++++++++++ .../core-dm-provider/restrictToDmsId.ts | 5 +++++ 2 files changed, 17 insertions(+) create mode 100644 react-components/src/data-providers/core-dm-provider/cogniteCadRevisionSourceWithProperties.ts create mode 100644 react-components/src/data-providers/core-dm-provider/restrictToDmsId.ts diff --git a/react-components/src/data-providers/core-dm-provider/cogniteCadRevisionSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteCadRevisionSourceWithProperties.ts new file mode 100644 index 00000000000..9b79d61c01b --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/cogniteCadRevisionSourceWithProperties.ts @@ -0,0 +1,12 @@ +/*! + * Copyright 2024 Cognite AS + */ +import { type SourceSelectorV3 } from '@cognite/sdk/dist/src'; +import { COGNITE_CAD_REVISION_SOURCE } from './dataModels'; + +export const cogniteCadNodeSourceWithPRoperties = [ + { + source: COGNITE_CAD_REVISION_SOURCE, + properties: ['status', 'published', 'type', 'model3D', 'revisionId'] + } +] as const satisfies SourceSelectorV3; diff --git a/react-components/src/data-providers/core-dm-provider/restrictToDmsId.ts b/react-components/src/data-providers/core-dm-provider/restrictToDmsId.ts new file mode 100644 index 00000000000..8615ef52c8c --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/restrictToDmsId.ts @@ -0,0 +1,5 @@ +import { DmsUniqueIdentifier } from '../FdmSDK'; + +export function restrictToDmsId(identifier: T): DmsUniqueIdentifier { + return { externalId: identifier.externalId, space: identifier.space }; +} From a678a603a213975fc15a7832c2dd8c945d7a4b52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Wed, 28 Aug 2024 18:22:07 +0200 Subject: [PATCH 19/32] chore: more polishing and fixing --- .../filterNodesByMappedTo3d.ts | 6 +-- .../getCadModelsForInstance.ts | 40 +++++++++++++------ .../src/query/useModelsForInstanceQuery.ts | 2 +- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts index 08d6d535063..25f54a060f8 100644 --- a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts +++ b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts @@ -228,7 +228,7 @@ function getRevisionsCadNodeFromObject3D(object3dTableName: string): QueryTableE return { nodes: { from: object3dTableName, - through: { view: COGNITE_3D_OBJECT_SOURCE, identifier: 'cadNodes' }, + through: { view: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' }, filter: { containsAny: { property: [CORE_DM_3D_CONTAINER_SPACE, COGNITE_CAD_NODE_SOURCE.externalId, 'revisions'], @@ -243,7 +243,7 @@ function getRevisionsPointCloudVolumes(object3dTableName: string): QueryTableExp return { nodes: { from: object3dTableName, - through: { view: COGNITE_3D_OBJECT_SOURCE, identifier: 'pointCloudVolumes' }, + through: { view: COGNITE_POINT_CLOUD_VOLUME_SOURCE, identifier: 'object3D' }, filter: { containsAny: { property: [ @@ -262,7 +262,7 @@ function getObject3dRelation(visualizableTableName: string): QueryTableExpressio return { nodes: { from: visualizableTableName, - through: { view: COGNITE_VISUALIZABLE_SOURCE, identifier: 'object3d' } + through: { view: COGNITE_VISUALIZABLE_SOURCE, identifier: 'object3D' } } }; } diff --git a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts index 460ed7eff7b..3d725f2581e 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts @@ -6,7 +6,7 @@ import { type TaggedAddResourceOptions } from '../../components/Reveal3DResource import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { COGNITE_3D_OBJECT_SOURCE, - type COGNITE_CAD_NODE_SOURCE, + COGNITE_CAD_NODE_SOURCE, COGNITE_VISUALIZABLE_SOURCE, type CogniteCADNodeProperties, CORE_DM_SPACE @@ -18,7 +18,7 @@ export async function getCadModelsForInstance( instance: DmsUniqueIdentifier, fdmSdk: FdmSDK ): Promise { - const parameters = { instanceIds: [instance] }; + const parameters = { instanceExternalId: instance.externalId, instanceSpace: instance.space }; const query = { ...cadModelsForInstanceQuery, @@ -44,24 +44,40 @@ export async function getCadModelsForInstance( const cadModelsForInstanceQuery = { with: { - object_3ds: { + asset: { nodes: { filter: { - containsAny: { - property: [ - COGNITE_VISUALIZABLE_SOURCE.space, - COGNITE_VISUALIZABLE_SOURCE.externalId, - 'object3D' - ], - values: { parameter: 'instanceId' } - } + and: [ + { + equals: { + property: ['node', 'externalId'], + value: { parameter: 'instanceExternalId' } + } + }, + { + equals: { + property: ['node', 'space'], + value: { parameter: 'instanceSpace' } + } + } + ] } } }, + object_3ds: { + nodes: { + from: 'asset', + through: { + view: COGNITE_VISUALIZABLE_SOURCE, + identifier: 'object3D' + }, + direction: 'outwards' + } + }, cad_nodes: { nodes: { from: 'object_3ds', - through: { view: COGNITE_3D_OBJECT_SOURCE, identifier: 'cadNodes' } + through: { view: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' } } } }, diff --git a/react-components/src/query/useModelsForInstanceQuery.ts b/react-components/src/query/useModelsForInstanceQuery.ts index 316606312ef..d1c5fb25de4 100644 --- a/react-components/src/query/useModelsForInstanceQuery.ts +++ b/react-components/src/query/useModelsForInstanceQuery.ts @@ -24,7 +24,7 @@ export const useModelsForInstanceQuery = ( const fdm3dDataProvider = useFdm3dDataProvider(); return useQuery({ - queryKey: ['reveal', 'react-components', instance], + queryKey: ['reveal', 'react-components', 'models-for-instance', instance], queryFn: async () => { if (instance === undefined) { return undefined; From 2ab39030f25e1de75baa9ffa48e85d76c40b4a43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 29 Aug 2024 11:18:40 +0200 Subject: [PATCH 20/32] fix: filterNodesByMappedTo3d --- .../filterNodesByMappedTo3d.ts | 109 ++++++++---------- 1 file changed, 46 insertions(+), 63 deletions(-) diff --git a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts index 25f54a060f8..e44a5a96a18 100644 --- a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts +++ b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts @@ -6,7 +6,7 @@ import { type QueryRequest, type QueryTableExpressionV3, type SourceSelectorV3 -} from '@cognite/sdk/dist/src'; +} from '@cognite/sdk'; import { getDirectRelationProperties } from '../utils/getDirectRelationProperties'; import { type Cognite3DObjectProperties, @@ -14,15 +14,14 @@ import { COGNITE_CAD_NODE_SOURCE, COGNITE_POINT_CLOUD_VOLUME_SOURCE, COGNITE_VISUALIZABLE_SOURCE, - CORE_DM_3D_CONTAINER_SPACE, - CORE_DM_SPACE + CORE_DM_3D_CONTAINER_SPACE } from './dataModels'; import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { cogniteObject3dSourceWithProperties } from './cogniteObject3dSourceWithProperties'; import { type FdmKey } from '../../components/CacheProvider/types'; import { toFdmKey } from '../utils/toFdmKey'; -import { type ArrayElement, type PromiseType } from '../utils/typeUtils'; -import { head } from 'lodash'; +import { type PromiseType } from '../utils/typeUtils'; +import { isString } from 'lodash'; import { type QueryResult } from '../utils/queryNodesAndEdges'; export async function filterNodesByMappedTo3d( @@ -33,67 +32,48 @@ export async function filterNodesByMappedTo3d( ): Promise { const connectionData = await fetchConnectionData(nodes, revisionRefs, fdmSdk); - const assetKeys: Set = createRelevantAssetKeySet(connectionData); + const object3dKeys: Set = createRelevantObject3dKeys(connectionData); - return nodes.map((viewWithNodes) => ({ - view: viewWithNodes.view, - instances: viewWithNodes.instances.filter((instance) => assetKeys.has(toFdmKey(instance))) - })); + const result = nodes.map((viewWithNodes) => { + if (viewWithNodes.view.externalId !== 'CogniteAsset') { + return { + view: viewWithNodes.view, + instances: [] + }; + } + return { + view: viewWithNodes.view, + instances: viewWithNodes.instances.filter((instance) => { + const object3dId = instance.properties.object3D as unknown as + | DmsUniqueIdentifier + | undefined; + if (!isString(object3dId?.externalId) || !isString(object3dId?.space)) { + return false; + } + return object3dKeys.has(toFdmKey(object3dId)); + }) + }; + }); + + return result; } -function createRelevantAssetKeySet( +function createRelevantObject3dKeys( connectionData: PromiseType> ): Set { - const cadNodeSet = new Set( - new Array() - .concat(connectionData.items.initial_nodes_cad_nodes) - .concat(connectionData.items.direct_nodes_cad_nodes) - .concat(connectionData.items.indirect_nodes_cad_nodes) - .map(toFdmKey) - ); - - const pointCloudNodeSet = new Set( - new Array() - .concat(connectionData.items.initial_nodes_point_cloud_volumes) - .concat(connectionData.items.direct_nodes_point_cloud_volumes) - .concat(connectionData.items.indirect_nodes_point_cloud_volumes) - .map(toFdmKey) - ); - - const relevantObject3Ds = new Array< - ArrayElement - >() - .concat(connectionData.items.initial_nodes_object_3ds) - .concat(connectionData.items.direct_nodes_object_3ds) - .concat(connectionData.items.indirect_nodes_object_3ds) - .filter((object3d) => { - const props = object3d.properties[CORE_DM_SPACE]['Cognite3DObject/v1']; - return ( - props.cadNodes?.some((node) => cadNodeSet.has(toFdmKey(node))) || - props.pointCloudVolumes?.some((node) => pointCloudNodeSet.has(toFdmKey(node))) - ); - }); - - const relevantAssetKeySet = relevantObject3Ds.reduce((acc, object3D) => { - // Assume at most one connected asset - const firstAsset = head(object3D.properties[CORE_DM_SPACE]['Cognite3DObject/v1'].asset); - if (firstAsset === undefined) { - return acc; - } - acc.add(toFdmKey(firstAsset)); - return acc; - }, new Set()); - - // Append relevant edge start nodes directly to previous set - connectionData.items.indirectly_referenced_edges.reduce((acc, edge) => { - if (relevantAssetKeySet.has(toFdmKey(edge.endNode))) { - acc.add(toFdmKey(edge.startNode)); - } - - return acc; - }, relevantAssetKeySet); - - return relevantAssetKeySet; + const cadObject3dList = [...connectionData.items.initial_nodes_cad_nodes] + .concat(connectionData.items.direct_nodes_cad_nodes) + .concat(connectionData.items.indirect_nodes_cad_nodes) + .map((node) => toFdmKey(node.properties.cdf_cdm['CogniteCADNode/v1'].object3D)); + + const pointCloudObject3dList = [...connectionData.items.initial_nodes_point_cloud_volumes] + .concat(connectionData.items.direct_nodes_point_cloud_volumes) + .concat(connectionData.items.indirect_nodes_point_cloud_volumes) + .map((pointCloudVolume) => + toFdmKey(pointCloudVolume.properties.cdf_cdm['CognitePointCloudVolume/v1'].object3D) + ); + + return new Set([...cadObject3dList, ...pointCloudObject3dList]); } type SelectSourcesType = [ @@ -115,7 +95,9 @@ async function fetchConnectionData( ); const directlyMappedIds = nodes.flatMap((node) => - node.instances.map(getDirectRelationProperties) + node.instances.flatMap((instance) => + getDirectRelationProperties(instance).map((props) => props.externalId) + ) ); const parameters = { initialExternalIds, directlyMappedIds, revisionRefs }; @@ -262,7 +244,8 @@ function getObject3dRelation(visualizableTableName: string): QueryTableExpressio return { nodes: { from: visualizableTableName, - through: { view: COGNITE_VISUALIZABLE_SOURCE, identifier: 'object3D' } + through: { view: COGNITE_VISUALIZABLE_SOURCE, identifier: 'object3D' }, + direction: 'outwards' } }; } From 1de40d7de7890eb208af83236c5f4ba7903fbae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 29 Aug 2024 11:25:47 +0200 Subject: [PATCH 21/32] chore: lint fix --- .../src/data-providers/core-dm-provider/dataModels.ts | 4 ++-- .../core-dm-provider/filterNodesByMappedTo3d.ts | 2 +- .../core-dm-provider/getCadConnectionsForRevisions.ts | 5 ++--- .../core-dm-provider/getCadModelsForInstance.ts | 1 - .../core-dm-provider/getFdmConnectionsForNodeIds.ts | 4 ++-- .../src/data-providers/core-dm-provider/restrictToDmsId.ts | 5 ++++- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/react-components/src/data-providers/core-dm-provider/dataModels.ts b/react-components/src/data-providers/core-dm-provider/dataModels.ts index b7d61d0cce0..bbc4241c9af 100644 --- a/react-components/src/data-providers/core-dm-provider/dataModels.ts +++ b/react-components/src/data-providers/core-dm-provider/dataModels.ts @@ -4,8 +4,8 @@ import { type Timestamp, type ViewReference } from '@cognite/sdk'; import { type DmsUniqueIdentifier } from '../FdmSDK'; -export const CORE_DM_SPACE = 'cdf_cdm' as const; -export const CORE_DM_3D_CONTAINER_SPACE = 'cdf_cdm_3d' as const; +export const CORE_DM_SPACE = 'cdf_cdm'; +export const CORE_DM_3D_CONTAINER_SPACE = 'cdf_cdm_3d'; export const COGNITE_3D_OBJECT_SOURCE = { externalId: 'Cognite3DObject', diff --git a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts index e44a5a96a18..83a54c540d2 100644 --- a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts +++ b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts @@ -10,7 +10,7 @@ import { import { getDirectRelationProperties } from '../utils/getDirectRelationProperties'; import { type Cognite3DObjectProperties, - COGNITE_3D_OBJECT_SOURCE, + type COGNITE_3D_OBJECT_SOURCE, COGNITE_CAD_NODE_SOURCE, COGNITE_POINT_CLOUD_VOLUME_SOURCE, COGNITE_VISUALIZABLE_SOURCE, diff --git a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts index b9bd9752194..43103578ff6 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts @@ -3,17 +3,16 @@ */ import { type QueryRequest } from '@cognite/sdk/dist/src'; import { type FdmCadConnection, type FdmKey } from '../../components/CacheProvider/types'; -import { FdmNode, NodeItem, type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; +import { type NodeItem, type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { COGNITE_3D_OBJECT_SOURCE, COGNITE_ASSET_SOURCE, COGNITE_CAD_NODE_SOURCE, - CogniteAssetProperties, + type CogniteAssetProperties, type CogniteCADNodeProperties, CORE_DM_3D_CONTAINER_SPACE, CORE_DM_SPACE } from './dataModels'; -import { cogniteObject3dSourceWithProperties } from './cogniteObject3dSourceWithProperties'; import { cogniteCadNodeSourceWithProperties } from './cogniteCadNodeSourceWithProperties'; import { getModelIdFromExternalId, getRevisionIdFromExternalId } from './getCdfIdFromExternalId'; import { toFdmKey } from '../utils/toFdmKey'; diff --git a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts index 3d725f2581e..420fb8c90fc 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts @@ -5,7 +5,6 @@ import { type QueryRequest } from '@cognite/sdk/dist/src'; import { type TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { - COGNITE_3D_OBJECT_SOURCE, COGNITE_CAD_NODE_SOURCE, COGNITE_VISUALIZABLE_SOURCE, type CogniteCADNodeProperties, diff --git a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts index 696dfd22508..c59fb0be761 100644 --- a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts +++ b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts @@ -6,13 +6,13 @@ import { type FdmCadConnection, type FdmKey } from '../../components/CacheProvid import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { type Cognite3DObjectProperties, - COGNITE_3D_OBJECT_SOURCE, + type COGNITE_3D_OBJECT_SOURCE, COGNITE_ASSET_SOURCE, COGNITE_CAD_NODE_SOURCE, COGNITE_VISUALIZABLE_SOURCE, type CogniteAssetProperties, type CogniteCADNodeProperties, - CogniteVisualizableProperties, + type CogniteVisualizableProperties, CORE_DM_3D_CONTAINER_SPACE, CORE_DM_SPACE } from './dataModels'; diff --git a/react-components/src/data-providers/core-dm-provider/restrictToDmsId.ts b/react-components/src/data-providers/core-dm-provider/restrictToDmsId.ts index 8615ef52c8c..3e0cb5d4ccc 100644 --- a/react-components/src/data-providers/core-dm-provider/restrictToDmsId.ts +++ b/react-components/src/data-providers/core-dm-provider/restrictToDmsId.ts @@ -1,4 +1,7 @@ -import { DmsUniqueIdentifier } from '../FdmSDK'; +/*! + * Copyright 2024 Cognite AS + */ +import { type DmsUniqueIdentifier } from '../FdmSDK'; export function restrictToDmsId(identifier: T): DmsUniqueIdentifier { return { externalId: identifier.externalId, space: identifier.space }; From 691ef0123beb241deccf473eb09bf9cb725f0059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 29 Aug 2024 11:43:01 +0200 Subject: [PATCH 22/32] chore: reuse createFdmKey --- .../src/components/CacheProvider/FdmNodeCache.ts | 13 ++++--------- .../core-dm-provider/filterNodesByMappedTo3d.ts | 8 ++++---- .../getCadConnectionsForRevisions.ts | 10 +++++----- .../core-dm-provider/getFdmConnectionsForNodeIds.ts | 8 ++++---- .../src/data-providers/utils/toFdmKey.ts | 9 --------- .../idAndKeyTranslation.ts | 8 ++++---- 6 files changed, 21 insertions(+), 35 deletions(-) delete mode 100644 react-components/src/data-providers/utils/toFdmKey.ts rename react-components/src/{components/CacheProvider => utilities}/idAndKeyTranslation.ts (76%) diff --git a/react-components/src/components/CacheProvider/FdmNodeCache.ts b/react-components/src/components/CacheProvider/FdmNodeCache.ts index 45dcc03955e..569c9e78369 100644 --- a/react-components/src/components/CacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/FdmNodeCache.ts @@ -23,7 +23,7 @@ import { createModelTreeIndexKey, createModelRevisionKey, revisionKeyToIds -} from './idAndKeyTranslation'; +} from '../../utilities/idAndKeyTranslation'; import { partition } from 'lodash'; @@ -78,9 +78,7 @@ export class FdmNodeCache { modelRevisionIds: ModelRevisionId[], externalIds: DmsUniqueIdentifier[] ): ThreeDModelFdmMappings[] { - const inputExternalIdSet = new Set( - externalIds.map((id) => createFdmKey(id.space, id.externalId)) - ); + const inputExternalIdSet = new Set(externalIds.map(createFdmKey)); return modelRevisionIds.map((modelRevisionId) => { return this.getCachedModelMappingForRevision(modelRevisionId, inputExternalIdSet); @@ -122,7 +120,7 @@ export class FdmNodeCache { return []; } - const fdmKeySet = new Set(instances.map((id) => createFdmKey(id.space, id.externalId))); + const fdmKeySet = new Set(instances.map(createFdmKey)); const revisionToConnectionsMap = await this.getAndCacheRevisionToConnectionsMap( modelRevisions, @@ -424,10 +422,7 @@ function intersectWithFdmKeySet( relevantFdmKeySet: Set ): FdmConnectionWithNode[] { return connections.filter((connectionData) => { - const fdmKey = createFdmKey( - connectionData.connection.instance.space, - connectionData.connection.instance.externalId - ); + const fdmKey = createFdmKey(connectionData.connection.instance); return relevantFdmKeySet.has(fdmKey); }); } diff --git a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts index 83a54c540d2..832028301ac 100644 --- a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts +++ b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts @@ -19,7 +19,7 @@ import { import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { cogniteObject3dSourceWithProperties } from './cogniteObject3dSourceWithProperties'; import { type FdmKey } from '../../components/CacheProvider/types'; -import { toFdmKey } from '../utils/toFdmKey'; +import { createFdmKey } from '../../utilities/idAndKeyTranslation'; import { type PromiseType } from '../utils/typeUtils'; import { isString } from 'lodash'; import { type QueryResult } from '../utils/queryNodesAndEdges'; @@ -50,7 +50,7 @@ export async function filterNodesByMappedTo3d( if (!isString(object3dId?.externalId) || !isString(object3dId?.space)) { return false; } - return object3dKeys.has(toFdmKey(object3dId)); + return object3dKeys.has(createFdmKey(object3dId)); }) }; }); @@ -64,13 +64,13 @@ function createRelevantObject3dKeys( const cadObject3dList = [...connectionData.items.initial_nodes_cad_nodes] .concat(connectionData.items.direct_nodes_cad_nodes) .concat(connectionData.items.indirect_nodes_cad_nodes) - .map((node) => toFdmKey(node.properties.cdf_cdm['CogniteCADNode/v1'].object3D)); + .map((node) => createFdmKey(node.properties.cdf_cdm['CogniteCADNode/v1'].object3D)); const pointCloudObject3dList = [...connectionData.items.initial_nodes_point_cloud_volumes] .concat(connectionData.items.direct_nodes_point_cloud_volumes) .concat(connectionData.items.indirect_nodes_point_cloud_volumes) .map((pointCloudVolume) => - toFdmKey(pointCloudVolume.properties.cdf_cdm['CognitePointCloudVolume/v1'].object3D) + createFdmKey(pointCloudVolume.properties.cdf_cdm['CognitePointCloudVolume/v1'].object3D) ); return new Set([...cadObject3dList, ...pointCloudObject3dList]); diff --git a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts index 43103578ff6..02269c44c6d 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts @@ -15,7 +15,7 @@ import { } from './dataModels'; import { cogniteCadNodeSourceWithProperties } from './cogniteCadNodeSourceWithProperties'; import { getModelIdFromExternalId, getRevisionIdFromExternalId } from './getCdfIdFromExternalId'; -import { toFdmKey } from '../utils/toFdmKey'; +import { createFdmKey } from '../../utilities/idAndKeyTranslation'; import { type PromiseType } from '../utils/typeUtils'; import { isDefined } from '../../utilities/isDefined'; import { type QueryResult } from '../utils/queryNodesAndEdges'; @@ -33,7 +33,7 @@ export async function getCadConnectionsForRevisions( const returnResult = results.items.cad_nodes .map((cadNode) => { const props = cadNode.properties[CORE_DM_SPACE]['CogniteCADNode/v1']; - const object3dKey = cadNodeToModelMap.get(toFdmKey(cadNode)); + const object3dKey = cadNodeToModelMap.get(createFdmKey(cadNode)); if (object3dKey === undefined) { return undefined; @@ -66,7 +66,7 @@ function createObject3dToAssetMap>( ): Map { return new Map( assets.map((asset) => [ - toFdmKey(asset.properties[CORE_DM_SPACE]?.['CogniteAsset/v1'].object3D), + createFdmKey(asset.properties[CORE_DM_SPACE]?.['CogniteAsset/v1'].object3D), asset ]) ); @@ -77,8 +77,8 @@ function createCadNodeToObject3dMap( ): Map { return new Map( cadNodes.map((cadNode) => [ - toFdmKey(cadNode), - toFdmKey(cadNode.properties.cdf_cdm['CogniteCADNode/v1'].object3D) + createFdmKey(cadNode), + createFdmKey(cadNode.properties.cdf_cdm['CogniteCADNode/v1'].object3D) ]) ); } diff --git a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts index c59fb0be761..63e239799d1 100644 --- a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts +++ b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts @@ -17,7 +17,7 @@ import { CORE_DM_SPACE } from './dataModels'; import { getModelIdFromExternalId } from './getCdfIdFromExternalId'; -import { toFdmKey } from '../utils/toFdmKey'; +import { createFdmKey } from '../../utilities/idAndKeyTranslation'; import { cogniteCadNodeSourceWithProperties } from './cogniteCadNodeSourceWithProperties'; import { restrictToDmsId } from './restrictToDmsId'; @@ -63,14 +63,14 @@ export async function getFdmConnectionsForNodes( const relevant = treeIndexSet.has(treeIndex); if (relevant) { - relevantCadNodeRefToObject3dRef.set(toFdmKey(cadNode), toFdmKey(props.object3D)); - treeIndexToCadNodeMap.set(treeIndex, toFdmKey(cadNode)); + relevantCadNodeRefToObject3dRef.set(createFdmKey(cadNode), createFdmKey(props.object3D)); + treeIndexToCadNodeMap.set(treeIndex, createFdmKey(cadNode)); } }); const relevantObjectToAssetsMap = new Map( result.items.assets.map((asset) => [ - toFdmKey(asset.properties.cdf_cdm['CogniteVisualizable/v1'].object3D), + createFdmKey(asset.properties.cdf_cdm['CogniteVisualizable/v1'].object3D), asset ]) ); diff --git a/react-components/src/data-providers/utils/toFdmKey.ts b/react-components/src/data-providers/utils/toFdmKey.ts deleted file mode 100644 index 5593449d90f..00000000000 --- a/react-components/src/data-providers/utils/toFdmKey.ts +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Copyright 2024 Cognite AS - */ -import { type FdmKey } from '../../components/CacheProvider/types'; -import { type DmsUniqueIdentifier } from '../FdmSDK'; - -export function toFdmKey(dmsId: DmsUniqueIdentifier): FdmKey { - return `${dmsId.space}/${dmsId.externalId}`; -} diff --git a/react-components/src/components/CacheProvider/idAndKeyTranslation.ts b/react-components/src/utilities/idAndKeyTranslation.ts similarity index 76% rename from react-components/src/components/CacheProvider/idAndKeyTranslation.ts rename to react-components/src/utilities/idAndKeyTranslation.ts index 0a56049c768..0076d1d420c 100644 --- a/react-components/src/components/CacheProvider/idAndKeyTranslation.ts +++ b/react-components/src/utilities/idAndKeyTranslation.ts @@ -2,7 +2,7 @@ * Copyright 2023 Cognite AS */ -import { type ExternalId, type Space } from '../../data-providers/FdmSDK'; +import { type DmsUniqueIdentifier } from '../data-providers/FdmSDK'; import { type FdmKey, type ModelTreeIndexKey, @@ -10,7 +10,7 @@ import { type TreeIndex, type RevisionId, type ModelId -} from './types'; +} from '../components/CacheProvider/types'; import { split } from 'lodash'; @@ -31,6 +31,6 @@ export function createModelTreeIndexKey( return `${modelId}/${revisionId}/${treeIndex}`; } -export function createFdmKey(spaceId: Space, externalId: ExternalId): FdmKey { - return `${spaceId}/${externalId}`; +export function createFdmKey(id: DmsUniqueIdentifier): FdmKey { + return `${id.space}/${id.externalId}`; } From 10d4f075969b89b0d8a9df038245ebd15e593052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 29 Aug 2024 12:34:48 +0200 Subject: [PATCH 23/32] chore: move utils file back --- react-components/src/components/CacheProvider/FdmNodeCache.ts | 2 +- .../CacheProvider}/idAndKeyTranslation.ts | 4 ++-- .../core-dm-provider/filterNodesByMappedTo3d.ts | 2 +- .../core-dm-provider/getCadConnectionsForRevisions.ts | 2 +- .../core-dm-provider/getFdmConnectionsForNodeIds.ts | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) rename react-components/src/{utilities => components/CacheProvider}/idAndKeyTranslation.ts (87%) diff --git a/react-components/src/components/CacheProvider/FdmNodeCache.ts b/react-components/src/components/CacheProvider/FdmNodeCache.ts index 569c9e78369..03c56b496f2 100644 --- a/react-components/src/components/CacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/FdmNodeCache.ts @@ -23,7 +23,7 @@ import { createModelTreeIndexKey, createModelRevisionKey, revisionKeyToIds -} from '../../utilities/idAndKeyTranslation'; +} from './idAndKeyTranslation'; import { partition } from 'lodash'; diff --git a/react-components/src/utilities/idAndKeyTranslation.ts b/react-components/src/components/CacheProvider/idAndKeyTranslation.ts similarity index 87% rename from react-components/src/utilities/idAndKeyTranslation.ts rename to react-components/src/components/CacheProvider/idAndKeyTranslation.ts index 0076d1d420c..6df9932fe51 100644 --- a/react-components/src/utilities/idAndKeyTranslation.ts +++ b/react-components/src/components/CacheProvider/idAndKeyTranslation.ts @@ -2,7 +2,7 @@ * Copyright 2023 Cognite AS */ -import { type DmsUniqueIdentifier } from '../data-providers/FdmSDK'; +import { type DmsUniqueIdentifier } from '../../data-providers/FdmSDK'; import { type FdmKey, type ModelTreeIndexKey, @@ -10,7 +10,7 @@ import { type TreeIndex, type RevisionId, type ModelId -} from '../components/CacheProvider/types'; +} from './types'; import { split } from 'lodash'; diff --git a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts index 832028301ac..e6f8fce93f4 100644 --- a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts +++ b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts @@ -19,7 +19,7 @@ import { import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { cogniteObject3dSourceWithProperties } from './cogniteObject3dSourceWithProperties'; import { type FdmKey } from '../../components/CacheProvider/types'; -import { createFdmKey } from '../../utilities/idAndKeyTranslation'; +import { createFdmKey } from '../../components/CacheProvider/idAndKeyTranslation'; import { type PromiseType } from '../utils/typeUtils'; import { isString } from 'lodash'; import { type QueryResult } from '../utils/queryNodesAndEdges'; diff --git a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts index 02269c44c6d..8a928f9b9f9 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts @@ -15,7 +15,7 @@ import { } from './dataModels'; import { cogniteCadNodeSourceWithProperties } from './cogniteCadNodeSourceWithProperties'; import { getModelIdFromExternalId, getRevisionIdFromExternalId } from './getCdfIdFromExternalId'; -import { createFdmKey } from '../../utilities/idAndKeyTranslation'; +import { createFdmKey } from '../../components/CacheProvider/idAndKeyTranslation'; import { type PromiseType } from '../utils/typeUtils'; import { isDefined } from '../../utilities/isDefined'; import { type QueryResult } from '../utils/queryNodesAndEdges'; diff --git a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts index 63e239799d1..d1e3c324482 100644 --- a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts +++ b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts @@ -17,7 +17,7 @@ import { CORE_DM_SPACE } from './dataModels'; import { getModelIdFromExternalId } from './getCdfIdFromExternalId'; -import { createFdmKey } from '../../utilities/idAndKeyTranslation'; +import { createFdmKey } from '../../components/CacheProvider/idAndKeyTranslation'; import { cogniteCadNodeSourceWithProperties } from './cogniteCadNodeSourceWithProperties'; import { restrictToDmsId } from './restrictToDmsId'; From 82d95fd0c264c5313fc485c40202627ed7f9071d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 29 Aug 2024 12:36:35 +0200 Subject: [PATCH 24/32] chore: revert unnecessary change --- .../stories/utilities/getAddModelOptionsFromUrl.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/react-components/stories/utilities/getAddModelOptionsFromUrl.ts b/react-components/stories/utilities/getAddModelOptionsFromUrl.ts index a2ec110e27c..9c1b4d7686f 100644 --- a/react-components/stories/utilities/getAddModelOptionsFromUrl.ts +++ b/react-components/stories/utilities/getAddModelOptionsFromUrl.ts @@ -16,8 +16,8 @@ export function getAddModelOptionsFromUrl(localModelUrlFallback: string): AddMod } return { - modelId: 3544114490298106, - revisionId: 6405404576933316, + modelId: -1, + revisionId: -1, localPath: modelUrl ?? localModelUrlFallback }; } From 353e5a60fd500a7d351f853dce1da4459dc05377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Mon, 2 Sep 2024 09:48:16 +0200 Subject: [PATCH 25/32] chore: retrigger CI From cc9b22c5794f8d9011676d3caf2a6f486547a8a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Mon, 2 Sep 2024 14:24:12 +0200 Subject: [PATCH 26/32] chore: update format of revision external ID --- .../core-dm-provider/getCdfIdFromExternalId.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts b/react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts index 4aa32552777..999a1e34a8c 100644 --- a/react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts +++ b/react-components/src/data-providers/core-dm-provider/getCdfIdFromExternalId.ts @@ -10,7 +10,6 @@ export function getModelIdFromExternalId(externalId: string): ModelId { } export function getRevisionIdFromExternalId(externalId: string): RevisionId { - // The externalId should be on the form `revision_${modelId}_${revisionId}` - const [_prefix, _modelId, revisionId] = externalId.split('_'); - return Number(revisionId); + // The externalId should be on the form `cog_3d_revision_${revisionId}` + return Number(externalId.slice('cog_3d_revision_'.length)); } From 7d6105c04a17bf57fe94a35252b236449449d824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Tue, 3 Sep 2024 09:01:05 +0200 Subject: [PATCH 27/32] chore: apply changes to file a-posterioris --- .../useAll3dDirectConnectionsWithProperties.ts | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/react-components/src/query/useAll3dDirectConnectionsWithProperties.ts b/react-components/src/query/useAll3dDirectConnectionsWithProperties.ts index 9d73befa29d..bc06ff88d5d 100644 --- a/react-components/src/query/useAll3dDirectConnectionsWithProperties.ts +++ b/react-components/src/query/useAll3dDirectConnectionsWithProperties.ts @@ -21,10 +21,7 @@ export function useAll3dDirectConnectionsWithProperties( const connectionKeys = useMemo(() => { return connectionWithNodeAndView.map((item) => { - const fdmKey = createFdmKey( - item.connection.instance.space, - item.connection.instance.externalId - ); + const fdmKey = createFdmKey(item.connection.instance); return fdmKey; }); }, [connectionWithNodeAndView]); @@ -32,10 +29,7 @@ export function useAll3dDirectConnectionsWithProperties( const connectionWithNodeAndViewMap = useMemo(() => { return new Map( connectionWithNodeAndView.map((item) => { - const fdmKey = createFdmKey( - item.connection.instance.space, - item.connection.instance.externalId - ); + const fdmKey = createFdmKey(item.connection.instance); return [fdmKey, item]; }) ); @@ -57,15 +51,15 @@ export function useAll3dDirectConnectionsWithProperties( }; }); - const instancesViews = connectionWithNodeAndView.map((item) => { - return item.view; + const instancesViews = connectionWithNodeAndView.flatMap((item) => { + return item.views; }); const uniqueViews = uniqBy(instancesViews, (item) => { if (item === undefined) { return ''; } - const fdmKey = createFdmKey(item?.space, item?.externalId); + const fdmKey = createFdmKey(item); return fdmKey; }); @@ -125,7 +119,7 @@ export function useAll3dDirectConnectionsWithProperties( let connectionFound: FdmConnectionWithNode | undefined; itemsData.items.every((itemData) => { - const fdmKey = createFdmKey(itemData.space, itemData.externalId); + const fdmKey = createFdmKey(itemData); if (connectionWithNodeAndViewMap.has(fdmKey)) { connectionFound = connectionWithNodeAndViewMap.get(fdmKey); return false; From 593b33cdca65d86e1d1edea3abfce6774c584124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Tue, 3 Sep 2024 09:58:16 +0200 Subject: [PATCH 28/32] chore: create useful warning --- .../src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts b/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts index dee1c2c756a..c5758b6fd16 100644 --- a/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts +++ b/react-components/src/data-providers/core-dm-provider/CoreDm3dDataProvider.ts @@ -122,7 +122,7 @@ export class CoreDm3dFdm3dDataProvider implements Fdm3dDataProvider { nodes: Node3D[] ): Promise { if (models.length !== 1) { - throw new Error(`Expected 1 model, got ${models.length}`); + console.warn(`Expected 1 CoreDM 3D model, got ${models.length}:`, ...models); } const model = models[0]; From fe08beed17300049a7e245488f8dc6dbb757eae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Tue, 3 Sep 2024 09:59:04 +0200 Subject: [PATCH 29/32] chore: correct SDK path, factor out constants --- .../src/components/CacheProvider/requests.ts | 2 +- .../cogniteAssetSourceWithProperties.ts | 2 +- .../cogniteCadNodeSourceWithProperties.ts | 2 +- .../cogniteCadRevisionSourceWithProperties.ts | 2 +- .../cogniteObject3dSourceWithProperties.ts | 2 +- .../data-providers/core-dm-provider/dataModels.ts | 5 +++++ .../core-dm-provider/filterNodesByMappedTo3d.ts | 14 +++++++++++--- .../getCadConnectionsForRevisions.ts | 10 ++++++---- .../core-dm-provider/getCadModelsForInstance.ts | 5 +++-- .../core-dm-provider/getDMSModels.ts | 2 +- .../core-dm-provider/getDMSRevision.ts | 2 +- .../getEdgeConnected3dInstances.ts | 2 +- .../getFdmConnectionsForNodeIds.ts | 6 ++++-- react-components/src/data-providers/types.ts | 2 +- react-components/src/utilities/queryKeys.ts | 2 +- 15 files changed, 39 insertions(+), 21 deletions(-) diff --git a/react-components/src/components/CacheProvider/requests.ts b/react-components/src/components/CacheProvider/requests.ts index 2f27440ffd0..6303885e0bc 100644 --- a/react-components/src/components/CacheProvider/requests.ts +++ b/react-components/src/components/CacheProvider/requests.ts @@ -90,7 +90,7 @@ export async function nodeIdsToTreeIndices( revisionId: RevisionId, nodeIds: NodeId[], cogniteClient: CogniteClient -): Promise { +): Promise { const outputsUrl = `${cogniteClient.getBaseUrl()}/api/v1/projects/${ cogniteClient.project }/3d/models/${modelId}/revisions/${revisionId}/nodes/treeindices/byinternalids`; diff --git a/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts index 659ca9b722e..0c059bc4010 100644 --- a/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts +++ b/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts @@ -1,7 +1,7 @@ /*! * Copyright 2024 Cognite AS */ -import { type SourceSelectorV3 } from '@cognite/sdk/dist/src'; +import { type SourceSelectorV3 } from '@cognite/sdk'; import { COGNITE_ASSET_SOURCE } from './dataModels'; export const cogniteAssetSourceWithProperties = [ diff --git a/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts index cd25532bdb3..d10d49cf29a 100644 --- a/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts +++ b/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts @@ -1,7 +1,7 @@ /*! * Copyright 2024 Cognite AS */ -import { type SourceSelectorV3 } from '@cognite/sdk/dist/src'; +import { type SourceSelectorV3 } from '@cognite/sdk'; import { COGNITE_CAD_NODE_SOURCE } from './dataModels'; export const cogniteCadNodeSourceWithProperties = [ diff --git a/react-components/src/data-providers/core-dm-provider/cogniteCadRevisionSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteCadRevisionSourceWithProperties.ts index 9b79d61c01b..034445d6711 100644 --- a/react-components/src/data-providers/core-dm-provider/cogniteCadRevisionSourceWithProperties.ts +++ b/react-components/src/data-providers/core-dm-provider/cogniteCadRevisionSourceWithProperties.ts @@ -1,7 +1,7 @@ /*! * Copyright 2024 Cognite AS */ -import { type SourceSelectorV3 } from '@cognite/sdk/dist/src'; +import { type SourceSelectorV3 } from '@cognite/sdk'; import { COGNITE_CAD_REVISION_SOURCE } from './dataModels'; export const cogniteCadNodeSourceWithPRoperties = [ diff --git a/react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts index 64caf0f441f..5a34fdb3290 100644 --- a/react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts +++ b/react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts @@ -1,7 +1,7 @@ /*! * Copyright 2024 Cognite AS */ -import { type SourceSelectorV3 } from '@cognite/sdk/dist/src'; +import { type SourceSelectorV3 } from '@cognite/sdk'; import { COGNITE_3D_OBJECT_SOURCE } from './dataModels'; export const cogniteObject3dSourceWithProperties = [ diff --git a/react-components/src/data-providers/core-dm-provider/dataModels.ts b/react-components/src/data-providers/core-dm-provider/dataModels.ts index bbc4241c9af..f71f0f9f27f 100644 --- a/react-components/src/data-providers/core-dm-provider/dataModels.ts +++ b/react-components/src/data-providers/core-dm-provider/dataModels.ts @@ -7,6 +7,11 @@ import { type DmsUniqueIdentifier } from '../FdmSDK'; export const CORE_DM_SPACE = 'cdf_cdm'; export const CORE_DM_3D_CONTAINER_SPACE = 'cdf_cdm_3d'; +export const COGNITE_VISUALIZABLE_VIEW_VERSION_KEY = 'CogniteVisualizable/v1'; +export const COGNITE_ASSET_VIEW_VERSION_KEY = 'CogniteAsset/v1'; +export const COGNITE_CAD_NODE_VIEW_VERSION_KEY = 'CogniteCADNode/v1'; +export const COGNITE_POINT_CLOUD_VOLUME_VIEW_VERSION_KEY = 'CognitePointCloudVolume/v1'; + export const COGNITE_3D_OBJECT_SOURCE = { externalId: 'Cognite3DObject', space: CORE_DM_SPACE, diff --git a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts index e6f8fce93f4..7ac96185c24 100644 --- a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts +++ b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts @@ -12,9 +12,12 @@ import { type Cognite3DObjectProperties, type COGNITE_3D_OBJECT_SOURCE, COGNITE_CAD_NODE_SOURCE, + COGNITE_CAD_NODE_VIEW_VERSION_KEY, COGNITE_POINT_CLOUD_VOLUME_SOURCE, + COGNITE_POINT_CLOUD_VOLUME_VIEW_VERSION_KEY, COGNITE_VISUALIZABLE_SOURCE, - CORE_DM_3D_CONTAINER_SPACE + CORE_DM_3D_CONTAINER_SPACE, + CORE_DM_SPACE } from './dataModels'; import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { cogniteObject3dSourceWithProperties } from './cogniteObject3dSourceWithProperties'; @@ -64,13 +67,18 @@ function createRelevantObject3dKeys( const cadObject3dList = [...connectionData.items.initial_nodes_cad_nodes] .concat(connectionData.items.direct_nodes_cad_nodes) .concat(connectionData.items.indirect_nodes_cad_nodes) - .map((node) => createFdmKey(node.properties.cdf_cdm['CogniteCADNode/v1'].object3D)); + .map((node) => + createFdmKey(node.properties[CORE_DM_SPACE][COGNITE_CAD_NODE_VIEW_VERSION_KEY].object3D) + ); const pointCloudObject3dList = [...connectionData.items.initial_nodes_point_cloud_volumes] .concat(connectionData.items.direct_nodes_point_cloud_volumes) .concat(connectionData.items.indirect_nodes_point_cloud_volumes) .map((pointCloudVolume) => - createFdmKey(pointCloudVolume.properties.cdf_cdm['CognitePointCloudVolume/v1'].object3D) + createFdmKey( + pointCloudVolume.properties[CORE_DM_SPACE][COGNITE_POINT_CLOUD_VOLUME_VIEW_VERSION_KEY] + .object3D + ) ); return new Set([...cadObject3dList, ...pointCloudObject3dList]); diff --git a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts index 8a928f9b9f9..95387734ca7 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts @@ -1,13 +1,15 @@ /*! * Copyright 2024 Cognite AS */ -import { type QueryRequest } from '@cognite/sdk/dist/src'; +import { type QueryRequest } from '@cognite/sdk'; import { type FdmCadConnection, type FdmKey } from '../../components/CacheProvider/types'; import { type NodeItem, type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { COGNITE_3D_OBJECT_SOURCE, COGNITE_ASSET_SOURCE, + COGNITE_ASSET_VIEW_VERSION_KEY, COGNITE_CAD_NODE_SOURCE, + COGNITE_CAD_NODE_VIEW_VERSION_KEY, type CogniteAssetProperties, type CogniteCADNodeProperties, CORE_DM_3D_CONTAINER_SPACE, @@ -32,7 +34,7 @@ export async function getCadConnectionsForRevisions( const returnResult = results.items.cad_nodes .map((cadNode) => { - const props = cadNode.properties[CORE_DM_SPACE]['CogniteCADNode/v1']; + const props = cadNode.properties[CORE_DM_SPACE][COGNITE_CAD_NODE_VIEW_VERSION_KEY]; const object3dKey = cadNodeToModelMap.get(createFdmKey(cadNode)); if (object3dKey === undefined) { @@ -66,7 +68,7 @@ function createObject3dToAssetMap>( ): Map { return new Map( assets.map((asset) => [ - createFdmKey(asset.properties[CORE_DM_SPACE]?.['CogniteAsset/v1'].object3D), + createFdmKey(asset.properties[CORE_DM_SPACE]?.[COGNITE_ASSET_VIEW_VERSION_KEY].object3D), asset ]) ); @@ -78,7 +80,7 @@ function createCadNodeToObject3dMap( return new Map( cadNodes.map((cadNode) => [ createFdmKey(cadNode), - createFdmKey(cadNode.properties.cdf_cdm['CogniteCADNode/v1'].object3D) + createFdmKey(cadNode.properties[CORE_DM_SPACE][COGNITE_CAD_NODE_VIEW_VERSION_KEY].object3D) ]) ); } diff --git a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts index 420fb8c90fc..a4bc16aed08 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts @@ -1,11 +1,12 @@ /*! * Copyright 2024 Cognite AS */ -import { type QueryRequest } from '@cognite/sdk/dist/src'; +import { type QueryRequest } from '@cognite/sdk'; import { type TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { COGNITE_CAD_NODE_SOURCE, + COGNITE_CAD_NODE_VIEW_VERSION_KEY, COGNITE_VISUALIZABLE_SOURCE, type CogniteCADNodeProperties, CORE_DM_SPACE @@ -30,7 +31,7 @@ export async function getCadModelsForInstance( >(query); return results.items.cad_nodes.flatMap((cadNode) => { - const props = cadNode.properties[CORE_DM_SPACE]['CogniteCADNode/v1']; + const props = cadNode.properties[CORE_DM_SPACE][COGNITE_CAD_NODE_VIEW_VERSION_KEY]; return props.revisions.map((revision) => ({ type: 'cad', addOptions: { diff --git a/react-components/src/data-providers/core-dm-provider/getDMSModels.ts b/react-components/src/data-providers/core-dm-provider/getDMSModels.ts index 6c873e2ce32..c710274e6aa 100644 --- a/react-components/src/data-providers/core-dm-provider/getDMSModels.ts +++ b/react-components/src/data-providers/core-dm-provider/getDMSModels.ts @@ -1,7 +1,7 @@ /*! * Copyright 2024 Cognite AS */ -import { type QueryRequest } from '@cognite/sdk/dist/src'; +import { type QueryRequest } from '@cognite/sdk'; import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { type Cognite3DModelProperties, COGNITE_3D_MODEL_SOURCE } from './dataModels'; diff --git a/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts index d230d5afb8d..c606c273692 100644 --- a/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts +++ b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts @@ -1,7 +1,7 @@ /*! * Copyright 2024 Cognite AS */ -import { type QueryRequest } from '@cognite/sdk/dist/src'; +import { type QueryRequest } from '@cognite/sdk'; import { type DmsUniqueIdentifier, type FdmSDK, type NodeItem } from '../FdmSDK'; import { COGNITE_3D_REVISION_SOURCE, diff --git a/react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts b/react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts index fb09de51db9..aa4daf47f32 100644 --- a/react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts +++ b/react-components/src/data-providers/core-dm-provider/getEdgeConnected3dInstances.ts @@ -1,7 +1,7 @@ /*! * Copyright 2024 Cognite AS */ -import { type QueryRequest } from '@cognite/sdk/dist/src'; +import { type QueryRequest } from '@cognite/sdk'; import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { type Cognite3DObjectProperties, diff --git a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts index d1e3c324482..c6b59140968 100644 --- a/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts +++ b/react-components/src/data-providers/core-dm-provider/getFdmConnectionsForNodeIds.ts @@ -9,7 +9,9 @@ import { type COGNITE_3D_OBJECT_SOURCE, COGNITE_ASSET_SOURCE, COGNITE_CAD_NODE_SOURCE, + COGNITE_CAD_NODE_VIEW_VERSION_KEY, COGNITE_VISUALIZABLE_SOURCE, + COGNITE_VISUALIZABLE_VIEW_VERSION_KEY, type CogniteAssetProperties, type CogniteCADNodeProperties, type CogniteVisualizableProperties, @@ -56,7 +58,7 @@ export async function getFdmConnectionsForNodes( >(query); result.items.cad_nodes.forEach((cadNode) => { - const props = cadNode.properties[CORE_DM_SPACE]['CogniteCADNode/v1']; + const props = cadNode.properties[CORE_DM_SPACE][COGNITE_CAD_NODE_VIEW_VERSION_KEY]; const revisionIndex = props.revisions.findIndex((id) => id === revisionRef); const treeIndex = props.treeIndexes[revisionIndex]; @@ -70,7 +72,7 @@ export async function getFdmConnectionsForNodes( const relevantObjectToAssetsMap = new Map( result.items.assets.map((asset) => [ - createFdmKey(asset.properties.cdf_cdm['CogniteVisualizable/v1'].object3D), + createFdmKey(asset.properties[CORE_DM_SPACE][COGNITE_VISUALIZABLE_VIEW_VERSION_KEY].object3D), asset ]) ); diff --git a/react-components/src/data-providers/types.ts b/react-components/src/data-providers/types.ts index 7101cb245d4..fe7badfabb8 100644 --- a/react-components/src/data-providers/types.ts +++ b/react-components/src/data-providers/types.ts @@ -8,7 +8,7 @@ import { type InternalId, type Metadata, type Relationship -} from '@cognite/sdk/'; +} from '@cognite/sdk'; import { type DmsUniqueIdentifier, type Source } from './FdmSDK'; export type FdmInstanceWithView = DmsUniqueIdentifier & { view: Source }; diff --git a/react-components/src/utilities/queryKeys.ts b/react-components/src/utilities/queryKeys.ts index 21dae6bc4f4..eb7e1635b49 100644 --- a/react-components/src/utilities/queryKeys.ts +++ b/react-components/src/utilities/queryKeys.ts @@ -1,7 +1,7 @@ /*! * Copyright 2024 Cognite AS */ -import { type IdEither } from '@cognite/sdk/'; +import { type IdEither } from '@cognite/sdk'; export const queryKeys = { all: ['cdf'] as const, From 8f898f25900db03cb2f334f3993626a514312d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Tue, 3 Sep 2024 10:18:10 +0200 Subject: [PATCH 30/32] chore: refactor queries --- .../core-dm-provider/cadConnectionsQuery.ts | 66 ++++++++ .../cadModelsForInstanceQuery.ts | 47 ++++++ .../check3dConnectedEquipmentQuery.ts | 148 +++++++++++++++++ .../cogniteAssetSourceWithProperties.ts | 6 +- .../cogniteCadNodeSourceWithProperties.ts | 6 +- .../cogniteCadRevisionSourceWithProperties.ts | 2 +- .../cogniteDescribableSourceWithProperties.ts | 9 ++ .../cogniteObject3dSourceWithProperties.ts | 6 +- .../core-dm-provider/dataModels.ts | 7 + .../filterNodesByMappedTo3d.ts | 153 +----------------- .../getCadConnectionsForRevisions.ts | 63 +------- .../getCadModelsForInstance.ts | 48 +----- .../core-dm-provider/getDMSRevision.ts | 56 +------ .../core-dm-provider/revisionQuery.ts | 46 ++++++ 14 files changed, 339 insertions(+), 324 deletions(-) create mode 100644 react-components/src/data-providers/core-dm-provider/cadConnectionsQuery.ts create mode 100644 react-components/src/data-providers/core-dm-provider/cadModelsForInstanceQuery.ts create mode 100644 react-components/src/data-providers/core-dm-provider/check3dConnectedEquipmentQuery.ts create mode 100644 react-components/src/data-providers/core-dm-provider/cogniteDescribableSourceWithProperties.ts create mode 100644 react-components/src/data-providers/core-dm-provider/revisionQuery.ts diff --git a/react-components/src/data-providers/core-dm-provider/cadConnectionsQuery.ts b/react-components/src/data-providers/core-dm-provider/cadConnectionsQuery.ts new file mode 100644 index 00000000000..5ebe8612812 --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/cadConnectionsQuery.ts @@ -0,0 +1,66 @@ +import { QueryRequest } from '@cognite/sdk/dist/src'; +import { cogniteAssetSourceWithProperties } from './cogniteAssetSourceWithProperties'; +import { cogniteCadNodeSourceWithProperties } from './cogniteCadNodeSourceWithProperties'; +import { + COGNITE_3D_OBJECT_SOURCE, + COGNITE_ASSET_SOURCE, + COGNITE_CAD_NODE_SOURCE, + CORE_DM_3D_CONTAINER_SPACE +} from './dataModels'; + +export const cadConnectionsQuery = { + with: { + cad_nodes: { + nodes: { + filter: { + and: [ + { + in: { + property: [ + CORE_DM_3D_CONTAINER_SPACE, + COGNITE_CAD_NODE_SOURCE.externalId, + 'model3D' + ], + values: { parameter: 'modelRefs' } + } + }, + { + containsAny: { + property: [ + CORE_DM_3D_CONTAINER_SPACE, + COGNITE_CAD_NODE_SOURCE.externalId, + 'revisions' + ], + values: { parameter: 'revisionRefs' } + } + } + ] + } + }, + limit: 10000 + }, + object_3ds: { + nodes: { + from: 'cad_nodes', + through: { view: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' }, + direction: 'outwards', + filter: { + hasData: [COGNITE_3D_OBJECT_SOURCE] + } + }, + limit: 10000 + }, + assets: { + nodes: { + from: 'object_3ds', + through: { view: COGNITE_ASSET_SOURCE, identifier: 'object3D' }, + direction: 'inwards' + }, + limit: 10000 + } + }, + select: { + cad_nodes: { sources: cogniteCadNodeSourceWithProperties }, + assets: { sources: cogniteAssetSourceWithProperties } + } +} as const satisfies Omit; diff --git a/react-components/src/data-providers/core-dm-provider/cadModelsForInstanceQuery.ts b/react-components/src/data-providers/core-dm-provider/cadModelsForInstanceQuery.ts new file mode 100644 index 00000000000..edcff8a19e9 --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/cadModelsForInstanceQuery.ts @@ -0,0 +1,47 @@ +import { QueryRequest } from '@cognite/sdk/dist/src'; +import { cogniteCadNodeSourceWithProperties } from './cogniteCadNodeSourceWithProperties'; +import { COGNITE_CAD_NODE_SOURCE, COGNITE_VISUALIZABLE_SOURCE } from './dataModels'; + +export const cadModelsForInstanceQuery = { + with: { + asset: { + nodes: { + filter: { + and: [ + { + equals: { + property: ['node', 'externalId'], + value: { parameter: 'instanceExternalId' } + } + }, + { + equals: { + property: ['node', 'space'], + value: { parameter: 'instanceSpace' } + } + } + ] + } + } + }, + object_3ds: { + nodes: { + from: 'asset', + through: { + view: COGNITE_VISUALIZABLE_SOURCE, + identifier: 'object3D' + }, + direction: 'outwards' + } + }, + cad_nodes: { + nodes: { + from: 'object_3ds', + through: { view: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' } + } + } + }, + select: { + cad_nodes: { sources: cogniteCadNodeSourceWithProperties } + } +} as const satisfies Omit; diff --git a/react-components/src/data-providers/core-dm-provider/check3dConnectedEquipmentQuery.ts b/react-components/src/data-providers/core-dm-provider/check3dConnectedEquipmentQuery.ts new file mode 100644 index 00000000000..f7a78c5210b --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/check3dConnectedEquipmentQuery.ts @@ -0,0 +1,148 @@ +import { QueryRequest, QueryTableExpressionV3, SourceSelectorV3 } from '@cognite/sdk/dist/src'; +import { cogniteObject3dSourceWithProperties } from './cogniteObject3dSourceWithProperties'; +import { + COGNITE_CAD_NODE_SOURCE, + COGNITE_POINT_CLOUD_VOLUME_SOURCE, + COGNITE_VISUALIZABLE_SOURCE, + CORE_DM_3D_CONTAINER_SPACE +} from './dataModels'; + +const pointCloudVolumeSourceWithProperties = [ + { + source: COGNITE_POINT_CLOUD_VOLUME_SOURCE, + properties: ['object3D'] + } +] as const satisfies SourceSelectorV3; + +const cadNodeSourceWithProperties = [ + { + source: COGNITE_CAD_NODE_SOURCE, + properties: ['object3D'] + } +] as const satisfies SourceSelectorV3; + +export const check3dConnectedEquipmentQuery = { + with: { + initial_nodes: { + nodes: { + filter: { + and: [ + { + in: { + property: ['node', 'externalId'], + values: { parameter: 'initialExternalIds' } + } + }, + { + hasData: [COGNITE_VISUALIZABLE_SOURCE] + } + ] + } + } + }, + directly_referenced_nodes: { + nodes: { + filter: { + and: [ + { + in: { + property: ['node', 'externalId'], + values: { parameter: 'directlyMappedIds' } + } + }, + { + hasData: [COGNITE_VISUALIZABLE_SOURCE] + } + ] + } + } + }, + indirectly_referenced_edges: { + edges: { + from: 'initial_nodes', + direction: 'outwards', + nodeFilter: { + hasData: [COGNITE_VISUALIZABLE_SOURCE] + } + } + }, + indirectly_referenced_nodes: { + nodes: { + from: 'indirectly_referenced_edges' + } + }, + initial_nodes_object_3ds: getObject3dRelation('initial_nodes'), + initial_nodes_cad_nodes: getRevisionsCadNodeFromObject3D('initial_nodes_object_3ds'), + initial_nodes_point_cloud_volumes: getRevisionsPointCloudVolumes('initial_nodes_object_3ds'), + direct_nodes_object_3ds: getObject3dRelation('directly_referenced_nodes'), + direct_nodes_cad_nodes: getRevisionsCadNodeFromObject3D('direct_nodes_object_3ds'), + direct_nodes_point_cloud_volumes: getRevisionsPointCloudVolumes('direct_nodes_object_3ds'), + indirect_nodes_object_3ds: getObject3dRelation('indirectly_referenced_nodes'), + indirect_nodes_cad_nodes: getRevisionsCadNodeFromObject3D('indirect_nodes_object_3ds'), + indirect_nodes_point_cloud_volumes: getRevisionsPointCloudVolumes('indirect_nodes_object_3ds') + }, + select: { + indirectly_referenced_edges: {}, + initial_nodes_object_3ds: { sources: cogniteObject3dSourceWithProperties }, + initial_nodes_cad_nodes: { + sources: cadNodeSourceWithProperties + }, + initial_nodes_point_cloud_volumes: { sources: pointCloudVolumeSourceWithProperties }, + direct_nodes_object_3ds: { sources: cogniteObject3dSourceWithProperties }, + direct_nodes_cad_nodes: { + sources: cadNodeSourceWithProperties + }, + direct_nodes_point_cloud_volumes: { sources: pointCloudVolumeSourceWithProperties }, + indirect_nodes_object_3ds: { sources: cogniteObject3dSourceWithProperties }, + indirect_nodes_cad_nodes: { + sources: cadNodeSourceWithProperties + }, + indirect_nodes_point_cloud_volumes: { + sources: pointCloudVolumeSourceWithProperties + } + } +} as const satisfies Omit; + +function getRevisionsCadNodeFromObject3D(object3dTableName: string): QueryTableExpressionV3 { + return { + nodes: { + from: object3dTableName, + through: { view: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' }, + filter: { + containsAny: { + property: [CORE_DM_3D_CONTAINER_SPACE, COGNITE_CAD_NODE_SOURCE.externalId, 'revisions'], + values: { parameter: 'revisionRefs' } + } + } + } + }; +} + +function getRevisionsPointCloudVolumes(object3dTableName: string): QueryTableExpressionV3 { + return { + nodes: { + from: object3dTableName, + through: { view: COGNITE_POINT_CLOUD_VOLUME_SOURCE, identifier: 'object3D' }, + filter: { + containsAny: { + property: [ + CORE_DM_3D_CONTAINER_SPACE, + COGNITE_POINT_CLOUD_VOLUME_SOURCE.externalId, + 'revisions' + ], + values: { parameter: 'revisionRefs' } + } + } + } + }; +} + +function getObject3dRelation(visualizableTableName: string): QueryTableExpressionV3 { + return { + nodes: { + from: visualizableTableName, + through: { view: COGNITE_VISUALIZABLE_SOURCE, identifier: 'object3D' }, + direction: 'outwards' + } + }; +} diff --git a/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts index 0c059bc4010..e12cd4cb8cd 100644 --- a/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts +++ b/react-components/src/data-providers/core-dm-provider/cogniteAssetSourceWithProperties.ts @@ -3,16 +3,14 @@ */ import { type SourceSelectorV3 } from '@cognite/sdk'; import { COGNITE_ASSET_SOURCE } from './dataModels'; +import { cogniteDescribableSourceWithProperties } from './cogniteDescribableSourceWithProperties'; export const cogniteAssetSourceWithProperties = [ { source: COGNITE_ASSET_SOURCE, properties: [ + ...cogniteDescribableSourceWithProperties[0].properties, 'object3D', - 'name', - 'description', - 'tags', - 'aliases', 'sourceId', 'sourceContext', 'source', diff --git a/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts index d10d49cf29a..8f0b1098eca 100644 --- a/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts +++ b/react-components/src/data-providers/core-dm-provider/cogniteCadNodeSourceWithProperties.ts @@ -3,15 +3,13 @@ */ import { type SourceSelectorV3 } from '@cognite/sdk'; import { COGNITE_CAD_NODE_SOURCE } from './dataModels'; +import { cogniteDescribableSourceWithProperties } from './cogniteDescribableSourceWithProperties'; export const cogniteCadNodeSourceWithProperties = [ { source: COGNITE_CAD_NODE_SOURCE, properties: [ - 'name', - 'description', - 'tags', - 'aliases', + ...cogniteDescribableSourceWithProperties[0].properties, 'object3D', 'model3D', 'cadNodeReference', diff --git a/react-components/src/data-providers/core-dm-provider/cogniteCadRevisionSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteCadRevisionSourceWithProperties.ts index 034445d6711..617e9e41d48 100644 --- a/react-components/src/data-providers/core-dm-provider/cogniteCadRevisionSourceWithProperties.ts +++ b/react-components/src/data-providers/core-dm-provider/cogniteCadRevisionSourceWithProperties.ts @@ -4,7 +4,7 @@ import { type SourceSelectorV3 } from '@cognite/sdk'; import { COGNITE_CAD_REVISION_SOURCE } from './dataModels'; -export const cogniteCadNodeSourceWithPRoperties = [ +export const cogniteCadRevisionSourceWithProperties = [ { source: COGNITE_CAD_REVISION_SOURCE, properties: ['status', 'published', 'type', 'model3D', 'revisionId'] diff --git a/react-components/src/data-providers/core-dm-provider/cogniteDescribableSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteDescribableSourceWithProperties.ts new file mode 100644 index 00000000000..73f0d61c99e --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/cogniteDescribableSourceWithProperties.ts @@ -0,0 +1,9 @@ +import { SourceSelectorV3 } from '@cognite/sdk/dist/src'; +import { COGNITE_DESCRIBABLE_SOURCE } from './dataModels'; + +export const cogniteDescribableSourceWithProperties = [ + { + source: COGNITE_DESCRIBABLE_SOURCE, + properties: ['name', 'description', 'tags', 'aliases'] + } +] as const satisfies SourceSelectorV3; diff --git a/react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts index 5a34fdb3290..10356b09776 100644 --- a/react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts +++ b/react-components/src/data-providers/core-dm-provider/cogniteObject3dSourceWithProperties.ts @@ -3,15 +3,13 @@ */ import { type SourceSelectorV3 } from '@cognite/sdk'; import { COGNITE_3D_OBJECT_SOURCE } from './dataModels'; +import { cogniteDescribableSourceWithProperties } from './cogniteDescribableSourceWithProperties'; export const cogniteObject3dSourceWithProperties = [ { source: COGNITE_3D_OBJECT_SOURCE, properties: [ - 'name', - 'description', - 'tags', - 'aliases', + ...cogniteDescribableSourceWithProperties[0].properties, 'xMin', 'xMax', 'yMin', diff --git a/react-components/src/data-providers/core-dm-provider/dataModels.ts b/react-components/src/data-providers/core-dm-provider/dataModels.ts index f71f0f9f27f..9c82ea489b4 100644 --- a/react-components/src/data-providers/core-dm-provider/dataModels.ts +++ b/react-components/src/data-providers/core-dm-provider/dataModels.ts @@ -12,6 +12,13 @@ export const COGNITE_ASSET_VIEW_VERSION_KEY = 'CogniteAsset/v1'; export const COGNITE_CAD_NODE_VIEW_VERSION_KEY = 'CogniteCADNode/v1'; export const COGNITE_POINT_CLOUD_VOLUME_VIEW_VERSION_KEY = 'CognitePointCloudVolume/v1'; +export const COGNITE_DESCRIBABLE_SOURCE = { + externalId: 'CogniteDescribable', + space: CORE_DM_SPACE, + version: 'v1', + type: 'view' +} as const satisfies ViewReference; + export const COGNITE_3D_OBJECT_SOURCE = { externalId: 'Cognite3DObject', space: CORE_DM_SPACE, diff --git a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts index 7ac96185c24..f6b0ff1b2c2 100644 --- a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts +++ b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts @@ -2,11 +2,6 @@ * Copyright 2024 Cognite AS */ import { type InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; -import { - type QueryRequest, - type QueryTableExpressionV3, - type SourceSelectorV3 -} from '@cognite/sdk'; import { getDirectRelationProperties } from '../utils/getDirectRelationProperties'; import { type Cognite3DObjectProperties, @@ -15,17 +10,15 @@ import { COGNITE_CAD_NODE_VIEW_VERSION_KEY, COGNITE_POINT_CLOUD_VOLUME_SOURCE, COGNITE_POINT_CLOUD_VOLUME_VIEW_VERSION_KEY, - COGNITE_VISUALIZABLE_SOURCE, - CORE_DM_3D_CONTAINER_SPACE, CORE_DM_SPACE } from './dataModels'; import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; -import { cogniteObject3dSourceWithProperties } from './cogniteObject3dSourceWithProperties'; import { type FdmKey } from '../../components/CacheProvider/types'; import { createFdmKey } from '../../components/CacheProvider/idAndKeyTranslation'; import { type PromiseType } from '../utils/typeUtils'; import { isString } from 'lodash'; import { type QueryResult } from '../utils/queryNodesAndEdges'; +import { check3dConnectedEquipmentQuery } from './check3dConnectedEquipmentQuery'; export async function filterNodesByMappedTo3d( nodes: InstancesWithView[], @@ -97,7 +90,7 @@ async function fetchConnectionData( nodes: InstancesWithView[], revisionRefs: DmsUniqueIdentifier[], fdmSdk: FdmSDK -): Promise> { +): Promise> { const initialExternalIds = nodes.flatMap((node) => node.instances.map((instance) => instance.externalId) ); @@ -111,149 +104,9 @@ async function fetchConnectionData( const parameters = { initialExternalIds, directlyMappedIds, revisionRefs }; const query = { - ...checkEquipmentFilter, + ...check3dConnectedEquipmentQuery, parameters }; return await fdmSdk.queryAllNodesAndEdges(query); } - -const pointCloudVolumeSourceWithProperties = [ - { - source: COGNITE_POINT_CLOUD_VOLUME_SOURCE, - properties: ['object3D'] - } -] as const satisfies SourceSelectorV3; - -const cadNodeSourceWithProperties = [ - { - source: COGNITE_CAD_NODE_SOURCE, - properties: ['object3D'] - } -] as const satisfies SourceSelectorV3; - -const checkEquipmentFilter = { - with: { - initial_nodes: { - nodes: { - filter: { - and: [ - { - in: { - property: ['node', 'externalId'], - values: { parameter: 'initialExternalIds' } - } - }, - { - hasData: [COGNITE_VISUALIZABLE_SOURCE] - } - ] - } - } - }, - directly_referenced_nodes: { - nodes: { - filter: { - and: [ - { - in: { - property: ['node', 'externalId'], - values: { parameter: 'directlyMappedIds' } - } - }, - { - hasData: [COGNITE_VISUALIZABLE_SOURCE] - } - ] - } - } - }, - indirectly_referenced_edges: { - edges: { - from: 'initial_nodes', - direction: 'outwards', - nodeFilter: { - hasData: [COGNITE_VISUALIZABLE_SOURCE] - } - } - }, - indirectly_referenced_nodes: { - nodes: { - from: 'indirectly_referenced_edges' - } - }, - initial_nodes_object_3ds: getObject3dRelation('initial_nodes'), - initial_nodes_cad_nodes: getRevisionsCadNodeFromObject3D('initial_nodes_object_3ds'), - initial_nodes_point_cloud_volumes: getRevisionsPointCloudVolumes('initial_nodes_object_3ds'), - direct_nodes_object_3ds: getObject3dRelation('directly_referenced_nodes'), - direct_nodes_cad_nodes: getRevisionsCadNodeFromObject3D('direct_nodes_object_3ds'), - direct_nodes_point_cloud_volumes: getRevisionsPointCloudVolumes('direct_nodes_object_3ds'), - indirect_nodes_object_3ds: getObject3dRelation('indirectly_referenced_nodes'), - indirect_nodes_cad_nodes: getRevisionsCadNodeFromObject3D('indirect_nodes_object_3ds'), - indirect_nodes_point_cloud_volumes: getRevisionsPointCloudVolumes('indirect_nodes_object_3ds') - }, - select: { - indirectly_referenced_edges: {}, - initial_nodes_object_3ds: { sources: cogniteObject3dSourceWithProperties }, - initial_nodes_cad_nodes: { - sources: cadNodeSourceWithProperties - }, - initial_nodes_point_cloud_volumes: { sources: pointCloudVolumeSourceWithProperties }, - direct_nodes_object_3ds: { sources: cogniteObject3dSourceWithProperties }, - direct_nodes_cad_nodes: { - sources: cadNodeSourceWithProperties - }, - direct_nodes_point_cloud_volumes: { sources: pointCloudVolumeSourceWithProperties }, - indirect_nodes_object_3ds: { sources: cogniteObject3dSourceWithProperties }, - indirect_nodes_cad_nodes: { - sources: cadNodeSourceWithProperties - }, - indirect_nodes_point_cloud_volumes: { - sources: pointCloudVolumeSourceWithProperties - } - } -} as const satisfies Omit; - -function getRevisionsCadNodeFromObject3D(object3dTableName: string): QueryTableExpressionV3 { - return { - nodes: { - from: object3dTableName, - through: { view: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' }, - filter: { - containsAny: { - property: [CORE_DM_3D_CONTAINER_SPACE, COGNITE_CAD_NODE_SOURCE.externalId, 'revisions'], - values: { parameter: 'revisionRefs' } - } - } - } - }; -} - -function getRevisionsPointCloudVolumes(object3dTableName: string): QueryTableExpressionV3 { - return { - nodes: { - from: object3dTableName, - through: { view: COGNITE_POINT_CLOUD_VOLUME_SOURCE, identifier: 'object3D' }, - filter: { - containsAny: { - property: [ - CORE_DM_3D_CONTAINER_SPACE, - COGNITE_POINT_CLOUD_VOLUME_SOURCE.externalId, - 'revisions' - ], - values: { parameter: 'revisionRefs' } - } - } - } - }; -} - -function getObject3dRelation(visualizableTableName: string): QueryTableExpressionV3 { - return { - nodes: { - from: visualizableTableName, - through: { view: COGNITE_VISUALIZABLE_SOURCE, identifier: 'object3D' }, - direction: 'outwards' - } - }; -} diff --git a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts index 95387734ca7..9e6b76aeb2d 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts @@ -1,28 +1,24 @@ /*! * Copyright 2024 Cognite AS */ -import { type QueryRequest } from '@cognite/sdk'; import { type FdmCadConnection, type FdmKey } from '../../components/CacheProvider/types'; import { type NodeItem, type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { - COGNITE_3D_OBJECT_SOURCE, COGNITE_ASSET_SOURCE, COGNITE_ASSET_VIEW_VERSION_KEY, COGNITE_CAD_NODE_SOURCE, COGNITE_CAD_NODE_VIEW_VERSION_KEY, type CogniteAssetProperties, type CogniteCADNodeProperties, - CORE_DM_3D_CONTAINER_SPACE, CORE_DM_SPACE } from './dataModels'; -import { cogniteCadNodeSourceWithProperties } from './cogniteCadNodeSourceWithProperties'; import { getModelIdFromExternalId, getRevisionIdFromExternalId } from './getCdfIdFromExternalId'; import { createFdmKey } from '../../components/CacheProvider/idAndKeyTranslation'; import { type PromiseType } from '../utils/typeUtils'; import { isDefined } from '../../utilities/isDefined'; import { type QueryResult } from '../utils/queryNodesAndEdges'; import { restrictToDmsId } from './restrictToDmsId'; -import { cogniteAssetSourceWithProperties } from './cogniteAssetSourceWithProperties'; +import { cadConnectionsQuery } from './cadConnectionsQuery'; export async function getCadConnectionsForRevisions( modelRevisions: Array<[DmsUniqueIdentifier, DmsUniqueIdentifier]>, @@ -137,60 +133,3 @@ async function getModelConnectionResults( return await fdmSdk.queryAllNodesAndEdges(query); } - -const cadConnectionsQuery = { - with: { - cad_nodes: { - nodes: { - filter: { - and: [ - { - in: { - property: [ - CORE_DM_3D_CONTAINER_SPACE, - COGNITE_CAD_NODE_SOURCE.externalId, - 'model3D' - ], - values: { parameter: 'modelRefs' } - } - }, - { - containsAny: { - property: [ - CORE_DM_3D_CONTAINER_SPACE, - COGNITE_CAD_NODE_SOURCE.externalId, - 'revisions' - ], - values: { parameter: 'revisionRefs' } - } - } - ] - } - }, - limit: 10000 - }, - object_3ds: { - nodes: { - from: 'cad_nodes', - through: { view: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' }, - direction: 'outwards', - filter: { - hasData: [COGNITE_3D_OBJECT_SOURCE] - } - }, - limit: 10000 - }, - assets: { - nodes: { - from: 'object_3ds', - through: { view: COGNITE_ASSET_SOURCE, identifier: 'object3D' }, - direction: 'inwards' - }, - limit: 10000 - } - }, - select: { - cad_nodes: { sources: cogniteCadNodeSourceWithProperties }, - assets: { sources: cogniteAssetSourceWithProperties } - } -} as const satisfies Omit; diff --git a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts index a4bc16aed08..e42fb6a2a91 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts @@ -1,18 +1,16 @@ /*! * Copyright 2024 Cognite AS */ -import { type QueryRequest } from '@cognite/sdk'; import { type TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { COGNITE_CAD_NODE_SOURCE, COGNITE_CAD_NODE_VIEW_VERSION_KEY, - COGNITE_VISUALIZABLE_SOURCE, type CogniteCADNodeProperties, CORE_DM_SPACE } from './dataModels'; -import { cogniteCadNodeSourceWithProperties } from './cogniteCadNodeSourceWithProperties'; import { getModelIdFromExternalId, getRevisionIdFromExternalId } from './getCdfIdFromExternalId'; +import { cadModelsForInstanceQuery } from './cadModelsForInstanceQuery'; export async function getCadModelsForInstance( instance: DmsUniqueIdentifier, @@ -41,47 +39,3 @@ export async function getCadModelsForInstance( })); }); } - -const cadModelsForInstanceQuery = { - with: { - asset: { - nodes: { - filter: { - and: [ - { - equals: { - property: ['node', 'externalId'], - value: { parameter: 'instanceExternalId' } - } - }, - { - equals: { - property: ['node', 'space'], - value: { parameter: 'instanceSpace' } - } - } - ] - } - } - }, - object_3ds: { - nodes: { - from: 'asset', - through: { - view: COGNITE_VISUALIZABLE_SOURCE, - identifier: 'object3D' - }, - direction: 'outwards' - } - }, - cad_nodes: { - nodes: { - from: 'object_3ds', - through: { view: COGNITE_CAD_NODE_SOURCE, identifier: 'object3D' } - } - } - }, - select: { - cad_nodes: { sources: cogniteCadNodeSourceWithProperties } - } -} as const satisfies Omit; diff --git a/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts index c606c273692..d44ccf7b1e3 100644 --- a/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts +++ b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts @@ -3,13 +3,9 @@ */ import { type QueryRequest } from '@cognite/sdk'; import { type DmsUniqueIdentifier, type FdmSDK, type NodeItem } from '../FdmSDK'; -import { - COGNITE_3D_REVISION_SOURCE, - COGNITE_CAD_REVISION_SOURCE, - CORE_DM_3D_CONTAINER_SPACE, - type CogniteCADRevisionProperties -} from './dataModels'; +import { COGNITE_CAD_REVISION_SOURCE, type CogniteCADRevisionProperties } from './dataModels'; import { restrictToDmsId } from './restrictToDmsId'; +import { revisionQuery } from './revisionQuery'; export async function getDMSRevision( model: DmsUniqueIdentifier, @@ -17,12 +13,12 @@ export async function getDMSRevision( fdmSdk: FdmSDK ): Promise> { const query = { - ...cadConnectionQuery, + ...revisionQuery, parameters: { modelReference: restrictToDmsId(model), revisionId } } as const satisfies QueryRequest; const result = await fdmSdk.queryNodesAndEdges< - typeof cadConnectionQuery, + typeof revisionQuery, [{ source: typeof COGNITE_CAD_REVISION_SOURCE; properties: CogniteCADRevisionProperties }] >(query); @@ -34,47 +30,3 @@ export async function getDMSRevision( return result.items.revision[0]; } - -const cadConnectionQuery = { - with: { - revision: { - nodes: { - filter: { - and: [ - { - equals: { - property: [ - CORE_DM_3D_CONTAINER_SPACE, - COGNITE_3D_REVISION_SOURCE.externalId, - 'model3D' - ], - value: { parameter: 'modelReference' } - } - }, - { - equals: { - property: [ - CORE_DM_3D_CONTAINER_SPACE, - COGNITE_CAD_REVISION_SOURCE.externalId, - 'revisionId' - ], - value: { parameter: 'revisionId' } - } - } - ] - } - }, - limit: 1 - } - }, - select: { - revision: { - sources: [ - { - source: COGNITE_CAD_REVISION_SOURCE, - properties: ['status', 'published', 'type', 'model3D', 'revisionId'] - } - ] - } - } -} as const satisfies Omit; diff --git a/react-components/src/data-providers/core-dm-provider/revisionQuery.ts b/react-components/src/data-providers/core-dm-provider/revisionQuery.ts new file mode 100644 index 00000000000..10f3071062f --- /dev/null +++ b/react-components/src/data-providers/core-dm-provider/revisionQuery.ts @@ -0,0 +1,46 @@ +import { QueryRequest } from '@cognite/sdk/dist/src'; +import { + COGNITE_3D_REVISION_SOURCE, + COGNITE_CAD_REVISION_SOURCE, + CORE_DM_3D_CONTAINER_SPACE +} from './dataModels'; +import { cogniteCadRevisionSourceWithProperties } from './cogniteCadRevisionSourceWithProperties'; + +export const revisionQuery = { + with: { + revision: { + nodes: { + filter: { + and: [ + { + equals: { + property: [ + CORE_DM_3D_CONTAINER_SPACE, + COGNITE_3D_REVISION_SOURCE.externalId, + 'model3D' + ], + value: { parameter: 'modelReference' } + } + }, + { + equals: { + property: [ + CORE_DM_3D_CONTAINER_SPACE, + COGNITE_CAD_REVISION_SOURCE.externalId, + 'revisionId' + ], + value: { parameter: 'revisionId' } + } + } + ] + } + }, + limit: 1 + } + }, + select: { + revision: { + sources: cogniteCadRevisionSourceWithProperties + } + } +} as const satisfies Omit; From 9dfed45eb1db25761eeec5d42463d91f63559ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Tue, 3 Sep 2024 10:20:29 +0200 Subject: [PATCH 31/32] chore: lint fix --- .../core-dm-provider/cadConnectionsQuery.ts | 5 ++++- .../core-dm-provider/cadModelsForInstanceQuery.ts | 5 ++++- .../core-dm-provider/check3dConnectedEquipmentQuery.ts | 9 ++++++++- .../cogniteDescribableSourceWithProperties.ts | 5 ++++- .../core-dm-provider/filterNodesByMappedTo3d.ts | 4 ++-- .../core-dm-provider/getCadConnectionsForRevisions.ts | 4 ++-- .../core-dm-provider/getCadModelsForInstance.ts | 2 +- .../data-providers/core-dm-provider/getDMSRevision.ts | 2 +- .../src/data-providers/core-dm-provider/revisionQuery.ts | 5 ++++- 9 files changed, 30 insertions(+), 11 deletions(-) diff --git a/react-components/src/data-providers/core-dm-provider/cadConnectionsQuery.ts b/react-components/src/data-providers/core-dm-provider/cadConnectionsQuery.ts index 5ebe8612812..5bec90d38ef 100644 --- a/react-components/src/data-providers/core-dm-provider/cadConnectionsQuery.ts +++ b/react-components/src/data-providers/core-dm-provider/cadConnectionsQuery.ts @@ -1,4 +1,7 @@ -import { QueryRequest } from '@cognite/sdk/dist/src'; +/*! + * Copyright 2024 Cognite AS + */ +import { type QueryRequest } from '@cognite/sdk/dist/src'; import { cogniteAssetSourceWithProperties } from './cogniteAssetSourceWithProperties'; import { cogniteCadNodeSourceWithProperties } from './cogniteCadNodeSourceWithProperties'; import { diff --git a/react-components/src/data-providers/core-dm-provider/cadModelsForInstanceQuery.ts b/react-components/src/data-providers/core-dm-provider/cadModelsForInstanceQuery.ts index edcff8a19e9..89b4ec6426f 100644 --- a/react-components/src/data-providers/core-dm-provider/cadModelsForInstanceQuery.ts +++ b/react-components/src/data-providers/core-dm-provider/cadModelsForInstanceQuery.ts @@ -1,4 +1,7 @@ -import { QueryRequest } from '@cognite/sdk/dist/src'; +/*! + * Copyright 2024 Cognite AS + */ +import { type QueryRequest } from '@cognite/sdk/dist/src'; import { cogniteCadNodeSourceWithProperties } from './cogniteCadNodeSourceWithProperties'; import { COGNITE_CAD_NODE_SOURCE, COGNITE_VISUALIZABLE_SOURCE } from './dataModels'; diff --git a/react-components/src/data-providers/core-dm-provider/check3dConnectedEquipmentQuery.ts b/react-components/src/data-providers/core-dm-provider/check3dConnectedEquipmentQuery.ts index f7a78c5210b..dae9887e8a6 100644 --- a/react-components/src/data-providers/core-dm-provider/check3dConnectedEquipmentQuery.ts +++ b/react-components/src/data-providers/core-dm-provider/check3dConnectedEquipmentQuery.ts @@ -1,4 +1,11 @@ -import { QueryRequest, QueryTableExpressionV3, SourceSelectorV3 } from '@cognite/sdk/dist/src'; +/*! + * Copyright 2024 Cognite AS + */ +import { + type QueryRequest, + type QueryTableExpressionV3, + type SourceSelectorV3 +} from '@cognite/sdk/dist/src'; import { cogniteObject3dSourceWithProperties } from './cogniteObject3dSourceWithProperties'; import { COGNITE_CAD_NODE_SOURCE, diff --git a/react-components/src/data-providers/core-dm-provider/cogniteDescribableSourceWithProperties.ts b/react-components/src/data-providers/core-dm-provider/cogniteDescribableSourceWithProperties.ts index 73f0d61c99e..7868abe18aa 100644 --- a/react-components/src/data-providers/core-dm-provider/cogniteDescribableSourceWithProperties.ts +++ b/react-components/src/data-providers/core-dm-provider/cogniteDescribableSourceWithProperties.ts @@ -1,4 +1,7 @@ -import { SourceSelectorV3 } from '@cognite/sdk/dist/src'; +/*! + * Copyright 2024 Cognite AS + */ +import { type SourceSelectorV3 } from '@cognite/sdk/dist/src'; import { COGNITE_DESCRIBABLE_SOURCE } from './dataModels'; export const cogniteDescribableSourceWithProperties = [ diff --git a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts index f6b0ff1b2c2..f1be93b8eff 100644 --- a/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts +++ b/react-components/src/data-providers/core-dm-provider/filterNodesByMappedTo3d.ts @@ -6,9 +6,9 @@ import { getDirectRelationProperties } from '../utils/getDirectRelationPropertie import { type Cognite3DObjectProperties, type COGNITE_3D_OBJECT_SOURCE, - COGNITE_CAD_NODE_SOURCE, + type COGNITE_CAD_NODE_SOURCE, COGNITE_CAD_NODE_VIEW_VERSION_KEY, - COGNITE_POINT_CLOUD_VOLUME_SOURCE, + type COGNITE_POINT_CLOUD_VOLUME_SOURCE, COGNITE_POINT_CLOUD_VOLUME_VIEW_VERSION_KEY, CORE_DM_SPACE } from './dataModels'; diff --git a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts index 9e6b76aeb2d..5649a16501a 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadConnectionsForRevisions.ts @@ -4,9 +4,9 @@ import { type FdmCadConnection, type FdmKey } from '../../components/CacheProvider/types'; import { type NodeItem, type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { - COGNITE_ASSET_SOURCE, + type COGNITE_ASSET_SOURCE, COGNITE_ASSET_VIEW_VERSION_KEY, - COGNITE_CAD_NODE_SOURCE, + type COGNITE_CAD_NODE_SOURCE, COGNITE_CAD_NODE_VIEW_VERSION_KEY, type CogniteAssetProperties, type CogniteCADNodeProperties, diff --git a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts index e42fb6a2a91..e135af7a599 100644 --- a/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts +++ b/react-components/src/data-providers/core-dm-provider/getCadModelsForInstance.ts @@ -4,7 +4,7 @@ import { type TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; import { - COGNITE_CAD_NODE_SOURCE, + type COGNITE_CAD_NODE_SOURCE, COGNITE_CAD_NODE_VIEW_VERSION_KEY, type CogniteCADNodeProperties, CORE_DM_SPACE diff --git a/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts index d44ccf7b1e3..dea05b9b985 100644 --- a/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts +++ b/react-components/src/data-providers/core-dm-provider/getDMSRevision.ts @@ -3,7 +3,7 @@ */ import { type QueryRequest } from '@cognite/sdk'; import { type DmsUniqueIdentifier, type FdmSDK, type NodeItem } from '../FdmSDK'; -import { COGNITE_CAD_REVISION_SOURCE, type CogniteCADRevisionProperties } from './dataModels'; +import { type COGNITE_CAD_REVISION_SOURCE, type CogniteCADRevisionProperties } from './dataModels'; import { restrictToDmsId } from './restrictToDmsId'; import { revisionQuery } from './revisionQuery'; diff --git a/react-components/src/data-providers/core-dm-provider/revisionQuery.ts b/react-components/src/data-providers/core-dm-provider/revisionQuery.ts index 10f3071062f..45b9f095816 100644 --- a/react-components/src/data-providers/core-dm-provider/revisionQuery.ts +++ b/react-components/src/data-providers/core-dm-provider/revisionQuery.ts @@ -1,4 +1,7 @@ -import { QueryRequest } from '@cognite/sdk/dist/src'; +/*! + * Copyright 2024 Cognite AS + */ +import { type QueryRequest } from '@cognite/sdk/dist/src'; import { COGNITE_3D_REVISION_SOURCE, COGNITE_CAD_REVISION_SOURCE, From b6fb572b5f9f94cc4a008019168fcb67ce6cebfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Tue, 3 Sep 2024 10:57:16 +0200 Subject: [PATCH 32/32] chore(react-components): bump to version 0.56.0 --- 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 7645de163a6..d68290c483f 100644 --- a/react-components/package.json +++ b/react-components/package.json @@ -1,6 +1,6 @@ { "name": "@cognite/reveal-react-components", - "version": "0.55.10", + "version": "0.56.0", "exports": { ".": { "import": "./dist/index.js",