@cornerstonejs/core 1.39.0 → 1.40.0

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.
Files changed (38) hide show
  1. package/dist/cjs/RenderingEngine/BaseVolumeViewport.d.ts +5 -1
  2. package/dist/cjs/RenderingEngine/BaseVolumeViewport.js +47 -2
  3. package/dist/cjs/RenderingEngine/BaseVolumeViewport.js.map +1 -1
  4. package/dist/cjs/RenderingEngine/Viewport.js +2 -3
  5. package/dist/cjs/RenderingEngine/Viewport.js.map +1 -1
  6. package/dist/cjs/RenderingEngine/VolumeViewport.d.ts +1 -2
  7. package/dist/cjs/RenderingEngine/VolumeViewport.js +16 -2
  8. package/dist/cjs/RenderingEngine/VolumeViewport.js.map +1 -1
  9. package/dist/cjs/types/IVolumeViewport.d.ts +1 -1
  10. package/dist/cjs/types/ViewportProperties.d.ts +1 -0
  11. package/dist/cjs/types/VolumeViewportProperties.d.ts +2 -0
  12. package/dist/esm/RenderingEngine/BaseVolumeViewport.js +47 -2
  13. package/dist/esm/RenderingEngine/BaseVolumeViewport.js.map +1 -1
  14. package/dist/esm/RenderingEngine/Viewport.js +1 -2
  15. package/dist/esm/RenderingEngine/Viewport.js.map +1 -1
  16. package/dist/esm/RenderingEngine/VolumeViewport.js +16 -2
  17. package/dist/esm/RenderingEngine/VolumeViewport.js.map +1 -1
  18. package/dist/types/RenderingEngine/BaseVolumeViewport.d.ts +5 -1
  19. package/dist/types/RenderingEngine/BaseVolumeViewport.d.ts.map +1 -1
  20. package/dist/types/RenderingEngine/Viewport.d.ts.map +1 -1
  21. package/dist/types/RenderingEngine/VolumeViewport.d.ts +1 -2
  22. package/dist/types/RenderingEngine/VolumeViewport.d.ts.map +1 -1
  23. package/dist/types/types/IVolumeViewport.d.ts +1 -1
  24. package/dist/types/types/IVolumeViewport.d.ts.map +1 -1
  25. package/dist/types/types/ViewportProperties.d.ts +1 -0
  26. package/dist/types/types/ViewportProperties.d.ts.map +1 -1
  27. package/dist/types/types/VolumeViewportProperties.d.ts +2 -0
  28. package/dist/types/types/VolumeViewportProperties.d.ts.map +1 -1
  29. package/dist/umd/index.js +1 -1
  30. package/dist/umd/index.js.map +1 -1
  31. package/package.json +2 -2
  32. package/src/RenderingEngine/BaseVolumeViewport.ts +99 -1
  33. package/src/RenderingEngine/Viewport.ts +6 -3
  34. package/src/RenderingEngine/VolumeViewport.ts +23 -4
  35. package/src/types/IViewport.ts +1 -1
  36. package/src/types/IVolumeViewport.ts +2 -1
  37. package/src/types/ViewportProperties.ts +2 -0
  38. package/src/types/VolumeViewportProperties.ts +3 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/core",
3
- "version": "1.39.0",
3
+ "version": "1.40.0",
4
4
  "description": "",
5
5
  "main": "src/index.ts",
6
6
  "types": "dist/types/index.d.ts",
@@ -47,5 +47,5 @@
47
47
  "type": "individual",
48
48
  "url": "https://ohif.org/donate"
49
49
  },
50
- "gitHead": "dfec4edcd4585f7a33884517071b77ec2c944cf6"
50
+ "gitHead": "28ed3eaf75ccd5cab7c7c0df0f4b09950cc42d7c"
51
51
  }
@@ -3,6 +3,8 @@ import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransf
3
3
  import vtkColorMaps from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps';
4
4
  import vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunction';
5
5
 
6
+ import { vec3 } from 'gl-matrix';
7
+
6
8
  import cache from '../cache';
7
9
  import {
8
10
  MPR_CAMERA_VALUES,
@@ -31,7 +33,9 @@ import type {
31
33
  Point2,
32
34
  Point3,
33
35
  VOIRange,
36
+ EventTypes,
34
37
  VolumeViewportProperties,
38
+ ICamera,
35
39
  } from '../types';
36
40
  import { VoiModifiedEventDetail } from '../types/EventTypes';
37
41
  import type { ViewportInput } from '../types/IViewport';
@@ -77,7 +81,8 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
77
81
  string,
78
82
  VolumeViewportProperties
79
83
  >();
80
-
84
+ // Camera properties
85
+ private initialViewUp: Point3;
81
86
  protected viewportProperties: VolumeViewportProperties = {};
82
87
 
83
88
  constructor(props: ViewportInput) {
@@ -95,6 +100,16 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
95
100
  const renderer = this.getRenderer();
96
101
 
97
102
  const camera = vtkSlabCamera.newInstance();
103
+
104
+ this.initialViewUp = <Point3>[0, -1, 0];
105
+ const viewPlaneNormal = <Point3>[0, 0, -1];
106
+
107
+ camera.setDirectionOfProjection(
108
+ -viewPlaneNormal[0],
109
+ -viewPlaneNormal[1],
110
+ -viewPlaneNormal[2]
111
+ );
112
+ camera.setViewUp(...this.initialViewUp);
98
113
  renderer.setActiveCamera(camera);
99
114
 
100
115
  switch (this.type) {
@@ -471,6 +486,33 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
471
486
  this.viewportProperties.voiRange = voiRangeToUse;
472
487
  }
473
488
 
489
+ private setRotation(rotation: number): void {
490
+ const previousCamera = this.getCamera();
491
+
492
+ this.rotateCamera(rotation);
493
+
494
+ // New camera after rotation
495
+ const camera = this.getCamera();
496
+
497
+ const eventDetail: EventTypes.CameraModifiedEventDetail = {
498
+ previousCamera,
499
+ camera,
500
+ element: this.element,
501
+ viewportId: this.id,
502
+ renderingEngineId: this.renderingEngineId,
503
+ rotation,
504
+ };
505
+
506
+ triggerEvent(this.element, Events.CAMERA_MODIFIED, eventDetail);
507
+ this.viewportProperties.rotation = rotation;
508
+ }
509
+
510
+ private rotateCamera(rotation: number): void {
511
+ const rotationToApply = rotation - this.getRotation();
512
+ // rotating camera to the new value
513
+ this.getVtkActiveCamera().roll(-rotationToApply);
514
+ }
515
+
474
516
  /**
475
517
  * Update the default properties for the volume viewport on the volume
476
518
  * @param ViewportProperties - The properties to set
@@ -525,6 +567,7 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
525
567
  preset,
526
568
  interpolationType,
527
569
  slabThickness,
570
+ rotation,
528
571
  }: VolumeViewportProperties = {},
529
572
  volumeId?: string,
530
573
  suppressEvents = false
@@ -538,6 +581,7 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
538
581
  colormap,
539
582
  preset,
540
583
  slabThickness,
584
+ rotation,
541
585
  });
542
586
  }
543
587
 
@@ -576,6 +620,10 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
576
620
  //We need to set the current slab thickness here since setSlabThickness is define in VolumeViewport
577
621
  this.viewportProperties.slabThickness = slabThickness;
578
622
  }
623
+
624
+ if (rotation !== undefined) {
625
+ this.setRotation(rotation);
626
+ }
579
627
  }
580
628
 
581
629
  /**
@@ -609,6 +657,10 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
609
657
  this.viewportProperties.slabThickness = properties.slabThickness;
610
658
  }
611
659
 
660
+ if (properties.rotation !== undefined) {
661
+ this.setRotation(properties.rotation);
662
+ }
663
+
612
664
  this.render();
613
665
  }
614
666
 
@@ -683,6 +735,7 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
683
735
  interpolationType,
684
736
  invert,
685
737
  slabThickness,
738
+ rotation,
686
739
  } = this.viewportProperties;
687
740
 
688
741
  const voiRanges = this.getActors()
@@ -711,6 +764,7 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
711
764
  interpolationType: interpolationType,
712
765
  invert: invert,
713
766
  slabThickness: slabThickness,
767
+ rotation: rotation,
714
768
  };
715
769
  };
716
770
 
@@ -937,6 +991,49 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
937
991
  return true;
938
992
  }
939
993
 
994
+ /**
995
+ * Gets the rotation resulting from the value set in setRotation AND taking into
996
+ * account any flips that occurred subsequently from the camera provided or the viewport.
997
+ *
998
+ * @returns the rotation resulting from the value set in setRotation AND taking into
999
+ * account any flips that occurred subsequently.
1000
+ */
1001
+ public getRotation = (): number => {
1002
+ const {
1003
+ viewUp: currentViewUp,
1004
+ viewPlaneNormal,
1005
+ flipVertical,
1006
+ } = this.getCamera();
1007
+
1008
+ // The initial view up vector without any rotation, but incorporating vertical flip.
1009
+ const initialViewUp = flipVertical
1010
+ ? vec3.negate(vec3.create(), this.initialViewUp)
1011
+ : this.initialViewUp;
1012
+
1013
+ // The angle between the initial and current view up vectors.
1014
+ // TODO: check with VTK about rounding errors here.
1015
+ const initialToCurrentViewUpAngle =
1016
+ (vec3.angle(initialViewUp, currentViewUp) * 180) / Math.PI;
1017
+
1018
+ // Now determine if initialToCurrentViewUpAngle is positive or negative by comparing
1019
+ // the direction of the initial/current view up cross product with the current
1020
+ // viewPlaneNormal.
1021
+
1022
+ const initialToCurrentViewUpCross = vec3.cross(
1023
+ vec3.create(),
1024
+ initialViewUp,
1025
+ currentViewUp
1026
+ );
1027
+
1028
+ // The sign of the dot product of the start/end view up cross product and
1029
+ // the viewPlaneNormal indicates a positive or negative rotation respectively.
1030
+ const normalDot = vec3.dot(initialToCurrentViewUpCross, viewPlaneNormal);
1031
+
1032
+ return normalDot >= 0
1033
+ ? initialToCurrentViewUpAngle
1034
+ : (360 - initialToCurrentViewUpAngle) % 360;
1035
+ };
1036
+
940
1037
  /**
941
1038
  * gets the visible bounds of the viewport in the world coordinate system
942
1039
  */
@@ -1209,6 +1306,7 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
1209
1306
  typeof orientation === 'string' &&
1210
1307
  MPR_CAMERA_VALUES[orientation]
1211
1308
  ) {
1309
+ this.viewportProperties.orientation = orientation;
1212
1310
  return MPR_CAMERA_VALUES[orientation];
1213
1311
  } else {
1214
1312
  throw new Error(
@@ -18,7 +18,7 @@ import {
18
18
  isEqual,
19
19
  } from '../utilities';
20
20
  import hasNaNValues from '../utilities/hasNaNValues';
21
- import { EPSILON, RENDERING_DEFAULTS } from '../constants';
21
+ import { RENDERING_DEFAULTS } from '../constants';
22
22
  import type {
23
23
  ICamera,
24
24
  ActorEntry,
@@ -1190,7 +1190,11 @@ class Viewport implements IViewport {
1190
1190
  updatedCamera: ICamera
1191
1191
  ): Promise<void> {
1192
1192
  const actorEntries = this.getActors();
1193
- const allPromises = actorEntries.map(async (actorEntry) => {
1193
+ // Todo: this was using an async and promise wait all because of the
1194
+ // new surface rendering use case, which broke the more important 3D
1195
+ // volume rendering, so reverting this back for now until I can figure
1196
+ // out a better way to handle this.
1197
+ actorEntries.map((actorEntry) => {
1194
1198
  // we assume that the first two clipping plane of the mapper are always
1195
1199
  // the 'camera' clipping. Update clipping planes only if the actor is
1196
1200
  // a vtkVolume
@@ -1228,7 +1232,6 @@ class Viewport implements IViewport {
1228
1232
  });
1229
1233
  });
1230
1234
 
1231
- await Promise.all(allPromises);
1232
1235
  this.posProcessNewActors();
1233
1236
  }
1234
1237
 
@@ -42,7 +42,6 @@ class VolumeViewport extends BaseVolumeViewport {
42
42
  super(props);
43
43
 
44
44
  const { orientation } = this.options;
45
-
46
45
  // if the camera is set to be acquisition axis then we need to skip
47
46
  // it for now until the volume is set
48
47
  if (orientation && orientation !== OrientationAxis.ACQUISITION) {
@@ -144,6 +143,7 @@ class VolumeViewport extends BaseVolumeViewport {
144
143
  viewUp,
145
144
  });
146
145
 
146
+ this.viewportProperties.orientation = orientation;
147
147
  this.resetCamera();
148
148
 
149
149
  if (immediate) {
@@ -231,7 +231,8 @@ class VolumeViewport extends BaseVolumeViewport {
231
231
  public resetCamera(
232
232
  resetPan = true,
233
233
  resetZoom = true,
234
- resetToCenter = true
234
+ resetToCenter = true,
235
+ resetRotation = false
235
236
  ): boolean {
236
237
  super.resetCamera(resetPan, resetZoom, resetToCenter);
237
238
 
@@ -239,6 +240,7 @@ class VolumeViewport extends BaseVolumeViewport {
239
240
 
240
241
  const activeCamera = this.getVtkActiveCamera();
241
242
  const viewPlaneNormal = <Point3>activeCamera.getViewPlaneNormal();
243
+ const viewUp = <Point3>activeCamera.getViewUp();
242
244
  const focalPoint = <Point3>activeCamera.getFocalPoint();
243
245
 
244
246
  // always add clipping planes for the volume viewport. If a use case
@@ -274,6 +276,19 @@ class VolumeViewport extends BaseVolumeViewport {
274
276
  }
275
277
  });
276
278
 
279
+ //Only reset the rotation of the camera if wanted (so we don't reset everytime resetCamera is called) and also verify that the viewport has an orientation that we know (sagittal, coronal, axial)
280
+ if (
281
+ resetRotation &&
282
+ MPR_CAMERA_VALUES[this.viewportProperties.orientation] !== undefined
283
+ ) {
284
+ const viewToReset =
285
+ MPR_CAMERA_VALUES[this.viewportProperties.orientation];
286
+ this.setCameraNoEvent({
287
+ viewUp: viewToReset.viewUp,
288
+ viewPlaneNormal: viewToReset.viewPlaneNormal,
289
+ });
290
+ }
291
+
277
292
  return true;
278
293
  }
279
294
 
@@ -370,8 +385,6 @@ class VolumeViewport extends BaseVolumeViewport {
370
385
  return getClosestImageId(volume, focalPoint, viewPlaneNormal);
371
386
  };
372
387
 
373
- getRotation = (): number => 0;
374
-
375
388
  /**
376
389
  * Reset the viewport properties to the default values
377
390
  *
@@ -433,6 +446,12 @@ class VolumeViewport extends BaseVolumeViewport {
433
446
  volumeId: volumeActor.uid,
434
447
  };
435
448
 
449
+ const resetPan = true;
450
+ const resetZoom = true;
451
+ const resetToCenter = true;
452
+ const resetCameraRotation = true;
453
+ this.resetCamera(resetPan, resetZoom, resetToCenter, resetCameraRotation);
454
+
436
455
  triggerEvent(this.element, Events.VOI_MODIFIED, eventDetails);
437
456
  }
438
457
  }
@@ -42,7 +42,7 @@ interface IViewport {
42
42
  isDisabled: boolean;
43
43
  /** The rendering state of this viewport */
44
44
  viewportStatus: ViewportStatus;
45
- /** the rotation applied to the view */
45
+ /** get the rotation either from the camera provided or the viewport if not provided */
46
46
  getRotation: () => number;
47
47
  /** frameOfReferenceUID the viewport's default actor is rendering */
48
48
  getFrameOfReferenceUID: () => string;
@@ -136,7 +136,8 @@ export default interface IVolumeViewport extends IViewport {
136
136
  resetCamera(
137
137
  resetPan?: boolean,
138
138
  resetZoom?: boolean,
139
- resetToCenter?: boolean
139
+ resetToCenter?: boolean,
140
+ resetRotation?: boolean
140
141
  ): boolean;
141
142
  /**
142
143
  * Sets the blendMode for actors of the viewport.
@@ -16,6 +16,8 @@ type ViewportProperties = {
16
16
  colormap?: ColormapPublic;
17
17
  /** interpolation type */
18
18
  interpolationType?: InterpolationType;
19
+ /**Rotation of the camera */
20
+ rotation?: number;
19
21
  };
20
22
 
21
23
  export type { ViewportProperties };
@@ -1,4 +1,5 @@
1
1
  import { ViewportProperties } from './ViewportProperties';
2
+ import { OrientationAxis } from '../enums';
2
3
 
3
4
  /**
4
5
  * Stack Viewport Properties
@@ -8,6 +9,8 @@ type VolumeViewportProperties = ViewportProperties & {
8
9
  preset?: string;
9
10
 
10
11
  slabThickness?: number;
12
+
13
+ orientation?: OrientationAxis;
11
14
  };
12
15
 
13
16
  export default VolumeViewportProperties;