From bde15407f5bf98d0c2acc3b1c7d9f4e2c67ec819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= <70905152+haakonflatval-cognite@users.noreply.github.com> Date: Wed, 22 Jan 2025 13:47:48 +0100 Subject: [PATCH] fix: correct point cloud volume <-> asset mapping (#4966) * fix(react-components): correct asset <-> point cloud volume mapping * chore: correct list method with empty input * test: fix tests * chore: bump version to 4.23.1 --- .../core-dm-provider/listMappedFdmNodes.ts | 4 ++ viewer/package.json | 2 +- ...PointCloudDMStylableObjectProvider.test.ts | 24 +++++-- .../getDMPointCloudObjects.ts | 71 ++++++++++++------- 4 files changed, 70 insertions(+), 31 deletions(-) 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 e52027b5a35..e5146ab2276 100644 --- a/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts +++ b/react-components/src/data-providers/core-dm-provider/listMappedFdmNodes.ts @@ -42,6 +42,10 @@ export async function listMappedFdmNodes( limit: number, fdmSdk: FdmSDK ): Promise { + if (revisionRefs.length === 0) { + return []; + } + const filter = makeSureNonEmptyFilterForRequest(instancesFilter); const rawQuery = cadAndPointCloudAssetQuery(sourcesToSearch, filter, limit); diff --git a/viewer/package.json b/viewer/package.json index fcb589dd56e..4386c88f2cc 100644 --- a/viewer/package.json +++ b/viewer/package.json @@ -1,6 +1,6 @@ { "name": "@cognite/reveal", - "version": "4.23.0", + "version": "4.23.1", "description": "WebGL based 3D viewer for CAD and point clouds processed in Cognite Data Fusion.", "homepage": "https://github.com/cognitedata/reveal/tree/master/viewer", "repository": { diff --git a/viewer/packages/data-providers/src/pointcloud-stylable-object-providers/pointcloud-volume-data-providers/CdfPointCloudDMStylableObjectProvider.test.ts b/viewer/packages/data-providers/src/pointcloud-stylable-object-providers/pointcloud-volume-data-providers/CdfPointCloudDMStylableObjectProvider.test.ts index 3b16021fb90..38664a05d46 100644 --- a/viewer/packages/data-providers/src/pointcloud-stylable-object-providers/pointcloud-volume-data-providers/CdfPointCloudDMStylableObjectProvider.test.ts +++ b/viewer/packages/data-providers/src/pointcloud-stylable-object-providers/pointcloud-volume-data-providers/CdfPointCloudDMStylableObjectProvider.test.ts @@ -43,7 +43,8 @@ const mock = { cdf_cdm: { 'CognitePointCloudVolume/v1': { volume: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], - volumeType: 'Box' + volumeType: 'Box', + object3D: { externalId: 'obj3d0', space: 'objSpace' } } } } @@ -59,7 +60,8 @@ const mock = { cdf_cdm: { 'CognitePointCloudVolume/v1': { volume: [-0.03, 0.1, -1000, -0.03, 0.1, 1000, 0.04], - volumeType: 'Cylinder' + volumeType: 'Cylinder', + object3D: { externalId: 'obj3d1', space: 'objSpace' } } } } @@ -72,7 +74,14 @@ const mock = { space: 'test_space', externalId: 'test_asset_1', createdTime: 0, - lastUpdatedTime: 0 + lastUpdatedTime: 0, + properties: { + cdf_cdm: { + 'CogniteAsset/v1': { + object3D: { externalId: 'obj3d0', space: 'objSpace' } + } + } + } }, { instanceType: 'node', @@ -80,7 +89,14 @@ const mock = { space: 'test_space', externalId: 'test_asset_2', createdTime: 0, - lastUpdatedTime: 0 + lastUpdatedTime: 0, + properties: { + cdf_cdm: { + 'CogniteAsset/v1': { + object3D: { externalId: 'obj3d1', space: 'objSpace' } + } + } + } } ] } diff --git a/viewer/packages/data-providers/src/pointcloud-stylable-object-providers/pointcloud-volume-data-providers/getDMPointCloudObjects.ts b/viewer/packages/data-providers/src/pointcloud-stylable-object-providers/pointcloud-volume-data-providers/getDMPointCloudObjects.ts index 8fd7b4aa16e..b351e374d57 100644 --- a/viewer/packages/data-providers/src/pointcloud-stylable-object-providers/pointcloud-volume-data-providers/getDMPointCloudObjects.ts +++ b/viewer/packages/data-providers/src/pointcloud-stylable-object-providers/pointcloud-volume-data-providers/getDMPointCloudObjects.ts @@ -11,7 +11,7 @@ import { PointCloudVolumeObject3DProperties } from './types'; import { CdfPointCloudObjectAnnotation } from '../types'; import { QueryNextCursors } from '../../types'; -import { IShape, Box, Cylinder } from '@reveal/utilities'; +import { IShape, Box, Cylinder, DMInstanceKey, dmInstanceRefToKey, DMInstanceRef } from '@reveal/utilities'; import { DMModelIdentifierType } from '../../DataSourceType'; type QueryResult = Awaited>>; @@ -46,43 +46,62 @@ export async function getDMPointCloudObjects( }; const query = getDMPointCloudVolumeCollectionQuery(modelIdentifier.revisionExternalId, modelIdentifier.revisionSpace); - const annotationLimit = query.with.pointCloudVolumes.limit; + const assetLimit = query.with.assets.limit; + const volumeLimit = query.with.pointCloudVolumes.limit; let nextCursor: QueryNextCursors | undefined = undefined; let hasNext = true; + type AssetResult = ExhaustedQueryResult['assets'][number]; + while (hasNext) { const { pointCloudVolumes, assets, nextCursor: currentCursor }: QueryResult = await dmsSdk.queryNodesAndEdges(query, nextCursor); - if (result.pointCloudVolumes.length === 0) { - result.pointCloudVolumes.push(...pointCloudVolumes); - } + result.pointCloudVolumes.push(...pointCloudVolumes); result.assets.push(...assets); - hasNext = assets.length === annotationLimit && currentCursor?.assets !== undefined; - nextCursor = { - assets: currentCursor?.assets - }; + hasNext = + (assets.length === assetLimit && currentCursor?.assets !== undefined) || + (pointCloudVolumes.length === volumeLimit && currentCursor?.pointCloudVolumes !== undefined); + nextCursor = currentCursor; } - const annotations: CdfPointCloudObjectAnnotation[] = result.pointCloudVolumes.map((volume, index) => { - const pointCloudVolumeProperties = volume.properties.cdf_cdm[ - 'CognitePointCloudVolume/v1' - ] as unknown as PointCloudVolumeObject3DProperties; - const region = pointCloudVolumeToRevealShapes( - pointCloudVolumeProperties.volume, - pointCloudVolumeProperties.volumeType - ); - - return { - volumeMetadata: { - instanceRef: { externalId: volume.externalId, space: volume.space }, - asset: { externalId: result.assets[index].externalId, space: result.assets[index].space } - }, - region: [region] - }; - }); + const object3DAndAssetPairs: [DMInstanceKey, AssetResult][] = result.assets.map(asset => [ + dmInstanceRefToKey(asset.properties.cdf_cdm['CogniteAsset/v1'].object3D as DMInstanceRef), + asset + ]); + + const object3DToAssetMap = new Map(object3DAndAssetPairs); + + const annotations: CdfPointCloudObjectAnnotation[] = result.pointCloudVolumes + .map(volume => { + const pointCloudVolumeProperties = volume.properties.cdf_cdm[ + 'CognitePointCloudVolume/v1' + ] as unknown as PointCloudVolumeObject3DProperties; + const region = pointCloudVolumeToRevealShapes( + pointCloudVolumeProperties.volume, + pointCloudVolumeProperties.volumeType + ); + + const asset = object3DToAssetMap.get( + dmInstanceRefToKey(volume.properties.cdf_cdm['CognitePointCloudVolume/v1'].object3D as DMInstanceRef) + ); + + if (asset === undefined) { + return undefined; + } + + return { + volumeMetadata: { + instanceRef: { externalId: volume.externalId, space: volume.space }, + asset: { externalId: asset.externalId, space: asset.space } + }, + region: [region] + }; + }) + .filter(result => result !== undefined); + return annotations; }