Skip to content

Commit

Permalink
feat: point cloud styling (#2569)
Browse files Browse the repository at this point in the history
* feat: Add ability to style objects in point clouds (#2104)

* feat: point cloud API for styling (#2179)

* feat: Webassembly setup (#2353)

* Update point cloud feature branch from master (#2416)

* feat: Rust/Webassembly octree implementation for faster point-object assignment (#2327)

* feat: custom classification (#2320)

* docs: finalize point cloud styling docs (#2500)

* refactor: move point cloud object provider to data-providers and expose object bounding boxes (#2522)

* fix: point cloud custom transformation (#2550)

* improvement: various fixes for point clouds (#2551)

* fix: export point cloud object metadata (#2552)

* Various big and small fixes

Co-authored-by: Lars Moastuen <lars.moastuen@cognite.com>
Co-authored-by: Christopher J. Tannum <christopher.tannum@cognite.com>
Co-authored-by: Savokr <savelii.novikov@cognite.com>
Co-authored-by: Pramod S <87521752+pramodcog@users.noreply.github.com>
  • Loading branch information
5 people authored Oct 18, 2022
1 parent a0108f7 commit 50ba964
Show file tree
Hide file tree
Showing 144 changed files with 5,394 additions and 562 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ jobs:
continue-on-error: false
run: yarn run lint

- name: Rust fmt
working-directory: viewer
continue-on-error: false
run: |
rustup component add rustfmt
cargo fmt --check
# Skip to save time - development version is enough
# - name: Build prod version
# working-directory: viewer
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Generated by Cargo
# will have compiled files and executables
target
**/wasm/pkg/

**/.DS_Store
**/dist
Expand Down
17 changes: 17 additions & 0 deletions documentation/docs/examples/click-reactions-pointcloud.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,20 @@ viewer.on('click', async event => {
};
});
```

## Getting information about object assigned to a clicked point
Using Cognite's Annotations API, a user can define objects within a point cloud model.
In order to retrieve information about a clicked object, users may get the `annotationId` that is assigned to each point.
The `annotationId` is available in the `intersection` object returned from `viewer.getIntersectionFromPixel`.
An annotation id of 0 means that the clicked point is not assigned to any object.

```js runnable
viewer.on('click', async event => {
const intersection = await viewer.getIntersectionFromPixel(
event.offsetX, event.offsetY
);
if (intersection) {
alert(`Clicked object: ${intersection.annotationId}`);
};
});
```
91 changes: 91 additions & 0 deletions documentation/docs/examples/pointcloud-styling.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
id: pointcloud-styling
title: Pointcloud styling
description: Usage of the styling API for pointcloud models
---

Cognite Data Fusion has a concept of "objects" in point clouds, represented by one or more bounding volumes for
each object. The objects are backed by the [CDF Annotations API](https://docs.cognite.com/api/v1/#tag/Annotations).
Reveal supports styling individual objects within a point cloud.

import { DemoWrapper } from '@site/versioned_docs/version-4.x/components/DemoWrapper';

<DemoWrapper modelType="pointcloud" />

In this context, a _stylable object_ is represented by a volume in space. Styling an object results in all points that lie within the corresponding volume to attain the assigned style.

Stylable objects must be supplied separately from the model itself. Upon adding a new point cloud model to the viewer, Reveal will automatically fetch data describing the point cloud objects from CDF's Annotations API, if any are available. To get the number of fetched stylable objects, use the property `model.stylableObjectCount`, where `model` is a `CognitePointCloudModel`.

After the model and associated stylable objects are loaded, you may list the objects using `model.traverseStylableObjects`. This method traverses all objects as instances of `PointCloudObjectMetadata`, containing the following fields:

| Field | Field type | Description |
|----------------------------|---------------------------------|---------------------------------------------------------------------------------------|
| `annotationId` | `number` | The ID of the CDF annotation that this stylable object corresponds to. |
| `assetId` | `number?` | The ID of the CDF asset associated with the annotation, if any. |
| `boundingBox` | `THREE.Box3` | The bounding box of the stylable object in Reveal space. |

To visualize all bounding boxes associated with the stylable objects:

```js runnable
const boxGroup = new THREE.Group();

model.traverseStylableObjects(obj => boxGroup.add(new THREE.Box3Helper(obj.boundingBox)));

viewer.addObject3D(boxGroup);
```

Point cloud objects can be styled with a `PointCloudAppearance` object, containing the following attributes:

| Field | Field type | Description |
|----------------------------|---------------------------------|---------------------------------------------------------------------------------------|
| `color` | `[number, number, number]?` | Override color by setting RGB values in range [0,255]. `[0, 0, 0]` means no override. |
| `visible` | `boolean?` | When false, stylable object will be invisible. Default value is `true`. |

To assign a style to one or more stylable objects, you must first create an instance of the abstract class `PointCloudObjectCollection`. Currently, the only implementation of this class provided by Reveal is `AnnotationIdPointCloudObjectCollection`, which is initialized with a list of annotation IDs corresponding to stylable objects. To see all available annotation IDs associated with the model, you may use the method `model.traverseStylableObjects`.

To color all stylable objects green:

```js runnable
const annotationIds = [];

model.traverseStylableObjects(objectMetadata => annotationIds.push(objectMetadata.annotationId));

const objectCollection = new AnnotationIdPointCloudObjectCollection(annotationIds);
const appearance = { color: [0, 255, 0] };

model.assignStyledObjectCollection(objectCollection, appearance);
```

After assigning style to an object collection, you may use the property `model.styledCollections` to get a list of all object collections and their assigned styles registered on the model.

## Default appearance

It is also possible to set a default appearance for the point cloud using the `model.setDefaultPointCloudAppearance`. The following example makes all annotated objects visible, while hiding everything else:

```js runnable
const annotationIds = [];

model.traverseStylableObjects(annotationMetadata => annotationIds.push(annotationMetadata.annotationId));

const objectCollection = new AnnotationIdPointCloudObjectCollection(annotationIds);
const appearance = { visible: true };

model.assignStyledObjectCollection(objectCollection, appearance);
model.setDefaultPointCloudAppearance({ visible: false });
```

Like in CAD styling, stylable objects that are part of multiple styled object collections will attain the appearance of the object set whose first style assignment was last.

## Unassigning styled object collections

To reset style of an object collection, use `model.unassignStyledObjectCollection` with the previously styled `PointCloudObjectCollection` as argument. To reset all styled objects use `model.removeAllStyledCollections`

## Reset all styled object collections

To reset all styled object collections, use the method `model.removeAllStyledObjectCollections()`.

This example removes all style on stylable object collections and makes sure the rest of the point cloud is visible.
```js runnable
model.removeAllStyledObjectCollections();
model.setDefaultPointCloudAppearance({ visible: true });
```
3 changes: 2 additions & 1 deletion documentation/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module.exports = {
collapsed: false,
items: [
'examples/cad-basic',
'examples/pointcloud',
{
"Styling CAD models": [
'examples/cad-styling',
Expand All @@ -26,14 +27,14 @@ module.exports = {
'examples/cad-styling-custom',
]
},
'examples/pointcloud-styling',
'examples/cad-prioritized-nodes',
'examples/cad-transform-override',
'examples/cad-2doverlay',
'examples/cad-3dobjects',
'examples/node-visiting',
'examples/clipping',
'examples/cad-save-viewerstate',
'examples/pointcloud',
'examples/click-reactions-cad',
'examples/click-reactions-pointcloud',
'examples/antialiasing',
Expand Down
5 changes: 5 additions & 0 deletions documentation/src/plugins/remark-runnable-reveal-demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ const versionedImportNode = {
type: 'import',
value:
"import { LiveCodeSnippet } from '@site/versioned_docs/version-3.x/components/LiveCodeSnippet';",
},
'runnable-4x': {
type: 'import',
value:
"import { LiveCodeSnippet } from '@site/versioned_docs/version-4.x/components/LiveCodeSnippet';",
}
};

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions documentation/versioned_sidebars/version-4.x-sidebars.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 48 additions & 1 deletion documentation/yarn.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions examples/src/pages/Viewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { PointCloudUi } from '../utils/PointCloudUi';
import { ModelUi } from '../utils/ModelUi';
import { createSDKFromEnvironment } from '../utils/example-helpers';
import { PointCloudClassificationFilterUI } from '../utils/PointCloudClassificationFilterUI';
import { PointCloudObjectStylingUI } from '../utils/PointCloudObjectStylingUI';
import { CustomCameraManager } from '../utils/CustomCameraManager';
import { MeasurementUi } from '../utils/MeasurementUi';

Expand Down Expand Up @@ -183,8 +184,10 @@ export function Viewer() {
new NodeStylingUI(gui.addFolder(`Node styling #${modelUi.cadModels.length}`), client, viewer, model);
new BulkHtmlOverlayUI(gui.addFolder(`Node tagging #${modelUi.cadModels.length}`), viewer, model, client);
} else if (model instanceof CognitePointCloudModel) {
new PointCloudClassificationFilterUI(gui.addFolder(`Class filter #${modelUi.pointCloudModels.length}`), model);
const modelIndex = modelUi.pointCloudModels.length
new PointCloudClassificationFilterUI(gui.addFolder(`Class filter #${modelIndex}`), model);
pointCloudUi.applyToAllModels();
new PointCloudObjectStylingUI(gui.addFolder(`Point cloud object styling #${modelIndex}`), model, viewer);
}
}
const modelUi = new ModelUi(gui.addFolder('Models'), viewer, handleModelAdded);
Expand Down Expand Up @@ -338,8 +341,11 @@ export function Viewer() {
break;
case 'pointcloud':
{
const { pointIndex, point } = intersection;
console.log(`Clicked point with pointIndex ${pointIndex} at`, point);
const { point } = intersection;
console.log(`Clicked point assigned to the object with annotationId: ${intersection.annotationId} at`, point);
const sphere = new THREE.Mesh(new THREE.SphereGeometry(0.1), new THREE.MeshBasicMaterial({ color: 'red' }));
sphere.position.copy(point);
viewer.addObject3D(sphere);
}
break;
}
Expand Down
Loading

0 comments on commit 50ba964

Please sign in to comment.