@cornerstonejs/tools 1.70.5 → 1.70.6

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 (81) hide show
  1. package/dist/cjs/tools/AdvancedMagnifyTool.d.ts +1 -1
  2. package/dist/cjs/tools/AdvancedMagnifyTool.js +35 -43
  3. package/dist/cjs/tools/AdvancedMagnifyTool.js.map +1 -1
  4. package/dist/cjs/tools/AdvancedMagnifyViewport.d.ts +1 -1
  5. package/dist/cjs/tools/AdvancedMagnifyViewport.js +8 -2
  6. package/dist/cjs/tools/AdvancedMagnifyViewport.js.map +1 -1
  7. package/dist/cjs/tools/AdvancedMagnifyViewportManager.d.ts +2 -1
  8. package/dist/cjs/tools/AdvancedMagnifyViewportManager.js +32 -3
  9. package/dist/cjs/tools/AdvancedMagnifyViewportManager.js.map +1 -1
  10. package/dist/cjs/tools/OrientationMarkerTool.js +6 -1
  11. package/dist/cjs/tools/OrientationMarkerTool.js.map +1 -1
  12. package/dist/cjs/tools/base/AnnotationTool.js +4 -1
  13. package/dist/cjs/tools/base/AnnotationTool.js.map +1 -1
  14. package/dist/cjs/tools/displayTools/Labelmap/labelmapDisplay.js +5 -0
  15. package/dist/cjs/tools/displayTools/Labelmap/labelmapDisplay.js.map +1 -1
  16. package/dist/cjs/tools/segmentation/BrushTool.js +12 -1
  17. package/dist/cjs/tools/segmentation/BrushTool.js.map +1 -1
  18. package/dist/cjs/tools/segmentation/strategies/compositions/dynamicThreshold.js +3 -0
  19. package/dist/cjs/tools/segmentation/strategies/compositions/dynamicThreshold.js.map +1 -1
  20. package/dist/cjs/tools/segmentation/strategies/compositions/preview.js +10 -2
  21. package/dist/cjs/tools/segmentation/strategies/compositions/preview.js.map +1 -1
  22. package/dist/cjs/types/ToolSpecificAnnotationTypes.d.ts +2 -1
  23. package/dist/cjs/utilities/cine/playClip.d.ts +1 -1
  24. package/dist/cjs/utilities/cine/playClip.js +2 -5
  25. package/dist/cjs/utilities/cine/playClip.js.map +1 -1
  26. package/dist/cjs/utilities/planar/filterAnnotationsForDisplay.js +3 -0
  27. package/dist/cjs/utilities/planar/filterAnnotationsForDisplay.js.map +1 -1
  28. package/dist/esm/tools/AdvancedMagnifyTool.js +35 -43
  29. package/dist/esm/tools/AdvancedMagnifyTool.js.map +1 -1
  30. package/dist/esm/tools/AdvancedMagnifyViewport.js +8 -2
  31. package/dist/esm/tools/AdvancedMagnifyViewport.js.map +1 -1
  32. package/dist/esm/tools/AdvancedMagnifyViewportManager.js +38 -4
  33. package/dist/esm/tools/AdvancedMagnifyViewportManager.js.map +1 -1
  34. package/dist/esm/tools/OrientationMarkerTool.js +6 -1
  35. package/dist/esm/tools/OrientationMarkerTool.js.map +1 -1
  36. package/dist/esm/tools/base/AnnotationTool.js +4 -1
  37. package/dist/esm/tools/base/AnnotationTool.js.map +1 -1
  38. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.js +5 -0
  39. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.js.map +1 -1
  40. package/dist/esm/tools/segmentation/BrushTool.js +13 -2
  41. package/dist/esm/tools/segmentation/BrushTool.js.map +1 -1
  42. package/dist/esm/tools/segmentation/strategies/compositions/dynamicThreshold.js +3 -0
  43. package/dist/esm/tools/segmentation/strategies/compositions/dynamicThreshold.js.map +1 -1
  44. package/dist/esm/tools/segmentation/strategies/compositions/preview.js +10 -2
  45. package/dist/esm/tools/segmentation/strategies/compositions/preview.js.map +1 -1
  46. package/dist/esm/utilities/cine/playClip.js +2 -2
  47. package/dist/esm/utilities/cine/playClip.js.map +1 -1
  48. package/dist/esm/utilities/planar/filterAnnotationsForDisplay.js +3 -0
  49. package/dist/esm/utilities/planar/filterAnnotationsForDisplay.js.map +1 -1
  50. package/dist/types/tools/AdvancedMagnifyTool.d.ts +1 -1
  51. package/dist/types/tools/AdvancedMagnifyTool.d.ts.map +1 -1
  52. package/dist/types/tools/AdvancedMagnifyViewport.d.ts +1 -1
  53. package/dist/types/tools/AdvancedMagnifyViewport.d.ts.map +1 -1
  54. package/dist/types/tools/AdvancedMagnifyViewportManager.d.ts +2 -1
  55. package/dist/types/tools/AdvancedMagnifyViewportManager.d.ts.map +1 -1
  56. package/dist/types/tools/OrientationMarkerTool.d.ts.map +1 -1
  57. package/dist/types/tools/base/AnnotationTool.d.ts.map +1 -1
  58. package/dist/types/tools/displayTools/Labelmap/labelmapDisplay.d.ts.map +1 -1
  59. package/dist/types/tools/segmentation/BrushTool.d.ts.map +1 -1
  60. package/dist/types/tools/segmentation/strategies/compositions/dynamicThreshold.d.ts.map +1 -1
  61. package/dist/types/tools/segmentation/strategies/compositions/preview.d.ts.map +1 -1
  62. package/dist/types/types/ToolSpecificAnnotationTypes.d.ts +2 -1
  63. package/dist/types/types/ToolSpecificAnnotationTypes.d.ts.map +1 -1
  64. package/dist/types/utilities/cine/playClip.d.ts +1 -1
  65. package/dist/types/utilities/cine/playClip.d.ts.map +1 -1
  66. package/dist/types/utilities/planar/filterAnnotationsForDisplay.d.ts.map +1 -1
  67. package/dist/umd/index.js +1 -1
  68. package/dist/umd/index.js.map +1 -1
  69. package/package.json +4 -4
  70. package/src/tools/AdvancedMagnifyTool.ts +42 -66
  71. package/src/tools/AdvancedMagnifyViewport.ts +11 -3
  72. package/src/tools/AdvancedMagnifyViewportManager.ts +74 -3
  73. package/src/tools/OrientationMarkerTool.ts +7 -1
  74. package/src/tools/base/AnnotationTool.ts +8 -2
  75. package/src/tools/displayTools/Labelmap/labelmapDisplay.ts +7 -0
  76. package/src/tools/segmentation/BrushTool.ts +17 -1
  77. package/src/tools/segmentation/strategies/compositions/dynamicThreshold.ts +6 -0
  78. package/src/tools/segmentation/strategies/compositions/preview.ts +14 -4
  79. package/src/types/ToolSpecificAnnotationTypes.ts +2 -1
  80. package/src/utilities/cine/playClip.ts +2 -2
  81. package/src/utilities/planar/filterAnnotationsForDisplay.ts +3 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/tools",
3
- "version": "1.70.5",
3
+ "version": "1.70.6",
4
4
  "description": "Cornerstone3D Tools",
5
5
  "main": "src/index.ts",
6
6
  "types": "dist/types/index.d.ts",
@@ -29,7 +29,7 @@
29
29
  "webpack:watch": "webpack --mode development --progress --watch --config ./.webpack/webpack.dev.js"
30
30
  },
31
31
  "dependencies": {
32
- "@cornerstonejs/core": "^1.70.5",
32
+ "@cornerstonejs/core": "^1.70.6",
33
33
  "@icr/polyseg-wasm": "0.4.0",
34
34
  "@types/offscreencanvas": "2019.7.3",
35
35
  "comlink": "^4.4.1",
@@ -41,7 +41,7 @@
41
41
  },
42
42
  "peerDependencies": {
43
43
  "@icr/polyseg-wasm": "0.4.0",
44
- "@kitware/vtk.js": "30.3.1",
44
+ "@kitware/vtk.js": "30.3.3",
45
45
  "@types/d3-array": "^3.0.4",
46
46
  "@types/d3-interpolate": "^3.0.1",
47
47
  "d3-array": "^3.2.3",
@@ -59,5 +59,5 @@
59
59
  "type": "individual",
60
60
  "url": "https://ohif.org/donate"
61
61
  },
62
- "gitHead": "bf3d33986d1cdad6ab4abf9e4004dcb16a1a83c9"
62
+ "gitHead": "6358796a0031d69a9987ce089bbc27b8a3801dc1"
63
63
  }
@@ -66,8 +66,8 @@ class AdvancedMagnifyTool extends AnnotationTool {
66
66
  shadow: true,
67
67
  magnifyingGlass: {
68
68
  radius: 125, // px
69
- zoomFactor: 2.5,
70
- zoomFactorList: [2.5, 3, 3.5, 4, 4.5, 5],
69
+ zoomFactor: 3,
70
+ zoomFactorList: [1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5],
71
71
  autoPan: {
72
72
  enabled: true,
73
73
  padding: 10, // px
@@ -111,11 +111,10 @@ class AdvancedMagnifyTool extends AnnotationTool {
111
111
  const { magnifyingGlass: config } = this.configuration;
112
112
  const { radius, zoomFactor, autoPan } = config;
113
113
 
114
- const worldHandlesPoints = this._getWorldHandlesPoints(
115
- viewport,
114
+ const canvasHandlePoints = this._getCanvasHandlePoints(
116
115
  canvasPos,
117
116
  radius
118
- );
117
+ ) as [Types.Point3, Types.Point3, Types.Point3, Types.Point3];
119
118
 
120
119
  const camera = viewport.getCamera();
121
120
  const { viewPlaneNormal, viewUp } = camera;
@@ -146,8 +145,11 @@ class AdvancedMagnifyTool extends AnnotationTool {
146
145
  sourceViewportId: viewport.id,
147
146
  magnifyViewportId,
148
147
  zoomFactor,
148
+ // this means that the last coordinate for the points
149
+ // is 0 and should not be used for calculations
150
+ isCanvasAnnotation: true,
149
151
  handles: {
150
- points: worldHandlesPoints,
152
+ points: canvasHandlePoints,
151
153
  activeHandleIndex: null,
152
154
  },
153
155
  },
@@ -164,12 +166,13 @@ class AdvancedMagnifyTool extends AnnotationTool {
164
166
  padding: autoPan.padding,
165
167
  callback: (data: AutoPanCallbackData) => {
166
168
  const annotationPoints = annotation.data.handles.points;
167
- const { world: worldDelta } = data.delta;
169
+ const { canvas: canvasDelta } = data.delta;
168
170
 
169
171
  for (let i = 0, len = annotationPoints.length; i < len; i++) {
170
- annotationPoints[i][0] += worldDelta[0];
171
- annotationPoints[i][1] += worldDelta[1];
172
- annotationPoints[i][2] += worldDelta[2];
172
+ const point = annotationPoints[i];
173
+ point[0] += canvasDelta[0];
174
+ point[1] += canvasDelta[1];
175
+ annotation.invalidated = true;
173
176
  }
174
177
  },
175
178
  },
@@ -217,20 +220,12 @@ class AdvancedMagnifyTool extends AnnotationTool {
217
220
  canvasCoords: Types.Point2,
218
221
  proximity: number
219
222
  ): boolean => {
220
- const enabledElement = getEnabledElement(element);
221
- const { viewport } = enabledElement;
222
-
223
223
  const { data } = annotation;
224
224
  const { points } = data.handles;
225
225
 
226
226
  // For some reason Typescript doesn't understand this, so we need to be
227
227
  // more specific about the type
228
- const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p)) as [
229
- Types.Point2,
230
- Types.Point2,
231
- Types.Point2,
232
- Types.Point2
233
- ];
228
+ const canvasCoordinates = points;
234
229
 
235
230
  const canvasTop = canvasCoordinates[0];
236
231
  const canvasBottom = canvasCoordinates[2];
@@ -242,7 +237,7 @@ class AdvancedMagnifyTool extends AnnotationTool {
242
237
  ] as Types.Point2;
243
238
  const radiusPoint = getCanvasCircleRadius([center, canvasCoords]);
244
239
 
245
- if (Math.abs(radiusPoint - radius) < proximity * 1.5) {
240
+ if (Math.abs(radiusPoint - radius) < proximity * 2) {
246
241
  return true;
247
242
  }
248
243
 
@@ -347,7 +342,7 @@ class AdvancedMagnifyTool extends AnnotationTool {
347
342
  this.isDrawing = true;
348
343
  const eventDetail = evt.detail;
349
344
  const { element, deltaPoints } = eventDetail;
350
- const worldPosDelta = deltaPoints?.world ?? [0, 0, 0];
345
+ const canvasDelta = deltaPoints?.canvas ?? [0, 0, 0];
351
346
  const enabledElement = getEnabledElement(element);
352
347
  const { renderingEngine } = enabledElement;
353
348
 
@@ -355,9 +350,8 @@ class AdvancedMagnifyTool extends AnnotationTool {
355
350
  const { points } = annotation.data.handles;
356
351
 
357
352
  points.forEach((point) => {
358
- point[0] += worldPosDelta[0];
359
- point[1] += worldPosDelta[1];
360
- point[2] += worldPosDelta[2];
353
+ point[0] += canvasDelta[0];
354
+ point[1] += canvasDelta[1];
361
355
  });
362
356
 
363
357
  annotation.invalidated = true;
@@ -377,14 +371,13 @@ class AdvancedMagnifyTool extends AnnotationTool {
377
371
  if (handleIndex === undefined) {
378
372
  // Moving tool
379
373
  const { deltaPoints } = eventDetail;
380
- const worldPosDelta = deltaPoints.world;
374
+ const canvasDelta = deltaPoints.canvas;
381
375
 
382
376
  const points = data.handles.points;
383
377
 
384
378
  points.forEach((point) => {
385
- point[0] += worldPosDelta[0];
386
- point[1] += worldPosDelta[1];
387
- point[2] += worldPosDelta[2];
379
+ point[0] += canvasDelta[0];
380
+ point[1] += canvasDelta[1];
388
381
  });
389
382
  annotation.invalidated = true;
390
383
  } else {
@@ -400,16 +393,12 @@ class AdvancedMagnifyTool extends AnnotationTool {
400
393
 
401
394
  _dragHandle = (evt: EventTypes.InteractionEventType): void => {
402
395
  const eventDetail = evt.detail;
403
- const { element } = eventDetail;
404
- const enabledElement = getEnabledElement(element);
405
- const { viewport } = enabledElement;
406
- const { worldToCanvas } = viewport;
407
396
 
408
397
  const { annotation } = this.editData;
409
398
  const { data } = annotation;
410
399
  const { points } = data.handles;
411
400
 
412
- const canvasCoordinates = points.map((p) => worldToCanvas(p));
401
+ const canvasCoordinates = points;
413
402
  const canvasTop = canvasCoordinates[0];
414
403
  const canvasBottom = canvasCoordinates[2];
415
404
  const canvasLeft = canvasCoordinates[3];
@@ -426,16 +415,15 @@ class AdvancedMagnifyTool extends AnnotationTool {
426
415
  canvasCenter,
427
416
  currentCanvasPoints,
428
417
  ]);
429
- const newWorldHandlesPoints = this._getWorldHandlesPoints(
430
- viewport,
418
+ const newCanvasHandlePoints = this._getCanvasHandlePoints(
431
419
  canvasCenter,
432
420
  newRadius
433
421
  );
434
422
 
435
- points[0] = newWorldHandlesPoints[0];
436
- points[1] = newWorldHandlesPoints[1];
437
- points[2] = newWorldHandlesPoints[2];
438
- points[3] = newWorldHandlesPoints[3];
423
+ points[0] = newCanvasHandlePoints[0];
424
+ points[1] = newCanvasHandlePoints[1];
425
+ points[2] = newCanvasHandlePoints[2];
426
+ points[3] = newCanvasHandlePoints[3];
439
427
  };
440
428
 
441
429
  cancel = (element: HTMLDivElement) => {
@@ -513,18 +501,18 @@ class AdvancedMagnifyTool extends AnnotationTool {
513
501
  return renderStatus;
514
502
  }
515
503
 
516
- annotations = this.filterInteractableAnnotationsForElement(
517
- element,
518
- annotations
519
- );
520
-
521
504
  annotations = annotations?.filter(
522
505
  (annotation) =>
523
506
  (<AdvancedMagnifyAnnotation>annotation).data.sourceViewportId ===
524
507
  viewport.id
525
508
  );
526
509
 
527
- if (!annotations?.length) {
510
+ const filteredAnnotations = this.filterInteractableAnnotationsForElement(
511
+ element,
512
+ annotations
513
+ );
514
+
515
+ if (!filteredAnnotations?.length) {
528
516
  return renderStatus;
529
517
  }
530
518
 
@@ -534,8 +522,8 @@ class AdvancedMagnifyTool extends AnnotationTool {
534
522
  viewportId: enabledElement.viewport.id,
535
523
  };
536
524
 
537
- for (let i = 0; i < annotations.length; i++) {
538
- const annotation = annotations[i] as AdvancedMagnifyAnnotation;
525
+ for (let i = 0; i < filteredAnnotations.length; i++) {
526
+ const annotation = filteredAnnotations[i] as AdvancedMagnifyAnnotation;
539
527
  const { annotationUID, data } = annotation;
540
528
  const { magnifyViewportId, zoomFactor, handles } = data;
541
529
  const { points, activeHandleIndex } = handles;
@@ -546,9 +534,7 @@ class AdvancedMagnifyTool extends AnnotationTool {
546
534
  const lineDash = this.getStyle('lineDash', styleSpecifier, annotation);
547
535
  const color = this.getStyle('color', styleSpecifier, annotation);
548
536
 
549
- const canvasCoordinates = points.map((p) =>
550
- viewport.worldToCanvas(p)
551
- ) as Types.Point2[];
537
+ const canvasCoordinates = points;
552
538
  const canvasTop = canvasCoordinates[0];
553
539
  const canvasBottom = canvasCoordinates[2];
554
540
  const canvasLeft = canvasCoordinates[3];
@@ -701,23 +687,13 @@ class AdvancedMagnifyTool extends AnnotationTool {
701
687
  return dropdown;
702
688
  }
703
689
 
704
- private _getWorldHandlesPoints = (
705
- viewport,
706
- canvasCenterPos,
707
- canvasRadius
708
- ): Types.Point3[] => {
709
- const canvasHandlesPoints = [
710
- [canvasCenterPos[0], canvasCenterPos[1] - canvasRadius], // top
711
- [canvasCenterPos[0] + canvasRadius, canvasCenterPos[1]], // right
712
- [canvasCenterPos[0], canvasCenterPos[1] + canvasRadius], // bottom
713
- [canvasCenterPos[0] - canvasRadius, canvasCenterPos[1]], // left
690
+ private _getCanvasHandlePoints = (canvasCenterPos, canvasRadius) => {
691
+ return [
692
+ [canvasCenterPos[0], canvasCenterPos[1] - canvasRadius, 0], // top
693
+ [canvasCenterPos[0] + canvasRadius, canvasCenterPos[1], 0], // right
694
+ [canvasCenterPos[0], canvasCenterPos[1] + canvasRadius, 0], // bottom
695
+ [canvasCenterPos[0] - canvasRadius, canvasCenterPos[1], 0], // left
714
696
  ];
715
-
716
- const worldHandlesPoints = canvasHandlesPoints.map((p) =>
717
- viewport.canvasToWorld(p)
718
- ) as Types.Point3[];
719
-
720
- return worldHandlesPoints;
721
697
  };
722
698
  }
723
699
 
@@ -91,7 +91,7 @@ class AdvancedMagnifyViewport {
91
91
  this._sourceEnabledElement = sourceEnabledElement;
92
92
  this._autoPan = autoPan;
93
93
 
94
- // Pulic properties
94
+ // Public properties
95
95
  this.radius = radius;
96
96
  this.position = position;
97
97
  this.zoomFactor = zoomFactor;
@@ -234,7 +234,7 @@ class AdvancedMagnifyViewport {
234
234
  return magnifyElement;
235
235
  }
236
236
 
237
- private _convertZoomFactorToParalellScale(
237
+ private _convertZoomFactorToParallelScale(
238
238
  viewport,
239
239
  magnifyViewport,
240
240
  zoomFactor
@@ -556,7 +556,7 @@ class AdvancedMagnifyViewport {
556
556
  const worldPos = sourceViewport.canvasToWorld(this.position);
557
557
 
558
558
  // Use the original viewport for the base for parallelScale
559
- const parallelScale = this._convertZoomFactorToParalellScale(
559
+ const parallelScale = this._convertZoomFactorToParallelScale(
560
560
  sourceViewport,
561
561
  magnifyViewport,
562
562
  this.zoomFactor
@@ -601,6 +601,11 @@ class AdvancedMagnifyViewport {
601
601
  const { viewport: sourceViewport } = this._sourceEnabledElement;
602
602
  const { viewport: magnifyViewport } = this._enabledElement;
603
603
  const sourceProperties = sourceViewport.getProperties();
604
+ const imageData = magnifyViewport.getImageData();
605
+
606
+ if (!imageData) {
607
+ return;
608
+ }
604
609
 
605
610
  magnifyViewport.setProperties(sourceProperties);
606
611
  this._syncViewportsCameras(sourceViewport, magnifyViewport);
@@ -611,6 +616,9 @@ class AdvancedMagnifyViewport {
611
616
  magnifyViewport as Types.IStackViewport
612
617
  );
613
618
  }
619
+
620
+ this._syncViewportsCameras(sourceViewport, magnifyViewport);
621
+ magnifyViewport.render();
614
622
  }
615
623
 
616
624
  private _resizeViewport() {
@@ -4,6 +4,7 @@ import {
4
4
  Enums,
5
5
  getRenderingEngine,
6
6
  CONSTANTS,
7
+ getEnabledElementByViewportId,
7
8
  } from '@cornerstonejs/core';
8
9
  import type { Types } from '@cornerstonejs/core';
9
10
  import { AnnotationRemovedEventType } from '../types/EventTypes';
@@ -47,6 +48,7 @@ export type MagnifyViewportInfo = {
47
48
  type MagnifyViewportsMapEntry = {
48
49
  annotation: AdvancedMagnifyAnnotation;
49
50
  magnifyViewport: AdvancedMagnifyViewport;
51
+ magnifyViewportInfo: MagnifyViewportInfo;
50
52
  };
51
53
 
52
54
  /**
@@ -110,6 +112,7 @@ class AdvancedMagnifyViewportManager {
110
112
  this._magnifyViewportsMap.set(magnifyViewport.viewportId, {
111
113
  annotation,
112
114
  magnifyViewport,
115
+ magnifyViewportInfo: viewportInfo,
113
116
  });
114
117
 
115
118
  return magnifyViewport;
@@ -133,7 +136,7 @@ class AdvancedMagnifyViewportManager {
133
136
  this._destroyViewports();
134
137
  }
135
138
 
136
- private _destroyViewport(magnifyViewportId: string) {
139
+ public destroyViewport(magnifyViewportId: string) {
137
140
  const magnifyViewportMapEntry =
138
141
  this._magnifyViewportsMap.get(magnifyViewportId);
139
142
 
@@ -153,7 +156,7 @@ class AdvancedMagnifyViewportManager {
153
156
  const magnifyViewportIds = Array.from(this._magnifyViewportsMap.keys());
154
157
 
155
158
  magnifyViewportIds.forEach((magnifyViewportId) =>
156
- this._destroyViewport(magnifyViewportId)
159
+ this.destroyViewport(magnifyViewportId)
157
160
  );
158
161
  }
159
162
 
@@ -164,7 +167,7 @@ class AdvancedMagnifyViewportManager {
164
167
  return;
165
168
  }
166
169
 
167
- this._destroyViewport(annotation.data.magnifyViewportId);
170
+ this.destroyViewport(annotation.data.magnifyViewportId);
168
171
  };
169
172
 
170
173
  private _getMagnifyViewportsMapEntriesBySourceViewportId(sourceViewportId) {
@@ -185,6 +188,17 @@ class AdvancedMagnifyViewportManager {
185
188
  const magnifyViewportsMapEntries =
186
189
  this._getMagnifyViewportsMapEntriesBySourceViewportId(sourceViewportId);
187
190
 
191
+ const { viewport } = getEnabledElementByViewportId(sourceViewportId);
192
+
193
+ // if the viewport was new in terms of image, we need to destroy the magnify
194
+ // viewports and recreate them, the new image might have different dimensions
195
+ // or orientation etc.
196
+ if ((viewport as Types.IStackViewport).stackActorReInitialized) {
197
+ // we should invalidate the viewport as well
198
+ // this will trigger the magnify viewport to be updated
199
+ this._reset(sourceViewportId);
200
+ }
201
+
188
202
  magnifyViewportsMapEntries.forEach(({ annotation }) => {
189
203
  annotation.metadata.referencedImageId = imageId;
190
204
  annotation.invalidated = true;
@@ -242,6 +256,29 @@ class AdvancedMagnifyViewportManager {
242
256
  });
243
257
  };
244
258
 
259
+ private _reset(sourceViewportId: string) {
260
+ const magnifyViewports =
261
+ this._getMagnifyViewportsMapEntriesBySourceViewportId(sourceViewportId);
262
+
263
+ magnifyViewports.forEach(
264
+ ({ magnifyViewport, annotation, magnifyViewportInfo }) => {
265
+ this.destroyViewport(magnifyViewport.viewportId);
266
+
267
+ // if it is new image we need to update the magnifyViewportInfo
268
+ // since it might have new image dimensions etc.
269
+ const newEnabledElement =
270
+ getEnabledElementByViewportId(sourceViewportId);
271
+
272
+ this.createViewport(annotation, {
273
+ ...magnifyViewportInfo,
274
+ sourceEnabledElement: {
275
+ ...newEnabledElement,
276
+ },
277
+ });
278
+ }
279
+ );
280
+ }
281
+
245
282
  private _addEventListeners() {
246
283
  eventTarget.addEventListener(
247
284
  cstEvents.ANNOTATION_REMOVED,
@@ -262,10 +299,30 @@ class AdvancedMagnifyViewportManager {
262
299
  this._newStackImageCallback
263
300
  );
264
301
 
302
+ const newStackHandler = (evt) => {
303
+ const { viewportId: sourceViewportId } = evt.detail;
304
+ this._reset(sourceViewportId);
305
+ };
306
+
307
+ element.addEventListener(Events.STACK_VIEWPORT_NEW_STACK, newStackHandler);
308
+
309
+ const newVolumeHandler = (evt) => {
310
+ const { viewportId: sourceViewportId } = evt.detail;
311
+ this._reset(sourceViewportId);
312
+ };
313
+ element.addEventListener(
314
+ Events.VOLUME_VIEWPORT_NEW_VOLUME,
315
+ newVolumeHandler
316
+ );
317
+
265
318
  element.addEventListener(
266
319
  Events.VOLUME_NEW_IMAGE,
267
320
  this._newVolumeImageCallback
268
321
  );
322
+
323
+ // Store the event handlers to remove later
324
+ element.newStackHandler = newStackHandler;
325
+ element.newVolumeHandler = newVolumeHandler;
269
326
  }
270
327
 
271
328
  private _removeSourceElementEventListener(element) {
@@ -278,6 +335,20 @@ class AdvancedMagnifyViewportManager {
278
335
  Events.VOLUME_NEW_IMAGE,
279
336
  this._newVolumeImageCallback
280
337
  );
338
+
339
+ // Remove using the stored handlers
340
+ element.removeEventListener(
341
+ Events.STACK_VIEWPORT_NEW_STACK,
342
+ element.newStackHandler
343
+ );
344
+ element.removeEventListener(
345
+ Events.VOLUME_VIEWPORT_NEW_VOLUME,
346
+ element.newVolumeHandler
347
+ );
348
+
349
+ // Clean up references
350
+ delete element.newStackHandler;
351
+ delete element.newVolumeHandler;
281
352
  }
282
353
 
283
354
  private _initialize() {
@@ -213,7 +213,12 @@ class OrientationMarkerTool extends BaseTool {
213
213
 
214
214
  let viewports = renderingEngine.getViewports();
215
215
  viewports = filterViewportsWithToolEnabled(viewports, this.getToolName());
216
- viewports.forEach((viewport) => this.addAxisActorInViewport(viewport));
216
+
217
+ viewports.forEach((viewport) => {
218
+ if (!viewport.getWidget(this.getToolName())) {
219
+ this.addAxisActorInViewport(viewport);
220
+ }
221
+ });
217
222
  }
218
223
 
219
224
  async addAxisActorInViewport(viewport) {
@@ -268,6 +273,7 @@ class OrientationMarkerTool extends BaseTool {
268
273
  orientationWidget,
269
274
  actor,
270
275
  };
276
+ viewport.addWidget(this.getToolName(), orientationWidget);
271
277
  renderWindow.render();
272
278
  viewport.getRenderingEngine().render();
273
279
 
@@ -266,6 +266,7 @@ abstract class AnnotationTool extends AnnotationDisplayTool {
266
266
  const { viewport } = enabledElement;
267
267
 
268
268
  const { data } = annotation;
269
+ const { isCanvasAnnotation } = data;
269
270
  const { points, textBox } = data.handles;
270
271
 
271
272
  if (textBox) {
@@ -292,10 +293,15 @@ abstract class AnnotationTool extends AnnotationDisplayTool {
292
293
 
293
294
  for (let i = 0; i < points?.length; i++) {
294
295
  const point = points[i];
295
- const annotationCanvasCoordinate = viewport.worldToCanvas(point);
296
+ const annotationCanvasCoordinate = isCanvasAnnotation
297
+ ? point.slice(0, 2)
298
+ : viewport.worldToCanvas(point);
296
299
 
297
300
  const near =
298
- vec2.distance(canvasCoords, annotationCanvasCoordinate) < proximity;
301
+ vec2.distance(
302
+ canvasCoords,
303
+ annotationCanvasCoordinate as Types.Point2
304
+ ) < proximity;
299
305
 
300
306
  if (near === true) {
301
307
  data.handles.activeHandleIndex = i;
@@ -361,6 +361,13 @@ function _setLabelmapColorAndOpacity(
361
361
 
362
362
  for (let i = 1; i < numColors; i++) {
363
363
  // Start from 1 to skip the background segment index.
364
+ const isHidden = segmentsHidden.has(i);
365
+
366
+ if (isHidden) {
367
+ outlineWidths[i - 1] = 0;
368
+ continue;
369
+ }
370
+
364
371
  outlineWidths[i - 1] =
365
372
  i === activeSegmentIndex
366
373
  ? outlineWidth + toolGroupLabelmapConfig.activeSegmentOutlineWidthDelta
@@ -2,6 +2,9 @@ import {
2
2
  utilities as csUtils,
3
3
  cache,
4
4
  getEnabledElement,
5
+ StackViewport,
6
+ eventTarget,
7
+ Enums,
5
8
  } from '@cornerstonejs/core';
6
9
  import { vec3, vec2 } from 'gl-matrix';
7
10
 
@@ -112,7 +115,6 @@ class BrushTool extends BaseTool {
112
115
  strategySpecificConfiguration: {
113
116
  THRESHOLD: {
114
117
  threshold: [-150, -70], // E.g. CT Fat // Only used during threshold strategies.
115
- dynamicRadius: 0, // in voxel counts in each direction, only used during dynamic threshold strategies.
116
118
  },
117
119
  },
118
120
  defaultStrategy: 'FILL_INSIDE_CIRCLE',
@@ -208,6 +210,20 @@ class BrushTool extends BaseTool {
208
210
  ] as LabelmapSegmentationDataVolume;
209
211
  const actors = viewport.getActors();
210
212
 
213
+ const isStackViewport = viewport instanceof StackViewport;
214
+
215
+ if (isStackViewport) {
216
+ const event = new CustomEvent(Enums.Events.ERROR_EVENT, {
217
+ detail: {
218
+ type: 'Segmentation',
219
+ message: 'Cannot perform brush operation on the selected viewport',
220
+ },
221
+ cancelable: true,
222
+ });
223
+ eventTarget.dispatchEvent(event);
224
+ return null;
225
+ }
226
+
211
227
  // we used to take the first actor here but we should take the one that is
212
228
  // probably the same size as the segmentation volume
213
229
  const volumes = actors.map((actorEntry) =>
@@ -77,9 +77,15 @@ export default {
77
77
  const { configuration, viewport } = operationData;
78
78
  const { THRESHOLD: { dynamicRadius = 0 } = {} } =
79
79
  configuration.strategySpecificConfiguration || {};
80
+
81
+ if (dynamicRadius === 0) {
82
+ return;
83
+ }
84
+
80
85
  const { spacing } = (
81
86
  viewport as Types.IStackViewport | Types.IVolumeViewport
82
87
  ).getImageData();
88
+
83
89
  const centerCanvas = [
84
90
  viewport.element.clientWidth / 2,
85
91
  viewport.element.clientHeight / 2,
@@ -4,10 +4,19 @@ import { triggerSegmentationDataModified } from '../../../../stateManagement/seg
4
4
  import { config as segmentationConfig } from '../../../../stateManagement/segmentation';
5
5
  import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
6
6
 
7
+ function lightenColor(r, g, b, a, factor = 0.4) {
8
+ return [
9
+ Math.round(r + (255 - r) * factor),
10
+ Math.round(g + (255 - g) * factor),
11
+ Math.round(b + (255 - b) * factor),
12
+ a,
13
+ ];
14
+ }
15
+
7
16
  /**
8
- * Sets up a preview to use an alternate set of colours. First fills the
17
+ * Sets up a preview to use an alternate set of colors. First fills the
9
18
  * preview segment index with the final one for all pixels, then resets
10
- * the preview colours.
19
+ * the preview colors.
11
20
  * This is only activated when the preview segment index is defined, either
12
21
  * from the initial state or from the global state.
13
22
  */
@@ -71,7 +80,8 @@ export default {
71
80
  if (!configColor && !segmentColor) {
72
81
  return;
73
82
  }
74
- const previewColor = configColor || segmentColor.map((it) => it * 0.9);
83
+ const previewColor = configColor || lightenColor(...segmentColor);
84
+
75
85
  segmentationConfig.color.setColorForSegmentIndex(
76
86
  toolGroupId,
77
87
  segmentationRepresentationUID,
@@ -88,7 +98,7 @@ export default {
88
98
  previewVoxelManager: previewVoxelManager,
89
99
  previewSegmentIndex,
90
100
  preview,
91
- } = operationData;
101
+ } = operationData || {};
92
102
  if (previewSegmentIndex === undefined) {
93
103
  return;
94
104
  }
@@ -87,8 +87,9 @@ export interface AdvancedMagnifyAnnotation extends Annotation {
87
87
  zoomFactor: number;
88
88
  sourceViewportId: string;
89
89
  magnifyViewportId: string;
90
+ isCanvasAnnotation: boolean;
90
91
  handles: {
91
- points: Types.Point3[]; // [top, right, bottom, left]
92
+ points: [Types.Point3, Types.Point3, Types.Point3, Types.Point3]; // in canvas space
92
93
  activeHandleIndex: number | null;
93
94
  };
94
95
  };
@@ -198,10 +198,10 @@ function playClip(
198
198
  * Stops an already playing clip.
199
199
  * @param element - HTML Element
200
200
  */
201
- function stopClip(element: HTMLDivElement, viewportId?: string): void {
201
+ function stopClip(element: HTMLDivElement, options = {} as any): void {
202
202
  _stopClip(element, {
203
203
  stopDynamicCine: true,
204
- viewportId,
204
+ ...options,
205
205
  });
206
206
  }
207
207
 
@@ -47,6 +47,9 @@ export default function filterAnnotationsForDisplay(
47
47
  if (!annotation.isVisible) {
48
48
  return false;
49
49
  }
50
+ if (annotation.data.isCanvasAnnotation) {
51
+ return true;
52
+ }
50
53
  return viewport.isReferenceViewable(annotation.metadata, filterOptions);
51
54
  });
52
55
  }