@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,41 +1,31 @@
1
- import { getEnabledElementByViewportId, VolumeViewport, } from '@cornerstonejs/core';
2
- import addLabelmapToElement from './addLabelmapToElement';
3
- import removeLabelmapFromElement from './removeLabelmapFromElement';
4
- import { getActiveSegmentation } from '../../../stateManagement/segmentation/activeSegmentation';
5
- import { getColorLUT } from '../../../stateManagement/segmentation/getColorLUT';
6
- import { getCurrentLabelmapImageIdsForViewport } from '../../../stateManagement/segmentation/getCurrentLabelmapImageIdForViewport';
1
+ import { Enums as CoreEnums, eventTarget, getEnabledElementByViewportId, } from '@cornerstonejs/core';
7
2
  import { getSegmentation } from '../../../stateManagement/segmentation/getSegmentation';
8
- import { segmentationStyle } from '../../../stateManagement/segmentation/SegmentationStyle';
9
3
  import SegmentationRepresentations from '../../../enums/SegmentationRepresentations';
10
- import { internalGetHiddenSegmentIndices } from '../../../stateManagement/segmentation/helpers/internalGetHiddenSegmentIndices';
11
- import { getActiveSegmentIndex } from '../../../stateManagement/segmentation/getActiveSegmentIndex';
12
4
  import { getLabelmapActorEntries } from '../../../stateManagement/segmentation/helpers/getSegmentationActor';
13
5
  import { getPolySeg } from '../../../config';
14
6
  import { computeAndAddRepresentation } from '../../../utilities/segmentation/computeAndAddRepresentation';
15
7
  import { triggerSegmentationDataModified } from '../../../stateManagement/segmentation/triggerSegmentationEvents';
16
8
  import { defaultSegmentationStateManager } from '../../../stateManagement/segmentation/SegmentationStateManager';
17
- export const MAX_NUMBER_COLORS = 255;
18
- const labelMapConfigCache = new Map();
9
+ import { removeLabelmapRepresentationFromViewport, resolveLabelmapRenderPlan, } from './labelmapRenderPlan';
10
+ import { MAX_NUMBER_COLORS, setLabelmapColorAndOpacity, } from './labelmapActorStyle';
11
+ export { MAX_NUMBER_COLORS };
12
+ const unsupportedImageMapperStates = new Map();
19
13
  let polySegConversionInProgress = false;
20
14
  function removeRepresentation(viewportId, segmentationId, renderImmediate = false) {
15
+ clearUnsupportedImageMapperError(viewportId, segmentationId);
21
16
  const enabledElement = getEnabledElementByViewportId(viewportId);
22
- labelMapConfigCache.forEach((value, key) => {
23
- if (key.includes(segmentationId)) {
24
- labelMapConfigCache.delete(key);
25
- }
26
- });
27
17
  if (!enabledElement) {
28
18
  return;
29
19
  }
30
20
  const { viewport } = enabledElement;
31
- removeLabelmapFromElement(viewport.element, segmentationId);
21
+ removeLabelmapRepresentationFromViewport(viewport, segmentationId);
32
22
  if (!renderImmediate) {
33
23
  return;
34
24
  }
35
25
  viewport.render();
36
26
  }
37
27
  async function render(viewport, representation) {
38
- const { segmentationId, config } = representation;
28
+ const { segmentationId } = representation;
39
29
  const segmentation = getSegmentation(segmentationId);
40
30
  if (!segmentation) {
41
31
  console.warn('No segmentation found for segmentationId: ', segmentationId);
@@ -48,7 +38,9 @@ async function render(viewport, representation) {
48
38
  !polySegConversionInProgress) {
49
39
  polySegConversionInProgress = true;
50
40
  const polySeg = getPolySeg();
51
- labelmapData = await computeAndAddRepresentation(segmentationId, SegmentationRepresentations.Labelmap, () => polySeg.computeLabelmapData(segmentationId, { viewport }), () => {
41
+ labelmapData = await computeAndAddRepresentation(segmentationId, SegmentationRepresentations.Labelmap, () => polySeg.computeLabelmapData(segmentationId, {
42
+ viewport: viewport,
43
+ }), () => {
52
44
  defaultSegmentationStateManager.processLabelmapRepresentationAddition(viewport.id, segmentationId);
53
45
  setTimeout(() => {
54
46
  triggerSegmentationDataModified(segmentationId);
@@ -65,208 +57,55 @@ async function render(viewport, representation) {
65
57
  if (!labelmapData) {
66
58
  return;
67
59
  }
68
- if (viewport instanceof VolumeViewport) {
69
- if (!labelmapActorEntries?.length) {
70
- await _addLabelmapToViewport(viewport, labelmapData, segmentationId, config);
71
- }
72
- labelmapActorEntries = getLabelmapActorEntries(viewport.id, segmentationId);
73
- }
74
- else {
75
- const labelmapImageIds = getCurrentLabelmapImageIdsForViewport(viewport.id, segmentationId);
76
- if (!labelmapImageIds?.length) {
77
- return;
60
+ const renderPlan = resolveLabelmapRenderPlan({
61
+ viewport,
62
+ segmentation,
63
+ representation,
64
+ });
65
+ if (renderPlan.kind === 'unsupported') {
66
+ if (labelmapActorEntries?.length) {
67
+ renderPlan.remove();
78
68
  }
79
- if (!labelmapActorEntries) {
80
- await _addLabelmapToViewport(viewport, labelmapData, segmentationId, config);
69
+ if (renderPlan.unsupportedStateKey) {
70
+ reportUnsupportedImageMapperError(viewport.id, segmentationId, renderPlan.unsupportedStateKey);
81
71
  }
82
- labelmapActorEntries = getLabelmapActorEntries(viewport.id, segmentationId);
72
+ return;
83
73
  }
74
+ clearUnsupportedImageMapperError(viewport.id, segmentationId);
75
+ labelmapActorEntries = await renderPlan.reconcile({
76
+ actorEntries: labelmapActorEntries,
77
+ labelMapData: labelmapData,
78
+ });
84
79
  if (!labelmapActorEntries?.length) {
85
80
  return;
86
81
  }
87
82
  for (const labelmapActorEntry of labelmapActorEntries) {
88
- _setLabelmapColorAndOpacity(viewport.id, labelmapActorEntry, representation);
89
- }
90
- }
91
- function _setLabelmapColorAndOpacity(viewportId, labelmapActorEntry, segmentationRepresentation) {
92
- const { segmentationId } = segmentationRepresentation;
93
- const { cfun, ofun } = segmentationRepresentation.config;
94
- const { colorLUTIndex } = segmentationRepresentation;
95
- const activeSegmentation = getActiveSegmentation(viewportId);
96
- const isActiveLabelmap = activeSegmentation?.segmentationId === segmentationId;
97
- const labelmapStyle = segmentationStyle.getStyle({
98
- viewportId,
99
- type: SegmentationRepresentations.Labelmap,
100
- segmentationId,
101
- });
102
- const renderInactiveSegmentations = segmentationStyle.getRenderInactiveSegmentations(viewportId);
103
- const colorLUT = getColorLUT(colorLUTIndex);
104
- const numColors = Math.min(256, colorLUT.length);
105
- const { outlineWidth, renderOutline, outlineOpacity, activeSegmentOutlineWidthDelta, } = _getLabelmapConfig(labelmapStyle, isActiveLabelmap);
106
- const segmentsHidden = internalGetHiddenSegmentIndices(viewportId, {
107
- segmentationId,
108
- type: SegmentationRepresentations.Labelmap,
109
- });
110
- for (let i = 0; i < numColors; i++) {
111
- const segmentIndex = i;
112
- const segmentColor = colorLUT[segmentIndex];
113
- const perSegmentStyle = segmentationStyle.getStyle({
114
- viewportId,
115
- type: SegmentationRepresentations.Labelmap,
116
- segmentationId,
117
- segmentIndex,
118
- });
119
- const segmentSpecificLabelmapConfig = perSegmentStyle;
120
- const { fillAlpha, outlineWidth, renderFill, renderOutline } = _getLabelmapConfig(labelmapStyle, isActiveLabelmap, segmentSpecificLabelmapConfig);
121
- const { forceOpacityUpdate, forceColorUpdate } = _needsTransferFunctionUpdate(viewportId, segmentationId, segmentIndex, {
122
- fillAlpha,
123
- renderFill,
124
- renderOutline,
125
- segmentColor,
126
- outlineWidth,
127
- segmentsHidden: segmentsHidden,
128
- cfun,
129
- ofun,
130
- });
131
- if (forceColorUpdate) {
132
- cfun.addRGBPoint(segmentIndex, segmentColor[0] / MAX_NUMBER_COLORS, segmentColor[1] / MAX_NUMBER_COLORS, segmentColor[2] / MAX_NUMBER_COLORS);
133
- }
134
- if (forceOpacityUpdate) {
135
- if (renderFill) {
136
- const segmentOpacity = segmentsHidden.has(segmentIndex)
137
- ? 0
138
- : (segmentColor[3] / 255) * fillAlpha;
139
- ofun.removePoint(segmentIndex);
140
- ofun.addPointLong(segmentIndex, segmentOpacity, 0.5, 1.0);
141
- }
142
- else {
143
- ofun.addPointLong(segmentIndex, 0.01, 0.5, 1.0);
144
- }
145
- }
146
- }
147
- ofun.setClamping(false);
148
- const labelmapActor = labelmapActorEntry.actor;
149
- const { preLoad } = labelmapActor.get?.('preLoad') || { preLoad: null };
150
- if (preLoad) {
151
- preLoad({ cfun, ofun, actor: labelmapActor });
83
+ setLabelmapColorAndOpacity(viewport.id, labelmapActorEntry, representation);
152
84
  }
153
- else {
154
- labelmapActor.getProperty().setRGBTransferFunction(0, cfun);
155
- labelmapActor.getProperty().setScalarOpacity(0, ofun);
156
- labelmapActor.getProperty().setInterpolationTypeToNearest();
157
- }
158
- if (renderOutline) {
159
- labelmapActor.getProperty().setUseLabelOutline(renderOutline);
160
- labelmapActor.getProperty().setLabelOutlineOpacity(outlineOpacity);
161
- const activeSegmentIndex = getActiveSegmentIndex(segmentationRepresentation.segmentationId);
162
- const outlineWidths = new Array(numColors - 1);
163
- for (let i = 1; i < numColors; i++) {
164
- const isHidden = segmentsHidden.has(i);
165
- if (isHidden) {
166
- outlineWidths[i - 1] = 0;
167
- continue;
168
- }
169
- outlineWidths[i - 1] =
170
- i === activeSegmentIndex
171
- ? outlineWidth + activeSegmentOutlineWidthDelta
172
- : outlineWidth;
173
- }
174
- labelmapActor.getProperty().setLabelOutlineThickness(outlineWidths);
175
- labelmapActor.modified();
176
- labelmapActor.getProperty().modified();
177
- labelmapActor.getMapper().modified();
178
- }
179
- else {
180
- labelmapActor
181
- .getProperty()
182
- .setLabelOutlineThickness(new Array(numColors - 1).fill(0));
183
- }
184
- const visible = isActiveLabelmap || renderInactiveSegmentations;
185
- labelmapActor.setVisibility(visible);
186
85
  }
187
- function _getLabelmapConfig(labelmapConfig, isActiveLabelmap, segmentsLabelmapConfig) {
188
- const segmentLabelmapConfig = segmentsLabelmapConfig || {};
189
- const configToUse = {
190
- ...labelmapConfig,
191
- ...segmentLabelmapConfig,
192
- };
193
- const fillAlpha = isActiveLabelmap
194
- ? configToUse.fillAlpha
195
- : configToUse.fillAlphaInactive;
196
- const outlineWidth = isActiveLabelmap
197
- ? configToUse.outlineWidth
198
- : configToUse.outlineWidthInactive;
199
- const renderFill = isActiveLabelmap
200
- ? configToUse.renderFill
201
- : configToUse.renderFillInactive;
202
- const renderOutline = isActiveLabelmap
203
- ? configToUse.renderOutline
204
- : configToUse.renderOutlineInactive;
205
- const outlineOpacity = isActiveLabelmap
206
- ? configToUse.outlineOpacity
207
- : configToUse.outlineOpacityInactive;
208
- const activeSegmentOutlineWidthDelta = configToUse.activeSegmentOutlineWidthDelta;
209
- return {
210
- fillAlpha,
211
- outlineWidth,
212
- renderFill,
213
- renderOutline,
214
- outlineOpacity,
215
- activeSegmentOutlineWidthDelta,
216
- };
86
+ function getUpdateFunction(_viewport) {
87
+ return;
217
88
  }
218
- function _needsTransferFunctionUpdate(viewportId, segmentationId, segmentIndex, { fillAlpha, renderFill, renderOutline, segmentColor, outlineWidth, segmentsHidden, cfun, ofun, }) {
219
- const cacheUID = `${viewportId}-${segmentationId}-${segmentIndex}`;
220
- const oldConfig = labelMapConfigCache.get(cacheUID);
221
- if (!oldConfig) {
222
- labelMapConfigCache.set(cacheUID, {
223
- fillAlpha,
224
- renderFill,
225
- renderOutline,
226
- outlineWidth,
227
- segmentColor: segmentColor.slice(),
228
- segmentsHidden: new Set(segmentsHidden),
229
- cfunMTime: cfun.getMTime(),
230
- ofunMTime: ofun.getMTime(),
231
- });
232
- return {
233
- forceOpacityUpdate: true,
234
- forceColorUpdate: true,
235
- };
236
- }
237
- const { fillAlpha: oldFillAlpha, renderFill: oldRenderFill, renderOutline: oldRenderOutline, outlineWidth: oldOutlineWidth, segmentColor: oldSegmentColor, segmentsHidden: oldSegmentsHidden, cfunMTime: oldCfunMTime, ofunMTime: oldOfunMTime, } = oldConfig;
238
- const forceColorUpdate = oldSegmentColor[0] !== segmentColor[0] ||
239
- oldSegmentColor[1] !== segmentColor[1] ||
240
- oldSegmentColor[2] !== segmentColor[2];
241
- const forceOpacityUpdate = oldSegmentColor[3] !== segmentColor[3] ||
242
- oldFillAlpha !== fillAlpha ||
243
- oldRenderFill !== renderFill ||
244
- oldRenderOutline !== renderOutline ||
245
- oldOutlineWidth !== outlineWidth ||
246
- oldSegmentsHidden !== segmentsHidden;
247
- if (forceOpacityUpdate || forceColorUpdate) {
248
- labelMapConfigCache.set(cacheUID, {
249
- fillAlpha,
250
- renderFill,
251
- renderOutline,
252
- outlineWidth,
253
- segmentColor: segmentColor.slice(),
254
- segmentsHidden: new Set(segmentsHidden),
255
- cfunMTime: cfun.getMTime(),
256
- ofunMTime: ofun.getMTime(),
257
- });
258
- }
259
- return {
260
- forceOpacityUpdate,
261
- forceColorUpdate,
262
- };
89
+ function getUnsupportedImageMapperStateKey(viewportId, segmentationId) {
90
+ return `${viewportId}:${segmentationId}`;
263
91
  }
264
- async function _addLabelmapToViewport(viewport, labelmapData, segmentationId, config) {
265
- const result = await addLabelmapToElement(viewport.element, labelmapData, segmentationId, config);
266
- return result || undefined;
92
+ function clearUnsupportedImageMapperError(viewportId, segmentationId) {
93
+ unsupportedImageMapperStates.delete(getUnsupportedImageMapperStateKey(viewportId, segmentationId));
267
94
  }
268
- function getUpdateFunction(viewport) {
269
- return;
95
+ function reportUnsupportedImageMapperError(viewportId, segmentationId, stateKey) {
96
+ const cacheKey = getUnsupportedImageMapperStateKey(viewportId, segmentationId);
97
+ const previousStateKey = unsupportedImageMapperStates.get(cacheKey);
98
+ if (previousStateKey === stateKey) {
99
+ return;
100
+ }
101
+ unsupportedImageMapperStates.set(cacheKey, stateKey);
102
+ eventTarget.dispatchEvent(new CustomEvent(CoreEnums.Events.ERROR_EVENT, {
103
+ detail: {
104
+ type: 'Segmentation',
105
+ message: 'Labelmap image-mapper rendering is only supported on legacy orthographic single-slice volume viewports.',
106
+ },
107
+ cancelable: true,
108
+ }));
270
109
  }
271
110
  export default {
272
111
  getUpdateFunction,
@@ -0,0 +1,3 @@
1
+ import type { CreateLabelmapRenderPlanArgs, LabelmapRenderPlan } from './types';
2
+ declare function createLabelmapRenderPlan({ isVolumeImageMapper, kind, renderMode, segmentationId, unsupportedStateKey, updateAfterMount, useSliceRendering, viewport, canRenderCurrentViewport, getExpectedRepresentationUIDs, mount, update, }: CreateLabelmapRenderPlanArgs): LabelmapRenderPlan;
3
+ export { createLabelmapRenderPlan };
@@ -0,0 +1,51 @@
1
+ import { getLabelmapActorEntries } from '../../../../stateManagement/segmentation/helpers/getSegmentationActor';
2
+ import { removeLabelmapRepresentationFromViewport } from './removeLabelmapRepresentationFromViewport';
3
+ function createLabelmapRenderPlan({ isVolumeImageMapper, kind, renderMode, segmentationId, unsupportedStateKey, updateAfterMount = true, useSliceRendering, viewport, canRenderCurrentViewport = () => kind !== 'unsupported', getExpectedRepresentationUIDs = () => [], mount = async () => undefined, update = () => undefined, }) {
4
+ const remove = () => removeLabelmapRepresentationFromViewport(viewport, segmentationId);
5
+ const needsRemount = (actorEntries) => haveActorUIDsChanged(actorEntries, getExpectedRepresentationUIDs());
6
+ return {
7
+ kind,
8
+ renderMode,
9
+ useSliceRendering,
10
+ isVolumeImageMapper,
11
+ unsupportedStateKey,
12
+ getExpectedRepresentationUIDs,
13
+ mount,
14
+ needsRemount,
15
+ remove,
16
+ update,
17
+ reconcile: async ({ actorEntries, labelMapData }) => {
18
+ if (!canRenderCurrentViewport()) {
19
+ return actorEntries;
20
+ }
21
+ let nextActorEntries = actorEntries;
22
+ if (needsRemount(nextActorEntries) && nextActorEntries?.length) {
23
+ remove();
24
+ nextActorEntries = undefined;
25
+ }
26
+ const mounted = !nextActorEntries?.length;
27
+ if (mounted) {
28
+ await mount({ labelMapData });
29
+ }
30
+ nextActorEntries = getLabelmapActorEntries(viewport.id, segmentationId);
31
+ if (nextActorEntries?.length && (!mounted || updateAfterMount)) {
32
+ update({ actorEntries: nextActorEntries });
33
+ }
34
+ return nextActorEntries;
35
+ },
36
+ };
37
+ }
38
+ function haveActorUIDsChanged(actorEntries, expectedRepresentationUIDs) {
39
+ const actualUIDs = new Set((actorEntries ?? []).map((entry) => entry.representationUID));
40
+ const expectedUIDs = new Set(expectedRepresentationUIDs);
41
+ if (actualUIDs.size !== expectedUIDs.size) {
42
+ return true;
43
+ }
44
+ for (const expectedUID of expectedUIDs) {
45
+ if (!actualUIDs.has(expectedUID)) {
46
+ return true;
47
+ }
48
+ }
49
+ return false;
50
+ }
51
+ export { createLabelmapRenderPlan };
@@ -0,0 +1,4 @@
1
+ export { createLabelmapRenderPlan } from './createLabelmapRenderPlan';
2
+ export { removeLabelmapRepresentationFromViewport } from './removeLabelmapRepresentationFromViewport';
3
+ export { resolveLabelmapRenderPlan } from './resolveLabelmapRenderPlan';
4
+ export type { LabelmapRenderPlan, LabelmapRenderPlanKind, LabelmapRenderPlanMountResult, } from './types';
@@ -0,0 +1,3 @@
1
+ export { createLabelmapRenderPlan } from './createLabelmapRenderPlan';
2
+ export { removeLabelmapRepresentationFromViewport } from './removeLabelmapRepresentationFromViewport';
3
+ export { resolveLabelmapRenderPlan } from './resolveLabelmapRenderPlan';
@@ -0,0 +1,14 @@
1
+ import { type Types } from '@cornerstonejs/core';
2
+ import type { ViewportLabelmapRenderMode } from '../../../../stateManagement/segmentation/helpers/getViewportLabelmapRenderMode';
3
+ import type { LabelmapRenderingConfig, Segmentation } from '../../../../types/SegmentationStateTypes';
4
+ import type { LabelmapRenderPlan } from './types';
5
+ declare function createLegacyVolumeLabelmapPlan({ config, isVolumeImageMapper, renderMode, segmentation, segmentationId, useSliceRendering, viewport, }: {
6
+ config: LabelmapRenderingConfig;
7
+ isVolumeImageMapper: boolean;
8
+ renderMode: ViewportLabelmapRenderMode;
9
+ segmentation: Segmentation;
10
+ segmentationId: string;
11
+ useSliceRendering: boolean;
12
+ viewport: Types.IViewport;
13
+ }): LabelmapRenderPlan;
14
+ export { createLegacyVolumeLabelmapPlan };
@@ -0,0 +1,143 @@
1
+ import { addVolumesToViewports, Enums, cache, volumeLoader, utilities, } from '@cornerstonejs/core';
2
+ import { triggerSegmentationDataModified, triggerSegmentationModified, } from '../../../../stateManagement/segmentation/triggerSegmentationEvents';
3
+ import { getLabelmaps, getOrCreateLabelmapVolume, } from '../../../../stateManagement/segmentation/helpers/labelmapSegmentationState';
4
+ import { addVolumesAsIndependentComponents } from '../addVolumesAsIndependentComponents';
5
+ import { createLabelmapRepresentationUID } from '../labelmapRepresentationUID';
6
+ import { createLabelmapRenderPlan } from './createLabelmapRenderPlan';
7
+ import { addLabelmapToPlanarGenericViewport, isPlanarNextVolumeViewport, } from './planarGenericVolumeLabelmap';
8
+ const { uuidv4 } = utilities;
9
+ function createLegacyVolumeLabelmapPlan({ config, isVolumeImageMapper, renderMode, segmentation, segmentationId, useSliceRendering, viewport, }) {
10
+ return createLabelmapRenderPlan({
11
+ isVolumeImageMapper,
12
+ kind: 'legacy-volume',
13
+ renderMode,
14
+ segmentationId,
15
+ useSliceRendering,
16
+ viewport,
17
+ getExpectedRepresentationUIDs: () => getExpectedVolumeLabelmapRepresentationUIDs(segmentation, segmentationId),
18
+ mount: ({ labelMapData }) => mountLegacyVolumeLabelmap({
19
+ config,
20
+ labelMapData,
21
+ segmentation,
22
+ segmentationId,
23
+ viewport,
24
+ }),
25
+ });
26
+ }
27
+ function getExpectedVolumeLabelmapRepresentationUIDs(segmentation, segmentationId) {
28
+ return getLabelmaps(segmentation)
29
+ .filter(canResolveLayerAsVolume)
30
+ .map((layer) => createLabelmapRepresentationUID({
31
+ segmentationId,
32
+ referencedId: layer.labelmapId,
33
+ }));
34
+ }
35
+ async function mountLegacyVolumeLabelmap({ config, labelMapData, segmentation, segmentationId, viewport, }) {
36
+ const { id: viewportId } = viewport;
37
+ const visibility = true;
38
+ const immediateRender = false;
39
+ const suppressEvents = true;
40
+ const volumeCompatibleViewport = viewport;
41
+ const labelmapLayers = getVolumeBackedLabelmapLayers(segmentation);
42
+ if (!labelmapLayers.length) {
43
+ const volumeLabelMapData = labelMapData;
44
+ const volumeId = ensureVolumeHasVolumeId(volumeLabelMapData, segmentation);
45
+ if (!cache.getVolume(volumeId)) {
46
+ await handleMissingVolume(labelMapData);
47
+ }
48
+ labelmapLayers.push({
49
+ labelmapId: volumeId,
50
+ type: 'volume',
51
+ volumeId,
52
+ imageIds: cache.getVolume(volumeId)?.imageIds,
53
+ });
54
+ }
55
+ let blendMode = config?.blendMode ?? Enums.BlendModes.MAXIMUM_INTENSITY_BLEND;
56
+ let useIndependentComponents = blendMode === Enums.BlendModes.LABELMAP_EDGE_PROJECTION_BLEND;
57
+ if (useIndependentComponents) {
58
+ const referenceVolumeId = volumeCompatibleViewport.getVolumeId?.();
59
+ const baseVolume = cache.getVolume(referenceVolumeId);
60
+ const segVolume = cache.getVolume(labelmapLayers[0]?.volumeId);
61
+ const segDims = segVolume.dimensions;
62
+ const refDims = baseVolume.dimensions;
63
+ if (segDims[0] !== refDims[0] ||
64
+ segDims[1] !== refDims[1] ||
65
+ segDims[2] !== refDims[2]) {
66
+ useIndependentComponents = false;
67
+ blendMode = Enums.BlendModes.MAXIMUM_INTENSITY_BLEND;
68
+ console.debug('Dimensions mismatch - falling back to regular volume addition');
69
+ }
70
+ }
71
+ const volumeInputs = labelmapLayers.map((layer) => ({
72
+ volumeId: layer.volumeId,
73
+ visibility,
74
+ representationUID: createLabelmapRepresentationUID({
75
+ segmentationId,
76
+ referencedId: layer.labelmapId,
77
+ }),
78
+ useIndependentComponents,
79
+ blendMode,
80
+ }));
81
+ if (isPlanarNextVolumeViewport(viewport)) {
82
+ return addLabelmapToPlanarGenericViewport({
83
+ blendMode,
84
+ labelmapLayers,
85
+ segmentationId,
86
+ viewport,
87
+ visibility,
88
+ });
89
+ }
90
+ if (!volumeInputs[0].useIndependentComponents) {
91
+ await addVolumesToViewports(viewport.getRenderingEngine(), volumeInputs, [viewportId], immediateRender, suppressEvents);
92
+ triggerSegmentationDataModified(segmentationId);
93
+ return;
94
+ }
95
+ return addVolumesAsIndependentComponents({
96
+ viewport: volumeCompatibleViewport,
97
+ volumeInputs,
98
+ segmentationId,
99
+ });
100
+ }
101
+ function canResolveLayerAsVolume(layer) {
102
+ return Boolean(layer.volumeId || layer.geometryVolumeId || layer.imageIds?.length);
103
+ }
104
+ function getVolumeBackedLabelmapLayers(segmentation) {
105
+ return getLabelmaps(segmentation)
106
+ .map((layer) => {
107
+ if (layer.volumeId) {
108
+ return layer;
109
+ }
110
+ const volume = getOrCreateLabelmapVolume(layer);
111
+ if (!volume?.volumeId) {
112
+ return;
113
+ }
114
+ return {
115
+ ...layer,
116
+ volumeId: volume.volumeId,
117
+ };
118
+ })
119
+ .filter((layer) => Boolean(layer));
120
+ }
121
+ function ensureVolumeHasVolumeId(labelMapData, segmentation) {
122
+ let { volumeId } = labelMapData;
123
+ if (!volumeId) {
124
+ volumeId = uuidv4();
125
+ segmentation.representationData.Labelmap = {
126
+ ...segmentation.representationData.Labelmap,
127
+ volumeId,
128
+ };
129
+ labelMapData.volumeId = volumeId;
130
+ triggerSegmentationModified(segmentation.segmentationId);
131
+ }
132
+ return volumeId;
133
+ }
134
+ async function handleMissingVolume(labelMapData) {
135
+ const stackData = labelMapData;
136
+ const hasImageIds = stackData.imageIds.length > 0;
137
+ if (!hasImageIds) {
138
+ throw new Error('cannot create labelmap, no imageIds found for the volume labelmap');
139
+ }
140
+ const volume = await volumeLoader.createAndCacheVolumeFromImages(labelMapData.volumeId ?? uuidv4(), stackData.imageIds);
141
+ return volume;
142
+ }
143
+ export { createLegacyVolumeLabelmapPlan };
@@ -0,0 +1,40 @@
1
+ import { type Types, Enums } from '@cornerstonejs/core';
2
+ import type { LabelmapRenderPlanMountResult } from './types';
3
+ type PlanarNextVolumeViewport = Types.IViewport & {
4
+ getCurrentImageIdIndex?: () => number;
5
+ getDefaultActor?: () => (Types.ActorEntry & {
6
+ actorMapper?: {
7
+ renderMode?: Types.ActorRenderMode;
8
+ };
9
+ }) | undefined;
10
+ getVolumeId: () => string | undefined;
11
+ getViewReference: (specifier?: Types.ViewReferenceSpecifier) => Types.ViewReference;
12
+ getViewState: () => {
13
+ orientation?: unknown;
14
+ };
15
+ getActors?: () => Types.ActorEntry[];
16
+ render?: () => void;
17
+ addDisplaySet: (displaySetId: string, options: {
18
+ orientation?: unknown;
19
+ role?: 'source' | 'overlay';
20
+ }) => Promise<void>;
21
+ setDisplaySetPresentation: (dataId: string, props: {
22
+ blendMode?: Enums.BlendModes;
23
+ visible?: boolean;
24
+ }) => void;
25
+ setViewReference: (viewReference: Types.ViewReference) => void;
26
+ type: string;
27
+ };
28
+ declare function isPlanarNextVolumeViewport(viewport: Types.IViewport): viewport is PlanarNextVolumeViewport;
29
+ declare function addLabelmapToPlanarGenericViewport(args: {
30
+ blendMode: Enums.BlendModes;
31
+ labelmapLayers: Array<{
32
+ imageIds?: string[];
33
+ labelmapId: string;
34
+ volumeId?: string;
35
+ }>;
36
+ segmentationId: string;
37
+ viewport: PlanarNextVolumeViewport;
38
+ visibility: boolean;
39
+ }): Promise<LabelmapRenderPlanMountResult>;
40
+ export { addLabelmapToPlanarGenericViewport, isPlanarNextVolumeViewport, type PlanarNextVolumeViewport, };
@@ -0,0 +1,79 @@
1
+ import { ActorRenderMode, Enums, cache, utilities, } from '@cornerstonejs/core';
2
+ import { createLabelmapRepresentationUID } from '../labelmapRepresentationUID';
3
+ function isPlanarNextVolumeViewport(viewport) {
4
+ const genericViewport = viewport;
5
+ return (genericViewport.type === Enums.ViewportType.PLANAR_NEXT &&
6
+ typeof genericViewport.getVolumeId === 'function' &&
7
+ typeof genericViewport.getViewReference === 'function' &&
8
+ typeof genericViewport.getViewState === 'function' &&
9
+ typeof genericViewport.addDisplaySet === 'function' &&
10
+ typeof genericViewport.setDisplaySetPresentation === 'function' &&
11
+ typeof genericViewport.setViewReference === 'function');
12
+ }
13
+ async function addLabelmapToPlanarGenericViewport(args) {
14
+ const { blendMode, labelmapLayers, segmentationId, viewport, visibility } = args;
15
+ const sourceVolumeRenderMode = getPlanarNextVolumeRenderMode(viewport);
16
+ if (!sourceVolumeRenderMode) {
17
+ return;
18
+ }
19
+ const sourceVolumeId = viewport.getVolumeId();
20
+ const sourceViewReference = sourceVolumeId
21
+ ? viewport.getViewReference({ volumeId: sourceVolumeId })
22
+ : viewport.getViewReference();
23
+ const requestedOrientation = viewport.getViewState().orientation;
24
+ const currentImageIdIndex = Math.max(0, viewport.getCurrentImageIdIndex?.() ?? 0);
25
+ let firstActorEntry;
26
+ for (const layer of labelmapLayers) {
27
+ if (!layer.volumeId) {
28
+ continue;
29
+ }
30
+ const volume = cache.getVolume(layer.volumeId);
31
+ if (!volume) {
32
+ throw new Error(`imageVolume with id: ${layer.volumeId} does not exist, you need to create/allocate the volume first`);
33
+ }
34
+ const representationUID = createLabelmapRepresentationUID({
35
+ segmentationId,
36
+ referencedId: layer.labelmapId,
37
+ });
38
+ const dataId = representationUID;
39
+ utilities.genericViewportDataSetMetadataProvider.add(dataId, {
40
+ kind: 'planar',
41
+ imageIds: volume.imageIds,
42
+ initialImageIdIndex: Math.min(currentImageIdIndex, Math.max(volume.imageIds.length - 1, 0)),
43
+ reference: {
44
+ kind: 'segmentation',
45
+ segmentationId,
46
+ representationUID,
47
+ labelmapId: layer.labelmapId,
48
+ },
49
+ volumeId: layer.volumeId,
50
+ });
51
+ await viewport.addDisplaySet(dataId, {
52
+ orientation: requestedOrientation,
53
+ role: 'overlay',
54
+ });
55
+ viewport.setDisplaySetPresentation(dataId, {
56
+ blendMode,
57
+ visible: visibility,
58
+ });
59
+ firstActorEntry ||= viewport
60
+ .getActors?.()
61
+ .find((actorEntry) => actorEntry.representationUID === representationUID);
62
+ }
63
+ viewport.setViewReference(sourceViewReference);
64
+ viewport.render?.();
65
+ if (firstActorEntry) {
66
+ return {
67
+ uid: firstActorEntry.uid,
68
+ actor: firstActorEntry.actor,
69
+ };
70
+ }
71
+ }
72
+ function getPlanarNextVolumeRenderMode(viewport) {
73
+ const renderMode = viewport.getDefaultActor?.()?.actorMapper?.renderMode;
74
+ if (renderMode === ActorRenderMode.CPU_VOLUME ||
75
+ renderMode === ActorRenderMode.VTK_VOLUME_SLICE) {
76
+ return renderMode;
77
+ }
78
+ }
79
+ export { addLabelmapToPlanarGenericViewport, isPlanarNextVolumeViewport, };
@@ -0,0 +1,3 @@
1
+ import type { Types } from '@cornerstonejs/core';
2
+ declare function removeLabelmapRepresentationFromViewport(viewport: Types.IViewport, segmentationId: string): void;
3
+ export { removeLabelmapRepresentationFromViewport };