@cornerstonejs/tools 1.36.3 → 1.37.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 (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
@@ -1,5 +1,5 @@
1
1
  import { utilities as csUtils, getEnabledElement } from '@cornerstonejs/core';
2
- import { vec3 } from 'gl-matrix';
2
+ import { vec3, vec2 } from 'gl-matrix';
3
3
 
4
4
  import type { Types } from '@cornerstonejs/core';
5
5
  import type {
@@ -19,7 +19,12 @@ import {
19
19
  fillInsideCircle,
20
20
  } from './strategies/fillCircle';
21
21
  import { eraseInsideCircle } from './strategies/eraseCircle';
22
- import { Events, ToolModes, SegmentationRepresentations } from '../../enums';
22
+ import {
23
+ Events,
24
+ ToolModes,
25
+ SegmentationRepresentations,
26
+ StrategyCallbacks,
27
+ } from '../../enums';
23
28
  import { drawCircle as drawCircleSvg } from '../../drawingSvg';
24
29
  import {
25
30
  resetElementCursor,
@@ -40,6 +45,22 @@ import {
40
45
  } from '../../types/LabelmapTypes';
41
46
  import { isVolumeSegmentation } from './strategies/utils/stackVolumeCheck';
42
47
 
48
+ /**
49
+ * A type for preview data/information, used to setup previews on hover, or
50
+ * maintain the preview information.
51
+ */
52
+ export type PreviewData = {
53
+ /**
54
+ * The preview data returned from the strategy
55
+ */
56
+ preview: unknown;
57
+ timer?: number;
58
+ timerStart: number;
59
+ startPoint: Types.Point2;
60
+ element: HTMLDivElement;
61
+ isDrag: boolean;
62
+ };
63
+
43
64
  /**
44
65
  * @public
45
66
  */
@@ -62,6 +83,15 @@ class BrushTool extends BaseTool {
62
83
  centerCanvas?: Array<number>;
63
84
  };
64
85
 
86
+ private _previewData?: PreviewData = {
87
+ preview: null,
88
+ element: null,
89
+ timerStart: 0,
90
+ timer: null,
91
+ startPoint: [NaN, NaN],
92
+ isDrag: false,
93
+ };
94
+
65
95
  constructor(
66
96
  toolProps: PublicToolProps = {},
67
97
  defaultToolProps: ToolProps = {
@@ -76,20 +106,53 @@ class BrushTool extends BaseTool {
76
106
  THRESHOLD_INSIDE_SPHERE: thresholdInsideSphere,
77
107
  },
78
108
  strategySpecificConfiguration: {
79
- THRESHOLD_INSIDE_CIRCLE: {
109
+ THRESHOLD: {
80
110
  threshold: [-150, -70], // E.g. CT Fat // Only used during threshold strategies.
81
111
  },
82
112
  },
83
113
  defaultStrategy: 'FILL_INSIDE_CIRCLE',
84
114
  activeStrategy: 'FILL_INSIDE_CIRCLE',
85
115
  brushSize: 25,
116
+ preview: {
117
+ // Have to enable the preview to use this
118
+ enabled: false,
119
+ previewColors: {},
120
+ // The time before showing a preview
121
+ previewTimeMs: 250,
122
+ // The distance to move to show a preview before preview time expired
123
+ previewMoveDistance: 8,
124
+ // The distance to drag before being considered a drag rather than click
125
+ dragMoveDistance: 4,
126
+ // The time to consider a mouse click a drag when moved less than dragMoveDistance
127
+ dragTimeMs: 500,
128
+ },
129
+ // Whether to show a center circle/position. Set to null to not show
130
+ centerRadius: 2,
131
+ actions: {
132
+ [StrategyCallbacks.AcceptPreview]: {
133
+ method: StrategyCallbacks.AcceptPreview,
134
+ bindings: [
135
+ {
136
+ key: 'Enter',
137
+ },
138
+ ],
139
+ },
140
+ [StrategyCallbacks.RejectPreview]: {
141
+ method: StrategyCallbacks.RejectPreview,
142
+ bindings: [
143
+ {
144
+ key: 'Escape',
145
+ },
146
+ ],
147
+ },
148
+ },
86
149
  },
87
150
  }
88
151
  ) {
89
152
  super(toolProps, defaultToolProps);
90
153
  }
91
154
 
92
- onSetToolPassive = () => {
155
+ onSetToolPassive = (evt) => {
93
156
  this.disableCursor();
94
157
  };
95
158
 
@@ -97,20 +160,16 @@ class BrushTool extends BaseTool {
97
160
  this.disableCursor();
98
161
  };
99
162
 
100
- onSetToolDisabled = () => {
163
+ onSetToolDisabled = (evt) => {
101
164
  this.disableCursor();
102
165
  };
103
166
 
104
167
  private disableCursor() {
105
168
  this._hoverData = undefined;
169
+ this.rejectPreview();
106
170
  }
107
171
 
108
- preMouseDownCallback = (
109
- evt: EventTypes.MouseDownActivateEventType
110
- ): boolean => {
111
- const eventData = evt.detail;
112
- const { element } = eventData;
113
-
172
+ createEditData(element) {
114
173
  const enabledElement = getEnabledElement(element);
115
174
  const { viewport, renderingEngine } = enabledElement;
116
175
 
@@ -151,7 +210,7 @@ class BrushTool extends BaseTool {
151
210
  // First volume actor for now.
152
211
  const firstVolumeActorUID = actors[0].uid;
153
212
 
154
- this._editData = {
213
+ return {
155
214
  volumeId,
156
215
  referencedVolumeId: firstVolumeActorUID,
157
216
  segmentsLocked,
@@ -181,49 +240,128 @@ class BrushTool extends BaseTool {
181
240
  );
182
241
  return;
183
242
 
184
- // Todo: add sphere manipulation support for stacks of images
243
+ // Todo: add sphere (volumetric) manipulation support for stacks of images
185
244
  // we should basically check if the stack constructs a valid volume
186
245
  // meaning all the metadata is present and consistent
187
- // then we should create a volume and use it as a reference
188
- // ideally a tiny volume that does not exceeds the boundary of the
189
- // sphere brush size
246
+ // then we use a VoxelManager mapping to map a volume like appearance
247
+ // for the stack data.
190
248
  // csUtils.isValidVolume(referencedImageIds
191
249
  }
192
250
 
193
- this._editData = {
251
+ return {
194
252
  imageIdReferenceMap,
195
253
  segmentsLocked,
196
254
  segmentationRepresentationUID,
197
255
  };
198
256
  }
257
+ }
258
+
259
+ preMouseDownCallback = (
260
+ evt: EventTypes.MouseDownActivateEventType
261
+ ): boolean => {
262
+ const eventData = evt.detail;
263
+ const { element } = eventData;
264
+ const enabledElement = getEnabledElement(element);
265
+ const { renderingEngine } = enabledElement;
199
266
 
267
+ this._editData = this.createEditData(element);
200
268
  this._activateDraw(element);
201
269
 
202
270
  hideElementCursor(element);
203
271
 
204
272
  evt.preventDefault();
205
273
 
274
+ // This might be a mouse down
275
+ this._previewData.isDrag = false;
276
+ this._previewData.timerStart = Date.now();
277
+
206
278
  triggerAnnotationRenderForViewportUIDs(
207
279
  renderingEngine,
208
- viewportIdsToRender
280
+ this._hoverData.viewportIdsToRender
281
+ );
282
+
283
+ this.applyActiveStrategyCallback(
284
+ enabledElement,
285
+ this.getOperationData(element),
286
+ StrategyCallbacks.OnInteractionStart
209
287
  );
210
288
 
211
289
  return true;
212
290
  };
213
291
 
292
+ /**
293
+ * This call will be made when the mouse moves and the tool is active, but
294
+ * not actually drawing at the moment.
295
+ * The behavior is:
296
+ * 1. Update the cursor
297
+ * 2. Call the active strategy event 'preview' and 'rejectPreview'
298
+ * on the mouse cursor position on a periodic basis to create a preview
299
+ * when configured to do so.
300
+ *
301
+ * The preview will be shown after the mouse has been stationary for 250 ms.
302
+ * Any preview will be cancelled (immediately) after moving outside the center
303
+ * distance.
304
+ * As well, if the mouse moves but stays inside the center area for 250 ms,
305
+ * then the cancel will happen with a new preview being added.
306
+ *
307
+ * See mouse up details for how the preview gets accepted.
308
+ *
309
+ * The preview also needs to be cancelled on changing tools.
310
+ */
214
311
  mouseMoveCallback = (evt: EventTypes.InteractionEventType): void => {
215
312
  if (this.mode === ToolModes.Active) {
216
313
  this.updateCursor(evt);
314
+ if (!this.configuration.preview.enabled) {
315
+ return;
316
+ }
317
+ const { previewTimeMs, previewMoveDistance, dragMoveDistance } =
318
+ this.configuration.preview;
319
+ const { currentPoints, element } = evt.detail;
320
+ const { canvas } = currentPoints;
321
+
322
+ const { preview, startPoint, timer, timerStart, isDrag } =
323
+ this._previewData;
324
+ const delta = vec2.distance(canvas, startPoint);
325
+ const time = Date.now() - timerStart;
326
+ if (
327
+ delta > previewMoveDistance ||
328
+ (time > previewTimeMs && delta > dragMoveDistance)
329
+ ) {
330
+ if (timer) {
331
+ window.clearTimeout(timer);
332
+ this._previewData.timer = null;
333
+ }
334
+ if (preview && !isDrag) {
335
+ this.rejectPreview(element);
336
+ }
337
+ }
338
+ if (!this._previewData.timer) {
339
+ const timer = window.setTimeout(this.previewCallback, 250);
340
+ Object.assign(this._previewData, {
341
+ timerStart: Date.now(),
342
+ timer,
343
+ startPoint: canvas,
344
+ element,
345
+ });
346
+ }
217
347
  }
218
348
  };
219
349
 
220
- private updateCursor(evt: EventTypes.InteractionEventType) {
221
- const eventData = evt.detail;
222
- const { element } = eventData;
223
- const { currentPoints } = eventData;
224
- const centerCanvas = currentPoints.canvas;
350
+ previewCallback = () => {
351
+ if (this._previewData.preview) {
352
+ return;
353
+ }
354
+ this._previewData.timer = null;
355
+ this._previewData.preview = this.applyActiveStrategyCallback(
356
+ getEnabledElement(this._previewData.element),
357
+ this.getOperationData(this._previewData.element),
358
+ StrategyCallbacks.Preview
359
+ );
360
+ };
361
+
362
+ private createHoverData(element, centerCanvas?) {
225
363
  const enabledElement = getEnabledElement(element);
226
- const { renderingEngine, viewport } = enabledElement;
364
+ const { viewport } = enabledElement;
227
365
 
228
366
  const camera = viewport.getCamera();
229
367
  const { viewPlaneNormal, viewUp } = camera;
@@ -266,7 +404,7 @@ class BrushTool extends BaseTool {
266
404
  data: {},
267
405
  };
268
406
 
269
- this._hoverData = {
407
+ return {
270
408
  brushCursor,
271
409
  centerCanvas,
272
410
  segmentIndex,
@@ -275,43 +413,88 @@ class BrushTool extends BaseTool {
275
413
  segmentColor,
276
414
  viewportIdsToRender,
277
415
  };
416
+ }
417
+
418
+ /**
419
+ * Updates the cursor position and whether it is showing or not.
420
+ * Can be over-ridden to add more cursor details or a preview.
421
+ */
422
+ protected updateCursor(evt: EventTypes.InteractionEventType) {
423
+ const eventData = evt.detail;
424
+ const { element } = eventData;
425
+ const { currentPoints } = eventData;
426
+ const centerCanvas = currentPoints.canvas;
427
+ this._hoverData = this.createHoverData(element, centerCanvas);
278
428
 
279
429
  this._calculateCursor(element, centerCanvas);
280
430
 
281
431
  triggerAnnotationRenderForViewportUIDs(
282
- renderingEngine,
283
- viewportIdsToRender
432
+ getEnabledElement(element).renderingEngine,
433
+ this._hoverData.viewportIdsToRender
284
434
  );
285
435
  }
286
436
 
287
437
  private _dragCallback = (evt: EventTypes.InteractionEventType): void => {
288
438
  const eventData = evt.detail;
289
- const { element } = eventData;
439
+ const { element, currentPoints } = eventData;
290
440
  const enabledElement = getEnabledElement(element);
291
441
  const { renderingEngine } = enabledElement;
292
442
 
293
443
  this.updateCursor(evt);
294
444
 
295
- const {
296
- segmentIndex,
297
- segmentationId,
298
- segmentationRepresentationUID,
299
- brushCursor,
300
- viewportIdsToRender,
301
- } = this._hoverData;
302
-
303
- const { data } = brushCursor;
304
- const { viewPlaneNormal, viewUp } = brushCursor.metadata;
445
+ const { viewportIdsToRender } = this._hoverData;
305
446
 
306
447
  triggerAnnotationRenderForViewportUIDs(
307
448
  renderingEngine,
308
449
  viewportIdsToRender
309
450
  );
310
451
 
452
+ const delta = vec2.distance(
453
+ currentPoints.canvas,
454
+ this._previewData.startPoint
455
+ );
456
+ const { dragTimeMs, dragMoveDistance } = this.configuration.preview;
457
+ if (
458
+ !this._previewData.isDrag &&
459
+ this._previewData.preview &&
460
+ Date.now() - this._previewData.timerStart < dragTimeMs &&
461
+ delta < dragMoveDistance
462
+ ) {
463
+ // If we are showing a preview, then don't start dragging quite immediately
464
+ // so that click up can accept the preview.
465
+ return;
466
+ }
467
+
468
+ this._previewData.preview = this.applyActiveStrategy(
469
+ enabledElement,
470
+ this.getOperationData()
471
+ );
472
+ this._previewData.element = element;
473
+ // Add a bit of time to the timer start so small accidental movements dont
474
+ // cause issues on clicking
475
+ this._previewData.timerStart = Date.now() + dragTimeMs;
476
+ this._previewData.isDrag = true;
477
+ this._previewData.startPoint = currentPoints.canvas;
478
+ };
479
+
480
+ protected getOperationData(element?) {
481
+ const editData = this._editData || this.createEditData(element);
482
+
483
+ const {
484
+ segmentIndex,
485
+ segmentationId,
486
+ segmentationRepresentationUID,
487
+ brushCursor,
488
+ } = this._hoverData || this.createHoverData(element);
489
+ const { data, metadata = {} } = brushCursor || {};
490
+ const { viewPlaneNormal, viewUp } = metadata;
311
491
  const operationData = {
312
- ...this._editData,
313
- points: data.handles.points,
492
+ ...editData,
493
+ points: data?.handles?.points,
314
494
  segmentIndex,
495
+ previewColors: this.configuration.preview.enabled
496
+ ? this.configuration.preview.previewColors
497
+ : null,
315
498
  viewPlaneNormal,
316
499
  toolGroupId: this.toolGroupId,
317
500
  segmentationId,
@@ -319,10 +502,11 @@ class BrushTool extends BaseTool {
319
502
  viewUp,
320
503
  strategySpecificConfiguration:
321
504
  this.configuration.strategySpecificConfiguration,
505
+ // Provide the preview information so that data can be used directly
506
+ preview: this._previewData?.preview,
322
507
  };
323
-
324
- this.applyActiveStrategy(enabledElement, operationData);
325
- };
508
+ return operationData;
509
+ }
326
510
 
327
511
  private _calculateCursor(element, centerCanvas) {
328
512
  const enabledElement = getEnabledElement(element);
@@ -382,46 +566,77 @@ class BrushTool extends BaseTool {
382
566
  data.invalidated = false;
383
567
  }
384
568
 
569
+ /**
570
+ * The end callback call is made when the mouse is released. This will
571
+ * perform another active strategy render event to render the final position.
572
+ * As well, the finish strategy callback will be made during this time.
573
+ */
385
574
  private _endCallback = (evt: EventTypes.InteractionEventType): void => {
386
575
  const eventData = evt.detail;
387
576
  const { element } = eventData;
577
+ const enabledElement = getEnabledElement(element);
388
578
 
389
- const {
390
- segmentIndex,
391
- segmentationId,
392
- segmentationRepresentationUID,
393
- brushCursor,
394
- } = this._hoverData;
395
-
396
- const { data } = brushCursor;
397
- const { viewPlaneNormal, viewUp } = brushCursor.metadata;
579
+ const operationData = this.getOperationData(element);
580
+ // Don't re-fill when the preview is showing and the user clicks again
581
+ // otherwise the new area of hover may get filled, which is unexpected
582
+ if (!this._previewData.preview && !this._previewData.isDrag) {
583
+ this.applyActiveStrategy(enabledElement, operationData);
584
+ }
398
585
 
399
586
  this._deactivateDraw(element);
400
587
 
401
588
  resetElementCursor(element);
402
589
 
403
- const enabledElement = getEnabledElement(element);
404
-
405
590
  this.updateCursor(evt);
406
591
 
407
- const operationData = {
408
- points: data.handles.points,
409
- ...this._editData,
410
- segmentIndex,
411
- viewPlaneNormal,
412
- toolGroupId: this.toolGroupId,
413
- segmentationId,
414
- segmentationRepresentationUID,
415
- viewUp,
416
- strategySpecificConfiguration:
417
- this.configuration.strategySpecificConfiguration,
418
- };
419
-
420
592
  this._editData = null;
421
593
 
422
- this.applyActiveStrategy(enabledElement, operationData);
594
+ this.applyActiveStrategyCallback(
595
+ enabledElement,
596
+ operationData,
597
+ StrategyCallbacks.OnInteractionEnd
598
+ );
599
+
600
+ if (!this._previewData.isDrag) {
601
+ this.acceptPreview(element);
602
+ }
423
603
  };
424
604
 
605
+ /**
606
+ * Cancels any preview view being shown, resetting any segments being shown.
607
+ */
608
+ public rejectPreview(element = this._previewData.element) {
609
+ if (!element || !this._previewData.preview) {
610
+ return;
611
+ }
612
+ const enabledElement = getEnabledElement(element);
613
+ this.applyActiveStrategyCallback(
614
+ enabledElement,
615
+ this.getOperationData(element),
616
+ StrategyCallbacks.RejectPreview
617
+ );
618
+ this._previewData.preview = null;
619
+ this._previewData.isDrag = false;
620
+ }
621
+
622
+ /**
623
+ * Accepts a preview, marking it as the active segment.
624
+ */
625
+ public acceptPreview(element = this._previewData.element) {
626
+ if (!element) {
627
+ return;
628
+ }
629
+ const enabledElement = getEnabledElement(element);
630
+
631
+ this.applyActiveStrategyCallback(
632
+ enabledElement,
633
+ this.getOperationData(element),
634
+ StrategyCallbacks.AcceptPreview
635
+ );
636
+ this._previewData.isDrag = false;
637
+ this._previewData.preview = null;
638
+ }
639
+
425
640
  /**
426
641
  * Add event handlers for the modify event loop, and prevent default event propagation.
427
642
  */
@@ -529,6 +744,21 @@ class BrushTool extends BaseTool {
529
744
  color,
530
745
  }
531
746
  );
747
+
748
+ const { centerRadius } = this.configuration;
749
+ if (centerRadius >= 0) {
750
+ const circleUID1 = '1';
751
+ drawCircleSvg(
752
+ svgDrawingHelper,
753
+ annotationUID,
754
+ circleUID1,
755
+ center as Types.Point2,
756
+ 2,
757
+ {
758
+ color,
759
+ }
760
+ );
761
+ }
532
762
  }
533
763
  }
534
764
 
@@ -10,6 +10,7 @@ import {
10
10
  } from '../../types';
11
11
 
12
12
  import { fillInsideCircle } from './strategies/fillCircle';
13
+ import { eraseInsideCircle } from './strategies/eraseCircle';
13
14
  import { Events } from '../../enums';
14
15
  import { drawCircle as drawCircleSvg } from '../../drawingSvg';
15
16
  import {
@@ -69,7 +70,7 @@ class CircleScissorsTool extends BaseTool {
69
70
  configuration: {
70
71
  strategies: {
71
72
  FILL_INSIDE: fillInsideCircle,
72
- // ERASE_INSIDE: eraseInsideCircle,
73
+ ERASE_INSIDE: eraseInsideCircle,
73
74
  },
74
75
  defaultStrategy: 'FILL_INSIDE',
75
76
  activeStrategy: 'FILL_INSIDE',
@@ -275,6 +276,7 @@ class CircleScissorsTool extends BaseTool {
275
276
  points: data.handles.points,
276
277
  viewPlaneNormal,
277
278
  viewUp,
279
+ strategySpecificConfiguration: {},
278
280
  };
279
281
 
280
282
  this.editData = null;
@@ -10,6 +10,7 @@ import {
10
10
  } from '../../types';
11
11
 
12
12
  import { fillInsideSphere } from './strategies/fillSphere';
13
+ import { eraseInsideSphere } from './strategies/eraseSphere';
13
14
  import { Events, SegmentationRepresentations } from '../../enums';
14
15
  import { drawCircle as drawCircleSvg } from '../../drawingSvg';
15
16
  import {
@@ -71,6 +72,7 @@ class SphereScissorsTool extends BaseTool {
71
72
  configuration: {
72
73
  strategies: {
73
74
  FILL_INSIDE: fillInsideSphere,
75
+ ERASE_INSIDE: eraseInsideSphere,
74
76
  },
75
77
  defaultStrategy: 'FILL_INSIDE',
76
78
  activeStrategy: 'FILL_INSIDE',
@@ -153,6 +155,7 @@ class SphereScissorsTool extends BaseTool {
153
155
  centerCanvas: canvasPos,
154
156
  segmentationRepresentationUID,
155
157
  segmentIndex,
158
+ segmentationId,
156
159
  segmentsLocked,
157
160
  segmentColor,
158
161
  toolGroupId,