@cornerstonejs/core 3.16.0 → 3.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ import { mat4 } from 'gl-matrix';
1
2
  import type { WSIViewportProperties, Point3, Point2, ICamera, CPUIImageData, ViewportInput } from '../types';
2
3
  import { Transform } from './helpers/cpuFallback/rendering/transform';
3
4
  import Viewport from './Viewport';
@@ -26,6 +27,10 @@ declare class WSIViewport extends Viewport {
26
27
  getProperties: () => WSIViewportProperties;
27
28
  resetProperties(): void;
28
29
  protected getScalarData(): any;
30
+ computeTransforms(): {
31
+ indexToWorld: mat4;
32
+ worldToIndex: mat4;
33
+ };
29
34
  getImageData(): CPUIImageData;
30
35
  hasImageURI(imageURI: string): boolean;
31
36
  setCamera(camera: ICamera): void;
@@ -37,6 +42,10 @@ declare class WSIViewport extends Viewport {
37
42
  static getDicomMicroscopyViewer: () => Promise<any>;
38
43
  getFrameOfReferenceUID: () => string;
39
44
  resize: () => void;
45
+ worldToIndexWSI(point: Point3): Point2;
46
+ indexToWorldWSI(point: Point2): Point3;
47
+ worldToIndex(point: Point3): Point3;
48
+ indexToWorld(point: Point3): Point3;
40
49
  canvasToWorld: (canvasPos: Point2) => Point3;
41
50
  worldToCanvas: (worldPos: Point3) => Point2;
42
51
  setDataIds(imageIds: string[], options?: DataSetOptions & {
@@ -47,8 +56,8 @@ declare class WSIViewport extends Viewport {
47
56
  postrender: () => void;
48
57
  scroll(delta: number): void;
49
58
  getRotation: () => number;
50
- protected canvasToIndex: (canvasPos: Point2) => Point2;
51
- protected indexToCanvas: (indexPos: Point2) => Point2;
59
+ protected canvasToIndex: (canvasPos: Point2) => Point3;
60
+ protected indexToCanvas: (indexPos: Point3) => Point2;
52
61
  getSliceIndex(): number;
53
62
  getView(): any;
54
63
  private refreshRenderValues;
@@ -1,4 +1,4 @@
1
- import { vec3 } from 'gl-matrix';
1
+ import { vec3, mat4 } from 'gl-matrix';
2
2
  import { Events as EVENTS, MetadataModules } from '../enums';
3
3
  import uuidv4 from '../utilities/uuidv4';
4
4
  import * as metaData from '../metaData';
@@ -10,7 +10,9 @@ import triggerEvent from '../utilities/triggerEvent';
10
10
  import { peerImport } from '../init';
11
11
  import { pointInShapeCallback } from '../utilities/pointInShapeCallback';
12
12
  import microscopyViewportCss from '../constants/microscopyViewportCss';
13
+ let WSIUtilFunctions = null;
13
14
  const _map = Symbol.for('map');
15
+ const affineSymbol = Symbol.for('affine');
14
16
  const EVENT_POSTRENDER = 'postrender';
15
17
  class WSIViewport extends Viewport {
16
18
  constructor(props) {
@@ -56,28 +58,17 @@ class WSIViewport extends Viewport {
56
58
  if (!this.metadata) {
57
59
  return;
58
60
  }
59
- const [px, py] = this.canvasToIndex(canvasPos);
60
- const { origin, spacing, direction } = this.getImageData();
61
- const worldPos = vec3.fromValues(0, 0, 0);
62
- const iVector = direction.slice(0, 3);
63
- const jVector = direction.slice(3, 6);
64
- vec3.scaleAndAdd(worldPos, origin, iVector, px * spacing[0]);
65
- vec3.scaleAndAdd(worldPos, worldPos, jVector, py * spacing[1]);
66
- return [worldPos[0], worldPos[1], worldPos[2]];
61
+ const indexPoint = this.canvasToIndex(canvasPos);
62
+ indexPoint[1] = -indexPoint[1];
63
+ return this.indexToWorld(indexPoint);
67
64
  };
68
65
  this.worldToCanvas = (worldPos) => {
69
66
  if (!this.metadata) {
70
67
  return;
71
68
  }
72
- const { spacing, direction, origin } = this.metadata;
73
- const iVector = direction.slice(0, 3);
74
- const jVector = direction.slice(3, 6);
75
- const diff = vec3.subtract([0, 0, 0], worldPos, origin);
76
- const indexPoint = [
77
- vec3.dot(diff, iVector) / spacing[0],
78
- vec3.dot(diff, jVector) / spacing[1],
79
- ];
80
- const canvasPoint = this.indexToCanvas(indexPoint);
69
+ const indexPoint = this.worldToIndex(worldPos);
70
+ indexPoint[1] = -indexPoint[1];
71
+ const canvasPoint = this.indexToCanvas([indexPoint[0], indexPoint[1], 0]);
81
72
  return canvasPoint;
82
73
  };
83
74
  this.postrender = () => {
@@ -93,12 +84,13 @@ class WSIViewport extends Viewport {
93
84
  this.canvasToIndex = (canvasPos) => {
94
85
  const transform = this.getTransform();
95
86
  transform.invert();
96
- return transform.transformPoint(canvasPos.map((it) => it * devicePixelRatio));
87
+ const indexPoint = transform.transformPoint(canvasPos.map((it) => it * devicePixelRatio));
88
+ return [indexPoint[0], indexPoint[1], 0];
97
89
  };
98
90
  this.indexToCanvas = (indexPos) => {
99
91
  const transform = this.getTransform();
100
92
  return transform
101
- .transformPoint(indexPos)
93
+ .transformPoint([indexPos[0], indexPos[1]])
102
94
  .map((it) => it / devicePixelRatio);
103
95
  };
104
96
  this.customRenderViewportToCanvas = () => {
@@ -199,6 +191,23 @@ class WSIViewport extends Viewport {
199
191
  getScalarData() {
200
192
  return null;
201
193
  }
194
+ computeTransforms() {
195
+ const indexToWorld = mat4.create();
196
+ const worldToIndex = mat4.create();
197
+ mat4.fromTranslation(indexToWorld, this.metadata.origin);
198
+ indexToWorld[0] = this.metadata.direction[0];
199
+ indexToWorld[1] = this.metadata.direction[1];
200
+ indexToWorld[2] = this.metadata.direction[2];
201
+ indexToWorld[4] = this.metadata.direction[3];
202
+ indexToWorld[5] = this.metadata.direction[4];
203
+ indexToWorld[6] = this.metadata.direction[5];
204
+ indexToWorld[8] = this.metadata.direction[6];
205
+ indexToWorld[9] = this.metadata.direction[7];
206
+ indexToWorld[10] = this.metadata.direction[8];
207
+ mat4.scale(indexToWorld, indexToWorld, this.metadata.spacing);
208
+ mat4.invert(worldToIndex, indexToWorld);
209
+ return { indexToWorld, worldToIndex };
210
+ }
202
211
  getImageData() {
203
212
  const { metadata } = this;
204
213
  if (!metadata) {
@@ -212,13 +221,10 @@ class WSIViewport extends Viewport {
212
221
  getScalarData: () => this.getScalarData(),
213
222
  getSpacing: () => metadata.spacing,
214
223
  worldToIndex: (point) => {
215
- const canvasPoint = this.worldToCanvas(point);
216
- const pixelCoord = this.canvasToIndex(canvasPoint);
217
- return [pixelCoord[0], pixelCoord[1], 0];
224
+ return this.worldToIndex(point);
218
225
  },
219
226
  indexToWorld: (point) => {
220
- const canvasPoint = this.indexToCanvas([point[0], point[1]]);
221
- return this.canvasToWorld(canvasPoint);
227
+ return this.indexToWorld(point);
222
228
  },
223
229
  };
224
230
  const imageDataReturn = {
@@ -282,7 +288,11 @@ class WSIViewport extends Viewport {
282
288
  this.refreshRenderValues();
283
289
  const { resolution, xSpacing, centerIndex } = this.internalCamera;
284
290
  const canvasToWorldRatio = resolution * xSpacing;
285
- const canvasCenter = this.indexToCanvas(centerIndex.slice(0, 2));
291
+ const canvasCenter = this.indexToCanvas([
292
+ centerIndex[0],
293
+ centerIndex[1],
294
+ 0,
295
+ ]);
286
296
  const focalPoint = this.canvasToWorld(canvasCenter);
287
297
  return {
288
298
  parallelProjection: true,
@@ -296,6 +306,40 @@ class WSIViewport extends Viewport {
296
306
  static { this.getDicomMicroscopyViewer = async () => {
297
307
  return peerImport('dicom-microscopy-viewer');
298
308
  }; }
309
+ worldToIndexWSI(point) {
310
+ if (!WSIUtilFunctions) {
311
+ return;
312
+ }
313
+ const affine = this.viewer[affineSymbol];
314
+ const pixelCoords = WSIUtilFunctions.applyInverseTransform({
315
+ coordinate: [point[0], point[1]],
316
+ affine,
317
+ });
318
+ return [pixelCoords[0], pixelCoords[1]];
319
+ }
320
+ indexToWorldWSI(point) {
321
+ if (!WSIUtilFunctions) {
322
+ return;
323
+ }
324
+ const sliceCoords = WSIUtilFunctions.applyTransform({
325
+ coordinate: [point[0], point[1]],
326
+ affine: this.viewer[affineSymbol],
327
+ });
328
+ return [sliceCoords[0], sliceCoords[1], 0];
329
+ }
330
+ worldToIndex(point) {
331
+ const { worldToIndex: worldToIndexMatrix } = this.computeTransforms();
332
+ const imageCoord = vec3.create();
333
+ vec3.transformMat4(imageCoord, point, worldToIndexMatrix);
334
+ return imageCoord;
335
+ }
336
+ indexToWorld(point) {
337
+ const { indexToWorld: indexToWorldMatrix } = this.computeTransforms();
338
+ const worldPos = vec3.create();
339
+ const point3D = vec3.fromValues(...point);
340
+ vec3.transformMat4(worldPos, point3D, indexToWorldMatrix);
341
+ return [worldPos[0], worldPos[1], worldPos[2]];
342
+ }
299
343
  setDataIds(imageIds, options) {
300
344
  if (options?.miniNavigationOverlay !== false) {
301
345
  WSIViewport.addMiniNavigationOverlayCss();
@@ -312,6 +356,7 @@ class WSIViewport extends Viewport {
312
356
  this.microscopyElement.innerText = 'Loading';
313
357
  this.imageIds = imageIds;
314
358
  const DicomMicroscopyViewer = await WSIViewport.getDicomMicroscopyViewer();
359
+ WSIUtilFunctions ||= DicomMicroscopyViewer.utils;
315
360
  this.frameOfReferenceUID = null;
316
361
  const metadataDicomweb = this.imageIds.map((imageId) => {
317
362
  const imageMetadata = client.getDICOMwebMetadata(imageId);
@@ -1 +1 @@
1
- export declare const version = "3.16.0";
1
+ export declare const version = "3.16.1";
@@ -1 +1 @@
1
- export const version = '3.16.0';
1
+ export const version = '3.16.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/core",
3
- "version": "3.16.0",
3
+ "version": "3.16.1",
4
4
  "description": "Cornerstone3D Core",
5
5
  "module": "./dist/esm/index.js",
6
6
  "types": "./dist/esm/index.d.ts",
@@ -97,5 +97,5 @@
97
97
  "type": "individual",
98
98
  "url": "https://ohif.org/donate"
99
99
  },
100
- "gitHead": "16136620b12d12a19fe62f8b8a2ddbc468c4543b"
100
+ "gitHead": "50d792050fd2cab62160c80568daf2949c3fa868"
101
101
  }