@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,4 +1,4 @@
1
- import { BaseVolumeViewport, cache, getEnabledElement, } from '@cornerstonejs/core';
1
+ import { BaseVolumeViewport, getEnabledElement } from '@cornerstonejs/core';
2
2
  import { BaseTool } from '../base';
3
3
  import { fillInsideRectangle } from './strategies/fillRectangle';
4
4
  import { eraseInsideRectangle } from './strategies/eraseRectangle';
@@ -9,7 +9,9 @@ import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCur
9
9
  import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
10
10
  import { config as segmentationConfig, segmentLocking, segmentIndex as segmentIndexController, activeSegmentation, } from '../../stateManagement/segmentation';
11
11
  import { getCurrentLabelmapImageIdForViewport, getSegmentation, } from '../../stateManagement/segmentation/segmentationState';
12
+ import getViewportLabelmapRenderMode from '../../stateManagement/segmentation/helpers/getViewportLabelmapRenderMode';
12
13
  import LabelmapBaseTool from './LabelmapBaseTool';
14
+ import { getOrCreateLabelmapVolume, resolveLabelmapForSegment, } from '../../stateManagement/segmentation/helpers/labelmapSegmentationState';
13
15
  class RectangleScissorsTool extends LabelmapBaseTool {
14
16
  constructor(toolProps = {}, defaultToolProps = {
15
17
  supportedInteractionTypes: ['Mouse', 'Touch'],
@@ -84,13 +86,18 @@ class RectangleScissorsTool extends LabelmapBaseTool {
84
86
  referencedVolumeId: null,
85
87
  imageId: null,
86
88
  };
87
- if (viewport instanceof BaseVolumeViewport) {
88
- const { volumeId } = labelmapData;
89
- const segmentation = cache.getVolume(volumeId);
89
+ const viewportRenderMode = getViewportLabelmapRenderMode(viewport);
90
+ if (viewportRenderMode === 'volume' ||
91
+ viewport instanceof BaseVolumeViewport) {
92
+ const layer = resolveLabelmapForSegment(getSegmentation(segmentationId), segmentIndex);
93
+ const segmentation = layer ? getOrCreateLabelmapVolume(layer) : undefined;
94
+ if (!segmentation) {
95
+ return;
96
+ }
90
97
  this.editData = {
91
98
  ...this.editData,
92
- volumeId,
93
- referencedVolumeId: segmentation.referencedVolumeId,
99
+ volumeId: segmentation.volumeId,
100
+ referencedVolumeId: layer?.referencedVolumeId ?? segmentation.referencedVolumeId,
94
101
  };
95
102
  }
96
103
  else {
@@ -1,3 +1,4 @@
1
+ var _a;
1
2
  import { getEnabledElement, utilities as csUtils, getEnabledElementByViewportId, utilities, } from '@cornerstonejs/core';
2
3
  import { addAnnotation, getAllAnnotations, getAnnotations, removeAnnotation, } from '../../stateManagement/annotation/annotationState';
3
4
  import { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking';
@@ -9,7 +10,6 @@ import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnota
9
10
  import BidirectionalTool from '../annotation/BidirectionalTool';
10
11
  import { getSegmentIndexColor } from '../../stateManagement/segmentation/config/segmentationColor';
11
12
  class SegmentBidirectionalTool extends BidirectionalTool {
12
- static { this.toolName = 'SegmentBidirectional'; }
13
13
  constructor(toolProps = {}) {
14
14
  super(toolProps);
15
15
  this.renderAnnotation = (enabledElement, svgDrawingHelper) => {
@@ -173,68 +173,70 @@ class SegmentBidirectionalTool extends BidirectionalTool {
173
173
  triggerAnnotationRenderForViewportIds(viewportIdsToRender);
174
174
  return annotation;
175
175
  }
176
- static { this.hydrate = (viewportId, axis, options) => {
177
- const enabledElement = getEnabledElementByViewportId(viewportId);
178
- if (!enabledElement) {
179
- return;
180
- }
181
- const { viewport } = enabledElement;
182
- const existingAnnotations = getAllAnnotations();
183
- const toolAnnotations = existingAnnotations.filter((annotation) => annotation.metadata.toolName === 'SegmentBidirectional');
184
- const existingAnnotation = toolAnnotations.find((annotation) => {
185
- const { metadata } = annotation;
186
- if (metadata.segmentIndex === options?.segmentIndex &&
187
- metadata.segmentationId === options?.segmentationId) {
188
- return true;
189
- }
190
- return false;
191
- });
192
- if (existingAnnotation) {
193
- removeAnnotation(existingAnnotation.annotationUID);
176
+ }
177
+ _a = SegmentBidirectionalTool;
178
+ SegmentBidirectionalTool.toolName = 'SegmentBidirectional';
179
+ SegmentBidirectionalTool.hydrate = (viewportId, axis, options) => {
180
+ const enabledElement = getEnabledElementByViewportId(viewportId);
181
+ if (!enabledElement) {
182
+ return;
183
+ }
184
+ const { viewport } = enabledElement;
185
+ const existingAnnotations = getAllAnnotations();
186
+ const toolAnnotations = existingAnnotations.filter((annotation) => annotation.metadata.toolName === 'SegmentBidirectional');
187
+ const existingAnnotation = toolAnnotations.find((annotation) => {
188
+ const { metadata } = annotation;
189
+ if (metadata.segmentIndex === options?.segmentIndex &&
190
+ metadata.segmentationId === options?.segmentationId) {
191
+ return true;
194
192
  }
195
- const { FrameOfReferenceUID, referencedImageId, viewPlaneNormal, instance, } = this.hydrateBase(SegmentBidirectionalTool, enabledElement, axis[0], options);
196
- const [majorAxis, minorAxis] = axis;
197
- const [major0, major1] = majorAxis;
198
- const [minor0, minor1] = minorAxis;
199
- const points = [major0, major1, minor0, minor1];
200
- const { toolInstance, ...serializableOptions } = options || {};
201
- const annotation = {
202
- annotationUID: options?.annotationUID || utilities.uuidv4(),
203
- data: {
204
- handles: {
205
- points,
206
- activeHandleIndex: null,
207
- textBox: {
208
- hasMoved: false,
209
- worldPosition: [0, 0, 0],
210
- worldBoundingBox: {
211
- topLeft: [0, 0, 0],
212
- topRight: [0, 0, 0],
213
- bottomLeft: [0, 0, 0],
214
- bottomRight: [0, 0, 0],
215
- },
193
+ return false;
194
+ });
195
+ if (existingAnnotation) {
196
+ removeAnnotation(existingAnnotation.annotationUID);
197
+ }
198
+ const { FrameOfReferenceUID, referencedImageId, viewPlaneNormal, instance, } = _a.hydrateBase(_a, enabledElement, axis[0], options);
199
+ const [majorAxis, minorAxis] = axis;
200
+ const [major0, major1] = majorAxis;
201
+ const [minor0, minor1] = minorAxis;
202
+ const points = [major0, major1, minor0, minor1];
203
+ const { toolInstance, ...serializableOptions } = options || {};
204
+ const annotation = {
205
+ annotationUID: options?.annotationUID || utilities.uuidv4(),
206
+ data: {
207
+ handles: {
208
+ points,
209
+ activeHandleIndex: null,
210
+ textBox: {
211
+ hasMoved: false,
212
+ worldPosition: [0, 0, 0],
213
+ worldBoundingBox: {
214
+ topLeft: [0, 0, 0],
215
+ topRight: [0, 0, 0],
216
+ bottomLeft: [0, 0, 0],
217
+ bottomRight: [0, 0, 0],
216
218
  },
217
219
  },
218
- cachedStats: {},
219
220
  },
220
- highlighted: false,
221
- autoGenerated: false,
222
- invalidated: false,
223
- isLocked: false,
224
- isVisible: true,
225
- metadata: {
226
- segmentIndex: options?.segmentIndex,
227
- segmentationId: options?.segmentationId,
228
- toolName: instance.getToolName(),
229
- viewPlaneNormal,
230
- FrameOfReferenceUID,
231
- referencedImageId,
232
- ...serializableOptions,
233
- },
234
- };
235
- addAnnotation(annotation, viewport.element);
236
- triggerAnnotationRenderForViewportIds([viewport.id]);
237
- return annotation;
238
- }; }
239
- }
221
+ cachedStats: {},
222
+ },
223
+ highlighted: false,
224
+ autoGenerated: false,
225
+ invalidated: false,
226
+ isLocked: false,
227
+ isVisible: true,
228
+ metadata: {
229
+ segmentIndex: options?.segmentIndex,
230
+ segmentationId: options?.segmentationId,
231
+ toolName: instance.getToolName(),
232
+ viewPlaneNormal,
233
+ FrameOfReferenceUID,
234
+ referencedImageId,
235
+ ...serializableOptions,
236
+ },
237
+ };
238
+ addAnnotation(annotation, viewport.element);
239
+ triggerAnnotationRenderForViewportIds([viewport.id]);
240
+ return annotation;
241
+ };
240
242
  export default SegmentBidirectionalTool;
@@ -8,10 +8,6 @@ import { getHoveredContourSegmentationAnnotation, getSegmentIndexAtLabelmapBorde
8
8
  import { state } from '../../store/state';
9
9
  import { ToolModes } from '../../enums';
10
10
  class SegmentSelectTool extends BaseTool {
11
- static { this.SelectMode = {
12
- Inside: 'Inside',
13
- Border: 'Border',
14
- }; }
15
11
  constructor(toolProps = {}, defaultToolProps = {
16
12
  supportedInteractionTypes: ['Mouse', 'Touch'],
17
13
  configuration: {
@@ -98,5 +94,9 @@ class SegmentSelectTool extends BaseTool {
98
94
  triggerAnnotationRenderForViewportIds(viewportIds);
99
95
  }
100
96
  }
97
+ SegmentSelectTool.SelectMode = {
98
+ Inside: 'Inside',
99
+ Border: 'Border',
100
+ };
101
101
  SegmentSelectTool.toolName = 'SegmentSelectTool';
102
102
  export default SegmentSelectTool;
@@ -8,6 +8,7 @@ import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnota
8
8
  import { config as segmentationConfig, segmentLocking, segmentIndex as segmentIndexController, activeSegmentation, } from '../../stateManagement/segmentation';
9
9
  import { getSegmentation } from '../../stateManagement/segmentation/segmentationState';
10
10
  import LabelmapBaseTool from './LabelmapBaseTool';
11
+ import getViewportICamera from '../../utilities/getViewportICamera';
11
12
  import getEllipseWorldCoordinates from '../../utilities/getEllipseWorldCoordinates';
12
13
  import { getCenterAndRadiusInCanvas } from '../../utilities/getCenterAndRadiusInCanvas';
13
14
  class SphereScissorsTool extends LabelmapBaseTool {
@@ -35,8 +36,11 @@ class SphereScissorsTool extends LabelmapBaseTool {
35
36
  const enabledElement = getEnabledElement(element);
36
37
  const { viewport } = enabledElement;
37
38
  this.isDrawing = true;
38
- const camera = viewport.getCamera();
39
+ const camera = getViewportICamera(viewport);
39
40
  const { viewPlaneNormal, viewUp } = camera;
41
+ if (!viewPlaneNormal || !viewUp) {
42
+ throw new Error('Unable to resolve viewport view plane for scissors tool');
43
+ }
40
44
  const activeSegmentationRepresentation = activeSegmentation.getActiveSegmentation(viewport.id);
41
45
  if (!activeSegmentationRepresentation) {
42
46
  throw new Error('No active segmentation detected, create one before using scissors tool');
@@ -3,6 +3,7 @@ import { StrategyCallbacks } from '../../../enums';
3
3
  import type { LabelmapToolOperationDataAny } from '../../../types/LabelmapToolOperationData';
4
4
  import type vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
5
5
  import type { LabelmapMemo } from '../../../utilities/segmentation/createLabelmapMemo';
6
+ import type { LabelmapEditTransaction } from '../../../stateManagement/segmentation/helpers/labelmapSegmentationState';
6
7
  export type InitializedOperationData = LabelmapToolOperationDataAny & {
7
8
  operationName?: string;
8
9
  centerSegmentIndexInfo: {
@@ -48,6 +49,12 @@ export type InitializedOperationData = LabelmapToolOperationDataAny & {
48
49
  };
49
50
  memo?: LabelmapMemo;
50
51
  modified?: boolean;
52
+ previewOnHover?: boolean;
53
+ labelValue?: number;
54
+ labelmapId?: string;
55
+ overwriteSegmentIndices?: number[];
56
+ imageId?: string;
57
+ labelmapEditTransaction?: LabelmapEditTransaction;
51
58
  };
52
59
  export type StrategyFunction = (operationData: InitializedOperationData, ...args: any[]) => unknown;
53
60
  export type CompositionInstance = {
@@ -1,30 +1,10 @@
1
- import { utilities as csUtils } from '@cornerstonejs/core';
2
1
  import { triggerSegmentationDataModified } from '../../../stateManagement/segmentation/triggerSegmentationEvents';
3
2
  import compositions from './compositions';
4
3
  import { getStrategyData } from './utils/getStrategyData';
5
4
  import { StrategyCallbacks } from '../../../enums';
6
- export default class BrushStrategy {
7
- static { this.COMPOSITIONS = compositions; }
8
- static { this.childFunctions = {
9
- [StrategyCallbacks.OnInteractionStart]: addListMethod(StrategyCallbacks.OnInteractionStart, StrategyCallbacks.Initialize),
10
- [StrategyCallbacks.OnInteractionEnd]: addListMethod(StrategyCallbacks.OnInteractionEnd, StrategyCallbacks.Initialize),
11
- [StrategyCallbacks.Fill]: addListMethod(StrategyCallbacks.Fill),
12
- [StrategyCallbacks.Initialize]: addListMethod(StrategyCallbacks.Initialize),
13
- [StrategyCallbacks.CreateIsInThreshold]: addSingletonMethod(StrategyCallbacks.CreateIsInThreshold),
14
- [StrategyCallbacks.Interpolate]: addListMethod(StrategyCallbacks.Interpolate, StrategyCallbacks.Initialize),
15
- [StrategyCallbacks.AcceptPreview]: addListMethod(StrategyCallbacks.AcceptPreview, StrategyCallbacks.Initialize),
16
- [StrategyCallbacks.RejectPreview]: addListMethod(StrategyCallbacks.RejectPreview, StrategyCallbacks.Initialize),
17
- [StrategyCallbacks.INTERNAL_setValue]: addSingletonMethod(StrategyCallbacks.INTERNAL_setValue),
18
- [StrategyCallbacks.Preview]: addSingletonMethod(StrategyCallbacks.Preview, false),
19
- [StrategyCallbacks.ComputeInnerCircleRadius]: addListMethod(StrategyCallbacks.ComputeInnerCircleRadius),
20
- [StrategyCallbacks.EnsureSegmentationVolumeFor3DManipulation]: addListMethod(StrategyCallbacks.EnsureSegmentationVolumeFor3DManipulation),
21
- [StrategyCallbacks.EnsureImageVolumeFor3DManipulation]: addListMethod(StrategyCallbacks.EnsureImageVolumeFor3DManipulation),
22
- [StrategyCallbacks.AddPreview]: addListMethod(StrategyCallbacks.AddPreview),
23
- [StrategyCallbacks.GetStatistics]: addSingletonMethod(StrategyCallbacks.GetStatistics),
24
- [StrategyCallbacks.CalculateCursorGeometry]: addSingletonMethod(StrategyCallbacks.CalculateCursorGeometry, true),
25
- [StrategyCallbacks.RenderCursor]: addSingletonMethod(StrategyCallbacks.RenderCursor, true),
26
- compositions: null,
27
- }; }
5
+ import { eraseCrossLayerOverwrites, prepareOverlapOperationData, } from './utils/labelmapOverlap';
6
+ import { shouldUseLazyLabelmapEditing } from '../utils/shouldUseLazyLabelmapEditing';
7
+ class BrushStrategy {
28
8
  constructor(name, ...initializers) {
29
9
  this._initialize = [];
30
10
  this._fill = [];
@@ -34,9 +14,30 @@ export default class BrushStrategy {
34
14
  if (!initializedData) {
35
15
  return;
36
16
  }
17
+ const isLazyLabelmapEditing = shouldUseLazyLabelmapEditing(initializedData.viewport);
18
+ const shouldPrepareOverlap = !isLazyLabelmapEditing || !initializedData.previewOnHover;
19
+ const originalSegmentationVoxelManager = initializedData.segmentationVoxelManager;
20
+ const originalSegmentationImageData = initializedData.segmentationImageData;
21
+ if (shouldPrepareOverlap) {
22
+ prepareOverlapOperationData(initializedData);
23
+ }
24
+ if (initializedData.memo?.segmentationVoxelManager !==
25
+ initializedData.segmentationVoxelManager) {
26
+ initializedData.memo = initializedData.createMemo(initializedData.segmentationId, initializedData.segmentationVoxelManager);
27
+ }
28
+ if (initializedData.segmentationVoxelManager !==
29
+ originalSegmentationVoxelManager ||
30
+ initializedData.segmentationImageData !== originalSegmentationImageData) {
31
+ this._initialize.forEach((func) => func(initializedData));
32
+ }
37
33
  this._fill.forEach((func) => func(initializedData));
38
34
  const { segmentationVoxelManager, segmentIndex } = initializedData;
39
- triggerSegmentationDataModified(initializedData.segmentationId, segmentationVoxelManager.getArrayOfModifiedSlices(), segmentIndex);
35
+ const crossLayerModifiedSlices = eraseCrossLayerOverwrites(initializedData);
36
+ const modifiedSlices = new Set([
37
+ ...(segmentationVoxelManager.getArrayOfModifiedSlices() ?? []),
38
+ ...crossLayerModifiedSlices,
39
+ ]);
40
+ triggerSegmentationDataModified(initializedData.segmentationId, Array.from(modifiedSlices), segmentIndex);
40
41
  return initializedData;
41
42
  };
42
43
  this.onInteractionStart = (enabledElement, operationData) => {
@@ -116,6 +117,28 @@ export default class BrushStrategy {
116
117
  return initializedData;
117
118
  }
118
119
  }
120
+ BrushStrategy.COMPOSITIONS = compositions;
121
+ BrushStrategy.childFunctions = {
122
+ [StrategyCallbacks.OnInteractionStart]: addListMethod(StrategyCallbacks.OnInteractionStart, StrategyCallbacks.Initialize),
123
+ [StrategyCallbacks.OnInteractionEnd]: addListMethod(StrategyCallbacks.OnInteractionEnd, StrategyCallbacks.Initialize),
124
+ [StrategyCallbacks.Fill]: addListMethod(StrategyCallbacks.Fill),
125
+ [StrategyCallbacks.Initialize]: addListMethod(StrategyCallbacks.Initialize),
126
+ [StrategyCallbacks.CreateIsInThreshold]: addSingletonMethod(StrategyCallbacks.CreateIsInThreshold),
127
+ [StrategyCallbacks.Interpolate]: addListMethod(StrategyCallbacks.Interpolate, StrategyCallbacks.Initialize),
128
+ [StrategyCallbacks.AcceptPreview]: addListMethod(StrategyCallbacks.AcceptPreview, StrategyCallbacks.Initialize),
129
+ [StrategyCallbacks.RejectPreview]: addListMethod(StrategyCallbacks.RejectPreview, StrategyCallbacks.Initialize),
130
+ [StrategyCallbacks.INTERNAL_setValue]: addSingletonMethod(StrategyCallbacks.INTERNAL_setValue),
131
+ [StrategyCallbacks.Preview]: addSingletonMethod(StrategyCallbacks.Preview, false),
132
+ [StrategyCallbacks.ComputeInnerCircleRadius]: addListMethod(StrategyCallbacks.ComputeInnerCircleRadius),
133
+ [StrategyCallbacks.EnsureSegmentationVolumeFor3DManipulation]: addListMethod(StrategyCallbacks.EnsureSegmentationVolumeFor3DManipulation),
134
+ [StrategyCallbacks.EnsureImageVolumeFor3DManipulation]: addListMethod(StrategyCallbacks.EnsureImageVolumeFor3DManipulation),
135
+ [StrategyCallbacks.AddPreview]: addListMethod(StrategyCallbacks.AddPreview),
136
+ [StrategyCallbacks.GetStatistics]: addSingletonMethod(StrategyCallbacks.GetStatistics),
137
+ [StrategyCallbacks.CalculateCursorGeometry]: addSingletonMethod(StrategyCallbacks.CalculateCursorGeometry, true),
138
+ [StrategyCallbacks.RenderCursor]: addSingletonMethod(StrategyCallbacks.RenderCursor, true),
139
+ compositions: null,
140
+ };
141
+ export default BrushStrategy;
119
142
  function addListMethod(name, createInitialized) {
120
143
  const listName = `_${name}`;
121
144
  return (brushStrategy, func) => {
@@ -1,7 +1,7 @@
1
1
  import { vec3 } from 'gl-matrix';
2
2
  import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
3
- import { drawCircle as drawCircleSvg } from '../../../../drawingSvg';
4
- import { getCenterAndRadiusInCanvas } from '../../../../utilities/getCenterAndRadiusInCanvas';
3
+ import { drawCircle as drawCircleSvg, drawPath as drawPathSvg, } from '../../../../drawingSvg';
4
+ import getViewportICamera from '../../../../utilities/getViewportICamera';
5
5
  export default {
6
6
  [StrategyCallbacks.CalculateCursorGeometry]: function (enabledElement, operationData) {
7
7
  if (!operationData) {
@@ -9,8 +9,11 @@ export default {
9
9
  }
10
10
  const { configuration, activeStrategy, hoverData } = operationData;
11
11
  const { viewport } = enabledElement;
12
- const camera = viewport.getCamera();
12
+ const camera = getViewportICamera(viewport);
13
13
  const { brushSize } = configuration;
14
+ if (!camera.viewUp || !camera.viewPlaneNormal) {
15
+ return;
16
+ }
14
17
  const viewUp = vec3.fromValues(camera.viewUp[0], camera.viewUp[1], camera.viewUp[2]);
15
18
  const viewPlaneNormal = vec3.fromValues(camera.viewPlaneNormal[0], camera.viewPlaneNormal[1], camera.viewPlaneNormal[2]);
16
19
  const viewRight = vec3.create();
@@ -45,6 +48,7 @@ export default {
45
48
  leftCursorInWorld,
46
49
  rightCursorInWorld,
47
50
  ];
51
+ data.editPoints = [...data.handles.points];
48
52
  const strategy = configuration.strategies[activeStrategy];
49
53
  if (typeof strategy?.computeInnerCircleRadius === 'function') {
50
54
  strategy.computeInnerCircleRadius({
@@ -65,28 +69,58 @@ export default {
65
69
  if (!toolMetadata) {
66
70
  return;
67
71
  }
68
- const annotationUID = toolMetadata.brushCursorUID;
72
+ const annotationUID = toolMetadata.brushCursorUID || 'brushCursor';
69
73
  const data = brushCursor.data;
70
- const { points } = data.handles;
71
- const { center, radius } = getCenterAndRadiusInCanvas(points, viewport);
72
74
  const color = `rgb(${toolMetadata.segmentColor?.slice(0, 3) || [0, 0, 0]})`;
73
75
  if (!viewport.getRenderingEngine()) {
74
76
  console.warn('Rendering Engine has been destroyed');
75
77
  return;
76
78
  }
77
- const circleUID = '0';
78
- drawCircleSvg(svgDrawingHelper, annotationUID, circleUID, center, radius, {
79
- color,
80
- lineDash: this.centerSegmentIndexInfo.segmentIndex === 0 ? [1, 2] : null,
81
- });
79
+ const points = data.handles?.points || [];
80
+ const totalCircles = Math.floor((points?.length || 0) / 4);
81
+ const circleGeometries = [];
82
+ for (let i = 0; i < points.length; i += 4) {
83
+ const circlePoints = points.slice(i, i + 4);
84
+ if (circlePoints.length < 2) {
85
+ continue;
86
+ }
87
+ const canvasCoordinates = circlePoints.map((p) => viewport.worldToCanvas(p));
88
+ const bottom = canvasCoordinates[0];
89
+ const top = canvasCoordinates[1];
90
+ const center = [
91
+ Math.floor((bottom[0] + top[0]) / 2),
92
+ Math.floor((bottom[1] + top[1]) / 2),
93
+ ];
94
+ const radius = Math.round(Math.abs(bottom[1] - center[1]));
95
+ circleGeometries.push({ center, radius });
96
+ }
97
+ const currentCircle = circleGeometries[circleGeometries.length - 1];
98
+ if (circleGeometries.length > 1) {
99
+ drawPathSvg(svgDrawingHelper, annotationUID, 'stroke-preview', circleGeometries.map((circle) => circle.center), {
100
+ color,
101
+ lineWidth: currentCircle.radius * 2,
102
+ strokeOpacity: 0.35,
103
+ lineCap: 'round',
104
+ lineJoin: 'round',
105
+ lineDash: this.centerSegmentIndexInfo.segmentIndex === 0 ? '6,4' : undefined,
106
+ });
107
+ }
108
+ if (currentCircle) {
109
+ drawCircleSvg(svgDrawingHelper, annotationUID, 'current-circle', currentCircle.center, currentCircle.radius, {
110
+ color,
111
+ lineWidth: 2,
112
+ strokeOpacity: 1,
113
+ lineDash: this.centerSegmentIndexInfo.segmentIndex === 0 ? [1, 2] : null,
114
+ }, 'brush-cursor');
115
+ }
82
116
  const { dynamicRadiusInCanvas } = configuration?.threshold || {
83
117
  dynamicRadiusInCanvas: 0,
84
118
  };
85
- if (dynamicRadiusInCanvas) {
86
- const circleUID1 = '1';
87
- drawCircleSvg(svgDrawingHelper, annotationUID, circleUID1, center, dynamicRadiusInCanvas, {
119
+ if (dynamicRadiusInCanvas && currentCircle) {
120
+ const circleUID1 = 'dynamic-radius';
121
+ drawCircleSvg(svgDrawingHelper, annotationUID, circleUID1, currentCircle.center, dynamicRadiusInCanvas, {
88
122
  color,
89
- });
123
+ }, 'brush-cursor');
90
124
  }
91
125
  },
92
126
  };
@@ -1,7 +1,7 @@
1
1
  import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
2
2
  export default {
3
3
  [StrategyCallbacks.OnInteractionStart]: (operationData) => {
4
- const { segmentIndex, previewSegmentIndex, segmentationVoxelManager, centerIJK, viewPlaneNormal, segmentationImageData, configuration, } = operationData;
4
+ const { segmentIndex, labelValue, previewSegmentIndex, segmentationVoxelManager, centerIJK, viewPlaneNormal, segmentationImageData, configuration, } = operationData;
5
5
  if (!configuration?.useCenterSegmentIndex) {
6
6
  operationData.centerSegmentIndexInfo.segmentIndex = null;
7
7
  operationData.centerSegmentIndexInfo.hasSegmentIndex = false;
@@ -23,7 +23,7 @@ export default {
23
23
  nestedBounds[2] = [centerIJK[2], centerIJK[2]];
24
24
  }
25
25
  const callback = ({ value }) => {
26
- hasSegmentIndex ||= value === segmentIndex;
26
+ hasSegmentIndex ||= value === (labelValue ?? segmentIndex);
27
27
  hasPreviewIndex ||= value === previewSegmentIndex;
28
28
  };
29
29
  segmentationVoxelManager.forEach(callback, {
@@ -1,5 +1,6 @@
1
1
  import { vec3 } from 'gl-matrix';
2
2
  import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
3
+ import getViewportICamera from '../../../../utilities/getViewportICamera';
3
4
  export default {
4
5
  [StrategyCallbacks.Initialize]: (operationData) => {
5
6
  const { operationName, centerIJK, segmentationVoxelManager, imageVoxelManager, configuration, segmentIndex, viewport, } = operationData;
@@ -13,7 +14,10 @@ export default {
13
14
  const boundsIJK = segmentationVoxelManager.getBoundsIJK();
14
15
  const { range: oldThreshold, dynamicRadius = 0 } = configuration.threshold;
15
16
  const useDelta = oldThreshold ? 0 : dynamicRadius;
16
- const { viewPlaneNormal } = viewport.getCamera();
17
+ const { viewPlaneNormal } = getViewportICamera(viewport);
18
+ if (!viewPlaneNormal) {
19
+ return;
20
+ }
17
21
  const nestedBounds = boundsIJK.map((ijk, idx) => {
18
22
  const [min, max] = ijk;
19
23
  return [
@@ -3,7 +3,7 @@ import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
3
3
  import IslandRemoval from '../../../../utilities/segmentation/islandRemoval';
4
4
  export default {
5
5
  [StrategyCallbacks.OnInteractionEnd]: (operationData) => {
6
- const { previewSegmentIndex, segmentIndex, viewport, segmentationVoxelManager, activeStrategy, memo, } = operationData;
6
+ const { previewSegmentIndex, segmentIndex, labelValue, viewport, segmentationVoxelManager, activeStrategy, memo, } = operationData;
7
7
  if (activeStrategy !== 'THRESHOLD_INSIDE_SPHERE_WITH_ISLAND_REMOVAL' ||
8
8
  segmentIndex === null) {
9
9
  return;
@@ -12,7 +12,7 @@ export default {
12
12
  const voxelManager = memo?.voxelManager || segmentationVoxelManager;
13
13
  if (!islandRemoval.initialize(viewport, voxelManager, {
14
14
  previewSegmentIndex,
15
- segmentIndex,
15
+ segmentIndex: labelValue ?? segmentIndex,
16
16
  })) {
17
17
  return;
18
18
  }
@@ -29,7 +29,7 @@ export default {
29
29
  operationData.modified = true;
30
30
  },
31
31
  [StrategyCallbacks.AcceptPreview]: (operationData) => {
32
- const { previewSegmentIndex, segmentationVoxelManager, memo, segmentIndex, centerSegmentIndexInfo, } = operationData || {};
32
+ const { previewSegmentIndex, segmentationVoxelManager, memo, segmentIndex, labelValue, centerSegmentIndexInfo, } = operationData || {};
33
33
  const { changedIndices } = centerSegmentIndexInfo || {};
34
34
  const labelmapMemo = memo;
35
35
  const callback = ({ index }) => {
@@ -41,7 +41,7 @@ export default {
41
41
  }
42
42
  else {
43
43
  if (oldValue === previewSegmentIndex) {
44
- labelmapMemo.voxelManager.setAtIndex(index, segmentIndex);
44
+ labelmapMemo.voxelManager.setAtIndex(index, labelValue ?? segmentIndex);
45
45
  }
46
46
  }
47
47
  };
@@ -1,25 +1,33 @@
1
1
  import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
2
2
  import { handleUseSegmentCenterIndex } from '../utils/handleUseSegmentCenterIndex';
3
+ import { getSegmentation } from '../../../../stateManagement/segmentation/getSegmentation';
4
+ import { getSegmentIndexForLabelValue } from '../../../../stateManagement/segmentation/helpers/labelmapSegmentationState';
3
5
  export default {
4
6
  [StrategyCallbacks.INTERNAL_setValue]: (operationData, { value, index }) => {
5
- const { segmentsLocked, previewSegmentIndex, memo, segmentationVoxelManager, centerSegmentIndexInfo, segmentIndex, } = operationData;
7
+ const { segmentsLocked, previewSegmentIndex, memo, segmentationVoxelManager, centerSegmentIndexInfo, segmentIndex, labelValue, labelmapId, segmentationId, } = operationData;
6
8
  const existingValue = segmentationVoxelManager.getAtIndex(index);
7
- if (segmentsLocked.includes(value)) {
9
+ const segmentation = getSegmentation(segmentationId);
10
+ const existingSegmentIndex = segmentation && labelmapId
11
+ ? getSegmentIndexForLabelValue(segmentation, labelmapId, existingValue)
12
+ : existingValue;
13
+ const writeValue = previewSegmentIndex ?? labelValue ?? segmentIndex;
14
+ if (segmentsLocked.includes(existingSegmentIndex)) {
8
15
  return;
9
16
  }
10
- if (!centerSegmentIndexInfo && existingValue === segmentIndex) {
17
+ if (!centerSegmentIndexInfo &&
18
+ existingValue === (labelValue ?? segmentIndex)) {
11
19
  return;
12
20
  }
13
21
  if (centerSegmentIndexInfo?.segmentIndex !== 0 &&
14
- existingValue === segmentIndex) {
22
+ existingValue === (labelValue ?? segmentIndex)) {
15
23
  return;
16
24
  }
17
25
  if (centerSegmentIndexInfo?.segmentIndex === null) {
18
- memo.voxelManager.setAtIndex(index, previewSegmentIndex ?? segmentIndex);
26
+ memo.voxelManager.setAtIndex(index, writeValue);
19
27
  return;
20
28
  }
21
29
  if (!previewSegmentIndex) {
22
- let useSegmentIndex = segmentIndex;
30
+ let useSegmentIndex = labelValue ?? segmentIndex;
23
31
  if (centerSegmentIndexInfo) {
24
32
  useSegmentIndex = centerSegmentIndexInfo.segmentIndex;
25
33
  }
@@ -0,0 +1,4 @@
1
+ import type { InitializedOperationData } from '../BrushStrategy';
2
+ declare function collectCrossLayerEraseBindingsForOperation(operationData: InitializedOperationData): void;
3
+ declare function eraseCrossLayerOverwrites(operationData: InitializedOperationData): number[];
4
+ export { collectCrossLayerEraseBindingsForOperation as collectCrossLayerEraseBindings, eraseCrossLayerOverwrites, };
@@ -0,0 +1,23 @@
1
+ import { getSegmentation } from '../../../../stateManagement/segmentation/getSegmentation';
2
+ import { collectCrossLayerEraseBindings, eraseLabelmapEditTransactionOverwrites, } from '../../../../stateManagement/segmentation/helpers/labelmapSegmentationState';
3
+ function collectCrossLayerEraseBindingsForOperation(operationData) {
4
+ const { segmentationId, labelmapId, overwriteSegmentIndices } = operationData;
5
+ const segmentation = getSegmentation(segmentationId);
6
+ operationData.crossLayerEraseBindings = segmentation
7
+ ? collectCrossLayerEraseBindings(segmentation, labelmapId, overwriteSegmentIndices)
8
+ : [];
9
+ }
10
+ function eraseCrossLayerOverwrites(operationData) {
11
+ const segmentation = getSegmentation(operationData.segmentationId);
12
+ if (!segmentation) {
13
+ return [];
14
+ }
15
+ return eraseLabelmapEditTransactionOverwrites(segmentation, operationData.labelmapEditTransaction, {
16
+ viewport: operationData.viewport,
17
+ referenceImageData: operationData.segmentationImageData,
18
+ isInObject: operationData.isInObject,
19
+ isInObjectBoundsIJK: operationData.isInObjectBoundsIJK,
20
+ imageId: operationData.imageId,
21
+ });
22
+ }
23
+ export { collectCrossLayerEraseBindingsForOperation as collectCrossLayerEraseBindings, eraseCrossLayerOverwrites, };
@@ -54,7 +54,7 @@ function getStrategyDataForStackViewport({ operationData, viewport, strategy, })
54
54
  if (!labelmapImageId) {
55
55
  return null;
56
56
  }
57
- const actorEntry = getLabelmapActorEntry(viewport.id, segmentationId);
57
+ const actorEntry = getLabelmapActorEntry(viewport.id, segmentationId, labelmapImageId);
58
58
  if (!actorEntry) {
59
59
  return null;
60
60
  }