Skip to content

Commit

Permalink
feat(reveal): Add support for CDM 360 images in reveal (#4894)
Browse files Browse the repository at this point in the history
* Add support for CDM 360 images in reveal and reveal react components

* Update api spec

* Make amends

* Move type to top of file

* Revert changes to what's in master for react-components

* Bump version

* Bump minor instead of patch as API has changed
  • Loading branch information
anders-hopland authored Nov 27, 2024
1 parent f130c6a commit 1f9db64
Show file tree
Hide file tree
Showing 12 changed files with 666 additions and 9 deletions.
2 changes: 1 addition & 1 deletion viewer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cognite/reveal",
"version": "4.21.3",
"version": "4.22.0",
"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": {
Expand Down
5 changes: 4 additions & 1 deletion viewer/packages/api/src/api-helpers/Image360ApiHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import { DEFAULT_IMAGE_360_OPACITY } from '@reveal/360-images/src/entity/Image36
import { Image360History } from '@reveal/360-images/src/Image360History';
import { Image360Action } from '@reveal/360-images/src/Image360Action';
import { Image360IconIntersectionData } from '@reveal/360-images/src/types';
import { Cdf360CdmDescriptorProvider } from '@reveal/data-providers/src/image-360-data-providers/descriptor-providers/datamodels/cdm/Cdf360CdmDescriptorProvider';

export class Image360ApiHelper<DataSourceT extends DataSourceType> {
private readonly _image360Facade: Image360Facade<DataSourceT>;
Expand Down Expand Up @@ -110,9 +111,11 @@ export class Image360ApiHelper<DataSourceT extends DataSourceType> {
this._hasEventListeners = hasEventListeners ?? true;
const image360EventDescriptorProvider = new Cdf360EventDescriptorProvider(cogniteClient);
const image360DataModelsDescriptorProvider = new Cdf360DataModelsDescriptorProvider(cogniteClient);
const image360CdmDescriptorProvider = new Cdf360CdmDescriptorProvider(cogniteClient);
const combinedDescriptorProvider = new Cdf360CombinedDescriptorProvider(
image360DataModelsDescriptorProvider,
image360EventDescriptorProvider
image360EventDescriptorProvider,
image360CdmDescriptorProvider
);

const setNeedsRedraw: () => void = () => (this._needsRedraw = true);
Expand Down
2 changes: 1 addition & 1 deletion viewer/packages/data-providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export { Cdf360EventDescriptorProvider } from './src/image-360-data-providers/de
export {
Cdf360DataModelsDescriptorProvider,
Image360DataModelIdentifier
} from './src/image-360-data-providers/descriptor-providers/datamodels/Cdf360DataModelsDescriptorProvider';
} from './src/image-360-data-providers/descriptor-providers/datamodels/system-space/Cdf360DataModelsDescriptorProvider';
export { Cdf360CombinedDescriptorProvider } from './src/image-360-data-providers/descriptor-providers/Cdf360CombinedDescriptorProvider';
export { LocalModelDataProvider } from './src/model-data-providers/LocalModelDataProvider';
export { LocalModelIdentifier } from './src/model-identifiers/LocalModelIdentifier';
Expand Down
2 changes: 1 addition & 1 deletion viewer/packages/data-providers/src/DataSourceType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Copyright 2024 Cognite AS
*/
import { AnnotationModel, AnnotationsAssetRef } from '@cognite/sdk';
import { Image360DataModelIdentifier } from './image-360-data-providers/descriptor-providers/datamodels/Cdf360DataModelsDescriptorProvider';
import { Image360DataModelIdentifier } from './image-360-data-providers/descriptor-providers/datamodels/system-space/Cdf360DataModelsDescriptorProvider';
import { DMInstanceRef } from './pointcloud-stylable-object-providers/types';
import { PointCloudAnnotationVolumeCollection, PointCloudDMVolumeCollection } from '@reveal/pointcloud-styling';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ import { Historical360ImageSet, Image360DescriptorProvider } from '../../types';
import {
Cdf360DataModelsDescriptorProvider,
Image360DataModelIdentifier
} from './datamodels/Cdf360DataModelsDescriptorProvider';
} from './datamodels/system-space/Cdf360DataModelsDescriptorProvider';
import { Cdf360EventDescriptorProvider } from './events/Cdf360EventDescriptorProvider';
import { Cdf360CdmDescriptorProvider } from './datamodels/cdm/Cdf360CdmDescriptorProvider';

export class Cdf360CombinedDescriptorProvider
implements Image360DescriptorProvider<Metadata | Image360DataModelIdentifier>
{
private readonly _eventProvider: Cdf360EventDescriptorProvider;
private readonly _fdmProvider: Cdf360DataModelsDescriptorProvider;
private readonly _cdmProvider: Cdf360CdmDescriptorProvider;

public static isFdmIdentifier(
metadataFilter: Metadata | Image360DataModelIdentifier
Expand All @@ -25,17 +27,26 @@ export class Cdf360CombinedDescriptorProvider
);
}

constructor(fdmProvider: Cdf360DataModelsDescriptorProvider, eventProvider: Cdf360EventDescriptorProvider) {
constructor(
fdmProvider: Cdf360DataModelsDescriptorProvider,
eventProvider: Cdf360EventDescriptorProvider,
cdmProvider: Cdf360CdmDescriptorProvider
) {
this._fdmProvider = fdmProvider;
this._eventProvider = eventProvider;
this._cdmProvider = cdmProvider;
}

public get360ImageDescriptors(
metadataFilter: Metadata | Image360DataModelIdentifier,
preMultipliedRotation: boolean
): Promise<Historical360ImageSet[]> {
if (Cdf360CombinedDescriptorProvider.isFdmIdentifier(metadataFilter)) {
return this._fdmProvider.get360ImageDescriptors(metadataFilter, preMultipliedRotation);
if (metadataFilter.source === 'cdm') {
return this._cdmProvider.get360ImageDescriptors(metadataFilter, preMultipliedRotation);
} else {
return this._fdmProvider.get360ImageDescriptors(metadataFilter, preMultipliedRotation);
}
} else {
return this._eventProvider.get360ImageDescriptors(metadataFilter, preMultipliedRotation);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
/*!
* Copyright 2023 Cognite AS
*/

import { CogniteClient, FileInfo } from '@cognite/sdk';
import { Cdf360CdmDescriptorProvider } from './Cdf360CdmDescriptorProvider';
import { It, Mock } from 'moq.ts';

const mock = {
headers: {
'access-control-allow-credentials': 'false',
'access-control-allow-headers':
'accept,accept-language,content-type,content-language,content-range,origin,authorization,api-key,auth-ticket,cdf-version,cdf-experiments,env,x-cdp-app,x-cdp-clienttag,x-cdp-sdk,x-ms-blob-content-type,x-upload-content-type,x-user-agent',
'access-control-allow-methods': 'GET,POST,PUT,PATCH,DELETE,OPTIONS,HEAD',
'access-control-allow-origin': '*',
'access-control-expose-headers': 'x-request-id',
'access-control-max-age': '7200',
connection: 'close',
'content-encoding': 'gzip',
'content-length': '6542',
'content-type': 'application/json',
date: 'Thu, 16 Nov 2023 14:46:45 GMT',
server: 'envoy',
'strict-transport-security': 'max-age=31536000',
vary: 'Accept-Encoding',
'x-envoy-upstream-service-time': '143',
'x-request-id': '87518dc6-0c61-9ef0-9588-94f61ab5a450'
},
status: 200,
data: {
items: {
image_collection: [
{
instanceType: 'node',
version: 1,
space: 'test_space',
externalId: 'test_collection',
createdTime: 0,
lastUpdatedTime: 0,
properties: {
cdf_cdm: {
'Cognite360ImageCollection/v1': {
name: 'Test Collection'
}
}
}
}
],
images: [
{
instanceType: 'node',
version: 1,
space: 'test_space',
externalId: 'test_image_1',
createdTime: 0,
lastUpdatedTime: 0,
properties: {
cdf_cdm: {
'Cognite360Image/v1': {
top: {
externalId: 'test_image_3_Top',
space: 'test_space'
},
back: {
externalId: 'test_image_3_Back',
space: 'test_space'
},
left: {
externalId: 'test_image_3_Left',
space: 'test_space'
},
front: {
externalId: 'test_image_3_Front',
space: 'test_space'
},
right: {
externalId: 'test_image_3_Right',
space: 'test_space'
},
bottom: {
externalId: 'test_image_3_Bottom',
space: 'test_space'
},
collection360: {
space: 'test_space',
externalId: 'test_collection'
},
scaleX: 1,
scaleY: 1,
scaleZ: 1,
translationX: 0,
translationY: 0,
translationZ: 0,
eulerRotationX: 0,
eulerRotationY: 0,
eulerRotationZ: 0
}
}
}
},
{
instanceType: 'node',
version: 1,
space: 'test_space',
externalId: 'test_image_2',
createdTime: 0,
lastUpdatedTime: 0,
properties: {
cdf_cdm: {
'Cognite360Image/v1': {
top: {
externalId: 'test_image_3_Top',
space: 'test_space'
},
back: {
externalId: 'test_image_3_Back',
space: 'test_space'
},
left: {
externalId: 'test_image_3_Left',
space: 'test_space'
},
front: {
externalId: 'test_image_3_Front',
space: 'test_space'
},
right: {
externalId: 'test_image_3_Right',
space: 'test_space'
},
bottom: {
externalId: 'test_image_3_Bottom',
space: 'test_space'
},
collection360: {
space: 'test_space',
externalId: 'test_collection'
},
scaleX: 1,
scaleY: 1,
scaleZ: 1,
translationX: 1,
translationY: 1,
translationZ: 1,
eulerRotationX: 1,
eulerRotationY: 1,
eulerRotationZ: 1
}
}
}
},
{
instanceType: 'node',
version: 1,
space: 'test_space',
externalId: 'test_image_3',
createdTime: 0,
lastUpdatedTime: 0,
properties: {
cdf_cdm: {
'Cognite360Image/v1': {
top: {
externalId: 'test_image_3_Top',
space: 'test_space'
},
back: {
externalId: 'test_image_3_Back',
space: 'test_space'
},
left: {
externalId: 'test_image_3_Left',
space: 'test_space'
},
front: {
externalId: 'test_image_3_Front',
space: 'test_space'
},
right: {
externalId: 'test_image_3_Right',
space: 'test_space'
},
bottom: {
externalId: 'test_image_3_Bottom',
space: 'test_space'
},
collection360: {
space: 'test_space',
externalId: 'test_collection'
},
scaleX: 1,
scaleY: 1,
scaleZ: 1,
translationX: 3,
translationY: 3,
translationZ: 3,
eulerRotationX: 3,
eulerRotationY: 3,
eulerRotationZ: 3
}
}
}
}
],
stations: []
}
}
};

describe(Cdf360CdmDescriptorProvider.name, () => {
test('MyTest', async () => {
const sdkMock = new Mock<CogniteClient>()
.setup(instance =>
instance.post(
It.Is((path: string) => path.includes('query')),
It.IsAny()
)
)
.returns(Promise.resolve(mock))
.setup(instance =>
instance.post(
It.Is((path: string) => path.includes('files')),
It.IsAny()
)
)
.returns(
Promise.resolve({
data: {
items: mock.data.items.images
.map((_, n) => Array.from(Array(6).keys()).map(_ => ({ id: n, mimeType: 'image/jpeg' }) as FileInfo))
.flatMap(p => p)
},
headers: {},
status: 200
})
)
.setup(instance => instance.getBaseUrl())
.returns('https://example.com');

const provider = new Cdf360CdmDescriptorProvider(sdkMock.object());

const descriptors = await provider.get360ImageDescriptors(
{
source: 'cdm',
space: 'christjt-test-system-360',
image360CollectionExternalId: 'c_RC_2'
},
true
);

expect(descriptors.length).toBe(3);
});
});
Loading

0 comments on commit 1f9db64

Please sign in to comment.