@cornerstonejs/core 1.53.0 → 1.54.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.
Files changed (183) hide show
  1. package/dist/cjs/RenderingEngine/RenderingEngine.js +5 -0
  2. package/dist/cjs/RenderingEngine/RenderingEngine.js.map +1 -1
  3. package/dist/cjs/RenderingEngine/Viewport.d.ts +1 -2
  4. package/dist/cjs/RenderingEngine/Viewport.js +21 -8
  5. package/dist/cjs/RenderingEngine/Viewport.js.map +1 -1
  6. package/dist/cjs/RenderingEngine/VolumeViewport.d.ts +14 -2
  7. package/dist/cjs/RenderingEngine/VolumeViewport.js +60 -12
  8. package/dist/cjs/RenderingEngine/VolumeViewport.js.map +1 -1
  9. package/dist/cjs/RenderingEngine/VolumeViewport3D.d.ts +0 -1
  10. package/dist/cjs/RenderingEngine/VolumeViewport3D.js +0 -7
  11. package/dist/cjs/RenderingEngine/VolumeViewport3D.js.map +1 -1
  12. package/dist/cjs/RenderingEngine/helpers/setDefaultVolumeVOI.js +10 -7
  13. package/dist/cjs/RenderingEngine/helpers/setDefaultVolumeVOI.js.map +1 -1
  14. package/dist/cjs/cache/cache.d.ts +2 -0
  15. package/dist/cjs/cache/cache.js +10 -0
  16. package/dist/cjs/cache/cache.js.map +1 -1
  17. package/dist/cjs/cache/classes/ImageVolume.d.ts +1 -0
  18. package/dist/cjs/cache/classes/ImageVolume.js +25 -3
  19. package/dist/cjs/cache/classes/ImageVolume.js.map +1 -1
  20. package/dist/cjs/cache/classes/Surface.d.ts +6 -3
  21. package/dist/cjs/cache/classes/Surface.js +9 -0
  22. package/dist/cjs/cache/classes/Surface.js.map +1 -1
  23. package/dist/cjs/cache/index.d.ts +2 -1
  24. package/dist/cjs/cache/index.js +3 -1
  25. package/dist/cjs/cache/index.js.map +1 -1
  26. package/dist/cjs/constants/backgroundColors.d.ts +4 -0
  27. package/dist/cjs/constants/backgroundColors.js +7 -0
  28. package/dist/cjs/constants/backgroundColors.js.map +1 -0
  29. package/dist/cjs/constants/index.d.ts +2 -1
  30. package/dist/cjs/constants/index.js +3 -1
  31. package/dist/cjs/constants/index.js.map +1 -1
  32. package/dist/cjs/enums/Events.d.ts +2 -1
  33. package/dist/cjs/enums/Events.js +1 -0
  34. package/dist/cjs/enums/Events.js.map +1 -1
  35. package/dist/cjs/index.d.ts +2 -2
  36. package/dist/cjs/index.js +2 -1
  37. package/dist/cjs/index.js.map +1 -1
  38. package/dist/cjs/loaders/volumeLoader.d.ts +10 -2
  39. package/dist/cjs/loaders/volumeLoader.js +49 -29
  40. package/dist/cjs/loaders/volumeLoader.js.map +1 -1
  41. package/dist/cjs/requestPool/requestPoolManager.js +1 -1
  42. package/dist/cjs/requestPool/requestPoolManager.js.map +1 -1
  43. package/dist/cjs/types/IGeometry.d.ts +2 -2
  44. package/dist/cjs/types/IImageVolume.d.ts +2 -1
  45. package/dist/cjs/types/ISurface.d.ts +13 -0
  46. package/dist/cjs/types/ISurface.js +3 -0
  47. package/dist/cjs/types/ISurface.js.map +1 -0
  48. package/dist/cjs/types/index.d.ts +2 -1
  49. package/dist/cjs/utilities/VoxelManager.d.ts +1 -1
  50. package/dist/cjs/utilities/VoxelManager.js +3 -0
  51. package/dist/cjs/utilities/VoxelManager.js.map +1 -1
  52. package/dist/cjs/utilities/cacheUtils.js +16 -1
  53. package/dist/cjs/utilities/cacheUtils.js.map +1 -1
  54. package/dist/cjs/utilities/convertVolumeToStackViewport.js +1 -1
  55. package/dist/cjs/utilities/convertVolumeToStackViewport.js.map +1 -1
  56. package/dist/cjs/utilities/generateVolumePropsFromImageIds.js.map +1 -1
  57. package/dist/cjs/utilities/getViewportImageIds.d.ts +3 -0
  58. package/dist/cjs/utilities/getViewportImageIds.js +20 -0
  59. package/dist/cjs/utilities/getViewportImageIds.js.map +1 -0
  60. package/dist/cjs/utilities/index.d.ts +2 -1
  61. package/dist/cjs/utilities/index.js +3 -1
  62. package/dist/cjs/utilities/index.js.map +1 -1
  63. package/dist/cjs/webWorkerManager/webWorkerManager.d.ts +3 -3
  64. package/dist/cjs/webWorkerManager/webWorkerManager.js +40 -30
  65. package/dist/cjs/webWorkerManager/webWorkerManager.js.map +1 -1
  66. package/dist/esm/RenderingEngine/RenderingEngine.js +5 -0
  67. package/dist/esm/RenderingEngine/RenderingEngine.js.map +1 -1
  68. package/dist/esm/RenderingEngine/Viewport.js +21 -8
  69. package/dist/esm/RenderingEngine/Viewport.js.map +1 -1
  70. package/dist/esm/RenderingEngine/VolumeViewport.js +61 -13
  71. package/dist/esm/RenderingEngine/VolumeViewport.js.map +1 -1
  72. package/dist/esm/RenderingEngine/VolumeViewport3D.js +0 -7
  73. package/dist/esm/RenderingEngine/VolumeViewport3D.js.map +1 -1
  74. package/dist/esm/RenderingEngine/helpers/setDefaultVolumeVOI.js +7 -7
  75. package/dist/esm/RenderingEngine/helpers/setDefaultVolumeVOI.js.map +1 -1
  76. package/dist/esm/cache/cache.js +10 -0
  77. package/dist/esm/cache/cache.js.map +1 -1
  78. package/dist/esm/cache/classes/ImageVolume.js +24 -2
  79. package/dist/esm/cache/classes/ImageVolume.js.map +1 -1
  80. package/dist/esm/cache/classes/Surface.js +9 -0
  81. package/dist/esm/cache/classes/Surface.js.map +1 -1
  82. package/dist/esm/cache/index.js +2 -1
  83. package/dist/esm/cache/index.js.map +1 -1
  84. package/dist/esm/constants/backgroundColors.js +5 -0
  85. package/dist/esm/constants/backgroundColors.js.map +1 -0
  86. package/dist/esm/constants/index.js +2 -1
  87. package/dist/esm/constants/index.js.map +1 -1
  88. package/dist/esm/enums/Events.js +1 -0
  89. package/dist/esm/enums/Events.js.map +1 -1
  90. package/dist/esm/index.js +2 -2
  91. package/dist/esm/index.js.map +1 -1
  92. package/dist/esm/loaders/volumeLoader.js +45 -28
  93. package/dist/esm/loaders/volumeLoader.js.map +1 -1
  94. package/dist/esm/requestPool/requestPoolManager.js +1 -1
  95. package/dist/esm/requestPool/requestPoolManager.js.map +1 -1
  96. package/dist/esm/types/ISurface.js +2 -0
  97. package/dist/esm/types/ISurface.js.map +1 -0
  98. package/dist/esm/utilities/VoxelManager.js +3 -0
  99. package/dist/esm/utilities/VoxelManager.js.map +1 -1
  100. package/dist/esm/utilities/cacheUtils.js +15 -1
  101. package/dist/esm/utilities/cacheUtils.js.map +1 -1
  102. package/dist/esm/utilities/convertVolumeToStackViewport.js +1 -1
  103. package/dist/esm/utilities/convertVolumeToStackViewport.js.map +1 -1
  104. package/dist/esm/utilities/generateVolumePropsFromImageIds.js.map +1 -1
  105. package/dist/esm/utilities/getViewportImageIds.js +15 -0
  106. package/dist/esm/utilities/getViewportImageIds.js.map +1 -0
  107. package/dist/esm/utilities/index.js +2 -1
  108. package/dist/esm/utilities/index.js.map +1 -1
  109. package/dist/esm/webWorkerManager/webWorkerManager.js +40 -30
  110. package/dist/esm/webWorkerManager/webWorkerManager.js.map +1 -1
  111. package/dist/types/RenderingEngine/RenderingEngine.d.ts.map +1 -1
  112. package/dist/types/RenderingEngine/Viewport.d.ts +1 -2
  113. package/dist/types/RenderingEngine/Viewport.d.ts.map +1 -1
  114. package/dist/types/RenderingEngine/VolumeViewport.d.ts +14 -2
  115. package/dist/types/RenderingEngine/VolumeViewport.d.ts.map +1 -1
  116. package/dist/types/RenderingEngine/VolumeViewport3D.d.ts +0 -1
  117. package/dist/types/RenderingEngine/VolumeViewport3D.d.ts.map +1 -1
  118. package/dist/types/RenderingEngine/helpers/setDefaultVolumeVOI.d.ts.map +1 -1
  119. package/dist/types/cache/cache.d.ts +2 -0
  120. package/dist/types/cache/cache.d.ts.map +1 -1
  121. package/dist/types/cache/classes/ImageVolume.d.ts +1 -0
  122. package/dist/types/cache/classes/ImageVolume.d.ts.map +1 -1
  123. package/dist/types/cache/classes/Surface.d.ts +6 -3
  124. package/dist/types/cache/classes/Surface.d.ts.map +1 -1
  125. package/dist/types/cache/index.d.ts +2 -1
  126. package/dist/types/cache/index.d.ts.map +1 -1
  127. package/dist/types/constants/backgroundColors.d.ts +5 -0
  128. package/dist/types/constants/backgroundColors.d.ts.map +1 -0
  129. package/dist/types/constants/index.d.ts +2 -1
  130. package/dist/types/constants/index.d.ts.map +1 -1
  131. package/dist/types/enums/Events.d.ts +2 -1
  132. package/dist/types/enums/Events.d.ts.map +1 -1
  133. package/dist/types/index.d.ts +2 -2
  134. package/dist/types/index.d.ts.map +1 -1
  135. package/dist/types/loaders/volumeLoader.d.ts +10 -2
  136. package/dist/types/loaders/volumeLoader.d.ts.map +1 -1
  137. package/dist/types/requestPool/requestPoolManager.d.ts.map +1 -1
  138. package/dist/types/types/IGeometry.d.ts +2 -2
  139. package/dist/types/types/IGeometry.d.ts.map +1 -1
  140. package/dist/types/types/IImageVolume.d.ts +2 -1
  141. package/dist/types/types/IImageVolume.d.ts.map +1 -1
  142. package/dist/types/types/ISurface.d.ts +14 -0
  143. package/dist/types/types/ISurface.d.ts.map +1 -0
  144. package/dist/types/types/index.d.ts +2 -1
  145. package/dist/types/types/index.d.ts.map +1 -1
  146. package/dist/types/utilities/VoxelManager.d.ts +1 -1
  147. package/dist/types/utilities/VoxelManager.d.ts.map +1 -1
  148. package/dist/types/utilities/generateVolumePropsFromImageIds.d.ts.map +1 -1
  149. package/dist/types/utilities/getViewportImageIds.d.ts +4 -0
  150. package/dist/types/utilities/getViewportImageIds.d.ts.map +1 -0
  151. package/dist/types/utilities/index.d.ts +2 -1
  152. package/dist/types/utilities/index.d.ts.map +1 -1
  153. package/dist/types/webWorkerManager/webWorkerManager.d.ts +3 -3
  154. package/dist/types/webWorkerManager/webWorkerManager.d.ts.map +1 -1
  155. package/dist/umd/index.js +1 -1
  156. package/dist/umd/index.js.map +1 -1
  157. package/package.json +2 -2
  158. package/src/RenderingEngine/RenderingEngine.ts +8 -0
  159. package/src/RenderingEngine/Viewport.ts +35 -10
  160. package/src/RenderingEngine/VolumeViewport.ts +135 -16
  161. package/src/RenderingEngine/VolumeViewport3D.ts +0 -8
  162. package/src/RenderingEngine/helpers/setDefaultVolumeVOI.ts +17 -12
  163. package/src/cache/cache.ts +25 -0
  164. package/src/cache/classes/ImageVolume.ts +37 -4
  165. package/src/cache/classes/Surface.ts +16 -4
  166. package/src/cache/index.ts +2 -1
  167. package/src/constants/backgroundColors.ts +5 -0
  168. package/src/constants/index.ts +2 -0
  169. package/src/enums/Events.ts +8 -0
  170. package/src/index.ts +2 -1
  171. package/src/loaders/volumeLoader.ts +109 -43
  172. package/src/requestPool/requestPoolManager.ts +7 -1
  173. package/src/types/IGeometry.ts +2 -2
  174. package/src/types/IImageVolume.ts +9 -1
  175. package/src/types/ISurface.ts +14 -0
  176. package/src/types/index.ts +2 -0
  177. package/src/utilities/VoxelManager.ts +7 -1
  178. package/src/utilities/cacheUtils.ts +25 -1
  179. package/src/utilities/convertVolumeToStackViewport.ts +1 -1
  180. package/src/utilities/generateVolumePropsFromImageIds.ts +1 -2
  181. package/src/utilities/getViewportImageIds.ts +22 -0
  182. package/src/utilities/index.ts +2 -0
  183. package/src/webWorkerManager/webWorkerManager.js +71 -43
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/core",
3
- "version": "1.53.0",
3
+ "version": "1.54.1",
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": "881872ffe29341443f91cead0b810871a6a1929b"
50
+ "gitHead": "3cea03f5216a14ff0e24802a393fab97ba7e0b7c"
51
51
  }
@@ -305,6 +305,14 @@ class RenderingEngine implements IRenderingEngine {
305
305
 
306
306
  this.setVtkjsDrivenViewports(vtkDrivenViewportInputEntries);
307
307
  this.setCustomViewports(customRenderingViewportInputEntries);
308
+
309
+ // Making sure the setViewports api also can fill the canvas
310
+ // properly
311
+ viewportInputEntries.forEach((vp) => {
312
+ const canvas = getOrCreateCanvas(vp.element);
313
+ const { background } = vp.defaultOptions;
314
+ this.fillCanvasWithBackgroundColor(canvas, background);
315
+ });
308
316
  }
309
317
 
310
318
  /**
@@ -87,7 +87,6 @@ class Viewport implements IViewport {
87
87
  /** options for the viewport which includes orientation axis, backgroundColor and displayArea */
88
88
  options: ViewportInputOptions;
89
89
  /** informs if a new actor was added before a resetCameraClippingRange phase */
90
- protected newActorAdded = false;
91
90
  private _suppressCameraModifiedEvents = false;
92
91
  /** A flag representing if viewport methods should fire events or not */
93
92
  readonly suppressEvents: boolean;
@@ -507,7 +506,6 @@ class Viewport implements IViewport {
507
506
  const renderer = this.getRenderer();
508
507
  renderer.addActor(actor);
509
508
  this._actors.set(actorUID, Object.assign({}, actorEntry));
510
- this.newActorAdded = true;
511
509
  }
512
510
 
513
511
  /**
@@ -765,6 +763,10 @@ class Viewport implements IViewport {
765
763
  // compute the radius of the enclosing sphere
766
764
  radius = Math.sqrt(radius) * 0.5;
767
765
 
766
+ // For 3D viewport, we should increase the radius to make sure the whole
767
+ // volume is visible and we don't get clipping artifacts.
768
+ radius = this.type === ViewportType.VOLUME_3D ? radius * 10 : radius;
769
+
768
770
  const distance = this.insetImageMultiplier * radius;
769
771
 
770
772
  const viewUpToSet: Point3 =
@@ -1152,7 +1154,7 @@ class Viewport implements IViewport {
1152
1154
 
1153
1155
  // only modify the clipping planes if the camera is modified out of plane
1154
1156
  // or a new actor is added and we need to update the clipping planes
1155
- if (cameraModifiedOutOfPlane || viewUpHasChanged || this.newActorAdded) {
1157
+ if (cameraModifiedOutOfPlane || viewUpHasChanged) {
1156
1158
  const actorEntry = this.getDefaultActor();
1157
1159
  if (!actorEntry?.actor) {
1158
1160
  return;
@@ -1162,7 +1164,10 @@ class Viewport implements IViewport {
1162
1164
  this.updateClippingPlanesForActors(updatedCamera);
1163
1165
  }
1164
1166
 
1165
- if (actorIsA(actorEntry, 'vtkImageSlice')) {
1167
+ if (
1168
+ actorIsA(actorEntry, 'vtkImageSlice') ||
1169
+ this.type === ViewportType.VOLUME_3D
1170
+ ) {
1166
1171
  const renderer = this.getRenderer();
1167
1172
  renderer.resetCameraClippingRange();
1168
1173
  }
@@ -1251,12 +1256,6 @@ class Viewport implements IViewport {
1251
1256
  viewport: this,
1252
1257
  });
1253
1258
  });
1254
-
1255
- this.posProcessNewActors();
1256
- }
1257
-
1258
- protected posProcessNewActors(): void {
1259
- this.newActorAdded = false;
1260
1259
  }
1261
1260
 
1262
1261
  public setOrientationOfClippingPlanes(
@@ -1291,6 +1290,32 @@ class Viewport implements IViewport {
1291
1290
  vtkPlanes[1].setOrigin(newOrigin2);
1292
1291
  }
1293
1292
 
1293
+ /**
1294
+ * Method to get the clipping planes of a given actor
1295
+ * @param actorEntry - The actor entry (a specific type you'll define dependent on your code)
1296
+ * @returns vtkPlanes - An array of vtkPlane objects associated with the given actor
1297
+ */
1298
+ public getClippingPlanesForActor(actorEntry?: ActorEntry): vtkPlane[] {
1299
+ if (!actorEntry) {
1300
+ actorEntry = this.getDefaultActor();
1301
+ }
1302
+
1303
+ if (!actorEntry.actor) {
1304
+ throw new Error('Invalid actor entry: Actor is undefined');
1305
+ }
1306
+
1307
+ const mapper = actorEntry.actor.getMapper();
1308
+ let vtkPlanes = actorEntry?.clippingFilter
1309
+ ? actorEntry.clippingFilter.getClippingPlanes()
1310
+ : mapper.getClippingPlanes();
1311
+
1312
+ if (vtkPlanes.length === 0 && actorEntry?.clippingFilter) {
1313
+ vtkPlanes = [vtkPlane.newInstance(), vtkPlane.newInstance()];
1314
+ }
1315
+
1316
+ return vtkPlanes;
1317
+ }
1318
+
1294
1319
  private _getWorldDistanceViewUpAndViewRight(bounds, viewUp, viewPlaneNormal) {
1295
1320
  const viewUpCorners = this._getCorners(bounds);
1296
1321
  const viewRightCorners = this._getCorners(bounds);
@@ -17,8 +17,10 @@ import type { ViewportInput } from '../types/IViewport';
17
17
  import {
18
18
  actorIsA,
19
19
  getClosestImageId,
20
+ getSliceRange,
20
21
  getSpacingInNormalDirection,
21
22
  isImageActor,
23
+ snapFocalPointToSlice,
22
24
  triggerEvent,
23
25
  } from '../utilities';
24
26
  import BaseVolumeViewport from './BaseVolumeViewport';
@@ -88,6 +90,15 @@ class VolumeViewport extends BaseVolumeViewport {
88
90
  return numberOfSlices;
89
91
  };
90
92
 
93
+ /**
94
+ * Returns the image index associated with the volume viewport.
95
+ * @returns The image index.
96
+ */
97
+ public getSliceIndex = (): number => {
98
+ const { imageIndex } = getImageSliceDataForVolumeViewport(this);
99
+ return imageIndex;
100
+ };
101
+
91
102
  /**
92
103
  * Creates and adds volume actors for all volumes defined in the `volumeInputArray`.
93
104
  * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input.
@@ -125,26 +136,35 @@ class VolumeViewport extends BaseVolumeViewport {
125
136
  * @param orientation - The orientation to set the camera to.
126
137
  * @param immediate - Whether the `Viewport` should be rendered as soon as the camera is set.
127
138
  */
128
- public setOrientation(orientation: OrientationAxis, immediate = true): void {
139
+ public setOrientation(
140
+ orientation: OrientationAxis | OrientationVectors,
141
+ immediate = true
142
+ ): void {
129
143
  let viewPlaneNormal, viewUp;
130
144
 
131
- if (MPR_CAMERA_VALUES[orientation]) {
132
- ({ viewPlaneNormal, viewUp } = MPR_CAMERA_VALUES[orientation]);
133
- } else if (orientation === 'acquisition') {
134
- ({ viewPlaneNormal, viewUp } = this._getAcquisitionPlaneOrientation());
135
- } else {
136
- throw new Error(
137
- `Invalid orientation: ${orientation}. Use Enums.OrientationAxis instead.`
138
- );
139
- }
145
+ // check if the orientation is a string or an object
146
+ if (typeof orientation === 'string') {
147
+ if (MPR_CAMERA_VALUES[orientation]) {
148
+ ({ viewPlaneNormal, viewUp } = MPR_CAMERA_VALUES[orientation]);
149
+ } else if (orientation === 'acquisition') {
150
+ ({ viewPlaneNormal, viewUp } = this._getAcquisitionPlaneOrientation());
151
+ } else {
152
+ throw new Error(
153
+ `Invalid orientation: ${orientation}. Use Enums.OrientationAxis instead.`
154
+ );
155
+ }
140
156
 
141
- this.setCamera({
142
- viewPlaneNormal,
143
- viewUp,
144
- });
157
+ this.setCamera({
158
+ viewPlaneNormal,
159
+ viewUp,
160
+ });
145
161
 
146
- this.viewportProperties.orientation = orientation;
147
- this.resetCamera();
162
+ this.viewportProperties.orientation = orientation;
163
+ this.resetCamera();
164
+ } else {
165
+ ({ viewPlaneNormal, viewUp } = orientation);
166
+ this.applyViewOrientation(orientation);
167
+ }
148
168
 
149
169
  if (immediate) {
150
170
  this.render();
@@ -455,6 +475,105 @@ class VolumeViewport extends BaseVolumeViewport {
455
475
 
456
476
  triggerEvent(this.element, Events.VOI_MODIFIED, eventDetails);
457
477
  }
478
+
479
+ /**
480
+ * Retrieves the clipping planes for the slices in the volume viewport.
481
+ * @returns An array of vtkPlane objects representing the clipping planes, or an array of objects with normal and origin properties if raw is true.
482
+ */
483
+ getSlicesClippingPlanes(): Array<{
484
+ sliceIndex: number;
485
+ planes: Array<{
486
+ normal: Point3;
487
+ origin: Point3;
488
+ }>;
489
+ }> {
490
+ const focalPoints = this.getSlicePlaneCoordinates();
491
+ const { viewPlaneNormal } = this.getCamera();
492
+ const slabThickness = RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;
493
+
494
+ return focalPoints.map(({ point, sliceIndex }) => {
495
+ const vtkPlanes = [vtkPlane.newInstance(), vtkPlane.newInstance()];
496
+
497
+ this.setOrientationOfClippingPlanes(
498
+ vtkPlanes,
499
+ slabThickness,
500
+ viewPlaneNormal,
501
+ point
502
+ );
503
+
504
+ return {
505
+ sliceIndex,
506
+ planes: vtkPlanes.map((plane) => ({
507
+ normal: plane.getNormal(),
508
+ origin: plane.getOrigin(),
509
+ })),
510
+ };
511
+ });
512
+ }
513
+
514
+ /**
515
+ * Returns an array of 3D coordinates representing the slice plane positions.
516
+ * It starts by the focal point as a reference point on the current slice that
517
+ * the camera is looking at, and then it calculates the slice plane positions
518
+ * by moving the focal point in the direction of the view plane normal back and
519
+ * forward, and snaps them to the slice.
520
+ *
521
+ * @returns An array of Point3 representing the slice plane coordinates.
522
+ */
523
+ public getSlicePlaneCoordinates = (): Array<{
524
+ sliceIndex: number;
525
+ point: Point3;
526
+ }> => {
527
+ const actorEntry = this.getDefaultActor();
528
+
529
+ if (!actorEntry?.actor) {
530
+ console.warn('No image data found for calculating vtkPlanes.');
531
+ return [];
532
+ }
533
+
534
+ const volumeId = actorEntry.uid;
535
+ const imageVolume = cache.getVolume(volumeId);
536
+
537
+ const camera = this.getCamera();
538
+ const { focalPoint, position, viewPlaneNormal } = camera;
539
+ const spacingInNormalDirection = getSpacingInNormalDirection(
540
+ imageVolume,
541
+ viewPlaneNormal
542
+ );
543
+ const sliceRange = getSliceRange(
544
+ actorEntry.actor as vtkVolume,
545
+ viewPlaneNormal,
546
+ focalPoint
547
+ );
548
+
549
+ // calculate the number of slices that is possible to visit
550
+ // in the direction of the view back and forward
551
+ const numSlicesBackward = Math.round(
552
+ (sliceRange.current - sliceRange.min) / spacingInNormalDirection
553
+ );
554
+
555
+ const numSlicesForward = Math.round(
556
+ (sliceRange.max - sliceRange.current) / spacingInNormalDirection
557
+ );
558
+
559
+ const currentSliceIndex = this.getSliceIndex();
560
+ const focalPoints = [];
561
+
562
+ for (let i = -numSlicesBackward; i <= numSlicesForward; i++) {
563
+ const { newFocalPoint: point } = snapFocalPointToSlice(
564
+ focalPoint,
565
+ position,
566
+ sliceRange,
567
+ viewPlaneNormal,
568
+ spacingInNormalDirection,
569
+ i
570
+ );
571
+
572
+ focalPoints.push({ sliceIndex: currentSliceIndex + i, point });
573
+ }
574
+
575
+ return focalPoints;
576
+ };
458
577
  }
459
578
 
460
579
  export default VolumeViewport;
@@ -46,14 +46,6 @@ class VolumeViewport3D extends BaseVolumeViewport {
46
46
  return null;
47
47
  };
48
48
 
49
- posProcessNewActors(): void {
50
- if (this.newActorAdded) {
51
- const renderer = this.getRenderer();
52
- renderer.resetCameraClippingRange();
53
- }
54
- super.posProcessNewActors();
55
- }
56
-
57
49
  setSlabThickness(
58
50
  slabThickness: number,
59
51
  filterActorUIDs?: Array<string>
@@ -8,6 +8,7 @@ import { loadAndCacheImage } from '../../loaders/imageLoader';
8
8
  import * as metaData from '../../metaData';
9
9
  import { getMinMax, windowLevel } from '../../utilities';
10
10
  import { RequestType } from '../../enums';
11
+ import cache from '../../cache';
11
12
 
12
13
  const PRIORITY = 0;
13
14
  const REQUEST_TYPE = RequestType.Prefetch;
@@ -175,20 +176,24 @@ async function getVOIFromMinMax(
175
176
  // instead. For the first scenario, we use the arrayBuffer of the volume to get the correct
176
177
  // slice for the imageScalarData, and for the second scenario we use the getPixelData
177
178
  // on the Cornerstone IImage object to get the pixel data.
178
- const image = await loadAndCacheImage(imageId, options);
179
-
180
- let imageScalarData;
181
- if (!image) {
182
- imageScalarData = _getImageScalarDataFromImageVolume(
183
- imageVolume,
184
- byteOffset,
185
- bytePerPixel,
186
- voxelsPerImage
187
- );
188
- } else {
189
- imageScalarData = image.getPixelData();
179
+ // Note: we don't want to use the derived or generated images for setting the
180
+ // default VOI, because they are not the original. This is ugly but don't
181
+ // know how to do it better.
182
+ let image = cache.getImage(imageId);
183
+
184
+ if (!image?.referencedImageId) {
185
+ image = await loadAndCacheImage(imageId, options);
190
186
  }
191
187
 
188
+ const imageScalarData = image
189
+ ? image.getPixelData()
190
+ : _getImageScalarDataFromImageVolume(
191
+ imageVolume,
192
+ byteOffset,
193
+ bytePerPixel,
194
+ voxelsPerImage
195
+ );
196
+
192
197
  // Get the min and max pixel values of the middle slice
193
198
  const { min, max } = getMinMax(imageScalarData);
194
199
 
@@ -704,6 +704,31 @@ class Cache implements ICache {
704
704
  return cachedVolume.volume;
705
705
  };
706
706
 
707
+ /**
708
+ * Retrieves an array of image volumes from the cache.
709
+ * @returns An array of image volumes.
710
+ */
711
+ public getVolumes = (): Array<IImageVolume> => {
712
+ const cachedVolumes = Array.from(this._volumeCache.values());
713
+
714
+ return cachedVolumes.map((cachedVolume) => cachedVolume.volume);
715
+ };
716
+
717
+ /**
718
+ * Filters the cached volumes by the specified reference volume ID.
719
+ * @param volumeId - The ID of the reference volume.
720
+ * @returns An array of image volumes that have the specified reference volume ID.
721
+ */
722
+ public filterVolumesByReferenceId = (
723
+ volumeId: string
724
+ ): Array<IImageVolume> => {
725
+ const cachedVolumes = this.getVolumes();
726
+
727
+ return cachedVolumes.filter((volume) => {
728
+ return volume.referencedVolumeId === volumeId;
729
+ });
730
+ };
731
+
707
732
  /**
708
733
  * Removes the image loader associated with a given Id from the cache
709
734
  *
@@ -238,6 +238,26 @@ export class ImageVolume implements IImageVolume {
238
238
  : [<PixelDataTypedArray>this.scalarData];
239
239
  }
240
240
 
241
+ /**
242
+ * Updates the internals of the volume to reflect the changes in the
243
+ * underlying scalar data. This should be called when the scalar data
244
+ * is modified externally
245
+ */
246
+ public modified() {
247
+ this.imageData.modified();
248
+
249
+ if (this.isDynamicVolume()) {
250
+ throw new Error('Not implemented');
251
+ } else {
252
+ this.scalarData = this.imageData
253
+ .getPointData()
254
+ .getScalars()
255
+ .getData() as PixelDataTypedArray;
256
+ }
257
+
258
+ this.numFrames = this._getNumFrames();
259
+ }
260
+
241
261
  /**
242
262
  * If completelyRemove is true, remove the volume completely from the cache. Otherwise,
243
263
  * convert the volume to cornerstone images (stack images) and store it in the cache
@@ -529,10 +549,12 @@ export class ImageVolume implements IImageVolume {
529
549
  // check if the referenced volume has imageIds to see how many
530
550
  // images we need to generate
531
551
  const referencedVolumeId = this.referencedVolumeId;
532
- const referencedVolume = cache.getVolume(referencedVolumeId);
533
552
 
534
- const numSlices =
535
- referencedVolume?.imageIds?.length || this.dimensions[2];
553
+ let numSlices = this.dimensions[2];
554
+ if (referencedVolumeId) {
555
+ const referencedVolume = cache.getVolume(referencedVolumeId);
556
+ numSlices = referencedVolume?.imageIds?.length ?? numSlices;
557
+ }
536
558
 
537
559
  this.imageIds = Array.from({ length: numSlices }, (_, i) => {
538
560
  return `generated:${this.volumeId}:${i}`;
@@ -667,7 +689,18 @@ export class ImageVolume implements IImageVolume {
667
689
  );
668
690
  }
669
691
  // 5. When as much of the Volume is processed into Images as possible
670
- // without breaching the cache limit, remove the Volume
692
+ // without breaching the cache limit, remove the Volume
693
+ // but first check if the volume is referenced as a derived
694
+ // volume by another volume, then we need to update their referencedVolumeId
695
+ // to be now the referencedImageIds of this volume
696
+ const otherVolumes = cache.filterVolumesByReferenceId(this.volumeId);
697
+
698
+ if (otherVolumes.length) {
699
+ otherVolumes.forEach((volume) => {
700
+ volume.referencedImageIds = this.imageIds;
701
+ });
702
+ }
703
+
671
704
  this.removeFromCache();
672
705
 
673
706
  return this.imageIds;
@@ -1,4 +1,4 @@
1
- import { SurfaceData, Point3 } from '../../types';
1
+ import { SurfaceData, Point3, ISurface, Color, RGB } from '../../types';
2
2
 
3
3
  type SurfaceProps = {
4
4
  id: string;
@@ -10,11 +10,11 @@ type SurfaceProps = {
10
10
  /**
11
11
  * Surface class for storing surface data
12
12
  */
13
- export class Surface {
13
+ export class Surface implements ISurface {
14
14
  readonly id: string;
15
15
  readonly sizeInBytes: number;
16
16
  readonly frameOfReferenceUID: string;
17
- private color: Point3 = [200, 0, 0]; // default color
17
+ private color: RGB = [200, 0, 0]; // default color
18
18
  private points: number[];
19
19
  private polys: number[];
20
20
 
@@ -31,7 +31,7 @@ export class Surface {
31
31
  return this.points.length * 4 + this.polys.length * 4;
32
32
  }
33
33
 
34
- public getColor(): Point3 {
34
+ public getColor(): RGB {
35
35
  return this.color;
36
36
  }
37
37
 
@@ -43,6 +43,18 @@ export class Surface {
43
43
  return this.polys;
44
44
  }
45
45
 
46
+ public setColor(color: RGB): void {
47
+ this.color = color;
48
+ }
49
+
50
+ public setPoints(points: number[]): void {
51
+ this.points = points;
52
+ }
53
+
54
+ public setPolys(polys: number[]): void {
55
+ this.polys = polys;
56
+ }
57
+
46
58
  public getSizeInBytes(): number {
47
59
  return this.sizeInBytes;
48
60
  }
@@ -1,5 +1,6 @@
1
1
  import cache, { Cache } from './cache';
2
2
  import ImageVolume from './classes/ImageVolume';
3
+ import { Surface } from './classes/Surface';
3
4
 
4
- export { ImageVolume, Cache };
5
+ export { ImageVolume, Cache, Surface };
5
6
  export default cache;
@@ -0,0 +1,5 @@
1
+ const backgroundColors = {
2
+ slicer3D: [160 / 255, 164 / 255, 217 / 255],
3
+ };
4
+
5
+ export default backgroundColors;
@@ -3,6 +3,7 @@ import RENDERING_DEFAULTS from './rendering';
3
3
  import EPSILON from './epsilon';
4
4
  import MPR_CAMERA_VALUES from './mprCameraValues';
5
5
  import VIEWPORT_PRESETS from './viewportPresets';
6
+ import BACKGROUND_COLORS from './backgroundColors';
6
7
 
7
8
  export {
8
9
  CPU_COLORMAPS,
@@ -10,4 +11,5 @@ export {
10
11
  MPR_CAMERA_VALUES,
11
12
  EPSILON,
12
13
  VIEWPORT_PRESETS,
14
+ BACKGROUND_COLORS,
13
15
  };
@@ -215,6 +215,14 @@ enum Events {
215
215
  * Triggers when the clipping planes has been updated
216
216
  */
217
217
  CLIPPING_PLANES_UPDATED = 'CORNERSTONE_CLIPPING_PLANES_UPDATED',
218
+
219
+ /**
220
+ * Triggers when the webworker has made progress
221
+ * You should use it with a workerType to indicate the type of worker that is making progress
222
+ * Checkout the polySEG convertors in the cornerstone tools
223
+ * to lean how to use it
224
+ */
225
+ WEB_WORKER_PROGRESS = 'CORNERSTONE_WEB_WORKER_PROGRESS',
218
226
  // IMAGE_CACHE_FULL = 'CORNERSTONE_IMAGE_CACHE_FULL',
219
227
  // PRE_RENDER = 'CORNERSTONE_PRE_RENDER',
220
228
  // ELEMENT_RESIZED = 'CORNERSTONE_ELEMENT_RESIZED',
package/src/index.ts CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  getRenderingEngine,
20
20
  getRenderingEngines,
21
21
  } from './RenderingEngine/getRenderingEngine';
22
- import cache, { ImageVolume } from './cache';
22
+ import cache, { ImageVolume, Surface } from './cache';
23
23
  import imageRetrievalPoolManager from './requestPool/imageRetrievalPoolManager';
24
24
  import imageLoadPoolManager from './requestPool/imageLoadPoolManager';
25
25
 
@@ -103,6 +103,7 @@ export {
103
103
  VideoViewport,
104
104
  RenderingEngine,
105
105
  ImageVolume,
106
+ Surface,
106
107
  // Helpers
107
108
  getRenderingEngine,
108
109
  getRenderingEngines,