@cornerstonejs/tools 2.0.0-beta.28 → 2.0.0-beta.29

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 (63) hide show
  1. package/dist/esm/constants/COLOR_LUT.d.ts +2 -1
  2. package/dist/esm/eventListeners/segmentation/imageChangeEventListener.js +1 -1
  3. package/dist/esm/eventListeners/segmentation/segmentationModifiedEventListener.js +0 -1
  4. package/dist/esm/eventListeners/segmentation/segmentationRepresentationModifiedListener.d.ts +3 -0
  5. package/dist/esm/eventListeners/segmentation/segmentationRepresentationModifiedListener.js +6 -0
  6. package/dist/esm/init.js +4 -0
  7. package/dist/esm/stateManagement/segmentation/SegmentationRenderingEngine.js +22 -12
  8. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.d.ts +1 -0
  9. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.js +63 -25
  10. package/dist/esm/stateManagement/segmentation/SegmentationStyle.d.ts +22 -25
  11. package/dist/esm/stateManagement/segmentation/SegmentationStyle.js +138 -77
  12. package/dist/esm/stateManagement/segmentation/activeSegmentation.js +0 -4
  13. package/dist/esm/stateManagement/segmentation/config/segmentationColor.js +5 -5
  14. package/dist/esm/stateManagement/segmentation/config/segmentationVisibility.js +12 -8
  15. package/dist/esm/stateManagement/segmentation/config/styleHelpers.d.ts +17 -31
  16. package/dist/esm/stateManagement/segmentation/config/styleHelpers.js +14 -37
  17. package/dist/esm/stateManagement/segmentation/events/triggerSegmentationModified.d.ts +1 -1
  18. package/dist/esm/stateManagement/segmentation/events/triggerSegmentationModified.js +4 -14
  19. package/dist/esm/stateManagement/segmentation/events/triggerSegmentationRepresentationModified.d.ts +2 -0
  20. package/dist/esm/stateManagement/segmentation/events/triggerSegmentationRepresentationModified.js +10 -0
  21. package/dist/esm/stateManagement/segmentation/events/triggerSegmentationRepresentationRemoved.d.ts +2 -0
  22. package/dist/esm/stateManagement/segmentation/events/triggerSegmentationRepresentationRemoved.js +10 -0
  23. package/dist/esm/stateManagement/segmentation/getActiveSegmentIndex.js +3 -1
  24. package/dist/esm/stateManagement/segmentation/getGlobalStyle.js +1 -1
  25. package/dist/esm/stateManagement/segmentation/helpers/clearSegmentValue.js +0 -1
  26. package/dist/esm/stateManagement/segmentation/helpers/internalGetHiddenSegmentIndices.d.ts +5 -0
  27. package/dist/esm/stateManagement/segmentation/helpers/internalGetHiddenSegmentIndices.js +14 -0
  28. package/dist/esm/stateManagement/segmentation/helpers/normalizeSegmentationInput.js +13 -6
  29. package/dist/esm/stateManagement/segmentation/index.d.ts +3 -1
  30. package/dist/esm/stateManagement/segmentation/index.js +3 -1
  31. package/dist/esm/stateManagement/segmentation/internalAddSegmentationRepresentation.js +9 -8
  32. package/dist/esm/stateManagement/segmentation/polySeg/Contour/contourComputationStrategies.js +1 -1
  33. package/dist/esm/stateManagement/segmentation/polySeg/computeAndAddRepresentation.js +0 -1
  34. package/dist/esm/stateManagement/segmentation/removeSegment.d.ts +3 -0
  35. package/dist/esm/stateManagement/segmentation/removeSegment.js +50 -0
  36. package/dist/esm/stateManagement/segmentation/removeSegmentationRepresentations.d.ts +1 -1
  37. package/dist/esm/stateManagement/segmentation/removeSegmentationRepresentations.js +10 -12
  38. package/dist/esm/stateManagement/segmentation/segmentIndex.js +18 -2
  39. package/dist/esm/stateManagement/segmentation/segmentLocking.js +7 -11
  40. package/dist/esm/stateManagement/segmentation/setGlobalStyle.js +3 -3
  41. package/dist/esm/stateManagement/segmentation/triggerSegmentationEvents.d.ts +3 -1
  42. package/dist/esm/stateManagement/segmentation/triggerSegmentationEvents.js +3 -1
  43. package/dist/esm/stateManagement/segmentation/updateSegmentations.d.ts +5 -0
  44. package/dist/esm/stateManagement/segmentation/updateSegmentations.js +11 -0
  45. package/dist/esm/tools/base/ContourSegmentationBaseTool.js +11 -10
  46. package/dist/esm/tools/displayTools/Contour/contourConfig.js +2 -2
  47. package/dist/esm/tools/displayTools/Contour/contourHandler/handleContourSegmentation.js +1 -5
  48. package/dist/esm/tools/displayTools/Labelmap/labelmapConfig.js +3 -3
  49. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.js +38 -29
  50. package/dist/esm/tools/displayTools/Surface/surfaceDisplay.js +2 -2
  51. package/dist/esm/tools/segmentation/BrushTool.js +4 -1
  52. package/dist/esm/tools/segmentation/strategies/BrushStrategy.js +1 -1
  53. package/dist/esm/types/ContourTypes.d.ts +15 -8
  54. package/dist/esm/types/EventTypes.d.ts +6 -0
  55. package/dist/esm/types/LabelmapTypes.d.ts +9 -6
  56. package/dist/esm/types/SegmentationStateTypes.d.ts +31 -21
  57. package/dist/esm/types/SurfaceTypes.d.ts +1 -0
  58. package/dist/esm/types/index.d.ts +6 -4
  59. package/dist/esm/utilities/dynamicVolume/generateImageFromTimeData.d.ts +8 -2
  60. package/dist/esm/utilities/dynamicVolume/generateImageFromTimeData.js +51 -24
  61. package/dist/esm/utilities/dynamicVolume/index.d.ts +2 -2
  62. package/dist/esm/utilities/dynamicVolume/index.js +2 -2
  63. package/package.json +3 -3
@@ -1,7 +1,7 @@
1
1
  import { addColorLUT as _addColorLUT } from '../addColorLUT';
2
2
  import { getColorLUT as _getColorLUT } from '../getColorLUT';
3
3
  import { getSegmentationRepresentations } from '../getSegmentationRepresentation';
4
- import { triggerSegmentationModified } from '../triggerSegmentationEvents';
4
+ import { triggerSegmentationRepresentationModified } from '../triggerSegmentationEvents';
5
5
  function addColorLUT(colorLUT, colorLUTIndex) {
6
6
  if (!colorLUT) {
7
7
  throw new Error('addColorLUT: colorLUT is required');
@@ -17,9 +17,9 @@ function setColorLUT(viewportId, segmentationId, colorLUTsIndex) {
17
17
  throw new Error(`viewport specific state for viewport ${viewportId} does not exist`);
18
18
  }
19
19
  segmentationRepresentations.forEach((segmentationRepresentation) => {
20
- segmentationRepresentation.config.colorLUTIndex = colorLUTsIndex;
20
+ segmentationRepresentation.colorLUTIndex = colorLUTsIndex;
21
21
  });
22
- triggerSegmentationModified(segmentationId);
22
+ triggerSegmentationRepresentationModified(viewportId, segmentationId);
23
23
  }
24
24
  function getSegmentIndexColor(viewportId, segmentationId, segmentIndex) {
25
25
  const representations = getSegmentationRepresentations(viewportId, {
@@ -29,7 +29,7 @@ function getSegmentIndexColor(viewportId, segmentationId, segmentIndex) {
29
29
  throw new Error(`segmentation representation with segmentationId ${segmentationId} does not exist`);
30
30
  }
31
31
  const representation = representations[0];
32
- const { colorLUTIndex } = representation.config;
32
+ const { colorLUTIndex } = representation;
33
33
  const colorLUT = _getColorLUT(colorLUTIndex);
34
34
  let colorValue = colorLUT[segmentIndex];
35
35
  if (!colorValue) {
@@ -45,6 +45,6 @@ function setSegmentIndexColor(viewportId, segmentationId, segmentIndex, color) {
45
45
  for (let i = 0; i < color.length; i++) {
46
46
  colorReference[i] = color[i];
47
47
  }
48
- triggerSegmentationModified(segmentationId);
48
+ triggerSegmentationRepresentationModified(viewportId, segmentationId);
49
49
  }
50
50
  export { getSegmentIndexColor, addColorLUT, setColorLUT, setSegmentIndexColor };
@@ -1,7 +1,8 @@
1
1
  import { getSegmentationRepresentation, getSegmentationRepresentations, } from '../getSegmentationRepresentation';
2
2
  import { setSegmentationRepresentationVisibility as _setSegmentationRepresentationVisibility } from '../setSegmentationRepresentationVisibility';
3
3
  import { getSegmentationRepresentationVisibility as _getSegmentationRepresentationVisibility } from '../getSegmentationRepresentationVisibility';
4
- import { triggerSegmentationModified } from '../triggerSegmentationEvents';
4
+ import { triggerSegmentationRenderBySegmentationId } from '../SegmentationRenderingEngine';
5
+ import { triggerSegmentationRepresentationModified } from '../triggerSegmentationEvents';
5
6
  function setSegmentationRepresentationVisibility(viewportId, specifier, visibility) {
6
7
  const representations = getSegmentationRepresentations(viewportId, specifier);
7
8
  if (!representations) {
@@ -13,7 +14,6 @@ function setSegmentationRepresentationVisibility(viewportId, specifier, visibili
13
14
  type: representation.type,
14
15
  }, visibility);
15
16
  });
16
- triggerSegmentationModified(specifier.segmentationId);
17
17
  }
18
18
  function getSegmentationRepresentationVisibility(viewportId, specifier) {
19
19
  return _getSegmentationRepresentationVisibility(viewportId, specifier);
@@ -24,12 +24,10 @@ function setSegmentIndexVisibility(viewportId, specifier, segmentIndex, visibili
24
24
  return;
25
25
  }
26
26
  representations.forEach((representation) => {
27
- const hiddenSegments = representation.segmentsHidden ?? new Set();
28
- visibility
29
- ? hiddenSegments.delete(segmentIndex)
30
- : hiddenSegments.add(segmentIndex);
27
+ representation.segments[segmentIndex].visible = visibility;
31
28
  });
32
- triggerSegmentationModified(specifier.segmentationId);
29
+ triggerSegmentationRenderBySegmentationId(specifier.segmentationId);
30
+ triggerSegmentationRepresentationModified(viewportId, specifier.segmentationId);
33
31
  }
34
32
  function getSegmentIndexVisibility(viewportId, specifier, segmentIndex) {
35
33
  const hiddenSegments = getHiddenSegmentIndices(viewportId, specifier);
@@ -40,6 +38,12 @@ function getHiddenSegmentIndices(viewportId, specifier) {
40
38
  if (!representation) {
41
39
  return new Set();
42
40
  }
43
- return representation.segmentsHidden ?? new Set();
41
+ const segmentsHidden = Object.entries(representation.segments).reduce((acc, [segmentIndex, segment]) => {
42
+ if (!segment.visible) {
43
+ acc.add(Number(segmentIndex));
44
+ }
45
+ return acc;
46
+ }, new Set());
47
+ return segmentsHidden;
44
48
  }
45
49
  export { setSegmentationRepresentationVisibility, getSegmentationRepresentationVisibility, setSegmentIndexVisibility, getSegmentIndexVisibility, getHiddenSegmentIndices, };
@@ -1,39 +1,25 @@
1
- import SegmentationRepresentations from '../../../enums/SegmentationRepresentations';
1
+ import type SegmentationRepresentations from '../../../enums/SegmentationRepresentations';
2
2
  import type { ContourStyle } from '../../../types/ContourTypes';
3
3
  import type { LabelmapStyle } from '../../../types/LabelmapTypes';
4
4
  import type { SurfaceStyle } from '../../../types/SurfaceTypes';
5
- import type { RepresentationStyle } from '../SegmentationStyle';
6
- declare function getStyle(specifier: {
5
+ type BaseSpecifier = {
7
6
  viewportId?: string;
8
7
  segmentationId?: string;
9
- type?: SegmentationRepresentations;
10
8
  segmentIndex?: number;
11
- }): {
12
- style: RepresentationStyle;
13
- renderInactiveSegmentations: boolean;
14
9
  };
15
- declare function getGlobalStyle(type: SegmentationRepresentations): RepresentationStyle;
16
- declare function setGlobalStyle(type: SegmentationRepresentations, style: RepresentationStyle): void;
17
- declare function setGlobalLabelmapStyle(style: LabelmapStyle): void;
18
- declare function setGlobalContourStyle(style: ContourStyle): void;
19
- declare function setGlobalSurfaceStyle(style: SurfaceStyle): void;
20
- declare function setSegmentationSpecificStyle(specifier: {
21
- segmentationId: string;
22
- type: SegmentationRepresentations;
23
- segmentIndex?: number;
24
- }, style: RepresentationStyle): void;
25
- declare function setLabelmapStyle(specifier: {
26
- segmentationId: string;
27
- }, style: LabelmapStyle): void;
28
- declare function setViewportSpecificStyleForType(specifier: {
29
- viewportId: string;
30
- type: SegmentationRepresentations;
31
- }, style: RepresentationStyle): void;
32
- declare function setViewportSpecificStyleForSegmentation(specifier: {
33
- viewportId: string;
34
- segmentationId: string;
35
- type: SegmentationRepresentations;
10
+ type SpecifierWithType<T extends SegmentationRepresentations> = BaseSpecifier & {
11
+ type: T;
12
+ };
13
+ type StyleForType<T extends SegmentationRepresentations> = T extends SegmentationRepresentations.Labelmap ? LabelmapStyle : T extends SegmentationRepresentations.Contour ? ContourStyle : T extends SegmentationRepresentations.Surface ? SurfaceStyle : never;
14
+ declare function getStyle<T extends SegmentationRepresentations>(specifier: SpecifierWithType<T>): StyleForType<T>;
15
+ declare function setStyle<T extends SegmentationRepresentations>(specifier: SpecifierWithType<T>, style: StyleForType<T>): void;
16
+ declare function setRenderInactiveSegmentations(viewportId: string, renderInactiveSegmentations: boolean): void;
17
+ declare function getRenderInactiveSegmentations(viewportId: string): boolean;
18
+ declare function resetToGlobalStyle(): void;
19
+ declare function hasCustomStyle(specifier: {
20
+ viewportId?: string;
21
+ segmentationId?: string;
22
+ type?: SegmentationRepresentations;
36
23
  segmentIndex?: number;
37
- }, style: RepresentationStyle): void;
38
- declare function setViewportRenderInactiveSegmentations(viewportId: string, renderInactiveSegmentations: boolean): void;
39
- export { getStyle, getGlobalStyle, setGlobalStyle, setGlobalLabelmapStyle, setGlobalContourStyle, setGlobalSurfaceStyle, setSegmentationSpecificStyle, setLabelmapStyle, setViewportSpecificStyleForType, setViewportSpecificStyleForSegmentation, setViewportRenderInactiveSegmentations, };
24
+ }): boolean;
25
+ export { getStyle, setStyle, setRenderInactiveSegmentations, getRenderInactiveSegmentations, resetToGlobalStyle, hasCustomStyle, };
@@ -1,48 +1,25 @@
1
- import SegmentationRepresentations from '../../../enums/SegmentationRepresentations';
2
1
  import { triggerSegmentationRender } from '../SegmentationRenderingEngine';
3
2
  import { segmentationStyle } from '../SegmentationStyle';
3
+ import { triggerSegmentationRepresentationModified } from '../triggerSegmentationEvents';
4
4
  function getStyle(specifier) {
5
5
  return segmentationStyle.getStyle(specifier);
6
6
  }
7
- function getGlobalStyle(type) {
8
- return segmentationStyle.getGlobalStyle(type);
7
+ function setStyle(specifier, style) {
8
+ segmentationStyle.setStyle(specifier, style);
9
+ triggerSegmentationRepresentationModified(specifier.viewportId, specifier.segmentationId, specifier.type);
9
10
  }
10
- function setGlobalStyle(type, style) {
11
- segmentationStyle.setGlobalStyle(type, style);
12
- triggerSegmentationRender();
13
- }
14
- function setGlobalLabelmapStyle(style) {
15
- segmentationStyle.setGlobalLabelmapStyle(style);
16
- triggerSegmentationRender();
11
+ function setRenderInactiveSegmentations(viewportId, renderInactiveSegmentations) {
12
+ segmentationStyle.setRenderInactiveSegmentations(viewportId, renderInactiveSegmentations);
13
+ triggerSegmentationRender(viewportId);
17
14
  }
18
- function setGlobalContourStyle(style) {
19
- segmentationStyle.setGlobalContourStyle(style);
20
- triggerSegmentationRender();
15
+ function getRenderInactiveSegmentations(viewportId) {
16
+ return segmentationStyle.getRenderInactiveSegmentations(viewportId);
21
17
  }
22
- function setGlobalSurfaceStyle(style) {
23
- segmentationStyle.setGlobalSurfaceStyle(style);
18
+ function resetToGlobalStyle() {
19
+ segmentationStyle.resetToGlobalStyle();
24
20
  triggerSegmentationRender();
25
21
  }
26
- function setSegmentationSpecificStyle(specifier, style) {
27
- segmentationStyle.setSegmentationSpecificStyle(specifier, style);
28
- triggerSegmentationRender();
29
- }
30
- function setLabelmapStyle(specifier, style) {
31
- setSegmentationSpecificStyle({
32
- ...specifier,
33
- type: SegmentationRepresentations.Labelmap,
34
- }, style);
35
- }
36
- function setViewportSpecificStyleForType(specifier, style) {
37
- segmentationStyle.setViewportSpecificStyleForType(specifier, style);
38
- triggerSegmentationRender(specifier.viewportId);
39
- }
40
- function setViewportSpecificStyleForSegmentation(specifier, style) {
41
- segmentationStyle.setViewportSpecificStyleForSegmentation(specifier, style);
42
- triggerSegmentationRender(specifier.viewportId);
43
- }
44
- function setViewportRenderInactiveSegmentations(viewportId, renderInactiveSegmentations) {
45
- segmentationStyle.setViewportRenderInactiveSegmentations(viewportId, renderInactiveSegmentations);
46
- triggerSegmentationRender(viewportId);
22
+ function hasCustomStyle(specifier) {
23
+ return segmentationStyle.hasCustomStyle(specifier);
47
24
  }
48
- export { getStyle, getGlobalStyle, setGlobalStyle, setGlobalLabelmapStyle, setGlobalContourStyle, setGlobalSurfaceStyle, setSegmentationSpecificStyle, setLabelmapStyle, setViewportSpecificStyleForType, setViewportSpecificStyleForSegmentation, setViewportRenderInactiveSegmentations, };
25
+ export { getStyle, setStyle, setRenderInactiveSegmentations, getRenderInactiveSegmentations, resetToGlobalStyle, hasCustomStyle, };
@@ -1 +1 @@
1
- export declare function triggerSegmentationModified(segmentationId?: string): void;
1
+ export declare function triggerSegmentationModified(segmentationId: string): void;
@@ -1,18 +1,8 @@
1
1
  import { triggerEvent, eventTarget } from '@cornerstonejs/core';
2
2
  import { Events } from '../../../enums';
3
- import { getSegmentations } from '../getSegmentations';
4
3
  export function triggerSegmentationModified(segmentationId) {
5
- let segmentationIds;
6
- if (segmentationId) {
7
- segmentationIds = [segmentationId];
8
- }
9
- else {
10
- segmentationIds = getSegmentations().map(({ segmentationId }) => segmentationId);
11
- }
12
- segmentationIds.forEach((segmentationId) => {
13
- const eventDetail = {
14
- segmentationId,
15
- };
16
- triggerEvent(eventTarget, Events.SEGMENTATION_MODIFIED, eventDetail);
17
- });
4
+ const eventDetail = {
5
+ segmentationId,
6
+ };
7
+ triggerEvent(eventTarget, Events.SEGMENTATION_MODIFIED, eventDetail);
18
8
  }
@@ -0,0 +1,2 @@
1
+ import type { SegmentationRepresentations } from '../../../enums';
2
+ export declare function triggerSegmentationRepresentationModified(viewportId: string, segmentationId: string, type?: SegmentationRepresentations): void;
@@ -0,0 +1,10 @@
1
+ import { triggerEvent, eventTarget } from '@cornerstonejs/core';
2
+ import { Events } from '../../../enums';
3
+ export function triggerSegmentationRepresentationModified(viewportId, segmentationId, type) {
4
+ const eventDetail = {
5
+ segmentationId,
6
+ type,
7
+ viewportId,
8
+ };
9
+ triggerEvent(eventTarget, Events.SEGMENTATION_REPRESENTATION_MODIFIED, eventDetail);
10
+ }
@@ -0,0 +1,2 @@
1
+ import type { SegmentationRepresentations } from '../../../enums';
2
+ export declare function triggerSegmentationRepresentationRemoved(viewportId: string, segmentationId: string, type: SegmentationRepresentations): void;
@@ -0,0 +1,10 @@
1
+ import { triggerEvent, eventTarget } from '@cornerstonejs/core';
2
+ import { Events } from '../../../enums';
3
+ export function triggerSegmentationRepresentationRemoved(viewportId, segmentationId, type) {
4
+ const eventDetail = {
5
+ viewportId,
6
+ segmentationId,
7
+ type,
8
+ };
9
+ triggerEvent(eventTarget, Events.SEGMENTATION_REPRESENTATION_REMOVED, eventDetail);
10
+ }
@@ -2,6 +2,8 @@ import { getSegmentation } from './getSegmentation';
2
2
  export function getActiveSegmentIndex(segmentationId) {
3
3
  const segmentation = getSegmentation(segmentationId);
4
4
  if (segmentation) {
5
- return segmentation.activeSegmentIndex;
5
+ const activeSegmentIndex = Object.keys(segmentation.segments).find((segmentIndex) => segmentation.segments[segmentIndex].active);
6
+ return activeSegmentIndex ? Number(activeSegmentIndex) : undefined;
6
7
  }
8
+ return undefined;
7
9
  }
@@ -1,4 +1,4 @@
1
1
  import { segmentationStyle } from './SegmentationStyle';
2
2
  export function getGlobalStyle(type) {
3
- return segmentationStyle.getGlobalStyle(type);
3
+ return segmentationStyle.getStyle({ type });
4
4
  }
@@ -1,5 +1,4 @@
1
1
  import { cache } from '@cornerstonejs/core';
2
- import { SegmentationRepresentations } from '../../../enums';
3
2
  import { getSegmentation } from '../getSegmentation';
4
3
  import { triggerSegmentationDataModified } from '../triggerSegmentationEvents';
5
4
  export function clearSegmentValue(segmentationId, segmentIndex) {
@@ -0,0 +1,5 @@
1
+ import type { SegmentationRepresentations } from '../../../enums';
2
+ export declare function internalGetHiddenSegmentIndices(viewportId: any, specifier: {
3
+ segmentationId: string;
4
+ type: SegmentationRepresentations;
5
+ }): Set<unknown>;
@@ -0,0 +1,14 @@
1
+ import { getSegmentationRepresentation } from '../getSegmentationRepresentation';
2
+ export function internalGetHiddenSegmentIndices(viewportId, specifier) {
3
+ const representation = getSegmentationRepresentation(viewportId, specifier);
4
+ if (!representation) {
5
+ return new Set();
6
+ }
7
+ const segmentsHidden = Object.entries(representation.segments).reduce((acc, [segmentIndex, segment]) => {
8
+ if (!segment.visible) {
9
+ acc.add(Number(segmentIndex));
10
+ }
11
+ return acc;
12
+ }, new Set());
13
+ return segmentsHidden;
14
+ }
@@ -1,6 +1,6 @@
1
1
  import { SegmentationRepresentations } from '../../../enums';
2
2
  function normalizeSegmentationInput(segmentationInput) {
3
- const { segmentationId, representation } = segmentationInput;
3
+ const { segmentationId, representation, config } = segmentationInput;
4
4
  const { type, data: inputData } = representation;
5
5
  const data = inputData ? { ...inputData } : {};
6
6
  if (!data) {
@@ -11,13 +11,20 @@ function normalizeSegmentationInput(segmentationInput) {
11
11
  contourData.geometryIds = contourData.geometryIds ?? [];
12
12
  contourData.annotationUIDsMap = contourData.annotationUIDsMap ?? new Map();
13
13
  }
14
+ const normalizedSegments = {};
15
+ Object.entries(config.segments).forEach(([segmentIndex, segment]) => {
16
+ normalizedSegments[segmentIndex] = {
17
+ segmentIndex: Number(segmentIndex),
18
+ label: segment.label ?? `Segment ${segmentIndex}`,
19
+ locked: segment.locked ?? false,
20
+ cachedStats: segment.cachedStats ?? {},
21
+ active: segment.active ?? false,
22
+ };
23
+ });
14
24
  return {
15
25
  segmentationId,
16
- cachedStats: {},
17
- segmentLabels: {},
18
- label: null,
19
- segmentsLocked: new Set(),
20
- activeSegmentIndex: 1,
26
+ label: config.label ?? null,
27
+ segments: normalizedSegments,
21
28
  representationData: {
22
29
  [type]: {
23
30
  ...data,
@@ -1,6 +1,7 @@
1
1
  import { removeContourRepresentation, removeLabelmapRepresentation, removeSegmentationRepresentation, removeSurfaceRepresentation, removeSegmentationRepresentations, removeAllSegmentationRepresentations } from './removeSegmentationRepresentations';
2
2
  import { addContourRepresentationToViewport, addContourRepresentationToViewportMap, addSurfaceRepresentationToViewport, addSurfaceRepresentationToViewportMap, addLabelmapRepresentationToViewport, addLabelmapRepresentationToViewportMap, addSegmentationRepresentations } from './addSegmentationRepresentationsToViewport';
3
3
  import { addSegmentations } from './addSegmentations';
4
+ import { updateSegmentations } from './updateSegmentations';
4
5
  import * as activeSegmentation from './activeSegmentation';
5
6
  import * as segmentLocking from './segmentLocking';
6
7
  import * as state from './segmentationState';
@@ -12,10 +13,11 @@ import { computeVolumeLabelmapFromStack } from './helpers/computeVolumeLabelmapF
12
13
  import * as polySegManager from './polySeg';
13
14
  import { clearSegmentValue } from './helpers/clearSegmentValue';
14
15
  import { convertVolumeToStackLabelmap } from './helpers/computeStackLabelmapFromVolume';
16
+ import { removeSegment } from './removeSegment';
15
17
  declare const helpers: {
16
18
  clearSegmentValue: typeof clearSegmentValue;
17
19
  convertStackToVolumeLabelmap: typeof convertStackToVolumeLabelmap;
18
20
  computeVolumeLabelmapFromStack: typeof computeVolumeLabelmapFromStack;
19
21
  convertVolumeToStackLabelmap: typeof convertVolumeToStackLabelmap;
20
22
  };
21
- export { removeSegmentationRepresentation, removeContourRepresentation, removeLabelmapRepresentation, removeSurfaceRepresentation, removeSegmentationRepresentations, addLabelmapRepresentationToViewport, addLabelmapRepresentationToViewportMap, addSegmentationRepresentations, removeAllSegmentationRepresentations, addContourRepresentationToViewport, addContourRepresentationToViewportMap, addSurfaceRepresentationToViewport, addSurfaceRepresentationToViewportMap, addSegmentations, state, activeSegmentation, segmentLocking, config, segmentIndex, triggerSegmentationEvents, helpers, polySegManager as polySeg, };
23
+ export { removeSegmentationRepresentation, removeContourRepresentation, removeLabelmapRepresentation, removeSurfaceRepresentation, removeSegmentationRepresentations, addLabelmapRepresentationToViewport, addLabelmapRepresentationToViewportMap, addSegmentationRepresentations, removeAllSegmentationRepresentations, addContourRepresentationToViewport, addContourRepresentationToViewportMap, addSurfaceRepresentationToViewport, addSurfaceRepresentationToViewportMap, addSegmentations, updateSegmentations, state, activeSegmentation, segmentLocking, config, segmentIndex, triggerSegmentationEvents, helpers, polySegManager as polySeg, removeSegment, };
@@ -1,6 +1,7 @@
1
1
  import { removeContourRepresentation, removeLabelmapRepresentation, removeSegmentationRepresentation, removeSurfaceRepresentation, removeSegmentationRepresentations, removeAllSegmentationRepresentations, } from './removeSegmentationRepresentations';
2
2
  import { addContourRepresentationToViewport, addContourRepresentationToViewportMap, addSurfaceRepresentationToViewport, addSurfaceRepresentationToViewportMap, addLabelmapRepresentationToViewport, addLabelmapRepresentationToViewportMap, addSegmentationRepresentations, } from './addSegmentationRepresentationsToViewport';
3
3
  import { addSegmentations } from './addSegmentations';
4
+ import { updateSegmentations } from './updateSegmentations';
4
5
  import * as activeSegmentation from './activeSegmentation';
5
6
  import * as segmentLocking from './segmentLocking';
6
7
  import * as state from './segmentationState';
@@ -12,10 +13,11 @@ import { computeVolumeLabelmapFromStack } from './helpers/computeVolumeLabelmapF
12
13
  import * as polySegManager from './polySeg';
13
14
  import { clearSegmentValue } from './helpers/clearSegmentValue';
14
15
  import { convertVolumeToStackLabelmap } from './helpers/computeStackLabelmapFromVolume';
16
+ import { removeSegment } from './removeSegment';
15
17
  const helpers = {
16
18
  clearSegmentValue,
17
19
  convertStackToVolumeLabelmap,
18
20
  computeVolumeLabelmapFromStack,
19
21
  convertVolumeToStackLabelmap,
20
22
  };
21
- export { removeSegmentationRepresentation, removeContourRepresentation, removeLabelmapRepresentation, removeSurfaceRepresentation, removeSegmentationRepresentations, addLabelmapRepresentationToViewport, addLabelmapRepresentationToViewportMap, addSegmentationRepresentations, removeAllSegmentationRepresentations, addContourRepresentationToViewport, addContourRepresentationToViewportMap, addSurfaceRepresentationToViewport, addSurfaceRepresentationToViewportMap, addSegmentations, state, activeSegmentation, segmentLocking, config, segmentIndex, triggerSegmentationEvents, helpers, polySegManager as polySeg, };
23
+ export { removeSegmentationRepresentation, removeContourRepresentation, removeLabelmapRepresentation, removeSurfaceRepresentation, removeSegmentationRepresentations, addLabelmapRepresentationToViewport, addLabelmapRepresentationToViewportMap, addSegmentationRepresentations, removeAllSegmentationRepresentations, addContourRepresentationToViewport, addContourRepresentationToViewportMap, addSurfaceRepresentationToViewport, addSurfaceRepresentationToViewportMap, addSegmentations, updateSegmentations, state, activeSegmentation, segmentLocking, config, segmentIndex, triggerSegmentationEvents, helpers, polySegManager as polySeg, removeSegment, };
@@ -18,15 +18,16 @@ function internalAddSegmentationRepresentation(viewportId, representationInput)
18
18
  triggerSegmentationModified(segmentationId);
19
19
  }
20
20
  function getColorLUTIndex(config) {
21
- const colorLUT = config?.colorLUT;
22
- const nextIndex = getNextColorLUTIndex();
23
- const colorLUTToAdd = Array.isArray(colorLUT)
24
- ? colorLUT
21
+ const { colorLUTOrIndex } = config || {};
22
+ const isIndexProvided = typeof colorLUTOrIndex === 'number';
23
+ const selectedColorLUT = isIndexProvided
24
+ ? getColorLUT(colorLUTOrIndex)
25
25
  : CORNERSTONE_COLOR_LUT;
26
- addColorLUT(colorLUTToAdd, nextIndex);
27
- const colorLUTIndex = nextIndex;
28
- if (!getColorLUT(colorLUTIndex)) {
29
- throw new Error(`Color LUT with index ${colorLUTIndex} not found`);
26
+ const colorLUTIndex = isIndexProvided
27
+ ? colorLUTOrIndex
28
+ : getNextColorLUTIndex();
29
+ if (!isIndexProvided) {
30
+ addColorLUT(selectedColorLUT, colorLUTIndex);
30
31
  }
31
32
  return colorLUTIndex;
32
33
  }
@@ -37,7 +37,7 @@ export async function computeContourData(segmentationId, options = {}) {
37
37
  }
38
38
  const { viewport } = options;
39
39
  const annotationUIDsMap = createAndAddContourSegmentationsFromClippedSurfaces(rawContourData, viewport, segmentationId);
40
- segmentationStyle.setSegmentationSpecificStyle({ segmentationId, type: SegmentationRepresentations.Contour }, {
40
+ segmentationStyle.setStyle({ segmentationId, type: SegmentationRepresentations.Contour }, {
41
41
  fillAlpha: 0,
42
42
  });
43
43
  return {
@@ -4,7 +4,6 @@ import addRepresentationData from '../internalAddRepresentationData';
4
4
  import { triggerSegmentationModified } from '../triggerSegmentationEvents';
5
5
  import debounce from '../../../utilities/debounce';
6
6
  import { registerPolySegWorker } from './registerPolySegWorker';
7
- import { defaultSegmentationStateManager } from '../SegmentationStateManager';
8
7
  const computedRepresentations = new Map();
9
8
  async function computeAndAddRepresentation(segmentationId, type, computeFunction, updateFunction, onComputationComplete) {
10
9
  registerPolySegWorker();
@@ -0,0 +1,3 @@
1
+ export declare function removeSegment(segmentationId: string, segmentIndex: number, options?: {
2
+ setNextSegmentAsActive: boolean;
3
+ }): void;
@@ -0,0 +1,50 @@
1
+ import { getActiveSegmentIndex } from './getActiveSegmentIndex';
2
+ import { getSegmentation } from './getSegmentation';
3
+ import { getSegmentationRepresentations } from './getSegmentationRepresentation';
4
+ import { getViewportIdsWithSegmentation } from './getViewportIdsWithSegmentation';
5
+ import { clearSegmentValue } from './helpers/clearSegmentValue';
6
+ import { setActiveSegmentIndex } from './segmentIndex';
7
+ import { updateSegmentations } from './updateSegmentations';
8
+ export function removeSegment(segmentationId, segmentIndex, options = {
9
+ setNextSegmentAsActive: true,
10
+ }) {
11
+ clearSegmentValue(segmentationId, segmentIndex);
12
+ const isThisSegmentActive = getActiveSegmentIndex(segmentationId) === segmentIndex;
13
+ const segmentation = getSegmentation(segmentationId);
14
+ const { segments } = segmentation;
15
+ delete segments[segmentIndex];
16
+ const updatedSegments = {
17
+ ...segments,
18
+ };
19
+ updateSegmentations([
20
+ {
21
+ segmentationId,
22
+ payload: {
23
+ segments: updatedSegments,
24
+ },
25
+ },
26
+ ]);
27
+ if (isThisSegmentActive && options.setNextSegmentAsActive) {
28
+ const segmentIndices = Object.keys(segments)
29
+ .map(Number)
30
+ .sort((a, b) => a - b);
31
+ const currentIndex = segmentIndices.indexOf(segmentIndex);
32
+ const nextSegmentIndex = segmentIndices[currentIndex + 1];
33
+ const previousSegmentIndex = segmentIndices[currentIndex - 1];
34
+ if (nextSegmentIndex !== undefined) {
35
+ setActiveSegmentIndex(segmentationId, nextSegmentIndex);
36
+ }
37
+ else if (previousSegmentIndex !== undefined) {
38
+ setActiveSegmentIndex(segmentationId, previousSegmentIndex);
39
+ }
40
+ }
41
+ const viewportIds = getViewportIdsWithSegmentation(segmentationId);
42
+ viewportIds.forEach((viewportId) => {
43
+ const representations = getSegmentationRepresentations(viewportId, {
44
+ segmentationId,
45
+ });
46
+ representations.forEach((representation) => {
47
+ delete representation.segments[segmentIndex];
48
+ });
49
+ });
50
+ }
@@ -4,7 +4,7 @@ declare function removeSegmentationRepresentation(viewportId: string, specifier:
4
4
  type: SegmentationRepresentations;
5
5
  }, immediate?: boolean): void;
6
6
  declare function removeSegmentationRepresentations(viewportId: string, specifier: {
7
- segmentationId: string;
7
+ segmentationId?: string;
8
8
  type?: SegmentationRepresentations;
9
9
  }, immediate?: boolean): void;
10
10
  declare function removeAllSegmentationRepresentations(): void;
@@ -14,11 +14,11 @@ function removeSegmentationRepresentation(viewportId, specifier, immediate) {
14
14
  }
15
15
  function removeSegmentationRepresentations(viewportId, specifier, immediate) {
16
16
  const { segmentationId, type } = specifier;
17
+ _removeRepresentation(viewportId, segmentationId, type, immediate);
17
18
  defaultSegmentationStateManager.removeSegmentationRepresentations(viewportId, {
18
19
  segmentationId,
19
20
  type,
20
21
  });
21
- _removeRepresentation(viewportId, segmentationId, type, immediate);
22
22
  }
23
23
  function removeAllSegmentationRepresentations() {
24
24
  const state = defaultSegmentationStateManager.getAllViewportSegmentationRepresentations();
@@ -56,19 +56,17 @@ function _removeRepresentation(viewportId, segmentationId, type, immediate) {
56
56
  type,
57
57
  });
58
58
  representations.forEach((representation) => {
59
- if (representation.type === type) {
60
- if (type === SegmentationRepresentations.Labelmap) {
61
- labelmapDisplay.removeRepresentation(viewportId, segmentationId, immediate);
62
- }
63
- else if (type === SegmentationRepresentations.Contour) {
64
- contourDisplay.removeRepresentation(viewportId, segmentationId, immediate);
65
- }
66
- else {
67
- throw new Error(`The representation ${type} is not supported yet`);
68
- }
59
+ if (representation.type === SegmentationRepresentations.Labelmap) {
60
+ labelmapDisplay.removeRepresentation(viewportId, segmentationId, immediate);
61
+ }
62
+ else if (representation.type === SegmentationRepresentations.Contour) {
63
+ contourDisplay.removeRepresentation(viewportId, segmentationId, immediate);
64
+ }
65
+ else {
66
+ throw new Error(`The representation ${representation.type} is not supported yet`);
69
67
  }
70
68
  });
71
- const { viewport } = getEnabledElementByViewportId(viewportId);
69
+ const { viewport } = getEnabledElementByViewportId(viewportId) || {};
72
70
  if (viewport) {
73
71
  viewport.render();
74
72
  }
@@ -4,17 +4,33 @@ import { getSegmentation } from './getSegmentation';
4
4
  import { getViewportIdsWithSegmentation } from './getViewportIdsWithSegmentation';
5
5
  import { triggerSegmentationModified } from './triggerSegmentationEvents';
6
6
  import { getActiveSegmentIndex } from './getActiveSegmentIndex';
7
+ import { getSegmentationRepresentations } from './getSegmentationRepresentation';
7
8
  function setActiveSegmentIndex(segmentationId, segmentIndex) {
8
9
  const segmentation = getSegmentation(segmentationId);
9
10
  if (typeof segmentIndex === 'string') {
10
11
  console.warn('segmentIndex is a string, converting to number');
11
12
  segmentIndex = Number(segmentIndex);
12
13
  }
13
- if (segmentation?.activeSegmentIndex !== segmentIndex) {
14
- segmentation.activeSegmentIndex = segmentIndex;
14
+ Object.values(segmentation.segments).forEach((segment) => {
15
+ segment.active = false;
16
+ });
17
+ if (segmentation.segments[segmentIndex].active !== true) {
18
+ segmentation.segments[segmentIndex].active = true;
15
19
  triggerSegmentationModified(segmentationId);
16
20
  }
17
21
  const viewportIds = getViewportIdsWithSegmentation(segmentationId);
22
+ viewportIds.forEach((viewportId) => {
23
+ const representations = getSegmentationRepresentations(viewportId, {
24
+ segmentationId,
25
+ });
26
+ representations.forEach((representation) => {
27
+ if (!representation.segments[segmentIndex]) {
28
+ representation.segments[segmentIndex] = {
29
+ visible: true,
30
+ };
31
+ }
32
+ });
33
+ });
18
34
  viewportIds.forEach((viewportId) => {
19
35
  const toolGroup = getToolGroupForViewport(viewportId);
20
36
  invalidateBrushCursor(toolGroup.id);
@@ -5,21 +5,16 @@ function isSegmentIndexLocked(segmentationId, segmentIndex) {
5
5
  if (!segmentation) {
6
6
  throw new Error(`No segmentation state found for ${segmentationId}`);
7
7
  }
8
- const { segmentsLocked } = segmentation;
9
- return segmentsLocked.has(segmentIndex);
8
+ const { segments } = segmentation;
9
+ return segments[segmentIndex].locked;
10
10
  }
11
11
  function setSegmentIndexLocked(segmentationId, segmentIndex, locked = true) {
12
12
  const segmentation = getSegmentation(segmentationId);
13
13
  if (!segmentation) {
14
14
  throw new Error(`No segmentation state found for ${segmentationId}`);
15
15
  }
16
- const { segmentsLocked } = segmentation;
17
- if (locked) {
18
- segmentsLocked.add(segmentIndex);
19
- }
20
- else {
21
- segmentsLocked.delete(segmentIndex);
22
- }
16
+ const { segments } = segmentation;
17
+ segments[segmentIndex].locked = locked;
23
18
  triggerSegmentationModified(segmentationId);
24
19
  }
25
20
  function getLockedSegmentIndices(segmentationId) {
@@ -27,7 +22,8 @@ function getLockedSegmentIndices(segmentationId) {
27
22
  if (!segmentation) {
28
23
  throw new Error(`No segmentation state found for ${segmentationId}`);
29
24
  }
30
- const { segmentsLocked } = segmentation;
31
- return Array.from(segmentsLocked);
25
+ const { segments } = segmentation;
26
+ const lockedSegmentIndices = Object.keys(segments).filter((segmentIndex) => segments[segmentIndex].locked);
27
+ return lockedSegmentIndices.map((segmentIndex) => parseInt(segmentIndex));
32
28
  }
33
29
  export { isSegmentIndexLocked, setSegmentIndexLocked, getLockedSegmentIndices };