@cornerstonejs/tools 1.36.3 → 1.37.1

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 (283) hide show
  1. package/dist/cjs/drawingSvg/drawEllipse.js +1 -1
  2. package/dist/cjs/drawingSvg/drawEllipse.js.map +1 -1
  3. package/dist/cjs/drawingSvg/drawEllipseByCoordinates.js +2 -3
  4. package/dist/cjs/drawingSvg/drawEllipseByCoordinates.js.map +1 -1
  5. package/dist/cjs/enums/StrategyCallbacks.d.ts +13 -0
  6. package/dist/cjs/enums/StrategyCallbacks.js +17 -0
  7. package/dist/cjs/enums/StrategyCallbacks.js.map +1 -0
  8. package/dist/cjs/enums/index.d.ts +2 -1
  9. package/dist/cjs/enums/index.js +3 -1
  10. package/dist/cjs/enums/index.js.map +1 -1
  11. package/dist/cjs/eventDispatchers/keyboardEventHandlers/keyDown.js +17 -7
  12. package/dist/cjs/eventDispatchers/keyboardEventHandlers/keyDown.js.map +1 -1
  13. package/dist/cjs/eventDispatchers/shared/getActiveToolForKeyboardEvent.js +4 -1
  14. package/dist/cjs/eventDispatchers/shared/getActiveToolForKeyboardEvent.js.map +1 -1
  15. package/dist/cjs/eventDispatchers/shared/getToolsWithActionsForKeyboardEvents.d.ts +3 -0
  16. package/dist/cjs/eventDispatchers/shared/getToolsWithActionsForKeyboardEvents.js +33 -0
  17. package/dist/cjs/eventDispatchers/shared/getToolsWithActionsForKeyboardEvents.js.map +1 -0
  18. package/dist/cjs/eventDispatchers/shared/getToolsWithActionsForMouseEvent.js.map +1 -1
  19. package/dist/cjs/stateManagement/segmentation/config/segmentationColor.js +8 -1
  20. package/dist/cjs/stateManagement/segmentation/config/segmentationColor.js.map +1 -1
  21. package/dist/cjs/tools/annotation/EllipticalROITool.js +1 -2
  22. package/dist/cjs/tools/annotation/EllipticalROITool.js.map +1 -1
  23. package/dist/cjs/tools/base/AnnotationTool.js.map +1 -1
  24. package/dist/cjs/tools/base/BaseTool.d.ts +2 -0
  25. package/dist/cjs/tools/base/BaseTool.js +7 -1
  26. package/dist/cjs/tools/base/BaseTool.js.map +1 -1
  27. package/dist/cjs/tools/segmentation/BrushTool.d.ts +45 -3
  28. package/dist/cjs/tools/segmentation/BrushTool.js +197 -71
  29. package/dist/cjs/tools/segmentation/BrushTool.js.map +1 -1
  30. package/dist/cjs/tools/segmentation/CircleScissorsTool.js +3 -1
  31. package/dist/cjs/tools/segmentation/CircleScissorsTool.js.map +1 -1
  32. package/dist/cjs/tools/segmentation/SphereScissorsTool.js +3 -0
  33. package/dist/cjs/tools/segmentation/SphereScissorsTool.js.map +1 -1
  34. package/dist/cjs/tools/segmentation/strategies/BrushStrategy.d.ts +87 -0
  35. package/dist/cjs/tools/segmentation/strategies/BrushStrategy.js +137 -0
  36. package/dist/cjs/tools/segmentation/strategies/BrushStrategy.js.map +1 -0
  37. package/dist/cjs/tools/segmentation/strategies/compositions/determineSegmentIndex.d.ts +6 -0
  38. package/dist/cjs/tools/segmentation/strategies/compositions/determineSegmentIndex.js +53 -0
  39. package/dist/cjs/tools/segmentation/strategies/compositions/determineSegmentIndex.js.map +1 -0
  40. package/dist/cjs/tools/segmentation/strategies/compositions/dynamicThreshold.d.ts +6 -0
  41. package/dist/cjs/tools/segmentation/strategies/compositions/dynamicThreshold.js +41 -0
  42. package/dist/cjs/tools/segmentation/strategies/compositions/dynamicThreshold.js.map +1 -0
  43. package/dist/cjs/tools/segmentation/strategies/compositions/erase.d.ts +5 -0
  44. package/dist/cjs/tools/segmentation/strategies/compositions/erase.js +12 -0
  45. package/dist/cjs/tools/segmentation/strategies/compositions/erase.js.map +1 -0
  46. package/dist/cjs/tools/segmentation/strategies/compositions/index.d.ts +35 -0
  47. package/dist/cjs/tools/segmentation/strategies/compositions/index.js +24 -0
  48. package/dist/cjs/tools/segmentation/strategies/compositions/index.js.map +1 -0
  49. package/dist/cjs/tools/segmentation/strategies/compositions/islandRemoval.d.ts +5 -0
  50. package/dist/cjs/tools/segmentation/strategies/compositions/islandRemoval.js +129 -0
  51. package/dist/cjs/tools/segmentation/strategies/compositions/islandRemoval.js.map +1 -0
  52. package/dist/cjs/tools/segmentation/strategies/compositions/preview.d.ts +8 -0
  53. package/dist/cjs/tools/segmentation/strategies/compositions/preview.js +84 -0
  54. package/dist/cjs/tools/segmentation/strategies/compositions/preview.js.map +1 -0
  55. package/dist/cjs/tools/segmentation/strategies/compositions/regionFill.d.ts +5 -0
  56. package/dist/cjs/tools/segmentation/strategies/compositions/regionFill.js +27 -0
  57. package/dist/cjs/tools/segmentation/strategies/compositions/regionFill.js.map +1 -0
  58. package/dist/cjs/tools/segmentation/strategies/compositions/setValue.d.ts +8 -0
  59. package/dist/cjs/tools/segmentation/strategies/compositions/setValue.js +33 -0
  60. package/dist/cjs/tools/segmentation/strategies/compositions/setValue.js.map +1 -0
  61. package/dist/cjs/tools/segmentation/strategies/compositions/threshold.d.ts +5 -0
  62. package/dist/cjs/tools/segmentation/strategies/compositions/threshold.js +24 -0
  63. package/dist/cjs/tools/segmentation/strategies/compositions/threshold.js.map +1 -0
  64. package/dist/cjs/tools/segmentation/strategies/eraseCircle.d.ts +2 -7
  65. package/dist/cjs/tools/segmentation/strategies/eraseCircle.js +7 -4
  66. package/dist/cjs/tools/segmentation/strategies/eraseCircle.js.map +1 -1
  67. package/dist/cjs/tools/segmentation/strategies/eraseSphere.d.ts +2 -7
  68. package/dist/cjs/tools/segmentation/strategies/eraseSphere.js +7 -6
  69. package/dist/cjs/tools/segmentation/strategies/eraseSphere.js.map +1 -1
  70. package/dist/cjs/tools/segmentation/strategies/fillCircle.d.ts +13 -8
  71. package/dist/cjs/tools/segmentation/strategies/fillCircle.js +68 -90
  72. package/dist/cjs/tools/segmentation/strategies/fillCircle.js.map +1 -1
  73. package/dist/cjs/tools/segmentation/strategies/fillRectangle.js +3 -9
  74. package/dist/cjs/tools/segmentation/strategies/fillRectangle.js.map +1 -1
  75. package/dist/cjs/tools/segmentation/strategies/fillSphere.d.ts +6 -9
  76. package/dist/cjs/tools/segmentation/strategies/fillSphere.js +53 -64
  77. package/dist/cjs/tools/segmentation/strategies/fillSphere.js.map +1 -1
  78. package/dist/cjs/tools/segmentation/strategies/utils/getStrategyData.d.ts +3 -0
  79. package/dist/cjs/tools/segmentation/strategies/utils/getStrategyData.js +6 -0
  80. package/dist/cjs/tools/segmentation/strategies/utils/getStrategyData.js.map +1 -1
  81. package/dist/cjs/tools/segmentation/strategies/utils/isWithinThreshold.d.ts +2 -2
  82. package/dist/cjs/tools/segmentation/strategies/utils/isWithinThreshold.js +2 -2
  83. package/dist/cjs/tools/segmentation/strategies/utils/isWithinThreshold.js.map +1 -1
  84. package/dist/cjs/types/BoundsIJK.d.ts +1 -1
  85. package/dist/cjs/types/FloodFillTypes.d.ts +4 -4
  86. package/dist/cjs/types/LabelmapToolOperationData.d.ts +7 -2
  87. package/dist/cjs/types/index.d.ts +2 -1
  88. package/dist/cjs/utilities/math/ellipse/getCanvasEllipseCorners.d.ts +2 -3
  89. package/dist/cjs/utilities/math/ellipse/index.d.ts +2 -2
  90. package/dist/cjs/utilities/math/ellipse/index.js +26 -2
  91. package/dist/cjs/utilities/math/ellipse/index.js.map +1 -1
  92. package/dist/cjs/utilities/math/ellipse/pointInEllipse.d.ts +4 -1
  93. package/dist/cjs/utilities/math/ellipse/pointInEllipse.js +30 -17
  94. package/dist/cjs/utilities/math/ellipse/pointInEllipse.js.map +1 -1
  95. package/dist/cjs/utilities/math/sphere/pointInSphere.d.ts +1 -0
  96. package/dist/cjs/utilities/math/sphere/pointInSphere.js +2 -1
  97. package/dist/cjs/utilities/math/sphere/pointInSphere.js.map +1 -1
  98. package/dist/cjs/utilities/segmentation/brushThresholdForToolGroup.d.ts +1 -1
  99. package/dist/cjs/utilities/segmentation/brushThresholdForToolGroup.js +5 -5
  100. package/dist/cjs/utilities/segmentation/brushThresholdForToolGroup.js.map +1 -1
  101. package/dist/esm/drawingSvg/drawEllipse.js +1 -1
  102. package/dist/esm/drawingSvg/drawEllipse.js.map +1 -1
  103. package/dist/esm/drawingSvg/drawEllipseByCoordinates.js +2 -3
  104. package/dist/esm/drawingSvg/drawEllipseByCoordinates.js.map +1 -1
  105. package/dist/esm/enums/StrategyCallbacks.js +15 -0
  106. package/dist/esm/enums/StrategyCallbacks.js.map +1 -0
  107. package/dist/esm/enums/index.js +2 -1
  108. package/dist/esm/enums/index.js.map +1 -1
  109. package/dist/esm/eventDispatchers/keyboardEventHandlers/keyDown.js +17 -7
  110. package/dist/esm/eventDispatchers/keyboardEventHandlers/keyDown.js.map +1 -1
  111. package/dist/esm/eventDispatchers/shared/getActiveToolForKeyboardEvent.js +4 -1
  112. package/dist/esm/eventDispatchers/shared/getActiveToolForKeyboardEvent.js.map +1 -1
  113. package/dist/esm/eventDispatchers/shared/getToolsWithActionsForKeyboardEvents.js +29 -0
  114. package/dist/esm/eventDispatchers/shared/getToolsWithActionsForKeyboardEvents.js.map +1 -0
  115. package/dist/esm/eventDispatchers/shared/getToolsWithActionsForMouseEvent.js.map +1 -1
  116. package/dist/esm/stateManagement/segmentation/config/segmentationColor.js +8 -1
  117. package/dist/esm/stateManagement/segmentation/config/segmentationColor.js.map +1 -1
  118. package/dist/esm/tools/annotation/EllipticalROITool.js +1 -2
  119. package/dist/esm/tools/annotation/EllipticalROITool.js.map +1 -1
  120. package/dist/esm/tools/base/AnnotationTool.js.map +1 -1
  121. package/dist/esm/tools/base/BaseTool.js +5 -1
  122. package/dist/esm/tools/base/BaseTool.js.map +1 -1
  123. package/dist/esm/tools/segmentation/BrushTool.js +208 -87
  124. package/dist/esm/tools/segmentation/BrushTool.js.map +1 -1
  125. package/dist/esm/tools/segmentation/CircleScissorsTool.js +3 -0
  126. package/dist/esm/tools/segmentation/CircleScissorsTool.js.map +1 -1
  127. package/dist/esm/tools/segmentation/SphereScissorsTool.js +3 -0
  128. package/dist/esm/tools/segmentation/SphereScissorsTool.js.map +1 -1
  129. package/dist/esm/tools/segmentation/strategies/BrushStrategy.js +136 -0
  130. package/dist/esm/tools/segmentation/strategies/BrushStrategy.js.map +1 -0
  131. package/dist/esm/tools/segmentation/strategies/compositions/determineSegmentIndex.js +48 -0
  132. package/dist/esm/tools/segmentation/strategies/compositions/determineSegmentIndex.js.map +1 -0
  133. package/dist/esm/tools/segmentation/strategies/compositions/dynamicThreshold.js +35 -0
  134. package/dist/esm/tools/segmentation/strategies/compositions/dynamicThreshold.js.map +1 -0
  135. package/dist/esm/tools/segmentation/strategies/compositions/erase.js +7 -0
  136. package/dist/esm/tools/segmentation/strategies/compositions/erase.js.map +1 -0
  137. package/dist/esm/tools/segmentation/strategies/compositions/index.js +19 -0
  138. package/dist/esm/tools/segmentation/strategies/compositions/index.js.map +1 -0
  139. package/dist/esm/tools/segmentation/strategies/compositions/islandRemoval.js +124 -0
  140. package/dist/esm/tools/segmentation/strategies/compositions/islandRemoval.js.map +1 -0
  141. package/dist/esm/tools/segmentation/strategies/compositions/preview.js +77 -0
  142. package/dist/esm/tools/segmentation/strategies/compositions/preview.js.map +1 -0
  143. package/dist/esm/tools/segmentation/strategies/compositions/regionFill.js +21 -0
  144. package/dist/esm/tools/segmentation/strategies/compositions/regionFill.js.map +1 -0
  145. package/dist/esm/tools/segmentation/strategies/compositions/setValue.js +28 -0
  146. package/dist/esm/tools/segmentation/strategies/compositions/setValue.js.map +1 -0
  147. package/dist/esm/tools/segmentation/strategies/compositions/threshold.js +19 -0
  148. package/dist/esm/tools/segmentation/strategies/compositions/threshold.js.map +1 -0
  149. package/dist/esm/tools/segmentation/strategies/eraseCircle.js +6 -8
  150. package/dist/esm/tools/segmentation/strategies/eraseCircle.js.map +1 -1
  151. package/dist/esm/tools/segmentation/strategies/eraseSphere.js +6 -7
  152. package/dist/esm/tools/segmentation/strategies/eraseSphere.js.map +1 -1
  153. package/dist/esm/tools/segmentation/strategies/fillCircle.js +64 -88
  154. package/dist/esm/tools/segmentation/strategies/fillCircle.js.map +1 -1
  155. package/dist/esm/tools/segmentation/strategies/fillRectangle.js +3 -9
  156. package/dist/esm/tools/segmentation/strategies/fillRectangle.js.map +1 -1
  157. package/dist/esm/tools/segmentation/strategies/fillSphere.js +53 -64
  158. package/dist/esm/tools/segmentation/strategies/fillSphere.js.map +1 -1
  159. package/dist/esm/tools/segmentation/strategies/utils/getStrategyData.js +7 -1
  160. package/dist/esm/tools/segmentation/strategies/utils/getStrategyData.js.map +1 -1
  161. package/dist/esm/tools/segmentation/strategies/utils/isWithinThreshold.js +2 -2
  162. package/dist/esm/tools/segmentation/strategies/utils/isWithinThreshold.js.map +1 -1
  163. package/dist/esm/utilities/math/ellipse/index.js +2 -2
  164. package/dist/esm/utilities/math/ellipse/index.js.map +1 -1
  165. package/dist/esm/utilities/math/ellipse/pointInEllipse.js +28 -16
  166. package/dist/esm/utilities/math/ellipse/pointInEllipse.js.map +1 -1
  167. package/dist/esm/utilities/math/sphere/pointInSphere.js +2 -1
  168. package/dist/esm/utilities/math/sphere/pointInSphere.js.map +1 -1
  169. package/dist/esm/utilities/segmentation/brushThresholdForToolGroup.js +11 -5
  170. package/dist/esm/utilities/segmentation/brushThresholdForToolGroup.js.map +1 -1
  171. package/dist/types/drawingSvg/drawEllipseByCoordinates.d.ts.map +1 -1
  172. package/dist/types/enums/StrategyCallbacks.d.ts +14 -0
  173. package/dist/types/enums/StrategyCallbacks.d.ts.map +1 -0
  174. package/dist/types/enums/index.d.ts +2 -1
  175. package/dist/types/eventDispatchers/keyboardEventHandlers/keyDown.d.ts.map +1 -1
  176. package/dist/types/eventDispatchers/shared/getActiveToolForKeyboardEvent.d.ts.map +1 -1
  177. package/dist/types/eventDispatchers/shared/getToolsWithActionsForKeyboardEvents.d.ts +4 -0
  178. package/dist/types/eventDispatchers/shared/getToolsWithActionsForKeyboardEvents.d.ts.map +1 -0
  179. package/dist/types/eventDispatchers/shared/getToolsWithActionsForMouseEvent.d.ts.map +1 -1
  180. package/dist/types/stateManagement/segmentation/config/segmentationColor.d.ts.map +1 -1
  181. package/dist/types/tools/annotation/EllipticalROITool.d.ts.map +1 -1
  182. package/dist/types/tools/base/AnnotationTool.d.ts.map +1 -1
  183. package/dist/types/tools/base/BaseTool.d.ts +2 -0
  184. package/dist/types/tools/base/BaseTool.d.ts.map +1 -1
  185. package/dist/types/tools/segmentation/BrushTool.d.ts +45 -3
  186. package/dist/types/tools/segmentation/BrushTool.d.ts.map +1 -1
  187. package/dist/types/tools/segmentation/CircleScissorsTool.d.ts.map +1 -1
  188. package/dist/types/tools/segmentation/SphereScissorsTool.d.ts.map +1 -1
  189. package/dist/types/tools/segmentation/strategies/BrushStrategy.d.ts +88 -0
  190. package/dist/types/tools/segmentation/strategies/BrushStrategy.d.ts.map +1 -0
  191. package/dist/types/tools/segmentation/strategies/compositions/determineSegmentIndex.d.ts +7 -0
  192. package/dist/types/tools/segmentation/strategies/compositions/determineSegmentIndex.d.ts.map +1 -0
  193. package/dist/types/tools/segmentation/strategies/compositions/dynamicThreshold.d.ts +7 -0
  194. package/dist/types/tools/segmentation/strategies/compositions/dynamicThreshold.d.ts.map +1 -0
  195. package/dist/types/tools/segmentation/strategies/compositions/erase.d.ts +6 -0
  196. package/dist/types/tools/segmentation/strategies/compositions/erase.d.ts.map +1 -0
  197. package/dist/types/tools/segmentation/strategies/compositions/index.d.ts +36 -0
  198. package/dist/types/tools/segmentation/strategies/compositions/index.d.ts.map +1 -0
  199. package/dist/types/tools/segmentation/strategies/compositions/islandRemoval.d.ts +6 -0
  200. package/dist/types/tools/segmentation/strategies/compositions/islandRemoval.d.ts.map +1 -0
  201. package/dist/types/tools/segmentation/strategies/compositions/preview.d.ts +9 -0
  202. package/dist/types/tools/segmentation/strategies/compositions/preview.d.ts.map +1 -0
  203. package/dist/types/tools/segmentation/strategies/compositions/regionFill.d.ts +6 -0
  204. package/dist/types/tools/segmentation/strategies/compositions/regionFill.d.ts.map +1 -0
  205. package/dist/types/tools/segmentation/strategies/compositions/setValue.d.ts +9 -0
  206. package/dist/types/tools/segmentation/strategies/compositions/setValue.d.ts.map +1 -0
  207. package/dist/types/tools/segmentation/strategies/compositions/threshold.d.ts +6 -0
  208. package/dist/types/tools/segmentation/strategies/compositions/threshold.d.ts.map +1 -0
  209. package/dist/types/tools/segmentation/strategies/eraseCircle.d.ts +2 -7
  210. package/dist/types/tools/segmentation/strategies/eraseCircle.d.ts.map +1 -1
  211. package/dist/types/tools/segmentation/strategies/eraseSphere.d.ts +2 -7
  212. package/dist/types/tools/segmentation/strategies/eraseSphere.d.ts.map +1 -1
  213. package/dist/types/tools/segmentation/strategies/fillCircle.d.ts +13 -8
  214. package/dist/types/tools/segmentation/strategies/fillCircle.d.ts.map +1 -1
  215. package/dist/types/tools/segmentation/strategies/fillRectangle.d.ts.map +1 -1
  216. package/dist/types/tools/segmentation/strategies/fillSphere.d.ts +6 -9
  217. package/dist/types/tools/segmentation/strategies/fillSphere.d.ts.map +1 -1
  218. package/dist/types/tools/segmentation/strategies/utils/getStrategyData.d.ts +3 -0
  219. package/dist/types/tools/segmentation/strategies/utils/getStrategyData.d.ts.map +1 -1
  220. package/dist/types/tools/segmentation/strategies/utils/isWithinThreshold.d.ts +2 -2
  221. package/dist/types/tools/segmentation/strategies/utils/isWithinThreshold.d.ts.map +1 -1
  222. package/dist/types/types/BoundsIJK.d.ts +1 -1
  223. package/dist/types/types/BoundsIJK.d.ts.map +1 -1
  224. package/dist/types/types/FloodFillTypes.d.ts +4 -4
  225. package/dist/types/types/FloodFillTypes.d.ts.map +1 -1
  226. package/dist/types/types/LabelmapToolOperationData.d.ts +7 -2
  227. package/dist/types/types/LabelmapToolOperationData.d.ts.map +1 -1
  228. package/dist/types/types/index.d.ts +2 -1
  229. package/dist/types/types/index.d.ts.map +1 -1
  230. package/dist/types/utilities/math/ellipse/getCanvasEllipseCorners.d.ts +2 -3
  231. package/dist/types/utilities/math/ellipse/getCanvasEllipseCorners.d.ts.map +1 -1
  232. package/dist/types/utilities/math/ellipse/index.d.ts +2 -2
  233. package/dist/types/utilities/math/ellipse/index.d.ts.map +1 -1
  234. package/dist/types/utilities/math/ellipse/pointInEllipse.d.ts +4 -1
  235. package/dist/types/utilities/math/ellipse/pointInEllipse.d.ts.map +1 -1
  236. package/dist/types/utilities/math/sphere/pointInSphere.d.ts +1 -0
  237. package/dist/types/utilities/math/sphere/pointInSphere.d.ts.map +1 -1
  238. package/dist/types/utilities/segmentation/brushThresholdForToolGroup.d.ts +1 -1
  239. package/dist/types/utilities/segmentation/brushThresholdForToolGroup.d.ts.map +1 -1
  240. package/dist/umd/index.js +1 -1
  241. package/dist/umd/index.js.map +1 -1
  242. package/package.json +3 -3
  243. package/src/drawingSvg/drawEllipse.ts +8 -8
  244. package/src/drawingSvg/drawEllipseByCoordinates.ts +4 -4
  245. package/src/enums/StrategyCallbacks.ts +52 -0
  246. package/src/enums/index.js +2 -0
  247. package/src/eventDispatchers/keyboardEventHandlers/keyDown.ts +22 -11
  248. package/src/eventDispatchers/shared/getActiveToolForKeyboardEvent.ts +6 -2
  249. package/src/eventDispatchers/shared/getToolsWithActionsForKeyboardEvents.ts +53 -0
  250. package/src/eventDispatchers/shared/getToolsWithActionsForMouseEvent.ts +0 -2
  251. package/src/stateManagement/segmentation/config/segmentationColor.ts +8 -1
  252. package/src/tools/annotation/EllipticalROITool.ts +1 -3
  253. package/src/tools/base/AnnotationTool.ts +0 -1
  254. package/src/tools/base/BaseTool.ts +32 -2
  255. package/src/tools/segmentation/BrushTool.ts +298 -68
  256. package/src/tools/segmentation/CircleScissorsTool.ts +3 -1
  257. package/src/tools/segmentation/SphereScissorsTool.ts +3 -0
  258. package/src/tools/segmentation/strategies/BrushStrategy.ts +364 -0
  259. package/src/tools/segmentation/strategies/compositions/determineSegmentIndex.ts +86 -0
  260. package/src/tools/segmentation/strategies/compositions/dynamicThreshold.ts +58 -0
  261. package/src/tools/segmentation/strategies/compositions/erase.ts +11 -0
  262. package/src/tools/segmentation/strategies/compositions/index.ts +19 -0
  263. package/src/tools/segmentation/strategies/compositions/islandRemoval.ts +179 -0
  264. package/src/tools/segmentation/strategies/compositions/preview.ts +138 -0
  265. package/src/tools/segmentation/strategies/compositions/regionFill.ts +45 -0
  266. package/src/tools/segmentation/strategies/compositions/setValue.ts +50 -0
  267. package/src/tools/segmentation/strategies/compositions/threshold.ts +35 -0
  268. package/src/tools/segmentation/strategies/eraseCircle.ts +10 -19
  269. package/src/tools/segmentation/strategies/eraseSphere.ts +10 -18
  270. package/src/tools/segmentation/strategies/fillCircle.ts +141 -164
  271. package/src/tools/segmentation/strategies/fillRectangle.ts +3 -13
  272. package/src/tools/segmentation/strategies/fillSphere.ts +105 -120
  273. package/src/tools/segmentation/strategies/utils/getStrategyData.ts +15 -1
  274. package/src/tools/segmentation/strategies/utils/isWithinThreshold.ts +5 -5
  275. package/src/types/BoundsIJK.ts +1 -1
  276. package/src/types/FloodFillTypes.ts +4 -4
  277. package/src/types/LabelmapToolOperationData.ts +20 -1
  278. package/src/types/index.ts +2 -0
  279. package/src/utilities/math/ellipse/getCanvasEllipseCorners.ts +2 -2
  280. package/src/utilities/math/ellipse/index.ts +2 -2
  281. package/src/utilities/math/ellipse/pointInEllipse.ts +52 -18
  282. package/src/utilities/math/sphere/pointInSphere.ts +10 -2
  283. package/src/utilities/segmentation/brushThresholdForToolGroup.ts +12 -5
@@ -0,0 +1,179 @@
1
+ import type { InitializedOperationData } from '../BrushStrategy';
2
+ import floodFill from '../../../../utilities/segmentation/floodFill';
3
+ import { triggerSegmentationDataModified } from '../../../../stateManagement/segmentation/triggerSegmentationEvents';
4
+ import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
5
+
6
+ /**
7
+ * Removes external islands and fills internal islands.
8
+ * External islands are areas of preview which are not connected via fill or
9
+ * preview colours to the clicked/dragged over points.
10
+ * Internal islands are areas of non-preview which are entirely surrounded by
11
+ * colours connected to the clicked/dragged over points.
12
+ */
13
+ export default {
14
+ [StrategyCallbacks.OnInteractionEnd]: (
15
+ operationData: InitializedOperationData
16
+ ) => {
17
+ const {
18
+ previewVoxelManager: previewVoxelManager,
19
+ segmentationVoxelManager: segmentationVoxelManager,
20
+ strategySpecificConfiguration,
21
+ previewSegmentIndex,
22
+ segmentIndex,
23
+ } = operationData;
24
+
25
+ if (!strategySpecificConfiguration.THRESHOLD || segmentIndex === null) {
26
+ return;
27
+ }
28
+
29
+ const clickedPoints = previewVoxelManager.getPoints();
30
+ if (!clickedPoints?.length) {
31
+ return;
32
+ }
33
+
34
+ if (previewSegmentIndex === undefined) {
35
+ return;
36
+ }
37
+
38
+ // Ensure the bounds includes the clicked points, otherwise the fill
39
+ // fails.
40
+ const boundsIJK = previewVoxelManager
41
+ .getBoundsIJK()
42
+ .map((bound, i) => [
43
+ Math.min(bound[0], ...clickedPoints.map((point) => point[i])),
44
+ Math.max(bound[1], ...clickedPoints.map((point) => point[i])),
45
+ ]);
46
+
47
+ if (boundsIJK.find((it) => it[0] < 0 || it[1] > 65535)) {
48
+ // Nothing done, so just skip this
49
+ return;
50
+ }
51
+
52
+ const floodedSet = new Set<number>();
53
+ // Returns true for new colour, and false otherwise
54
+ const getter = (i, j, k) => {
55
+ if (
56
+ i < boundsIJK[0][0] ||
57
+ i > boundsIJK[0][1] ||
58
+ j < boundsIJK[1][0] ||
59
+ j > boundsIJK[1][1] ||
60
+ k < boundsIJK[2][0] ||
61
+ k > boundsIJK[2][1]
62
+ ) {
63
+ return -1;
64
+ }
65
+ const index = segmentationVoxelManager.toIndex([i, j, k]);
66
+ if (floodedSet.has(index)) {
67
+ // Values already flooded
68
+ return -2;
69
+ }
70
+ const oldVal = segmentationVoxelManager.getAtIndex(index);
71
+ const isIn =
72
+ oldVal === previewSegmentIndex || oldVal === segmentIndex ? 1 : 0;
73
+ if (!isIn) {
74
+ segmentationVoxelManager.addPoint(index);
75
+ }
76
+ // 1 is values that are preview/segment index, 0 is everything else
77
+ return isIn;
78
+ };
79
+
80
+ let floodedCount = 0;
81
+
82
+ const onFlood = (i, j, k) => {
83
+ const index = segmentationVoxelManager.toIndex([i, j, k]);
84
+ if (floodedSet.has(index)) {
85
+ return;
86
+ }
87
+ // Fill this point with an indicator that this point is connected
88
+ previewVoxelManager.setAtIJK(i, j, k, previewSegmentIndex);
89
+ floodedSet.add(index);
90
+ floodedCount++;
91
+ };
92
+
93
+ clickedPoints.forEach((clickedPoint, index) => {
94
+ // @ts-ignore - need to ignore the spread appication to array params
95
+ if (getter(...clickedPoint) === 1) {
96
+ floodFill(getter, clickedPoint, {
97
+ onFlood,
98
+ diagonals: true,
99
+ });
100
+ }
101
+ });
102
+
103
+ let clearedCount = 0;
104
+ let previewCount = 0;
105
+
106
+ const callback = ({ index, pointIJK, value: trackValue }) => {
107
+ const value = segmentationVoxelManager.getAtIndex(index);
108
+ if (floodedSet.has(index)) {
109
+ previewCount++;
110
+ const newValue =
111
+ trackValue === segmentIndex ? segmentIndex : previewSegmentIndex;
112
+ previewVoxelManager.setAtIJKPoint(pointIJK, newValue);
113
+ } else if (value === previewSegmentIndex) {
114
+ clearedCount++;
115
+ const newValue = trackValue ?? 0;
116
+ previewVoxelManager.setAtIJKPoint(pointIJK, newValue);
117
+ }
118
+ };
119
+
120
+ previewVoxelManager.forEach(callback, {});
121
+
122
+ if (floodedCount - previewCount !== 0) {
123
+ console.warn(
124
+ 'There were flooded=',
125
+ floodedCount,
126
+ 'cleared=',
127
+ clearedCount,
128
+ 'preview count=',
129
+ previewCount,
130
+ 'not handled',
131
+ floodedCount - previewCount
132
+ );
133
+ }
134
+ const islandMap = new Set(segmentationVoxelManager.points || []);
135
+ floodedSet.clear();
136
+
137
+ for (const index of islandMap.keys()) {
138
+ if (floodedSet.has(index)) {
139
+ continue;
140
+ }
141
+ let isInternal = true;
142
+ const internalSet = new Set<number>();
143
+ const onFloodInternal = (i, j, k) => {
144
+ const floodIndex = previewVoxelManager.toIndex([i, j, k]);
145
+ floodedSet.add(floodIndex);
146
+ if (
147
+ (boundsIJK[0][0] !== boundsIJK[0][1] &&
148
+ (i === boundsIJK[0][0] || i === boundsIJK[0][1])) ||
149
+ (boundsIJK[1][0] !== boundsIJK[1][1] &&
150
+ (j === boundsIJK[1][0] || j === boundsIJK[1][1])) ||
151
+ (boundsIJK[2][0] !== boundsIJK[2][1] &&
152
+ (k === boundsIJK[2][0] || k === boundsIJK[2][1]))
153
+ ) {
154
+ isInternal = false;
155
+ }
156
+ if (isInternal) {
157
+ internalSet.add(floodIndex);
158
+ }
159
+ };
160
+ const pointIJK = previewVoxelManager.toIJK(index);
161
+ if (getter(...pointIJK) !== 0) {
162
+ continue;
163
+ }
164
+ floodFill(getter, pointIJK, {
165
+ onFlood: onFloodInternal,
166
+ diagonals: false,
167
+ });
168
+ if (isInternal) {
169
+ for (const index of internalSet) {
170
+ previewVoxelManager.setAtIndex(index, previewSegmentIndex);
171
+ }
172
+ }
173
+ }
174
+ triggerSegmentationDataModified(
175
+ operationData.segmentationId,
176
+ previewVoxelManager.getArrayOfSlices()
177
+ );
178
+ },
179
+ };
@@ -0,0 +1,138 @@
1
+ import type { Types } from '@cornerstonejs/core';
2
+ import type { InitializedOperationData } from '../BrushStrategy';
3
+ import { triggerSegmentationDataModified } from '../../../../stateManagement/segmentation/triggerSegmentationEvents';
4
+ import { config as segmentationConfig } from '../../../../stateManagement/segmentation';
5
+ import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
6
+
7
+ /**
8
+ * Sets up a preview to use an alternate set of colours. First fills the
9
+ * preview segment index with the final one for all pixels, then resets
10
+ * the preview colours.
11
+ * This is only activated when the preview segment index is defined, either
12
+ * from the initial state or from the global state.
13
+ */
14
+ export default {
15
+ [StrategyCallbacks.Preview]: function (
16
+ operationData: InitializedOperationData
17
+ ) {
18
+ const { previewColors, strategySpecificConfiguration, enabledElement } =
19
+ operationData;
20
+ if (!previewColors || !strategySpecificConfiguration) {
21
+ return;
22
+ }
23
+
24
+ // Clean up old preview data
25
+ if (operationData.preview) {
26
+ delete operationData.preview;
27
+ }
28
+ delete strategySpecificConfiguration.centerSegmentIndex;
29
+
30
+ // Now generate a normal preview as though the user had clicked, filled, released
31
+ this.onInteractionStart?.(enabledElement, operationData);
32
+ const preview = this.fill(enabledElement, operationData);
33
+ if (preview) {
34
+ preview.isPreviewFromHover = true;
35
+ operationData.preview = preview;
36
+ this.onInteractionEnd?.(enabledElement, operationData);
37
+ }
38
+ return preview;
39
+ },
40
+
41
+ [StrategyCallbacks.Initialize]: (operationData: InitializedOperationData) => {
42
+ const {
43
+ toolGroupId,
44
+ segmentIndex,
45
+ segmentationRepresentationUID,
46
+ previewSegmentIndex,
47
+ previewColors,
48
+ preview,
49
+ } = operationData;
50
+ if (previewColors === undefined) {
51
+ return;
52
+ }
53
+ if (preview) {
54
+ preview.previewVoxelManager.sourceVoxelManager =
55
+ operationData.segmentationVoxelManager;
56
+ // And use the preview data associated with this tracking object as needed
57
+ operationData.previewVoxelManager = preview.previewVoxelManager;
58
+ }
59
+
60
+ if (segmentIndex === null || !previewSegmentIndex) {
61
+ // Null means to reset the value, so we don't change the preview colour
62
+ return;
63
+ }
64
+
65
+ const configColor = previewColors?.[segmentIndex];
66
+ const segmentColor = segmentationConfig.color.getColorForSegmentIndex(
67
+ toolGroupId,
68
+ segmentationRepresentationUID,
69
+ segmentIndex
70
+ );
71
+ if (!configColor && !segmentColor) {
72
+ return;
73
+ }
74
+ const previewColor = configColor || segmentColor.map((it) => it * 0.9);
75
+ segmentationConfig.color.setColorForSegmentIndex(
76
+ toolGroupId,
77
+ segmentationRepresentationUID,
78
+ previewSegmentIndex,
79
+ previewColor as Types.Color
80
+ );
81
+ },
82
+
83
+ [StrategyCallbacks.AcceptPreview]: (
84
+ operationData: InitializedOperationData
85
+ ) => {
86
+ const {
87
+ segmentationVoxelManager: segmentationVoxelManager,
88
+ previewVoxelManager: previewVoxelManager,
89
+ previewSegmentIndex,
90
+ preview,
91
+ } = operationData;
92
+ if (previewSegmentIndex === undefined) {
93
+ return;
94
+ }
95
+ const segmentIndex = preview?.segmentIndex ?? operationData.segmentIndex;
96
+ const tracking = previewVoxelManager;
97
+ if (!tracking || tracking.modifiedSlices.size === 0) {
98
+ return;
99
+ }
100
+
101
+ const callback = ({ index }) => {
102
+ const oldValue = segmentationVoxelManager.getAtIndex(index);
103
+ if (oldValue === previewSegmentIndex) {
104
+ segmentationVoxelManager.setAtIndex(index, segmentIndex);
105
+ }
106
+ };
107
+ tracking.forEach(callback, {});
108
+
109
+ triggerSegmentationDataModified(
110
+ operationData.segmentationId,
111
+ tracking.getArrayOfSlices()
112
+ );
113
+ tracking.clear();
114
+ },
115
+
116
+ [StrategyCallbacks.RejectPreview]: (
117
+ operationData: InitializedOperationData
118
+ ) => {
119
+ const {
120
+ previewVoxelManager: previewVoxelManager,
121
+ segmentationVoxelManager: segmentationVoxelManager,
122
+ } = operationData;
123
+ if (previewVoxelManager.modifiedSlices.size === 0) {
124
+ return;
125
+ }
126
+
127
+ const callback = ({ index, value }) => {
128
+ segmentationVoxelManager.setAtIndex(index, value);
129
+ };
130
+ previewVoxelManager.forEach(callback);
131
+
132
+ triggerSegmentationDataModified(
133
+ operationData.segmentationId,
134
+ previewVoxelManager.getArrayOfSlices()
135
+ );
136
+ previewVoxelManager.clear();
137
+ },
138
+ };
@@ -0,0 +1,45 @@
1
+ import type { InitializedOperationData } from '../BrushStrategy';
2
+ import pointInShapeCallback from '../../../../utilities/pointInShapeCallback';
3
+ import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
4
+
5
+ /**
6
+ * Creates a fill strategy that uses the isWithinThreshold created by the
7
+ * createIsInThreshold and the bounds specified in the boundsIJK to go over
8
+ * the specified area, checking if in threshold, and if so, filling that area
9
+ * with the new segment by calling the setValue function.
10
+ */
11
+ export default {
12
+ [StrategyCallbacks.Fill]: (operationData: InitializedOperationData) => {
13
+ const {
14
+ segmentsLocked,
15
+ segmentationImageData,
16
+ segmentationVoxelManager: segmentationVoxelManager,
17
+ previewVoxelManager: previewVoxelManager,
18
+ imageVoxelManager: imageVoxelManager,
19
+ brushStrategy,
20
+ centerIJK,
21
+ } = operationData;
22
+ const isWithinThreshold =
23
+ brushStrategy.createIsInThreshold?.(operationData);
24
+ const { setValue } = brushStrategy;
25
+
26
+ const callback = isWithinThreshold
27
+ ? (data) => {
28
+ const { value, index } = data;
29
+ if (segmentsLocked.includes(value) || !isWithinThreshold(index)) {
30
+ return;
31
+ }
32
+ setValue(operationData, data);
33
+ }
34
+ : (data) => setValue(operationData, data);
35
+
36
+ pointInShapeCallback(
37
+ segmentationImageData as unknown,
38
+ imageVoxelManager.isInObject,
39
+ callback,
40
+ segmentationVoxelManager.boundsIJK
41
+ );
42
+
43
+ previewVoxelManager.addPoint(centerIJK);
44
+ },
45
+ };
@@ -0,0 +1,50 @@
1
+ import type { InitializedOperationData } from '../BrushStrategy';
2
+ import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
3
+
4
+ /**
5
+ * Creates a set value function which will apply the specified segmentIndex
6
+ * to the given location.
7
+ * If segmentIndex is null, it will clear the given segment index instead
8
+ * This is all done through the previewVoxelManager so that values can be recorded
9
+ * as changed, and the original values remembered.
10
+ */
11
+ export default {
12
+ [StrategyCallbacks.INTERNAL_setValue]: (
13
+ operationData: InitializedOperationData,
14
+ { value, index }
15
+ ) => {
16
+ const {
17
+ segmentsLocked,
18
+ segmentIndex,
19
+ previewVoxelManager: previewVoxelManager,
20
+ previewSegmentIndex,
21
+ segmentationVoxelManager: segmentationVoxelManager,
22
+ } = operationData;
23
+ const existingValue = segmentationVoxelManager.getAtIndex(index);
24
+ if (segmentIndex === null) {
25
+ const oldValue = previewVoxelManager.getAtIndex(index);
26
+ if (oldValue !== undefined) {
27
+ previewVoxelManager.setAtIndex(index, oldValue);
28
+ }
29
+ return;
30
+ }
31
+
32
+ if (existingValue === segmentIndex || segmentsLocked.includes(value)) {
33
+ return;
34
+ }
35
+ // Correct for preview data getting into the image area and not accepted/rejected
36
+ if (existingValue === previewSegmentIndex) {
37
+ if (previewVoxelManager.getAtIndex(index) === undefined) {
38
+ // Reset the value to ensure preview gets added to the indices
39
+ segmentationVoxelManager.setAtIndex(index, segmentIndex);
40
+ } else {
41
+ return;
42
+ }
43
+ }
44
+
45
+ // Now, just update the displayed value
46
+ const useSegmentIndex = previewSegmentIndex ?? segmentIndex;
47
+
48
+ previewVoxelManager.setAtIndex(index, useSegmentIndex);
49
+ },
50
+ };
@@ -0,0 +1,35 @@
1
+ import type { InitializedOperationData } from '../BrushStrategy';
2
+ import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
3
+
4
+ /**
5
+ * Adds an isWithinThreshold to the operation data that checks that the
6
+ * image value is within threshold[0]...threshold[1]
7
+ * No-op if threshold not defined.
8
+ */
9
+ export default {
10
+ [StrategyCallbacks.CreateIsInThreshold]: (
11
+ operationData: InitializedOperationData
12
+ ) => {
13
+ const {
14
+ imageVoxelManager: imageVoxelManager,
15
+ strategySpecificConfiguration,
16
+ segmentIndex,
17
+ } = operationData;
18
+ if (!strategySpecificConfiguration || !segmentIndex) {
19
+ return;
20
+ }
21
+ return (index) => {
22
+ const { THRESHOLD, THRESHOLD_INSIDE_CIRCLE } =
23
+ strategySpecificConfiguration;
24
+
25
+ const voxelValue = imageVoxelManager.getAtIndex(index);
26
+ // Prefer the generic version of the THRESHOLD configuration, but fallback
27
+ // to the older THRESHOLD_INSIDE_CIRCLE version.
28
+ const { threshold } = THRESHOLD || THRESHOLD_INSIDE_CIRCLE || {};
29
+ if (!threshold?.length) {
30
+ return true;
31
+ }
32
+ return threshold[0] <= voxelValue && voxelValue <= threshold[1];
33
+ };
34
+ },
35
+ };
@@ -1,22 +1,13 @@
1
- import type { Types } from '@cornerstonejs/core';
1
+ import BrushStrategy from './BrushStrategy';
2
+ import { CIRCLE_STRATEGY } from './fillCircle';
3
+ import compositions from './compositions';
2
4
 
3
- import { fillInsideCircle } from './fillCircle';
4
- import { LabelmapToolOperationData } from '../../../types';
5
+ const ERASE_CIRCLE_STRATEGY = new BrushStrategy(
6
+ 'EraseCircle',
7
+ compositions.erase,
8
+ ...CIRCLE_STRATEGY.compositions
9
+ );
5
10
 
6
- type OperationData = LabelmapToolOperationData & {
7
- points: any; // todo fix
8
- };
11
+ const eraseInsideCircle = ERASE_CIRCLE_STRATEGY.strategyFunction;
9
12
 
10
- export function eraseInsideCircle(
11
- enabledElement: Types.IEnabledElement,
12
- operationData: OperationData
13
- ): void {
14
- // Take the arguments and set the segmentIndex to 0,
15
- // Then use existing fillInsideCircle functionality.
16
- const eraseOperationData = {
17
- ...operationData,
18
- segmentIndex: 0,
19
- };
20
-
21
- fillInsideCircle(enabledElement, eraseOperationData);
22
- }
13
+ export { eraseInsideCircle };
@@ -1,21 +1,13 @@
1
- import type { Types } from '@cornerstonejs/core';
1
+ import BrushStrategy from './BrushStrategy';
2
+ import { SPHERE_STRATEGY } from './fillSphere';
3
+ import compositions from './compositions';
2
4
 
3
- import { fillInsideSphere } from './fillSphere';
4
- import { LabelmapToolOperationData } from '../../../types';
5
+ const ERASE_SPHERE_STRATEGY = new BrushStrategy(
6
+ 'EraseSphere',
7
+ compositions.erase,
8
+ ...SPHERE_STRATEGY.compositions
9
+ );
5
10
 
6
- type OperationData = LabelmapToolOperationData & {
7
- points: [Types.Point3, Types.Point3, Types.Point3, Types.Point3];
8
- };
11
+ const eraseInsideSphere = ERASE_SPHERE_STRATEGY.strategyFunction;
9
12
 
10
- export function eraseInsideSphere(
11
- enabledElement: Types.IEnabledElement,
12
- operationData: OperationData
13
- ): void {
14
- // Take the arguments and set the segmentIndex to 0,
15
- // Then use existing fillInsideCircle functionality.
16
- const eraseOperationData = Object.assign({}, operationData, {
17
- segmentIndex: 0,
18
- });
19
-
20
- fillInsideSphere(enabledElement, eraseOperationData);
21
- }
13
+ export { eraseInsideSphere };