@cornerstonejs/tools 1.68.1 → 1.68.2

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 (97) hide show
  1. package/dist/cjs/eventListeners/segmentation/imageChangeEventListener.js +5 -1
  2. package/dist/cjs/eventListeners/segmentation/imageChangeEventListener.js.map +1 -1
  3. package/dist/cjs/stateManagement/segmentation/segmentationState.d.ts +2 -1
  4. package/dist/cjs/stateManagement/segmentation/segmentationState.js +14 -1
  5. package/dist/cjs/stateManagement/segmentation/segmentationState.js.map +1 -1
  6. package/dist/cjs/store/ToolGroupManager/ToolGroup.d.ts +3 -0
  7. package/dist/cjs/store/ToolGroupManager/ToolGroup.js +14 -0
  8. package/dist/cjs/store/ToolGroupManager/ToolGroup.js.map +1 -1
  9. package/dist/cjs/synchronizers/synchronizers/createVOISynchronizer.d.ts +1 -1
  10. package/dist/cjs/synchronizers/synchronizers/createVOISynchronizer.js +2 -1
  11. package/dist/cjs/synchronizers/synchronizers/createVOISynchronizer.js.map +1 -1
  12. package/dist/cjs/tools/AdvancedMagnifyTool.d.ts +1 -0
  13. package/dist/cjs/tools/AdvancedMagnifyTool.js +10 -2
  14. package/dist/cjs/tools/AdvancedMagnifyTool.js.map +1 -1
  15. package/dist/cjs/tools/CrosshairsTool.js +2 -1
  16. package/dist/cjs/tools/CrosshairsTool.js.map +1 -1
  17. package/dist/cjs/tools/TrackballRotateTool.js +2 -2
  18. package/dist/cjs/tools/TrackballRotateTool.js.map +1 -1
  19. package/dist/cjs/tools/segmentation/BrushTool.js +2 -1
  20. package/dist/cjs/tools/segmentation/BrushTool.js.map +1 -1
  21. package/dist/cjs/tools/segmentation/strategies/BrushStrategy.js +0 -12
  22. package/dist/cjs/tools/segmentation/strategies/BrushStrategy.js.map +1 -1
  23. package/dist/cjs/utilities/cine/playClip.js +3 -0
  24. package/dist/cjs/utilities/cine/playClip.js.map +1 -1
  25. package/dist/cjs/utilities/getCalibratedUnits.js +10 -5
  26. package/dist/cjs/utilities/getCalibratedUnits.js.map +1 -1
  27. package/dist/cjs/utilities/segmentation/rectangleROIThresholdVolumeByRange.d.ts +1 -0
  28. package/dist/cjs/utilities/segmentation/rectangleROIThresholdVolumeByRange.js +1 -0
  29. package/dist/cjs/utilities/segmentation/rectangleROIThresholdVolumeByRange.js.map +1 -1
  30. package/dist/cjs/utilities/segmentation/thresholdVolumeByRange.d.ts +1 -0
  31. package/dist/cjs/utilities/segmentation/thresholdVolumeByRange.js +1 -1
  32. package/dist/cjs/utilities/segmentation/thresholdVolumeByRange.js.map +1 -1
  33. package/dist/cjs/workers/polySegConverters.js.map +1 -1
  34. package/dist/esm/eventListeners/segmentation/imageChangeEventListener.js +5 -1
  35. package/dist/esm/eventListeners/segmentation/imageChangeEventListener.js.map +1 -1
  36. package/dist/esm/stateManagement/segmentation/segmentationState.js +13 -1
  37. package/dist/esm/stateManagement/segmentation/segmentationState.js.map +1 -1
  38. package/dist/esm/store/ToolGroupManager/ToolGroup.js +14 -0
  39. package/dist/esm/store/ToolGroupManager/ToolGroup.js.map +1 -1
  40. package/dist/esm/synchronizers/synchronizers/createVOISynchronizer.js +2 -1
  41. package/dist/esm/synchronizers/synchronizers/createVOISynchronizer.js.map +1 -1
  42. package/dist/esm/tools/AdvancedMagnifyTool.js +11 -3
  43. package/dist/esm/tools/AdvancedMagnifyTool.js.map +1 -1
  44. package/dist/esm/tools/CrosshairsTool.js +2 -1
  45. package/dist/esm/tools/CrosshairsTool.js.map +1 -1
  46. package/dist/esm/tools/TrackballRotateTool.js +2 -2
  47. package/dist/esm/tools/TrackballRotateTool.js.map +1 -1
  48. package/dist/esm/tools/segmentation/BrushTool.js +1 -1
  49. package/dist/esm/tools/segmentation/BrushTool.js.map +1 -1
  50. package/dist/esm/tools/segmentation/strategies/BrushStrategy.js +1 -13
  51. package/dist/esm/tools/segmentation/strategies/BrushStrategy.js.map +1 -1
  52. package/dist/esm/utilities/cine/playClip.js +3 -0
  53. package/dist/esm/utilities/cine/playClip.js.map +1 -1
  54. package/dist/esm/utilities/getCalibratedUnits.js +10 -5
  55. package/dist/esm/utilities/getCalibratedUnits.js.map +1 -1
  56. package/dist/esm/utilities/segmentation/rectangleROIThresholdVolumeByRange.js +1 -0
  57. package/dist/esm/utilities/segmentation/rectangleROIThresholdVolumeByRange.js.map +1 -1
  58. package/dist/esm/utilities/segmentation/thresholdVolumeByRange.js +1 -1
  59. package/dist/esm/utilities/segmentation/thresholdVolumeByRange.js.map +1 -1
  60. package/dist/esm/workers/polySegConverters.js.map +1 -1
  61. package/dist/types/eventListeners/segmentation/imageChangeEventListener.d.ts.map +1 -1
  62. package/dist/types/stateManagement/segmentation/segmentationState.d.ts +2 -1
  63. package/dist/types/stateManagement/segmentation/segmentationState.d.ts.map +1 -1
  64. package/dist/types/store/ToolGroupManager/ToolGroup.d.ts +3 -0
  65. package/dist/types/store/ToolGroupManager/ToolGroup.d.ts.map +1 -1
  66. package/dist/types/synchronizers/synchronizers/createVOISynchronizer.d.ts +1 -1
  67. package/dist/types/synchronizers/synchronizers/createVOISynchronizer.d.ts.map +1 -1
  68. package/dist/types/tools/AdvancedMagnifyTool.d.ts +1 -0
  69. package/dist/types/tools/AdvancedMagnifyTool.d.ts.map +1 -1
  70. package/dist/types/tools/CrosshairsTool.d.ts.map +1 -1
  71. package/dist/types/tools/segmentation/BrushTool.d.ts.map +1 -1
  72. package/dist/types/tools/segmentation/strategies/BrushStrategy.d.ts.map +1 -1
  73. package/dist/types/utilities/cine/playClip.d.ts.map +1 -1
  74. package/dist/types/utilities/getCalibratedUnits.d.ts.map +1 -1
  75. package/dist/types/utilities/segmentation/rectangleROIThresholdVolumeByRange.d.ts +1 -0
  76. package/dist/types/utilities/segmentation/rectangleROIThresholdVolumeByRange.d.ts.map +1 -1
  77. package/dist/types/utilities/segmentation/thresholdVolumeByRange.d.ts +1 -0
  78. package/dist/types/utilities/segmentation/thresholdVolumeByRange.d.ts.map +1 -1
  79. package/dist/umd/985.index.js.map +1 -1
  80. package/dist/umd/index.js +1 -1
  81. package/dist/umd/index.js.map +1 -1
  82. package/package.json +3 -3
  83. package/src/eventListeners/segmentation/imageChangeEventListener.ts +7 -1
  84. package/src/stateManagement/segmentation/segmentationState.ts +24 -0
  85. package/src/store/ToolGroupManager/ToolGroup.ts +22 -0
  86. package/src/synchronizers/synchronizers/createVOISynchronizer.ts +4 -1
  87. package/src/tools/AdvancedMagnifyTool.ts +15 -2
  88. package/src/tools/AdvancedMagnifyViewportManager.ts +1 -1
  89. package/src/tools/CrosshairsTool.ts +2 -1
  90. package/src/tools/TrackballRotateTool.ts +2 -2
  91. package/src/tools/segmentation/BrushTool.ts +2 -1
  92. package/src/tools/segmentation/strategies/BrushStrategy.ts +0 -20
  93. package/src/utilities/cine/playClip.ts +4 -0
  94. package/src/utilities/getCalibratedUnits.ts +11 -6
  95. package/src/utilities/segmentation/rectangleROIThresholdVolumeByRange.ts +3 -0
  96. package/src/utilities/segmentation/thresholdVolumeByRange.ts +2 -2
  97. package/src/workers/polySegConverters.js +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/tools",
3
- "version": "1.68.1",
3
+ "version": "1.68.2",
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.68.1",
32
+ "@cornerstonejs/core": "^1.68.2",
33
33
  "@icr/polyseg-wasm": "0.4.0",
34
34
  "@types/offscreencanvas": "2019.7.3",
35
35
  "comlink": "^4.4.1",
@@ -59,5 +59,5 @@
59
59
  "type": "individual",
60
60
  "url": "https://ohif.org/donate"
61
61
  },
62
- "gitHead": "bc07d0e3bfd08cffba904f3deb5ce18b3079255d"
62
+ "gitHead": "7d2a43e464e709b9da393ef58fd105395112a2d9"
63
63
  }
@@ -45,6 +45,8 @@ const disable = function (element: HTMLDivElement): void {
45
45
  );
46
46
  };
47
47
 
48
+ const perToolGroupManualTriggers = new Map();
49
+
48
50
  /**
49
51
  * When the image is rendered, check what tools can be rendered for this element.
50
52
  *
@@ -123,7 +125,11 @@ function _imageChangeEventListener(evt) {
123
125
  // where we are in the process of updating the volume conversion to a stack while
124
126
  // the data is still coming in. In such situations, we should trigger the render
125
127
  // to ensure that the segmentation actors are created, even if the data arrives late.
126
- triggerSegmentationRender(toolGroup.id);
128
+
129
+ if (!perToolGroupManualTriggers.has(toolGroup.id)) {
130
+ perToolGroupManualTriggers.set(toolGroup.id, true);
131
+ triggerSegmentationRender(toolGroup.id);
132
+ }
127
133
 
128
134
  // we should return here, since there is no segmentation actor to update
129
135
  // we will hit this function later on after the actor is created
@@ -306,6 +306,29 @@ function setSegmentSpecificRepresentationConfig(
306
306
  }
307
307
  }
308
308
 
309
+ function getToolGroupIdFromSegmentationRepresentationUID(
310
+ segmentationRepresentationUID: string
311
+ ): string {
312
+ const allToolGroupRepresentations = getAllSegmentationRepresentations() || [];
313
+
314
+ const toolGroupIds = Object.keys(allToolGroupRepresentations);
315
+
316
+ for (const toolGroupId of toolGroupIds) {
317
+ const toolGroupRepresentations =
318
+ getAllSegmentationRepresentations()[toolGroupId];
319
+
320
+ const foundRepresentation = toolGroupRepresentations.find(
321
+ (representation) =>
322
+ representation.segmentationRepresentationUID ===
323
+ segmentationRepresentationUID
324
+ );
325
+
326
+ if (foundRepresentation) {
327
+ return toolGroupId;
328
+ }
329
+ }
330
+ }
331
+
309
332
  /**
310
333
  * Add the given segmentation representation data to the given tool group state. It fires
311
334
  * SEGMENTATION_REPRESENTATION_MODIFIED event if not suppressed.
@@ -512,4 +535,5 @@ export {
512
535
  removeColorLUT,
513
536
  //
514
537
  findSegmentationRepresentationByUID,
538
+ getToolGroupIdFromSegmentationRepresentationUID,
515
539
  };
@@ -48,6 +48,8 @@ export default class ToolGroup implements IToolGroup {
48
48
  id: string;
49
49
  viewportsInfo = [];
50
50
  toolOptions = {};
51
+ currentActivePrimaryToolName: string | null = null;
52
+ prevActivePrimaryToolName: string | null = null;
51
53
  /**
52
54
  * Options used for restoring a tool
53
55
  */
@@ -407,6 +409,18 @@ export default class ToolGroup implements IToolGroup {
407
409
  }
408
410
  }
409
411
 
412
+ // if it is a primary tool binding, we should store it as the previous primary tool
413
+ // so that we can restore it when the tool is disabled if desired
414
+ if (this._hasMousePrimaryButtonBinding(toolBindingsOptions)) {
415
+ if (this.prevActivePrimaryToolName === null) {
416
+ this.prevActivePrimaryToolName = toolName;
417
+ } else {
418
+ this.prevActivePrimaryToolName = this.currentActivePrimaryToolName;
419
+ }
420
+
421
+ this.currentActivePrimaryToolName = toolName;
422
+ }
423
+
410
424
  if (typeof toolInstance.onSetToolActive === 'function') {
411
425
  toolInstance.onSetToolActive();
412
426
  }
@@ -736,6 +750,14 @@ export default class ToolGroup implements IToolGroup {
736
750
  return cloneDeep(_configuration);
737
751
  }
738
752
 
753
+ /**
754
+ * Gets the name of the previously active tool.
755
+ * @returns The name of the previously active tool.
756
+ */
757
+ public getPrevActivePrimaryToolName(): string {
758
+ return this.prevActivePrimaryToolName;
759
+ }
760
+
739
761
  /**
740
762
  *
741
763
  * @param newToolGroupId - Id of the new (clone) tool group
@@ -20,8 +20,11 @@ type VOISynchronizerOptions = {
20
20
  */
21
21
  export default function createVOISynchronizer(
22
22
  synchronizerName: string,
23
- options = { syncInvertState: true } as VOISynchronizerOptions
23
+ options: VOISynchronizerOptions
24
24
  ): Synchronizer {
25
+ // = { syncInvertState: true } if options is not provided or undefined or {}
26
+ options = Object.assign({ syncInvertState: true }, options);
27
+
25
28
  const VOISynchronizer = createSynchronizer(
26
29
  synchronizerName,
27
30
  Enums.Events.VOI_MODIFIED,
@@ -5,7 +5,9 @@ import type { Types } from '@cornerstonejs/core';
5
5
 
6
6
  import {
7
7
  addAnnotation,
8
+ getAllAnnotations,
8
9
  getAnnotations,
10
+ removeAnnotation,
9
11
  } from '../stateManagement/annotation/annotationState';
10
12
  import { isAnnotationLocked } from '../stateManagement/annotation/annotationLocking';
11
13
  import { isAnnotationVisible } from '../stateManagement/annotation/annotationVisibility';
@@ -186,6 +188,18 @@ class AdvancedMagnifyTool extends AnnotationTool {
186
188
  return annotation;
187
189
  };
188
190
 
191
+ onSetToolDisabled = () => {
192
+ // reset
193
+ this.magnifyViewportManager.dispose();
194
+ // remove the annotations from the state for that toolGroup
195
+ const annotations = getAllAnnotations();
196
+ annotations.forEach((annotation) => {
197
+ if (annotation.metadata.toolName === this.getToolName()) {
198
+ removeAnnotation(annotation.annotationUID);
199
+ }
200
+ });
201
+ };
202
+
189
203
  /**
190
204
  * It returns if the canvas point is near the provided annotation in the provided
191
205
  * element or not. A proximity is passed to the function to determine the
@@ -588,8 +602,7 @@ class AdvancedMagnifyTool extends AnnotationTool {
588
602
  radius,
589
603
  {
590
604
  color,
591
- lineDash,
592
- lineWidth,
605
+ lineWidth: 5,
593
606
  },
594
607
  dataId
595
608
  );
@@ -15,7 +15,7 @@ import {
15
15
  import { AdvancedMagnifyAnnotation } from '../types/ToolSpecificAnnotationTypes';
16
16
 
17
17
  // Defined the tool name internally instead of importing
18
- // AdvangedMagnifyTool due to cyclic dependency
18
+ // AdvancedMagnifyTool due to cyclic dependency
19
19
  const ADVANCED_MAGNIFY_TOOL_NAME = 'AdvancedMagnify';
20
20
 
21
21
  const PARALLEL_THRESHOLD = 1 - CONSTANTS.EPSILON;
@@ -344,9 +344,10 @@ class CrosshairsTool extends AnnotationTool {
344
344
  */
345
345
  computeToolCenter = (viewportsInfo): void => {
346
346
  if (!viewportsInfo.length || viewportsInfo.length === 1) {
347
- throw new Error(
347
+ console.warn(
348
348
  'For crosshairs to operate, at least two viewports must be given.'
349
349
  );
350
+ return;
350
351
  }
351
352
 
352
353
  // Todo: handle two same view viewport, or more than 3 viewports
@@ -46,7 +46,7 @@ class TrackballRotateTool extends BaseTool {
46
46
 
47
47
  if (this.cleanUp !== null) {
48
48
  // Clean up previous event listener
49
- element.removeEventListener('mouseup', this.cleanUp);
49
+ document.removeEventListener('mouseup', this.cleanUp);
50
50
  }
51
51
 
52
52
  this.cleanUp = () => {
@@ -54,7 +54,7 @@ class TrackballRotateTool extends BaseTool {
54
54
  viewport.render();
55
55
  };
56
56
 
57
- element.addEventListener('mouseup', this.cleanUp, { once: true });
57
+ document.addEventListener('mouseup', this.cleanUp, { once: true });
58
58
  return true;
59
59
  };
60
60
 
@@ -209,7 +209,8 @@ class BrushTool extends BaseTool {
209
209
 
210
210
  return {
211
211
  volumeId,
212
- referencedVolumeId: firstVolumeActorUID,
212
+ referencedVolumeId:
213
+ labelmapData.referencedVolumeId ?? firstVolumeActorUID,
213
214
  segmentsLocked,
214
215
  segmentationRepresentationUID,
215
216
  };
@@ -215,26 +215,6 @@ export default class BrushStrategy {
215
215
  return operationData.preview;
216
216
  }
217
217
 
218
- if (isVolumeSegmentation(operationData, viewport)) {
219
- const { referencedVolumeId, volumeId } =
220
- operationData as LabelmapToolOperationDataVolume;
221
-
222
- const segmentation = cache.getVolume(volumeId);
223
-
224
- if (referencedVolumeId) {
225
- const imageVolume = cache.getVolume(referencedVolumeId);
226
-
227
- if (
228
- !csUtils.isEqual(segmentation.dimensions, imageVolume.dimensions) ||
229
- !csUtils.isEqual(segmentation.direction, imageVolume.direction)
230
- ) {
231
- throw new Error(
232
- 'Only source data the same dimensions/size/orientation as the segmentation currently supported.'
233
- );
234
- }
235
- }
236
- }
237
-
238
218
  const {
239
219
  imageVoxelManager,
240
220
  segmentationVoxelManager,
@@ -47,6 +47,10 @@ function playClip(
47
47
  );
48
48
  }
49
49
 
50
+ if (!playClipOptions) {
51
+ playClipOptions = {};
52
+ }
53
+
50
54
  // 4D Cine is enabled by default
51
55
  playClipOptions.dynamicCineEnabled =
52
56
  playClipOptions.dynamicCineEnabled ?? true;
@@ -140,7 +140,7 @@ const getCalibratedLengthUnitsAndScale = (image, handles) => {
140
140
  (region) =>
141
141
  SUPPORTED_REGION_DATA_TYPES.includes(region.regionDataType) &&
142
142
  SUPPORTED_LENGTH_VARIANT.includes(
143
- `${region.physicalUnitXDirection},${region.physicalUnitYDirection}`
143
+ `${region.physicalUnitsXDirection},${region.physicalUnitsYDirection}`
144
144
  )
145
145
  );
146
146
 
@@ -176,10 +176,15 @@ const getCalibratedLengthUnitsAndScale = (image, handles) => {
176
176
  }
177
177
 
178
178
  // everything except REGION/Uncalibratted
179
- const types = [CalibrationTypes.ERMF, CalibrationTypes.USER, CalibrationTypes.ERROR, CalibrationTypes.PROJECTION];
179
+ const types = [
180
+ CalibrationTypes.ERMF,
181
+ CalibrationTypes.USER,
182
+ CalibrationTypes.ERROR,
183
+ CalibrationTypes.PROJECTION,
184
+ ];
180
185
 
181
186
  if (types.includes(calibration?.type)) {
182
- calibrationType = calibration.type;
187
+ calibrationType = calibration.type;
183
188
  }
184
189
 
185
190
  return {
@@ -211,7 +216,7 @@ const getCalibratedProbeUnitsAndValue = (image, handles) => {
211
216
  (region) =>
212
217
  SUPPORTED_REGION_DATA_TYPES.includes(region.regionDataType) &&
213
218
  SUPPORTED_PROBE_VARIANT.includes(
214
- `${region.physicalUnitXDirection},${region.physicalUnitYDirection}`
219
+ `${region.physicalUnitsXDirection},${region.physicalUnitsYDirection}`
215
220
  )
216
221
  );
217
222
 
@@ -247,8 +252,8 @@ const getCalibratedProbeUnitsAndValue = (image, handles) => {
247
252
  calibrationType = 'US Region';
248
253
  values = [xValue, yValue];
249
254
  units = [
250
- UNIT_MAPPING[region.physicalUnitXDirection],
251
- UNIT_MAPPING[region.physicalUnitYDirection],
255
+ UNIT_MAPPING[region.physicalUnitsXDirection],
256
+ UNIT_MAPPING[region.physicalUnitsYDirection],
252
257
  ];
253
258
  }
254
259
 
@@ -13,6 +13,7 @@ export type ThresholdOptions = {
13
13
  numSlicesToProject?: number; // number of slices to project before and after current slice
14
14
  overwrite: boolean;
15
15
  overlapType?: number; // type of the voxel overlap
16
+ segmentIndex?: number; // segment index to threshold
16
17
  };
17
18
 
18
19
  export type AnnotationForThresholding = {
@@ -69,6 +70,8 @@ function rectangleROIThresholdVolumeByRange(
69
70
  { ...options, boundsIJK }
70
71
  );
71
72
 
73
+ outputSegmentationVolume.modified();
74
+
72
75
  return outputSegmentationVolume;
73
76
  }
74
77
 
@@ -12,6 +12,7 @@ export type ThresholdRangeOptions = {
12
12
  overwrite: boolean;
13
13
  boundsIJK: BoundsIJK;
14
14
  overlapType?: number;
15
+ segmentIndex?: number;
15
16
  };
16
17
 
17
18
  /**
@@ -136,9 +137,8 @@ function thresholdVolumeByRange(
136
137
  }
137
138
  }
138
139
 
139
- // Todo: make the segmentIndex a parameter
140
140
  if (insert) {
141
- scalarData[index] = 1;
141
+ scalarData[index] = options.segmentIndex || 1;
142
142
  }
143
143
  };
144
144
 
@@ -13,7 +13,6 @@ import { pointInShapeCallback } from '../utilities';
13
13
  import {
14
14
  containsPoint,
15
15
  getAABB,
16
- isPointInsidePolyline3D,
17
16
  projectTo2D,
18
17
  } from '../utilities/math/polyline';
19
18
  import { isPlaneIntersectingAABB } from '../utilities/planar';