@cornerstonejs/core 2.0.0-beta.26 → 2.0.0-beta.28

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 (150) hide show
  1. package/dist/esm/RenderingEngine/BaseVolumeViewport.d.ts +5 -1
  2. package/dist/esm/RenderingEngine/BaseVolumeViewport.js +56 -32
  3. package/dist/esm/RenderingEngine/RenderingEngine.js +7 -3
  4. package/dist/esm/RenderingEngine/StackViewport.d.ts +1 -2
  5. package/dist/esm/RenderingEngine/StackViewport.js +70 -85
  6. package/dist/esm/RenderingEngine/VideoViewport.js +50 -25
  7. package/dist/esm/RenderingEngine/Viewport.d.ts +3 -1
  8. package/dist/esm/RenderingEngine/Viewport.js +14 -8
  9. package/dist/esm/RenderingEngine/VolumeViewport.d.ts +1 -1
  10. package/dist/esm/RenderingEngine/VolumeViewport.js +15 -17
  11. package/dist/esm/RenderingEngine/VolumeViewport3D.d.ts +4 -1
  12. package/dist/esm/RenderingEngine/VolumeViewport3D.js +23 -3
  13. package/dist/esm/RenderingEngine/WSIViewport.d.ts +1 -1
  14. package/dist/esm/RenderingEngine/WSIViewport.js +31 -18
  15. package/dist/esm/RenderingEngine/helpers/createVolumeActor.js +2 -0
  16. package/dist/esm/RenderingEngine/helpers/setDefaultVolumeVOI.js +10 -11
  17. package/dist/esm/cache/cache.d.ts +1 -1
  18. package/dist/esm/cache/cache.js +8 -2
  19. package/dist/esm/cache/classes/StreamingDynamicImageVolume.js +2 -0
  20. package/dist/esm/enums/Events.d.ts +1 -1
  21. package/dist/esm/enums/Events.js +1 -1
  22. package/dist/esm/loaders/configuration/interleavedRetrieve.js +0 -3
  23. package/dist/esm/loaders/configuration/singleRetrieve.js +0 -3
  24. package/dist/esm/loaders/imageLoader.d.ts +9 -4
  25. package/dist/esm/loaders/imageLoader.js +55 -42
  26. package/dist/esm/loaders/index.d.ts +6 -0
  27. package/dist/esm/loaders/index.js +7 -0
  28. package/dist/esm/loaders/volumeLoader.d.ts +8 -4
  29. package/dist/esm/loaders/volumeLoader.js +26 -7
  30. package/dist/esm/types/AABB2.js +0 -1
  31. package/dist/esm/types/AABB3.js +0 -1
  32. package/dist/esm/types/ActorSliceRange.js +0 -1
  33. package/dist/esm/types/AffineMatrix.js +0 -1
  34. package/dist/esm/types/BoundsIJK.js +0 -1
  35. package/dist/esm/types/BoundsLPS.js +0 -1
  36. package/dist/esm/types/CPUFallbackColormap.js +0 -1
  37. package/dist/esm/types/CPUFallbackColormapData.js +0 -1
  38. package/dist/esm/types/CPUFallbackColormapsData.js +0 -1
  39. package/dist/esm/types/CPUFallbackEnabledElement.js +0 -1
  40. package/dist/esm/types/CPUFallbackLUT.js +0 -1
  41. package/dist/esm/types/CPUFallbackLookupTable.js +0 -1
  42. package/dist/esm/types/CPUFallbackRenderingTools.js +0 -1
  43. package/dist/esm/types/CPUFallbackTransform.js +0 -1
  44. package/dist/esm/types/CPUFallbackViewport.js +0 -1
  45. package/dist/esm/types/CPUFallbackViewportDisplayedArea.js +0 -1
  46. package/dist/esm/types/CPUIImageData.js +0 -1
  47. package/dist/esm/types/Color.js +0 -1
  48. package/dist/esm/types/Colormap.js +0 -1
  49. package/dist/esm/types/ContourData.js +0 -1
  50. package/dist/esm/types/Cornerstone3DConfig.js +0 -1
  51. package/dist/esm/types/CustomEventType.js +0 -1
  52. package/dist/esm/types/EventTypes.js +0 -1
  53. package/dist/esm/types/FlipDirection.js +0 -1
  54. package/dist/esm/types/IActor.js +0 -1
  55. package/dist/esm/types/IBaseVolumeViewport.js +0 -1
  56. package/dist/esm/types/ICache.js +0 -1
  57. package/dist/esm/types/ICachedGeometry.js +0 -1
  58. package/dist/esm/types/ICachedImage.js +0 -1
  59. package/dist/esm/types/ICachedVolume.js +0 -1
  60. package/dist/esm/types/ICamera.js +0 -1
  61. package/dist/esm/types/IContour.js +0 -1
  62. package/dist/esm/types/IContourSet.js +0 -1
  63. package/dist/esm/types/IDynamicImageVolume.js +0 -1
  64. package/dist/esm/types/IEnabledElement.js +0 -1
  65. package/dist/esm/types/IGeometry.js +0 -1
  66. package/dist/esm/types/IImage.js +0 -1
  67. package/dist/esm/types/IImageCalibration.js +0 -1
  68. package/dist/esm/types/IImageData.js +0 -1
  69. package/dist/esm/types/IImageFrame.js +0 -1
  70. package/dist/esm/types/IImageVolume.js +0 -1
  71. package/dist/esm/types/ILoadObject.js +0 -1
  72. package/dist/esm/types/IPointsManager.js +0 -1
  73. package/dist/esm/types/IRLEVoxelMap.js +0 -1
  74. package/dist/esm/types/IRegisterImageLoader.js +0 -1
  75. package/dist/esm/types/IRenderingEngine.js +0 -1
  76. package/dist/esm/types/IRetrieveConfiguration.js +0 -1
  77. package/dist/esm/types/IStackInput.js +0 -1
  78. package/dist/esm/types/IStackViewport.js +0 -1
  79. package/dist/esm/types/IStreamingImageVolume.js +0 -1
  80. package/dist/esm/types/IStreamingVolumeProperties.js +0 -1
  81. package/dist/esm/types/ISurface.js +0 -1
  82. package/dist/esm/types/ITransferFunctionNode.js +0 -1
  83. package/dist/esm/types/IVideoViewport.js +0 -1
  84. package/dist/esm/types/IViewport.js +0 -1
  85. package/dist/esm/types/IViewportId.js +0 -1
  86. package/dist/esm/types/IVolume.js +0 -1
  87. package/dist/esm/types/IVolumeInput.js +0 -1
  88. package/dist/esm/types/IVolumeViewport.js +0 -1
  89. package/dist/esm/types/IVoxelManager.js +0 -1
  90. package/dist/esm/types/IWSIViewport.js +0 -1
  91. package/dist/esm/types/ImageLoadListener.js +0 -1
  92. package/dist/esm/types/ImageLoadRequests.js +0 -1
  93. package/dist/esm/types/ImageLoaderFn.js +0 -1
  94. package/dist/esm/types/ImagePixelModule.js +0 -1
  95. package/dist/esm/types/ImagePlaneModule.js +0 -1
  96. package/dist/esm/types/ImageSliceData.js +0 -1
  97. package/dist/esm/types/ImageVolumeProps.js +0 -1
  98. package/dist/esm/types/Mat3.js +0 -1
  99. package/dist/esm/types/Metadata.js +0 -1
  100. package/dist/esm/types/MetadataModuleTypes.d.ts +4 -4
  101. package/dist/esm/types/MetadataModuleTypes.js +0 -1
  102. package/dist/esm/types/OrientationVectors.js +0 -1
  103. package/dist/esm/types/PixelDataTypedArray.js +0 -1
  104. package/dist/esm/types/Plane.js +0 -1
  105. package/dist/esm/types/Point2.js +0 -1
  106. package/dist/esm/types/Point3.js +0 -1
  107. package/dist/esm/types/Point4.js +0 -1
  108. package/dist/esm/types/RGB.js +0 -1
  109. package/dist/esm/types/ScalingParameters.js +0 -1
  110. package/dist/esm/types/StackViewportProperties.js +0 -1
  111. package/dist/esm/types/SurfaceData.js +0 -1
  112. package/dist/esm/types/TransformMatrix2D.js +0 -1
  113. package/dist/esm/types/VideoViewportProperties.js +0 -1
  114. package/dist/esm/types/VideoViewportTypes.js +0 -1
  115. package/dist/esm/types/ViewportInputOptions.js +0 -1
  116. package/dist/esm/types/ViewportPreset.js +0 -1
  117. package/dist/esm/types/ViewportProperties.d.ts +1 -0
  118. package/dist/esm/types/ViewportProperties.js +0 -1
  119. package/dist/esm/types/VolumeLoaderFn.js +0 -1
  120. package/dist/esm/types/VolumeProps.js +0 -1
  121. package/dist/esm/types/VolumeViewportProperties.js +0 -1
  122. package/dist/esm/types/WSIViewportProperties.js +0 -1
  123. package/dist/esm/types/displayArea.js +0 -1
  124. package/dist/esm/types/index.js +0 -1
  125. package/dist/esm/types/voi.js +0 -1
  126. package/dist/esm/utilities/VoxelManager.d.ts +3 -1
  127. package/dist/esm/utilities/VoxelManager.js +15 -9
  128. package/dist/esm/utilities/autoLoad.js +1 -1
  129. package/dist/esm/utilities/convertVolumeToStackViewport.js +1 -3
  130. package/dist/esm/utilities/createSigmoidRGBTransferFunction.d.ts +2 -1
  131. package/dist/esm/utilities/deepClone.d.ts +1 -0
  132. package/dist/esm/utilities/deepClone.js +28 -0
  133. package/dist/esm/utilities/eventListener/TargetEventListeners.js +1 -1
  134. package/dist/esm/utilities/getViewportImageIds.js +1 -3
  135. package/dist/esm/utilities/getViewportModality.js +1 -1
  136. package/dist/esm/utilities/getViewportsWithImageURI.d.ts +3 -3
  137. package/dist/esm/utilities/getViewportsWithImageURI.js +2 -9
  138. package/dist/esm/utilities/getViewportsWithVolumeId.d.ts +1 -1
  139. package/dist/esm/utilities/getViewportsWithVolumeId.js +3 -5
  140. package/dist/esm/utilities/getViewportsWithVolumeURI.d.ts +3 -0
  141. package/dist/esm/utilities/getViewportsWithVolumeURI.js +14 -0
  142. package/dist/esm/utilities/index.d.ts +3 -1
  143. package/dist/esm/utilities/index.js +3 -1
  144. package/dist/esm/utilities/loadImageToCanvas.js +0 -4
  145. package/dist/esm/utilities/pointInShapeCallback.d.ts +24 -0
  146. package/dist/esm/utilities/pointInShapeCallback.js +92 -0
  147. package/dist/esm/webWorkerManager/webWorkerManager.d.ts +11 -4
  148. package/package.json +56 -29
  149. package/dist/umd/index.js +0 -2
  150. package/dist/umd/index.js.map +0 -1
@@ -7,6 +7,8 @@ import Viewport from './Viewport';
7
7
  import { getOrCreateCanvas } from './helpers';
8
8
  import CanvasActor from './CanvasActor';
9
9
  import cache from '../cache/cache';
10
+ import uuidv4 from '../utilities/uuidv4';
11
+ import { pointInShapeCallback } from '../utilities/pointInShapeCallback';
10
12
  class VideoViewport extends Viewport {
11
13
  static { this.frameRangeExtractor = /(\/frames\/|[&?]frameNumber=)([^/&?]*)/i; }
12
14
  constructor(props) {
@@ -110,12 +112,14 @@ class VideoViewport extends Viewport {
110
112
  this.renderFrame();
111
113
  };
112
114
  this.renderFrame = () => {
115
+ const dpr = window.devicePixelRatio || 1;
113
116
  const transform = this.getTransform();
114
117
  const transformationMatrix = transform.getMatrix();
115
118
  const ctx = this.canvasContext;
116
119
  ctx.resetTransform();
117
- ctx.transform(transformationMatrix[0], transformationMatrix[1], transformationMatrix[2], transformationMatrix[3], transformationMatrix[4], transformationMatrix[5]);
118
- ctx.drawImage(this.videoElement, 0, 0, this.videoWidth || 1024, this.videoHeight || 1024);
120
+ ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
121
+ ctx.transform(transformationMatrix[0] / dpr, transformationMatrix[1] / dpr, transformationMatrix[2] / dpr, transformationMatrix[3] / dpr, transformationMatrix[4] / dpr, transformationMatrix[5] / dpr);
122
+ ctx.drawImage(this.videoElement, 0, 0, this.videoWidth, this.videoHeight);
119
123
  for (const actor of this.getActors()) {
120
124
  actor.actor.render(this, this.canvasContext);
121
125
  }
@@ -138,7 +142,7 @@ class VideoViewport extends Viewport {
138
142
  time: this.videoElement.currentTime,
139
143
  duration: this.videoElement.duration,
140
144
  });
141
- this.initialRender();
145
+ this.initialRender?.();
142
146
  const frame = this.getFrameNumber();
143
147
  if (this.isPlaying) {
144
148
  if (frame < this.frameRange[0]) {
@@ -225,7 +229,7 @@ class VideoViewport extends Viewport {
225
229
  };
226
230
  }
227
231
  setDataIds(imageIds, options) {
228
- this.setVideo(imageIds[0], (options.viewReference.sliceIndex || 0) + 1);
232
+ this.setVideo(imageIds[0], (options.viewReference?.sliceIndex || 0) + 1);
229
233
  }
230
234
  setVideo(imageId, frameNumber) {
231
235
  this.imageId = Array.isArray(imageId) ? imageId[0] : imageId;
@@ -423,15 +427,24 @@ class VideoViewport extends Viewport {
423
427
  });
424
428
  }
425
429
  getScalarData() {
426
- if (this.scalarData.frameNumber === this.getFrameNumber()) {
430
+ if (this.scalarData?.frameNumber === this.getFrameNumber()) {
427
431
  return this.scalarData;
428
432
  }
433
+ if (!this.videoElement ||
434
+ !this.videoElement.videoWidth ||
435
+ !this.videoElement.videoHeight) {
436
+ console.debug('Video not ready yet, returning empty scalar data');
437
+ const emptyData = new Uint8ClampedArray();
438
+ emptyData.getRange = () => [0, 255];
439
+ emptyData.frameNumber = -1;
440
+ return emptyData;
441
+ }
429
442
  const canvas = document.createElement('canvas');
430
- canvas.width = this.videoWidth;
431
- canvas.height = this.videoHeight;
443
+ canvas.width = this.videoElement.videoWidth;
444
+ canvas.height = this.videoElement.videoHeight;
432
445
  const context = canvas.getContext('2d');
433
446
  context.drawImage(this.videoElement, 0, 0);
434
- const canvasData = context.getImageData(0, 0, this.videoWidth, this.videoHeight);
447
+ const canvasData = context.getImageData(0, 0, canvas.width, canvas.height);
435
448
  const scalarData = canvasData.data;
436
449
  scalarData.getRange = () => [0, 255];
437
450
  scalarData.frameNumber = this.getFrameNumber();
@@ -442,6 +455,22 @@ class VideoViewport extends Viewport {
442
455
  const { metadata } = this;
443
456
  const spacing = metadata.spacing;
444
457
  const imageData = {
458
+ getDirection: () => metadata.direction,
459
+ getDimensions: () => metadata.dimensions,
460
+ getRange: () => [0, 255],
461
+ getScalarData: () => this.getScalarData(),
462
+ getSpacing: () => metadata.spacing,
463
+ worldToIndex: (point) => {
464
+ const canvasPoint = this.worldToCanvas(point);
465
+ const pixelCoord = this.canvasToIndex(canvasPoint);
466
+ return [pixelCoord[0], pixelCoord[1], 0];
467
+ },
468
+ indexToWorld: (point, destPoint) => {
469
+ const canvasPoint = this.indexToCanvas([point[0], point[1]]);
470
+ return this.canvasToWorld(canvasPoint, destPoint);
471
+ },
472
+ };
473
+ const imageDataForReturn = {
445
474
  dimensions: metadata.dimensions,
446
475
  spacing,
447
476
  origin: metadata.origin,
@@ -452,20 +481,15 @@ class VideoViewport extends Viewport {
452
481
  },
453
482
  getScalarData: () => this.getScalarData(),
454
483
  scalarData: this.getScalarData(),
455
- imageData: {
456
- getDirection: () => metadata.direction,
457
- getDimensions: () => metadata.dimensions,
458
- getRange: () => [0, 255],
459
- getScalarData: () => this.getScalarData(),
460
- getSpacing: () => metadata.spacing,
461
- worldToIndex: (point) => {
462
- const canvasPoint = this.worldToCanvas(point);
463
- const pixelCoord = this.canvasToIndex(canvasPoint);
464
- return [pixelCoord[0], pixelCoord[1], 0];
465
- },
466
- indexToWorld: (point, destPoint) => {
467
- const canvasPoint = this.indexToCanvas([point[0], point[1]]);
468
- return this.canvasToWorld(canvasPoint, destPoint);
484
+ imageData,
485
+ voxelManager: {
486
+ forEach: (callback, options) => {
487
+ return pointInShapeCallback(options.imageData, {
488
+ pointInShapeFn: options.isInObject ?? (() => true),
489
+ callback: callback,
490
+ boundsIJK: options.boundsIJK,
491
+ returnPoints: options.returnPoints ?? false,
492
+ });
469
493
  },
470
494
  },
471
495
  hasPixelSpacing: this.hasPixelSpacing,
@@ -478,7 +502,7 @@ class VideoViewport extends Viewport {
478
502
  get: () => this.getScalarData(),
479
503
  enumerable: true,
480
504
  });
481
- return imageData;
505
+ return imageDataForReturn;
482
506
  }
483
507
  hasImageURI(imageURI) {
484
508
  const framesMatch = imageURI.match(VideoViewport.frameRangeExtractor);
@@ -612,7 +636,7 @@ class VideoViewport extends Viewport {
612
636
  }
613
637
  }
614
638
  getViewReference(viewRefSpecifier) {
615
- let sliceIndex = viewRefSpecifier.sliceIndex;
639
+ let sliceIndex = viewRefSpecifier?.sliceIndex ?? this.getSliceIndex();
616
640
  if (!sliceIndex) {
617
641
  sliceIndex = this.isPlaying
618
642
  ? [this.frameRange[0] - 1, this.frameRange[1] - 1]
@@ -704,8 +728,9 @@ class VideoViewport extends Viewport {
704
728
  stackInputs.forEach((stackInput) => {
705
729
  const image = cache.getImage(stackInput.imageId);
706
730
  const imageActor = this.createActorMapper(image);
731
+ const uid = stackInput.actorUID ?? uuidv4();
707
732
  if (imageActor) {
708
- actors.push({ uid: stackInput.actorUID, actor: imageActor });
733
+ actors.push({ uid, actor: imageActor });
709
734
  if (stackInput.callback) {
710
735
  stackInput.callback({
711
736
  imageActor: imageActor,
@@ -77,7 +77,9 @@ declare class Viewport {
77
77
  setActors(actors: ActorEntry[]): void;
78
78
  _removeActor(actorUID: string): void;
79
79
  removeActors(actorUIDs: string[]): void;
80
- addActors(actors: ActorEntry[], resetCameraPanAndZoom?: boolean): void;
80
+ addActors(actors: ActorEntry[], options?: {
81
+ resetCamera?: boolean;
82
+ }): void;
81
83
  addActor(actorEntry: ActorEntry): void;
82
84
  removeAllActors(): void;
83
85
  protected resetCameraNoEvent(): void;
@@ -199,8 +199,7 @@ class Viewport {
199
199
  }
200
200
  setActors(actors) {
201
201
  this.removeAllActors();
202
- const resetCameraPanAndZoom = true;
203
- this.addActors(actors, resetCameraPanAndZoom);
202
+ this.addActors(actors, { resetCamera: true });
204
203
  }
205
204
  _removeActor(actorUID) {
206
205
  const actorEntry = this.getActor(actorUID);
@@ -217,7 +216,8 @@ class Viewport {
217
216
  this._removeActor(actorUID);
218
217
  });
219
218
  }
220
- addActors(actors, resetCameraPanAndZoom = false) {
219
+ addActors(actors, options = {}) {
220
+ const { resetCamera = false } = options;
221
221
  const renderingEngine = this.getRenderingEngine();
222
222
  if (!renderingEngine || renderingEngine.hasBeenDestroyed) {
223
223
  console.warn('Viewport::addActors::Rendering engine has not been initialized or has been destroyed');
@@ -226,10 +226,13 @@ class Viewport {
226
226
  actors.forEach((actor) => {
227
227
  this.addActor(actor);
228
228
  });
229
- this.resetCamera({
230
- resetPan: resetCameraPanAndZoom,
231
- resetZoom: resetCameraPanAndZoom,
232
- });
229
+ const prevViewPresentation = this.getViewPresentation();
230
+ const prevViewRef = this.getViewReference();
231
+ this.resetCamera();
232
+ if (!resetCamera) {
233
+ this.setViewReference(prevViewRef);
234
+ this.setViewPresentation(prevViewPresentation);
235
+ }
233
236
  }
234
237
  addActor(actorEntry) {
235
238
  const { uid: actorUID, actor } = actorEntry;
@@ -498,6 +501,9 @@ class Viewport {
498
501
  this.fitToCanvasCamera = camera;
499
502
  }
500
503
  getPan(initialCamera = this.initialCamera) {
504
+ if (!initialCamera) {
505
+ return [0, 0];
506
+ }
501
507
  const activeCamera = this.getVtkActiveCamera();
502
508
  const focalPoint = activeCamera.getFocalPoint();
503
509
  const zero3 = this.canvasToWorld([0, 0]);
@@ -664,7 +670,7 @@ class Viewport {
664
670
  }
665
671
  if (cameraModifiedOutOfPlane || viewUpHasChanged) {
666
672
  const actorEntry = this.getDefaultActor();
667
- if (!actorEntry.actor) {
673
+ if (!actorEntry?.actor) {
668
674
  return;
669
675
  }
670
676
  if (!actorIsA(actorEntry, 'vtkActor')) {
@@ -11,6 +11,7 @@ declare class VolumeViewport extends BaseVolumeViewport {
11
11
  getNumberOfSlices: () => number;
12
12
  addVolumes(volumeInputArray: IVolumeInput[], immediate?: boolean, suppressEvents?: boolean): Promise<void>;
13
13
  setOrientation(orientation: OrientationAxis | OrientationVectors, immediate?: boolean): void;
14
+ protected setCameraClippingRange(): void;
14
15
  private _getAcquisitionPlaneOrientation;
15
16
  private _setViewPlaneToAcquisitionPlane;
16
17
  setBlendMode(blendMode: BlendModes, filterActorUIDs?: any[], immediate?: boolean): void;
@@ -33,7 +34,6 @@ declare class VolumeViewport extends BaseVolumeViewport {
33
34
  getViewReference(viewRefSpecifier?: ViewReferenceSpecifier): ViewReference;
34
35
  resetProperties(volumeId?: string): void;
35
36
  private _resetProperties;
36
- private setCameraClippingRange;
37
37
  getSlicesClippingPlanes(): {
38
38
  sliceIndex: number;
39
39
  planes: {
@@ -54,8 +54,7 @@ class VolumeViewport extends BaseVolumeViewport {
54
54
  if (!actorEntry || !actorIsA(actorEntry, 'vtkVolume')) {
55
55
  return;
56
56
  }
57
- const { uid } = actorEntry;
58
- const volume = cache.getVolume(uid);
57
+ const volume = cache.getVolume(this.getVolumeId());
59
58
  if (!volume) {
60
59
  return;
61
60
  }
@@ -68,7 +67,7 @@ class VolumeViewport extends BaseVolumeViewport {
68
67
  console.warn('No image data found for calculating vtkPlanes.');
69
68
  return [];
70
69
  }
71
- const volumeId = actorEntry.uid;
70
+ const volumeId = this.getVolumeId();
72
71
  const imageVolume = cache.getVolume(volumeId);
73
72
  const camera = this.getCamera();
74
73
  const { focalPoint, position, viewPlaneNormal } = camera;
@@ -140,12 +139,21 @@ class VolumeViewport extends BaseVolumeViewport {
140
139
  this.render();
141
140
  }
142
141
  }
142
+ setCameraClippingRange() {
143
+ const activeCamera = this.getVtkActiveCamera();
144
+ if (activeCamera.getParallelProjection()) {
145
+ activeCamera.setClippingRange(activeCamera.getDistance(), activeCamera.getDistance() + this.getSlabThickness());
146
+ }
147
+ else {
148
+ activeCamera.setClippingRange(RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE);
149
+ }
150
+ }
143
151
  _getAcquisitionPlaneOrientation() {
144
152
  const actorEntry = this.getDefaultActor();
145
153
  if (!actorEntry) {
146
154
  return;
147
155
  }
148
- const volumeId = actorEntry.uid;
156
+ const volumeId = this.getVolumeId();
149
157
  const imageVolume = cache.getVolume(volumeId);
150
158
  if (!imageVolume) {
151
159
  throw new Error(`imageVolume with id: ${volumeId} does not exist in cache`);
@@ -199,7 +207,6 @@ class VolumeViewport extends BaseVolumeViewport {
199
207
  }
200
208
  super.resetCamera({ resetPan, resetZoom, resetToCenter });
201
209
  const activeCamera = this.getVtkActiveCamera();
202
- this.setCameraClippingRange();
203
210
  const viewPlaneNormal = activeCamera.getViewPlaneNormal();
204
211
  const focalPoint = activeCamera.getFocalPoint();
205
212
  const actorEntries = this.getActors();
@@ -258,7 +265,6 @@ class VolumeViewport extends BaseVolumeViewport {
258
265
  });
259
266
  const currentCamera = this.getCamera();
260
267
  this.updateClippingPlanesForActors(currentCamera);
261
- this.setCameraClippingRange();
262
268
  this.triggerCameraModifiedEventIfNecessary(currentCamera, currentCamera);
263
269
  this.viewportProperties.slabThickness = slabThickness;
264
270
  }
@@ -366,9 +372,10 @@ class VolumeViewport extends BaseVolumeViewport {
366
372
  this.viewportProperties.slabThickness = undefined;
367
373
  this.updateClippingPlanesForActors(this.getCamera());
368
374
  }
369
- const imageVolume = cache.getVolume(volumeActor.uid);
375
+ volumeId ||= this.getVolumeId();
376
+ const imageVolume = cache.getVolume(volumeId);
370
377
  if (!imageVolume) {
371
- throw new Error(`imageVolume with id: ${volumeActor.uid} does not exist in cache`);
378
+ throw new Error(`imageVolume with id: ${volumeId} does not exist in cache`);
372
379
  }
373
380
  setDefaultVolumeVOI(volumeActor.actor, imageVolume);
374
381
  if (isImageActor(volumeActor)) {
@@ -392,15 +399,6 @@ class VolumeViewport extends BaseVolumeViewport {
392
399
  });
393
400
  triggerEvent(this.element, Events.VOI_MODIFIED, eventDetails);
394
401
  }
395
- setCameraClippingRange() {
396
- const activeCamera = this.getVtkActiveCamera();
397
- if (activeCamera.getParallelProjection()) {
398
- activeCamera.setClippingRange(activeCamera.getDistance(), activeCamera.getDistance() + this.getSlabThickness());
399
- }
400
- else {
401
- activeCamera.setClippingRange(RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE);
402
- }
403
- }
404
402
  getSlicesClippingPlanes() {
405
403
  const focalPoints = this.getSlicePlaneCoordinates();
406
404
  const { viewPlaneNormal } = this.getCamera();
@@ -3,7 +3,7 @@ import type { ViewportInput } from '../types/IViewport';
3
3
  import BaseVolumeViewport from './BaseVolumeViewport';
4
4
  declare class VolumeViewport3D extends BaseVolumeViewport {
5
5
  constructor(props: ViewportInput);
6
- resetCamera({ resetPan, resetZoom, resetToCenter, }: {
6
+ resetCamera({ resetPan, resetZoom, resetToCenter, }?: {
7
7
  resetPan?: boolean;
8
8
  resetZoom?: boolean;
9
9
  resetToCenter?: boolean;
@@ -14,6 +14,9 @@ declare class VolumeViewport3D extends BaseVolumeViewport {
14
14
  setSlabThickness(slabThickness: number, filterActorUIDs?: string[]): void;
15
15
  setBlendMode(blendMode: BlendModes, filterActorUIDs?: string[], immediate?: boolean): void;
16
16
  resetProperties(volumeId?: string): void;
17
+ resetCameraForResize: () => boolean;
18
+ getSliceIndex(): number;
19
+ protected setCameraClippingRange(): void;
17
20
  resetSlabThickness(): void;
18
21
  }
19
22
  export default VolumeViewport3D;
@@ -16,6 +16,13 @@ class VolumeViewport3D extends BaseVolumeViewport {
16
16
  this.getCurrentImageId = () => {
17
17
  return null;
18
18
  };
19
+ this.resetCameraForResize = () => {
20
+ return this.resetCamera({
21
+ resetPan: true,
22
+ resetZoom: true,
23
+ resetToCenter: true,
24
+ });
25
+ };
19
26
  const { parallelProjection, orientation } = this.options;
20
27
  const activeCamera = this.getVtkActiveCamera();
21
28
  if (parallelProjection != null) {
@@ -25,7 +32,7 @@ class VolumeViewport3D extends BaseVolumeViewport {
25
32
  this.applyViewOrientation(orientation);
26
33
  }
27
34
  }
28
- resetCamera({ resetPan = true, resetZoom = true, resetToCenter = true, }) {
35
+ resetCamera({ resetPan = true, resetZoom = true, resetToCenter = true, } = {}) {
29
36
  super.resetCamera({ resetPan, resetZoom, resetToCenter });
30
37
  const activeCamera = this.getVtkActiveCamera();
31
38
  if (activeCamera.getParallelProjection()) {
@@ -54,9 +61,10 @@ class VolumeViewport3D extends BaseVolumeViewport {
54
61
  this.viewportProperties.slabThickness = undefined;
55
62
  this.updateClippingPlanesForActors(this.getCamera());
56
63
  }
57
- const imageVolume = cache.getVolume(volumeActor.uid);
64
+ volumeId ||= this.getVolumeId();
65
+ const imageVolume = cache.getVolume(volumeId);
58
66
  if (!imageVolume) {
59
- throw new Error(`imageVolume with id: ${volumeActor.uid} does not exist in cache`);
67
+ throw new Error(`imageVolume with id: ${volumeId} does not exist in cache`);
60
68
  }
61
69
  setDefaultVolumeVOI(volumeActor.actor, imageVolume);
62
70
  if (isImageActor(volumeActor)) {
@@ -68,6 +76,18 @@ class VolumeViewport3D extends BaseVolumeViewport {
68
76
  this.setCamera(this.initialCamera);
69
77
  triggerEvent(this.element, Events.VOI_MODIFIED, super.getVOIModifiedEventDetail(volumeId));
70
78
  }
79
+ getSliceIndex() {
80
+ return null;
81
+ }
82
+ setCameraClippingRange() {
83
+ const activeCamera = this.getVtkActiveCamera();
84
+ if (activeCamera.getParallelProjection()) {
85
+ activeCamera.setClippingRange(-RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE);
86
+ }
87
+ else {
88
+ activeCamera.setClippingRange(RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE);
89
+ }
90
+ }
71
91
  resetSlabThickness() {
72
92
  return null;
73
93
  }
@@ -52,7 +52,7 @@ declare class WSIViewport extends Viewport {
52
52
  getZoom(): any;
53
53
  setZoom(zoom: number): void;
54
54
  protected getTransform(): Transform;
55
- getReferenceId(): string;
55
+ getViewReferenceId(): string;
56
56
  getCurrentImageIdIndex(): number;
57
57
  }
58
58
  export default WSIViewport;
@@ -8,6 +8,7 @@ import { getOrCreateCanvas } from './helpers';
8
8
  import { EPSILON } from '../constants';
9
9
  import triggerEvent from '../utilities/triggerEvent';
10
10
  import { peerImport } from '../init';
11
+ import { pointInShapeCallback } from '../utilities/pointInShapeCallback';
11
12
  const _map = Symbol.for('map');
12
13
  const EVENT_POSTRENDER = 'postrender';
13
14
  class WSIViewport extends Viewport {
@@ -186,7 +187,23 @@ class WSIViewport extends Viewport {
186
187
  return null;
187
188
  }
188
189
  const { spacing } = metadata;
189
- return {
190
+ const imageData = {
191
+ getDirection: () => metadata.direction,
192
+ getDimensions: () => metadata.dimensions,
193
+ getRange: () => [0, 255],
194
+ getScalarData: () => this.getScalarData(),
195
+ getSpacing: () => metadata.spacing,
196
+ worldToIndex: (point) => {
197
+ const canvasPoint = this.worldToCanvas(point);
198
+ const pixelCoord = this.canvasToIndex(canvasPoint);
199
+ return [pixelCoord[0], pixelCoord[1], 0];
200
+ },
201
+ indexToWorld: (point) => {
202
+ const canvasPoint = this.indexToCanvas([point[0], point[1]]);
203
+ return this.canvasToWorld(canvasPoint);
204
+ },
205
+ };
206
+ const imageDataReturn = {
190
207
  dimensions: metadata.dimensions,
191
208
  spacing,
192
209
  numberOfComponents: 3,
@@ -196,29 +213,25 @@ class WSIViewport extends Viewport {
196
213
  Modality: this.modality,
197
214
  FrameOfReferenceUID: this.frameOfReferenceUID,
198
215
  },
199
- imageData: {
200
- getDirection: () => metadata.direction,
201
- getDimensions: () => metadata.dimensions,
202
- getRange: () => [0, 255],
203
- getScalarData: () => this.getScalarData(),
204
- getSpacing: () => metadata.spacing,
205
- worldToIndex: (point) => {
206
- const canvasPoint = this.worldToCanvas(point);
207
- const pixelCoord = this.canvasToIndex(canvasPoint);
208
- return [pixelCoord[0], pixelCoord[1], 0];
209
- },
210
- indexToWorld: (point) => {
211
- const canvasPoint = this.indexToCanvas([point[0], point[1]]);
212
- return this.canvasToWorld(canvasPoint);
213
- },
214
- },
215
216
  hasPixelSpacing: this.hasPixelSpacing,
216
217
  calibration: this.calibration,
217
218
  preScale: {
218
219
  scaled: false,
219
220
  },
220
221
  scalarData: this.getScalarData(),
222
+ imageData,
223
+ voxelManager: {
224
+ forEach: (callback, options) => {
225
+ return pointInShapeCallback(options.imageData, {
226
+ pointInShapeFn: options.isInObject ?? (() => true),
227
+ callback: callback,
228
+ boundsIJK: options.boundsIJK,
229
+ returnPoints: options.returnPoints ?? false,
230
+ });
231
+ },
232
+ },
221
233
  };
234
+ return imageDataReturn;
222
235
  }
223
236
  hasImageURI(imageURI) {
224
237
  return true;
@@ -404,7 +417,7 @@ class WSIViewport extends Viewport {
404
417
  transform.translate(-center[0], -center[1]);
405
418
  return transform;
406
419
  }
407
- getReferenceId() {
420
+ getViewReferenceId() {
408
421
  return `imageId:${this.getCurrentImageId()}`;
409
422
  }
410
423
  getCurrentImageIdIndex() {
@@ -18,6 +18,8 @@ async function createVolumeActor(props, element, viewportId, suppressEvents = fa
18
18
  const volumeActor = vtkVolume.newInstance();
19
19
  volumeActor.setMapper(volumeMapper);
20
20
  const { numberOfComponents } = imageData.get('numberOfComponents');
21
+ const volumeProperty = volumeActor.getProperty();
22
+ volumeProperty.set({ viewportId: viewportId });
21
23
  if (numberOfComponents === 3) {
22
24
  volumeActor.getProperty().setIndependentComponents(false);
23
25
  }
@@ -44,24 +44,23 @@ function getVOIFromMetadata(imageVolume) {
44
44
  const voiLutModule = metaData.get('voiLutModule', imageId);
45
45
  if (voiLutModule?.windowWidth && voiLutModule.windowCenter) {
46
46
  const { windowWidth, windowCenter } = voiLutModule;
47
- voi = {
48
- windowWidth: Array.isArray(windowWidth) ? windowWidth[0] : windowWidth,
49
- windowCenter: Array.isArray(windowCenter)
50
- ? windowCenter[0]
51
- : windowCenter,
52
- };
47
+ const width = Array.isArray(windowWidth) ? windowWidth[0] : windowWidth;
48
+ const center = Array.isArray(windowCenter)
49
+ ? windowCenter[0]
50
+ : windowCenter;
51
+ if (width !== 0) {
52
+ voi = { windowWidth: width, windowCenter: center };
53
+ }
53
54
  }
54
55
  }
55
56
  else {
56
57
  voi = metadata.voiLut[0];
57
58
  }
58
- if (voi) {
59
+ if (voi && (voi.windowWidth !== 0 || voi.windowCenter !== 0)) {
59
60
  const { lower, upper } = windowLevel.toLowHighRange(Number(voi.windowWidth), Number(voi.windowCenter));
60
- return {
61
- lower,
62
- upper,
63
- };
61
+ return { lower, upper };
64
62
  }
63
+ return undefined;
65
64
  }
66
65
  async function getVOIFromMiddleSliceMinMax(imageVolume) {
67
66
  const { imageIds } = imageVolume;
@@ -31,7 +31,7 @@ declare class Cache {
31
31
  getVolumeLoadObject: (volumeId: string) => IVolumeLoadObject | undefined;
32
32
  getGeometry: (geometryId: string) => IGeometry | undefined;
33
33
  getImage: (imageId: string) => IImage | undefined;
34
- getVolume: (volumeId: string) => IImageVolume | undefined;
34
+ getVolume: (volumeId: string, allowPartialMatch?: boolean) => IImageVolume | undefined;
35
35
  getVolumes: () => IImageVolume[];
36
36
  filterVolumesByReferenceId: (volumeId: string) => IImageVolume[];
37
37
  removeImageLoadObject: (imageId: string) => void;
@@ -133,13 +133,15 @@ class Cache {
133
133
  cachedImage.timeStamp = Date.now();
134
134
  return cachedImage.image;
135
135
  };
136
- this.getVolume = (volumeId) => {
136
+ this.getVolume = (volumeId, allowPartialMatch = false) => {
137
137
  if (volumeId === undefined) {
138
138
  throw new Error('getVolume: volumeId must not be undefined');
139
139
  }
140
140
  const cachedVolume = this._volumeCache.get(volumeId);
141
141
  if (!cachedVolume) {
142
- return;
142
+ return allowPartialMatch
143
+ ? [...this._volumeCache.values()].find((cv) => cv.volumeId.includes(volumeId))?.volume
144
+ : undefined;
143
145
  }
144
146
  cachedVolume.timeStamp = Date.now();
145
147
  return cachedVolume.volume;
@@ -277,6 +279,10 @@ class Cache {
277
279
  console.warn('The image was purged from the cache before it completed loading.');
278
280
  return;
279
281
  }
282
+ if (!image) {
283
+ console.warn('Image is undefined');
284
+ return;
285
+ }
280
286
  if (image.sizeInBytes === undefined || Number.isNaN(image.sizeInBytes)) {
281
287
  throw new Error('_putImageCommon: image.sizeInBytes must not be undefined');
282
288
  }
@@ -49,6 +49,8 @@ export default class StreamingDynamicImageVolume extends BaseStreamingImageVolum
49
49
  this.invalidateVolume(true);
50
50
  triggerEvent(eventTarget, Events.DYNAMIC_VOLUME_TIME_POINT_INDEX_CHANGED, {
51
51
  volumeId: this.volumeId,
52
+ timePointIndex: index,
53
+ numTimePoints: this.numTimePoints,
52
54
  imageIdGroupIndex: index,
53
55
  numImageIdGroups: this.numTimePoints,
54
56
  splittingTag: this.splittingTag,
@@ -26,7 +26,7 @@ declare enum Events {
26
26
  VOLUME_NEW_IMAGE = "CORNERSTONE_VOLUME_NEW_IMAGE",
27
27
  PRE_STACK_NEW_IMAGE = "CORNERSTONE_PRE_STACK_NEW_IMAGE",
28
28
  IMAGE_SPACING_CALIBRATED = "CORNERSTONE_IMAGE_SPACING_CALIBRATED",
29
- VIEWPORT_NEW_IMAGE_SET = "CORNERSTONE_STACK_VIEWPORT_NEW_STACK",
29
+ VIEWPORT_NEW_IMAGE_SET = "CORNERSTONE_VIEWPORT_NEW_IMAGE_SET",
30
30
  STACK_VIEWPORT_SCROLL = "CORNERSTONE_STACK_VIEWPORT_SCROLL",
31
31
  GEOMETRY_CACHE_GEOMETRY_ADDED = "CORNERSTONE_GEOMETRY_CACHE_GEOMETRY_ADDED",
32
32
  VOLUME_VIEWPORT_SCROLL_OUT_OF_BOUNDS = "VOLUME_VIEWPORT_SCROLL_OUT_OF_BOUNDS",
@@ -27,7 +27,7 @@ var Events;
27
27
  Events["VOLUME_NEW_IMAGE"] = "CORNERSTONE_VOLUME_NEW_IMAGE";
28
28
  Events["PRE_STACK_NEW_IMAGE"] = "CORNERSTONE_PRE_STACK_NEW_IMAGE";
29
29
  Events["IMAGE_SPACING_CALIBRATED"] = "CORNERSTONE_IMAGE_SPACING_CALIBRATED";
30
- Events["VIEWPORT_NEW_IMAGE_SET"] = "CORNERSTONE_STACK_VIEWPORT_NEW_STACK";
30
+ Events["VIEWPORT_NEW_IMAGE_SET"] = "CORNERSTONE_VIEWPORT_NEW_IMAGE_SET";
31
31
  Events["STACK_VIEWPORT_SCROLL"] = "CORNERSTONE_STACK_VIEWPORT_SCROLL";
32
32
  Events["GEOMETRY_CACHE_GEOMETRY_ADDED"] = "CORNERSTONE_GEOMETRY_CACHE_GEOMETRY_ADDED";
33
33
  Events["VOLUME_VIEWPORT_SCROLL_OUT_OF_BOUNDS"] = "VOLUME_VIEWPORT_SCROLL_OUT_OF_BOUNDS";
@@ -69,8 +69,5 @@ const interleavedRetrieveConfiguration = [
69
69
  requestType: RequestType.Thumbnail,
70
70
  retrieveType: 'multipleFinal',
71
71
  },
72
- {
73
- id: 'errorRetrieve',
74
- },
75
72
  ];
76
73
  export default interleavedRetrieveConfiguration;
@@ -3,8 +3,5 @@ const singleRetrieveStages = [
3
3
  id: 'initialImages',
4
4
  retrieveType: 'single',
5
5
  },
6
- {
7
- id: 'errorRetrieve',
8
- },
9
6
  ];
10
7
  export default singleRetrieveStages;