@cornerstonejs/tools 2.0.0-beta.23 → 2.0.0-beta.25

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 (70) hide show
  1. package/dist/esm/enums/SegmentationRepresentations.d.ts +3 -3
  2. package/dist/esm/enums/SegmentationRepresentations.js +3 -3
  3. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseMove.js +4 -0
  4. package/dist/esm/eventListeners/segmentation/labelmap/onLabelmapSegmentationDataModified.js +27 -23
  5. package/dist/esm/eventListeners/segmentation/segmentationDataModifiedEventListener.js +2 -2
  6. package/dist/esm/stateManagement/index.d.ts +3 -2
  7. package/dist/esm/stateManagement/index.js +2 -2
  8. package/dist/esm/stateManagement/segmentation/SegmentationRenderingEngine.d.ts +1 -2
  9. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.d.ts +9 -6
  10. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.js +72 -24
  11. package/dist/esm/stateManagement/segmentation/addSegmentationRepresentations.d.ts +8 -3
  12. package/dist/esm/stateManagement/segmentation/addSegmentationRepresentations.js +14 -4
  13. package/dist/esm/stateManagement/segmentation/config/segmentationConfig.d.ts +8 -7
  14. package/dist/esm/stateManagement/segmentation/convertVolumeToStackSegmentation.js +1 -1
  15. package/dist/esm/stateManagement/segmentation/getGlobalConfig.d.ts +2 -2
  16. package/dist/esm/stateManagement/segmentation/getPerSegmentConfig.d.ts +2 -2
  17. package/dist/esm/stateManagement/segmentation/getStackSegmentationImageIdsForViewport.d.ts +1 -0
  18. package/dist/esm/stateManagement/segmentation/getStackSegmentationImageIdsForViewport.js +5 -0
  19. package/dist/esm/stateManagement/segmentation/helpers/updateStackSegmentationState.js +5 -5
  20. package/dist/esm/stateManagement/segmentation/index.d.ts +2 -2
  21. package/dist/esm/stateManagement/segmentation/index.js +2 -2
  22. package/dist/esm/stateManagement/segmentation/internalAddSegmentationRepresentation.d.ts +3 -0
  23. package/dist/esm/stateManagement/segmentation/{addSegmentationRepresentation.js → internalAddSegmentationRepresentation.js} +4 -3
  24. package/dist/esm/stateManagement/segmentation/polySeg/Contour/contourComputationStrategies.js +4 -4
  25. package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/labelmapComputationStrategies.js +4 -4
  26. package/dist/esm/stateManagement/segmentation/polySeg/Surface/createAndCacheSurfacesFromRaw.js +1 -1
  27. package/dist/esm/stateManagement/segmentation/polySeg/Surface/surfaceComputationStrategies.js +6 -6
  28. package/dist/esm/stateManagement/segmentation/polySeg/Surface/updateSurfaceData.js +2 -2
  29. package/dist/esm/stateManagement/segmentation/segmentationState.d.ts +2 -2
  30. package/dist/esm/stateManagement/segmentation/segmentationState.js +2 -2
  31. package/dist/esm/stateManagement/segmentation/setGlobalConfig.d.ts +2 -2
  32. package/dist/esm/stateManagement/segmentation/setPerSegmentConfig.d.ts +2 -2
  33. package/dist/esm/store/ToolGroupManager/ToolGroup.d.ts +1 -1
  34. package/dist/esm/tools/AdvancedMagnifyTool.js +2 -2
  35. package/dist/esm/tools/ScaleOverlayTool.js +23 -20
  36. package/dist/esm/tools/annotation/LivewireContourTool.d.ts +5 -0
  37. package/dist/esm/tools/annotation/LivewireContourTool.js +156 -8
  38. package/dist/esm/tools/base/BaseTool.d.ts +1 -13
  39. package/dist/esm/tools/base/ContourSegmentationBaseTool.js +1 -1
  40. package/dist/esm/tools/displayTools/Contour/contourHandler/handleContourSegmentation.js +4 -4
  41. package/dist/esm/tools/displayTools/Contour/contourHandler/utils.js +1 -1
  42. package/dist/esm/tools/displayTools/Contour/removeContourFromElement.js +1 -1
  43. package/dist/esm/tools/segmentation/BrushTool.d.ts +38 -0
  44. package/dist/esm/tools/segmentation/BrushTool.js +40 -7
  45. package/dist/esm/tools/segmentation/CircleROIStartEndThresholdTool.js +23 -15
  46. package/dist/esm/tools/segmentation/RectangleROIStartEndThresholdTool.js +6 -0
  47. package/dist/esm/tools/segmentation/strategies/BrushStrategy.js +10 -5
  48. package/dist/esm/tools/segmentation/strategies/compositions/islandRemoval.js +1 -1
  49. package/dist/esm/tools/segmentation/strategies/compositions/preview.js +2 -2
  50. package/dist/esm/tools/segmentation/strategies/compositions/setValue.js +6 -4
  51. package/dist/esm/tools/segmentation/strategies/fillSphere.js +5 -14
  52. package/dist/esm/types/EventTypes.d.ts +1 -2
  53. package/dist/esm/types/IBaseTool.d.ts +2 -0
  54. package/dist/esm/types/IBaseTool.js +1 -0
  55. package/dist/esm/types/IToolGroup.d.ts +3 -63
  56. package/dist/esm/types/LabelmapToolOperationData.d.ts +5 -0
  57. package/dist/esm/types/SegmentationStateTypes.d.ts +22 -22
  58. package/dist/esm/types/index.d.ts +3 -2
  59. package/dist/esm/utilities/contourSegmentation/addContourSegmentationAnnotation.js +3 -3
  60. package/dist/esm/utilities/contourSegmentation/removeContourSegmentationAnnotation.js +1 -1
  61. package/dist/esm/utilities/contours/generateContourSetsFromLabelmap.js +7 -7
  62. package/dist/esm/utilities/segmentation/getHoveredContourSegmentationAnnotation.js +1 -1
  63. package/dist/esm/utilities/segmentation/getSegmentIndexAtLabelmapBorder.js +8 -4
  64. package/dist/esm/utilities/segmentation/getSegmentIndexAtWorldPoint.js +2 -2
  65. package/dist/esm/utilities/segmentation/getUniqueSegmentIndices.js +2 -2
  66. package/dist/esm/utilities/segmentation/isLineInSegment.js +3 -3
  67. package/dist/umd/index.js +1 -1
  68. package/dist/umd/index.js.map +1 -1
  69. package/package.json +16 -7
  70. package/dist/esm/stateManagement/segmentation/addSegmentationRepresentation.d.ts +0 -3
@@ -10,10 +10,11 @@ import { drawCircle as drawCircleSvg } from '../../drawingSvg';
10
10
  import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCursor';
11
11
  import triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportIds';
12
12
  import { isVolumeSegmentation } from './strategies/utils/stackVolumeCheck';
13
- import { getActiveSegmentationRepresentation, getCurrentLabelmapImageIdForViewport, getSegmentation, } from '../../stateManagement/segmentation/segmentationState';
13
+ import { getActiveSegmentationRepresentation, getCurrentLabelmapImageIdForViewport, getSegmentation, getStackSegmentationImageIdsForViewport, } from '../../stateManagement/segmentation/segmentationState';
14
14
  import { getLockedSegmentIndices } from '../../stateManagement/segmentation/segmentLocking';
15
15
  import { getActiveSegmentIndex } from '../../stateManagement/segmentation/getActiveSegmentIndex';
16
16
  import { getSegmentIndexColor } from '../../stateManagement/segmentation/config/segmentationColor';
17
+ import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
17
18
  class BrushTool extends BaseTool {
18
19
  constructor(toolProps = {}, defaultToolProps = {
19
20
  supportedInteractionTypes: ['Mouse', 'Touch'],
@@ -141,7 +142,6 @@ class BrushTool extends BaseTool {
141
142
  const eventData = evt.detail;
142
143
  const { element, currentPoints } = eventData;
143
144
  const enabledElement = getEnabledElement(element);
144
- const { renderingEngine } = enabledElement;
145
145
  this.updateCursor(evt);
146
146
  const { viewportIdsToRender } = this._hoverData;
147
147
  triggerAnnotationRenderForViewportUIDs(viewportIdsToRender);
@@ -235,12 +235,45 @@ class BrushTool extends BaseTool {
235
235
  return;
236
236
  }
237
237
  if (this.configuration.activeStrategy.includes('SPHERE')) {
238
- throw new Error('Sphere manipulation is not supported for stacks of image segmentations yet');
238
+ const referencedImageIds = viewport.getImageIds();
239
+ const isValidVolumeForSphere = csUtils.isValidVolume(referencedImageIds);
240
+ if (!isValidVolumeForSphere) {
241
+ throw new Error('Volume is not reconstructable for sphere manipulation');
242
+ }
243
+ const labelmapImageIds = getStackSegmentationImageIdsForViewport(viewport.id, segmentationId);
244
+ if (!labelmapImageIds || labelmapImageIds.length === 1) {
245
+ return {
246
+ imageId: segmentationImageId,
247
+ segmentsLocked,
248
+ };
249
+ }
250
+ const tempVolumeId = 'tempVolumeId';
251
+ const { dimensions, direction, origin, spacing, numberOfComponents, imageIds: sortedLabelmapImageIds, } = csUtils.generateVolumePropsFromImageIds(labelmapImageIds, tempVolumeId);
252
+ const newVoxelManager = csUtils.VoxelManager.createImageVolumeVoxelManager({
253
+ dimensions,
254
+ imageIds: sortedLabelmapImageIds,
255
+ numberOfComponents,
256
+ });
257
+ const newImageData = vtkImageData.newInstance();
258
+ newImageData.setDimensions(dimensions);
259
+ newImageData.setSpacing(spacing);
260
+ newImageData.setDirection(direction);
261
+ newImageData.setOrigin(origin);
262
+ return {
263
+ imageId: segmentationImageId,
264
+ segmentsLocked,
265
+ override: {
266
+ voxelManager: newVoxelManager,
267
+ imageData: newImageData,
268
+ },
269
+ };
270
+ }
271
+ else {
272
+ return {
273
+ imageId: segmentationImageId,
274
+ segmentsLocked,
275
+ };
239
276
  }
240
- return {
241
- imageId: segmentationImageId,
242
- segmentsLocked,
243
- };
244
277
  }
245
278
  }
246
279
  createHoverData(element, centerCanvas) {
@@ -171,30 +171,35 @@ class CircleROIStartEndThresholdTool extends CircleROITool {
171
171
  const canvasCorners = getCanvasCircleCorners(canvasCoordinates);
172
172
  const focalPoint = viewport.getCamera().focalPoint;
173
173
  const viewplaneNormal = viewport.getCamera().viewPlaneNormal;
174
- let startCoord = startCoordinate;
175
- let endCoord = endCoordinate;
174
+ let tempStartCoordinate = startCoordinate;
175
+ let tempEndCoordinate = endCoordinate;
176
176
  if (Array.isArray(startCoordinate)) {
177
- startCoord = this._getCoordinateForViewplaneNormal(startCoord, viewplaneNormal);
177
+ tempStartCoordinate = this._getCoordinateForViewplaneNormal(tempStartCoordinate, viewplaneNormal);
178
+ data.startCoordinate = tempStartCoordinate;
178
179
  }
179
180
  if (Array.isArray(endCoordinate)) {
180
- endCoord = this._getCoordinateForViewplaneNormal(endCoord, viewplaneNormal);
181
+ tempEndCoordinate = this._getCoordinateForViewplaneNormal(tempEndCoordinate, viewplaneNormal);
182
+ data.endCoordinate = tempEndCoordinate;
181
183
  }
182
- const roundedStartCoord = coreUtils.roundToPrecision(startCoord);
183
- const roundedEndCoord = coreUtils.roundToPrecision(endCoord);
184
- const coord = this._getCoordinateForViewplaneNormal(focalPoint, viewplaneNormal);
185
- const roundedCoord = coreUtils.roundToPrecision(coord);
186
- if (roundedCoord < Math.min(roundedStartCoord, roundedEndCoord) ||
187
- roundedCoord > Math.max(roundedStartCoord, roundedEndCoord)) {
184
+ const roundedStartCoordinate = coreUtils.roundToPrecision(data.startCoordinate);
185
+ const roundedEndCoordinate = coreUtils.roundToPrecision(data.endCoordinate);
186
+ const cameraCoordinate = this._getCoordinateForViewplaneNormal(focalPoint, viewplaneNormal);
187
+ const roundedCameraCoordinate = coreUtils.roundToPrecision(cameraCoordinate);
188
+ if (roundedCameraCoordinate <
189
+ Math.min(roundedStartCoordinate, roundedEndCoordinate) ||
190
+ roundedCameraCoordinate >
191
+ Math.max(roundedStartCoordinate, roundedEndCoordinate)) {
188
192
  continue;
189
193
  }
190
- if (annotation.invalidated) {
191
- this._throttledCalculateCachedStats(annotation, enabledElement);
192
- }
193
- const middleCoord = coreUtils.roundToPrecision((startCoord + endCoord) / 2);
194
+ const middleCoordinate = coreUtils.roundToPrecision((data.startCoordinate + data.endCoordinate) / 2);
194
195
  let isMiddleSlice = false;
195
- if (roundedCoord === middleCoord) {
196
+ if (roundedCameraCoordinate === middleCoordinate) {
196
197
  isMiddleSlice = true;
197
198
  }
199
+ data.handles.points[0][this._getIndexOfCoordinatesForViewplaneNormal(viewplaneNormal)] = middleCoordinate;
200
+ if (annotation.invalidated) {
201
+ this._throttledCalculateCachedStats(annotation, enabledElement);
202
+ }
198
203
  if (!viewport.getRenderingEngine()) {
199
204
  console.warn('Rendering Engine has been destroyed');
200
205
  return renderStatus;
@@ -420,6 +425,9 @@ class CircleROIStartEndThresholdTool extends CircleROITool {
420
425
  const targetId = this.getTargetId(viewport);
421
426
  const imageVolume = cache.getVolume(targetId.split(/volumeId:|\?/)[1]);
422
427
  this._computeProjectionPoints(annotation, imageVolume);
428
+ if (this.configuration.calculatePointsInsideVolume) {
429
+ this._computePointsInsideVolume(annotation, imageVolume, targetId, enabledElement);
430
+ }
423
431
  annotation.invalidated = false;
424
432
  triggerAnnotationModified(annotation, viewport.element);
425
433
  return cachedStats;
@@ -172,9 +172,12 @@ class RectangleROIStartEndThresholdTool extends RectangleROITool {
172
172
  let endCoord = endCoordinate;
173
173
  if (Array.isArray(startCoordinate)) {
174
174
  startCoord = this._getCoordinateForViewplaneNormal(startCoord, viewplaneNormal);
175
+ data.startCoordinate = startCoord;
176
+ data.handles.points[0][this._getIndexOfCoordinatesForViewplaneNormal(viewplaneNormal)] = startCoord;
175
177
  }
176
178
  if (Array.isArray(endCoordinate)) {
177
179
  endCoord = this._getCoordinateForViewplaneNormal(endCoord, viewplaneNormal);
180
+ data.endCoordinate = endCoord;
178
181
  }
179
182
  const roundedStartCoord = csUtils.roundToPrecision(startCoord);
180
183
  const roundedEndCoord = csUtils.roundToPrecision(endCoord);
@@ -378,6 +381,9 @@ class RectangleROIStartEndThresholdTool extends RectangleROITool {
378
381
  const targetId = this.getTargetId(viewport);
379
382
  const imageVolume = cache.getVolume(targetId.split(/volumeId:|\?/)[1]);
380
383
  this._computeProjectionPoints(annotation, imageVolume);
384
+ if (this.configuration.calculatePointsInsideVolume) {
385
+ this._computePointsInsideVolume(annotation, targetId, imageVolume, enabledElement);
386
+ }
381
387
  annotation.invalidated = false;
382
388
  triggerAnnotationModified(annotation, viewport.element);
383
389
  return cachedStats;
@@ -37,7 +37,8 @@ export default class BrushStrategy {
37
37
  }
38
38
  this._fill.forEach((func) => func(initializedData));
39
39
  const { segmentationVoxelManager, previewVoxelManager, previewSegmentIndex, } = initializedData;
40
- triggerSegmentationDataModified(initializedData.segmentationId, segmentationVoxelManager.getArrayOfSlices());
40
+ triggerSegmentationDataModified(initializedData.segmentationId, segmentationVoxelManager.getArrayOfModifiedSlices());
41
+ segmentationVoxelManager.resetModifiedSlices();
41
42
  if (!previewSegmentIndex || !previewVoxelManager.modifiedSlices.size) {
42
43
  return null;
43
44
  }
@@ -69,7 +70,9 @@ export default class BrushStrategy {
69
70
  BrushStrategy.childFunctions[key](this, result[key]);
70
71
  }
71
72
  });
72
- this.strategyFunction = (enabledElement, operationData) => this.fill(enabledElement, operationData);
73
+ this.strategyFunction = (enabledElement, operationData) => {
74
+ return this.fill(enabledElement, operationData);
75
+ };
73
76
  for (const key of Object.keys(BrushStrategy.childFunctions)) {
74
77
  this.strategyFunction[key] = this[key];
75
78
  }
@@ -82,9 +85,11 @@ export default class BrushStrategy {
82
85
  return operationData.preview;
83
86
  }
84
87
  const { imageVoxelManager, segmentationVoxelManager, segmentationImageData, } = data;
88
+ const segmentationVoxelManagerToUse = operationData.override?.voxelManager || segmentationVoxelManager;
89
+ const segmentationImageDataToUse = operationData.override?.imageData || segmentationImageData;
85
90
  const previewVoxelManager = operationData.preview?.previewVoxelManager ||
86
91
  VoxelManager.createHistoryVoxelManager({
87
- sourceVoxelManager: segmentationVoxelManager,
92
+ sourceVoxelManager: segmentationVoxelManagerToUse,
88
93
  });
89
94
  const previewEnabled = !!operationData.previewColors;
90
95
  const previewSegmentIndex = previewEnabled ? 255 : undefined;
@@ -94,8 +99,8 @@ export default class BrushStrategy {
94
99
  ...operationData,
95
100
  enabledElement,
96
101
  imageVoxelManager,
97
- segmentationVoxelManager,
98
- segmentationImageData,
102
+ segmentationVoxelManager: segmentationVoxelManagerToUse,
103
+ segmentationImageData: segmentationImageDataToUse,
99
104
  previewVoxelManager,
100
105
  viewport,
101
106
  centerWorld: null,
@@ -118,6 +118,6 @@ export default {
118
118
  }
119
119
  }
120
120
  }
121
- triggerSegmentationDataModified(operationData.segmentationId, previewVoxelManager.getArrayOfSlices());
121
+ triggerSegmentationDataModified(operationData.segmentationId, previewVoxelManager.getArrayOfModifiedSlices());
122
122
  },
123
123
  };
@@ -66,7 +66,7 @@ export default {
66
66
  }
67
67
  };
68
68
  tracking.forEach(callback, {});
69
- triggerSegmentationDataModified(operationData.segmentationId, tracking.getArrayOfSlices());
69
+ triggerSegmentationDataModified(operationData.segmentationId, tracking.getArrayOfModifiedSlices());
70
70
  tracking.clear();
71
71
  },
72
72
  [StrategyCallbacks.RejectPreview]: (operationData) => {
@@ -78,7 +78,7 @@ export default {
78
78
  segmentationVoxelManager.setAtIndex(index, value);
79
79
  };
80
80
  previewVoxelManager.forEach(callback);
81
- triggerSegmentationDataModified(operationData.segmentationId, previewVoxelManager.getArrayOfSlices());
81
+ triggerSegmentationDataModified(operationData.segmentationId, previewVoxelManager.getArrayOfModifiedSlices());
82
82
  previewVoxelManager.clear();
83
83
  },
84
84
  };
@@ -1,12 +1,14 @@
1
1
  import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
2
+ import { triggerEvent, eventTarget } from '@cornerstonejs/core';
2
3
  export default {
3
4
  [StrategyCallbacks.INTERNAL_setValue]: (operationData, { value, index }) => {
4
- const { segmentsLocked, segmentIndex, previewVoxelManager, previewSegmentIndex, segmentationVoxelManager, } = operationData;
5
+ const { segmentsLocked, segmentIndex, previewVoxelManager, previewSegmentIndex, segmentationVoxelManager, segmentationId, } = operationData;
5
6
  const existingValue = segmentationVoxelManager.getAtIndex(index);
7
+ let changed = false;
6
8
  if (segmentIndex === null) {
7
9
  const oldValue = previewVoxelManager.getAtIndex(index);
8
10
  if (oldValue !== undefined) {
9
- previewVoxelManager.setAtIndex(index, oldValue);
11
+ changed = previewVoxelManager.setAtIndex(index, oldValue);
10
12
  }
11
13
  return;
12
14
  }
@@ -15,13 +17,13 @@ export default {
15
17
  }
16
18
  if (existingValue === previewSegmentIndex) {
17
19
  if (previewVoxelManager.getAtIndex(index) === undefined) {
18
- segmentationVoxelManager.setAtIndex(index, segmentIndex);
20
+ changed = segmentationVoxelManager.setAtIndex(index, segmentIndex);
19
21
  }
20
22
  else {
21
23
  return;
22
24
  }
23
25
  }
24
26
  const useSegmentIndex = previewSegmentIndex ?? segmentIndex;
25
- previewVoxelManager.setAtIndex(index, useSegmentIndex);
27
+ changed = previewVoxelManager.setAtIndex(index, useSegmentIndex);
26
28
  },
27
29
  };
@@ -21,20 +21,11 @@ const sphereComposition = {
21
21
  operationData.centerIJK = transformWorldToIndex(segmentationImageData, center);
22
22
  const { boundsIJK: newBoundsIJK, topLeftWorld, bottomRightWorld, } = getSphereBoundsInfo(points.slice(0, 2), segmentationImageData, viewport);
23
23
  segmentationVoxelManager.boundsIJK = newBoundsIJK;
24
- if (imageVoxelManager) {
25
- imageVoxelManager.isInObject = createEllipseInPoint({
26
- topLeftWorld,
27
- bottomRightWorld,
28
- center,
29
- });
30
- }
31
- else {
32
- segmentationVoxelManager.isInObject = createEllipseInPoint({
33
- topLeftWorld,
34
- bottomRightWorld,
35
- center,
36
- });
37
- }
24
+ segmentationVoxelManager.isInObject = createEllipseInPoint({
25
+ topLeftWorld,
26
+ bottomRightWorld,
27
+ center,
28
+ });
38
29
  },
39
30
  };
40
31
  const SPHERE_STRATEGY = new BrushStrategy('Sphere', compositions.regionFill, compositions.setValue, sphereComposition, compositions.determineSegmentIndex, compositions.preview);
@@ -5,9 +5,8 @@ import type ITouchPoints from './ITouchPoints';
5
5
  import type IDistance from './IDistance';
6
6
  import type { SetToolBindingsType } from './ISetToolModeOptions';
7
7
  import type { Swipe } from '../enums/Touch';
8
- import type { ToolModes } from '../enums';
8
+ import type { ToolModes, ChangeTypes } from '../enums';
9
9
  import type { InterpolationROIAnnotation } from './ToolSpecificAnnotationTypes';
10
- import type { ChangeTypes } from '../enums';
11
10
  type NormalizedInteractionEventDetail = {
12
11
  eventName: string;
13
12
  renderingEngineId: string;
@@ -0,0 +1,2 @@
1
+ import type BaseTool from '../tools/base/BaseTool';
2
+ export type IBaseTool = BaseTool;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,63 +1,3 @@
1
- import type { Types } from '@cornerstonejs/core';
2
- import type { IToolBinding, SetToolBindingsType, ToolOptionsType } from './ISetToolModeOptions';
3
- import type { MouseBindings } from '../enums';
4
- import type { ToolConfiguration } from '../types';
5
- export default interface IToolGroup {
6
- _toolInstances: Record<string, unknown>;
7
- id: string;
8
- viewportsInfo: Array<Types.IViewportId>;
9
- toolOptions: Record<string, unknown>;
10
- getViewportIds: () => string[];
11
- getViewportsInfo: () => Array<Types.IViewportId>;
12
- getToolInstance: {
13
- (toolName: string): unknown;
14
- };
15
- hasTool(toolName: string): boolean;
16
- addTool: {
17
- (toolName: string, toolConfiguration?: ToolConfiguration): void;
18
- };
19
- addToolInstance: {
20
- (toolName: string, parentClassName: string, configuration?: unknown): void;
21
- };
22
- addViewport: {
23
- (viewportId: string, renderingEngineId?: string): void;
24
- };
25
- removeViewports: {
26
- (renderingEngineId: string, viewportId?: string): void;
27
- };
28
- setToolActive: {
29
- (toolName: string, toolBindingsOption?: SetToolBindingsType): void;
30
- };
31
- setToolPassive: {
32
- (toolName: string, options?: {
33
- removeAllBindings?: boolean | IToolBinding[];
34
- }): void;
35
- };
36
- setToolEnabled: {
37
- (toolName: string): void;
38
- };
39
- setToolDisabled: {
40
- (toolName: string): void;
41
- };
42
- getToolOptions: {
43
- (toolName: string): ToolOptionsType;
44
- };
45
- getActivePrimaryMouseButtonTool: {
46
- (): undefined | string;
47
- };
48
- setViewportsCursorByToolName: {
49
- (toolName: string, strategyName?: string): void;
50
- };
51
- setToolConfiguration: {
52
- (toolName: string, configuration: ToolConfiguration, overwrite?: boolean): void;
53
- };
54
- getToolConfiguration: {
55
- (toolName: string, configurationPath?: string): unknown;
56
- };
57
- getDefaultMousePrimary: {
58
- (): MouseBindings;
59
- };
60
- clone: {
61
- (newToolGroupId: string, fnToolFilter: (toolName: string) => boolean): IToolGroup;
62
- };
63
- }
1
+ import type ToolGroup from '../store/ToolGroupManager/ToolGroup';
2
+ type IToolGroup = ToolGroup;
3
+ export type { IToolGroup as default };
@@ -1,5 +1,6 @@
1
1
  import type { Types } from '@cornerstonejs/core';
2
2
  import type { LabelmapSegmentationDataStack, LabelmapSegmentationDataVolume } from './LabelmapTypes';
3
+ import type vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
3
4
  type LabelmapToolOperationData = {
4
5
  segmentationId: string;
5
6
  segmentIndex: number;
@@ -11,6 +12,10 @@ type LabelmapToolOperationData = {
11
12
  segmentationRepresentationUID: string;
12
13
  points: Types.Point3[];
13
14
  voxelManager: any;
15
+ override: {
16
+ voxelManager: Types.IVoxelManager<number>;
17
+ imageData: vtkImageData;
18
+ };
14
19
  preview: any;
15
20
  toolGroupId: string;
16
21
  };
@@ -3,24 +3,23 @@ import type * as Enums from '../enums';
3
3
  import type { ContourConfig, ContourRenderingConfig, ContourSegmentationData } from './ContourTypes';
4
4
  import type { LabelmapConfig, LabelmapRenderingConfig, LabelmapSegmentationData } from './LabelmapTypes';
5
5
  import type { SurfaceSegmentationData, SurfaceRenderingConfig } from './SurfaceTypes';
6
- export type SegmentRepresentationConfig = {
7
- [key: number | string]: RepresentationConfig;
8
- };
9
6
  export type SurfaceConfig = {};
10
- export type RepresentationConfig = {
11
- LABELMAP?: LabelmapConfig;
12
- CONTOUR?: ContourConfig;
13
- SURFACE?: SurfaceConfig;
7
+ export type RepresentationsConfig = {
8
+ [Enums.SegmentationRepresentations.Labelmap]?: LabelmapConfig;
9
+ [Enums.SegmentationRepresentations.Contour]?: ContourConfig;
10
+ [Enums.SegmentationRepresentations.Surface]?: SurfaceConfig;
14
11
  };
15
- export type SegmentationRepresentationConfig = {
12
+ export type RepresentationConfig = LabelmapConfig | ContourConfig | SurfaceConfig;
13
+ export type GlobalConfig = {
16
14
  renderInactiveRepresentations: boolean;
17
- representations: RepresentationConfig;
15
+ representations: RepresentationsConfig;
18
16
  };
19
- export type SegmentationRepresentationData = {
20
- LABELMAP?: LabelmapSegmentationData;
21
- CONTOUR?: ContourSegmentationData;
22
- SURFACE?: SurfaceSegmentationData;
17
+ export type RepresentationsData = {
18
+ [Enums.SegmentationRepresentations.Labelmap]?: LabelmapSegmentationData;
19
+ [Enums.SegmentationRepresentations.Contour]?: ContourSegmentationData;
20
+ [Enums.SegmentationRepresentations.Surface]?: SurfaceSegmentationData;
23
21
  };
22
+ export type RepresentationData = LabelmapSegmentationData | ContourSegmentationData | SurfaceSegmentationData;
24
23
  export type Segmentation = {
25
24
  segmentationId: string;
26
25
  type: Enums.SegmentationRepresentations;
@@ -33,7 +32,7 @@ export type Segmentation = {
33
32
  segmentLabels: {
34
33
  [key: string]: string;
35
34
  };
36
- representationData: SegmentationRepresentationData;
35
+ representationData: RepresentationsData;
37
36
  };
38
37
  export type BaseSegmentationRepresentation = {
39
38
  segmentationRepresentationUID: string;
@@ -46,7 +45,7 @@ export type BaseSegmentationRepresentation = {
46
45
  };
47
46
  config: {
48
47
  allSegments?: RepresentationConfig;
49
- perSegment?: SegmentRepresentationConfig;
48
+ perSegment?: RepresentationConfig;
50
49
  };
51
50
  };
52
51
  export type LabelmapRepresentation = BaseSegmentationRepresentation & {
@@ -62,7 +61,7 @@ export type SegmentationRepresentation = LabelmapRepresentation | ContourReprese
62
61
  export type SegmentationState = {
63
62
  colorLUT: Types.ColorLUT[];
64
63
  segmentations: Segmentation[];
65
- globalConfig: SegmentationRepresentationConfig;
64
+ globalConfig: GlobalConfig;
66
65
  representations: {
67
66
  [key: string]: SegmentationRepresentation;
68
67
  };
@@ -80,14 +79,9 @@ export type SegmentationPublicInput = {
80
79
  segmentationId: string;
81
80
  representation: {
82
81
  type: Enums.SegmentationRepresentations;
83
- data?: LabelmapSegmentationData | ContourSegmentationData | SurfaceSegmentationData;
82
+ data?: RepresentationData;
84
83
  };
85
84
  };
86
- export type RepresentationPublicInput = {
87
- segmentationId: string;
88
- type: Enums.SegmentationRepresentations;
89
- options?: RepresentationPublicInputOptions;
90
- };
91
85
  export type RepresentationPublicInputOptions = {
92
86
  segmentationRepresentationUID?: string;
93
87
  colorLUTOrIndex?: Types.ColorLUT | number;
@@ -96,3 +90,9 @@ export type RepresentationPublicInputOptions = {
96
90
  options?: unknown;
97
91
  };
98
92
  };
93
+ export type RepresentationPublicInput = {
94
+ segmentationId: string;
95
+ type: Enums.SegmentationRepresentations;
96
+ options?: RepresentationPublicInputOptions;
97
+ config?: RepresentationConfig;
98
+ };
@@ -22,7 +22,7 @@ import type ScrollOptions from './ScrollOptions';
22
22
  import type BoundsIJK from './BoundsIJK';
23
23
  import type SVGDrawingHelper from './SVGDrawingHelper';
24
24
  import type * as CINETypes from './CINETypes';
25
- import type { RepresentationConfig, SegmentationRepresentationConfig, SegmentationRepresentationData, Segmentation, SegmentationState, RepresentationPublicInput } from './SegmentationStateTypes';
25
+ import type { RepresentationConfig, RepresentationData, RepresentationsData, GlobalConfig, Segmentation, SegmentationState, RepresentationPublicInput } from './SegmentationStateTypes';
26
26
  import type { ISculptToolShape } from './ISculptToolShape';
27
27
  import type ISynchronizerEventHandler from './ISynchronizerEventHandler';
28
28
  import type { FloodFillGetter, FloodFillOptions, FloodFillResult } from './FloodFillTypes';
@@ -46,4 +46,5 @@ import type { SplineLineSegment } from './SplineLineSegment';
46
46
  import type { SplineProps } from './SplineProps';
47
47
  import type { BidirectionalData } from '../utilities/segmentation/createBidirectionalToolData';
48
48
  import type { PolySegConversionOptions } from './PolySeg';
49
- export type { Annotation, Annotations, ContourAnnotationData, ContourAnnotation, ContourSegmentationAnnotationData, ContourSegmentationAnnotation, BidirectionalData, CanvasCoordinates, IAnnotationManager, InterpolationViewportData, ImageInterpolationData, GroupSpecificAnnotations, AnnotationState, AnnotationStyle, ToolSpecificAnnotationTypes, JumpToSliceOptions, AnnotationGroupSelector, AnnotationRenderContext, PlanarBoundingBox, ToolProps, PublicToolProps, ToolConfiguration, EventTypes, IPoints, ITouchPoints, IDistance, IToolBinding, SetToolBindingsType, ToolOptionsType, InteractionTypes, ToolAction, IToolGroup, IToolClassReference, ISynchronizerEventHandler, ToolHandle, AnnotationHandle, TextBoxHandle, Segmentation, SegmentationState, SegmentationRepresentationData, SegmentationRepresentationConfig, RepresentationConfig, RepresentationPublicInput, LabelmapTypes, SVGCursorDescriptor, SVGPoint, ScrollOptions, CINETypes, BoundsIJK, SVGDrawingHelper, FloodFillResult, FloodFillGetter, FloodFillOptions, ContourSegmentationData, ISculptToolShape, Statistics, NamedStatistics, LabelmapToolOperationData, LabelmapToolOperationDataStack, LabelmapToolOperationDataVolume, CardinalSplineProps, ClosestControlPoint, ClosestPoint, ClosestSplinePoint, ControlPointInfo, ISpline, SplineCurveSegment, SplineLineSegment, SplineProps, PolySegConversionOptions, };
49
+ import type { IBaseTool } from './IBaseTool';
50
+ export type { Annotation, Annotations, ContourAnnotationData, ContourAnnotation, ContourSegmentationAnnotationData, ContourSegmentationAnnotation, BidirectionalData, CanvasCoordinates, IAnnotationManager, InterpolationViewportData, ImageInterpolationData, GroupSpecificAnnotations, AnnotationState, AnnotationStyle, ToolSpecificAnnotationTypes, JumpToSliceOptions, AnnotationGroupSelector, AnnotationRenderContext, PlanarBoundingBox, ToolProps, PublicToolProps, ToolConfiguration, EventTypes, IPoints, ITouchPoints, IDistance, IToolBinding, SetToolBindingsType, ToolOptionsType, InteractionTypes, ToolAction, IToolGroup, IToolClassReference, ISynchronizerEventHandler, ToolHandle, AnnotationHandle, TextBoxHandle, Segmentation, SegmentationState, RepresentationData, RepresentationsData, RepresentationConfig, RepresentationPublicInput, LabelmapTypes, SVGCursorDescriptor, SVGPoint, ScrollOptions, CINETypes, BoundsIJK, SVGDrawingHelper, FloodFillResult, FloodFillGetter, FloodFillOptions, ContourSegmentationData, ISculptToolShape, Statistics, NamedStatistics, LabelmapToolOperationData, LabelmapToolOperationDataStack, LabelmapToolOperationDataVolume, CardinalSplineProps, ClosestControlPoint, ClosestPoint, ClosestSplinePoint, ControlPointInfo, ISpline, SplineCurveSegment, SplineLineSegment, SplineProps, PolySegConversionOptions, IBaseTool, GlobalConfig, };
@@ -8,10 +8,10 @@ export function addContourSegmentationAnnotation(annotation) {
8
8
  }
9
9
  const { segmentationId, segmentIndex } = annotation.data.segmentation;
10
10
  const segmentation = getSegmentation(segmentationId);
11
- if (!segmentation.representationData.CONTOUR) {
12
- segmentation.representationData.CONTOUR = { annotationUIDsMap: new Map() };
11
+ if (!segmentation.representationData.Contour) {
12
+ segmentation.representationData.Contour = { annotationUIDsMap: new Map() };
13
13
  }
14
- const { annotationUIDsMap } = segmentation.representationData.CONTOUR;
14
+ const { annotationUIDsMap } = segmentation.representationData.Contour;
15
15
  let annotationsUIDsSet = annotationUIDsMap.get(segmentIndex);
16
16
  if (!annotationsUIDsSet) {
17
17
  annotationsUIDsSet = new Set();
@@ -5,7 +5,7 @@ export function removeContourSegmentationAnnotation(annotation) {
5
5
  }
6
6
  const { segmentationId, segmentIndex } = annotation.data.segmentation;
7
7
  const segmentation = getSegmentation(segmentationId);
8
- const { annotationUIDsMap } = segmentation?.representationData.CONTOUR || {};
8
+ const { annotationUIDsMap } = segmentation?.representationData.Contour || {};
9
9
  const annotationsUIDsSet = annotationUIDsMap?.get(segmentIndex);
10
10
  if (!annotationsUIDsSet) {
11
11
  return;
@@ -15,13 +15,13 @@ function generateContourSetsFromLabelmap({ segmentations }) {
15
15
  return;
16
16
  }
17
17
  const numSlices = vol.dimensions[2];
18
- const segData = vol.imageData.getPointData().getScalars().getData();
18
+ const voxelManager = vol.voxelManager;
19
19
  const pixelsPerSlice = vol.dimensions[0] * vol.dimensions[1];
20
20
  for (let z = 0; z < numSlices; z++) {
21
21
  for (let y = 0; y < vol.dimensions[1]; y++) {
22
22
  const index = y * vol.dimensions[0] + z * pixelsPerSlice;
23
- segData[index] = 0;
24
- segData[index + vol.dimensions[0] - 1] = 0;
23
+ voxelManager.setAtIndex(index, 0);
24
+ voxelManager.setAtIndex(index + vol.dimensions[0] - 1, 0);
25
25
  }
26
26
  }
27
27
  const ContourSets = [];
@@ -41,13 +41,13 @@ function generateContourSetsFromLabelmap({ segmentations }) {
41
41
  });
42
42
  const { containedSegmentIndices } = segment;
43
43
  for (let sliceIndex = 0; sliceIndex < numSlices; sliceIndex++) {
44
- if (isSliceEmptyForSegment(sliceIndex, segData, pixelsPerSlice, segIndex)) {
44
+ if (isSliceEmptyForSegment(sliceIndex, voxelManager, pixelsPerSlice, segIndex)) {
45
45
  continue;
46
46
  }
47
47
  const frameStart = sliceIndex * pixelsPerSlice;
48
48
  try {
49
49
  for (let i = 0; i < pixelsPerSlice; i++) {
50
- const value = segData[i + frameStart];
50
+ const value = voxelManager.getAtIndex(i + frameStart);
51
51
  if (value === segIndex || containedSegmentIndices?.has(value)) {
52
52
  scalars.setValue(i + frameStart, 1);
53
53
  }
@@ -96,11 +96,11 @@ function generateContourSetsFromLabelmap({ segmentations }) {
96
96
  }
97
97
  return ContourSets;
98
98
  }
99
- function isSliceEmptyForSegment(sliceIndex, segData, pixelsPerSlice, segIndex) {
99
+ function isSliceEmptyForSegment(sliceIndex, voxelManager, pixelsPerSlice, segIndex) {
100
100
  const startIdx = sliceIndex * pixelsPerSlice;
101
101
  const endIdx = startIdx + pixelsPerSlice;
102
102
  for (let i = startIdx; i < endIdx; i++) {
103
- if (segData[i] === segIndex) {
103
+ if (voxelManager.getAtIndex(i) === segIndex) {
104
104
  return false;
105
105
  }
106
106
  }
@@ -2,7 +2,7 @@ import { getAnnotation } from '../../stateManagement';
2
2
  import { getSegmentation } from '../../stateManagement/segmentation/segmentationState';
3
3
  export function getHoveredContourSegmentationAnnotation(segmentationId) {
4
4
  const segmentation = getSegmentation(segmentationId);
5
- const { annotationUIDsMap } = segmentation.representationData.CONTOUR;
5
+ const { annotationUIDsMap } = segmentation.representationData.Contour;
6
6
  for (const [segmentIndex, annotationUIDs] of annotationUIDsMap.entries()) {
7
7
  const highlightedAnnotationUID = Array.from(annotationUIDs).find((annotationUID) => getAnnotation(annotationUID).highlighted);
8
8
  if (highlightedAnnotationUID) {
@@ -3,15 +3,17 @@ import { getSegmentation, getSegmentationRepresentationsForSegmentation, getCurr
3
3
  import { isVolumeSegmentation } from '../../tools/segmentation/strategies/utils/stackVolumeCheck';
4
4
  export function getSegmentIndexAtLabelmapBorder(segmentationId, worldPoint, { viewport, searchRadius }) {
5
5
  const segmentation = getSegmentation(segmentationId);
6
- const labelmapData = segmentation.representationData.LABELMAP;
7
- if (isVolumeSegmentation(labelmapData)) {
6
+ const labelmapData = segmentation.representationData.Labelmap;
7
+ if (isVolumeSegmentation(labelmapData, viewport)) {
8
8
  const { volumeId } = labelmapData;
9
9
  const segmentationVolume = cache.getVolume(volumeId);
10
10
  if (!segmentationVolume) {
11
11
  return;
12
12
  }
13
+ const voxelManager = segmentationVolume.voxelManager;
13
14
  const imageData = segmentationVolume.imageData;
14
- const segmentIndex = imageData.getScalarValueFromWorld(worldPoint);
15
+ const indexIJK = utilities.transformWorldToIndex(imageData, worldPoint);
16
+ const segmentIndex = voxelManager.getAtIJK(indexIJK[0], indexIJK[1], indexIJK[2]);
15
17
  const canvasPoint = viewport.worldToCanvas(worldPoint);
16
18
  const onEdge = isSegmentOnEdgeCanvas(canvasPoint, segmentIndex, viewport, imageData, searchRadius);
17
19
  return onEdge ? segmentIndex : undefined;
@@ -69,7 +71,9 @@ function isSegmentOnEdgeCanvas(canvasPoint, segmentIndex, viewport, imageData, s
69
71
  const getNeighborIndex = (deltaI, deltaJ) => {
70
72
  const neighborCanvas = [canvasPoint[0] + deltaI, canvasPoint[1] + deltaJ];
71
73
  const worldPoint = viewport.canvasToWorld(neighborCanvas);
72
- return imageData.getScalarValueFromWorld(worldPoint);
74
+ const voxelManager = imageData.get('voxelManager').voxelManager;
75
+ const indexIJK = utilities.transformWorldToIndex(imageData, worldPoint);
76
+ return voxelManager.getAtIJK(indexIJK[0], indexIJK[1], indexIJK[2]);
73
77
  };
74
78
  return isSegmentOnEdge(getNeighborIndex, segmentIndex, searchRadius);
75
79
  }
@@ -21,7 +21,7 @@ export function getSegmentIndexAtWorldPoint(segmentationId, worldPoint, options
21
21
  }
22
22
  }
23
23
  export function getSegmentIndexAtWorldForLabelmap(segmentation, worldPoint, { viewport }) {
24
- const labelmapData = segmentation.representationData.LABELMAP;
24
+ const labelmapData = segmentation.representationData.Labelmap;
25
25
  if (isVolumeSegmentation(labelmapData)) {
26
26
  const { volumeId } = labelmapData;
27
27
  const segmentationVolume = cache.getVolume(volumeId);
@@ -51,7 +51,7 @@ export function getSegmentIndexAtWorldForLabelmap(segmentation, worldPoint, { vi
51
51
  return segmentIndex;
52
52
  }
53
53
  export function getSegmentIndexAtWorldForContour(segmentation, worldPoint, { viewport }) {
54
- const contourData = segmentation.representationData.CONTOUR;
54
+ const contourData = segmentation.representationData.Contour;
55
55
  const segmentIndices = Array.from(contourData.annotationUIDsMap.keys());
56
56
  const { viewPlaneNormal } = viewport.getCamera();
57
57
  for (const segmentIndex of segmentIndices) {