@cornerstonejs/tools 4.22.13 → 5.0.0

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 (225) hide show
  1. package/dist/esm/config.d.ts +4 -0
  2. package/dist/esm/drawingSvg/drawPath.d.ts +3 -0
  3. package/dist/esm/drawingSvg/drawPath.js +4 -1
  4. package/dist/esm/eventListeners/keyboard/keyDownListener.js +2 -2
  5. package/dist/esm/eventListeners/mouse/getMouseEventPoints.d.ts +1 -1
  6. package/dist/esm/eventListeners/mouse/getMouseEventPoints.js +19 -1
  7. package/dist/esm/eventListeners/mouse/mouseDoubleClickListener.js +8 -1
  8. package/dist/esm/eventListeners/mouse/mouseDownListener.js +37 -5
  9. package/dist/esm/eventListeners/mouse/mouseMoveListener.js +3 -0
  10. package/dist/esm/eventListeners/segmentation/imageChangeEventListener.js +60 -92
  11. package/dist/esm/eventListeners/segmentation/labelmap/onLabelmapSegmentationDataModified.js +49 -21
  12. package/dist/esm/eventListeners/segmentation/labelmap/performStackLabelmapUpdate.js +7 -13
  13. package/dist/esm/eventListeners/segmentation/labelmap/performVolumeLabelmapUpdate.js +44 -18
  14. package/dist/esm/eventListeners/touch/getTouchEventPoints.js +27 -4
  15. package/dist/esm/eventListeners/touch/touchStartListener.js +27 -9
  16. package/dist/esm/eventListeners/wheel/wheelListener.js +5 -1
  17. package/dist/esm/init.js +2 -0
  18. package/dist/esm/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.js +10 -4
  19. package/dist/esm/stateManagement/segmentation/SegmentationRenderingEngine.js +23 -20
  20. package/dist/esm/stateManagement/segmentation/SegmentationRepresentationDisplayRegistry.d.ts +12 -0
  21. package/dist/esm/stateManagement/segmentation/SegmentationRepresentationDisplayRegistry.js +7 -0
  22. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.d.ts +1 -11
  23. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.js +28 -166
  24. package/dist/esm/stateManagement/segmentation/addColorLUT.js +7 -1
  25. package/dist/esm/stateManagement/segmentation/getCurrentLabelmapImageIdForViewport.js +16 -1
  26. package/dist/esm/stateManagement/segmentation/helpers/clearSegmentValue.js +9 -7
  27. package/dist/esm/stateManagement/segmentation/helpers/getSegmentationActor.d.ts +1 -1
  28. package/dist/esm/stateManagement/segmentation/helpers/getSegmentationActor.js +3 -2
  29. package/dist/esm/stateManagement/segmentation/helpers/getViewportLabelmapRenderMode.d.ts +5 -0
  30. package/dist/esm/stateManagement/segmentation/helpers/getViewportLabelmapRenderMode.js +58 -0
  31. package/dist/esm/stateManagement/segmentation/helpers/labelmapImageMapperSupport.d.ts +52 -0
  32. package/dist/esm/stateManagement/segmentation/helpers/labelmapImageMapperSupport.js +246 -0
  33. package/dist/esm/stateManagement/segmentation/helpers/labelmapSegmentationState.d.ts +1 -0
  34. package/dist/esm/stateManagement/segmentation/helpers/labelmapSegmentationState.js +1 -0
  35. package/dist/esm/stateManagement/segmentation/helpers/normalizeSegmentationInput.js +11 -1
  36. package/dist/esm/stateManagement/segmentation/internalAddSegmentationRepresentation.js +3 -3
  37. package/dist/esm/stateManagement/segmentation/labelmapModel/index.d.ts +9 -0
  38. package/dist/esm/stateManagement/segmentation/labelmapModel/index.js +7 -0
  39. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapEditTransaction.d.ts +54 -0
  40. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapEditTransaction.js +224 -0
  41. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageIdMapping.d.ts +6 -0
  42. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageIdMapping.js +39 -0
  43. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageReferenceResolver.d.ts +23 -0
  44. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageReferenceResolver.js +269 -0
  45. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLayerStore.d.ts +15 -0
  46. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLayerStore.js +160 -0
  47. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLegacyAdapter.d.ts +4 -0
  48. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLegacyAdapter.js +42 -0
  49. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapSegmentBindings.d.ts +11 -0
  50. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapSegmentBindings.js +73 -0
  51. package/dist/esm/stateManagement/segmentation/labelmapModel/normalizeLabelmapSegmentationData.d.ts +17 -0
  52. package/dist/esm/stateManagement/segmentation/labelmapModel/normalizeLabelmapSegmentationData.js +75 -0
  53. package/dist/esm/stateManagement/segmentation/labelmapModel/privateLabelmap.d.ts +5 -0
  54. package/dist/esm/stateManagement/segmentation/labelmapModel/privateLabelmap.js +106 -0
  55. package/dist/esm/stateManagement/segmentation/models/SegmentModel.d.ts +11 -0
  56. package/dist/esm/stateManagement/segmentation/models/SegmentModel.js +19 -0
  57. package/dist/esm/stateManagement/segmentation/models/SegmentationModel.d.ts +12 -0
  58. package/dist/esm/stateManagement/segmentation/models/SegmentationModel.js +23 -0
  59. package/dist/esm/stateManagement/segmentation/removeSegmentationRepresentations.js +6 -10
  60. package/dist/esm/stateManagement/segmentation/segmentIndex.js +24 -0
  61. package/dist/esm/stateManagement/segmentation/segmentationEventManager.js +2 -9
  62. package/dist/esm/stateManagement/segmentation/segmentationState.d.ts +2 -1
  63. package/dist/esm/stateManagement/segmentation/segmentationState.js +4 -1
  64. package/dist/esm/store/state.js +2 -1
  65. package/dist/esm/synchronizers/callbacks/imageSliceSyncCallback.js +12 -3
  66. package/dist/esm/synchronizers/callbacks/presentationViewSyncCallback.js +5 -2
  67. package/dist/esm/synchronizers/callbacks/zoomPanSyncCallback.js +51 -3
  68. package/dist/esm/tools/AdvancedMagnifyTool.js +1 -1
  69. package/dist/esm/tools/CrosshairsTool.js +5 -5
  70. package/dist/esm/tools/OrientationControllerTool.js +1 -1
  71. package/dist/esm/tools/OrientationMarkerTool.js +4 -4
  72. package/dist/esm/tools/PanTool.js +26 -3
  73. package/dist/esm/tools/PlanarRotateTool.js +19 -4
  74. package/dist/esm/tools/ReferenceCursors.js +7 -1
  75. package/dist/esm/tools/SculptorTool/CircleSculptCursor.js +1 -1
  76. package/dist/esm/tools/TrackballRotateTool.js +3 -2
  77. package/dist/esm/tools/VolumeCroppingTool.js +3 -2
  78. package/dist/esm/tools/WindowLevelTool.d.ts +2 -1
  79. package/dist/esm/tools/WindowLevelTool.js +48 -4
  80. package/dist/esm/tools/ZoomTool.d.ts +8 -0
  81. package/dist/esm/tools/ZoomTool.js +92 -11
  82. package/dist/esm/tools/annotation/AngleTool.js +33 -31
  83. package/dist/esm/tools/annotation/ArrowAnnotateTool.js +30 -28
  84. package/dist/esm/tools/annotation/BidirectionalTool.js +51 -49
  85. package/dist/esm/tools/annotation/CircleROITool.js +49 -44
  86. package/dist/esm/tools/annotation/CobbAngleTool.js +1 -1
  87. package/dist/esm/tools/annotation/DragProbeTool.js +1 -1
  88. package/dist/esm/tools/annotation/ETDRSGridTool.js +1 -1
  89. package/dist/esm/tools/annotation/EllipticalROITool.js +42 -37
  90. package/dist/esm/tools/annotation/HeightTool.js +1 -1
  91. package/dist/esm/tools/annotation/KeyImageTool.js +11 -11
  92. package/dist/esm/tools/annotation/LabelTool.js +37 -35
  93. package/dist/esm/tools/annotation/LengthTool.js +35 -33
  94. package/dist/esm/tools/annotation/LivewireContourSegmentationTool.js +6 -4
  95. package/dist/esm/tools/annotation/LivewireContourTool.js +1 -1
  96. package/dist/esm/tools/annotation/PlanarFreehandContourSegmentationTool.js +6 -4
  97. package/dist/esm/tools/annotation/PlanarFreehandROITool.js +1 -1
  98. package/dist/esm/tools/annotation/ProbeTool.js +51 -46
  99. package/dist/esm/tools/annotation/RectangleROITool.js +42 -37
  100. package/dist/esm/tools/annotation/RegionSegmentPlusTool.js +1 -1
  101. package/dist/esm/tools/annotation/RegionSegmentTool.js +1 -1
  102. package/dist/esm/tools/annotation/SplineContourSegmentationTool.js +1 -1
  103. package/dist/esm/tools/annotation/SplineROITool.js +51 -49
  104. package/dist/esm/tools/annotation/UltrasoundDirectionalTool.js +1 -1
  105. package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/UltrasoundPleuraBLineTool.js +57 -55
  106. package/dist/esm/tools/annotation/VideoRedactionTool.js +1 -1
  107. package/dist/esm/tools/base/AnnotationDisplayTool.js +9 -6
  108. package/dist/esm/tools/base/AnnotationTool.js +2 -1
  109. package/dist/esm/tools/base/BaseTool.js +16 -10
  110. package/dist/esm/tools/base/ContourSegmentationBaseTool.js +1 -1
  111. package/dist/esm/tools/base/GrowCutBaseTool.js +2 -2
  112. package/dist/esm/tools/displayTools/Labelmap/addLabelmapToElement.d.ts +2 -4
  113. package/dist/esm/tools/displayTools/Labelmap/addLabelmapToElement.js +15 -85
  114. package/dist/esm/tools/displayTools/Labelmap/labelmapActorStyle.d.ts +5 -0
  115. package/dist/esm/tools/displayTools/Labelmap/labelmapActorStyle.js +191 -0
  116. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.d.ts +4 -3
  117. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.js +48 -209
  118. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/createLabelmapRenderPlan.d.ts +3 -0
  119. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/createLabelmapRenderPlan.js +51 -0
  120. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/index.d.ts +4 -0
  121. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/index.js +3 -0
  122. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/legacyVolumePlan.d.ts +14 -0
  123. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/legacyVolumePlan.js +143 -0
  124. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/planarGenericVolumeLabelmap.d.ts +40 -0
  125. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/planarGenericVolumeLabelmap.js +79 -0
  126. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/removeLabelmapRepresentationFromViewport.d.ts +3 -0
  127. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/removeLabelmapRepresentationFromViewport.js +18 -0
  128. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/resolveLabelmapRenderPlan.d.ts +9 -0
  129. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/resolveLabelmapRenderPlan.js +56 -0
  130. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/stackImagePlan.d.ts +11 -0
  131. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/stackImagePlan.js +35 -0
  132. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/types.d.ts +48 -0
  133. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/types.js +0 -0
  134. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/volumeSliceImageMapperPlan.d.ts +13 -0
  135. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/volumeSliceImageMapperPlan.js +34 -0
  136. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan.d.ts +2 -0
  137. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan.js +1 -0
  138. package/dist/esm/tools/displayTools/Labelmap/labelmapRepresentationUID.d.ts +8 -0
  139. package/dist/esm/tools/displayTools/Labelmap/labelmapRepresentationUID.js +18 -0
  140. package/dist/esm/tools/displayTools/Labelmap/removeLabelmapFromElement.js +2 -5
  141. package/dist/esm/tools/displayTools/Labelmap/removeLabelmapRepresentationData.d.ts +3 -0
  142. package/dist/esm/tools/displayTools/Labelmap/removeLabelmapRepresentationData.js +16 -0
  143. package/dist/esm/tools/displayTools/Labelmap/syncStackLabelmapActors.d.ts +2 -0
  144. package/dist/esm/tools/displayTools/Labelmap/syncStackLabelmapActors.js +135 -0
  145. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapImageMapper.d.ts +16 -0
  146. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapImageMapper.js +267 -0
  147. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapSliceData.d.ts +27 -0
  148. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapSliceData.js +185 -0
  149. package/dist/esm/tools/displayTools/registerBuiltInSegmentationRepresentationDisplays.d.ts +1 -0
  150. package/dist/esm/tools/displayTools/registerBuiltInSegmentationRepresentationDisplays.js +16 -0
  151. package/dist/esm/tools/segmentation/BrushTool.d.ts +9 -2
  152. package/dist/esm/tools/segmentation/BrushTool.js +109 -25
  153. package/dist/esm/tools/segmentation/CircleScissorsTool.js +13 -6
  154. package/dist/esm/tools/segmentation/LabelmapBaseTool.d.ts +2 -3
  155. package/dist/esm/tools/segmentation/LabelmapBaseTool.js +77 -38
  156. package/dist/esm/tools/segmentation/LabelmapEditWithContour.js +3 -3
  157. package/dist/esm/tools/segmentation/PaintFillTool.js +11 -4
  158. package/dist/esm/tools/segmentation/RectangleROIStartEndThresholdTool.d.ts +2 -0
  159. package/dist/esm/tools/segmentation/RectangleROIStartEndThresholdTool.js +16 -8
  160. package/dist/esm/tools/segmentation/RectangleScissorsTool.js +13 -6
  161. package/dist/esm/tools/segmentation/SegmentBidirectionalTool.js +63 -61
  162. package/dist/esm/tools/segmentation/SegmentSelectTool.js +4 -4
  163. package/dist/esm/tools/segmentation/SphereScissorsTool.js +5 -1
  164. package/dist/esm/tools/segmentation/strategies/BrushStrategy.d.ts +7 -0
  165. package/dist/esm/tools/segmentation/strategies/BrushStrategy.js +47 -24
  166. package/dist/esm/tools/segmentation/strategies/compositions/circularCursor.js +49 -15
  167. package/dist/esm/tools/segmentation/strategies/compositions/determineSegmentIndex.js +2 -2
  168. package/dist/esm/tools/segmentation/strategies/compositions/dynamicThreshold.js +5 -1
  169. package/dist/esm/tools/segmentation/strategies/compositions/islandRemovalComposition.js +2 -2
  170. package/dist/esm/tools/segmentation/strategies/compositions/preview.js +2 -2
  171. package/dist/esm/tools/segmentation/strategies/compositions/setValue.js +14 -6
  172. package/dist/esm/tools/segmentation/strategies/utils/crossLayerErase.d.ts +4 -0
  173. package/dist/esm/tools/segmentation/strategies/utils/crossLayerErase.js +23 -0
  174. package/dist/esm/tools/segmentation/strategies/utils/getStrategyData.js +1 -1
  175. package/dist/esm/tools/segmentation/strategies/utils/handleUseSegmentCenterIndex.js +12 -11
  176. package/dist/esm/tools/segmentation/strategies/utils/labelmapOverlap.d.ts +4 -0
  177. package/dist/esm/tools/segmentation/strategies/utils/labelmapOverlap.js +41 -0
  178. package/dist/esm/tools/segmentation/strategies/utils/overwritePolicy.d.ts +3 -0
  179. package/dist/esm/tools/segmentation/strategies/utils/overwritePolicy.js +31 -0
  180. package/dist/esm/tools/segmentation/strategies/utils/segmentSeparation.d.ts +3 -0
  181. package/dist/esm/tools/segmentation/strategies/utils/segmentSeparation.js +38 -0
  182. package/dist/esm/tools/segmentation/utils/LazyBrushEditController.d.ts +19 -0
  183. package/dist/esm/tools/segmentation/utils/LazyBrushEditController.js +55 -0
  184. package/dist/esm/tools/segmentation/utils/lazyBrushPreview.d.ts +3 -0
  185. package/dist/esm/tools/segmentation/utils/lazyBrushPreview.js +34 -0
  186. package/dist/esm/tools/segmentation/utils/shouldUseLazyLabelmapEditing.d.ts +3 -0
  187. package/dist/esm/tools/segmentation/utils/shouldUseLazyLabelmapEditing.js +42 -0
  188. package/dist/esm/types/LabelmapToolOperationData.d.ts +5 -0
  189. package/dist/esm/types/LabelmapTypes.d.ts +29 -6
  190. package/dist/esm/types/SegmentationStateTypes.d.ts +4 -0
  191. package/dist/esm/utilities/calibrateImageSpacing.js +17 -2
  192. package/dist/esm/utilities/contours/AnnotationToPointData.js +1 -1
  193. package/dist/esm/utilities/getSphereBoundsInfo.js +5 -1
  194. package/dist/esm/utilities/getViewportICamera.d.ts +4 -0
  195. package/dist/esm/utilities/getViewportICamera.js +23 -0
  196. package/dist/esm/utilities/getViewportsForAnnotation.js +5 -1
  197. package/dist/esm/utilities/math/basic/BasicStatsCalculator.js +9 -7
  198. package/dist/esm/utilities/pointInSurroundingSphereCallback.js +8 -1
  199. package/dist/esm/utilities/segmentation/InterpolationManager/InterpolationManager.js +121 -118
  200. package/dist/esm/utilities/segmentation/SegmentStatsCalculator.js +5 -4
  201. package/dist/esm/utilities/segmentation/VolumetricCalculator.js +1 -1
  202. package/dist/esm/utilities/segmentation/createLabelmapVolumeForViewport.js +1 -1
  203. package/dist/esm/utilities/segmentation/getReferenceVolumeForSegmentation.js +1 -1
  204. package/dist/esm/utilities/segmentation/getReferenceVolumeForSegmentationVolume.js +11 -2
  205. package/dist/esm/utilities/segmentation/getSegmentIndexAtLabelmapBorder.js +36 -17
  206. package/dist/esm/utilities/segmentation/getSegmentIndexAtWorldPoint.js +42 -25
  207. package/dist/esm/utilities/segmentation/getUniqueSegmentIndices.js +3 -30
  208. package/dist/esm/utilities/segmentation/index.d.ts +2 -1
  209. package/dist/esm/utilities/segmentation/index.js +2 -1
  210. package/dist/esm/utilities/segmentation/utilsForWorker.js +2 -2
  211. package/dist/esm/utilities/segmentation/validateLabelmap.js +1 -1
  212. package/dist/esm/utilities/stackPrefetch/stackPrefetch.js +0 -1
  213. package/dist/esm/utilities/touch/index.js +3 -2
  214. package/dist/esm/utilities/viewportCapabilities.d.ts +16 -0
  215. package/dist/esm/utilities/viewportCapabilities.js +18 -0
  216. package/dist/esm/utilities/viewportFilters/filterViewportsWithParallelNormals.d.ts +1 -1
  217. package/dist/esm/utilities/viewportFilters/filterViewportsWithParallelNormals.js +12 -4
  218. package/dist/esm/utilities/viewportFilters/filterViewportsWithSameOrientation.d.ts +1 -1
  219. package/dist/esm/utilities/viewportFilters/filterViewportsWithSameOrientation.js +11 -4
  220. package/dist/esm/utilities/viewportFilters/getViewportIdsWithToolToRender.js +1 -1
  221. package/dist/esm/utilities/viewportPresentation.d.ts +3 -0
  222. package/dist/esm/utilities/viewportPresentation.js +26 -0
  223. package/dist/esm/version.d.ts +1 -1
  224. package/dist/esm/version.js +1 -1
  225. package/package.json +10 -10
@@ -1,13 +1,20 @@
1
1
  import { getEnabledElement } from '@cornerstonejs/core';
2
2
  export default function getTouchEventPoints(evt, element) {
3
3
  const elementToUse = element || evt.currentTarget;
4
+ const { viewport } = getEnabledElement(elementToUse) || {};
5
+ if (!viewport) {
6
+ return [];
7
+ }
4
8
  const touches = evt.type === 'touchend' ? evt.changedTouches : evt.touches;
5
- return Object.keys(touches).map((i) => {
9
+ return Object.keys(touches)
10
+ .map((i) => {
6
11
  const clientPoint = _clientToPoint(touches[i]);
7
12
  const pagePoint = _pageToPoint(touches[i]);
8
13
  const canvasPoint = _pagePointsToCanvasPoints(elementToUse, pagePoint);
9
- const { viewport } = getEnabledElement(elementToUse);
10
- const worldPoint = viewport.canvasToWorld(canvasPoint);
14
+ const worldPoint = getWorldPoint(viewport, canvasPoint);
15
+ if (!worldPoint) {
16
+ return;
17
+ }
11
18
  return {
12
19
  page: pagePoint,
13
20
  client: clientPoint,
@@ -21,7 +28,8 @@ export default function getTouchEventPoints(evt, element) {
21
28
  rotationAngle: touches[i].rotationAngle,
22
29
  },
23
30
  };
24
- });
31
+ })
32
+ .filter(Boolean);
25
33
  }
26
34
  function _pagePointsToCanvasPoints(element, pagePoint) {
27
35
  const rect = element.getBoundingClientRect();
@@ -36,3 +44,18 @@ function _pageToPoint(touch) {
36
44
  function _clientToPoint(touch) {
37
45
  return [touch.clientX, touch.clientY];
38
46
  }
47
+ function getWorldPoint(viewport, canvasPoint) {
48
+ try {
49
+ return viewport.canvasToWorld(canvasPoint);
50
+ }
51
+ catch (error) {
52
+ if (isNoMountedDataError(error)) {
53
+ return;
54
+ }
55
+ throw error;
56
+ }
57
+ }
58
+ function isNoMountedDataError(error) {
59
+ return (error instanceof Error &&
60
+ error.message.includes('because no data is mounted'));
61
+ }
@@ -1,4 +1,4 @@
1
- import { getEnabledElement, triggerEvent } from '@cornerstonejs/core';
1
+ import { getEnabledElement, triggerEvent, utilities, } from '@cornerstonejs/core';
2
2
  import Events from '../../enums/Events';
3
3
  import { Swipe } from '../../enums/Touch';
4
4
  import getTouchEventPoints from './getTouchEventPoints';
@@ -59,8 +59,8 @@ const defaultTapState = {
59
59
  tapMaxDistance: 24,
60
60
  tapToleranceMs: 300,
61
61
  };
62
- let state = JSON.parse(JSON.stringify(defaultState));
63
- let tapState = JSON.parse(JSON.stringify(defaultTapState));
62
+ let state = utilities.deepClone(defaultState);
63
+ let tapState = utilities.deepClone(defaultTapState);
64
64
  function triggerEventCallback(ele, name, eventDetail) {
65
65
  return triggerEvent(ele, name, eventDetail);
66
66
  }
@@ -194,7 +194,7 @@ function _onTouchEnd(evt) {
194
194
  };
195
195
  triggerEventCallback(eventDetail.element, TOUCH_END, eventDetail);
196
196
  _checkTouchTap(evt);
197
- state = JSON.parse(JSON.stringify(defaultState));
197
+ state = utilities.deepClone(defaultState);
198
198
  document.removeEventListener('touchmove', _onTouchDrag);
199
199
  document.removeEventListener('touchend', _onTouchEnd);
200
200
  }
@@ -236,7 +236,7 @@ function _checkTouchTap(evt) {
236
236
  taps: tapState.taps,
237
237
  };
238
238
  triggerEventCallback(eventDetail.element, TOUCH_TAP, eventDetail);
239
- tapState = JSON.parse(JSON.stringify(defaultTapState));
239
+ tapState = utilities.deepClone(defaultTapState);
240
240
  }, tapState.tapToleranceMs);
241
241
  }
242
242
  function _checkTouchSwipe(evt, deltaPoints) {
@@ -267,9 +267,22 @@ function _checkTouchSwipe(evt, deltaPoints) {
267
267
  }
268
268
  }
269
269
  function _updateTouchEventsLastPoints(element, lastPoints) {
270
- const { viewport } = getEnabledElement(element);
271
- return lastPoints.map((lp) => {
272
- const world = viewport.canvasToWorld(lp.canvas);
270
+ const { viewport } = getEnabledElement(element) || {};
271
+ if (!viewport) {
272
+ return lastPoints;
273
+ }
274
+ return lastPoints
275
+ .map((lp) => {
276
+ let world;
277
+ try {
278
+ world = viewport.canvasToWorld(lp.canvas);
279
+ }
280
+ catch (error) {
281
+ if (isNoMountedDataError(error)) {
282
+ return;
283
+ }
284
+ throw error;
285
+ }
273
286
  return {
274
287
  page: lp.page,
275
288
  client: lp.client,
@@ -277,6 +290,11 @@ function _updateTouchEventsLastPoints(element, lastPoints) {
277
290
  world,
278
291
  touch: lp.touch,
279
292
  };
280
- });
293
+ })
294
+ .filter(Boolean);
295
+ }
296
+ function isNoMountedDataError(error) {
297
+ return (error instanceof Error &&
298
+ error.message.includes('because no data is mounted'));
281
299
  }
282
300
  export default touchStartListener;
@@ -9,6 +9,10 @@ function wheelListener(evt) {
9
9
  if (evt.deltaY > -1 && evt.deltaY < 1) {
10
10
  return;
11
11
  }
12
+ const points = getMouseEventPoints(evt);
13
+ if (!points) {
14
+ return;
15
+ }
12
16
  evt.preventDefault();
13
17
  const { spinX, spinY, pixelX, pixelY } = normalizeWheel(evt);
14
18
  const direction = spinY < 0 ? -1 : 1;
@@ -27,7 +31,7 @@ function wheelListener(evt) {
27
31
  pixelY,
28
32
  direction,
29
33
  },
30
- points: getMouseEventPoints(evt),
34
+ points,
31
35
  };
32
36
  triggerEvent(element, Events.MOUSE_WHEEL, eventDetail);
33
37
  }
package/dist/esm/init.js CHANGED
@@ -10,11 +10,13 @@ import { defaultSegmentationStateManager } from './stateManagement/segmentation/
10
10
  import segmentationRepresentationModifiedListener from './eventListeners/segmentation/segmentationRepresentationModifiedListener';
11
11
  import { setConfig } from './config';
12
12
  import segmentationRemovedListener from './eventListeners/segmentation/segmentationRemovedEventListener';
13
+ import { registerBuiltInSegmentationRepresentationDisplays } from './tools/displayTools/registerBuiltInSegmentationRepresentationDisplays';
13
14
  let csToolsInitialized = false;
14
15
  export function init(defaultConfiguration = {}) {
15
16
  if (csToolsInitialized) {
16
17
  return;
17
18
  }
19
+ registerBuiltInSegmentationRepresentationDisplays();
18
20
  setConfig(defaultConfiguration);
19
21
  _addCornerstoneEventListeners();
20
22
  _addCornerstoneToolsEventListeners();
@@ -1,4 +1,7 @@
1
1
  import { Enums, eventTarget, getEnabledElement, utilities, } from '@cornerstonejs/core';
2
+ function isUnsafeKey(key) {
3
+ return key === '__proto__' || key === 'constructor' || key === 'prototype';
4
+ }
2
5
  class FrameOfReferenceSpecificAnnotationManager {
3
6
  constructor(uid) {
4
7
  this.getGroupKey = (annotationGroupSelector) => {
@@ -77,6 +80,9 @@ class FrameOfReferenceSpecificAnnotationManager {
77
80
  const { metadata } = annotation;
78
81
  const { FrameOfReferenceUID, toolName } = metadata;
79
82
  groupKey = groupKey || FrameOfReferenceUID;
83
+ if (isUnsafeKey(groupKey) || isUnsafeKey(toolName)) {
84
+ return;
85
+ }
80
86
  const annotations = this.annotations;
81
87
  let frameOfReferenceSpecificAnnotations = annotations[groupKey];
82
88
  if (!frameOfReferenceSpecificAnnotations) {
@@ -146,13 +152,13 @@ class FrameOfReferenceSpecificAnnotationManager {
146
152
  return;
147
153
  }
148
154
  const toolSpecificAnnotations = frameOfReferenceSpecificAnnotations[toolName];
149
- return structuredClone(toolSpecificAnnotations);
155
+ return utilities.deepClone(toolSpecificAnnotations);
150
156
  }
151
157
  else if (groupKey) {
152
158
  const frameOfReferenceSpecificAnnotations = annotations[groupKey];
153
- return structuredClone(frameOfReferenceSpecificAnnotations);
159
+ return utilities.deepClone(frameOfReferenceSpecificAnnotations);
154
160
  }
155
- return structuredClone(annotations);
161
+ return utilities.deepClone(annotations);
156
162
  };
157
163
  this.restoreAnnotations = (state, groupKey, toolName) => {
158
164
  const annotations = this.annotations;
@@ -168,7 +174,7 @@ class FrameOfReferenceSpecificAnnotationManager {
168
174
  annotations[groupKey] = state;
169
175
  }
170
176
  else {
171
- this.annotations = structuredClone(state);
177
+ this.annotations = utilities.deepClone(state);
172
178
  }
173
179
  };
174
180
  this.getAllAnnotations = () => {
@@ -1,21 +1,13 @@
1
1
  import { triggerEvent, eventTarget, Enums, getRenderingEngines, getEnabledElementByViewportId, } from '@cornerstonejs/core';
2
2
  import { SegmentationRepresentations, Events as csToolsEvents, } from '../../enums';
3
- import Representations from '../../enums/SegmentationRepresentations';
4
3
  import { getSegmentation } from './getSegmentation';
5
4
  import { getSegmentationRepresentations } from './getSegmentationRepresentation';
6
- import surfaceDisplay from '../../tools/displayTools/Surface/surfaceDisplay';
7
- import contourDisplay from '../../tools/displayTools/Contour/contourDisplay';
8
- import labelmapDisplay from '../../tools/displayTools/Labelmap/labelmapDisplay';
9
5
  import { addTool } from '../../store/addTool';
10
6
  import { state } from '../../store/state';
11
7
  import PlanarFreehandContourSegmentationTool from '../../tools/annotation/PlanarFreehandContourSegmentationTool';
12
8
  import { getToolGroupForViewport } from '../../store/ToolGroupManager';
13
9
  import { addDefaultSegmentationListener } from './segmentationEventManager';
14
- const renderers = {
15
- [Representations.Labelmap]: labelmapDisplay,
16
- [Representations.Contour]: contourDisplay,
17
- [Representations.Surface]: surfaceDisplay,
18
- };
10
+ import { getSegmentationRepresentationDisplay } from './SegmentationRepresentationDisplayRegistry';
19
11
  const planarContourToolName = PlanarFreehandContourSegmentationTool.toolName;
20
12
  class SegmentationRenderingEngine {
21
13
  constructor() {
@@ -108,22 +100,33 @@ class SegmentationRenderingEngine {
108
100
  if (representation.type === SegmentationRepresentations.Contour) {
109
101
  this._addPlanarFreeHandToolIfAbsent(viewport);
110
102
  }
111
- const display = renderers[representation.type];
103
+ const display = getSegmentationRepresentationDisplay(representation.type);
112
104
  const segmentation = getSegmentation(representation.segmentationId);
113
105
  const existingRepresentation = segmentation.representationData[representation.type] !== undefined;
114
- try {
115
- display.render(viewport, representation).then(() => {
116
- if (!existingRepresentation) {
117
- addDefaultSegmentationListener(viewport, representation.segmentationId, representation.type);
118
- }
106
+ if (!display) {
107
+ console.warn(`No display registered for segmentation representation type ${representation.type}.`);
108
+ return Promise.resolve({
109
+ segmentationId: representation.segmentationId,
110
+ type: representation.type,
119
111
  });
120
112
  }
121
- catch (error) {
113
+ return display
114
+ .render(viewport, representation)
115
+ .then(() => {
116
+ if (!existingRepresentation) {
117
+ addDefaultSegmentationListener(viewport, representation.segmentationId, representation.type);
118
+ }
119
+ return {
120
+ segmentationId: representation.segmentationId,
121
+ type: representation.type,
122
+ };
123
+ })
124
+ .catch((error) => {
122
125
  console.error(error);
123
- }
124
- return Promise.resolve({
125
- segmentationId: representation.segmentationId,
126
- type: representation.type,
126
+ return {
127
+ segmentationId: representation.segmentationId,
128
+ type: representation.type,
129
+ };
127
130
  });
128
131
  });
129
132
  Promise.allSettled(segmentationRenderList).then((results) => {
@@ -0,0 +1,12 @@
1
+ import type { Types } from '@cornerstonejs/core';
2
+ import type SegmentationRepresentations from '../../enums/SegmentationRepresentations';
3
+ import type { SegmentationRepresentation } from '../../types/SegmentationStateTypes';
4
+ type SegmentationRepresentationUpdateFunction = (segmentationId: string) => Promise<void>;
5
+ export type SegmentationRepresentationDisplay = {
6
+ getUpdateFunction: (viewport: Types.IVolumeViewport | Types.IStackViewport) => SegmentationRepresentationUpdateFunction | void | null;
7
+ render: (viewport: Types.IVolumeViewport | Types.IStackViewport, representation: SegmentationRepresentation) => Promise<void>;
8
+ removeRepresentation: (viewportId: string, segmentationId: string, renderImmediate?: boolean) => void;
9
+ };
10
+ export declare function registerSegmentationRepresentationDisplay(representationType: SegmentationRepresentations, display: SegmentationRepresentationDisplay): void;
11
+ export declare function getSegmentationRepresentationDisplay(representationType: SegmentationRepresentations): SegmentationRepresentationDisplay | undefined;
12
+ export {};
@@ -0,0 +1,7 @@
1
+ const segmentationRepresentationDisplays = new Map();
2
+ export function registerSegmentationRepresentationDisplay(representationType, display) {
3
+ segmentationRepresentationDisplays.set(representationType, display);
4
+ }
5
+ export function getSegmentationRepresentationDisplay(representationType) {
6
+ return segmentationRepresentationDisplays.get(representationType);
7
+ }
@@ -4,9 +4,7 @@ import type { RenderingConfig, RepresentationsData, Segmentation, SegmentationRe
4
4
  export default class SegmentationStateManager {
5
5
  private state;
6
6
  readonly uid: string;
7
- private _stackLabelmapImageIdReferenceMap;
8
- private _labelmapImageIdReferenceMap;
9
- private _labelmapKeysBySegmentationId;
7
+ private readonly labelmapImageReferenceResolver;
10
8
  constructor(uid?: string);
11
9
  getState(): Readonly<SegmentationState>;
12
10
  private updateState;
@@ -21,9 +19,7 @@ export default class SegmentationStateManager {
21
19
  private addDefaultSegmentationRepresentation;
22
20
  addLabelmapRepresentation(state: SegmentationState, viewportId: string, segmentationId: string, renderingConfig?: RenderingConfig): void;
23
21
  processLabelmapRepresentationAddition(viewportId: string, segmentationId: string): Promise<void>;
24
- _updateLabelmapSegmentationReferences(segmentationId: any, viewport: any, labelmapImageIds: any, updateCallback: any): string | undefined;
25
22
  updateLabelmapSegmentationImageReferences(viewportId: any, segmentationId: any): string;
26
- _updateAllLabelmapSegmentationImageReferences(viewportId: any, segmentationId: any): void;
27
23
  getLabelmapImageIds(representationData: RepresentationsData): any;
28
24
  getLabelmapImageIdsForImageId(imageId: string, segmentationId: string): string[];
29
25
  getCurrentLabelmapImageIdsForViewport(viewportId: string, segmentationId: string): string[] | undefined;
@@ -44,11 +40,6 @@ export default class SegmentationStateManager {
44
40
  segmentationId: string;
45
41
  type: SegmentationRepresentations;
46
42
  }>;
47
- _updateLabelmapImageIdReferenceMap({ segmentationId, referenceImageId, labelmapImageId, }: {
48
- segmentationId: any;
49
- referenceImageId: any;
50
- labelmapImageId: any;
51
- }): void;
52
43
  _setActiveSegmentation(state: SegmentationState, viewportId: string, segmentationId: string): void;
53
44
  setActiveSegmentation(viewportId: string, segmentationId: string): void;
54
45
  getActiveSegmentation(viewportId: string): Segmentation | undefined;
@@ -79,7 +70,6 @@ export default class SegmentationStateManager {
79
70
  viewportId: string;
80
71
  representations: SegmentationRepresentation[];
81
72
  }[];
82
- private _generateMapKey;
83
73
  }
84
74
  declare function internalComputeVolumeLabelmapFromStack({ imageIds, options, }: {
85
75
  imageIds: string[];
@@ -1,10 +1,12 @@
1
- import { BaseVolumeViewport, cache, utilities as csUtils, getEnabledElementByViewportId, volumeLoader, } from '@cornerstonejs/core';
1
+ import { utilities as csUtils, getEnabledElementByViewportId, volumeLoader, } from '@cornerstonejs/core';
2
2
  import { SegmentationRepresentations } from '../../enums';
3
3
  import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';
4
4
  import vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunction';
5
+ import getViewportLabelmapRenderMode from './helpers/getViewportLabelmapRenderMode';
5
6
  import { triggerSegmentationModified, triggerSegmentationRemoved, triggerSegmentationRepresentationModified, triggerSegmentationRepresentationRemoved, } from './triggerSegmentationEvents';
6
7
  import { segmentationStyle } from './SegmentationStyle';
7
8
  import { triggerSegmentationAdded } from './events/triggerSegmentationAdded';
9
+ import { ensureLabelmapState, LabelmapImageReferenceResolver, syncLegacyLabelmapData, } from './labelmapModel';
8
10
  const initialDefaultState = {
9
11
  colorLUT: [],
10
12
  segmentations: [],
@@ -12,12 +14,10 @@ const initialDefaultState = {
12
14
  };
13
15
  export default class SegmentationStateManager {
14
16
  constructor(uid) {
15
- this._stackLabelmapImageIdReferenceMap = new Map();
16
- this._labelmapImageIdReferenceMap = new Map();
17
- this._labelmapKeysBySegmentationId = new Map();
18
17
  uid ||= csUtils.uuidv4();
19
18
  this.state = Object.freeze(csUtils.deepClone(initialDefaultState));
20
19
  this.uid = uid;
20
+ this.labelmapImageReferenceResolver = new LabelmapImageReferenceResolver(this.getSegmentation.bind(this));
21
21
  }
22
22
  getState() {
23
23
  return this.state;
@@ -34,9 +34,7 @@ export default class SegmentationStateManager {
34
34
  return this.state.colorLUT.length;
35
35
  }
36
36
  resetState() {
37
- this._stackLabelmapImageIdReferenceMap.clear();
38
- this._labelmapImageIdReferenceMap.clear();
39
- this._labelmapKeysBySegmentationId.clear();
37
+ this.labelmapImageReferenceResolver.reset();
40
38
  this.state = Object.freeze(csUtils.deepClone(initialDefaultState));
41
39
  }
42
40
  getSegmentation(segmentationId) {
@@ -50,6 +48,10 @@ export default class SegmentationStateManager {
50
48
  return;
51
49
  }
52
50
  Object.assign(segmentation, payload);
51
+ if (segmentation.representationData?.Labelmap) {
52
+ ensureLabelmapState(segmentation);
53
+ syncLegacyLabelmapData(segmentation);
54
+ }
53
55
  });
54
56
  triggerSegmentationModified(segmentationId);
55
57
  }
@@ -59,9 +61,12 @@ export default class SegmentationStateManager {
59
61
  }
60
62
  this.updateState((state) => {
61
63
  const newSegmentation = csUtils.deepClone(segmentation);
62
- if (newSegmentation.representationData.Labelmap &&
63
- 'volumeId' in newSegmentation.representationData.Labelmap &&
64
- !('imageIds' in newSegmentation.representationData.Labelmap)) {
64
+ if (newSegmentation.representationData?.Labelmap) {
65
+ ensureLabelmapState(newSegmentation);
66
+ syncLegacyLabelmapData(newSegmentation);
67
+ }
68
+ const labelmapData = newSegmentation.representationData.Labelmap;
69
+ if (labelmapData?.volumeId && !('imageIds' in labelmapData)) {
65
70
  const imageIds = this.getLabelmapImageIds(newSegmentation.representationData);
66
71
  newSegmentation.representationData
67
72
  .Labelmap.imageIds = imageIds;
@@ -71,14 +76,7 @@ export default class SegmentationStateManager {
71
76
  triggerSegmentationAdded(segmentation.segmentationId);
72
77
  }
73
78
  removeSegmentation(segmentationId) {
74
- this._stackLabelmapImageIdReferenceMap.delete(segmentationId);
75
- const keys = this._labelmapKeysBySegmentationId.get(segmentationId);
76
- if (keys) {
77
- for (const key of keys) {
78
- this._labelmapImageIdReferenceMap.delete(key);
79
- }
80
- this._labelmapKeysBySegmentationId.delete(segmentationId);
81
- }
79
+ this.labelmapImageReferenceResolver.removeSegmentation(segmentationId);
82
80
  this.updateState((state) => {
83
81
  const filteredSegmentations = state.segmentations.filter((segmentation) => segmentation.segmentationId !== segmentationId);
84
82
  state.segmentations.splice(0, state.segmentations.length, ...filteredSegmentations);
@@ -96,6 +94,7 @@ export default class SegmentationStateManager {
96
94
  });
97
95
  if (existingRepresentations.length > 0) {
98
96
  console.debug('A segmentation representation of type', type, 'already exists in viewport', viewportId, 'for segmentation', segmentationId);
97
+ triggerSegmentationRepresentationModified(viewportId, segmentationId, type);
99
98
  return;
100
99
  }
101
100
  this.updateState((state) => {
@@ -162,148 +161,30 @@ export default class SegmentationStateManager {
162
161
  if (!segmentation) {
163
162
  return;
164
163
  }
165
- const volumeViewport = enabledElement.viewport instanceof BaseVolumeViewport;
164
+ const volumeViewport = getViewportLabelmapRenderMode(enabledElement.viewport) === 'volume';
166
165
  const { representationData } = segmentation;
167
- const isBaseVolumeSegmentation = 'volumeId' in representationData.Labelmap;
168
- const viewport = enabledElement.viewport;
166
+ const isBaseVolumeSegmentation = !!representationData.Labelmap.volumeId;
169
167
  if (!volumeViewport && !isBaseVolumeSegmentation) {
170
168
  !this.updateLabelmapSegmentationImageReferences(viewportId, segmentation.segmentationId);
171
169
  }
172
170
  }
173
- _updateLabelmapSegmentationReferences(segmentationId, viewport, labelmapImageIds, updateCallback) {
174
- const referenceImageId = viewport.getCurrentImageId();
175
- let viewableLabelmapImageIdFound = false;
176
- for (const labelmapImageId of labelmapImageIds) {
177
- const viewableImageId = viewport.isReferenceViewable({ referencedImageId: labelmapImageId }, { asOverlay: true });
178
- if (viewableImageId) {
179
- viewableLabelmapImageIdFound = true;
180
- this._stackLabelmapImageIdReferenceMap
181
- .get(segmentationId)
182
- .set(referenceImageId, labelmapImageId);
183
- this._updateLabelmapImageIdReferenceMap({
184
- segmentationId,
185
- referenceImageId,
186
- labelmapImageId,
187
- });
188
- }
189
- }
190
- if (updateCallback) {
191
- updateCallback(viewport, segmentationId, labelmapImageIds);
192
- }
193
- return viewableLabelmapImageIdFound
194
- ? this._stackLabelmapImageIdReferenceMap
195
- .get(segmentationId)
196
- .get(referenceImageId)
197
- : undefined;
198
- }
199
171
  updateLabelmapSegmentationImageReferences(viewportId, segmentationId) {
200
- const segmentation = this.getSegmentation(segmentationId);
201
- if (!segmentation) {
202
- return;
203
- }
204
- if (!this._stackLabelmapImageIdReferenceMap.has(segmentationId)) {
205
- this._stackLabelmapImageIdReferenceMap.set(segmentationId, new Map());
206
- }
207
- const { representationData } = segmentation;
208
- if (!representationData.Labelmap) {
209
- return;
210
- }
211
- const labelmapImageIds = this.getLabelmapImageIds(representationData);
212
- const enabledElement = getEnabledElementByViewportId(viewportId);
213
- const stackViewport = enabledElement.viewport;
214
- return this._updateLabelmapSegmentationReferences(segmentationId, stackViewport, labelmapImageIds, null);
215
- }
216
- _updateAllLabelmapSegmentationImageReferences(viewportId, segmentationId) {
217
- const segmentation = this.getSegmentation(segmentationId);
218
- if (!segmentation) {
219
- return;
220
- }
221
- if (!this._stackLabelmapImageIdReferenceMap.has(segmentationId)) {
222
- this._stackLabelmapImageIdReferenceMap.set(segmentationId, new Map());
223
- }
224
- const { representationData } = segmentation;
225
- if (!representationData.Labelmap) {
226
- return;
227
- }
228
- const labelmapImageIds = this.getLabelmapImageIds(representationData);
229
- const enabledElement = getEnabledElementByViewportId(viewportId);
230
- const stackViewport = enabledElement.viewport;
231
- this._updateLabelmapSegmentationReferences(segmentationId, stackViewport, labelmapImageIds, (stackViewport, segmentationId, labelmapImageIds) => {
232
- const imageIds = stackViewport.getImageIds();
233
- imageIds.forEach((referenceImageId, index) => {
234
- for (const labelmapImageId of labelmapImageIds) {
235
- const viewableImageId = stackViewport.isReferenceViewable({ referencedImageId: labelmapImageId, sliceIndex: index }, { asOverlay: true, withNavigation: true });
236
- if (viewableImageId) {
237
- this._stackLabelmapImageIdReferenceMap
238
- .get(segmentationId)
239
- .set(referenceImageId, labelmapImageId);
240
- this._updateLabelmapImageIdReferenceMap({
241
- segmentationId,
242
- referenceImageId,
243
- labelmapImageId,
244
- });
245
- }
246
- }
247
- });
248
- });
172
+ return this.labelmapImageReferenceResolver.updateLabelmapSegmentationImageReferences(viewportId, segmentationId);
249
173
  }
250
174
  getLabelmapImageIds(representationData) {
251
- const labelmapData = representationData.Labelmap;
252
- let labelmapImageIds;
253
- if (labelmapData.imageIds) {
254
- labelmapImageIds = labelmapData
255
- .imageIds;
256
- }
257
- else if (!labelmapImageIds &&
258
- labelmapData.volumeId) {
259
- const volumeId = labelmapData
260
- .volumeId;
261
- const volume = cache.getVolume(volumeId);
262
- labelmapImageIds = volume.imageIds;
263
- }
264
- return labelmapImageIds;
175
+ return this.labelmapImageReferenceResolver.getLabelmapImageIds(representationData);
265
176
  }
266
177
  getLabelmapImageIdsForImageId(imageId, segmentationId) {
267
- const key = this._generateMapKey({
268
- segmentationId,
269
- referenceImageId: imageId,
270
- });
271
- return this._labelmapImageIdReferenceMap.get(key);
178
+ return this.labelmapImageReferenceResolver.getLabelmapImageIdsForImageId(imageId, segmentationId);
272
179
  }
273
180
  getCurrentLabelmapImageIdsForViewport(viewportId, segmentationId) {
274
- const enabledElement = getEnabledElementByViewportId(viewportId);
275
- if (!enabledElement) {
276
- return;
277
- }
278
- const stackViewport = enabledElement.viewport;
279
- const referenceImageId = stackViewport.getCurrentImageId();
280
- return this.getLabelmapImageIdsForImageId(referenceImageId, segmentationId);
181
+ return this.labelmapImageReferenceResolver.getCurrentLabelmapImageIdsForViewport(viewportId, segmentationId);
281
182
  }
282
183
  getCurrentLabelmapImageIdForViewport(viewportId, segmentationId) {
283
- const enabledElement = getEnabledElementByViewportId(viewportId);
284
- if (!enabledElement) {
285
- return;
286
- }
287
- if (!this._stackLabelmapImageIdReferenceMap.has(segmentationId)) {
288
- return;
289
- }
290
- const stackViewport = enabledElement.viewport;
291
- const currentImageId = stackViewport.getCurrentImageId();
292
- const imageIdReferenceMap = this._stackLabelmapImageIdReferenceMap.get(segmentationId);
293
- return imageIdReferenceMap.get(currentImageId);
184
+ return this.labelmapImageReferenceResolver.getCurrentLabelmapImageIdForViewport(viewportId, segmentationId);
294
185
  }
295
186
  getStackSegmentationImageIdsForViewport(viewportId, segmentationId) {
296
- const segmentation = this.getSegmentation(segmentationId);
297
- if (!segmentation) {
298
- return [];
299
- }
300
- this._updateAllLabelmapSegmentationImageReferences(viewportId, segmentationId);
301
- const { viewport } = getEnabledElementByViewportId(viewportId);
302
- const imageIds = viewport.getImageIds();
303
- const associatedReferenceImageAndLabelmapImageIds = this._stackLabelmapImageIdReferenceMap.get(segmentationId);
304
- return imageIds.map((imageId) => {
305
- return associatedReferenceImageAndLabelmapImageIds.get(imageId);
306
- });
187
+ return this.labelmapImageReferenceResolver.getStackSegmentationImageIdsForViewport(viewportId, segmentationId);
307
188
  }
308
189
  removeSegmentationRepresentationsInternal(viewportId, specifier) {
309
190
  const removedRepresentations = [];
@@ -369,23 +250,6 @@ export default class SegmentationStateManager {
369
250
  }
370
251
  return removedRepresentations;
371
252
  }
372
- _updateLabelmapImageIdReferenceMap({ segmentationId, referenceImageId, labelmapImageId, }) {
373
- const key = this._generateMapKey({ segmentationId, referenceImageId });
374
- if (!this._labelmapImageIdReferenceMap.has(key)) {
375
- this._labelmapImageIdReferenceMap.set(key, [labelmapImageId]);
376
- }
377
- else {
378
- const currentValues = this._labelmapImageIdReferenceMap.get(key);
379
- const newValues = Array.from(new Set([...currentValues, labelmapImageId]));
380
- this._labelmapImageIdReferenceMap.set(key, newValues);
381
- }
382
- let keys = this._labelmapKeysBySegmentationId.get(segmentationId);
383
- if (!keys) {
384
- keys = new Set();
385
- this._labelmapKeysBySegmentationId.set(segmentationId, keys);
386
- }
387
- keys.add(key);
388
- }
389
253
  _setActiveSegmentation(state, viewportId, segmentationId) {
390
254
  const viewport = state.viewportSegRepresentations[viewportId];
391
255
  if (!viewport) {
@@ -444,13 +308,14 @@ export default class SegmentationStateManager {
444
308
  }
445
309
  setSegmentationRepresentationVisibility(viewportId, specifier, visible) {
446
310
  this.updateState((state) => {
447
- const viewportRepresentations = this.getSegmentationRepresentations(viewportId, specifier);
311
+ const viewportRepresentations = state.viewportSegRepresentations[viewportId]?.filter((representation) => representation.segmentationId === specifier.segmentationId &&
312
+ representation.type === specifier.type);
448
313
  if (!viewportRepresentations) {
449
314
  return;
450
315
  }
451
316
  viewportRepresentations.forEach((representation) => {
452
317
  representation.visible = visible;
453
- Object.entries(representation.segments).forEach(([segmentIndex, segment]) => {
318
+ Object.values(representation.segments).forEach((segment) => {
454
319
  segment.visible = visible;
455
320
  });
456
321
  });
@@ -491,9 +356,6 @@ export default class SegmentationStateManager {
491
356
  });
492
357
  return result;
493
358
  }
494
- _generateMapKey({ segmentationId, referenceImageId }) {
495
- return `${segmentationId}-${referenceImageId}`;
496
- }
497
359
  }
498
360
  async function internalComputeVolumeLabelmapFromStack({ imageIds, options, }) {
499
361
  const segmentationImageIds = imageIds;
@@ -2,6 +2,8 @@ import { utilities } from '@cornerstonejs/core';
2
2
  import { defaultSegmentationStateManager } from './SegmentationStateManager';
3
3
  import { getNextColorLUTIndex } from './getNextColorLUTIndex';
4
4
  import CORNERSTONE_COLOR_LUT from '../../constants/COLOR_LUT';
5
+ const PREVIEW_COLOR_INDEX = 255;
6
+ const MINIMUM_COLOR_LUT_ENTRIES = PREVIEW_COLOR_INDEX + 1;
5
7
  export function addColorLUT(colorLUT, index) {
6
8
  const segmentationStateManager = defaultSegmentationStateManager;
7
9
  const indexToUse = index ?? getNextColorLUTIndex();
@@ -16,10 +18,14 @@ export function addColorLUT(colorLUT, index) {
16
18
  }
17
19
  return color;
18
20
  });
19
- if (colorLUTToUse.length < 255) {
21
+ if (colorLUTToUse.length < MINIMUM_COLOR_LUT_ENTRIES) {
20
22
  const missingColorLUTs = CORNERSTONE_COLOR_LUT.slice(colorLUTToUse.length);
21
23
  colorLUTToUse = [...colorLUTToUse, ...missingColorLUTs];
22
24
  }
25
+ while (colorLUTToUse.length < MINIMUM_COLOR_LUT_ENTRIES) {
26
+ const paletteIndex = ((colorLUTToUse.length - 1) % (CORNERSTONE_COLOR_LUT.length - 1)) + 1;
27
+ colorLUTToUse.push([...CORNERSTONE_COLOR_LUT[paletteIndex]]);
28
+ }
23
29
  segmentationStateManager.addColorLUT(colorLUTToUse, indexToUse);
24
30
  return indexToUse;
25
31
  }