@cornerstonejs/tools 5.0.16 → 5.1.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 (67) hide show
  1. package/dist/esm/stateManagement/segmentation/helpers/labelmapImageMapperSupport.js +1 -1
  2. package/dist/esm/stateManagement/segmentation/labelmapModel/normalizeLabelmapSegmentationData.js +1 -1
  3. package/dist/esm/stateManagement/segmentation/labelmapModel/privateLabelmap.js +2 -2
  4. package/dist/esm/stateManagement/segmentation/utilities/getViewportAssociatedToSegmentation.js +2 -1
  5. package/dist/esm/synchronizers/callbacks/cameraSyncCallback.js +19 -2
  6. package/dist/esm/synchronizers/callbacks/imageSliceSyncCallback.js +3 -0
  7. package/dist/esm/synchronizers/callbacks/voiSyncCallback.js +13 -1
  8. package/dist/esm/tools/AdvancedMagnifyTool.js +36 -10
  9. package/dist/esm/tools/CrosshairsTool.js +100 -49
  10. package/dist/esm/tools/MagnifyTool.d.ts +1 -1
  11. package/dist/esm/tools/MagnifyTool.js +27 -6
  12. package/dist/esm/tools/OrientationControllerTool.js +3 -2
  13. package/dist/esm/tools/OrientationMarkerTool.js +3 -0
  14. package/dist/esm/tools/OverlayGridTool.js +2 -1
  15. package/dist/esm/tools/ReferenceCursors.d.ts +1 -1
  16. package/dist/esm/tools/ReferenceCursors.js +24 -3
  17. package/dist/esm/tools/ReferenceLinesTool.js +5 -4
  18. package/dist/esm/tools/ScaleOverlayTool.js +2 -1
  19. package/dist/esm/tools/TrackballRotateTool.js +6 -4
  20. package/dist/esm/tools/VolumeCroppingControlTool.js +11 -6
  21. package/dist/esm/tools/VolumeCroppingTool.js +6 -4
  22. package/dist/esm/tools/VolumeRotateTool.js +4 -2
  23. package/dist/esm/tools/WindowLevelRegionTool.js +27 -3
  24. package/dist/esm/tools/WindowLevelTool.js +4 -8
  25. package/dist/esm/tools/annotation/DragProbeTool.js +2 -1
  26. package/dist/esm/tools/annotation/ETDRSGridTool.js +3 -2
  27. package/dist/esm/tools/annotation/EllipticalROITool.js +2 -1
  28. package/dist/esm/tools/annotation/LabelTool.js +2 -1
  29. package/dist/esm/tools/annotation/LivewireContourTool.js +12 -1
  30. package/dist/esm/tools/annotation/RectangleROITool.js +2 -1
  31. package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/UltrasoundPleuraBLineTool.js +2 -1
  32. package/dist/esm/tools/annotation/WholeBodySegmentTool.js +3 -2
  33. package/dist/esm/tools/annotation/planarFreehandROITool/drawLoop.js +1 -1
  34. package/dist/esm/tools/base/AnnotationTool.js +6 -0
  35. package/dist/esm/tools/base/GrowCutBaseTool.js +3 -2
  36. package/dist/esm/tools/displayTools/Contour/contourDisplay.js +2 -1
  37. package/dist/esm/tools/displayTools/Contour/contourHandler/handleContourSegmentation.js +3 -2
  38. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/legacyVolumePlan.js +21 -9
  39. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/planarGenericVolumeLabelmap.js +1 -1
  40. package/dist/esm/tools/displayTools/Labelmap/removeLabelmapRepresentationData.js +1 -1
  41. package/dist/esm/tools/displayTools/Labelmap/syncStackLabelmapActors.js +36 -0
  42. package/dist/esm/tools/segmentation/CircleScissorsTool.js +2 -1
  43. package/dist/esm/tools/segmentation/RectangleScissorsTool.js +2 -1
  44. package/dist/esm/tools/segmentation/SegmentBidirectionalTool.js +2 -1
  45. package/dist/esm/tools/segmentation/strategies/fillRectangle.js +2 -1
  46. package/dist/esm/types/LabelmapTypes.d.ts +1 -1
  47. package/dist/esm/utilities/cine/playClip.js +28 -0
  48. package/dist/esm/utilities/genericViewportToolHelpers.d.ts +11 -0
  49. package/dist/esm/utilities/genericViewportToolHelpers.js +37 -0
  50. package/dist/esm/utilities/getVOIMultipliers.js +1 -3
  51. package/dist/esm/utilities/getViewportICamera.js +3 -2
  52. package/dist/esm/utilities/index.d.ts +2 -1
  53. package/dist/esm/utilities/index.js +2 -1
  54. package/dist/esm/utilities/math/polyline/getSubPixelSpacingAndXYDirections.js +7 -3
  55. package/dist/esm/utilities/planar/filterAnnotationsForDisplay.js +7 -2
  56. package/dist/esm/utilities/segmentation/getSegmentIndexAtWorldPoint.js +2 -1
  57. package/dist/esm/utilities/segmentation/growCut/runGrowCutForSphere.js +3 -2
  58. package/dist/esm/utilities/setViewportCamera.d.ts +3 -0
  59. package/dist/esm/utilities/setViewportCamera.js +58 -0
  60. package/dist/esm/utilities/stackPrefetch/stackPrefetchUtils.js +6 -2
  61. package/dist/esm/utilities/viewport/isViewportPreScaled.js +2 -13
  62. package/dist/esm/utilities/voi/colorbar/ViewportColorbar.js +17 -5
  63. package/dist/esm/utilities/voi/windowlevel/extractWindowLevelRegionToolData.d.ts +1 -1
  64. package/dist/esm/utilities/voi/windowlevel/extractWindowLevelRegionToolData.js +28 -1
  65. package/dist/esm/version.d.ts +1 -1
  66. package/dist/esm/version.js +1 -1
  67. package/package.json +4 -4
@@ -1,9 +1,11 @@
1
1
  import { BaseTool } from './base';
2
2
  import { Events } from '../enums';
3
- import { getEnabledElement, StackViewport, Enums } from '@cornerstonejs/core';
3
+ import { getEnabledElement, StackViewport, Enums, utilities as csUtils, } from '@cornerstonejs/core';
4
4
  import { getViewportIdsWithToolToRender } from '../utilities/viewportFilters';
5
5
  import triggerAnnotationRenderForViewportIds from '../utilities/triggerAnnotationRenderForViewportIds';
6
+ import { getNativeSourceProperties } from '../utilities/genericViewportToolHelpers';
6
7
  import { state } from '../store/state';
8
+ import { vec3 } from 'gl-matrix';
7
9
  import { hideElementCursor, resetElementCursor, } from '../cursors/elementCursor';
8
10
  const MAGNIFY_VIEWPORT_ID = 'magnify-viewport';
9
11
  class MagnifyTool extends BaseTool {
@@ -22,8 +24,9 @@ class MagnifyTool extends BaseTool {
22
24
  const { element, currentPoints } = eventDetail;
23
25
  const enabledElement = getEnabledElement(element);
24
26
  const { viewport, renderingEngine } = enabledElement;
25
- if (!(viewport instanceof StackViewport)) {
26
- throw new Error('MagnifyTool only works on StackViewports');
27
+ if (!(viewport instanceof StackViewport) &&
28
+ !csUtils.isGenericViewport(viewport)) {
29
+ throw new Error('MagnifyTool only works on Stack or native planar viewports');
27
30
  }
28
31
  const referencedImageId = this._getReferencedImageId(viewport);
29
32
  if (!referencedImageId) {
@@ -51,8 +54,13 @@ class MagnifyTool extends BaseTool {
51
54
  const { enabledElement, referencedImageId, viewportIdsToRender, renderingEngine, currentPoints, } = this.editData;
52
55
  const { viewport } = enabledElement;
53
56
  const { element } = viewport;
54
- const viewportProperties = viewport.getProperties();
55
- const { rotation: originalViewportRotation, flipHorizontal: originalViewportFlipHorizontal, flipVertical: originalViewportFlipVertical, } = viewport.getViewPresentation();
57
+ const native = csUtils.isGenericViewport(viewport)
58
+ ? getNativeSourceProperties(viewport)
59
+ : undefined;
60
+ const viewportProperties = native
61
+ ? native.properties
62
+ : viewport.getProperties();
63
+ const { rotation: originalViewportRotation, flipHorizontal: originalViewportFlipHorizontal, flipVertical: originalViewportFlipVertical, } = native ?? viewport.getViewPresentation();
56
64
  const { canvas: canvasPos, world: worldPos } = currentPoints;
57
65
  let magnifyToolElement;
58
66
  magnifyToolElement = element.querySelector('.magnifyTool');
@@ -86,8 +94,18 @@ class MagnifyTool extends BaseTool {
86
94
  flipHorizontal: originalViewportFlipHorizontal,
87
95
  flipVertical: originalViewportFlipVertical,
88
96
  });
89
- const { parallelScale } = viewport.getCamera();
90
97
  const { focalPoint, position, viewPlaneNormal } = magnifyViewport.getCamera();
98
+ let parallelScale;
99
+ if (csUtils.isGenericViewport(viewport)) {
100
+ const sourceElement = viewport.element;
101
+ const worldTop = viewport.canvasToWorld([0, 0]);
102
+ const worldBottom = viewport.canvasToWorld([0, 1]);
103
+ const worldPerPixel = vec3.distance(worldTop, worldBottom);
104
+ parallelScale = (worldPerPixel * sourceElement.clientHeight) / 2;
105
+ }
106
+ else {
107
+ ({ parallelScale } = viewport.getCamera());
108
+ }
91
109
  const distance = Math.sqrt(Math.pow(focalPoint[0] - position[0], 2) +
92
110
  Math.pow(focalPoint[1] - position[1], 2) +
93
111
  Math.pow(focalPoint[2] - position[2], 2));
@@ -190,6 +208,9 @@ class MagnifyTool extends BaseTool {
190
208
  if (viewport instanceof StackViewport) {
191
209
  referencedImageId = targetId.split('imageId:')[1];
192
210
  }
211
+ else if (csUtils.isGenericViewport(viewport)) {
212
+ referencedImageId = getNativeSourceProperties(viewport).currentImageId;
213
+ }
193
214
  return referencedImageId;
194
215
  }
195
216
  }
@@ -1,6 +1,7 @@
1
1
  import { BaseTool } from './base';
2
2
  import { getEnabledElementByIds, Enums, eventTarget, } from '@cornerstonejs/core';
3
3
  import { getToolGroup } from '../store/ToolGroupManager';
4
+ import setViewportCamera, { resetViewportCamera, } from '../utilities/setViewportCamera';
4
5
  import * as ToolsEnums from '../enums';
5
6
  import { vec3, mat4, quat } from 'gl-matrix';
6
7
  import { vtkOrientationControllerWidget } from '../utilities/vtkjs/OrientationControllerWidget';
@@ -432,11 +433,11 @@ class OrientationControllerTool extends BaseTool {
432
433
  mat4.fromQuat(interpolatedMatrix, interpolatedQuat);
433
434
  const interpolatedForward = interpolatedMatrix.slice(8, 11);
434
435
  const interpolatedUp = interpolatedMatrix.slice(4, 7);
435
- viewport.setCamera({
436
+ setViewportCamera(viewport, {
436
437
  viewPlaneNormal: isLastStep ? finalNormal : interpolatedForward,
437
438
  viewUp: isLastStep ? finalUp : interpolatedUp,
438
439
  });
439
- viewport.resetCamera(ANIMATE_RESET_CAMERA_OPTIONS);
440
+ resetViewportCamera(viewport, ANIMATE_RESET_CAMERA_OPTIONS);
440
441
  viewport.render();
441
442
  if (!isLastStep) {
442
443
  const handle = requestAnimationFrame(animate);
@@ -171,6 +171,9 @@ class OrientationMarkerTool extends BaseTool {
171
171
  let viewports = renderingEngine.getViewports();
172
172
  viewports = filterViewportsWithToolEnabled(viewports, this.getToolName());
173
173
  viewports.forEach((viewport) => {
174
+ if (typeof viewport.getWidget !== 'function') {
175
+ return;
176
+ }
174
177
  const widget = viewport.getWidget(this.getToolName());
175
178
  if (!widget || widget.isDeleted()) {
176
179
  this.addAxisActorInViewport(viewport);
@@ -3,6 +3,7 @@ import { metaData, CONSTANTS, getRenderingEngine, utilities as csUtils, } from '
3
3
  import { addAnnotation, getAnnotations, } from '../stateManagement/annotation/annotationState';
4
4
  import { getToolGroup } from '../store/ToolGroupManager';
5
5
  import { drawLine as drawLineSvg } from '../drawingSvg';
6
+ import getViewportICamera from '../utilities/getViewportICamera';
6
7
  import triggerAnnotationRenderForViewportIds from '../utilities/triggerAnnotationRenderForViewportIds';
7
8
  import AnnotationDisplayTool from './base/AnnotationDisplayTool';
8
9
  const { EPSILON } = CONSTANTS;
@@ -89,7 +90,7 @@ class OverlayGridTool extends AnnotationDisplayTool {
89
90
  }
90
91
  const annotation = annotations[0];
91
92
  const { annotationUID } = annotation;
92
- const { focalPoint, viewPlaneNormal } = targetViewport.getCamera();
93
+ const { focalPoint, viewPlaneNormal } = getViewportICamera(targetViewport);
93
94
  const styleSpecifier = {
94
95
  toolGroupId: this.toolGroupId,
95
96
  toolName: this.getToolName(),
@@ -19,6 +19,6 @@ declare class ReferenceCursors extends AnnotationDisplayTool {
19
19
  onCameraModified: (evt: Types.EventTypes.CameraModifiedEvent) => void;
20
20
  filterInteractableAnnotationsForElement(element: HTMLDivElement, annotations: Annotations): Annotations;
21
21
  renderAnnotation: (enabledElement: Types.IEnabledElement, svgDrawingHelper: SVGDrawingHelper) => boolean;
22
- updateViewportImage(viewport: Types.IStackViewport | Types.IVolumeViewport): void;
22
+ updateViewportImage(viewport: Types.IViewport): void;
23
23
  }
24
24
  export default ReferenceCursors;
@@ -3,12 +3,14 @@ import { addAnnotation, getAnnotations, } from '../stateManagement/annotation/an
3
3
  import { isAnnotationVisible } from '../stateManagement/annotation/annotationVisibility';
4
4
  import { drawLine } from '../drawingSvg';
5
5
  import { getViewportIdsWithToolToRender } from '../utilities/viewportFilters';
6
+ import getViewportICamera from '../utilities/getViewportICamera';
6
7
  import triggerAnnotationRenderForViewportIds from '../utilities/triggerAnnotationRenderForViewportIds';
7
8
  import { vec3 } from 'gl-matrix';
8
9
  import AnnotationDisplayTool from './base/AnnotationDisplayTool';
9
10
  import vtkMath from '@kitware/vtk.js/Common/Core/Math';
10
11
  import { hideElementCursor, resetElementCursor, } from '../cursors/elementCursor';
11
12
  import { getToolGroup } from '../store/ToolGroupManager';
13
+ import { jumpToFocalPoint } from '../utilities/genericViewportToolHelpers';
12
14
  class ReferenceCursors extends AnnotationDisplayTool {
13
15
  constructor(toolProps = {}, defaultToolProps = {
14
16
  supportedInteractionTypes: ['Mouse', 'Touch'],
@@ -48,7 +50,7 @@ class ReferenceCursors extends AnnotationDisplayTool {
48
50
  }
49
51
  const { viewport, renderingEngine } = enabledElement;
50
52
  this.isDrawing = true;
51
- const camera = viewport.getCamera();
53
+ const camera = getViewportICamera(viewport);
52
54
  const { viewPlaneNormal, viewUp } = camera;
53
55
  if (!viewPlaneNormal || !viewUp) {
54
56
  throw new Error('Camera not found');
@@ -258,7 +260,7 @@ class ReferenceCursors extends AnnotationDisplayTool {
258
260
  if (!viewport) {
259
261
  return [];
260
262
  }
261
- const camera = viewport.getCamera();
263
+ const camera = getViewportICamera(viewport);
262
264
  const { viewPlaneNormal, focalPoint } = camera;
263
265
  if (!viewPlaneNormal || !focalPoint) {
264
266
  return [];
@@ -287,7 +289,7 @@ class ReferenceCursors extends AnnotationDisplayTool {
287
289
  }
288
290
  }
289
291
  else if (viewport instanceof VolumeViewport) {
290
- const { focalPoint, viewPlaneNormal } = viewport.getCamera();
292
+ const { focalPoint, viewPlaneNormal } = getViewportICamera(viewport);
291
293
  if (!focalPoint || !viewPlaneNormal) {
292
294
  return;
293
295
  }
@@ -308,6 +310,25 @@ class ReferenceCursors extends AnnotationDisplayTool {
308
310
  }
309
311
  }
310
312
  }
313
+ else if (utilities.isGenericViewport(viewport)) {
314
+ const { focalPoint, viewPlaneNormal } = getViewportICamera(viewport);
315
+ if (!focalPoint || !viewPlaneNormal) {
316
+ return;
317
+ }
318
+ const plane = utilities.planar.planeEquation(viewPlaneNormal, focalPoint);
319
+ const currentDistance = utilities.planar.planeDistanceToPoint(plane, currentMousePosition, true);
320
+ if (Math.abs(currentDistance) < 0.5) {
321
+ return;
322
+ }
323
+ const normalizedViewPlane = vec3.normalize(vec3.create(), vec3.fromValues(...viewPlaneNormal));
324
+ const scaledPlaneNormal = vec3.scale(vec3.create(), normalizedViewPlane, currentDistance);
325
+ const newFocalPoint = vec3.add(vec3.create(), vec3.fromValues(...focalPoint), scaledPlaneNormal);
326
+ jumpToFocalPoint(viewport, newFocalPoint);
327
+ const renderingEngine = viewport.getRenderingEngine();
328
+ if (renderingEngine) {
329
+ renderingEngine.renderViewport(viewport.id);
330
+ }
331
+ }
311
332
  }
312
333
  }
313
334
  ReferenceCursors.toolName = 'ReferenceCursors';
@@ -5,6 +5,7 @@ import { addAnnotation } from '../stateManagement/annotation/annotationState';
5
5
  import { drawLine as drawLineSvg } from '../drawingSvg';
6
6
  import { filterViewportsWithToolEnabled } from '../utilities/viewportFilters';
7
7
  import triggerAnnotationRenderForViewportIds from '../utilities/triggerAnnotationRenderForViewportIds';
8
+ import getViewportICamera from '../utilities/getViewportICamera';
8
9
  import AnnotationDisplayTool from './base/AnnotationDisplayTool';
9
10
  const { EPSILON } = CONSTANTS;
10
11
  class ReferenceLines extends AnnotationDisplayTool {
@@ -27,11 +28,11 @@ class ReferenceLines extends AnnotationDisplayTool {
27
28
  let viewports = renderingEngine.getViewports();
28
29
  viewports = filterViewportsWithToolEnabled(viewports, this.getToolName());
29
30
  const sourceViewport = renderingEngine.getViewport(this.configuration.sourceViewportId);
30
- if (!sourceViewport?.getImageData()) {
31
+ if (!sourceViewport?.getImageData?.()) {
31
32
  return;
32
33
  }
33
34
  const { element } = sourceViewport;
34
- const { viewUp, viewPlaneNormal } = sourceViewport.getCamera();
35
+ const { viewUp, viewPlaneNormal } = getViewportICamera(sourceViewport);
35
36
  const sourceViewportCanvasCornersInWorld = csUtils.getViewportImageCornersInWorld(sourceViewport);
36
37
  let annotation = this.editData?.annotation;
37
38
  const FrameOfReferenceUID = sourceViewport.getFrameOfReferenceUID();
@@ -108,8 +109,8 @@ class ReferenceLines extends AnnotationDisplayTool {
108
109
  const topRight = annotation.data.handles.points[1];
109
110
  const bottomLeft = annotation.data.handles.points[2];
110
111
  const bottomRight = annotation.data.handles.points[3];
111
- const { focalPoint, viewPlaneNormal, viewUp } = targetViewport.getCamera();
112
- const { viewPlaneNormal: sourceViewPlaneNormal } = sourceViewport.getCamera();
112
+ const { focalPoint, viewPlaneNormal, viewUp } = getViewportICamera(targetViewport);
113
+ const { viewPlaneNormal: sourceViewPlaneNormal } = getViewportICamera(sourceViewport);
113
114
  if (this.isParallel(viewPlaneNormal, sourceViewPlaneNormal)) {
114
115
  return renderStatus;
115
116
  }
@@ -1,4 +1,5 @@
1
1
  import AnnotationDisplayTool from './base/AnnotationDisplayTool';
2
+ import getViewportICamera from '../utilities/getViewportICamera';
2
3
  import { vec3 } from 'gl-matrix';
3
4
  import { getEnabledElementByIds, getRenderingEngines, utilities as csUtils, } from '@cornerstonejs/core';
4
5
  import { addAnnotation, getAnnotations, } from '../stateManagement/annotation/annotationState';
@@ -37,7 +38,7 @@ class ScaleOverlayTool extends AnnotationDisplayTool {
37
38
  if (!viewport) {
38
39
  return;
39
40
  }
40
- const { viewUp, viewPlaneNormal } = viewport.getCamera();
41
+ const { viewUp, viewPlaneNormal } = getViewportICamera(viewport);
41
42
  const viewportCanvasCornersInWorld = csUtils.getViewportImageCornersInWorld(viewport);
42
43
  let annotation = this.editData?.annotation;
43
44
  const annotations = getAnnotations(this.getToolName(), viewport.element);
@@ -1,9 +1,11 @@
1
1
  import vtkMath from '@kitware/vtk.js/Common/Core/Math';
2
2
  import { Events } from '../enums';
3
- import { eventTarget, getEnabledElement, getEnabledElementByIds, } from '@cornerstonejs/core';
3
+ import { eventTarget, getEnabledElement, getEnabledElementByIds, utilities as csUtils, } from '@cornerstonejs/core';
4
4
  import { mat4, vec3 } from 'gl-matrix';
5
5
  import { BaseTool } from './base';
6
6
  import { getToolGroup } from '../store/ToolGroupManager';
7
+ import getViewportICamera from '../utilities/getViewportICamera';
8
+ import setViewportCamera, { resetViewportCamera, } from '../utilities/setViewportCamera';
7
9
  import { applyViewportPresentation, getViewportPresentation, } from '../utilities/viewportPresentation';
8
10
  class TrackballRotateTool extends BaseTool {
9
11
  constructor(toolProps = {}, defaultToolProps = {
@@ -66,7 +68,7 @@ class TrackballRotateTool extends BaseTool {
66
68
  }
67
69
  const { viewport } = element;
68
70
  const viewPresentation = getViewportPresentation(viewport);
69
- viewport.resetCamera();
71
+ resetViewportCamera(viewport);
70
72
  applyViewportPresentation(viewport, viewPresentation);
71
73
  viewport.render();
72
74
  });
@@ -114,7 +116,7 @@ class TrackballRotateTool extends BaseTool {
114
116
  mat4.identity(transform);
115
117
  mat4.rotate(transform, transform, angle, axis);
116
118
  vec3.transformMat4(newViewUp, viewUp, transform);
117
- viewport.setCamera({
119
+ setViewportCamera(viewport, {
118
120
  position: newPosition,
119
121
  viewUp: newViewUp,
120
122
  focalPoint: newFocalPoint,
@@ -130,7 +132,7 @@ class TrackballRotateTool extends BaseTool {
130
132
  const { rotateIncrementDegrees } = this.configuration;
131
133
  const enabledElement = getEnabledElement(element);
132
134
  const { viewport } = enabledElement;
133
- const camera = viewport.getCamera();
135
+ const camera = getViewportICamera(viewport);
134
136
  const width = element.clientWidth;
135
137
  const height = element.clientHeight;
136
138
  const normalizedPosition = [
@@ -3,6 +3,8 @@ import vtkMath from '@kitware/vtk.js/Common/Core/Math';
3
3
  import { AnnotationTool } from './base';
4
4
  import { getRenderingEngine, getEnabledElementByIds, getEnabledElement, Enums, CONSTANTS, triggerEvent, eventTarget, convertColorArrayToRgbString, } from '@cornerstonejs/core';
5
5
  import { getToolGroup } from '../store/ToolGroupManager';
6
+ import getViewportICamera from '../utilities/getViewportICamera';
7
+ import { resetViewportCamera } from '../utilities/setViewportCamera';
6
8
  import { addAnnotation, getAnnotations, removeAnnotation, } from '../stateManagement/annotation/annotationState';
7
9
  import { drawCircle as drawCircleSvg, drawLine as drawLineSvg, } from '../drawingSvg';
8
10
  import { state } from '../store/state';
@@ -64,13 +66,13 @@ class VolumeCroppingControlTool extends AnnotationTool {
64
66
  }
65
67
  }
66
68
  const { element } = viewport;
67
- const { position, focalPoint } = viewport.getCamera();
69
+ const { position, focalPoint } = getViewportICamera(viewport);
68
70
  let annotations = this._getAnnotations(enabledElement);
69
71
  annotations = this.filterInteractableAnnotationsForElement(element, annotations);
70
72
  if (annotations?.length) {
71
73
  removeAnnotation(annotations[0].annotationUID);
72
74
  }
73
- const orientation = getOrientationFromNormal(viewport.getCamera().viewPlaneNormal);
75
+ const orientation = getOrientationFromNormal(getViewportICamera(viewport).viewPlaneNormal);
74
76
  const annotation = {
75
77
  highlighted: false,
76
78
  metadata: {
@@ -108,7 +110,7 @@ class VolumeCroppingControlTool extends AnnotationTool {
108
110
  const resetToCenter = true;
109
111
  const resetRotation = true;
110
112
  const suppressEvents = true;
111
- viewport.resetCamera({
113
+ resetViewportCamera(viewport, {
112
114
  resetPan,
113
115
  resetZoom,
114
116
  resetToCenter,
@@ -188,8 +190,11 @@ class VolumeCroppingControlTool extends AnnotationTool {
188
190
  }
189
191
  const enabledElement = getEnabledElement(element);
190
192
  let orientation = null;
191
- if (enabledElement.viewport && enabledElement.viewport.getCamera) {
192
- orientation = getOrientationFromNormal(enabledElement.viewport.getCamera().viewPlaneNormal);
193
+ if (enabledElement.viewport) {
194
+ const { viewPlaneNormal } = getViewportICamera(enabledElement.viewport);
195
+ if (viewPlaneNormal) {
196
+ orientation = getOrientationFromNormal(viewPlaneNormal);
197
+ }
193
198
  }
194
199
  const filtered = annotations.filter((annotation) => {
195
200
  if (annotation.data.orientation &&
@@ -226,7 +231,7 @@ class VolumeCroppingControlTool extends AnnotationTool {
226
231
  const { viewport, renderingEngine } = enabledElement;
227
232
  const { element } = viewport;
228
233
  const annotations = this._getAnnotations(enabledElement);
229
- const camera = viewport.getCamera();
234
+ const camera = getViewportICamera(viewport);
230
235
  const filteredToolAnnotations = this.filterInteractableAnnotationsForElement(element, annotations);
231
236
  const viewportAnnotation = filteredToolAnnotations[0];
232
237
  if (!viewportAnnotation || !viewportAnnotation.data) {
@@ -8,6 +8,8 @@ import vtkPlane from '@kitware/vtk.js/Common/DataModel/Plane';
8
8
  import { BaseTool } from './base';
9
9
  import { getRenderingEngine, getEnabledElementByIds, getEnabledElement, Enums, triggerEvent, eventTarget, } from '@cornerstonejs/core';
10
10
  import { getToolGroup } from '../store/ToolGroupManager';
11
+ import getViewportICamera from '../utilities/getViewportICamera';
12
+ import setViewportCamera, { resetViewportCamera, } from '../utilities/setViewportCamera';
11
13
  import { Events } from '../enums';
12
14
  import { PLANEINDEX, SPHEREINDEX, NUM_CLIPPING_PLANES, extractVolumeDirectionVectors, parseCornerKey, copyClippingPlanes, } from '../utilities/volumeCropping';
13
15
  import { addLine3DBetweenPoints, calculateAdaptiveSphereRadius, } from '../utilities/draw3D';
@@ -471,7 +473,7 @@ class VolumeCroppingTool extends BaseTool {
471
473
  5;
472
474
  const enabledElement = getEnabledElement(element);
473
475
  const { viewport } = enabledElement;
474
- const camera = viewport.getCamera();
476
+ const camera = getViewportICamera(viewport);
475
477
  const width = element.clientWidth;
476
478
  const height = element.clientHeight;
477
479
  const normalizedPosition = [
@@ -684,7 +686,7 @@ class VolumeCroppingTool extends BaseTool {
684
686
  mat4.identity(transform);
685
687
  mat4.rotate(transform, transform, angle, axis);
686
688
  vec3.transformMat4(newViewUp, viewUp, transform);
687
- viewport.setCamera({
689
+ setViewportCamera(viewport, {
688
690
  position: newPosition,
689
691
  viewUp: newViewUp,
690
692
  focalPoint: newFocalPoint,
@@ -710,7 +712,7 @@ class VolumeCroppingTool extends BaseTool {
710
712
  }
711
713
  const { viewport } = element;
712
714
  const viewPresentation = getViewportPresentation(viewport);
713
- viewport.resetCamera();
715
+ resetViewportCamera(viewport);
714
716
  applyViewportPresentation(viewport, viewPresentation);
715
717
  viewport.render();
716
718
  });
@@ -835,7 +837,7 @@ class VolumeCroppingTool extends BaseTool {
835
837
  const { rotateIncrementDegrees } = this.configuration;
836
838
  const enabledElement = getEnabledElement(element);
837
839
  const { viewport } = enabledElement;
838
- const camera = viewport.getCamera();
840
+ const camera = getViewportICamera(viewport);
839
841
  const width = element.clientWidth;
840
842
  const height = element.clientHeight;
841
843
  const normalizedPosition = [
@@ -1,6 +1,8 @@
1
1
  import { BaseTool } from './base';
2
2
  import { getEnabledElement } from '@cornerstonejs/core';
3
3
  import { mat4, vec3 } from 'gl-matrix';
4
+ import getViewportICamera from '../utilities/getViewportICamera';
5
+ import setViewportCamera from '../utilities/setViewportCamera';
4
6
  const DIRECTIONS = {
5
7
  X: [1, 0, 0],
6
8
  Y: [0, 1, 0],
@@ -22,7 +24,7 @@ class VolumeRotateTool extends BaseTool {
22
24
  const enabledElement = getEnabledElement(element);
23
25
  const { viewport } = enabledElement;
24
26
  const { direction, rotateIncrementDegrees } = this.configuration;
25
- const camera = viewport.getCamera();
27
+ const camera = getViewportICamera(viewport);
26
28
  const { viewUp, position, focalPoint } = camera;
27
29
  const { direction: deltaY } = wheel;
28
30
  const [cx, cy, cz] = focalPoint;
@@ -40,7 +42,7 @@ class VolumeRotateTool extends BaseTool {
40
42
  mat4.identity(transform);
41
43
  mat4.rotate(transform, transform, angle, [ax, ay, az]);
42
44
  vec3.transformMat4(newViewUp, viewUp, transform);
43
- viewport.setCamera({
45
+ setViewportCamera(viewport, {
44
46
  position: newPosition,
45
47
  viewUp: newViewUp,
46
48
  focalPoint: newFocalPoint,
@@ -1,4 +1,5 @@
1
1
  import { AnnotationTool } from './base';
2
+ import getViewportICamera from '../utilities/getViewportICamera';
2
3
  import { getEnabledElement, utilities } from '@cornerstonejs/core';
3
4
  import { addAnnotation, getAnnotations, removeAnnotation, } from '../stateManagement';
4
5
  import { triggerAnnotationCompleted } from '../stateManagement/annotation/helpers/state';
@@ -24,7 +25,7 @@ class WindowLevelRegionTool extends AnnotationTool {
24
25
  const enabledElement = getEnabledElement(element);
25
26
  const { viewport } = enabledElement;
26
27
  this.isDrawing = true;
27
- const camera = viewport.getCamera();
28
+ const camera = getViewportICamera(viewport);
28
29
  const { viewPlaneNormal, viewUp } = camera;
29
30
  const referencedImageId = this.getReferencedImageId(viewport, worldPos, viewPlaneNormal, viewUp);
30
31
  const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
@@ -171,6 +172,9 @@ class WindowLevelRegionTool extends AnnotationTool {
171
172
  const enabledElement = getEnabledElement(element);
172
173
  const { viewport } = enabledElement;
173
174
  const imageData = windowLevel.extractWindowLevelRegionToolData(viewport);
175
+ if (!imageData) {
176
+ return;
177
+ }
174
178
  const { data } = annotation;
175
179
  const { points } = data.handles;
176
180
  const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p));
@@ -191,9 +195,29 @@ class WindowLevelRegionTool extends AnnotationTool {
191
195
  }
192
196
  const windowWidth = Math.max(Math.abs(minMaxMean.max - minMaxMean.min), this.configuration.minWindowWidth);
193
197
  const windowCenter = minMaxMean.mean;
194
- const voiLutFunction = viewport.getProperties().VOILUTFunction;
198
+ const presentationViewport = utilities.viewportSupportsDisplaySetPresentation(viewport)
199
+ ? viewport
200
+ : undefined;
201
+ const sourceDataId = presentationViewport?.getSourceDataId();
202
+ const voiLutFunction = presentationViewport
203
+ ? sourceDataId
204
+ ? presentationViewport.getDisplaySetPresentation(sourceDataId)?.voiLUTFunction
205
+ : undefined
206
+ : viewport.getProperties().VOILUTFunction;
195
207
  const voiRange = utilities.windowLevel.toLowHighRange(windowWidth, windowCenter, voiLutFunction);
196
- viewport.setProperties({ voiRange });
208
+ if (presentationViewport) {
209
+ if (sourceDataId) {
210
+ presentationViewport.setDisplaySetPresentation(sourceDataId, {
211
+ voiRange,
212
+ });
213
+ }
214
+ else {
215
+ presentationViewport.setDisplaySetPresentation({ voiRange });
216
+ }
217
+ }
218
+ else {
219
+ viewport.setProperties({ voiRange });
220
+ }
197
221
  viewport.render();
198
222
  };
199
223
  this.cancel = () => {
@@ -54,23 +54,19 @@ class WindowLevelTool extends BaseTool {
54
54
  viewportsContainingVolumeUID =
55
55
  utilities.getViewportsWithVolumeId(volumeId);
56
56
  ({ lower, upper } = properties.voiRange);
57
- const volume = cache.getVolume(volumeId);
58
- if (!volume) {
57
+ if (!cache.getVolume(volumeId)) {
59
58
  throw new Error('Volume not found ' + volumeId);
60
59
  }
61
- modality = volume.metadata.Modality;
62
- isPreScaled = volume.scaling && Object.keys(volume.scaling).length > 0;
63
60
  }
64
61
  else if (properties.voiRange) {
65
- modality = viewport.modality;
66
62
  ({ lower, upper } = properties.voiRange);
67
- const { preScale = { scaled: false } } = viewport.getImageData?.() || {};
68
- isPreScaled =
69
- preScale.scaled && preScale.scalingParameters?.suvbw !== undefined;
70
63
  }
71
64
  else {
72
65
  throw new Error('Viewport is not a valid type');
73
66
  }
67
+ const descriptor = utilities.getScalingDescriptor(viewport, volumeId);
68
+ modality = descriptor?.modality;
69
+ isPreScaled = !!descriptor?.isPreScaled;
74
70
  if (modality === PT && isPreScaled) {
75
71
  newRange = this.getPTScaledNewRange({
76
72
  deltaPointsCanvas: deltaPoints.canvas,
@@ -3,6 +3,7 @@ import { drawHandles as drawHandlesSvg, drawTextBox as drawTextBoxSvg, } from '.
3
3
  import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
4
4
  import { hideElementCursor } from '../../cursors/elementCursor';
5
5
  import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
6
+ import getViewportICamera from '../../utilities/getViewportICamera';
6
7
  import ProbeTool from './ProbeTool';
7
8
  class DragProbeTool extends ProbeTool {
8
9
  constructor(toolProps = {}, defaultToolProps = {
@@ -21,7 +22,7 @@ class DragProbeTool extends ProbeTool {
21
22
  const enabledElement = getEnabledElement(element);
22
23
  const { viewport, renderingEngine } = enabledElement;
23
24
  this.isDrawing = true;
24
- const camera = viewport.getCamera();
25
+ const camera = getViewportICamera(viewport);
25
26
  const { viewPlaneNormal, viewUp } = camera;
26
27
  const referencedImageId = this.getReferencedImageId(viewport, worldPos, viewPlaneNormal, viewUp);
27
28
  const annotation = {
@@ -1,4 +1,5 @@
1
1
  import { AnnotationTool } from '../base';
2
+ import getViewportICamera from '../../utilities/getViewportICamera';
2
3
  import { getEnabledElement } from '@cornerstonejs/core';
3
4
  import { addAnnotation, getAnnotations, removeAnnotation, } from '../../stateManagement/annotation/annotationState';
4
5
  import { isAnnotationVisible } from '../../stateManagement/annotation/annotationVisibility';
@@ -31,7 +32,7 @@ class ETDRSGridTool extends AnnotationTool {
31
32
  const enabledElement = getEnabledElement(element);
32
33
  const { viewport, renderingEngine } = enabledElement;
33
34
  this.isDrawing = true;
34
- const camera = viewport.getCamera();
35
+ const camera = getViewportICamera(viewport);
35
36
  const { viewPlaneNormal, viewUp } = camera;
36
37
  const referencedImageId = this.getReferencedImageId(viewport, worldPos, viewPlaneNormal, viewUp);
37
38
  const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
@@ -341,7 +342,7 @@ class ETDRSGridTool extends AnnotationTool {
341
342
  viewport.canvas.width / 2,
342
343
  viewport.canvas.height / 2,
343
344
  ]);
344
- const { viewUp } = viewport.getCamera();
345
+ const { viewUp } = getViewportICamera(viewport);
345
346
  const p2 = vec3.scaleAndAdd(vec3.create(), p1, viewUp, measurement);
346
347
  const p1Canvas = viewport.worldToCanvas(p1);
347
348
  const p2Canvas = viewport.worldToCanvas(p2);
@@ -11,6 +11,7 @@ import { drawCircle as drawCircleSvg, drawEllipseByCoordinates as drawEllipseSvg
11
11
  import { state } from '../../store/state';
12
12
  import { ChangeTypes, Events } from '../../enums';
13
13
  import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
14
+ import getViewportICamera from '../../utilities/getViewportICamera';
14
15
  import getWorldWidthAndHeightFromTwoPoints from '../../utilities/planar/getWorldWidthAndHeightFromTwoPoints';
15
16
  import { pointInEllipse, getCanvasEllipseCorners, } from '../../utilities/math/ellipse';
16
17
  import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCursor';
@@ -499,7 +500,7 @@ class EllipticalROITool extends AnnotationTool {
499
500
  const { element } = viewport;
500
501
  const { points } = data.handles;
501
502
  const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p));
502
- const { viewPlaneNormal, viewUp } = viewport.getCamera();
503
+ const { viewPlaneNormal, viewUp } = getViewportICamera(viewport);
503
504
  const [topLeftCanvas, bottomRightCanvas] = (getCanvasEllipseCorners(canvasCoordinates));
504
505
  const topLeftWorld = viewport.canvasToWorld(topLeftCanvas);
505
506
  const bottomRightWorld = viewport.canvasToWorld(bottomRightCanvas);
@@ -7,6 +7,7 @@ import { addAnnotation, getAnnotations, removeAnnotation, } from '../../stateMan
7
7
  import { drawTextBox as drawTextBoxSvg } from '../../drawingSvg';
8
8
  import { state } from '../../store/state';
9
9
  import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
10
+ import getViewportICamera from '../../utilities/getViewportICamera';
10
11
  import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
11
12
  import { triggerAnnotationCompleted, triggerAnnotationModified, } from '../../stateManagement/annotation/helpers/state';
12
13
  import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCursor';
@@ -278,7 +279,7 @@ LabelTool.hydrate = (viewportId, position, label, options) => {
278
279
  }
279
280
  const { viewport } = enabledElement;
280
281
  const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
281
- const { viewPlaneNormal, viewUp } = viewport.getCamera();
282
+ const { viewPlaneNormal, viewUp } = getViewportICamera(viewport);
282
283
  const instance = new _a();
283
284
  const referencedImageId = instance.getReferencedImageId(viewport, position, viewPlaneNormal, viewUp);
284
285
  const annotation = {
@@ -441,7 +441,18 @@ class LivewireContourTool extends ContourSegmentationBaseTool {
441
441
  throw new Error('Viewport not supported');
442
442
  }
443
443
  scalarData = csUtils.convertToGrayscale(scalarData, width, height);
444
- const { voiRange } = viewport.getProperties();
444
+ let voiRange;
445
+ const sourceViewport = viewport;
446
+ if (csUtils.viewportSupportsDisplaySetPresentation(sourceViewport)) {
447
+ const dataId = sourceViewport.getSourceDataId();
448
+ voiRange = (((dataId
449
+ ? sourceViewport.getDisplaySetPresentation(dataId)?.voiRange
450
+ : undefined) ?? sourceViewport.getDefaultVOIRange(dataId)) ??
451
+ undefined);
452
+ }
453
+ else {
454
+ ({ voiRange } = viewport.getProperties());
455
+ }
445
456
  const startPos = worldToSlice(worldPos);
446
457
  this.scissors = LivewireScissors.createInstanceFromRawPixelData(scalarData, width, height, voiRange);
447
458
  if (nextPos) {
@@ -12,6 +12,7 @@ import { drawHandles as drawHandlesSvg, drawRectByCoordinates as drawRectSvg, }
12
12
  import { state } from '../../store/state';
13
13
  import { ChangeTypes, Events } from '../../enums';
14
14
  import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
15
+ import getViewportICamera from '../../utilities/getViewportICamera';
15
16
  import * as rectangle from '../../utilities/math/rectangle';
16
17
  import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCursor';
17
18
  import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
@@ -334,7 +335,7 @@ class RectangleROITool extends AnnotationTool {
334
335
  annotation,
335
336
  styleSpecifier,
336
337
  });
337
- const { viewPlaneNormal, viewUp } = viewport.getCamera();
338
+ const { viewPlaneNormal, viewUp } = getViewportICamera(viewport);
338
339
  if (!data.cachedStats[targetId] ||
339
340
  data.cachedStats[targetId].areaUnit == null) {
340
341
  data.cachedStats[targetId] = {
@@ -10,6 +10,7 @@ import * as lineSegment from '../../../utilities/math/line';
10
10
  import { drawHandles as drawHandlesSvg, drawLine as drawLineSvg, drawFan as drawFanSvg, } from '../../../drawingSvg';
11
11
  import { state } from '../../../store/state';
12
12
  import { getViewportIdsWithToolToRender } from '../../../utilities/viewportFilters';
13
+ import getViewportICamera from '../../../utilities/getViewportICamera';
13
14
  import triggerAnnotationRenderForViewportIds from '../../../utilities/triggerAnnotationRenderForViewportIds';
14
15
  import { resetElementCursor, hideElementCursor, } from '../../../cursors/elementCursor';
15
16
  import { angleFromCenter, calculateInnerFanPercentage, clipInterval, intervalFromPoints, mergeIntervals, subtractIntervals, } from '../../../utilities/math/fan/fanUtils';
@@ -61,7 +62,7 @@ class UltrasoundPleuraBLineTool extends AnnotationTool {
61
62
  const { viewport } = enabledElement;
62
63
  hideElementCursor(element);
63
64
  this.isDrawing = true;
64
- const { viewPlaneNormal, viewUp, position: cameraPosition, } = viewport.getCamera();
65
+ const { viewPlaneNormal, viewUp, position: cameraPosition, } = getViewportICamera(viewport);
65
66
  const referencedImageId = this.getReferencedImageId(viewport, worldPos, viewPlaneNormal, viewUp);
66
67
  const annotation = {
67
68
  highlighted: true,