Skip to content

Commit

Permalink
Merge refs/heads/master into renovate/serde-1.x
Browse files Browse the repository at this point in the history
  • Loading branch information
cognite-bulldozer[bot] authored Jul 17, 2023
2 parents 2b10c2d + 5dedfc3 commit a1616a8
Show file tree
Hide file tree
Showing 20 changed files with 924 additions and 70 deletions.
3 changes: 3 additions & 0 deletions examples/src/pages/Viewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -471,8 +471,11 @@ export function Viewer() {
new THREE.SphereGeometry(0.1),
new THREE.MeshBasicMaterial({ color: 'red' })
);

sphere.position.copy(point);
viewer.addObject3D(sphere);

pointCloudObjectsUi.createModelAnnotation(point, model);
}
}
break;
Expand Down
51 changes: 49 additions & 2 deletions examples/src/utils/PointCloudObjectStylingUI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export class PointCloudObjectStylingUI {
creatingUser: '',
assetRef: 0
};
private _createAnnotationsOnClick = false;

constructor(uiFolder: dat.GUI, model: CognitePointCloudModel, viewer: Cognite3DViewer, client: CogniteClient) {
this._model = model;
Expand All @@ -53,10 +54,20 @@ export class PointCloudObjectStylingUI {
this.createAnnotationUi(this._selectedAnnotationFolder);

const state = {
showBoundingBoxes: false
showBoundingBoxes: false,
createAnnotationsOnClick: false
};

const actions = {
deleteAllAnnotations: async () => {
const annotations = await client.annotations
.list({ filter: { annotatedResourceIds: [{ id: model.modelId }], annotatedResourceType: 'threedmodel' } })
.autoPagingToArray({ limit: 1000 });

await client.annotations.delete(annotations.map(annotation => ({ id: annotation.id })));

console.log(`Deleted ${annotations.length} annotations`);
},
reset: () => {
this._model.removeAllStyledObjectCollections();
},
Expand All @@ -76,12 +87,48 @@ export class PointCloudObjectStylingUI {
}
};

uiFolder.addFolder('DANGER ZONE').add(actions, 'deleteAllAnnotations').name('Delete all annotations for model');
uiFolder.add(actions, 'reset').name('Reset all styled objects');
uiFolder.add(actions, 'randomColors').name('Set random for objects');
uiFolder.add(actions, 'randomColors').name('Set random colors for objects');
uiFolder
.add(state, 'showBoundingBoxes')
.name('Show object bounding boxes')
.onChange((value: boolean) => this.toggleObjectBoundingBoxes(value));
uiFolder
.add(state, 'createAnnotationsOnClick')
.name('Create annotations on model click')
.onChange((value: boolean) => (this._createAnnotationsOnClick = value));
}

async createModelAnnotation(position: THREE.Vector3, model: CognitePointCloudModel) {
if (!this._createAnnotationsOnClick) return;

const cdfPosition = position.clone().applyMatrix4(model.getCdfToDefaultModelTransformation().invert());

const annotation = await this._client.annotations.create([
{
annotatedResourceId: model.modelId,
annotatedResourceType: 'threedmodel',
annotationType: 'pointcloud.BoundingVolume',
status: 'suggested',
creatingApp: 'reveal-examples',
creatingUser: 'reveal-user',
creatingAppVersion: '0.0.1',
data: {
label: 'Dummy annotation',
region: [
{
box: {
matrix: new THREE.Matrix4().makeTranslation(cdfPosition.x, cdfPosition.y, cdfPosition.z).transpose()
.elements
}
}
]
}
}
]);

console.log('Annotation successfully created', annotation);
}

async updateSelectedAnnotation(annotationId: number | undefined) {
Expand Down
2 changes: 2 additions & 0 deletions react-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@storybook/react": "7.0.26",
"@storybook/react-webpack5": "7.0.26",
"@storybook/testing-library": "0.2.0",
"@tanstack/react-query-devtools": "^4.29.19",
"@types/lodash": "^4.14.190",
"@types/react": "18.2.7",
"@types/styled-components": "5.1.26",
Expand Down Expand Up @@ -69,6 +70,7 @@
"dist"
],
"dependencies": {
"@tanstack/react-query": "^4.29.19",
"lodash": "^4.17.21",
"style-loader": "^3.3.3"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,52 @@
/*!
* Copyright 2023 Cognite AS
*/
import { type ReactElement, useEffect, useRef } from 'react';
import { type AddModelOptions, type CogniteCadModel } from '@cognite/reveal';
import { type ReactElement, useEffect, useState } from 'react';
import {
type NodeAppearance,
type AddModelOptions,
type CogniteCadModel,
TreeIndexNodeCollection,
NodeIdNodeCollection,
DefaultNodeAppearance
} from '@cognite/reveal';
import { useReveal } from '../RevealContainer/RevealContext';
import { type Matrix4 } from 'three';
import { useSDK } from '../RevealContainer/SDKProvider';
import { type CogniteClient } from '@cognite/sdk';

type Cognite3dModelProps = {
export type NodeStylingGroup = {
nodeIds: number[];
style?: NodeAppearance;
};

export type TreeIndexStylingGroup = {
treeIndices: number[];
style?: NodeAppearance;
};

export type CadModelStyling = {
defaultStyle?: NodeAppearance;
groups?: Array<NodeStylingGroup | TreeIndexStylingGroup>;
};

type CogniteCadModelProps = {
addModelOptions: AddModelOptions;
styling?: CadModelStyling;
transform?: Matrix4;
onLoad?: () => void;
onLoad?: (model: CogniteCadModel) => void;
};

export function CadModelContainer({
addModelOptions,
transform,
styling,
onLoad
}: Cognite3dModelProps): ReactElement {
const modelRef = useRef<CogniteCadModel>();
}: CogniteCadModelProps): ReactElement {
const [model, setModel] = useState<CogniteCadModel>();
const viewer = useReveal();
const sdk = useSDK();

const { modelId, revisionId, geometryFilter } = addModelOptions;

useEffect(() => {
Expand All @@ -27,29 +55,67 @@ export function CadModelContainer({
}, [modelId, revisionId, geometryFilter]);

useEffect(() => {
if (modelRef.current === undefined || transform === undefined) return;
modelRef.current.setModelTransformation(transform);
}, [transform]);
if (model === undefined || transform === undefined) return;
model.setModelTransformation(transform);
}, [transform, model]);

useEffect(() => {
if (model === undefined || styling === undefined) return;

applyStyling(sdk, model, styling).catch(console.error);

return () => {
model.removeAllStyledNodeCollections();
model.setDefaultNodeAppearance(DefaultNodeAppearance.Default);
};
}, [styling, model]);

return <></>;

async function addModel(
modelId: number,
revisionId: number,
transform?: Matrix4,
onLoad?: () => void
): Promise<void> {
onLoad?: (model: CogniteCadModel) => void
): Promise<CogniteCadModel> {
const cadModel = await viewer.addCadModel({ modelId, revisionId });
if (transform !== undefined) {
cadModel.setModelTransformation(transform);
}
modelRef.current = cadModel;
onLoad?.();
setModel(cadModel);
onLoad?.(cadModel);

return cadModel;
}

function removeModel(): void {
if (modelRef.current === undefined || !viewer.models.includes(modelRef.current)) return;
viewer.removeModel(modelRef.current);
modelRef.current = undefined;
if (model === undefined || !viewer.models.includes(model)) return;
viewer.removeModel(model);
setModel(undefined);
}
}

async function applyStyling(
sdk: CogniteClient,
model: CogniteCadModel,
styling?: CadModelStyling
): Promise<void> {
if (styling === undefined) return;

if (styling.defaultStyle !== undefined) {
model.setDefaultNodeAppearance(styling.defaultStyle);
}

if (styling.groups !== undefined) {
for (const group of styling.groups) {
if ('treeIndices' in group && group.style !== undefined) {
const nodes = new TreeIndexNodeCollection(group.treeIndices);
model.assignStyledNodeCollection(nodes, group.style);
} else if ('nodeIds' in group && group.style !== undefined) {
const nodes = new NodeIdNodeCollection(sdk, model);
await nodes.executeFilter(group.nodeIds);
model.assignStyledNodeCollection(nodes, group.style);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,41 @@
import { type ReactElement, useEffect, useContext, useRef } from 'react';
import { useReveal } from '../RevealContainer/RevealContext';
import { ModelsLoadingStateContext } from '../Reveal3DResources/ModelsLoadingContext';
import { type CameraState } from '@cognite/reveal';
import {
DefaultCameraManager,
type CameraControlsOptions,
type CameraState
} from '@cognite/reveal';

export type CameraControllerProps = {
initialFitCamera?: FittingStrategy;
cameraControlsOptions?: CameraControlsOptions;
};

type FittingStrategy =
| { to: 'cameraState'; state: CameraState }
| { to: 'allModels' }
| { to: 'none' };

export function CameraController({ initialFitCamera }: CameraControllerProps): ReactElement {
export function CameraController({
initialFitCamera,
cameraControlsOptions
}: CameraControllerProps): ReactElement {
const initialCameraSet = useRef(false);
const viewer = useReveal();
const { modelsAdded } = useContext(ModelsLoadingStateContext);

const fittingStrategy: Required<FittingStrategy> = initialFitCamera ?? { to: 'allModels' };

useEffect(() => {
if (cameraControlsOptions === undefined) return;

if (!(viewer.cameraManager instanceof DefaultCameraManager))
throw new Error('CameraControlsOptions can be set only on default CameraManager');

viewer.cameraManager.setCameraControlsOptions(cameraControlsOptions);
}, [cameraControlsOptions]);

useEffect(() => {
if (initialCameraSet.current) return;
if (fittingStrategy.to === 'none') {
Expand All @@ -34,7 +51,7 @@ export function CameraController({ initialFitCamera }: CameraControllerProps): R
return;
}
if (fittingStrategy.to === 'allModels' && modelsAdded) {
viewer.fitCameraToModels(viewer.models, 0, true);
viewer.fitCameraToModels(undefined, undefined, true);
initialCameraSet.current = true;
}
}, [modelsAdded]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { type Image360Collection } from '@cognite/reveal';

type Image360CollectionContainerProps = {
siteId: string;
onLoad?: () => void;
onLoad?: (image360: Image360Collection) => void;
};

export function Image360CollectionContainer({
Expand All @@ -27,7 +27,7 @@ export function Image360CollectionContainer({
async function add360Collection(): Promise<void> {
const image360Collection = await viewer.add360ImageSet('events', { site_id: siteId });
modelRef.current = image360Collection;
onLoad?.();
onLoad?.(image360Collection);
}

function remove360Collection(): void {
Expand Down
Loading

0 comments on commit a1616a8

Please sign in to comment.