Skip to content

Commit

Permalink
Merge pull request #113 from PaulHax/camera-2d
Browse files Browse the repository at this point in the history
View 2D: Reset camera with viewport aspect ratio
  • Loading branch information
thewtex authored Jan 31, 2024
2 parents 278151a + ab5836a commit 2529b54
Show file tree
Hide file tree
Showing 37 changed files with 773 additions and 582 deletions.
12 changes: 12 additions & 0 deletions .changeset/clever-peaches-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@itk-viewer/remote-viewport': patch
'@itk-viewer/blosc-zarr': patch
'@itk-viewer/arcball': patch
'@itk-viewer/element': patch
'@itk-viewer/viewer': patch
'@itk-viewer/utils': patch
'@itk-viewer/vtkjs': patch
'@itk-viewer/io': patch
---

Add orthographic camera and zooming to 2D view.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ micromamba/*
venv/*
packages/blosc-zarr/*
!packages/blosc-zarr/bloscZarrDecompress.js
.changesets/*
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"cy:component": "cypress run --component",
"cy:component:chrome": "cypress run --component --browser chrome",
"clean": "git clean -fdx",
"ci:publish": "pnpm publish -r --access public"
"ci:publish": "pnpm --filter=!vtk-js-transfer-function-example publish -r --access public"
},
"devDependencies": {
"@changesets/cli": "^2.27.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/blosc-zarr/bloscZarrDecompress.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
getPipelinesBaseUrl,
getPipelineWorkerUrl,
} from 'itk-wasm';
import { getSize } from '@itk-viewer/wasm-utils/dtypeUtils.js';
import { getSize } from '@itk-viewer/utils/dtypeUtils.js';

const cores = navigator.hardwareConcurrency ? navigator.hardwareConcurrency : 4;
const numberOfWorkers = cores + Math.floor(Math.sqrt(cores));
Expand Down
2 changes: 1 addition & 1 deletion packages/blosc-zarr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"typescript": "^5.3.3"
},
"dependencies": {
"@itk-viewer/wasm-utils": "workspace:^",
"@itk-viewer/utils": "workspace:^",
"itk-wasm": "1.0.0-b.160"
},
"eslintConfig": {
Expand Down
31 changes: 31 additions & 0 deletions packages/element/examples/compare.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Compare</title>
<link rel="stylesheet" href="index.css" />
<script type="module" src="../src/itk-viewer-element.ts"></script>
<script type="module" src="../src/itk-viewport.ts"></script>
<script type="module" src="../src/itk-view-2d.ts"></script>
<script type="module" src="../src/itk-view-2d-vtkjs.ts"></script>

<script type="module" src="./compare.ts"></script>
</head>

<body>
<itk-viewer class="fill" style="flex-direction: row; gap: 0.25rem">
<itk-viewport class="fill">
<itk-view-2d class="fill">
<itk-view-2d-vtkjs></itk-view-2d-vtkjs>
</itk-view-2d>
</itk-viewport>
<itk-viewport class="fill">
<itk-view-2d class="fill">
<itk-view-2d-vtkjs></itk-view-2d-vtkjs>
</itk-view-2d>
</itk-viewport>
</itk-viewer>
</body>
</html>
25 changes: 25 additions & 0 deletions packages/element/examples/compare.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ZarrMultiscaleSpatialImage } from '@itk-viewer/io/ZarrMultiscaleSpatialImage.js';
import { setPipelineWorkerUrl, setPipelinesBaseUrl } from 'itk-wasm';

const pipelineWorkerUrl = '/itk/web-workers/itk-wasm-pipeline.min.worker.js';
setPipelineWorkerUrl(pipelineWorkerUrl);
const pipelineBaseUrl = '/itk/pipelines';
setPipelinesBaseUrl(pipelineBaseUrl);

document.addEventListener('DOMContentLoaded', async function () {
const [v0, v1] = Array.from(document.querySelectorAll('itk-viewport')).map(
(el) => el.getActor(),
);
const camera = v0?.getSnapshot()?.context?.camera;
if (!camera) throw new Error('Could not get camera');
v1?.send({ type: 'setCamera', camera });

const imagePath = '/ome-ngff-prototypes/single_image/v0.4/zyx.ome.zarr';
const url = new URL(imagePath, document.location.origin);
const image = await ZarrMultiscaleSpatialImage.fromUrl(url);

const viewerElement = document.querySelector('itk-viewer');
if (!viewerElement) throw new Error('Could not find element');
const viewer = viewerElement.getActor();
viewer.send({ type: 'setImage', image, name: 'image' });
});
2 changes: 0 additions & 2 deletions packages/element/examples/view-2d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ setPipelinesBaseUrl(pipelineBaseUrl);

document.addEventListener('DOMContentLoaded', async function () {
const imagePath = '/ome-ngff-prototypes/single_image/v0.4/zyx.ome.zarr';
// const imagePath = '/astronaut.zarr';
const url = new URL(imagePath, document.location.origin);
const image = await ZarrMultiscaleSpatialImage.fromUrl(url);

const viewerElement = document.querySelector('itk-viewer');
if (!viewerElement) throw new Error('Could not find element');
const viewer = viewerElement.getActor();

viewer.send({ type: 'setImage', image, name: 'image' });
});
1 change: 1 addition & 0 deletions packages/element/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"@itk-viewer/remote-viewport": "workspace:^",
"@itk-viewer/viewer": "workspace:^",
"@itk-viewer/vtkjs": "workspace:^",
"@itk-viewer/utils": "workspace:^",
"@lit/context": "^1.1.0",
"gl-matrix": "^3.4.3",
"itk-wasm": "1.0.0-b.160",
Expand Down
2 changes: 0 additions & 2 deletions packages/element/src/itk-image-info-viewport.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ describe('ImageInfoViewport', () => {
<itk-image-info-viewport></itk-image-info-viewport>
</itk-viewer>
`);

cy.get('itk-viewer').shadow().contains('Viewer');
});

it('has image info', () => {
Expand Down
11 changes: 5 additions & 6 deletions packages/element/src/itk-remote-viewport-webrtc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@ import { Ref, createRef, ref } from 'lit/directives/ref.js';
import { SelectorController } from 'xstate-lit';
import { ActorRefFrom } from 'xstate';

import { Bounds } from '@itk-viewer/utils/bounding-box.js';
import { chunk } from '@itk-viewer/io/dimensionUtils.js';
import { viewportMachine } from '@itk-viewer/viewer/viewport.js';
import { Camera } from '@itk-viewer/viewer/camera.js';
import {
RemoteActor,
createHyphaMachineConfig,
createRemoteViewport,
Image,
} from '@itk-viewer/remote-viewport/remote-viewport.js';

import type { Image } from '@itk-viewer/remote-viewport/remote-viewport.js';

import { ItkViewport } from './itk-viewport.js';
import './itk-camera.js';
import { Bounds } from '@itk-viewer/io/types.js';
import { chunk } from '@itk-viewer/io/dimensionUtils.js';
import { viewportMachine } from '@itk-viewer/viewer/viewport.js';
import { Camera } from '@itk-viewer/viewer/camera.js';

type ViewportActor = ActorRefFrom<typeof viewportMachine>;

Expand Down
11 changes: 5 additions & 6 deletions packages/element/src/itk-remote-viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@ import { Ref, createRef, ref } from 'lit/directives/ref.js';
import { SelectorController } from 'xstate-lit';
import { ActorRefFrom } from 'xstate';

import { Bounds } from '@itk-viewer/utils/bounding-box.js';
import { chunk } from '@itk-viewer/io/dimensionUtils.js';
import { viewportMachine } from '@itk-viewer/viewer/viewport.js';
import { Camera } from '@itk-viewer/viewer/camera.js';
import {
RemoteActor,
createHyphaMachineConfig,
createRemoteViewport,
Image,
} from '@itk-viewer/remote-viewport/remote-viewport.js';

import type { Image } from '@itk-viewer/remote-viewport/remote-viewport.js';

import { ItkViewport } from './itk-viewport.js';
import './itk-camera.js';
import { Bounds } from '@itk-viewer/io/types.js';
import { chunk } from '@itk-viewer/io/dimensionUtils.js';
import { viewportMachine } from '@itk-viewer/viewer/viewport.js';
import { Camera } from '@itk-viewer/viewer/camera.js';

type ViewportActor = ActorRefFrom<typeof viewportMachine>;

Expand Down
1 change: 0 additions & 1 deletion packages/element/src/itk-viewer-element.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@ import './itk-viewer-element';
describe('Lit mount', () => {
it('mounts', () => {
cy.mount<'itk-viewer'>(html`<itk-viewer image="url"></itk-viewer>`);
cy.get('itk-viewer').shadow().contains('Viewer');
});
});
5 changes: 1 addition & 4 deletions packages/element/src/itk-viewer-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ export class ItkViewer extends LitElement {
}

render() {
return html`
<h1>Viewer</h1>
<slot @viewport=${handleLogic(this.actor)}></slot>
`;
return html`<slot @viewport=${handleLogic(this.actor)}></slot>`;
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/io/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
},
"dependencies": {
"@itk-viewer/blosc-zarr": "workspace:^",
"@itk-viewer/wasm-utils": "workspace:^",
"@itk-viewer/utils": "workspace:^",
"axios": "^1.6.3",
"gl-matrix": "^3.4.3",
"itk-wasm": "1.0.0-b.160",
Expand Down
2 changes: 1 addition & 1 deletion packages/io/src/ImageDataFromChunks.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
ElementGetter,
getSize,
testLittleEndian,
} from '@itk-viewer/wasm-utils/dtypeUtils.js';
} from '@itk-viewer/utils/dtypeUtils.js';

const haveSharedArrayBuffer = typeof self.SharedArrayBuffer === 'function';

Expand Down
6 changes: 2 additions & 4 deletions packages/io/src/MultiscaleSpatialImage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
import { ImageType, TypedArray } from 'itk-wasm';
import WebworkerPromise from 'webworker-promise';

import { getDtype } from '@itk-viewer/wasm-utils/dtypeUtils.js';

import { getDtype } from '@itk-viewer/utils/dtypeUtils.js';
import { Bounds, ReadonlyBounds } from '@itk-viewer/utils/bounding-box.js';
import { componentTypeToTypedArray } from './componentTypeToTypedArray.js';
import {
chunk,
Expand All @@ -23,9 +23,7 @@ import {
} from './dimensionUtils.js';
import { transformBounds } from './transformBounds.js';
import {
Bounds,
Extent,
ReadonlyBounds,
ReadOnlyDimensionBounds,
ScaleInfo,
SpatialDimensions,
Expand Down
2 changes: 1 addition & 1 deletion packages/io/src/ZarrMultiscaleSpatialImage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ImageType, PixelTypes } from 'itk-wasm';
import PQueue from 'p-queue';

import { bloscZarrDecompress } from '@itk-viewer/blosc-zarr/bloscZarrDecompress.js';
import { getComponentType } from '@itk-viewer/wasm-utils/dtypeUtils.js';
import { getComponentType } from '@itk-viewer/utils/dtypeUtils.js';

import MultiscaleSpatialImage from './MultiscaleSpatialImage.js';
import { ZarrStoreParser } from './ZarrStoreParser.js';
Expand Down
13 changes: 1 addition & 12 deletions packages/io/src/dimensionUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Bounds, Dimension, SpatialDimensions } from './types.js';
import { Dimension, SpatialDimensions } from './types.js';

export const CXYZT = Object.freeze(['c', 'x', 'y', 'z', 't'] as const); // viewer indexing

Expand Down Expand Up @@ -43,14 +43,3 @@ export const nonNullable = <T>(value: T): value is NonNullable<T> => {
};

export const XYZ = Object.freeze(['x', 'y', 'z']) as SpatialDimensions;

const INIT_BOUNDS = Object.freeze([
Number.MAX_VALUE,
-Number.MAX_VALUE, // X
Number.MAX_VALUE,
-Number.MAX_VALUE, // Y
Number.MAX_VALUE,
-Number.MAX_VALUE, // Z
] as Bounds);

export const createBounds = () => [...INIT_BOUNDS] as Bounds;
3 changes: 2 additions & 1 deletion packages/io/src/transformBounds.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ReadonlyMat4, vec3 } from 'gl-matrix';
import type { Bounds, ReadonlyBounds, Vector3 } from './types.js';
import { ReadonlyBounds, Bounds } from '@itk-viewer/utils/bounding-box.js';
import type { Vector3 } from './types.js';

// from vtk.js/Sources/Common/DataModel/BoundingBox
// Computes the two corners with minimal and maximal coordinates
Expand Down
9 changes: 0 additions & 9 deletions packages/io/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,6 @@ import { TypedArray } from 'itk-wasm';
export type ValueOf<T> = T[keyof T];
export type Awaitable<T> = Promise<T> | T;

export type Bounds = [number, number, number, number, number, number];
export type ReadonlyBounds = readonly [
number,
number,
number,
number,
number,
number,
];
export type Extent = [number, number, number, number, number, number];
export type Range = [number, number];
export type ReadonlyRange = readonly [number, number];
Expand Down
1 change: 1 addition & 0 deletions packages/remote-viewport/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"dependencies": {
"@itk-viewer/io": "workspace:^",
"@itk-viewer/viewer": "workspace:^",
"@itk-viewer/utils": "workspace:^",
"@itk-wasm/htj2k": "2.1.0",
"gl-matrix": "^3.4.3",
"imjoy-rpc": "^0.5.46",
Expand Down
10 changes: 4 additions & 6 deletions packages/remote-viewport/src/remote-machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@ import {
getBytes,
worldBoundsToIndexBounds,
} from '@itk-viewer/io/MultiscaleSpatialImage.js';
import { Bounds, ReadOnlyDimensionBounds } from '@itk-viewer/io/types.js';
import {
XYZ,
createBounds,
ensuredDims,
} from '@itk-viewer/io/dimensionUtils.js';
import { ReadOnlyDimensionBounds } from '@itk-viewer/io/types.js';

import { createBounds, Bounds } from '@itk-viewer/utils/bounding-box.js';
import { XYZ, ensuredDims } from '@itk-viewer/io/dimensionUtils.js';
import { toMat4 } from '@itk-viewer/viewer/camera.js';

const MAX_IMAGE_BYTES_DEFAULT = 4000 * 1000 * 1000; // 4000 MB
Expand Down
7 changes: 3 additions & 4 deletions packages/remote-viewport/src/remote-viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ import { createActor, fromPromise } from 'xstate';
import { hyphaWebsocketClient } from 'imjoy-rpc';
import { ReadonlyMat4, mat4, vec3 } from 'gl-matrix';
import { decode, Image } from '@itk-wasm/htj2k';
import { RendererEntries, remoteMachine, Context } from './remote-machine.js';
export type { Image } from '@itk-wasm/htj2k';
import { Bounds } from '@itk-viewer/utils/bounding-box.js';
import { XYZ } from '@itk-viewer/io/dimensionUtils.js';
import {
MultiscaleSpatialImage,
worldBoundsToIndexBounds,
} from '@itk-viewer/io/MultiscaleSpatialImage.js';
import { Bounds } from '@itk-viewer/io/types.js';
import { transformBounds } from '@itk-viewer/io/transformBounds.js';

export type { Image } from '@itk-wasm/htj2k';
import { RendererEntries, remoteMachine, Context } from './remote-machine.js';

// Should match constant in agave-renderer::renderer.py
const RENDERER_SERVICE_ID = 'agave-renderer';
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@itk-viewer/wasm-utils",
"name": "@itk-viewer/utils",
"version": "0.1.2",
"description": "Utils for io and itk-wasm packages",
"type": "module",
Expand Down
49 changes: 49 additions & 0 deletions packages/utils/src/bounding-box.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
export type Bounds = [number, number, number, number, number, number];

export type ReadonlyBounds = readonly [
number,
number,
number,
number,
number,
number,
];

const INIT_BOUNDS = Object.freeze([
Number.MAX_VALUE,
-Number.MAX_VALUE, // X
Number.MAX_VALUE,
-Number.MAX_VALUE, // Y
Number.MAX_VALUE,
-Number.MAX_VALUE, // Z
] as ReadonlyBounds);

export const createBounds = () => [...INIT_BOUNDS] as Bounds;

export function addPoint(bounds: Bounds, x: number, y: number, z: number) {
const [xMin, xMax, yMin, yMax, zMin, zMax] = bounds;
bounds[0] = xMin < x ? xMin : x;
bounds[1] = xMax > x ? xMax : x;
bounds[2] = yMin < y ? yMin : y;
bounds[3] = yMax > y ? yMax : y;
bounds[4] = zMin < z ? zMin : z;
bounds[5] = zMax > z ? zMax : z;
return bounds;
}

export function getCorners(bounds: ReadonlyBounds) {
const corners = new Array<[number, number, number]>(8);
let count = 0;
for (let ix = 0; ix < 2; ix++) {
for (let iy = 2; iy < 4; iy++) {
for (let iz = 4; iz < 6; iz++) {
corners[count++] = [bounds[ix], bounds[iy], bounds[iz]];
}
}
}
return corners;
}

export function getLength(bounds: ReadonlyBounds, index: number) {
return bounds[index * 2 + 1] - bounds[index * 2];
}
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 2529b54

Please sign in to comment.