@cornerstonejs/tools 5.0.0-beta.1 → 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 (285) 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/index.d.ts +2 -2
  18. package/dist/esm/index.js +2 -2
  19. package/dist/esm/init.js +2 -0
  20. package/dist/esm/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.js +10 -4
  21. package/dist/esm/stateManagement/segmentation/SegmentationRenderingEngine.js +23 -20
  22. package/dist/esm/stateManagement/segmentation/SegmentationRepresentationDisplayRegistry.d.ts +12 -0
  23. package/dist/esm/stateManagement/segmentation/SegmentationRepresentationDisplayRegistry.js +7 -0
  24. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.d.ts +1 -10
  25. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.js +28 -149
  26. package/dist/esm/stateManagement/segmentation/addColorLUT.js +7 -1
  27. package/dist/esm/stateManagement/segmentation/getCurrentLabelmapImageIdForViewport.js +16 -1
  28. package/dist/esm/stateManagement/segmentation/helpers/clearSegmentValue.js +9 -7
  29. package/dist/esm/stateManagement/segmentation/helpers/getSegmentationActor.d.ts +1 -1
  30. package/dist/esm/stateManagement/segmentation/helpers/getSegmentationActor.js +3 -2
  31. package/dist/esm/stateManagement/segmentation/helpers/getViewportLabelmapRenderMode.d.ts +5 -0
  32. package/dist/esm/stateManagement/segmentation/helpers/getViewportLabelmapRenderMode.js +58 -0
  33. package/dist/esm/stateManagement/segmentation/helpers/labelmapImageMapperSupport.d.ts +52 -0
  34. package/dist/esm/stateManagement/segmentation/helpers/labelmapImageMapperSupport.js +246 -0
  35. package/dist/esm/stateManagement/segmentation/helpers/labelmapSegmentationState.d.ts +1 -0
  36. package/dist/esm/stateManagement/segmentation/helpers/labelmapSegmentationState.js +1 -0
  37. package/dist/esm/stateManagement/segmentation/helpers/normalizeSegmentationInput.js +12 -1
  38. package/dist/esm/stateManagement/segmentation/internalAddSegmentationRepresentation.js +3 -3
  39. package/dist/esm/stateManagement/segmentation/labelmapModel/index.d.ts +9 -0
  40. package/dist/esm/stateManagement/segmentation/labelmapModel/index.js +7 -0
  41. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapEditTransaction.d.ts +54 -0
  42. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapEditTransaction.js +224 -0
  43. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageIdMapping.d.ts +6 -0
  44. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageIdMapping.js +39 -0
  45. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageReferenceResolver.d.ts +23 -0
  46. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageReferenceResolver.js +269 -0
  47. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLayerStore.d.ts +15 -0
  48. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLayerStore.js +160 -0
  49. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLegacyAdapter.d.ts +4 -0
  50. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLegacyAdapter.js +42 -0
  51. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapSegmentBindings.d.ts +11 -0
  52. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapSegmentBindings.js +73 -0
  53. package/dist/esm/stateManagement/segmentation/labelmapModel/normalizeLabelmapSegmentationData.d.ts +17 -0
  54. package/dist/esm/stateManagement/segmentation/labelmapModel/normalizeLabelmapSegmentationData.js +75 -0
  55. package/dist/esm/stateManagement/segmentation/labelmapModel/privateLabelmap.d.ts +5 -0
  56. package/dist/esm/stateManagement/segmentation/labelmapModel/privateLabelmap.js +106 -0
  57. package/dist/esm/stateManagement/segmentation/models/SegmentModel.d.ts +11 -0
  58. package/dist/esm/stateManagement/segmentation/models/SegmentModel.js +19 -0
  59. package/dist/esm/stateManagement/segmentation/models/SegmentationModel.d.ts +12 -0
  60. package/dist/esm/stateManagement/segmentation/models/SegmentationModel.js +23 -0
  61. package/dist/esm/stateManagement/segmentation/removeSegmentationRepresentations.js +6 -10
  62. package/dist/esm/stateManagement/segmentation/segmentIndex.js +24 -0
  63. package/dist/esm/stateManagement/segmentation/segmentationEventManager.js +2 -9
  64. package/dist/esm/stateManagement/segmentation/segmentationState.d.ts +2 -1
  65. package/dist/esm/stateManagement/segmentation/segmentationState.js +4 -1
  66. package/dist/esm/store/SynchronizerManager/Synchronizer.d.ts +3 -1
  67. package/dist/esm/store/state.js +2 -1
  68. package/dist/esm/synchronizers/callbacks/imageSliceSyncCallback.js +12 -3
  69. package/dist/esm/synchronizers/callbacks/presentationViewSyncCallback.js +5 -2
  70. package/dist/esm/synchronizers/callbacks/zoomPanSyncCallback.js +51 -3
  71. package/dist/esm/synchronizers/synchronizers/createPresentationViewSynchronizer.d.ts +1 -1
  72. package/dist/esm/tools/AdvancedMagnifyTool.js +4 -1
  73. package/dist/esm/tools/CrosshairsTool.d.ts +4 -0
  74. package/dist/esm/tools/CrosshairsTool.js +95 -41
  75. package/dist/esm/tools/MagnifyTool.js +3 -1
  76. package/dist/esm/tools/OrientationControllerTool.d.ts +45 -0
  77. package/dist/esm/tools/OrientationControllerTool.js +454 -0
  78. package/dist/esm/tools/OrientationMarkerTool.js +4 -4
  79. package/dist/esm/tools/PanTool.js +26 -3
  80. package/dist/esm/tools/PlanarRotateTool.js +19 -4
  81. package/dist/esm/tools/ReferenceCursors.js +7 -1
  82. package/dist/esm/tools/SculptorTool/CircleSculptCursor.js +1 -1
  83. package/dist/esm/tools/TrackballRotateTool.js +3 -2
  84. package/dist/esm/tools/VolumeCroppingControlTool.d.ts +10 -35
  85. package/dist/esm/tools/VolumeCroppingControlTool.js +179 -699
  86. package/dist/esm/tools/VolumeCroppingTool.d.ts +34 -32
  87. package/dist/esm/tools/VolumeCroppingTool.js +813 -532
  88. package/dist/esm/tools/WindowLevelTool.d.ts +2 -1
  89. package/dist/esm/tools/WindowLevelTool.js +48 -4
  90. package/dist/esm/tools/ZoomTool.d.ts +8 -0
  91. package/dist/esm/tools/ZoomTool.js +92 -11
  92. package/dist/esm/tools/annotation/AngleTool.js +38 -32
  93. package/dist/esm/tools/annotation/ArrowAnnotateTool.js +30 -28
  94. package/dist/esm/tools/annotation/BidirectionalTool.js +51 -49
  95. package/dist/esm/tools/annotation/CircleROITool.d.ts +1 -0
  96. package/dist/esm/tools/annotation/CircleROITool.js +89 -51
  97. package/dist/esm/tools/annotation/CobbAngleTool.js +1 -1
  98. package/dist/esm/tools/annotation/DragProbeTool.js +1 -1
  99. package/dist/esm/tools/annotation/ETDRSGridTool.js +1 -1
  100. package/dist/esm/tools/annotation/EllipticalROITool.js +46 -39
  101. package/dist/esm/tools/annotation/HeightTool.js +1 -1
  102. package/dist/esm/tools/annotation/KeyImageTool.js +11 -11
  103. package/dist/esm/tools/annotation/LabelTool.js +37 -35
  104. package/dist/esm/tools/annotation/LengthTool.js +35 -33
  105. package/dist/esm/tools/annotation/LivewireContourSegmentationTool.js +6 -4
  106. package/dist/esm/tools/annotation/LivewireContourTool.js +4 -8
  107. package/dist/esm/tools/annotation/PlanarFreehandContourSegmentationTool.js +6 -4
  108. package/dist/esm/tools/annotation/PlanarFreehandROITool.js +3 -4
  109. package/dist/esm/tools/annotation/ProbeTool.js +66 -56
  110. package/dist/esm/tools/annotation/RectangleROITool.js +48 -37
  111. package/dist/esm/tools/annotation/RegionSegmentPlusTool.js +1 -1
  112. package/dist/esm/tools/annotation/RegionSegmentTool.js +1 -1
  113. package/dist/esm/tools/annotation/SplineContourSegmentationTool.js +1 -1
  114. package/dist/esm/tools/annotation/SplineROITool.js +60 -56
  115. package/dist/esm/tools/annotation/UltrasoundDirectionalTool.js +1 -1
  116. package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/UltrasoundPleuraBLineTool.js +57 -55
  117. package/dist/esm/tools/annotation/VideoRedactionTool.js +1 -1
  118. package/dist/esm/tools/base/AnnotationDisplayTool.js +9 -6
  119. package/dist/esm/tools/base/AnnotationTool.js +2 -1
  120. package/dist/esm/tools/base/BaseTool.js +16 -10
  121. package/dist/esm/tools/base/ContourSegmentationBaseTool.js +1 -1
  122. package/dist/esm/tools/base/GrowCutBaseTool.js +2 -2
  123. package/dist/esm/tools/displayTools/Labelmap/addLabelmapToElement.d.ts +2 -4
  124. package/dist/esm/tools/displayTools/Labelmap/addLabelmapToElement.js +15 -85
  125. package/dist/esm/tools/displayTools/Labelmap/labelmapActorStyle.d.ts +5 -0
  126. package/dist/esm/tools/displayTools/Labelmap/labelmapActorStyle.js +191 -0
  127. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.d.ts +4 -3
  128. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.js +48 -209
  129. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/createLabelmapRenderPlan.d.ts +3 -0
  130. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/createLabelmapRenderPlan.js +51 -0
  131. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/index.d.ts +4 -0
  132. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/index.js +3 -0
  133. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/legacyVolumePlan.d.ts +14 -0
  134. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/legacyVolumePlan.js +143 -0
  135. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/planarGenericVolumeLabelmap.d.ts +40 -0
  136. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/planarGenericVolumeLabelmap.js +79 -0
  137. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/removeLabelmapRepresentationFromViewport.d.ts +3 -0
  138. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/removeLabelmapRepresentationFromViewport.js +18 -0
  139. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/resolveLabelmapRenderPlan.d.ts +9 -0
  140. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/resolveLabelmapRenderPlan.js +56 -0
  141. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/stackImagePlan.d.ts +11 -0
  142. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/stackImagePlan.js +35 -0
  143. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/types.d.ts +48 -0
  144. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/types.js +0 -0
  145. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/volumeSliceImageMapperPlan.d.ts +13 -0
  146. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/volumeSliceImageMapperPlan.js +34 -0
  147. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan.d.ts +2 -0
  148. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan.js +1 -0
  149. package/dist/esm/tools/displayTools/Labelmap/labelmapRepresentationUID.d.ts +8 -0
  150. package/dist/esm/tools/displayTools/Labelmap/labelmapRepresentationUID.js +18 -0
  151. package/dist/esm/tools/displayTools/Labelmap/removeLabelmapFromElement.js +2 -2
  152. package/dist/esm/tools/displayTools/Labelmap/removeLabelmapRepresentationData.d.ts +3 -0
  153. package/dist/esm/tools/displayTools/Labelmap/removeLabelmapRepresentationData.js +16 -0
  154. package/dist/esm/tools/displayTools/Labelmap/syncStackLabelmapActors.d.ts +2 -0
  155. package/dist/esm/tools/displayTools/Labelmap/syncStackLabelmapActors.js +135 -0
  156. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapImageMapper.d.ts +16 -0
  157. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapImageMapper.js +267 -0
  158. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapSliceData.d.ts +27 -0
  159. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapSliceData.js +185 -0
  160. package/dist/esm/tools/displayTools/registerBuiltInSegmentationRepresentationDisplays.d.ts +1 -0
  161. package/dist/esm/tools/displayTools/registerBuiltInSegmentationRepresentationDisplays.js +16 -0
  162. package/dist/esm/tools/index.d.ts +2 -1
  163. package/dist/esm/tools/index.js +2 -1
  164. package/dist/esm/tools/segmentation/BrushTool.d.ts +9 -2
  165. package/dist/esm/tools/segmentation/BrushTool.js +123 -26
  166. package/dist/esm/tools/segmentation/CircleScissorsTool.js +19 -36
  167. package/dist/esm/tools/segmentation/LabelmapBaseTool.d.ts +2 -3
  168. package/dist/esm/tools/segmentation/LabelmapBaseTool.js +77 -46
  169. package/dist/esm/tools/segmentation/LabelmapEditWithContour.js +3 -3
  170. package/dist/esm/tools/segmentation/PaintFillTool.js +11 -4
  171. package/dist/esm/tools/segmentation/RectangleROIStartEndThresholdTool.d.ts +2 -0
  172. package/dist/esm/tools/segmentation/RectangleROIStartEndThresholdTool.js +16 -8
  173. package/dist/esm/tools/segmentation/RectangleScissorsTool.js +13 -6
  174. package/dist/esm/tools/segmentation/SegmentBidirectionalTool.js +63 -61
  175. package/dist/esm/tools/segmentation/SegmentSelectTool.js +4 -4
  176. package/dist/esm/tools/segmentation/SphereScissorsTool.js +11 -31
  177. package/dist/esm/tools/segmentation/strategies/BrushStrategy.d.ts +7 -0
  178. package/dist/esm/tools/segmentation/strategies/BrushStrategy.js +47 -24
  179. package/dist/esm/tools/segmentation/strategies/compositions/circularCursor.js +49 -21
  180. package/dist/esm/tools/segmentation/strategies/compositions/determineSegmentIndex.js +2 -2
  181. package/dist/esm/tools/segmentation/strategies/compositions/dynamicThreshold.js +5 -1
  182. package/dist/esm/tools/segmentation/strategies/compositions/islandRemovalComposition.js +2 -2
  183. package/dist/esm/tools/segmentation/strategies/compositions/preview.js +2 -2
  184. package/dist/esm/tools/segmentation/strategies/compositions/setValue.js +14 -6
  185. package/dist/esm/tools/segmentation/strategies/fillCircle.d.ts +3 -1
  186. package/dist/esm/tools/segmentation/strategies/fillCircle.js +38 -31
  187. package/dist/esm/tools/segmentation/strategies/fillSphere.js +11 -3
  188. package/dist/esm/tools/segmentation/strategies/utils/crossLayerErase.d.ts +4 -0
  189. package/dist/esm/tools/segmentation/strategies/utils/crossLayerErase.js +23 -0
  190. package/dist/esm/tools/segmentation/strategies/utils/getStrategyData.js +1 -1
  191. package/dist/esm/tools/segmentation/strategies/utils/handleUseSegmentCenterIndex.js +12 -11
  192. package/dist/esm/tools/segmentation/strategies/utils/labelmapOverlap.d.ts +4 -0
  193. package/dist/esm/tools/segmentation/strategies/utils/labelmapOverlap.js +41 -0
  194. package/dist/esm/tools/segmentation/strategies/utils/overwritePolicy.d.ts +3 -0
  195. package/dist/esm/tools/segmentation/strategies/utils/overwritePolicy.js +31 -0
  196. package/dist/esm/tools/segmentation/strategies/utils/segmentSeparation.d.ts +3 -0
  197. package/dist/esm/tools/segmentation/strategies/utils/segmentSeparation.js +38 -0
  198. package/dist/esm/tools/segmentation/utils/LazyBrushEditController.d.ts +19 -0
  199. package/dist/esm/tools/segmentation/utils/LazyBrushEditController.js +55 -0
  200. package/dist/esm/tools/segmentation/utils/lazyBrushPreview.d.ts +3 -0
  201. package/dist/esm/tools/segmentation/utils/lazyBrushPreview.js +34 -0
  202. package/dist/esm/tools/segmentation/utils/shouldUseLazyLabelmapEditing.d.ts +3 -0
  203. package/dist/esm/tools/segmentation/utils/shouldUseLazyLabelmapEditing.js +42 -0
  204. package/dist/esm/types/ISynchronizerEventHandler.d.ts +2 -1
  205. package/dist/esm/types/LabelmapToolOperationData.d.ts +5 -0
  206. package/dist/esm/types/LabelmapTypes.d.ts +29 -6
  207. package/dist/esm/types/SegmentationStateTypes.d.ts +6 -0
  208. package/dist/esm/utilities/calibrateImageSpacing.js +17 -2
  209. package/dist/esm/utilities/contours/AnnotationToPointData.js +1 -1
  210. package/dist/esm/utilities/draw3D/addLine3DBetweenPoints.d.ts +7 -0
  211. package/dist/esm/utilities/draw3D/addLine3DBetweenPoints.js +34 -0
  212. package/dist/esm/utilities/draw3D/calculateAdaptiveSphereRadius.d.ts +6 -0
  213. package/dist/esm/utilities/draw3D/calculateAdaptiveSphereRadius.js +7 -0
  214. package/dist/esm/utilities/draw3D/index.d.ts +2 -0
  215. package/dist/esm/utilities/draw3D/index.js +2 -0
  216. package/dist/esm/utilities/drawing/getTextBoxCoordsCanvas.js +22 -14
  217. package/dist/esm/utilities/getCenterAndRadiusInCanvas.d.ts +6 -0
  218. package/dist/esm/utilities/getCenterAndRadiusInCanvas.js +26 -0
  219. package/dist/esm/utilities/getEllipseWorldCoordinates.d.ts +2 -0
  220. package/dist/esm/utilities/getEllipseWorldCoordinates.js +26 -0
  221. package/dist/esm/utilities/getSphereBoundsInfo.js +5 -1
  222. package/dist/esm/utilities/getViewportICamera.d.ts +4 -0
  223. package/dist/esm/utilities/getViewportICamera.js +23 -0
  224. package/dist/esm/utilities/getViewportsForAnnotation.js +5 -1
  225. package/dist/esm/utilities/index.d.ts +2 -1
  226. package/dist/esm/utilities/index.js +2 -1
  227. package/dist/esm/utilities/interactionDragCoordinator.d.ts +5 -0
  228. package/dist/esm/utilities/interactionDragCoordinator.js +16 -0
  229. package/dist/esm/utilities/math/basic/BasicStatsCalculator.js +9 -7
  230. package/dist/esm/utilities/pointInSurroundingSphereCallback.js +8 -1
  231. package/dist/esm/utilities/segmentation/InterpolationManager/InterpolationManager.js +121 -118
  232. package/dist/esm/utilities/segmentation/SegmentStatsCalculator.js +5 -4
  233. package/dist/esm/utilities/segmentation/VolumetricCalculator.js +1 -1
  234. package/dist/esm/utilities/segmentation/createLabelmapVolumeForViewport.js +1 -1
  235. package/dist/esm/utilities/segmentation/getReferenceVolumeForSegmentation.js +1 -1
  236. package/dist/esm/utilities/segmentation/getReferenceVolumeForSegmentationVolume.js +11 -2
  237. package/dist/esm/utilities/segmentation/getSegmentIndexAtLabelmapBorder.js +36 -17
  238. package/dist/esm/utilities/segmentation/getSegmentIndexAtWorldPoint.js +42 -25
  239. package/dist/esm/utilities/segmentation/getUniqueSegmentIndices.js +3 -30
  240. package/dist/esm/utilities/segmentation/index.d.ts +2 -1
  241. package/dist/esm/utilities/segmentation/index.js +2 -1
  242. package/dist/esm/utilities/segmentation/utilsForWorker.js +6 -2
  243. package/dist/esm/utilities/segmentation/validateLabelmap.js +1 -1
  244. package/dist/esm/utilities/stackPrefetch/stackPrefetch.js +0 -1
  245. package/dist/esm/utilities/touch/index.js +3 -2
  246. package/dist/esm/utilities/viewportCapabilities.d.ts +16 -0
  247. package/dist/esm/utilities/viewportCapabilities.js +18 -0
  248. package/dist/esm/utilities/viewportFilters/filterViewportsWithParallelNormals.d.ts +1 -1
  249. package/dist/esm/utilities/viewportFilters/filterViewportsWithParallelNormals.js +12 -4
  250. package/dist/esm/utilities/viewportFilters/filterViewportsWithSameOrientation.d.ts +1 -1
  251. package/dist/esm/utilities/viewportFilters/filterViewportsWithSameOrientation.js +11 -4
  252. package/dist/esm/utilities/viewportFilters/getViewportIdsWithToolToRender.js +1 -1
  253. package/dist/esm/utilities/viewportPresentation.d.ts +3 -0
  254. package/dist/esm/utilities/viewportPresentation.js +26 -0
  255. package/dist/esm/utilities/volumeCropping/computePlanePlaneIntersection.d.ts +6 -0
  256. package/dist/esm/utilities/volumeCropping/computePlanePlaneIntersection.js +37 -0
  257. package/dist/esm/utilities/volumeCropping/constants.d.ts +31 -0
  258. package/dist/esm/utilities/volumeCropping/constants.js +31 -0
  259. package/dist/esm/utilities/volumeCropping/copyClippingPlanes.d.ts +2 -0
  260. package/dist/esm/utilities/volumeCropping/copyClippingPlanes.js +6 -0
  261. package/dist/esm/utilities/volumeCropping/extractVolumeDirectionVectors.d.ts +9 -0
  262. package/dist/esm/utilities/volumeCropping/extractVolumeDirectionVectors.js +9 -0
  263. package/dist/esm/utilities/volumeCropping/findLineBoundsIntersection.d.ts +5 -0
  264. package/dist/esm/utilities/volumeCropping/findLineBoundsIntersection.js +50 -0
  265. package/dist/esm/utilities/volumeCropping/getColorKeyForPlaneIndex.d.ts +1 -0
  266. package/dist/esm/utilities/volumeCropping/getColorKeyForPlaneIndex.js +13 -0
  267. package/dist/esm/utilities/volumeCropping/getOrientationFromNormal.d.ts +2 -0
  268. package/dist/esm/utilities/volumeCropping/getOrientationFromNormal.js +19 -0
  269. package/dist/esm/utilities/volumeCropping/index.d.ts +9 -0
  270. package/dist/esm/utilities/volumeCropping/index.js +9 -0
  271. package/dist/esm/utilities/volumeCropping/parseCornerKey.d.ts +8 -0
  272. package/dist/esm/utilities/volumeCropping/parseCornerKey.js +11 -0
  273. package/dist/esm/utilities/volumeCropping/types.d.ts +5 -0
  274. package/dist/esm/utilities/volumeCropping/types.js +0 -0
  275. package/dist/esm/utilities/vtkjs/AnnotatedRhombicuboctahedronActor/index.d.ts +31 -0
  276. package/dist/esm/utilities/vtkjs/AnnotatedRhombicuboctahedronActor/index.js +391 -0
  277. package/dist/esm/utilities/vtkjs/OrientationControllerWidget/index.d.ts +69 -0
  278. package/dist/esm/utilities/vtkjs/OrientationControllerWidget/index.js +804 -0
  279. package/dist/esm/utilities/vtkjs/RhombicuboctahedronSource/index.d.ts +7 -0
  280. package/dist/esm/utilities/vtkjs/RhombicuboctahedronSource/index.js +144 -0
  281. package/dist/esm/utilities/vtkjs/index.d.ts +3 -0
  282. package/dist/esm/utilities/vtkjs/index.js +3 -0
  283. package/dist/esm/version.d.ts +1 -1
  284. package/dist/esm/version.js +1 -1
  285. package/package.json +10 -9
@@ -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
  }
@@ -6,7 +6,9 @@ export declare function getEllipseCornersFromCanvasCoordinates(canvasCoordinates
6
6
  declare function createPointInEllipse(cornersInWorld?: Types.Point3[], options?: {
7
7
  strokePointsWorld?: Types.Point3[];
8
8
  segmentationImageData?: vtkImageData;
9
- radius?: number;
9
+ xRadius?: number;
10
+ yRadius?: number;
11
+ aspectRatio?: [number, number];
10
12
  }): (pointLPS: Types.Point3 | null, pointIJK?: Types.Point3) => boolean;
11
13
  declare const CIRCLE_STRATEGY: BrushStrategy;
12
14
  declare const CIRCLE_THRESHOLD_STRATEGY: BrushStrategy;
@@ -5,7 +5,7 @@ import BrushStrategy from './BrushStrategy';
5
5
  import { StrategyCallbacks } from '../../../enums';
6
6
  import compositions from './compositions';
7
7
  import { pointInSphere } from '../../../utilities/math/sphere';
8
- const { transformWorldToIndex, transformIndexToWorld, isEqual } = csUtils;
8
+ const { transformWorldToIndex, transformIndexToWorld, isEqual, getNormalizedAspectRatio, } = csUtils;
9
9
  export function getEllipseCornersFromCanvasCoordinates(canvasCoordinates) {
10
10
  const [bottom, top, left, right] = canvasCoordinates;
11
11
  const topLeft = [left[0], top[1]];
@@ -14,16 +14,16 @@ export function getEllipseCornersFromCanvasCoordinates(canvasCoordinates) {
14
14
  const topRight = [right[0], top[1]];
15
15
  return [topLeft, bottomRight, bottomLeft, topRight];
16
16
  }
17
- function createCircleCornersForCenter(center, viewUp, viewRight, radius) {
17
+ function createCircleCornersForCenter(center, viewUp, viewRight, yRadius, xRadius) {
18
18
  const centerVec = vec3.fromValues(center[0], center[1], center[2]);
19
19
  const top = vec3.create();
20
- vec3.scaleAndAdd(top, centerVec, viewUp, radius);
20
+ vec3.scaleAndAdd(top, centerVec, viewUp, yRadius);
21
21
  const bottom = vec3.create();
22
- vec3.scaleAndAdd(bottom, centerVec, viewUp, -radius);
22
+ vec3.scaleAndAdd(bottom, centerVec, viewUp, -yRadius);
23
23
  const right = vec3.create();
24
- vec3.scaleAndAdd(right, centerVec, viewRight, radius);
24
+ vec3.scaleAndAdd(right, centerVec, viewRight, xRadius);
25
25
  const left = vec3.create();
26
- vec3.scaleAndAdd(left, centerVec, viewRight, -radius);
26
+ vec3.scaleAndAdd(left, centerVec, viewRight, -xRadius);
27
27
  return [
28
28
  bottom,
29
29
  top,
@@ -31,11 +31,12 @@ function createCircleCornersForCenter(center, viewUp, viewRight, radius) {
31
31
  right,
32
32
  ];
33
33
  }
34
- function createStrokePredicate(centers, radius) {
35
- if (!centers.length || radius <= 0) {
34
+ function createStrokePredicate(centers, xRadius, yRadius) {
35
+ if (!centers.length || xRadius <= 0 || yRadius <= 0) {
36
36
  return null;
37
37
  }
38
- const radiusSquared = radius * radius;
38
+ const xRadiusSquared = xRadius * xRadius;
39
+ const yRadiusSquared = yRadius * yRadius;
39
40
  const centerVecs = centers.map((point) => [point[0], point[1], point[2]]);
40
41
  const segments = [];
41
42
  for (let i = 1; i < centerVecs.length; i++) {
@@ -55,7 +56,8 @@ function createStrokePredicate(centers, radius) {
55
56
  const dx = worldPoint[0] - centerVec[0];
56
57
  const dy = worldPoint[1] - centerVec[1];
57
58
  const dz = worldPoint[2] - centerVec[2];
58
- if (dx * dx + dy * dy + dz * dz <= radiusSquared) {
59
+ if ((dx * dx) / xRadiusSquared + (dy * dy) / yRadiusSquared + dz * dz <=
60
+ 1) {
59
61
  return true;
60
62
  }
61
63
  }
@@ -64,7 +66,8 @@ function createStrokePredicate(centers, radius) {
64
66
  const dx = worldPoint[0] - start[0];
65
67
  const dy = worldPoint[1] - start[1];
66
68
  const dz = worldPoint[2] - start[2];
67
- if (dx * dx + dy * dy + dz * dz <= radiusSquared) {
69
+ if ((dx * dx) / xRadiusSquared + (dy * dy) / yRadiusSquared + dz * dz <=
70
+ 1) {
68
71
  return true;
69
72
  }
70
73
  continue;
@@ -80,7 +83,10 @@ function createStrokePredicate(centers, radius) {
80
83
  const distX = worldPoint[0] - projX;
81
84
  const distY = worldPoint[1] - projY;
82
85
  const distZ = worldPoint[2] - projZ;
83
- if (distX * distX + distY * distY + distZ * distZ <= radiusSquared) {
86
+ if ((distX * distX) / xRadiusSquared +
87
+ (distY * distY) / yRadiusSquared +
88
+ distZ * distZ <=
89
+ 1) {
84
90
  return true;
85
91
  }
86
92
  }
@@ -103,7 +109,13 @@ const initializeCircle = {
103
109
  }
104
110
  operationData.centerWorld = center;
105
111
  operationData.centerIJK = transformWorldToIndex(segmentationImageData, center);
106
- const brushRadius = points.length >= 2 ? vec3.distance(points[0], points[1]) / 2 : 0;
112
+ const aspectRatio = getNormalizedAspectRatio(viewport.getAspectRatio());
113
+ const yRadius = points.length >= 2
114
+ ? vec3.distance(points[0], points[1]) / 2 / aspectRatio[1]
115
+ : 0;
116
+ const xRadius = points.length >= 2
117
+ ? vec3.distance(points[2], points[3]) / 2 / aspectRatio[0]
118
+ : 0;
107
119
  const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p));
108
120
  const corners = getEllipseCornersFromCanvasCoordinates(canvasCoordinates);
109
121
  const cornersInWorld = corners.map((corner) => viewport.canvasToWorld(corner));
@@ -119,14 +131,16 @@ const initializeCircle = {
119
131
  ? operationData.strokePointsWorld
120
132
  : [operationData.centerWorld];
121
133
  const strokeCenters = strokeCentersSource.map((point) => vec3.clone(point));
122
- const strokeCornersWorld = strokeCenters.flatMap((centerPoint) => createCircleCornersForCenter(centerPoint, normalizedViewUp, viewRight, brushRadius));
134
+ const strokeCornersWorld = strokeCenters.flatMap((centerPoint) => createCircleCornersForCenter(centerPoint, normalizedViewUp, viewRight, yRadius, xRadius));
123
135
  const circleCornersIJK = strokeCornersWorld.map((world) => transformWorldToIndex(segmentationImageData, world));
124
136
  const boundsIJK = getBoundingBoxAroundShapeIJK(circleCornersIJK, segmentationImageData.getDimensions());
125
137
  operationData.strokePointsWorld = strokeCenters;
126
138
  operationData.isInObject = createPointInEllipse(cornersInWorld, {
127
139
  strokePointsWorld: strokeCenters,
128
140
  segmentationImageData,
129
- radius: brushRadius,
141
+ xRadius,
142
+ yRadius,
143
+ aspectRatio,
130
144
  });
131
145
  operationData.isInObjectBoundsIJK = boundsIJK;
132
146
  },
@@ -136,22 +150,22 @@ function createPointInEllipse(cornersInWorld = [], options = {}) {
136
150
  throw new Error('createPointInEllipse: cornersInWorld must have 4 points');
137
151
  }
138
152
  const [topLeft, bottomRight, bottomLeft, topRight] = cornersInWorld;
153
+ const aspectRatio = options.aspectRatio || [1, 1];
139
154
  const center = vec3.create();
140
155
  vec3.add(center, topLeft, bottomRight);
141
156
  vec3.scale(center, center, 0.5);
142
157
  const majorAxisVec = vec3.create();
143
158
  vec3.subtract(majorAxisVec, topRight, topLeft);
144
- const xRadius = vec3.length(majorAxisVec) / 2;
159
+ const originalRadius = vec3.length(majorAxisVec) / 2;
145
160
  vec3.normalize(majorAxisVec, majorAxisVec);
146
161
  const minorAxisVec = vec3.create();
147
162
  vec3.subtract(minorAxisVec, bottomLeft, topLeft);
148
- const yRadius = vec3.length(minorAxisVec) / 2;
149
163
  vec3.normalize(minorAxisVec, minorAxisVec);
150
- const normal = vec3.create();
151
- vec3.cross(normal, majorAxisVec, minorAxisVec);
152
- vec3.normalize(normal, normal);
153
- const radiusForStroke = options.radius ?? Math.max(xRadius, yRadius);
154
- const strokePredicate = createStrokePredicate(options.strokePointsWorld || [], radiusForStroke);
164
+ const xRadius = originalRadius / aspectRatio[0];
165
+ const yRadius = originalRadius / aspectRatio[1];
166
+ const xRadiusForStroke = options.xRadius ?? xRadius;
167
+ const yRadiusForStroke = options.yRadius ?? yRadius;
168
+ const strokePredicate = createStrokePredicate(options.strokePointsWorld || [], xRadiusForStroke, yRadiusForStroke);
155
169
  if (isEqual(xRadius, yRadius)) {
156
170
  const radius = xRadius;
157
171
  const sphereObj = {
@@ -186,15 +200,8 @@ function createPointInEllipse(cornersInWorld = [], options = {}) {
186
200
  }
187
201
  const pointVec = vec3.create();
188
202
  vec3.subtract(pointVec, worldPoint, center);
189
- const distToPlane = vec3.dot(pointVec, normal);
190
- const proj = vec3.create();
191
- vec3.scaleAndAdd(proj, pointVec, normal, -distToPlane);
192
- const fromTopLeft = vec3.create();
193
- const centerToTopLeft = vec3.create();
194
- vec3.subtract(centerToTopLeft, center, topLeft);
195
- vec3.subtract(fromTopLeft, proj, centerToTopLeft);
196
- const x = vec3.dot(fromTopLeft, majorAxisVec);
197
- const y = vec3.dot(fromTopLeft, minorAxisVec);
203
+ const x = vec3.dot(pointVec, majorAxisVec);
204
+ const y = vec3.dot(pointVec, minorAxisVec);
198
205
  return (x * x) / (xRadius * xRadius) + (y * y) / (yRadius * yRadius) <= 1;
199
206
  };
200
207
  }
@@ -4,7 +4,7 @@ import BrushStrategy from './BrushStrategy';
4
4
  import compositions from './compositions';
5
5
  import StrategyCallbacks from '../../../enums/StrategyCallbacks';
6
6
  import { createEllipseInPoint, getEllipseCornersFromCanvasCoordinates, } from './fillCircle';
7
- const { transformWorldToIndex } = csUtils;
7
+ const { transformWorldToIndex, getNormalizedAspectRatio } = csUtils;
8
8
  import { getSphereBoundsInfoFromViewport } from '../../../utilities/getSphereBoundsInfo';
9
9
  const sphereComposition = {
10
10
  [StrategyCallbacks.Initialize]: (operationData) => {
@@ -26,7 +26,13 @@ const sphereComposition = {
26
26
  const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p));
27
27
  const corners = getEllipseCornersFromCanvasCoordinates(canvasCoordinates);
28
28
  const cornersInWorld = corners.map((corner) => viewport.canvasToWorld(corner));
29
- const strokeRadius = points.length >= 2 ? vec3.distance(points[0], points[1]) / 2 : undefined;
29
+ const aspectRatio = getNormalizedAspectRatio(viewport.getAspectRatio());
30
+ const yRadius = points.length >= 2
31
+ ? vec3.distance(points[0], points[1]) / 2 / aspectRatio[1]
32
+ : 0;
33
+ const xRadius = points.length >= 2
34
+ ? vec3.distance(points[2], points[3]) / 2 / aspectRatio[0]
35
+ : 0;
30
36
  const strokeCenters = operationData.strokePointsWorld &&
31
37
  operationData.strokePointsWorld.length > 0
32
38
  ? operationData.strokePointsWorld
@@ -90,7 +96,9 @@ const sphereComposition = {
90
96
  operationData.isInObject = createEllipseInPoint(cornersInWorld, {
91
97
  strokePointsWorld: operationData.strokePointsWorld,
92
98
  segmentationImageData,
93
- radius: strokeRadius,
99
+ xRadius,
100
+ yRadius,
101
+ aspectRatio,
94
102
  });
95
103
  },
96
104
  };
@@ -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
  }
@@ -1,8 +1,9 @@
1
1
  export function handleUseSegmentCenterIndex({ operationData, existingValue, index, }) {
2
- const { previewSegmentIndex, memo, centerSegmentIndexInfo, previewOnHover, segmentIndex, } = operationData;
2
+ const { previewSegmentIndex, memo, centerSegmentIndexInfo, previewOnHover, segmentIndex, labelValue, } = operationData;
3
+ const activeLabelValue = labelValue ?? segmentIndex;
3
4
  const { hasPreviewIndex, hasSegmentIndex, segmentIndex: centerSegmentIndex, } = centerSegmentIndexInfo;
4
5
  if (centerSegmentIndex === 0 && hasSegmentIndex && hasPreviewIndex) {
5
- if (existingValue === segmentIndex) {
6
+ if (existingValue === activeLabelValue) {
6
7
  return;
7
8
  }
8
9
  if (previewOnHover) {
@@ -15,7 +16,7 @@ export function handleUseSegmentCenterIndex({ operationData, existingValue, inde
15
16
  return;
16
17
  }
17
18
  if (centerSegmentIndex === 0 && hasSegmentIndex && !hasPreviewIndex) {
18
- if (existingValue === 0 || existingValue !== segmentIndex) {
19
+ if (existingValue === 0 || existingValue !== activeLabelValue) {
19
20
  return;
20
21
  }
21
22
  memo.voxelManager.setAtIndex(index, previewSegmentIndex);
@@ -23,7 +24,7 @@ export function handleUseSegmentCenterIndex({ operationData, existingValue, inde
23
24
  return;
24
25
  }
25
26
  if (centerSegmentIndex === 0 && !hasSegmentIndex && hasPreviewIndex) {
26
- if (existingValue === segmentIndex) {
27
+ if (existingValue === activeLabelValue) {
27
28
  return;
28
29
  }
29
30
  if (previewOnHover) {
@@ -36,7 +37,7 @@ export function handleUseSegmentCenterIndex({ operationData, existingValue, inde
36
37
  return;
37
38
  }
38
39
  if (centerSegmentIndex === 0 && !hasSegmentIndex && !hasPreviewIndex) {
39
- if (existingValue === segmentIndex) {
40
+ if (existingValue === activeLabelValue) {
40
41
  return;
41
42
  }
42
43
  if (existingValue === previewSegmentIndex) {
@@ -48,7 +49,7 @@ export function handleUseSegmentCenterIndex({ operationData, existingValue, inde
48
49
  if (centerSegmentIndex === previewSegmentIndex &&
49
50
  hasSegmentIndex &&
50
51
  hasPreviewIndex) {
51
- if (existingValue === segmentIndex) {
52
+ if (existingValue === activeLabelValue) {
52
53
  return;
53
54
  }
54
55
  memo.voxelManager.setAtIndex(index, previewSegmentIndex);
@@ -57,25 +58,25 @@ export function handleUseSegmentCenterIndex({ operationData, existingValue, inde
57
58
  if (centerSegmentIndex === previewSegmentIndex &&
58
59
  !hasSegmentIndex &&
59
60
  hasPreviewIndex) {
60
- if (existingValue === segmentIndex) {
61
+ if (existingValue === activeLabelValue) {
61
62
  return;
62
63
  }
63
64
  memo.voxelManager.setAtIndex(index, previewSegmentIndex);
64
65
  return;
65
66
  }
66
- if (centerSegmentIndex === segmentIndex &&
67
+ if (centerSegmentIndex === activeLabelValue &&
67
68
  hasSegmentIndex &&
68
69
  hasPreviewIndex) {
69
- if (existingValue === segmentIndex) {
70
+ if (existingValue === activeLabelValue) {
70
71
  return;
71
72
  }
72
73
  memo.voxelManager.setAtIndex(index, previewSegmentIndex);
73
74
  return;
74
75
  }
75
- if (centerSegmentIndex === segmentIndex &&
76
+ if (centerSegmentIndex === activeLabelValue &&
76
77
  hasSegmentIndex &&
77
78
  !hasPreviewIndex) {
78
- if (existingValue === segmentIndex) {
79
+ if (existingValue === activeLabelValue) {
79
80
  return;
80
81
  }
81
82
  memo.voxelManager.setAtIndex(index, previewSegmentIndex);
@@ -0,0 +1,4 @@
1
+ import type { InitializedOperationData } from '../BrushStrategy';
2
+ import { eraseCrossLayerOverwrites } from './crossLayerErase';
3
+ declare function prepareOverlapOperationData(operationData: InitializedOperationData): void;
4
+ export { eraseCrossLayerOverwrites, prepareOverlapOperationData };
@@ -0,0 +1,41 @@
1
+ import { getSegmentation } from '../../../../stateManagement/segmentation/getSegmentation';
2
+ import { beginLabelmapEditTransaction, resolveLabelmapLayerEditTarget, } from '../../../../stateManagement/segmentation/helpers/labelmapSegmentationState';
3
+ import { eraseCrossLayerOverwrites } from './crossLayerErase';
4
+ import { resolveOverwriteSegmentIndices } from './overwritePolicy';
5
+ function prepareOverlapOperationData(operationData) {
6
+ const segmentation = getSegmentation(operationData.segmentationId);
7
+ if (!segmentation) {
8
+ return;
9
+ }
10
+ operationData.overwriteSegmentIndices =
11
+ resolveOverwriteSegmentIndices(operationData);
12
+ const transaction = beginLabelmapEditTransaction(segmentation, {
13
+ segmentIndex: operationData.segmentIndex,
14
+ overwriteSegmentIndices: operationData.overwriteSegmentIndices,
15
+ segmentationVoxelManager: operationData.segmentationVoxelManager,
16
+ segmentationImageData: operationData.segmentationImageData,
17
+ isInObject: operationData.isInObject,
18
+ isInObjectBoundsIJK: operationData.isInObjectBoundsIJK,
19
+ });
20
+ operationData.labelmapEditTransaction = transaction;
21
+ operationData.labelValue = transaction.labelValue;
22
+ operationData.labelmapId = transaction.labelmapId;
23
+ operationData.crossLayerEraseBindings = transaction.crossLayerEraseBindings;
24
+ if (transaction.movedSegment && transaction.activeLayer) {
25
+ const target = resolveLabelmapLayerEditTarget(transaction.activeLayer, {
26
+ viewport: operationData.viewport,
27
+ imageId: operationData.imageId,
28
+ sourceLayer: transaction.sourceLayer,
29
+ });
30
+ if (target.imageId) {
31
+ operationData.imageId = target.imageId;
32
+ }
33
+ if (target.imageData) {
34
+ operationData.segmentationImageData = target.imageData;
35
+ }
36
+ if (target.voxelManager) {
37
+ operationData.segmentationVoxelManager = target.voxelManager;
38
+ }
39
+ }
40
+ }
41
+ export { eraseCrossLayerOverwrites, prepareOverlapOperationData };
@@ -0,0 +1,3 @@
1
+ import type { InitializedOperationData } from '../BrushStrategy';
2
+ declare function resolveOverwriteSegmentIndices(operationData: InitializedOperationData): number[];
3
+ export { resolveOverwriteSegmentIndices };
@@ -0,0 +1,31 @@
1
+ import { getConfig } from '../../../../config';
2
+ import { SegmentationRepresentations } from '../../../../enums';
3
+ import { getSegmentation } from '../../../../stateManagement/segmentation/getSegmentation';
4
+ import { getSegmentationRepresentation } from '../../../../stateManagement/segmentation/getSegmentationRepresentation';
5
+ function resolveOverwriteSegmentIndices(operationData) {
6
+ const { segmentationId, segmentIndex, segmentsLocked, viewport } = operationData;
7
+ const segmentation = getSegmentation(segmentationId);
8
+ if (!segmentation || segmentIndex === 0) {
9
+ return [];
10
+ }
11
+ const overwriteMode = getConfig().segmentation?.overwriteMode ?? 'all';
12
+ if (overwriteMode === 'none') {
13
+ return [];
14
+ }
15
+ const allSegmentIndices = Object.keys(segmentation.segments)
16
+ .map(Number)
17
+ .filter((candidateSegmentIndex) => candidateSegmentIndex !== segmentIndex &&
18
+ !segmentsLocked.includes(candidateSegmentIndex));
19
+ if (overwriteMode === 'all') {
20
+ return allSegmentIndices;
21
+ }
22
+ const representation = getSegmentationRepresentation(viewport.id, {
23
+ segmentationId,
24
+ type: SegmentationRepresentations.Labelmap,
25
+ });
26
+ if (!representation?.visible) {
27
+ return [];
28
+ }
29
+ return allSegmentIndices.filter((candidateSegmentIndex) => representation.segments[candidateSegmentIndex]?.visible !== false);
30
+ }
31
+ export { resolveOverwriteSegmentIndices };
@@ -0,0 +1,3 @@
1
+ import type { InitializedOperationData } from '../BrushStrategy';
2
+ declare function separateSegmentIfNeeded(operationData: InitializedOperationData): void;
3
+ export { separateSegmentIfNeeded };
@@ -0,0 +1,38 @@
1
+ import { getSegmentation } from '../../../../stateManagement/segmentation/getSegmentation';
2
+ import { beginLabelmapEditTransaction, resolveLabelmapLayerEditTarget, } from '../../../../stateManagement/segmentation/helpers/labelmapSegmentationState';
3
+ function separateSegmentIfNeeded(operationData) {
4
+ const segmentation = getSegmentation(operationData.segmentationId);
5
+ if (!segmentation || !operationData.segmentIndex) {
6
+ return;
7
+ }
8
+ const transaction = beginLabelmapEditTransaction(segmentation, {
9
+ segmentIndex: operationData.segmentIndex,
10
+ overwriteSegmentIndices: operationData.overwriteSegmentIndices,
11
+ segmentationVoxelManager: operationData.segmentationVoxelManager,
12
+ segmentationImageData: operationData.segmentationImageData,
13
+ isInObject: operationData.isInObject,
14
+ isInObjectBoundsIJK: operationData.isInObjectBoundsIJK,
15
+ });
16
+ operationData.labelmapEditTransaction = transaction;
17
+ operationData.labelmapId = transaction.labelmapId;
18
+ operationData.labelValue = transaction.labelValue;
19
+ operationData.crossLayerEraseBindings = transaction.crossLayerEraseBindings;
20
+ if (!transaction.movedSegment || !transaction.activeLayer) {
21
+ return;
22
+ }
23
+ const target = resolveLabelmapLayerEditTarget(transaction.activeLayer, {
24
+ viewport: operationData.viewport,
25
+ imageId: operationData.imageId,
26
+ sourceLayer: transaction.sourceLayer,
27
+ });
28
+ if (target.imageId) {
29
+ operationData.imageId = target.imageId;
30
+ }
31
+ if (target.imageData) {
32
+ operationData.segmentationImageData = target.imageData;
33
+ }
34
+ if (target.voxelManager) {
35
+ operationData.segmentationVoxelManager = target.voxelManager;
36
+ }
37
+ }
38
+ export { separateSegmentIfNeeded };
@@ -0,0 +1,19 @@
1
+ import { type Types } from '@cornerstonejs/core';
2
+ declare class LazyBrushEditController {
3
+ private strokePointsWorld;
4
+ private previewPoints;
5
+ private pendingPreviewCleanup;
6
+ reset(): void;
7
+ clearPendingCleanup(): void;
8
+ appendStrokePoint(worldPoint: Types.Point3): void;
9
+ getStrokePointsWorld(): Types.Point3[];
10
+ capturePreviewCircle(hoverData: any): void;
11
+ scheduleCleanup({ element, centerCanvas, viewportId, segmentationId, refreshCursor, }: {
12
+ element: HTMLDivElement;
13
+ centerCanvas: Types.Point2;
14
+ viewportId: string;
15
+ segmentationId: string;
16
+ refreshCursor: (element: HTMLDivElement, centerCanvas: Types.Point2) => void;
17
+ }): void;
18
+ }
19
+ export default LazyBrushEditController;
@@ -0,0 +1,55 @@
1
+ import { eventTarget } from '@cornerstonejs/core';
2
+ import { Events } from '../../../enums';
3
+ import { appendLazyBrushPreviewCircle, appendLazyBrushStrokePoint, } from './lazyBrushPreview';
4
+ class LazyBrushEditController {
5
+ constructor() {
6
+ this.strokePointsWorld = [];
7
+ this.previewPoints = [];
8
+ this.pendingPreviewCleanup = null;
9
+ }
10
+ reset() {
11
+ this.strokePointsWorld = [];
12
+ this.previewPoints = [];
13
+ }
14
+ clearPendingCleanup() {
15
+ if (!this.pendingPreviewCleanup) {
16
+ return;
17
+ }
18
+ eventTarget.removeEventListener(Events.SEGMENTATION_RENDERED, this.pendingPreviewCleanup.listener);
19
+ this.pendingPreviewCleanup = null;
20
+ }
21
+ appendStrokePoint(worldPoint) {
22
+ this.strokePointsWorld = appendLazyBrushStrokePoint(this.strokePointsWorld, worldPoint);
23
+ }
24
+ getStrokePointsWorld() {
25
+ return this.strokePointsWorld;
26
+ }
27
+ capturePreviewCircle(hoverData) {
28
+ if (!hoverData) {
29
+ return;
30
+ }
31
+ const circlePoints = hoverData.brushCursor?.data?.editPoints;
32
+ this.previewPoints = appendLazyBrushPreviewCircle(this.previewPoints, circlePoints);
33
+ hoverData.brushCursor.data.handles.points = this.previewPoints;
34
+ }
35
+ scheduleCleanup({ element, centerCanvas, viewportId, segmentationId, refreshCursor, }) {
36
+ this.clearPendingCleanup();
37
+ const listener = ((evt) => {
38
+ const detail = evt.detail;
39
+ if (detail.viewportId !== viewportId ||
40
+ detail.segmentationId !== segmentationId) {
41
+ return;
42
+ }
43
+ this.clearPendingCleanup();
44
+ this.reset();
45
+ refreshCursor(element, centerCanvas);
46
+ });
47
+ this.pendingPreviewCleanup = {
48
+ viewportId,
49
+ segmentationId,
50
+ listener,
51
+ };
52
+ eventTarget.addEventListener(Events.SEGMENTATION_RENDERED, listener);
53
+ }
54
+ }
55
+ export default LazyBrushEditController;
@@ -0,0 +1,3 @@
1
+ import type { Types } from '@cornerstonejs/core';
2
+ export declare function appendLazyBrushStrokePoint(points?: Types.Point3[], point?: Types.Point3): Types.Point3[];
3
+ export declare function appendLazyBrushPreviewCircle(existingPoints?: Types.Point3[], circlePoints?: Types.Point3[]): Types.Point3[];
@@ -0,0 +1,34 @@
1
+ const EPSILON = 1e-3;
2
+ function clonePoint(point) {
3
+ return [point[0], point[1], point[2]];
4
+ }
5
+ function isSamePoint(a, b) {
6
+ return (Math.abs(a[0] - b[0]) < EPSILON &&
7
+ Math.abs(a[1] - b[1]) < EPSILON &&
8
+ Math.abs(a[2] - b[2]) < EPSILON);
9
+ }
10
+ export function appendLazyBrushStrokePoint(points = [], point) {
11
+ if (!point) {
12
+ return points;
13
+ }
14
+ if (points.length && isSamePoint(points[points.length - 1], point)) {
15
+ return points;
16
+ }
17
+ return [...points, clonePoint(point)];
18
+ }
19
+ export function appendLazyBrushPreviewCircle(existingPoints = [], circlePoints = []) {
20
+ if (!circlePoints.length) {
21
+ return existingPoints;
22
+ }
23
+ const nextCircle = circlePoints.map((point) => clonePoint(point));
24
+ if (!existingPoints.length) {
25
+ return nextCircle;
26
+ }
27
+ const previousCircle = existingPoints.slice(-nextCircle.length);
28
+ const isDuplicateCircle = previousCircle.length === nextCircle.length &&
29
+ previousCircle.every((point, index) => isSamePoint(point, nextCircle[index]));
30
+ if (isDuplicateCircle) {
31
+ return existingPoints;
32
+ }
33
+ return [...existingPoints, ...nextCircle];
34
+ }