@cornerstonejs/tools 0.56.1 → 0.56.3

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 (360) hide show
  1. package/dist/cjs/tools/CrosshairsTool.d.ts +1 -0
  2. package/dist/cjs/tools/CrosshairsTool.js +4 -1
  3. package/dist/cjs/tools/CrosshairsTool.js.map +1 -1
  4. package/dist/esm/tools/CrosshairsTool.d.ts +1 -0
  5. package/dist/esm/tools/CrosshairsTool.js +4 -1
  6. package/dist/esm/tools/CrosshairsTool.js.map +1 -1
  7. package/dist/umd/index.js +1 -1
  8. package/dist/umd/index.js.map +1 -1
  9. package/package.json +5 -4
  10. package/src/constants/COLOR_LUT.ts +262 -0
  11. package/src/constants/index.ts +3 -0
  12. package/src/cursors/ImageMouseCursor.ts +39 -0
  13. package/src/cursors/MouseCursor.ts +114 -0
  14. package/src/cursors/SVGCursorDescriptor.ts +462 -0
  15. package/src/cursors/SVGMouseCursor.ts +145 -0
  16. package/src/cursors/elementCursor.ts +69 -0
  17. package/src/cursors/index.ts +24 -0
  18. package/src/cursors/setCursorForElement.ts +33 -0
  19. package/src/drawingSvg/_getHash.ts +9 -0
  20. package/src/drawingSvg/_setAttributesIfNecessary.ts +13 -0
  21. package/src/drawingSvg/_setNewAttributesIfValid.ts +10 -0
  22. package/src/drawingSvg/clearByToolType.ts +26 -0
  23. package/src/drawingSvg/draw.ts +16 -0
  24. package/src/drawingSvg/drawArrow.ts +82 -0
  25. package/src/drawingSvg/drawCircle.ts +62 -0
  26. package/src/drawingSvg/drawEllipse.ts +71 -0
  27. package/src/drawingSvg/drawHandles.ts +87 -0
  28. package/src/drawingSvg/drawLine.ts +70 -0
  29. package/src/drawingSvg/drawLink.ts +76 -0
  30. package/src/drawingSvg/drawLinkedTextBox.ts +64 -0
  31. package/src/drawingSvg/drawPolyline.ts +80 -0
  32. package/src/drawingSvg/drawRect.ts +70 -0
  33. package/src/drawingSvg/drawTextBox.ts +213 -0
  34. package/src/drawingSvg/getSvgDrawingHelper.ts +98 -0
  35. package/src/drawingSvg/index.ts +23 -0
  36. package/src/enums/AnnotationStyleStates.ts +22 -0
  37. package/src/enums/Events.ts +242 -0
  38. package/src/enums/SegmentationRepresentations.ts +12 -0
  39. package/src/enums/ToolBindings.ts +37 -0
  40. package/src/enums/ToolModes.ts +31 -0
  41. package/src/enums/Touch.ts +8 -0
  42. package/src/enums/index.js +16 -0
  43. package/src/eventDispatchers/annotationModifiedEventDispatcher.ts +41 -0
  44. package/src/eventDispatchers/cameraModifiedEventDispatcher.ts +41 -0
  45. package/src/eventDispatchers/imageRenderedEventDispatcher.ts +37 -0
  46. package/src/eventDispatchers/imageSpacingCalibratedEventDispatcher.ts +50 -0
  47. package/src/eventDispatchers/index.js +15 -0
  48. package/src/eventDispatchers/keyboardEventHandlers/index.js +4 -0
  49. package/src/eventDispatchers/keyboardEventHandlers/keyDown.ts +29 -0
  50. package/src/eventDispatchers/keyboardEventHandlers/keyUp.ts +33 -0
  51. package/src/eventDispatchers/keyboardToolEventDispatcher.ts +28 -0
  52. package/src/eventDispatchers/mouseEventHandlers/index.js +19 -0
  53. package/src/eventDispatchers/mouseEventHandlers/mouseClick.ts +13 -0
  54. package/src/eventDispatchers/mouseEventHandlers/mouseDoubleClick.ts +13 -0
  55. package/src/eventDispatchers/mouseEventHandlers/mouseDown.ts +196 -0
  56. package/src/eventDispatchers/mouseEventHandlers/mouseDownActivate.ts +35 -0
  57. package/src/eventDispatchers/mouseEventHandlers/mouseDrag.ts +25 -0
  58. package/src/eventDispatchers/mouseEventHandlers/mouseMove.ts +70 -0
  59. package/src/eventDispatchers/mouseEventHandlers/mouseUp.ts +9 -0
  60. package/src/eventDispatchers/mouseEventHandlers/mouseWheel.ts +13 -0
  61. package/src/eventDispatchers/mouseToolEventDispatcher.ts +64 -0
  62. package/src/eventDispatchers/shared/customCallbackHandler.ts +73 -0
  63. package/src/eventDispatchers/shared/getActiveToolForKeyboardEvent.ts +58 -0
  64. package/src/eventDispatchers/shared/getActiveToolForMouseEvent.ts +61 -0
  65. package/src/eventDispatchers/shared/getActiveToolForTouchEvent.ts +64 -0
  66. package/src/eventDispatchers/shared/getMouseModifier.ts +30 -0
  67. package/src/eventDispatchers/shared/getToolsWithModesForMouseEvent.ts +56 -0
  68. package/src/eventDispatchers/shared/getToolsWithModesForTouchEvent.ts +54 -0
  69. package/src/eventDispatchers/touchEventHandlers/index.js +15 -0
  70. package/src/eventDispatchers/touchEventHandlers/touchDrag.ts +23 -0
  71. package/src/eventDispatchers/touchEventHandlers/touchEnd.ts +9 -0
  72. package/src/eventDispatchers/touchEventHandlers/touchPress.ts +13 -0
  73. package/src/eventDispatchers/touchEventHandlers/touchStart.ts +174 -0
  74. package/src/eventDispatchers/touchEventHandlers/touchStartActivate.ts +36 -0
  75. package/src/eventDispatchers/touchEventHandlers/touchTap.ts +9 -0
  76. package/src/eventDispatchers/touchToolEventDispatcher.ts +51 -0
  77. package/src/eventListeners/annotations/annotationModifiedListener.ts +22 -0
  78. package/src/eventListeners/annotations/annotationSelectionListener.ts +29 -0
  79. package/src/eventListeners/annotations/index.ts +4 -0
  80. package/src/eventListeners/index.ts +28 -0
  81. package/src/eventListeners/keyboard/index.ts +16 -0
  82. package/src/eventListeners/keyboard/keyDownListener.ts +99 -0
  83. package/src/eventListeners/mouse/getMouseEventPoints.ts +66 -0
  84. package/src/eventListeners/mouse/index.ts +55 -0
  85. package/src/eventListeners/mouse/mouseDoubleClickListener.ts +55 -0
  86. package/src/eventListeners/mouse/mouseDownListener.ts +519 -0
  87. package/src/eventListeners/mouse/mouseMoveListener.ts +33 -0
  88. package/src/eventListeners/segmentation/index.ts +11 -0
  89. package/src/eventListeners/segmentation/segmentationDataModifiedEventListener.ts +61 -0
  90. package/src/eventListeners/segmentation/segmentationModifiedEventListener.ts +32 -0
  91. package/src/eventListeners/segmentation/segmentationRepresentationModifiedEventListener.ts +15 -0
  92. package/src/eventListeners/segmentation/segmentationRepresentationRemovedEventListener.ts +16 -0
  93. package/src/eventListeners/touch/getTouchEventPoints.ts +75 -0
  94. package/src/eventListeners/touch/index.ts +37 -0
  95. package/src/eventListeners/touch/preventGhostClick.js +72 -0
  96. package/src/eventListeners/touch/touchStartListener.ts +499 -0
  97. package/src/eventListeners/wheel/index.ts +27 -0
  98. package/src/eventListeners/wheel/normalizeWheel.ts +69 -0
  99. package/src/eventListeners/wheel/wheelListener.ts +51 -0
  100. package/src/index.ts +133 -0
  101. package/src/init.ts +187 -0
  102. package/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts +399 -0
  103. package/src/stateManagement/annotation/annotationLocking.ts +178 -0
  104. package/src/stateManagement/annotation/annotationSelection.ts +163 -0
  105. package/src/stateManagement/annotation/annotationState.ts +180 -0
  106. package/src/stateManagement/annotation/annotationVisibility.ts +156 -0
  107. package/src/stateManagement/annotation/config/ToolStyle.ts +265 -0
  108. package/src/stateManagement/annotation/config/getFont.ts +36 -0
  109. package/src/stateManagement/annotation/config/getState.ts +26 -0
  110. package/src/stateManagement/annotation/config/helpers.ts +55 -0
  111. package/src/stateManagement/annotation/config/index.ts +5 -0
  112. package/src/stateManagement/annotation/helpers/state.ts +83 -0
  113. package/src/stateManagement/annotation/index.ts +15 -0
  114. package/src/stateManagement/index.js +40 -0
  115. package/src/stateManagement/segmentation/SegmentationStateManager.ts +491 -0
  116. package/src/stateManagement/segmentation/activeSegmentation.ts +60 -0
  117. package/src/stateManagement/segmentation/addSegmentationRepresentations.ts +77 -0
  118. package/src/stateManagement/segmentation/addSegmentations.ts +27 -0
  119. package/src/stateManagement/segmentation/config/index.ts +29 -0
  120. package/src/stateManagement/segmentation/config/segmentationColor.ts +132 -0
  121. package/src/stateManagement/segmentation/config/segmentationConfig.ts +195 -0
  122. package/src/stateManagement/segmentation/config/segmentationVisibility.ts +171 -0
  123. package/src/stateManagement/segmentation/helpers/index.ts +3 -0
  124. package/src/stateManagement/segmentation/helpers/normalizeSegmentationInput.ts +35 -0
  125. package/src/stateManagement/segmentation/helpers/validateSegmentationInput.ts +41 -0
  126. package/src/stateManagement/segmentation/index.ts +22 -0
  127. package/src/stateManagement/segmentation/removeSegmentationsFromToolGroup.ts +85 -0
  128. package/src/stateManagement/segmentation/segmentIndex.ts +38 -0
  129. package/src/stateManagement/segmentation/segmentLocking.ts +72 -0
  130. package/src/stateManagement/segmentation/segmentationState.ts +429 -0
  131. package/src/stateManagement/segmentation/triggerSegmentationEvents.ts +157 -0
  132. package/src/store/SynchronizerManager/Synchronizer.ts +344 -0
  133. package/src/store/SynchronizerManager/createSynchronizer.ts +41 -0
  134. package/src/store/SynchronizerManager/destroy.ts +14 -0
  135. package/src/store/SynchronizerManager/destroySynchronizer.ts +25 -0
  136. package/src/store/SynchronizerManager/getAllSynchronizers.ts +12 -0
  137. package/src/store/SynchronizerManager/getSynchronizer.ts +13 -0
  138. package/src/store/SynchronizerManager/getSynchronizersForViewport.ts +44 -0
  139. package/src/store/SynchronizerManager/index.js +15 -0
  140. package/src/store/ToolGroupManager/ToolGroup.ts +679 -0
  141. package/src/store/ToolGroupManager/createToolGroup.ts +33 -0
  142. package/src/store/ToolGroupManager/destroy.ts +24 -0
  143. package/src/store/ToolGroupManager/destroyToolGroup.ts +26 -0
  144. package/src/store/ToolGroupManager/getAllToolGroups.ts +12 -0
  145. package/src/store/ToolGroupManager/getToolGroup.ts +14 -0
  146. package/src/store/ToolGroupManager/getToolGroupForViewport.ts +44 -0
  147. package/src/store/ToolGroupManager/getToolGroupsWithToolName.ts +33 -0
  148. package/src/store/ToolGroupManager/index.ts +17 -0
  149. package/src/store/addEnabledElement.ts +137 -0
  150. package/src/store/addTool.ts +56 -0
  151. package/src/store/cancelActiveManipulations.ts +30 -0
  152. package/src/store/filterMoveableAnnotationTools.ts +61 -0
  153. package/src/store/filterToolsWithAnnotationsForElement.ts +51 -0
  154. package/src/store/filterToolsWithMoveableHandles.ts +51 -0
  155. package/src/store/index.ts +29 -0
  156. package/src/store/removeEnabledElement.ts +132 -0
  157. package/src/store/state.ts +57 -0
  158. package/src/store/svgNodeCache.ts +7 -0
  159. package/src/synchronizers/callbacks/areViewportsCoplanar .ts +12 -0
  160. package/src/synchronizers/callbacks/cameraSyncCallback.ts +33 -0
  161. package/src/synchronizers/callbacks/stackImageSyncCallback.ts +157 -0
  162. package/src/synchronizers/callbacks/voiSyncCallback.ts +51 -0
  163. package/src/synchronizers/callbacks/zoomPanSyncCallback.ts +43 -0
  164. package/src/synchronizers/index.ts +11 -0
  165. package/src/synchronizers/synchronizers/createCameraPositionSynchronizer.ts +25 -0
  166. package/src/synchronizers/synchronizers/createStackImageSynchronizer.ts +25 -0
  167. package/src/synchronizers/synchronizers/createVOISynchronizer.ts +24 -0
  168. package/src/synchronizers/synchronizers/createZoomPanSynchronizer.ts +25 -0
  169. package/src/synchronizers/synchronizers/index.ts +11 -0
  170. package/src/tools/CrosshairsTool.ts +2693 -0
  171. package/src/tools/MIPJumpToClickTool.ts +99 -0
  172. package/src/tools/MagnifyTool.ts +319 -0
  173. package/src/tools/PanTool.ts +58 -0
  174. package/src/tools/PlanarRotateTool.ts +77 -0
  175. package/src/tools/ReferenceCursors.ts +466 -0
  176. package/src/tools/ReferenceLinesTool.ts +279 -0
  177. package/src/tools/ScaleOverlayTool.ts +685 -0
  178. package/src/tools/StackScrollTool.ts +97 -0
  179. package/src/tools/StackScrollToolMouseWheelTool.ts +58 -0
  180. package/src/tools/TrackballRotateTool.ts +141 -0
  181. package/src/tools/VolumeRotateMouseWheelTool.ts +86 -0
  182. package/src/tools/WindowLevelTool.ts +260 -0
  183. package/src/tools/ZoomTool.ts +293 -0
  184. package/src/tools/annotation/AngleTool.ts +835 -0
  185. package/src/tools/annotation/ArrowAnnotateTool.ts +820 -0
  186. package/src/tools/annotation/BidirectionalTool.ts +1350 -0
  187. package/src/tools/annotation/CircleROITool.ts +1070 -0
  188. package/src/tools/annotation/CobbAngleTool.ts +815 -0
  189. package/src/tools/annotation/DragProbeTool.ts +213 -0
  190. package/src/tools/annotation/EllipticalROITool.ts +1223 -0
  191. package/src/tools/annotation/LengthTool.ts +861 -0
  192. package/src/tools/annotation/PlanarFreehandROITool.ts +636 -0
  193. package/src/tools/annotation/ProbeTool.ts +681 -0
  194. package/src/tools/annotation/RectangleROITool.ts +1028 -0
  195. package/src/tools/annotation/planarFreehandROITool/closedContourEditLoop.ts +488 -0
  196. package/src/tools/annotation/planarFreehandROITool/drawLoop.ts +462 -0
  197. package/src/tools/annotation/planarFreehandROITool/editLoopCommon.ts +331 -0
  198. package/src/tools/annotation/planarFreehandROITool/findOpenUShapedContourVectorToPeak.ts +74 -0
  199. package/src/tools/annotation/planarFreehandROITool/openContourEditLoop.ts +612 -0
  200. package/src/tools/annotation/planarFreehandROITool/openContourEndEditLoop.ts +74 -0
  201. package/src/tools/annotation/planarFreehandROITool/renderMethods.ts +407 -0
  202. package/src/tools/base/AnnotationDisplayTool.ts +228 -0
  203. package/src/tools/base/AnnotationTool.ts +307 -0
  204. package/src/tools/base/BaseTool.ts +215 -0
  205. package/src/tools/base/index.ts +4 -0
  206. package/src/tools/displayTools/Contour/addContourToElement.ts +135 -0
  207. package/src/tools/displayTools/Contour/contourDisplay.ts +252 -0
  208. package/src/tools/displayTools/Contour/index.ts +3 -0
  209. package/src/tools/displayTools/Contour/removeContourFromElement.ts +35 -0
  210. package/src/tools/displayTools/Labelmap/addLabelmapToElement.ts +57 -0
  211. package/src/tools/displayTools/Labelmap/index.ts +4 -0
  212. package/src/tools/displayTools/Labelmap/labelmapConfig.ts +37 -0
  213. package/src/tools/displayTools/Labelmap/labelmapDisplay.ts +461 -0
  214. package/src/tools/displayTools/Labelmap/removeLabelmapFromElement.ts +27 -0
  215. package/src/tools/displayTools/Labelmap/validateRepresentationData.ts +30 -0
  216. package/src/tools/displayTools/SegmentationDisplayTool.ts +198 -0
  217. package/src/tools/index.ts +84 -0
  218. package/src/tools/segmentation/BrushTool.ts +474 -0
  219. package/src/tools/segmentation/CircleScissorsTool.ts +365 -0
  220. package/src/tools/segmentation/PaintFillTool.ts +370 -0
  221. package/src/tools/segmentation/RectangleROIStartEndThresholdTool.ts +471 -0
  222. package/src/tools/segmentation/RectangleROIThresholdTool.ts +281 -0
  223. package/src/tools/segmentation/RectangleScissorsTool.ts +382 -0
  224. package/src/tools/segmentation/SphereScissorsTool.ts +368 -0
  225. package/src/tools/segmentation/strategies/eraseCircle.ts +30 -0
  226. package/src/tools/segmentation/strategies/eraseRectangle.ts +81 -0
  227. package/src/tools/segmentation/strategies/eraseSphere.ts +27 -0
  228. package/src/tools/segmentation/strategies/fillCircle.ts +185 -0
  229. package/src/tools/segmentation/strategies/fillRectangle.ts +110 -0
  230. package/src/tools/segmentation/strategies/fillSphere.ts +88 -0
  231. package/src/tools/segmentation/strategies/index.ts +9 -0
  232. package/src/types/AnnotationGroupSelector.ts +7 -0
  233. package/src/types/AnnotationStyle.ts +42 -0
  234. package/src/types/AnnotationTypes.ts +109 -0
  235. package/src/types/BoundsIJK.ts +5 -0
  236. package/src/types/CINETypes.ts +32 -0
  237. package/src/types/ContourTypes.ts +26 -0
  238. package/src/types/CursorTypes.ts +12 -0
  239. package/src/types/EventTypes.ts +657 -0
  240. package/src/types/FloodFillTypes.ts +19 -0
  241. package/src/types/IAnnotationManager.ts +89 -0
  242. package/src/types/IDistance.ts +16 -0
  243. package/src/types/IPoints.ts +18 -0
  244. package/src/types/ISetToolModeOptions.ts +29 -0
  245. package/src/types/ISynchronizerEventHandler.ts +11 -0
  246. package/src/types/IToolClassReference.ts +5 -0
  247. package/src/types/IToolGroup.ts +72 -0
  248. package/src/types/ITouchPoints.ts +14 -0
  249. package/src/types/InteractionTypes.ts +6 -0
  250. package/src/types/InternalToolTypes.ts +19 -0
  251. package/src/types/JumpToSliceOptions.ts +7 -0
  252. package/src/types/LabelmapTypes.ts +41 -0
  253. package/src/types/PlanarBoundingBox.ts +8 -0
  254. package/src/types/SVGDrawingHelper.ts +10 -0
  255. package/src/types/ScrollOptions.ts +9 -0
  256. package/src/types/SegmentationStateTypes.ts +248 -0
  257. package/src/types/ToolHandle.ts +26 -0
  258. package/src/types/ToolProps.ts +16 -0
  259. package/src/types/ToolSpecificAnnotationTypes.ts +311 -0
  260. package/src/types/index.ts +115 -0
  261. package/src/utilities/boundingBox/extend2DBoundingBoxInViewAxis.ts +29 -0
  262. package/src/utilities/boundingBox/getBoundingBoxAroundShape.ts +57 -0
  263. package/src/utilities/boundingBox/index.ts +4 -0
  264. package/src/utilities/calibrateImageSpacing.ts +46 -0
  265. package/src/utilities/cine/events.ts +9 -0
  266. package/src/utilities/cine/index.ts +5 -0
  267. package/src/utilities/cine/playClip.ts +435 -0
  268. package/src/utilities/cine/state.ts +18 -0
  269. package/src/utilities/clip.js +30 -0
  270. package/src/utilities/debounce.js +217 -0
  271. package/src/utilities/drawing/getTextBoxCoordsCanvas.ts +45 -0
  272. package/src/utilities/drawing/index.ts +3 -0
  273. package/src/utilities/dynamicVolume/getDataInTime.ts +110 -0
  274. package/src/utilities/dynamicVolume/index.ts +2 -0
  275. package/src/utilities/getAnnotationNearPoint.ts +130 -0
  276. package/src/utilities/getModalityUnit.ts +11 -0
  277. package/src/utilities/getToolsWithModesForElement.ts +52 -0
  278. package/src/utilities/index.ts +68 -0
  279. package/src/utilities/isObject.js +29 -0
  280. package/src/utilities/math/angle/angleBetweenLines.ts +29 -0
  281. package/src/utilities/math/circle/_types.ts +6 -0
  282. package/src/utilities/math/circle/getCanvasCircleCorners.ts +23 -0
  283. package/src/utilities/math/circle/getCanvasCircleRadius.ts +16 -0
  284. package/src/utilities/math/circle/index.ts +4 -0
  285. package/src/utilities/math/ellipse/getCanvasEllipseCorners.ts +26 -0
  286. package/src/utilities/math/ellipse/index.ts +4 -0
  287. package/src/utilities/math/ellipse/pointInEllipse.ts +38 -0
  288. package/src/utilities/math/ellipse/pointInEllipsoidWithConstraint.ts +35 -0
  289. package/src/utilities/math/index.ts +8 -0
  290. package/src/utilities/math/line/distanceToPoint.ts +24 -0
  291. package/src/utilities/math/line/distanceToPointSquared.ts +44 -0
  292. package/src/utilities/math/line/index.ts +5 -0
  293. package/src/utilities/math/line/intersectLine.ts +92 -0
  294. package/src/utilities/math/midPoint.ts +24 -0
  295. package/src/utilities/math/point/distanceToPoint.ts +22 -0
  296. package/src/utilities/math/point/index.ts +3 -0
  297. package/src/utilities/math/polyline/addCanvasPointsToArray.ts +62 -0
  298. package/src/utilities/math/polyline/calculateAreaOfPoints.ts +23 -0
  299. package/src/utilities/math/polyline/getIntersectionWithPolyline.ts +182 -0
  300. package/src/utilities/math/polyline/getSubPixelSpacingAndXYDirections.ts +99 -0
  301. package/src/utilities/math/polyline/index.ts +19 -0
  302. package/src/utilities/math/polyline/planarFreehandROIInternalTypes.ts +36 -0
  303. package/src/utilities/math/polyline/pointCanProjectOnLine.ts +57 -0
  304. package/src/utilities/math/polyline/pointsAreWithinCloseContourProximity.ts +15 -0
  305. package/src/utilities/math/rectangle/distanceToPoint.ts +82 -0
  306. package/src/utilities/math/rectangle/index.ts +3 -0
  307. package/src/utilities/math/sphere/index.ts +3 -0
  308. package/src/utilities/math/sphere/pointInSphere.ts +31 -0
  309. package/src/utilities/math/vec2/findClosestPoint.ts +40 -0
  310. package/src/utilities/math/vec2/index.ts +4 -0
  311. package/src/utilities/math/vec2/liangBarksyClip.ts +84 -0
  312. package/src/utilities/orientation/getOrientationStringLPS.ts +52 -0
  313. package/src/utilities/orientation/index.ts +4 -0
  314. package/src/utilities/orientation/invertOrientationStringLPS.ts +21 -0
  315. package/src/utilities/planar/filterAnnotationsForDisplay.ts +68 -0
  316. package/src/utilities/planar/filterAnnotationsWithinSlice.ts +85 -0
  317. package/src/utilities/planar/getPointInLineOfSightWithCriteria.ts +104 -0
  318. package/src/utilities/planar/getWorldWidthAndHeightFromCorners.ts +51 -0
  319. package/src/utilities/planar/getWorldWidthAndHeightFromTwoPoints.ts +51 -0
  320. package/src/utilities/planar/index.ts +18 -0
  321. package/src/utilities/planarFreehandROITool/index.ts +7 -0
  322. package/src/utilities/planarFreehandROITool/interpolateAnnotation.ts +87 -0
  323. package/src/utilities/planarFreehandROITool/interpolatePoints.ts +214 -0
  324. package/src/utilities/planarFreehandROITool/interpolation/algorithms/bspline.ts +55 -0
  325. package/src/utilities/planarFreehandROITool/interpolation/interpolateSegmentPoints.ts +90 -0
  326. package/src/utilities/pointInShapeCallback.ts +138 -0
  327. package/src/utilities/pointInSurroundingSphereCallback.ts +188 -0
  328. package/src/utilities/rectangleROITool/getBoundsIJKFromRectangleAnnotations.ts +76 -0
  329. package/src/utilities/rectangleROITool/index.ts +3 -0
  330. package/src/utilities/scroll.ts +62 -0
  331. package/src/utilities/segmentation/brushSizeForToolGroup.ts +72 -0
  332. package/src/utilities/segmentation/brushThresholdForToolGroup.ts +65 -0
  333. package/src/utilities/segmentation/createLabelmapVolumeForViewport.ts +74 -0
  334. package/src/utilities/segmentation/createMergedLabelmapForIndex.ts +65 -0
  335. package/src/utilities/segmentation/floodFill.ts +194 -0
  336. package/src/utilities/segmentation/getDefaultRepresentationConfig.ts +20 -0
  337. package/src/utilities/segmentation/index.ts +33 -0
  338. package/src/utilities/segmentation/isValidRepresentationConfig.ts +22 -0
  339. package/src/utilities/segmentation/rectangleROIThresholdVolumeByRange.ts +91 -0
  340. package/src/utilities/segmentation/thresholdSegmentationByRange.ts +129 -0
  341. package/src/utilities/segmentation/thresholdVolumeByRange.ts +150 -0
  342. package/src/utilities/segmentation/triggerSegmentationRender.ts +206 -0
  343. package/src/utilities/segmentation/utilities.ts +116 -0
  344. package/src/utilities/stackPrefetch/index.ts +8 -0
  345. package/src/utilities/stackPrefetch/stackPrefetch.ts +405 -0
  346. package/src/utilities/stackPrefetch/state.ts +17 -0
  347. package/src/utilities/throttle.js +69 -0
  348. package/src/utilities/touch/index.ts +246 -0
  349. package/src/utilities/triggerAnnotationRender.ts +237 -0
  350. package/src/utilities/triggerAnnotationRenderForViewportIds.ts +18 -0
  351. package/src/utilities/viewport/index.ts +5 -0
  352. package/src/utilities/viewport/isViewportPreScaled.ts +24 -0
  353. package/src/utilities/viewport/jumpToSlice.ts +73 -0
  354. package/src/utilities/viewport/jumpToWorld.ts +58 -0
  355. package/src/utilities/viewportFilters/filterViewportsWithFrameOfReferenceUID.ts +28 -0
  356. package/src/utilities/viewportFilters/filterViewportsWithParallelNormals.ts +26 -0
  357. package/src/utilities/viewportFilters/filterViewportsWithSameOrientation.ts +15 -0
  358. package/src/utilities/viewportFilters/filterViewportsWithToolEnabled.ts +72 -0
  359. package/src/utilities/viewportFilters/getViewportIdsWithToolToRender.ts +45 -0
  360. package/src/utilities/viewportFilters/index.ts +11 -0
@@ -0,0 +1,368 @@
1
+ import { cache, getEnabledElement, StackViewport } from '@cornerstonejs/core';
2
+ import type { Types } from '@cornerstonejs/core';
3
+
4
+ import { BaseTool } from '../base';
5
+ import {
6
+ PublicToolProps,
7
+ ToolProps,
8
+ EventTypes,
9
+ SVGDrawingHelper,
10
+ } from '../../types';
11
+
12
+ import { fillInsideSphere } from './strategies/fillSphere';
13
+ import { Events } from '../../enums';
14
+ import { drawCircle as drawCircleSvg } from '../../drawingSvg';
15
+ import {
16
+ resetElementCursor,
17
+ hideElementCursor,
18
+ } from '../../cursors/elementCursor';
19
+
20
+ import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
21
+ import {
22
+ config as segmentationConfig,
23
+ segmentLocking,
24
+ segmentIndex as segmentIndexController,
25
+ activeSegmentation,
26
+ } from '../../stateManagement/segmentation';
27
+
28
+ import { getSegmentation } from '../../stateManagement/segmentation/segmentationState';
29
+ import { LabelmapSegmentationData } from '../../types/LabelmapTypes';
30
+
31
+ /**
32
+ * Tool for manipulating segmentation data by drawing a sphere in 3d space. It acts on the
33
+ * active Segmentation on the viewport (enabled element) and requires an active
34
+ * segmentation to be already present. By default it will use the activeSegmentIndex
35
+ * for the segmentation to modify. You can use SegmentationModule to set the active
36
+ * segmentation and segmentIndex. Todo: sphere scissor has some memory problem which
37
+ * lead to ui blocking behavior that needs to be fixed.
38
+ */
39
+ class SphereScissorsTool extends BaseTool {
40
+ static toolName;
41
+ editData: {
42
+ annotation: any;
43
+ segmentation: any;
44
+ segmentIndex: number;
45
+ segmentsLocked: number[];
46
+ segmentationId: string;
47
+ toolGroupId: string;
48
+ segmentColor: [number, number, number, number];
49
+ viewportIdsToRender: string[];
50
+ handleIndex?: number;
51
+ movingTextBox: boolean;
52
+ newAnnotation?: boolean;
53
+ hasMoved?: boolean;
54
+ centerCanvas?: Array<number>;
55
+ } | null;
56
+ isDrawing: boolean;
57
+ isHandleOutsideImage: boolean;
58
+
59
+ constructor(
60
+ toolProps: PublicToolProps = {},
61
+ defaultToolProps: ToolProps = {
62
+ supportedInteractionTypes: ['Mouse', 'Touch'],
63
+ configuration: {
64
+ strategies: {
65
+ FILL_INSIDE: fillInsideSphere,
66
+ },
67
+ defaultStrategy: 'FILL_INSIDE',
68
+ activeStrategy: 'FILL_INSIDE',
69
+ },
70
+ }
71
+ ) {
72
+ super(toolProps, defaultToolProps);
73
+ }
74
+
75
+ /**
76
+ * Based on the current position of the mouse and the enabledElement, it
77
+ * finds the active segmentation info and use it for the current tool.
78
+ *
79
+ * @param evt - EventTypes.NormalizedMouseEventType
80
+ * @returns The annotation object.
81
+ *
82
+ */
83
+ preMouseDownCallback = (evt: EventTypes.InteractionEventType): true => {
84
+ const eventDetail = evt.detail;
85
+ const { currentPoints, element } = eventDetail;
86
+ const worldPos = currentPoints.world;
87
+ const canvasPos = currentPoints.canvas;
88
+
89
+ const enabledElement = getEnabledElement(element);
90
+ const { viewport, renderingEngine } = enabledElement;
91
+
92
+ this.isDrawing = true;
93
+
94
+ const camera = viewport.getCamera();
95
+ const { viewPlaneNormal, viewUp } = camera;
96
+ const toolGroupId = this.toolGroupId;
97
+
98
+ const activeSegmentationRepresentation =
99
+ activeSegmentation.getActiveSegmentationRepresentation(toolGroupId);
100
+ if (!activeSegmentationRepresentation) {
101
+ throw new Error(
102
+ 'No active segmentation detected, create one before using scissors tool'
103
+ );
104
+ }
105
+
106
+ const { segmentationRepresentationUID, segmentationId, type } =
107
+ activeSegmentationRepresentation;
108
+ const segmentIndex =
109
+ segmentIndexController.getActiveSegmentIndex(segmentationId);
110
+ const segmentsLocked = segmentLocking.getLockedSegments(segmentationId);
111
+
112
+ const segmentColor = segmentationConfig.color.getColorForSegmentIndex(
113
+ toolGroupId,
114
+ segmentationRepresentationUID,
115
+ segmentIndex
116
+ );
117
+
118
+ const { representationData } = getSegmentation(segmentationId);
119
+
120
+ // Todo: are we going to support contour editing with rectangle scissors?
121
+ const { volumeId } = representationData[type] as LabelmapSegmentationData;
122
+ const segmentation = cache.getVolume(volumeId);
123
+
124
+ this.isDrawing = true;
125
+
126
+ // Used for drawing the svg only, we might not need it at all
127
+ const annotation = {
128
+ metadata: {
129
+ viewPlaneNormal: <Types.Point3>[...viewPlaneNormal],
130
+ viewUp: <Types.Point3>[...viewUp],
131
+ FrameOfReferenceUID: viewport.getFrameOfReferenceUID(),
132
+ referencedImageId: '',
133
+ toolName: this.getToolName(),
134
+ segmentColor,
135
+ },
136
+ data: {
137
+ invalidated: true,
138
+ handles: {
139
+ points: [[...worldPos], [...worldPos], [...worldPos], [...worldPos]],
140
+ activeHandleIndex: null,
141
+ },
142
+ cachedStats: {},
143
+ highlighted: true,
144
+ },
145
+ };
146
+
147
+ const viewportIdsToRender = [viewport.id];
148
+
149
+ this.editData = {
150
+ annotation,
151
+ segmentation,
152
+ centerCanvas: canvasPos,
153
+ segmentIndex,
154
+ segmentsLocked,
155
+ segmentColor,
156
+ segmentationId,
157
+ toolGroupId,
158
+ viewportIdsToRender,
159
+ handleIndex: 3,
160
+ movingTextBox: false,
161
+ newAnnotation: true,
162
+ hasMoved: false,
163
+ };
164
+
165
+ this._activateDraw(element);
166
+
167
+ hideElementCursor(element);
168
+
169
+ evt.preventDefault();
170
+
171
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
172
+
173
+ return true;
174
+ };
175
+
176
+ _dragCallback = (evt: EventTypes.InteractionEventType) => {
177
+ this.isDrawing = true;
178
+ const eventDetail = evt.detail;
179
+ const { element } = eventDetail;
180
+ const { currentPoints } = eventDetail;
181
+ const currentCanvasPoints = currentPoints.canvas;
182
+ const enabledElement = getEnabledElement(element);
183
+ const { renderingEngine, viewport } = enabledElement;
184
+ const { canvasToWorld } = viewport;
185
+
186
+ //////
187
+ const { annotation, viewportIdsToRender, centerCanvas } = this.editData;
188
+ const { data } = annotation;
189
+
190
+ const dX = Math.abs(currentCanvasPoints[0] - centerCanvas[0]);
191
+ const dY = Math.abs(currentCanvasPoints[1] - centerCanvas[1]);
192
+ const radius = Math.sqrt(dX * dX + dY * dY);
193
+
194
+ const bottomCanvas: Types.Point2 = [
195
+ centerCanvas[0],
196
+ centerCanvas[1] + radius,
197
+ ];
198
+ const topCanvas: Types.Point2 = [centerCanvas[0], centerCanvas[1] - radius];
199
+ const leftCanvas: Types.Point2 = [
200
+ centerCanvas[0] - radius,
201
+ centerCanvas[1],
202
+ ];
203
+ const rightCanvas: Types.Point2 = [
204
+ centerCanvas[0] + radius,
205
+ centerCanvas[1],
206
+ ];
207
+
208
+ data.handles.points = [
209
+ canvasToWorld(bottomCanvas),
210
+ canvasToWorld(topCanvas),
211
+ canvasToWorld(leftCanvas),
212
+ canvasToWorld(rightCanvas),
213
+ ];
214
+
215
+ annotation.invalidated = true;
216
+
217
+ this.editData.hasMoved = true;
218
+
219
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
220
+ };
221
+
222
+ _endCallback = (evt: EventTypes.InteractionEventType) => {
223
+ const eventDetail = evt.detail;
224
+ const { element } = eventDetail;
225
+
226
+ const {
227
+ annotation,
228
+ newAnnotation,
229
+ hasMoved,
230
+ segmentation,
231
+ segmentIndex,
232
+ segmentsLocked,
233
+ segmentationId,
234
+ } = this.editData;
235
+ const { data } = annotation;
236
+ const { viewPlaneNormal, viewUp } = annotation.metadata;
237
+
238
+ if (newAnnotation && !hasMoved) {
239
+ return;
240
+ }
241
+ annotation.highlighted = false;
242
+ data.handles.activeHandleIndex = null;
243
+
244
+ this._deactivateDraw(element);
245
+
246
+ resetElementCursor(element);
247
+
248
+ const enabledElement = getEnabledElement(element);
249
+ const { viewport } = enabledElement;
250
+
251
+ this.editData = null;
252
+ this.isDrawing = false;
253
+
254
+ if (viewport instanceof StackViewport) {
255
+ throw new Error('Not implemented yet');
256
+ }
257
+
258
+ const operationData = {
259
+ points: data.handles.points,
260
+ volume: segmentation,
261
+ segmentIndex,
262
+ segmentsLocked,
263
+ segmentationId,
264
+ viewPlaneNormal,
265
+ viewUp,
266
+ };
267
+
268
+ this.applyActiveStrategy(enabledElement, operationData);
269
+ };
270
+
271
+ /**
272
+ * Add event handlers for the modify event loop, and prevent default event propagation.
273
+ */
274
+ _activateDraw = (element) => {
275
+ element.addEventListener(Events.MOUSE_UP, this._endCallback);
276
+ element.addEventListener(Events.MOUSE_DRAG, this._dragCallback);
277
+ element.addEventListener(Events.MOUSE_CLICK, this._endCallback);
278
+
279
+ element.addEventListener(Events.TOUCH_END, this._endCallback);
280
+ element.addEventListener(Events.TOUCH_TAP, this._endCallback);
281
+ element.addEventListener(Events.TOUCH_DRAG, this._dragCallback);
282
+ };
283
+
284
+ /**
285
+ * Add event handlers for the modify event loop, and prevent default event prapogation.
286
+ */
287
+ _deactivateDraw = (element) => {
288
+ element.removeEventListener(Events.MOUSE_UP, this._endCallback);
289
+ element.removeEventListener(Events.MOUSE_DRAG, this._dragCallback);
290
+ element.removeEventListener(Events.MOUSE_CLICK, this._endCallback);
291
+
292
+ element.removeEventListener(Events.TOUCH_END, this._endCallback);
293
+ element.removeEventListener(Events.TOUCH_DRAG, this._dragCallback);
294
+ element.removeEventListener(Events.TOUCH_TAP, this._endCallback);
295
+ };
296
+
297
+ /**
298
+ * it is used to draw the sphereScissor annotation in each
299
+ * request animation frame. Note that the annotation are disappeared
300
+ * after the segmentation modification.
301
+ *
302
+ * @param enabledElement - The Cornerstone's enabledElement.
303
+ * @param svgDrawingHelper - The svgDrawingHelper providing the context for drawing.
304
+ */
305
+ renderAnnotation = (
306
+ enabledElement: Types.IEnabledElement,
307
+ svgDrawingHelper: SVGDrawingHelper
308
+ ): boolean => {
309
+ let renderStatus = false;
310
+ if (!this.editData) {
311
+ return renderStatus;
312
+ }
313
+
314
+ const { viewport } = enabledElement;
315
+ const { viewportIdsToRender } = this.editData;
316
+
317
+ if (!viewportIdsToRender.includes(viewport.id)) {
318
+ return renderStatus;
319
+ }
320
+
321
+ const { annotation } = this.editData;
322
+
323
+ // Todo: rectangle color based on segment index
324
+ const toolMetadata = annotation.metadata;
325
+ const annotationUID = annotation.annotationUID;
326
+
327
+ const data = annotation.data;
328
+ const { points } = data.handles;
329
+ const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p));
330
+
331
+ const bottom = canvasCoordinates[0];
332
+ const top = canvasCoordinates[1];
333
+
334
+ const center = [
335
+ Math.floor((bottom[0] + top[0]) / 2),
336
+ Math.floor((bottom[1] + top[1]) / 2),
337
+ ];
338
+
339
+ const radius = Math.abs(bottom[1] - Math.floor((bottom[1] + top[1]) / 2));
340
+
341
+ const color = `rgb(${toolMetadata.segmentColor.slice(0, 3)})`;
342
+
343
+ // If rendering engine has been destroyed while rendering
344
+ if (!viewport.getRenderingEngine()) {
345
+ console.warn('Rendering Engine has been destroyed');
346
+ return renderStatus;
347
+ }
348
+
349
+ const circleUID = '0';
350
+ drawCircleSvg(
351
+ svgDrawingHelper,
352
+ annotationUID,
353
+ circleUID,
354
+ center as Types.Point2,
355
+ radius,
356
+ {
357
+ color,
358
+ }
359
+ );
360
+
361
+ renderStatus = true;
362
+
363
+ return renderStatus;
364
+ };
365
+ }
366
+
367
+ SphereScissorsTool.toolName = 'SphereScissor';
368
+ export default SphereScissorsTool;
@@ -0,0 +1,30 @@
1
+ import type { Types } from '@cornerstonejs/core';
2
+
3
+ import { fillInsideCircle } from './fillCircle';
4
+
5
+ type OperationData = {
6
+ segmentationId: string;
7
+ imageVolume: Types.IImageVolume;
8
+ points: any; // Todo:fix
9
+ volume: Types.IImageVolume;
10
+ segmentIndex: number;
11
+ segmentsLocked: number[];
12
+ viewPlaneNormal: number[];
13
+ viewUp: number[];
14
+ strategySpecificConfiguration: any;
15
+ constraintFn: () => boolean;
16
+ };
17
+
18
+ export function eraseInsideCircle(
19
+ enabledElement: Types.IEnabledElement,
20
+ operationData: OperationData
21
+ ): void {
22
+ // Take the arguments and set the segmentIndex to 0,
23
+ // Then use existing fillInsideCircle functionality.
24
+ const eraseOperationData = {
25
+ ...operationData,
26
+ segmentIndex: 0,
27
+ };
28
+
29
+ fillInsideCircle(enabledElement, eraseOperationData);
30
+ }
@@ -0,0 +1,81 @@
1
+ import { ImageVolume, utilities as csUtils } from '@cornerstonejs/core';
2
+ import type { Types } from '@cornerstonejs/core';
3
+
4
+ import { getBoundingBoxAroundShape } from '../../../utilities/boundingBox';
5
+ import { triggerSegmentationDataModified } from '../../../stateManagement/segmentation/triggerSegmentationEvents';
6
+ import { pointInShapeCallback } from '../../../utilities';
7
+
8
+ const { transformWorldToIndex } = csUtils;
9
+
10
+ type EraseOperationData = {
11
+ segmentationId: string;
12
+ points: [Types.Point3, Types.Point3, Types.Point3, Types.Point3];
13
+ volume: ImageVolume;
14
+ constraintFn: (x: [number, number, number]) => boolean;
15
+ segmentsLocked: number[];
16
+ };
17
+
18
+ function eraseRectangle(
19
+ enabledElement: Types.IEnabledElement,
20
+ operationData: EraseOperationData,
21
+ inside = true
22
+ ): void {
23
+ const {
24
+ volume: segmentation,
25
+ points,
26
+ segmentsLocked,
27
+ segmentationId,
28
+ } = operationData;
29
+ const { imageData, dimensions } = segmentation;
30
+ const scalarData = segmentation.getScalarData();
31
+
32
+ const rectangleCornersIJK = points.map((world) => {
33
+ return transformWorldToIndex(imageData, world);
34
+ });
35
+
36
+ const boundsIJK = getBoundingBoxAroundShape(rectangleCornersIJK, dimensions);
37
+
38
+ if (boundsIJK.every(([min, max]) => min !== max)) {
39
+ throw new Error('Oblique segmentation tools are not supported yet');
40
+ }
41
+
42
+ // Since always all points inside the boundsIJK is inside the rectangle...
43
+ const pointInShape = () => true;
44
+
45
+ const callback = ({ value, index }) => {
46
+ if (segmentsLocked.includes(value)) {
47
+ return;
48
+ }
49
+ scalarData[index] = 0;
50
+ };
51
+
52
+ pointInShapeCallback(imageData, pointInShape, callback, boundsIJK);
53
+
54
+ triggerSegmentationDataModified(segmentationId);
55
+ }
56
+
57
+ /**
58
+ * Erase the rectangle region segment inside the segmentation defined by the operationData.
59
+ * It erases the segmentation pixels inside the defined rectangle.
60
+ * @param enabledElement - The element for which the segment is being erased.
61
+ * @param operationData - EraseOperationData
62
+ */
63
+ export function eraseInsideRectangle(
64
+ enabledElement: Types.IEnabledElement,
65
+ operationData: EraseOperationData
66
+ ): void {
67
+ eraseRectangle(enabledElement, operationData, true);
68
+ }
69
+
70
+ /**
71
+ * Erase the rectangle region segment inside the segmentation defined by the operationData.
72
+ * It erases the segmentation pixels outside the defined rectangle.
73
+ * @param enabledElement - The element for which the segment is being erased.
74
+ * @param operationData - EraseOperationData
75
+ */
76
+ export function eraseOutsideRectangle(
77
+ enabledElement: Types.IEnabledElement,
78
+ operationData: EraseOperationData
79
+ ): void {
80
+ eraseRectangle(enabledElement, operationData, false);
81
+ }
@@ -0,0 +1,27 @@
1
+ import type { Types } from '@cornerstonejs/core';
2
+
3
+ import { fillInsideSphere } from './fillSphere';
4
+
5
+ type OperationData = {
6
+ points: [Types.Point3, Types.Point3, Types.Point3, Types.Point3];
7
+ volume: Types.IImageVolume;
8
+ segmentIndex: number;
9
+ segmentationId: string;
10
+ segmentsLocked: number[];
11
+ viewPlaneNormal: Types.Point3;
12
+ viewUp: Types.Point3;
13
+ constraintFn: () => boolean;
14
+ };
15
+
16
+ export function eraseInsideSphere(
17
+ enabledElement: Types.IEnabledElement,
18
+ operationData: OperationData
19
+ ): void {
20
+ // Take the arguments and set the segmentIndex to 0,
21
+ // Then use existing fillInsideCircle functionality.
22
+ const eraseOperationData = Object.assign({}, operationData, {
23
+ segmentIndex: 0,
24
+ });
25
+
26
+ fillInsideSphere(enabledElement, eraseOperationData);
27
+ }
@@ -0,0 +1,185 @@
1
+ import { vec3 } from 'gl-matrix';
2
+ import type { Types } from '@cornerstonejs/core';
3
+ import { utilities as csUtils } from '@cornerstonejs/core';
4
+
5
+ import {
6
+ getCanvasEllipseCorners,
7
+ pointInEllipse,
8
+ } from '../../../utilities/math/ellipse';
9
+ import { getBoundingBoxAroundShape } from '../../../utilities/boundingBox';
10
+ import { triggerSegmentationDataModified } from '../../../stateManagement/segmentation/triggerSegmentationEvents';
11
+ import { pointInShapeCallback } from '../../../utilities';
12
+
13
+ const { transformWorldToIndex } = csUtils;
14
+
15
+ type OperationData = {
16
+ segmentationId: string;
17
+ imageVolume: Types.IImageVolume;
18
+ points: any; // Todo:fix
19
+ volume: Types.IImageVolume;
20
+ segmentIndex: number;
21
+ segmentsLocked: number[];
22
+ viewPlaneNormal: number[];
23
+ viewUp: number[];
24
+ strategySpecificConfiguration: any;
25
+ constraintFn: () => boolean;
26
+ };
27
+
28
+ function fillCircle(
29
+ enabledElement: Types.IEnabledElement,
30
+ operationData: OperationData,
31
+ threshold = false
32
+ ): void {
33
+ const {
34
+ volume: segmentationVolume,
35
+ imageVolume,
36
+ points,
37
+ segmentsLocked,
38
+ segmentIndex,
39
+ segmentationId,
40
+ strategySpecificConfiguration,
41
+ } = operationData;
42
+ const { imageData, dimensions } = segmentationVolume;
43
+ const scalarData = segmentationVolume.getScalarData();
44
+ const { viewport } = enabledElement;
45
+
46
+ // Average the points to get the center of the ellipse
47
+ const center = vec3.fromValues(0, 0, 0);
48
+ points.forEach((point) => {
49
+ vec3.add(center, center, point);
50
+ });
51
+ vec3.scale(center, center, 1 / points.length);
52
+
53
+ const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p));
54
+
55
+ // 1. From the drawn tool: Get the ellipse (circle) topLeft and bottomRight
56
+ // corners in canvas coordinates
57
+ const [topLeftCanvas, bottomRightCanvas] =
58
+ getCanvasEllipseCorners(canvasCoordinates);
59
+
60
+ // 2. Find the extent of the ellipse (circle) in IJK index space of the image
61
+ const topLeftWorld = viewport.canvasToWorld(topLeftCanvas);
62
+ const bottomRightWorld = viewport.canvasToWorld(bottomRightCanvas);
63
+
64
+ const ellipsoidCornersIJK = [
65
+ <Types.Point3>transformWorldToIndex(imageData, topLeftWorld),
66
+ <Types.Point3>transformWorldToIndex(imageData, bottomRightWorld),
67
+ ];
68
+
69
+ const boundsIJK = getBoundingBoxAroundShape(ellipsoidCornersIJK, dimensions);
70
+
71
+ if (boundsIJK.every(([min, max]) => min !== max)) {
72
+ throw new Error('Oblique segmentation tools are not supported yet');
73
+ }
74
+
75
+ // using circle as a form of ellipse
76
+ const ellipseObj = {
77
+ center: center as Types.Point3,
78
+ xRadius: Math.abs(topLeftWorld[0] - bottomRightWorld[0]) / 2,
79
+ yRadius: Math.abs(topLeftWorld[1] - bottomRightWorld[1]) / 2,
80
+ zRadius: Math.abs(topLeftWorld[2] - bottomRightWorld[2]) / 2,
81
+ };
82
+
83
+ const modifiedSlicesToUse = new Set() as Set<number>;
84
+
85
+ let callback;
86
+
87
+ if (threshold) {
88
+ callback = ({ value, index, pointIJK }) => {
89
+ if (segmentsLocked.includes(value)) {
90
+ return;
91
+ }
92
+
93
+ if (
94
+ isWithinThreshold(index, imageVolume, strategySpecificConfiguration)
95
+ ) {
96
+ scalarData[index] = segmentIndex;
97
+ //Todo: I don't think this will always be index 2 in streamingImageVolume?
98
+ modifiedSlicesToUse.add(pointIJK[2]);
99
+ }
100
+ };
101
+ } else {
102
+ callback = ({ value, index, pointIJK }) => {
103
+ if (segmentsLocked.includes(value)) {
104
+ return;
105
+ }
106
+ scalarData[index] = segmentIndex;
107
+ //Todo: I don't think this will always be index 2 in streamingImageVolume?
108
+ modifiedSlicesToUse.add(pointIJK[2]);
109
+ };
110
+ }
111
+
112
+ pointInShapeCallback(
113
+ imageData,
114
+ (pointLPS, pointIJK) => pointInEllipse(ellipseObj, pointLPS),
115
+ callback,
116
+ boundsIJK
117
+ );
118
+
119
+ const arrayOfSlices: number[] = Array.from(modifiedSlicesToUse);
120
+
121
+ triggerSegmentationDataModified(segmentationId, arrayOfSlices);
122
+ }
123
+
124
+ function isWithinThreshold(
125
+ index: number,
126
+ imageVolume: Types.IImageVolume,
127
+ strategySpecificConfiguration: any
128
+ ) {
129
+ const { THRESHOLD_INSIDE_CIRCLE } = strategySpecificConfiguration;
130
+
131
+ const voxelValue = imageVolume.getScalarData()[index];
132
+ const { threshold } = THRESHOLD_INSIDE_CIRCLE;
133
+
134
+ return threshold[0] <= voxelValue && voxelValue <= threshold[1];
135
+ }
136
+
137
+ /**
138
+ * Fill inside the circular region segment inside the segmentation defined by the operationData.
139
+ * It fills the segmentation pixels inside the defined circle.
140
+ * @param enabledElement - The element for which the segment is being erased.
141
+ * @param operationData - EraseOperationData
142
+ */
143
+ export function fillInsideCircle(
144
+ enabledElement: Types.IEnabledElement,
145
+ operationData: OperationData
146
+ ): void {
147
+ fillCircle(enabledElement, operationData, false);
148
+ }
149
+
150
+ /**
151
+ * Fill inside the circular region segment inside the segmentation defined by the operationData.
152
+ * It fills the segmentation pixels inside the defined circle.
153
+ * @param enabledElement - The element for which the segment is being erased.
154
+ * @param operationData - EraseOperationData
155
+ */
156
+ export function thresholdInsideCircle(
157
+ enabledElement: Types.IEnabledElement,
158
+ operationData: OperationData
159
+ ): void {
160
+ const { volume, imageVolume } = operationData;
161
+
162
+ if (
163
+ !csUtils.isEqual(volume.dimensions, imageVolume.dimensions) ||
164
+ !csUtils.isEqual(volume.direction, imageVolume.direction)
165
+ ) {
166
+ throw new Error(
167
+ 'Only source data the same dimensions/size/orientation as the segmentation currently supported.'
168
+ );
169
+ }
170
+
171
+ fillCircle(enabledElement, operationData, true);
172
+ }
173
+
174
+ /**
175
+ * Fill outside the circular region segment inside the segmentation defined by the operationData.
176
+ * It fills the segmentation pixels outside the defined circle.
177
+ * @param enabledElement - The element for which the segment is being erased.
178
+ * @param operationData - EraseOperationData
179
+ */
180
+ export function fillOutsideCircle(
181
+ enabledElement: Types.IEnabledElement,
182
+ operationData: OperationData
183
+ ): void {
184
+ throw new Error('Not yet implemented');
185
+ }