@cornerstonejs/tools 2.0.0-beta.19 → 2.0.0-beta.20

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 (45) hide show
  1. package/dist/esm/eventListeners/segmentation/imageChangeEventListener.js +45 -72
  2. package/dist/esm/eventListeners/segmentation/labelmap/onLabelmapSegmentationDataModified.js +9 -6
  3. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.d.ts +5 -0
  4. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.js +102 -1
  5. package/dist/esm/stateManagement/segmentation/config/segmentationVisibility.js +0 -2
  6. package/dist/esm/stateManagement/segmentation/convertStackToVolumeSegmentation.d.ts +2 -2
  7. package/dist/esm/stateManagement/segmentation/convertStackToVolumeSegmentation.js +7 -14
  8. package/dist/esm/stateManagement/segmentation/convertVolumeToStackSegmentation.d.ts +3 -3
  9. package/dist/esm/stateManagement/segmentation/convertVolumeToStackSegmentation.js +14 -15
  10. package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/convertContourToLabelmap.d.ts +1 -1
  11. package/dist/esm/stateManagement/segmentation/polySeg/Labelmap/convertContourToLabelmap.js +3 -3
  12. package/dist/esm/stateManagement/segmentation/polySeg/Surface/convertLabelmapToSurface.js +2 -2
  13. package/dist/esm/stateManagement/segmentation/segmentationState.d.ts +3 -1
  14. package/dist/esm/stateManagement/segmentation/segmentationState.js +9 -1
  15. package/dist/esm/store/ToolGroupManager/ToolGroup.d.ts +2 -0
  16. package/dist/esm/store/ToolGroupManager/ToolGroup.js +10 -0
  17. package/dist/esm/tools/base/BaseTool.js +1 -1
  18. package/dist/esm/tools/displayTools/Labelmap/addLabelmapToElement.js +3 -1
  19. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.js +2 -3
  20. package/dist/esm/tools/displayTools/Labelmap/validateLabelmap.js +3 -3
  21. package/dist/esm/tools/segmentation/BrushTool.d.ts +5 -5
  22. package/dist/esm/tools/segmentation/BrushTool.js +6 -5
  23. package/dist/esm/tools/segmentation/CircleScissorsTool.d.ts +1 -1
  24. package/dist/esm/tools/segmentation/CircleScissorsTool.js +0 -2
  25. package/dist/esm/tools/segmentation/PaintFillTool.js +3 -5
  26. package/dist/esm/tools/segmentation/RectangleScissorsTool.d.ts +1 -1
  27. package/dist/esm/tools/segmentation/RectangleScissorsTool.js +1 -3
  28. package/dist/esm/tools/segmentation/SphereScissorsTool.d.ts +1 -1
  29. package/dist/esm/tools/segmentation/SphereScissorsTool.js +1 -3
  30. package/dist/esm/tools/segmentation/strategies/compositions/dynamicThreshold.js +5 -1
  31. package/dist/esm/tools/segmentation/strategies/utils/getStrategyData.js +5 -3
  32. package/dist/esm/tools/segmentation/strategies/utils/stackVolumeCheck.js +5 -5
  33. package/dist/esm/types/LabelmapTypes.d.ts +2 -2
  34. package/dist/esm/utilities/annotationHydration.js +1 -1
  35. package/dist/esm/utilities/segmentation/getSegmentIndexAtLabelmapBorder.js +2 -3
  36. package/dist/esm/utilities/segmentation/getSegmentIndexAtWorldPoint.js +2 -4
  37. package/dist/esm/utilities/segmentation/getUniqueSegmentIndices.js +3 -3
  38. package/dist/esm/utilities/segmentation/index.d.ts +1 -2
  39. package/dist/esm/utilities/segmentation/index.js +1 -2
  40. package/dist/esm/utilities/stackPrefetch/stackContextPrefetch.js +0 -2
  41. package/dist/umd/index.js +1 -1
  42. package/dist/umd/index.js.map +1 -1
  43. package/package.json +3 -3
  44. package/dist/esm/utilities/segmentation/createImageIdReferenceMap.d.ts +0 -2
  45. package/dist/esm/utilities/segmentation/createImageIdReferenceMap.js +0 -7
@@ -3,9 +3,7 @@ import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
3
3
  import { BaseVolumeViewport, getEnabledElement, Enums, getEnabledElementByIds, cache, utilities, } from '@cornerstonejs/core';
4
4
  import Representations from '../../enums/SegmentationRepresentations';
5
5
  import * as SegmentationState from '../../stateManagement/segmentation/segmentationState';
6
- import { isVolumeSegmentation } from '../../tools/segmentation/strategies/utils/stackVolumeCheck';
7
6
  import triggerSegmentationRender from '../../utilities/segmentation/triggerSegmentationRender';
8
- import triggerSegmentationRenderForViewports from '../../utilities/segmentation/triggerSegmentationRenderForViewports';
9
7
  const enable = function (element) {
10
8
  const { viewport } = getEnabledElement(element);
11
9
  if (viewport instanceof BaseVolumeViewport) {
@@ -31,89 +29,59 @@ function _imageChangeEventListener(evt) {
31
29
  if (!labelmapRepresentations.length) {
32
30
  return;
33
31
  }
32
+ const actors = viewport.getActors();
34
33
  labelmapRepresentations.forEach((representation) => {
35
- const segmentation = SegmentationState.getSegmentation(representation.segmentationId);
36
- if (!segmentation || !segmentation.representationData?.LABELMAP) {
37
- return;
38
- }
39
- const labelmapData = segmentation.representationData.LABELMAP;
40
- if (isVolumeSegmentation(labelmapData, viewport)) {
41
- return;
42
- }
43
- const { imageIdReferenceMap } = labelmapData;
44
- segmentationRepresentations[representation.segmentationRepresentationUID] =
45
- {
46
- imageIdReferenceMap,
47
- };
34
+ const { segmentationId } = representation;
35
+ const labelmapImageId = SegmentationState.updateSegmentationImageReferences(viewportId, segmentationId);
48
36
  });
49
- const representationList = Object.keys(segmentationRepresentations);
50
- const currentImageId = viewport.getCurrentImageId();
51
- const actors = viewport.getActors();
52
- const segmentationFound = actors.find((actor) => {
53
- if (!representationList.includes(actor.uid)) {
54
- return false;
37
+ const allLabelmapActors = actors.filter((actor) => labelmapRepresentations.some((representation) => representation.segmentationRepresentationUID === actor.uid));
38
+ allLabelmapActors.forEach((actor) => {
39
+ const validActor = labelmapRepresentations.find((representation) => {
40
+ const derivedImageId = SegmentationState.getLabelmapImageIdsForViewport(viewportId, representation.segmentationId);
41
+ return derivedImageId === actor.referencedId;
42
+ });
43
+ if (!validActor) {
44
+ viewport.removeActors([actor.uid]);
55
45
  }
56
- return true;
57
46
  });
58
- if (!segmentationFound) {
59
- if (!perViewportManualTriggers.has(viewportId)) {
60
- perViewportManualTriggers.set(viewportId, true);
61
- triggerSegmentationRenderForViewports([viewportId]);
47
+ labelmapRepresentations.forEach((representation) => {
48
+ const { segmentationId } = representation;
49
+ const currentImageId = viewport.getCurrentImageId();
50
+ const derivedImageId = SegmentationState.getLabelmapImageIdsForViewport(viewportId, segmentationId);
51
+ if (!derivedImageId) {
52
+ return;
62
53
  }
63
- return;
64
- }
65
- actors.forEach((actor) => {
66
- if (!representationList.includes(actor.uid)) {
54
+ const derivedImage = cache.getImage(derivedImageId);
55
+ if (!derivedImage) {
56
+ console.warn('No derived image found in the cache for segmentation representation', representation);
67
57
  return;
68
58
  }
69
- const segmentationActor = actor.actor;
70
- const { imageIdReferenceMap } = segmentationRepresentations[actor.uid];
71
- const derivedImageId = imageIdReferenceMap.get(currentImageId);
72
- const segmentationImageData = segmentationActor.getMapper().getInputData();
73
- if (!derivedImageId) {
74
- if (segmentationImageData.setDerivedImage) {
75
- segmentationImageData.setDerivedImage(null);
76
- return;
77
- }
59
+ const segmentationActorInput = actors.find((actor) => actor.referencedId === derivedImageId);
60
+ if (!segmentationActorInput) {
61
+ const { dimensions, spacing, direction } = viewport.getImageDataMetadata(derivedImage);
62
+ const currentImage = cache.getImage(currentImageId) ||
63
+ {
64
+ imageId: currentImageId,
65
+ };
66
+ const { origin: currentOrigin } = viewport.getImageDataMetadata(currentImage);
67
+ const originToUse = currentOrigin;
78
68
  const scalarArray = vtkDataArray.newInstance({
79
69
  name: 'Pixels',
80
70
  numberOfComponents: 1,
81
- values: new Uint8Array(segmentationImageData.getNumberOfPoints()),
71
+ values: [...derivedImage.getPixelData()],
82
72
  });
83
73
  const imageData = vtkImageData.newInstance();
74
+ imageData.setDimensions(dimensions[0], dimensions[1], 1);
75
+ imageData.setSpacing(spacing);
76
+ imageData.setDirection(direction);
77
+ imageData.setOrigin(originToUse);
84
78
  imageData.getPointData().setScalars(scalarArray);
85
- segmentationActor.getMapper().setInputData(imageData);
86
- return;
87
- }
88
- const derivedImage = cache.getImage(derivedImageId);
89
- const { dimensions, spacing, direction } = viewport.getImageDataMetadata(derivedImage);
90
- const currentImage = cache.getImage(currentImageId) ||
91
- {
92
- imageId: currentImageId,
93
- };
94
- const { origin: currentOrigin } = viewport.getImageDataMetadata(currentImage);
95
- const originToUse = currentOrigin;
96
- segmentationImageData.setOrigin(originToUse);
97
- segmentationImageData.modified();
98
- if (segmentationImageData.getDimensions()[0] !== dimensions[0] ||
99
- segmentationImageData.getDimensions()[1] !== dimensions[1]) {
100
- viewport.removeActors([actor.uid]);
79
+ imageData.modified();
101
80
  viewport.addImages([
102
81
  {
103
82
  imageId: derivedImageId,
104
- actorUID: actor.uid,
83
+ actorUID: representation.segmentationRepresentationUID,
105
84
  callback: ({ imageActor }) => {
106
- const scalarArray = vtkDataArray.newInstance({
107
- name: 'Pixels',
108
- numberOfComponents: 1,
109
- values: [...derivedImage.getPixelData()],
110
- });
111
- const imageData = vtkImageData.newInstance();
112
- imageData.setDimensions(dimensions[0], dimensions[1], 1);
113
- imageData.setSpacing(spacing);
114
- imageData.setDirection(direction);
115
- imageData.setOrigin(originToUse);
116
- imageData.getPointData().setScalars(scalarArray);
117
85
  imageActor.getMapper().setInputData(imageData);
118
86
  },
119
87
  },
@@ -121,11 +89,16 @@ function _imageChangeEventListener(evt) {
121
89
  triggerSegmentationRender();
122
90
  return;
123
91
  }
124
- if (segmentationImageData.setDerivedImage) {
125
- segmentationImageData.setDerivedImage(derivedImage);
126
- }
127
92
  else {
128
- utilities.updateVTKImageDataWithCornerstoneImage(segmentationImageData, derivedImage);
93
+ const segmentationImageData = segmentationActorInput.actor
94
+ .getMapper()
95
+ .getInputData();
96
+ if (segmentationImageData.setDerivedImage) {
97
+ segmentationImageData.setDerivedImage(derivedImage);
98
+ }
99
+ else {
100
+ utilities.updateVTKImageDataWithCornerstoneImage(segmentationImageData, derivedImage);
101
+ }
129
102
  }
130
103
  viewport.render();
131
104
  if (evt.type === Enums.Events.IMAGE_RENDERED) {
@@ -2,17 +2,22 @@ import { cache, utilities as csUtils, VolumeViewport, getEnabledElementByViewpor
2
2
  import * as SegmentationState from '../../../stateManagement/segmentation/segmentationState';
3
3
  const onLabelmapSegmentationDataModified = function (evt) {
4
4
  const { segmentationId, modifiedSlicesToUse } = evt.detail;
5
+ let modifiedSlices = modifiedSlicesToUse;
5
6
  const { representationData, type } = SegmentationState.getSegmentation(segmentationId);
6
7
  const labelmapRepresentationData = representationData[type];
8
+ if ('stack' in labelmapRepresentationData &&
9
+ 'volumeId' in labelmapRepresentationData) {
10
+ modifiedSlices = [];
11
+ }
7
12
  if ('volumeId' in labelmapRepresentationData) {
8
13
  performVolumeLabelmapUpdate({
9
- modifiedSlicesToUse,
14
+ modifiedSlicesToUse: modifiedSlices,
10
15
  representationData,
11
16
  type,
12
17
  });
13
18
  }
14
19
  const viewportIds = SegmentationState.getViewportIdsWithSegmentationId(segmentationId);
15
- if ('imageIdReferenceMap' in labelmapRepresentationData) {
20
+ if ('imageIds' in labelmapRepresentationData) {
16
21
  performStackLabelmapUpdate({
17
22
  viewportIds,
18
23
  segmentationId,
@@ -29,7 +34,7 @@ function performVolumeLabelmapUpdate({ modifiedSlicesToUse, representationData,
29
34
  }
30
35
  const { imageData, vtkOpenGLTexture } = segmentationVolume;
31
36
  let slicesToUpdate;
32
- if (modifiedSlicesToUse && Array.isArray(modifiedSlicesToUse)) {
37
+ if (modifiedSlicesToUse?.length > 0) {
33
38
  slicesToUpdate = modifiedSlicesToUse;
34
39
  }
35
40
  else {
@@ -60,10 +65,8 @@ function performStackLabelmapUpdate({ viewportIds, segmentationId, representatio
60
65
  if (!actorEntry) {
61
66
  return;
62
67
  }
63
- const currentImageId = viewport.getCurrentImageId();
64
68
  const segImageData = actorEntry.actor.getMapper().getInputData();
65
- const { imageIdReferenceMap } = representationData[type];
66
- const currentSegmentationImageId = imageIdReferenceMap.get(currentImageId);
69
+ const currentSegmentationImageId = SegmentationState.getLabelmapImageIdsForViewport(viewportId, representation.segmentationId);
67
70
  const segmentationImage = cache.getImage(currentSegmentationImageId);
68
71
  segImageData.modified();
69
72
  csUtils.updateVTKImageDataWithCornerstoneImage(segImageData, segmentationImage);
@@ -3,6 +3,7 @@ import type { RepresentationConfig, SegmentRepresentationConfig, Segmentation, S
3
3
  export default class SegmentationStateManager {
4
4
  private state;
5
5
  readonly uid: string;
6
+ private _stackLabelmapImageIdReferenceMap;
6
7
  constructor(uid?: string);
7
8
  getState(): SegmentationState;
8
9
  getColorLUT(lutIndex: number): Types.ColorLUT | undefined;
@@ -14,6 +15,9 @@ export default class SegmentationStateManager {
14
15
  getRepresentation(segmentationRepresentationUID: string): SegmentationRepresentation | undefined;
15
16
  addRepresentation(segmentationRepresentation: SegmentationRepresentation): void;
16
17
  addRepresentationToViewport(viewportId: string, segmentationRepresentationUID: string): void;
18
+ updateSegmentationImageReferences(viewportId: any, segmentationId: any): string;
19
+ private getLabelmapImageIds;
20
+ getLabelmapImageIdsForViewport(viewportId: string, segmentationId: string): string | undefined;
17
21
  getRepresentationsForViewport(viewportId: string): SegmentationRepresentation[];
18
22
  removeRepresentation(segmentationRepresentationUID: string): void;
19
23
  setActiveRepresentation(viewportId: string, segmentationRepresentationUID: string): void;
@@ -32,6 +36,7 @@ export default class SegmentationStateManager {
32
36
  setRepresentationVisibility(viewportId: string, segmentationRepresentationUID: string, visible: boolean): void;
33
37
  addColorLUT(colorLUT: Types.ColorLUT, lutIndex: number): void;
34
38
  removeColorLUT(colorLUTIndex: number): void;
39
+ _getStackIdForImageIds(imageIds: string[]): string;
35
40
  }
36
41
  declare const defaultSegmentationStateManager: SegmentationStateManager;
37
42
  export { defaultSegmentationStateManager };
@@ -1,8 +1,9 @@
1
- import { utilities as csUtils } from '@cornerstonejs/core';
1
+ import { BaseVolumeViewport, cache, utilities as csUtils, getEnabledElementByViewportId, } from '@cornerstonejs/core';
2
2
  import { SegmentationRepresentations } from '../../enums';
3
3
  import getDefaultContourConfig from '../../tools/displayTools/Contour/contourConfig';
4
4
  import getDefaultLabelmapConfig from '../../tools/displayTools/Labelmap/labelmapConfig';
5
5
  import getDefaultSurfaceConfig from '../../tools/displayTools/Surface/surfaceConfig';
6
+ import { convertStackToVolumeSegmentation } from './convertStackToVolumeSegmentation';
6
7
  const newGlobalConfig = {
7
8
  renderInactiveRepresentations: true,
8
9
  representations: {
@@ -20,6 +21,7 @@ const initialDefaultState = {
20
21
  };
21
22
  export default class SegmentationStateManager {
22
23
  constructor(uid) {
24
+ this._stackLabelmapImageIdReferenceMap = new Map();
23
25
  if (!uid) {
24
26
  uid = csUtils.uuidv4();
25
27
  }
@@ -45,6 +47,13 @@ export default class SegmentationStateManager {
45
47
  if (this.getSegmentation(segmentation.segmentationId)) {
46
48
  throw new Error(`Segmentation with id ${segmentation.segmentationId} already exists`);
47
49
  }
50
+ if (segmentation.representationData.LABELMAP &&
51
+ 'volumeId' in segmentation.representationData.LABELMAP &&
52
+ !('imageIds' in segmentation.representationData.LABELMAP)) {
53
+ const imageIds = this.getLabelmapImageIds(segmentation.representationData);
54
+ segmentation.representationData
55
+ .LABELMAP.imageIds = imageIds;
56
+ }
48
57
  this.state.segmentations.push(segmentation);
49
58
  }
50
59
  removeSegmentation(segmentationId) {
@@ -59,11 +68,98 @@ export default class SegmentationStateManager {
59
68
  segmentationRepresentation;
60
69
  }
61
70
  addRepresentationToViewport(viewportId, segmentationRepresentationUID) {
71
+ const enabledElement = getEnabledElementByViewportId(viewportId);
72
+ if (!enabledElement) {
73
+ return;
74
+ }
62
75
  if (!this.state.viewports[viewportId]) {
63
76
  this.state.viewports[viewportId] = {};
64
77
  }
78
+ const representation = this.getRepresentation(segmentationRepresentationUID);
79
+ if (representation.type !== SegmentationRepresentations.Labelmap) {
80
+ this.setActiveRepresentation(viewportId, segmentationRepresentationUID);
81
+ return;
82
+ }
83
+ const volumeViewport = enabledElement.viewport instanceof BaseVolumeViewport;
84
+ const segmentation = this.getSegmentation(representation.segmentationId);
85
+ const { representationData } = segmentation;
86
+ const isBaseVolumeSegmentation = 'volumeId' in representationData.LABELMAP;
87
+ if (!volumeViewport) {
88
+ if (isBaseVolumeSegmentation) {
89
+ }
90
+ else {
91
+ this.updateSegmentationImageReferences(viewportId, segmentation.segmentationId);
92
+ }
93
+ }
94
+ else {
95
+ const volumeViewport = enabledElement.viewport;
96
+ const frameOfReferenceUID = volumeViewport.getFrameOfReferenceUID();
97
+ if (!isBaseVolumeSegmentation) {
98
+ const imageIds = this.getLabelmapImageIds(segmentation.representationData);
99
+ const segImage = cache.getImage(imageIds[0]);
100
+ if (segImage?.FrameOfReferenceUID === frameOfReferenceUID) {
101
+ convertStackToVolumeSegmentation(segmentation);
102
+ }
103
+ }
104
+ else {
105
+ }
106
+ }
65
107
  this.setActiveRepresentation(viewportId, segmentationRepresentationUID);
66
108
  }
109
+ updateSegmentationImageReferences(viewportId, segmentationId) {
110
+ const segmentation = this.getSegmentation(segmentationId);
111
+ if (!segmentation) {
112
+ return;
113
+ }
114
+ if (!this._stackLabelmapImageIdReferenceMap.has(segmentationId)) {
115
+ this._stackLabelmapImageIdReferenceMap.set(segmentationId, new Map());
116
+ }
117
+ const { representationData } = segmentation;
118
+ const labelmapImageIds = this.getLabelmapImageIds(representationData);
119
+ const enabledElement = getEnabledElementByViewportId(viewportId);
120
+ const stackViewport = enabledElement.viewport;
121
+ const currentImageId = stackViewport.getCurrentImageId();
122
+ for (const labelmapImageId of labelmapImageIds) {
123
+ const viewableImageId = stackViewport.isReferenceViewable({ referencedImageId: labelmapImageId }, { asOverlay: true });
124
+ if (viewableImageId) {
125
+ this._stackLabelmapImageIdReferenceMap
126
+ .get(segmentationId)
127
+ .set(currentImageId, labelmapImageId);
128
+ }
129
+ }
130
+ return this._stackLabelmapImageIdReferenceMap
131
+ .get(segmentationId)
132
+ .get(currentImageId);
133
+ }
134
+ getLabelmapImageIds(representationData) {
135
+ const labelmapData = representationData.LABELMAP;
136
+ let labelmapImageIds;
137
+ if (labelmapData.imageIds) {
138
+ labelmapImageIds = labelmapData
139
+ .imageIds;
140
+ }
141
+ else if (!labelmapImageIds &&
142
+ labelmapData.volumeId) {
143
+ const volumeId = labelmapData
144
+ .volumeId;
145
+ const volume = cache.getVolume(volumeId);
146
+ labelmapImageIds = volume.imageIds;
147
+ }
148
+ return labelmapImageIds;
149
+ }
150
+ getLabelmapImageIdsForViewport(viewportId, segmentationId) {
151
+ const enabledElement = getEnabledElementByViewportId(viewportId);
152
+ if (!enabledElement) {
153
+ return;
154
+ }
155
+ if (!this._stackLabelmapImageIdReferenceMap.has(segmentationId)) {
156
+ return;
157
+ }
158
+ const stackViewport = enabledElement.viewport;
159
+ const currentImageId = stackViewport.getCurrentImageId();
160
+ const imageIdReferenceMap = this._stackLabelmapImageIdReferenceMap.get(segmentationId);
161
+ return imageIdReferenceMap.get(currentImageId);
162
+ }
67
163
  getRepresentationsForViewport(viewportId) {
68
164
  const viewport = this.state.viewports[viewportId];
69
165
  if (!viewport) {
@@ -167,6 +263,11 @@ export default class SegmentationStateManager {
167
263
  removeColorLUT(colorLUTIndex) {
168
264
  delete this.state.colorLUT[colorLUTIndex];
169
265
  }
266
+ _getStackIdForImageIds(imageIds) {
267
+ return imageIds
268
+ .map((imageId) => imageId.slice(-Math.round(imageId.length * 0.15)))
269
+ .join('_');
270
+ }
170
271
  }
171
272
  const defaultSegmentationStateManager = new SegmentationStateManager('DEFAULT');
172
273
  export { defaultSegmentationStateManager };
@@ -2,7 +2,6 @@ import * as SegmentationState from '../../../stateManagement/segmentation/segmen
2
2
  import { triggerSegmentationRepresentationModified } from '../triggerSegmentationEvents';
3
3
  function setRepresentationVisibility(viewportId, segmentationRepresentationUID, visibility) {
4
4
  const representation = SegmentationState.getRepresentation(segmentationRepresentationUID);
5
- debugger;
6
5
  if (!representation) {
7
6
  return;
8
7
  }
@@ -23,7 +22,6 @@ function setSegmentsVisibility(viewport, segmentationRepresentationUID, segmentI
23
22
  }
24
23
  function setSegmentIndexVisibility(viewportId, segmentationRepresentationUID, segmentIndex, visibility) {
25
24
  const hiddenSegments = getSegmentsHidden(viewportId, segmentationRepresentationUID);
26
- debugger;
27
25
  visibility
28
26
  ? hiddenSegments.delete(segmentIndex)
29
27
  : hiddenSegments.add(segmentIndex);
@@ -1,5 +1,5 @@
1
- declare function computeVolumeSegmentationFromStack({ imageIdReferenceMap, options, }: {
2
- imageIdReferenceMap: Map<string, string>;
1
+ declare function computeVolumeSegmentationFromStack({ imageIds, options, }: {
2
+ imageIds: string[];
3
3
  options?: {
4
4
  volumeId?: string;
5
5
  };
@@ -1,13 +1,12 @@
1
1
  import { volumeLoader, utilities as csUtils, eventTarget, cache, } from '@cornerstonejs/core';
2
- import { Events, SegmentationRepresentations } from '../../enums';
3
- import addRepresentations from './addRepresentations';
2
+ import { Events } from '../../enums';
4
3
  import { triggerSegmentationRender } from '../../utilities/segmentation';
5
4
  import { getSegmentation } from './segmentationState';
6
5
  import { triggerSegmentationDataModified } from './triggerSegmentationEvents';
7
- async function computeVolumeSegmentationFromStack({ imageIdReferenceMap, options, }) {
8
- const segmentationImageIds = Array.from(imageIdReferenceMap.values());
6
+ async function computeVolumeSegmentationFromStack({ imageIds, options, }) {
7
+ const segmentationImageIds = imageIds;
9
8
  const additionalDetails = {
10
- imageIdReferenceMap,
9
+ imageIds,
11
10
  };
12
11
  const volumeId = options?.volumeId ?? csUtils.uuidv4();
13
12
  await volumeLoader.createAndCacheVolumeFromImages(volumeId, segmentationImageIds, {
@@ -20,7 +19,7 @@ async function convertStackToVolumeSegmentation({ segmentationId, options, }) {
20
19
  const data = segmentation.representationData
21
20
  .LABELMAP;
22
21
  const { volumeId } = await computeVolumeSegmentationFromStack({
23
- imageIdReferenceMap: data.imageIdReferenceMap,
22
+ imageIds: data.imageIds,
24
23
  options,
25
24
  });
26
25
  await updateSegmentationState({
@@ -35,8 +34,8 @@ async function updateSegmentationState({ segmentationId, viewportId, volumeId, o
35
34
  if (options?.removeOriginal) {
36
35
  const data = segmentation.representationData
37
36
  .LABELMAP;
38
- const imageIdReferenceMap = data.imageIdReferenceMap;
39
- Array.from(imageIdReferenceMap.values()).forEach((imageId) => {
37
+ const { imageIds } = data;
38
+ imageIds.forEach((imageId) => {
40
39
  cache.removeImageLoadObject(imageId);
41
40
  });
42
41
  segmentation.representationData.LABELMAP = {
@@ -49,12 +48,6 @@ async function updateSegmentationState({ segmentationId, viewportId, volumeId, o
49
48
  volumeId,
50
49
  };
51
50
  }
52
- await addRepresentations(viewportId, [
53
- {
54
- segmentationId,
55
- type: SegmentationRepresentations.Labelmap,
56
- },
57
- ]);
58
51
  triggerSegmentationRender(viewportId);
59
52
  eventTarget.addEventListenerOnce(Events.SEGMENTATION_RENDERED, () => triggerSegmentationDataModified(segmentationId));
60
53
  }
@@ -1,7 +1,7 @@
1
1
  export declare function computeStackSegmentationFromVolume({ volumeId, }: {
2
2
  volumeId: string;
3
3
  }): Promise<{
4
- imageIdReferenceMap: Map<string, string>;
4
+ imageIds: string[];
5
5
  }>;
6
6
  export declare function convertVolumeToStackSegmentation({ segmentationId, options, }: {
7
7
  segmentationId: string;
@@ -11,10 +11,10 @@ export declare function convertVolumeToStackSegmentation({ segmentationId, optio
11
11
  removeOriginal?: boolean;
12
12
  };
13
13
  }): Promise<void>;
14
- export declare function updateStackSegmentationState({ segmentationId, viewportId, imageIdReferenceMap, options, }: {
14
+ export declare function updateStackSegmentationState({ segmentationId, viewportId, imageIds, options, }: {
15
15
  segmentationId: string;
16
16
  viewportId: string;
17
- imageIdReferenceMap: Map<any, any>;
17
+ imageIds: string[];
18
18
  options?: {
19
19
  removeOriginal?: boolean;
20
20
  };
@@ -1,7 +1,7 @@
1
1
  import { cache, eventTarget, getRenderingEngines, } from '@cornerstonejs/core';
2
2
  import { Events, SegmentationRepresentations } from '../../enums';
3
3
  import addRepresentations from './addRepresentations';
4
- import { triggerSegmentationRender, createImageIdReferenceMap, } from '../../utilities/segmentation';
4
+ import { triggerSegmentationRender } from '../../utilities/segmentation';
5
5
  import { getSegmentation } from './segmentationState';
6
6
  import { triggerSegmentationDataModified } from './triggerSegmentationEvents';
7
7
  export async function computeStackSegmentationFromVolume({ volumeId, }) {
@@ -16,24 +16,24 @@ export async function computeStackSegmentationFromVolume({ volumeId, }) {
16
16
  .getVolumeViewports()
17
17
  .find((vp) => vp.hasVolumeId(volumeId));
18
18
  segmentationVolume.decache(!volumeUsedInOtherViewports && isAllImagesCached);
19
- const imageIdReferenceMap = _getImageIdReferenceMapForStackSegmentation(segmentationVolume);
20
- return { imageIdReferenceMap };
19
+ const imageIds = _getLabelmapImageIdsForViewportForStackSegmentation(segmentationVolume);
20
+ return { imageIds };
21
21
  }
22
22
  export async function convertVolumeToStackSegmentation({ segmentationId, options, }) {
23
23
  const segmentation = getSegmentation(segmentationId);
24
24
  const data = segmentation.representationData
25
25
  .LABELMAP;
26
- const { imageIdReferenceMap } = await computeStackSegmentationFromVolume({
26
+ const { imageIds } = await computeStackSegmentationFromVolume({
27
27
  volumeId: data.volumeId,
28
28
  });
29
29
  await updateStackSegmentationState({
30
30
  segmentationId,
31
31
  viewportId: options.viewportId,
32
- imageIdReferenceMap,
32
+ imageIds,
33
33
  options,
34
34
  });
35
35
  }
36
- export async function updateStackSegmentationState({ segmentationId, viewportId, imageIdReferenceMap, options, }) {
36
+ export async function updateStackSegmentationState({ segmentationId, viewportId, imageIds, options, }) {
37
37
  const segmentation = getSegmentation(segmentationId);
38
38
  if (options?.removeOriginal) {
39
39
  const data = segmentation.representationData
@@ -42,13 +42,13 @@ export async function updateStackSegmentationState({ segmentationId, viewportId,
42
42
  cache.removeVolumeLoadObject(data.volumeId);
43
43
  }
44
44
  segmentation.representationData.LABELMAP = {
45
- imageIdReferenceMap,
45
+ imageIds,
46
46
  };
47
47
  }
48
48
  else {
49
49
  segmentation.representationData.LABELMAP = {
50
50
  ...segmentation.representationData.LABELMAP,
51
- imageIdReferenceMap,
51
+ imageIds,
52
52
  };
53
53
  }
54
54
  await addRepresentations(viewportId, [
@@ -60,15 +60,14 @@ export async function updateStackSegmentationState({ segmentationId, viewportId,
60
60
  triggerSegmentationRender();
61
61
  eventTarget.addEventListenerOnce(Events.SEGMENTATION_RENDERED, () => triggerSegmentationDataModified(segmentationId));
62
62
  }
63
- function _getImageIdReferenceMapForStackSegmentation(segmentationVolume) {
64
- if (segmentationVolume.additionalDetails?.imageIdReferenceMap) {
65
- return segmentationVolume.additionalDetails.imageIdReferenceMap;
63
+ function _getLabelmapImageIdsForViewportForStackSegmentation(segmentationVolume) {
64
+ if (segmentationVolume.additionalDetails?.imageIds) {
65
+ return segmentationVolume.additionalDetails.imageIds;
66
66
  }
67
67
  else if (segmentationVolume.referencedImageIds?.length &&
68
68
  !segmentationVolume.referencedImageIds[0].startsWith('derived')) {
69
- const referencedImageIds = segmentationVolume.referencedImageIds;
70
69
  const segmentationImageIds = segmentationVolume.imageIds;
71
- return createImageIdReferenceMap(referencedImageIds, [...segmentationImageIds].reverse());
70
+ return [...segmentationImageIds].reverse();
72
71
  }
73
72
  else {
74
73
  const referencedVolumeId = segmentationVolume.referencedVolumeId;
@@ -81,7 +80,7 @@ function _getImageIdReferenceMapForStackSegmentation(segmentationVolume) {
81
80
  }
82
81
  if (referencedVolume.imageIds?.[0].startsWith('derived')) {
83
82
  throw new Error(`Cannot convert volume segmentation that is derived from another segmentation
84
- to stack segmentation yet, include the additionalDetails.imageIdReferenceMap
83
+ to stack segmentation yet, include the additionalDetails.imageIds
85
84
  in the volume segmentation in case you need it for the conversion`);
86
85
  }
87
86
  const referencedImageIds = referencedVolume.imageIds;
@@ -90,6 +89,6 @@ function _getImageIdReferenceMapForStackSegmentation(segmentationVolume) {
90
89
  segmentationImageIdsToUse =
91
90
  segmentationVolume.convertToImageSlicesAndCache();
92
91
  }
93
- return createImageIdReferenceMap(referencedImageIds, [...segmentationImageIdsToUse].reverse());
92
+ return [...segmentationImageIdsToUse].reverse();
94
93
  }
95
94
  }
@@ -3,5 +3,5 @@ export declare function convertContourToVolumeLabelmap(contourRepresentationData
3
3
  volumeId: string;
4
4
  }>;
5
5
  export declare function convertContourToStackLabelmap(contourRepresentationData: ContourSegmentationData, options?: PolySegConversionOptions): Promise<{
6
- imageIdReferenceMap: Map<any, any>;
6
+ imageIds: any[];
7
7
  }>;
@@ -110,17 +110,17 @@ export async function convertContourToStackLabelmap(contourRepresentationData, o
110
110
  ],
111
111
  });
112
112
  triggerWorkerProgress(eventTarget, 1);
113
- const imageIdReferenceMap = new Map();
113
+ const segImageIds = [];
114
114
  newSegmentationsScalarData.forEach(({ scalarData }, referencedImageId) => {
115
115
  const segmentationInfo = segmentationsInfo.get(referencedImageId);
116
116
  const { imageId: segImageId } = segmentationInfo;
117
117
  const segImage = cache.getImage(segImageId);
118
118
  segImage.getPixelData().set(scalarData);
119
119
  segImage.imageFrame?.pixelData?.set(scalarData);
120
- imageIdReferenceMap.set(referencedImageId, segImageId);
120
+ segImageIds.push(segImageId);
121
121
  });
122
122
  return {
123
- imageIdReferenceMap,
123
+ imageIds: segImageIds,
124
124
  };
125
125
  }
126
126
  function _getAnnotationMapFromSegmentation(contourRepresentationData, options = {}) {
@@ -16,9 +16,9 @@ export async function convertLabelmapToSurface(labelmapRepresentationData, segme
16
16
  .volumeId;
17
17
  }
18
18
  else {
19
- const { imageIdReferenceMap } = labelmapRepresentationData;
19
+ const { imageIds } = labelmapRepresentationData;
20
20
  ({ volumeId } = await computeVolumeSegmentationFromStack({
21
- imageIdReferenceMap,
21
+ imageIds,
22
22
  }));
23
23
  }
24
24
  const volume = cache.getVolume(volumeId);
@@ -33,4 +33,6 @@ declare function getRepresentationVisibility(viewportId: string, segmentationRep
33
33
  declare function setRepresentationVisibility(viewportId: string, segmentationRepresentationUID: string, visible: boolean): void;
34
34
  declare function getActiveRepresentation(viewportId: string): SegmentationRepresentation | undefined;
35
35
  declare function setActiveRepresentation(viewportId: string, segmentationRepresentationUID: string, suppressEvents?: boolean): void;
36
- export { getDefaultSegmentationStateManager, getSegmentation, getSegmentations, addSegmentation, removeSegmentation, getRepresentations, getRepresentation, removeRepresentation, getGlobalConfig, setGlobalConfig, getAllSegmentsConfig, setAllSegmentsConfig, getPerSegmentConfig, setPerSegmentConfig, getRepresentationsForViewport, addRepresentationToViewport, getRepresentationsRenderingStateForViewport, addColorLUT, getColorLUT, getNextColorLUTIndex, removeColorLUT, getRepresentationsBySegmentationId, getRepresentationVisibility, setRepresentationVisibility, getViewportIdsWithSegmentationId, getActiveRepresentation, setActiveRepresentation, };
36
+ declare function getLabelmapImageIdsForViewport(viewportId: string, segmentationId?: string): string;
37
+ declare function updateSegmentationImageReferences(viewportId: string, segmentationId: string): void;
38
+ export { getDefaultSegmentationStateManager, getSegmentation, getSegmentations, addSegmentation, removeSegmentation, getRepresentations, getRepresentation, removeRepresentation, getGlobalConfig, setGlobalConfig, getAllSegmentsConfig, setAllSegmentsConfig, getPerSegmentConfig, setPerSegmentConfig, getRepresentationsForViewport, addRepresentationToViewport, getRepresentationsRenderingStateForViewport, addColorLUT, getColorLUT, getNextColorLUTIndex, removeColorLUT, getRepresentationsBySegmentationId, getRepresentationVisibility, setRepresentationVisibility, getViewportIdsWithSegmentationId, getActiveRepresentation, setActiveRepresentation, getLabelmapImageIdsForViewport, updateSegmentationImageReferences, };
@@ -146,4 +146,12 @@ function setActiveRepresentation(viewportId, segmentationRepresentationUID, supp
146
146
  triggerSegmentationRepresentationModified(segmentationRepresentationUID);
147
147
  }
148
148
  }
149
- export { getDefaultSegmentationStateManager, getSegmentation, getSegmentations, addSegmentation, removeSegmentation, getRepresentations, getRepresentation, removeRepresentation, getGlobalConfig, setGlobalConfig, getAllSegmentsConfig, setAllSegmentsConfig, getPerSegmentConfig, setPerSegmentConfig, getRepresentationsForViewport, addRepresentationToViewport, getRepresentationsRenderingStateForViewport, addColorLUT, getColorLUT, getNextColorLUTIndex, removeColorLUT, getRepresentationsBySegmentationId, getRepresentationVisibility, setRepresentationVisibility, getViewportIdsWithSegmentationId, getActiveRepresentation, setActiveRepresentation, };
149
+ function getLabelmapImageIdsForViewport(viewportId, segmentationId) {
150
+ const segmentationStateManager = getDefaultSegmentationStateManager();
151
+ return segmentationStateManager.getLabelmapImageIdsForViewport(viewportId, segmentationId);
152
+ }
153
+ function updateSegmentationImageReferences(viewportId, segmentationId) {
154
+ const segmentationStateManager = getDefaultSegmentationStateManager();
155
+ segmentationStateManager.updateSegmentationImageReferences(viewportId, segmentationId);
156
+ }
157
+ export { getDefaultSegmentationStateManager, getSegmentation, getSegmentations, addSegmentation, removeSegmentation, getRepresentations, getRepresentation, removeRepresentation, getGlobalConfig, setGlobalConfig, getAllSegmentsConfig, setAllSegmentsConfig, getPerSegmentConfig, setPerSegmentConfig, getRepresentationsForViewport, addRepresentationToViewport, getRepresentationsRenderingStateForViewport, addColorLUT, getColorLUT, getNextColorLUTIndex, removeColorLUT, getRepresentationsBySegmentationId, getRepresentationVisibility, setRepresentationVisibility, getViewportIdsWithSegmentationId, getActiveRepresentation, setActiveRepresentation, getLabelmapImageIdsForViewport, updateSegmentationImageReferences, };
@@ -38,6 +38,8 @@ export default class ToolGroup implements IToolGroup {
38
38
  getDefaultPrimaryBindings(): IToolBinding[];
39
39
  getToolConfiguration(toolName: string, configurationPath?: string): any;
40
40
  getPrevActivePrimaryToolName(): string;
41
+ setActivePrimaryTool(toolName: string): void;
42
+ getCurrentActivePrimaryToolName(): string;
41
43
  clone(newToolGroupId: any, fnToolFilter?: (toolName: string) => void): IToolGroup;
42
44
  private _hasMousePrimaryButtonBinding;
43
45
  private _renderViewports;