Skip to content

Commit

Permalink
Update point cloud feature branch from master (#2416)
Browse files Browse the repository at this point in the history
  • Loading branch information
haakonflatval-cognite authored Sep 9, 2022
1 parent 8795a53 commit 0e754a9
Show file tree
Hide file tree
Showing 257 changed files with 4,791 additions and 10,544 deletions.
61 changes: 10 additions & 51 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ on:
jobs:
build-viewer:
name: Build Reveal
runs-on: ubuntu-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

Expand Down Expand Up @@ -53,25 +53,18 @@ jobs:
working-directory: viewer
run: yarn run build

- name: Upload dist/ artifact
- name: Upload dist/ artifact
uses: actions/upload-artifact@v3
with:
name: viewer
path: viewer/dist/

run-coverage-tests:
name: Run unit tests
runs-on: ubuntu-latest
needs: build-viewer
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Download viewer build artifact
uses: actions/download-artifact@v3
with:
name: viewer
path: viewer/dist/

- uses: actions/cache@v2
id: npm_cache
with:
Expand Down Expand Up @@ -128,7 +121,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
msg: |
There were failures in the Visual regression tests workflow.
There were failures in the visual tests workflow.
Image diffs for visual tests can be downloaded as an artifact [here](https://github.com/cognitedata/reveal/actions/runs/${{ github.run_id }}).
- name: Upload image diffs for failed visual tests
Expand All @@ -146,12 +139,12 @@ jobs:
ci-examples:
name: Examples
runs-on: ubuntu-latest
runs-on: ubuntu-latest
needs: build-viewer
steps:
- uses: actions/checkout@v3

- name: Download viewer build artifact
- name: Download viewer build artifact
uses: actions/download-artifact@v3
with:
name: viewer
Expand All @@ -174,44 +167,10 @@ jobs:
# if: steps.npm_cache.outputs.cache-hit != 'true'
working-directory: examples
run: yarn install --immutable

- name: Increase number of inotify watches
run: 'echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p'

# Disabled because visual tests also builds examples
# - name: Build examples
# working-directory: examples
# run: |
# echo "NODE_OPTIONS=--max-old-space-size=8192" >> $GITHUB_ENV
# yarn build

- name: Visual regression tests
id: visualtests
working-directory: examples
run: 'yarn ci:e2e'
continue-on-error: true

- name: Check for failed visual test diffs
if: (always() && steps.visualtests.outcome == 'failure')
- name: Build examples
working-directory: examples
run: |
yarn
yarn test:ghprcomment
env:
ACTIONS_RUNTIME_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Upload image diffs for failed visual tests
if: (always() && steps.visualtests.outcome == 'failure')
uses: actions/upload-artifact@v3
with:
name: image-diffs-${{ github.sha }}
path: examples/src/visual_tests/__image_snapshots__/__diff_output__/*

- name: Report failed visual tests
if: (always() && steps.visualtests.outcome == 'failure')
run: |
echo There are failed visual tests, please inspect test results.
exit 1
run: yarn build

# runs only when there are changes in parser-worker/
# we use it here because github haven't figured out conditionally required checks
Expand Down Expand Up @@ -345,7 +304,7 @@ jobs:
yarn install --immutable
yarn build:fast
- name: Upload documentation artifact
- name: Upload documentation artifact
uses: actions/upload-artifact@v3
with:
name: preview-docs
Expand All @@ -364,7 +323,7 @@ jobs:
run: |
echo "PR_NUMBER=$(jq --raw-output .pull_request.number $GITHUB_EVENT_PATH)" >> $GITHUB_ENV
- name: Download documentation artifact
- name: Download documentation artifact
uses: actions/download-artifact@v3
if:
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ target

**/.env
**/.env.*
**/.cdf-environments.json
!**/.env.example

# Viewer ignores
Expand Down
160 changes: 160 additions & 0 deletions documentation/docs/examples/point-to-point-measurement.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
---
id: point-to-point-measurement
title: Point to point measurement
description: Demo shows how to measure point to point distance in Reveal.
---

import { DemoWrapper } from '@site/docs/components/DemoWrapper';
import useBaseUrl from '@docusaurus/useBaseUrl';

The `MeasurementTool` is a measuring tool for point to point distance in 3D models, by clicking to- and from-points. The default measurement unit is meters, but the tool provides callbacks to allow configuring the unit.
When exiting from the tool, all the measurement will be removed from the `Cognite3DViewer`. Note that the precision the tool can provide is limited, and the tool should only be used for approximate measurement - not high precision measurement for e.g. construction.

To effectively edit measuring line properties, tool is configurable with `MeasurementOptions` options to set
- Custom label content for each measurement.
- Size of line width in meters.
- Color of line.

:::tip
`CameraControlsOptions.changeCameraTargetOnClick` should be set to `false` to avoid click event registering for camera when `MeasurementTool` is active. Also avoid any custom click-handler that might interfere with the measurement tool.
:::

<DemoWrapper name="Cognite3DViewerDemo" />

## Point to point distance measurment
To enter point-to-point measurement mode, use `MeasurementTool.enterMeasurementMode()`. This will register events for handling mouse clicks and touch events to allow placing the measurement end-points. Note that the tool is optimized for use with mouse.

To exit measurement mode, call `exitMeasurementMode()`. The tool will also exit measurement mode if user presses Escape key.

```jsx runnable
// import { MeasurementTool } from '@cognite/reveal/tools';

const measurementTool = new MeasurementTool(viewer);
measurementTool.enterMeasurementMode();
```

## Events
The tool exposes events for subscribing to measurement start, end & added. In the below example, the mouse cursor is changed to a cross-hair while measuring.

```jsx runnable
// import { MeasurementTool } from '@cognite/reveal/tools';
const measurementTool = new MeasurementTool(viewer);

// Subscribe to measurement events
measurementTool.on('started',
() => viewer.domElement.style.cursor = 'crosshair');
measurementTool.on('ended',
() => viewer.domElement.attributeStyleMap.delete('cursor'));
measurementTool.on('added', (measurement) => {
alert(`Measurement added with ${JSON.stringify(measurement.distanceInMeters)} distance!`);
measurementTool.exitMeasurementMode();
});

measurementTool.enterMeasurementMode();
```



### Mode of measurement
To get the mode of measurement `MeasurementTool.isInMeasurementMode`. It returns `true` if the measurement is active else `false`.


## Set width, color & label units of the measuring line
To change width, color of the line and label units, use `MeasurementTool.setLineOptions(options: MeasurementOptions)`. MeasurementOptions expects
- `distanceToLabelCallback` : callback for custom operation on measurement labels
- `lineWidth` : number - units in meters
- `color` : THREE.color

The updated line width, color and label units will be applied for the next measuring distance.

```jsx runnable
// import { MeasurementTool } from '@cognite/reveal/tools';

const lineOptions = {
distanceToLabelCallback: (distanceInMeters) => {
// 1 meter = 100 centimeter
return `${(distanceInMeters * 100).toFixed(2)} cm`;
},
lineWidth: 0.1,
color: new THREE.Color(0xff0000)
};
const measurementTool = new MeasurementTool(viewer);
measurementTool.enterMeasurementMode();

//Update line width, color and label units for the next measuring line.
measurementTool.setLineOptions(lineOptions);
```

### Get all measurement
To get all measurements added the tool provides `MeasurementTool.getAllMeasurements()` which will
return an array of measurements of type `Measurement`, having below details
- `measurementId` : unique id of measurement.
- `startPoint` : start point of the measurement.
- `endPoint` : end point of the measurement.
- `distanceInMeters` : measured distance in meters.
```jsx runnable
// import { MeasurementTool } from '@cognite/reveal/tools';

const measurementTool = new MeasurementTool(viewer);
measurementTool.enterMeasurementMode();

//add measurements

//get all measurements
setTimeout(() => {
const measurements = measurementTool.getAllMeasurements();
measurements.forEach(measurement => {
alert(measurement.distanceInMeters);
});
}, 6000);
```

### Change appearance of existing measurement
To change existing measurement line width or color, use `MeasurementTool.updateLineWidth(lineWidth: number)` or `MeasurementTool.updateLineColor(color: THREE.Color)`

```jsx runnable
// import { MeasurementTool } from '@cognite/reveal/tools';

const measurementTool = new MeasurementTool(viewer);
setInterval(() => {
const measurements = measurementTool.getAllMeasurements();
console.log(measurements);
for (const measurement of measurements) {
const color = Math.floor(Math.random() * 16777215);
const lineWidth = (Math.random() * 1.0) + 0.2;
measurementTool.updateLineColor(measurement, new THREE.Color(color));
measurementTool.updateLineWidth(measurement, lineWidth);
}
}, 200);
measurementTool.enterMeasurementMode();
```

### Remove measurement
To remove a measurement from the viewer, we have `MeasurementTool.removeMeasurement(measurement: Measurement)`
- `measurement` : Measurement to be removed.

```jsx runnable
// import { MeasurementTool } from '@cognite/reveal/tools';

const measurementTool = new MeasurementTool(viewer);
measurementTool.enterMeasurementMode();

//remove the first measurement in the added list
setTimeout(() => {
const measurements = measurementTool.getAllMeasurements();

if (measurements[0]) {
measurementTool.removeMeasurement(measurements[0]);
}
}, 6000);
```

To remove all measurement from the viewer, use `MeasurementTool.removeAllMeasurement()`

### Label visibility
Measurement labels can be hidden/visible using `MeasurementTool.showMeasurementLabels(enable: boolean)`.
```jsx
// Hide all measurement lables
measurementTool.showMeasurementLabels(false);
```

28 changes: 26 additions & 2 deletions documentation/docs/examples/pointcloud.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ title: Pointcloud models
description: Usage of pointcloud models with Cognite3DViewer
---

`@cognite/reveal` supports point clouds through a third-party library, [`potree-core`](https://github.com/tentone/potree-core). The viewer
supports loading both point clouds and CAD models at the same time. Point clouds can be generated from various sources including
import useBaseUrl from '@docusaurus/useBaseUrl';

`@cognite/reveal` supports point clouds through a third-party library, [`three-loader`](https://github.com/pnext/three-loader) that is
included in the Reveal codebase and modified for our needs. Most of the internal point cloud logic is based on [`potree`](https://github.com/potree/potree/).
The viewer supports loading both point clouds and CAD models at the same time. Point clouds can be generated from various sources including
[laser scans](https://en.wikipedia.org/wiki/Laser_scanning) and [photogrammetry models](https://en.wikipedia.org/wiki/Photogrammetry).
Loading point clouds is done with identical code to when [loading CAD models](./cad-basic) - Reveal will determine that the model
is a point cloud model and act accordingly.
Expand Down Expand Up @@ -88,6 +91,27 @@ model.pointColorType = PotreePointColorType.Depth;
Other useful coloring schemes are `Rgb` (color) , `Classification` (color by point class) and `Intensity`
(strength of the backscattered signal in a laser scan).

## Point cloud post processing effects

Users can enable various post processing effects for point cloud rendering. One of them is the "point blending" effect
which produces a more "stable" rendering of surfaces within the point cloud model but it comes with a cost of
decreased performance.

<a target='_blank' href={useBaseUrl('/img/point-blending.jpg')}>
<img src={useBaseUrl('/img/point-blending.jpg')} alt="Illustration of point blending effect" />
</a>

You can enable the described effect by passing a corresponding property on initialization of `Cognite3DViewer`:
```jsx
const viewer = new Cognite3DViewer(
{
sdk: client,
pointCloudEffects: {
pointBlending: true
}
});
```

## Classification filtering

Some point clouds have classification information associated with each point. This can
Expand Down
23 changes: 14 additions & 9 deletions documentation/docs/extending/camera-manager.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ In certain cases it can be useful to customize behaviour of the camera:
## Overview

To create a custom camera manager class, `CameraManager` interface from `@cognite/reveal` must be implemented
and provided to `Cognite3DViewer` on construction using the `cameraManager`-option. Interface looks like this:
and provided to `Cognite3DViewer` on construction using the `cameraManager`-option. You can also set camera manager
in runtime by calling `setCameraManager` method of `Cognite3DViewer` class. Interface looks like this:

```js
export interface CameraManager {
Expand Down Expand Up @@ -96,7 +97,7 @@ When implementing these functions you can use a helper class `CameraManagerHelpe
Here is an example implementation of a custom camera manager that utilizes standard ThreeJS [`OrbitControls`](https://threejs.org/docs/index.html?q=orbit#examples/en/controls/OrbitControls) for mouse movement:

```js
import * as THREE from 'three';
import { THREE } from '@cognite/reveal';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

import { CameraManager, CameraManagerHelper, CameraState, CameraChangeDelegate } from '@cognite/reveal';
Expand All @@ -115,19 +116,24 @@ export class CustomCameraManager implements CameraManager {
this._controls.dampingFactor = 0.3;

this._controls.addEventListener('change', () => {
this._cameraChangedListener.forEach( cb => cb(this._camera.position,
this._controls.target));
this._cameraChangedListener.forEach( cb => cb(this._camera.position, this._controls.target));
});
}

set enabled(value: boolean) {
this._controls.enabled = value;
}

get enabled(): boolean {
return this._controls.enabled;
}

getCamera(): THREE.PerspectiveCamera {
return this._camera;
}

setCameraState(state: CameraState): void {
if (state.rotation && state.target) throw
new Error("Can't set both rotation and target");

if (state.rotation && state.target) throw new Error("Can't set both rotation and target");
const position = state.position ?? this._camera.position;
const rotation = state.rotation ?? this._camera.quaternion;
const target = state.target ?? ( state.rotation ?
Expand Down Expand Up @@ -160,8 +166,7 @@ export class CustomCameraManager implements CameraManager {
}

fitCameraToBoundingBox(boundingBox: THREE.Box3, duration?: number, radiusFactor?: number): void {
const { position, target } = CameraManagerHelper
.calculateCameraStateToFitBoundingBox(this._camera, boundingBox, radiusFactor);
const { position, target } = CameraManagerHelper.calculateCameraStateToFitBoundingBox(this._camera, boundingBox, radiusFactor);

this.setCameraState({ position, target });
}
Expand Down
Loading

0 comments on commit 0e754a9

Please sign in to comment.