@cornerstonejs/tools 1.33.0 → 1.35.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 (338) hide show
  1. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDown.js +4 -4
  2. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDown.js.map +1 -1
  3. package/dist/cjs/eventDispatchers/shared/getToolsWithActionsForMouseEvent.js +3 -2
  4. package/dist/cjs/eventDispatchers/shared/getToolsWithActionsForMouseEvent.js.map +1 -1
  5. package/dist/cjs/index.d.ts +2 -2
  6. package/dist/cjs/index.js +3 -2
  7. package/dist/cjs/index.js.map +1 -1
  8. package/dist/cjs/store/SynchronizerManager/Synchronizer.d.ts +1 -0
  9. package/dist/cjs/store/SynchronizerManager/Synchronizer.js +17 -1
  10. package/dist/cjs/store/SynchronizerManager/Synchronizer.js.map +1 -1
  11. package/dist/cjs/synchronizers/callbacks/areViewportsCoplanar .d.ts +1 -1
  12. package/dist/cjs/synchronizers/callbacks/areViewportsCoplanar .js.map +1 -1
  13. package/dist/cjs/synchronizers/callbacks/{stackImageSyncCallback.d.ts → imageSliceSyncCallback.d.ts} +1 -1
  14. package/dist/cjs/synchronizers/callbacks/{stackImageSyncCallback.js → imageSliceSyncCallback.js} +8 -4
  15. package/dist/cjs/synchronizers/callbacks/{stackImageSyncCallback.js.map → imageSliceSyncCallback.js.map} +1 -1
  16. package/dist/cjs/synchronizers/index.d.ts +3 -2
  17. package/dist/cjs/synchronizers/index.js +5 -3
  18. package/dist/cjs/synchronizers/index.js.map +1 -1
  19. package/dist/cjs/synchronizers/synchronizers/{createStackImageSynchronizer.d.ts → createImageSliceSynchronizer.d.ts} +1 -1
  20. package/dist/cjs/synchronizers/synchronizers/createImageSliceSynchronizer.js +17 -0
  21. package/dist/cjs/synchronizers/synchronizers/createImageSliceSynchronizer.js.map +1 -0
  22. package/dist/cjs/synchronizers/synchronizers/index.d.ts +3 -2
  23. package/dist/cjs/synchronizers/synchronizers/index.js +5 -3
  24. package/dist/cjs/synchronizers/synchronizers/index.js.map +1 -1
  25. package/dist/cjs/tools/AdvancedMagnifyTool.d.ts +4 -0
  26. package/dist/cjs/tools/AdvancedMagnifyTool.js +8 -3
  27. package/dist/cjs/tools/AdvancedMagnifyTool.js.map +1 -1
  28. package/dist/cjs/tools/annotation/SplineROITool.d.ts +59 -0
  29. package/dist/cjs/tools/annotation/SplineROITool.js +709 -0
  30. package/dist/cjs/tools/annotation/SplineROITool.js.map +1 -0
  31. package/dist/cjs/tools/annotation/splines/BSpline.d.ts +5 -0
  32. package/dist/cjs/tools/annotation/splines/BSpline.js +14 -0
  33. package/dist/cjs/tools/annotation/splines/BSpline.js.map +1 -0
  34. package/dist/cjs/tools/annotation/splines/CardinalSpline.d.ts +12 -0
  35. package/dist/cjs/tools/annotation/splines/CardinalSpline.js +38 -0
  36. package/dist/cjs/tools/annotation/splines/CardinalSpline.js.map +1 -0
  37. package/dist/cjs/tools/annotation/splines/CatmullRomSpline.d.ts +5 -0
  38. package/dist/cjs/tools/annotation/splines/CatmullRomSpline.js +12 -0
  39. package/dist/cjs/tools/annotation/splines/CatmullRomSpline.js.map +1 -0
  40. package/dist/cjs/tools/annotation/splines/CubicSpline.d.ts +13 -0
  41. package/dist/cjs/tools/annotation/splines/CubicSpline.js +192 -0
  42. package/dist/cjs/tools/annotation/splines/CubicSpline.js.map +1 -0
  43. package/dist/cjs/tools/annotation/splines/LinearSpline.d.ts +5 -0
  44. package/dist/cjs/tools/annotation/splines/LinearSpline.js +12 -0
  45. package/dist/cjs/tools/annotation/splines/LinearSpline.js.map +1 -0
  46. package/dist/cjs/tools/annotation/splines/QuadraticBezier.d.ts +6 -0
  47. package/dist/cjs/tools/annotation/splines/QuadraticBezier.js +20 -0
  48. package/dist/cjs/tools/annotation/splines/QuadraticBezier.js.map +1 -0
  49. package/dist/cjs/tools/annotation/splines/QuadraticSpline.d.ts +9 -0
  50. package/dist/cjs/tools/annotation/splines/QuadraticSpline.js +18 -0
  51. package/dist/cjs/tools/annotation/splines/QuadraticSpline.js.map +1 -0
  52. package/dist/cjs/tools/annotation/splines/Spline.d.ts +49 -0
  53. package/dist/cjs/tools/annotation/splines/Spline.js +420 -0
  54. package/dist/cjs/tools/annotation/splines/Spline.js.map +1 -0
  55. package/dist/cjs/tools/index.d.ts +2 -1
  56. package/dist/cjs/tools/index.js +3 -1
  57. package/dist/cjs/tools/index.js.map +1 -1
  58. package/dist/cjs/types/CardinalSplineProps.d.ts +5 -0
  59. package/dist/cjs/types/CardinalSplineProps.js +3 -0
  60. package/dist/cjs/types/CardinalSplineProps.js.map +1 -0
  61. package/dist/cjs/types/ClosestControlPoint.d.ts +4 -0
  62. package/dist/cjs/types/ClosestControlPoint.js +3 -0
  63. package/dist/cjs/types/ClosestControlPoint.js.map +1 -0
  64. package/dist/cjs/types/ClosestPoint.d.ts +5 -0
  65. package/dist/cjs/types/ClosestPoint.js +3 -0
  66. package/dist/cjs/types/ClosestPoint.js.map +1 -0
  67. package/dist/cjs/types/ClosestSplinePoint.d.ts +4 -0
  68. package/dist/cjs/types/ClosestSplinePoint.js +3 -0
  69. package/dist/cjs/types/ClosestSplinePoint.js.map +1 -0
  70. package/dist/cjs/types/ControlPointInfo.d.ts +5 -0
  71. package/dist/cjs/types/ControlPointInfo.js +3 -0
  72. package/dist/cjs/types/ControlPointInfo.js.map +1 -0
  73. package/dist/cjs/types/ISpline.d.ts +29 -0
  74. package/dist/cjs/types/ISpline.js +3 -0
  75. package/dist/cjs/types/ISpline.js.map +1 -0
  76. package/dist/cjs/types/SplineCurveSegment.d.ts +14 -0
  77. package/dist/cjs/types/SplineCurveSegment.js +3 -0
  78. package/dist/cjs/types/SplineCurveSegment.js.map +1 -0
  79. package/dist/cjs/types/SplineLineSegment.d.ts +10 -0
  80. package/dist/cjs/types/SplineLineSegment.js +3 -0
  81. package/dist/cjs/types/SplineLineSegment.js.map +1 -0
  82. package/dist/cjs/types/SplineProps.d.ts +4 -0
  83. package/dist/cjs/types/SplineProps.js +3 -0
  84. package/dist/cjs/types/SplineProps.js.map +1 -0
  85. package/dist/cjs/types/ToolSpecificAnnotationTypes.d.ts +34 -0
  86. package/dist/cjs/types/index.d.ts +10 -1
  87. package/dist/cjs/utilities/index.d.ts +2 -3
  88. package/dist/cjs/utilities/index.js +5 -5
  89. package/dist/cjs/utilities/index.js.map +1 -1
  90. package/dist/cjs/utilities/math/aabb/distanceToPoint.d.ts +2 -0
  91. package/dist/cjs/utilities/math/aabb/distanceToPoint.js +11 -0
  92. package/dist/cjs/utilities/math/aabb/distanceToPoint.js.map +1 -0
  93. package/dist/cjs/utilities/math/aabb/distanceToPointSquared.d.ts +2 -0
  94. package/dist/cjs/utilities/math/aabb/distanceToPointSquared.js +24 -0
  95. package/dist/cjs/utilities/math/aabb/distanceToPointSquared.js.map +1 -0
  96. package/dist/cjs/utilities/math/aabb/index.d.ts +2 -0
  97. package/dist/cjs/utilities/math/aabb/index.js +11 -0
  98. package/dist/cjs/utilities/math/aabb/index.js.map +1 -0
  99. package/dist/cjs/utilities/math/index.d.ts +6 -5
  100. package/dist/cjs/utilities/math/index.js +11 -9
  101. package/dist/cjs/utilities/math/index.js.map +1 -1
  102. package/dist/cjs/utilities/math/line/distanceToPointSquared.js +5 -21
  103. package/dist/cjs/utilities/math/line/distanceToPointSquared.js.map +1 -1
  104. package/dist/cjs/utilities/math/line/distanceToPointSquaredInfo.d.ts +5 -0
  105. package/dist/cjs/utilities/math/line/distanceToPointSquaredInfo.js +56 -0
  106. package/dist/cjs/utilities/math/line/distanceToPointSquaredInfo.js.map +1 -0
  107. package/dist/cjs/utilities/math/line/index.d.ts +2 -1
  108. package/dist/cjs/utilities/math/line/index.js +3 -1
  109. package/dist/cjs/utilities/math/line/index.js.map +1 -1
  110. package/dist/cjs/utilities/math/point/distanceToPoint.js +5 -6
  111. package/dist/cjs/utilities/math/point/distanceToPoint.js.map +1 -1
  112. package/dist/cjs/utilities/math/point/distanceToPointSquared.d.ts +4 -0
  113. package/dist/cjs/utilities/math/point/distanceToPointSquared.js +12 -0
  114. package/dist/cjs/utilities/math/point/distanceToPointSquared.js.map +1 -0
  115. package/dist/cjs/utilities/math/point/index.d.ts +3 -2
  116. package/dist/cjs/utilities/math/point/index.js +7 -3
  117. package/dist/cjs/utilities/math/point/index.js.map +1 -1
  118. package/dist/cjs/utilities/math/point/mirror.d.ts +2 -0
  119. package/dist/cjs/utilities/math/point/mirror.js +11 -0
  120. package/dist/cjs/utilities/math/point/mirror.js.map +1 -0
  121. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDown.js +4 -4
  122. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDown.js.map +1 -1
  123. package/dist/esm/eventDispatchers/shared/getToolsWithActionsForMouseEvent.js +2 -1
  124. package/dist/esm/eventDispatchers/shared/getToolsWithActionsForMouseEvent.js.map +1 -1
  125. package/dist/esm/index.js +2 -2
  126. package/dist/esm/index.js.map +1 -1
  127. package/dist/esm/store/SynchronizerManager/Synchronizer.js +17 -1
  128. package/dist/esm/store/SynchronizerManager/Synchronizer.js.map +1 -1
  129. package/dist/esm/synchronizers/callbacks/areViewportsCoplanar .js.map +1 -1
  130. package/dist/esm/synchronizers/callbacks/{stackImageSyncCallback.js → imageSliceSyncCallback.js} +8 -4
  131. package/dist/esm/synchronizers/callbacks/imageSliceSyncCallback.js.map +1 -0
  132. package/dist/esm/synchronizers/index.js +3 -2
  133. package/dist/esm/synchronizers/index.js.map +1 -1
  134. package/dist/esm/synchronizers/synchronizers/createImageSliceSynchronizer.js +11 -0
  135. package/dist/esm/synchronizers/synchronizers/createImageSliceSynchronizer.js.map +1 -0
  136. package/dist/esm/synchronizers/synchronizers/index.js +3 -2
  137. package/dist/esm/synchronizers/synchronizers/index.js.map +1 -1
  138. package/dist/esm/tools/AdvancedMagnifyTool.js +8 -3
  139. package/dist/esm/tools/AdvancedMagnifyTool.js.map +1 -1
  140. package/dist/esm/tools/annotation/SplineROITool.js +703 -0
  141. package/dist/esm/tools/annotation/SplineROITool.js.map +1 -0
  142. package/dist/esm/tools/annotation/splines/BSpline.js +10 -0
  143. package/dist/esm/tools/annotation/splines/BSpline.js.map +1 -0
  144. package/dist/esm/tools/annotation/splines/CardinalSpline.js +33 -0
  145. package/dist/esm/tools/annotation/splines/CardinalSpline.js.map +1 -0
  146. package/dist/esm/tools/annotation/splines/CatmullRomSpline.js +8 -0
  147. package/dist/esm/tools/annotation/splines/CatmullRomSpline.js.map +1 -0
  148. package/dist/esm/tools/annotation/splines/CubicSpline.js +165 -0
  149. package/dist/esm/tools/annotation/splines/CubicSpline.js.map +1 -0
  150. package/dist/esm/tools/annotation/splines/LinearSpline.js +8 -0
  151. package/dist/esm/tools/annotation/splines/LinearSpline.js.map +1 -0
  152. package/dist/esm/tools/annotation/splines/QuadraticBezier.js +16 -0
  153. package/dist/esm/tools/annotation/splines/QuadraticBezier.js.map +1 -0
  154. package/dist/esm/tools/annotation/splines/QuadraticSpline.js +14 -0
  155. package/dist/esm/tools/annotation/splines/QuadraticSpline.js.map +1 -0
  156. package/dist/esm/tools/annotation/splines/Spline.js +392 -0
  157. package/dist/esm/tools/annotation/splines/Spline.js.map +1 -0
  158. package/dist/esm/tools/index.js +2 -1
  159. package/dist/esm/tools/index.js.map +1 -1
  160. package/dist/esm/types/CardinalSplineProps.js +2 -0
  161. package/dist/esm/types/CardinalSplineProps.js.map +1 -0
  162. package/dist/esm/types/ClosestControlPoint.js +2 -0
  163. package/dist/esm/types/ClosestControlPoint.js.map +1 -0
  164. package/dist/esm/types/ClosestPoint.js +2 -0
  165. package/dist/esm/types/ClosestPoint.js.map +1 -0
  166. package/dist/esm/types/ClosestSplinePoint.js +2 -0
  167. package/dist/esm/types/ClosestSplinePoint.js.map +1 -0
  168. package/dist/esm/types/ControlPointInfo.js +2 -0
  169. package/dist/esm/types/ControlPointInfo.js.map +1 -0
  170. package/dist/esm/types/ISpline.js +2 -0
  171. package/dist/esm/types/ISpline.js.map +1 -0
  172. package/dist/esm/types/SplineCurveSegment.js +2 -0
  173. package/dist/esm/types/SplineCurveSegment.js.map +1 -0
  174. package/dist/esm/types/SplineLineSegment.js +2 -0
  175. package/dist/esm/types/SplineLineSegment.js.map +1 -0
  176. package/dist/esm/types/SplineProps.js +2 -0
  177. package/dist/esm/types/SplineProps.js.map +1 -0
  178. package/dist/esm/utilities/index.js +2 -3
  179. package/dist/esm/utilities/index.js.map +1 -1
  180. package/dist/esm/utilities/math/aabb/distanceToPoint.js +5 -0
  181. package/dist/esm/utilities/math/aabb/distanceToPoint.js.map +1 -0
  182. package/dist/esm/utilities/math/aabb/distanceToPointSquared.js +21 -0
  183. package/dist/esm/utilities/math/aabb/distanceToPointSquared.js.map +1 -0
  184. package/dist/esm/utilities/math/aabb/index.js +3 -0
  185. package/dist/esm/utilities/math/aabb/index.js.map +1 -0
  186. package/dist/esm/utilities/math/index.js +6 -5
  187. package/dist/esm/utilities/math/index.js.map +1 -1
  188. package/dist/esm/utilities/math/line/distanceToPointSquared.js +2 -21
  189. package/dist/esm/utilities/math/line/distanceToPointSquared.js.map +1 -1
  190. package/dist/esm/utilities/math/line/distanceToPointSquaredInfo.js +30 -0
  191. package/dist/esm/utilities/math/line/distanceToPointSquaredInfo.js.map +1 -0
  192. package/dist/esm/utilities/math/line/index.js +2 -1
  193. package/dist/esm/utilities/math/line/index.js.map +1 -1
  194. package/dist/esm/utilities/math/point/distanceToPoint.js +2 -6
  195. package/dist/esm/utilities/math/point/distanceToPoint.js.map +1 -1
  196. package/dist/esm/utilities/math/point/distanceToPointSquared.js +9 -0
  197. package/dist/esm/utilities/math/point/distanceToPointSquared.js.map +1 -0
  198. package/dist/esm/utilities/math/point/index.js +3 -2
  199. package/dist/esm/utilities/math/point/index.js.map +1 -1
  200. package/dist/esm/utilities/math/point/mirror.js +8 -0
  201. package/dist/esm/utilities/math/point/mirror.js.map +1 -0
  202. package/dist/types/eventDispatchers/mouseEventHandlers/mouseDown.d.ts.map +1 -1
  203. package/dist/types/eventDispatchers/shared/getToolsWithActionsForMouseEvent.d.ts.map +1 -1
  204. package/dist/types/index.d.ts +2 -2
  205. package/dist/types/index.d.ts.map +1 -1
  206. package/dist/types/store/SynchronizerManager/Synchronizer.d.ts +1 -0
  207. package/dist/types/store/SynchronizerManager/Synchronizer.d.ts.map +1 -1
  208. package/dist/types/synchronizers/callbacks/areViewportsCoplanar .d.ts +1 -1
  209. package/dist/types/synchronizers/callbacks/areViewportsCoplanar .d.ts.map +1 -1
  210. package/dist/types/synchronizers/callbacks/{stackImageSyncCallback.d.ts → imageSliceSyncCallback.d.ts} +2 -2
  211. package/dist/types/synchronizers/callbacks/imageSliceSyncCallback.d.ts.map +1 -0
  212. package/dist/types/synchronizers/index.d.ts +3 -2
  213. package/dist/types/synchronizers/index.d.ts.map +1 -1
  214. package/dist/types/synchronizers/synchronizers/createImageSliceSynchronizer.d.ts +3 -0
  215. package/dist/types/synchronizers/synchronizers/createImageSliceSynchronizer.d.ts.map +1 -0
  216. package/dist/types/synchronizers/synchronizers/index.d.ts +3 -2
  217. package/dist/types/synchronizers/synchronizers/index.d.ts.map +1 -1
  218. package/dist/types/tools/AdvancedMagnifyTool.d.ts +4 -0
  219. package/dist/types/tools/AdvancedMagnifyTool.d.ts.map +1 -1
  220. package/dist/types/tools/annotation/SplineROITool.d.ts +60 -0
  221. package/dist/types/tools/annotation/SplineROITool.d.ts.map +1 -0
  222. package/dist/types/tools/annotation/splines/BSpline.d.ts +6 -0
  223. package/dist/types/tools/annotation/splines/BSpline.d.ts.map +1 -0
  224. package/dist/types/tools/annotation/splines/CardinalSpline.d.ts +13 -0
  225. package/dist/types/tools/annotation/splines/CardinalSpline.d.ts.map +1 -0
  226. package/dist/types/tools/annotation/splines/CatmullRomSpline.d.ts +6 -0
  227. package/dist/types/tools/annotation/splines/CatmullRomSpline.d.ts.map +1 -0
  228. package/dist/types/tools/annotation/splines/CubicSpline.d.ts +14 -0
  229. package/dist/types/tools/annotation/splines/CubicSpline.d.ts.map +1 -0
  230. package/dist/types/tools/annotation/splines/LinearSpline.d.ts +6 -0
  231. package/dist/types/tools/annotation/splines/LinearSpline.d.ts.map +1 -0
  232. package/dist/types/tools/annotation/splines/QuadraticBezier.d.ts +7 -0
  233. package/dist/types/tools/annotation/splines/QuadraticBezier.d.ts.map +1 -0
  234. package/dist/types/tools/annotation/splines/QuadraticSpline.d.ts +10 -0
  235. package/dist/types/tools/annotation/splines/QuadraticSpline.d.ts.map +1 -0
  236. package/dist/types/tools/annotation/splines/Spline.d.ts +50 -0
  237. package/dist/types/tools/annotation/splines/Spline.d.ts.map +1 -0
  238. package/dist/types/tools/index.d.ts +2 -1
  239. package/dist/types/tools/index.d.ts.map +1 -1
  240. package/dist/types/types/CardinalSplineProps.d.ts +6 -0
  241. package/dist/types/types/CardinalSplineProps.d.ts.map +1 -0
  242. package/dist/types/types/ClosestControlPoint.d.ts +5 -0
  243. package/dist/types/types/ClosestControlPoint.d.ts.map +1 -0
  244. package/dist/types/types/ClosestPoint.d.ts +6 -0
  245. package/dist/types/types/ClosestPoint.d.ts.map +1 -0
  246. package/dist/types/types/ClosestSplinePoint.d.ts +5 -0
  247. package/dist/types/types/ClosestSplinePoint.d.ts.map +1 -0
  248. package/dist/types/types/ControlPointInfo.d.ts +6 -0
  249. package/dist/types/types/ControlPointInfo.d.ts.map +1 -0
  250. package/dist/types/types/ISpline.d.ts +30 -0
  251. package/dist/types/types/ISpline.d.ts.map +1 -0
  252. package/dist/types/types/SplineCurveSegment.d.ts +15 -0
  253. package/dist/types/types/SplineCurveSegment.d.ts.map +1 -0
  254. package/dist/types/types/SplineLineSegment.d.ts +11 -0
  255. package/dist/types/types/SplineLineSegment.d.ts.map +1 -0
  256. package/dist/types/types/SplineProps.d.ts +5 -0
  257. package/dist/types/types/SplineProps.d.ts.map +1 -0
  258. package/dist/types/types/ToolSpecificAnnotationTypes.d.ts +34 -0
  259. package/dist/types/types/ToolSpecificAnnotationTypes.d.ts.map +1 -1
  260. package/dist/types/types/index.d.ts +10 -1
  261. package/dist/types/types/index.d.ts.map +1 -1
  262. package/dist/types/utilities/index.d.ts +2 -3
  263. package/dist/types/utilities/index.d.ts.map +1 -1
  264. package/dist/types/utilities/math/aabb/distanceToPoint.d.ts +3 -0
  265. package/dist/types/utilities/math/aabb/distanceToPoint.d.ts.map +1 -0
  266. package/dist/types/utilities/math/aabb/distanceToPointSquared.d.ts +3 -0
  267. package/dist/types/utilities/math/aabb/distanceToPointSquared.d.ts.map +1 -0
  268. package/dist/types/utilities/math/aabb/index.d.ts +3 -0
  269. package/dist/types/utilities/math/aabb/index.d.ts.map +1 -0
  270. package/dist/types/utilities/math/index.d.ts +6 -5
  271. package/dist/types/utilities/math/index.d.ts.map +1 -1
  272. package/dist/types/utilities/math/line/distanceToPointSquared.d.ts.map +1 -1
  273. package/dist/types/utilities/math/line/distanceToPointSquaredInfo.d.ts +6 -0
  274. package/dist/types/utilities/math/line/distanceToPointSquaredInfo.d.ts.map +1 -0
  275. package/dist/types/utilities/math/line/index.d.ts +2 -1
  276. package/dist/types/utilities/math/line/index.d.ts.map +1 -1
  277. package/dist/types/utilities/math/point/distanceToPoint.d.ts.map +1 -1
  278. package/dist/types/utilities/math/point/distanceToPointSquared.d.ts +5 -0
  279. package/dist/types/utilities/math/point/distanceToPointSquared.d.ts.map +1 -0
  280. package/dist/types/utilities/math/point/index.d.ts +3 -2
  281. package/dist/types/utilities/math/point/index.d.ts.map +1 -1
  282. package/dist/types/utilities/math/point/mirror.d.ts +3 -0
  283. package/dist/types/utilities/math/point/mirror.d.ts.map +1 -0
  284. package/dist/umd/index.js +2 -1
  285. package/dist/umd/index.js.LICENSE.txt +6 -0
  286. package/dist/umd/index.js.map +1 -1
  287. package/package.json +3 -3
  288. package/src/eventDispatchers/mouseEventHandlers/mouseDown.ts +8 -6
  289. package/src/eventDispatchers/shared/getToolsWithActionsForMouseEvent.ts +3 -2
  290. package/src/index.ts +2 -0
  291. package/src/store/SynchronizerManager/Synchronizer.ts +28 -3
  292. package/src/synchronizers/callbacks/areViewportsCoplanar .ts +2 -2
  293. package/src/synchronizers/callbacks/{stackImageSyncCallback.ts → imageSliceSyncCallback.ts} +16 -8
  294. package/src/synchronizers/index.ts +5 -1
  295. package/src/synchronizers/synchronizers/{createStackImageSynchronizer.ts → createImageSliceSynchronizer.ts} +8 -5
  296. package/src/synchronizers/synchronizers/index.ts +4 -1
  297. package/src/tools/AdvancedMagnifyTool.ts +8 -3
  298. package/src/tools/annotation/SplineROITool.ts +1151 -0
  299. package/src/tools/annotation/splines/BSpline.ts +22 -0
  300. package/src/tools/annotation/splines/CardinalSpline.ts +45 -0
  301. package/src/tools/annotation/splines/CatmullRomSpline.ts +19 -0
  302. package/src/tools/annotation/splines/CubicSpline.ts +288 -0
  303. package/src/tools/annotation/splines/LinearSpline.ts +20 -0
  304. package/src/tools/annotation/splines/QuadraticBezier.ts +20 -0
  305. package/src/tools/annotation/splines/QuadraticSpline.ts +25 -0
  306. package/src/tools/annotation/splines/Spline.ts +729 -0
  307. package/src/tools/index.ts +2 -0
  308. package/src/types/CardinalSplineProps.ts +11 -0
  309. package/src/types/ClosestControlPoint.ts +6 -0
  310. package/src/types/ClosestPoint.ts +8 -0
  311. package/src/types/ClosestSplinePoint.ts +6 -0
  312. package/src/types/ControlPointInfo.ts +8 -0
  313. package/src/types/ISpline.ts +164 -0
  314. package/src/types/SplineCurveSegment.ts +28 -0
  315. package/src/types/SplineLineSegment.ts +20 -0
  316. package/src/types/SplineProps.ts +15 -0
  317. package/src/types/ToolSpecificAnnotationTypes.ts +35 -0
  318. package/src/types/index.ts +21 -0
  319. package/src/utilities/index.ts +6 -2
  320. package/src/utilities/math/aabb/distanceToPoint.ts +20 -0
  321. package/src/utilities/math/aabb/distanceToPointSquared.ts +47 -0
  322. package/src/utilities/math/aabb/index.ts +2 -0
  323. package/src/utilities/math/index.ts +10 -8
  324. package/src/utilities/math/line/distanceToPointSquared.ts +3 -29
  325. package/src/utilities/math/line/distanceToPointSquaredInfo.ts +54 -0
  326. package/src/utilities/math/line/index.ts +7 -1
  327. package/src/utilities/math/point/distanceToPoint.ts +2 -10
  328. package/src/utilities/math/point/distanceToPointSquared.ts +21 -0
  329. package/src/utilities/math/point/index.ts +3 -3
  330. package/src/utilities/math/point/mirror.ts +21 -0
  331. package/dist/cjs/synchronizers/synchronizers/createStackImageSynchronizer.js +0 -15
  332. package/dist/cjs/synchronizers/synchronizers/createStackImageSynchronizer.js.map +0 -1
  333. package/dist/esm/synchronizers/callbacks/stackImageSyncCallback.js.map +0 -1
  334. package/dist/esm/synchronizers/synchronizers/createStackImageSynchronizer.js +0 -9
  335. package/dist/esm/synchronizers/synchronizers/createStackImageSynchronizer.js.map +0 -1
  336. package/dist/types/synchronizers/callbacks/stackImageSyncCallback.d.ts.map +0 -1
  337. package/dist/types/synchronizers/synchronizers/createStackImageSynchronizer.d.ts +0 -3
  338. package/dist/types/synchronizers/synchronizers/createStackImageSynchronizer.d.ts.map +0 -1
@@ -0,0 +1,703 @@
1
+ import { AnnotationTool } from '../base';
2
+ import { getEnabledElement, eventTarget, triggerEvent, } from '@cornerstonejs/core';
3
+ import { vec3 } from 'gl-matrix';
4
+ import { addAnnotation, getAnnotations, removeAnnotation, } from '../../stateManagement/annotation/annotationState';
5
+ import { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking';
6
+ import { isAnnotationVisible } from '../../stateManagement/annotation/annotationVisibility';
7
+ import { drawHandles as drawHandlesSvg, drawPolyline as drawPolylineSvg, drawLinkedTextBox as drawLinkedTextBoxSvg, } from '../../drawingSvg';
8
+ import { state } from '../../store';
9
+ import { Events, MouseBindings, KeyboardBindings } from '../../enums';
10
+ import { resetElementCursor } from '../../cursors/elementCursor';
11
+ import { math, viewportFilters, drawing, throttle, roundNumber, triggerAnnotationRenderForViewportIds, getCalibratedScale, getCalibratedAreaUnits, } from '../../utilities';
12
+ import { CardinalSpline } from './splines/CardinalSpline';
13
+ import { LinearSpline } from './splines/LinearSpline';
14
+ import { CatmullRomSpline } from './splines/CatmullRomSpline';
15
+ import { BSpline } from './splines/BSpline';
16
+ const { getViewportIdsWithToolToRender } = viewportFilters;
17
+ const { getTextBoxCoordsCanvas } = drawing;
18
+ const SPLINE_MIN_POINTS = 3;
19
+ const SPLINE_CLICK_CLOSE_CURVE_DIST = 10;
20
+ const DEFAULT_SPLINE_CONFIG = {
21
+ resolution: 20,
22
+ controlPointAdditionDistance: 6,
23
+ controlPointDeletionDistance: 6,
24
+ showControlPointsConnectors: false,
25
+ controlPointAdditionEnabled: true,
26
+ controlPointDeletionEnabled: true,
27
+ };
28
+ var SplineTypesEnum;
29
+ (function (SplineTypesEnum) {
30
+ SplineTypesEnum["Cardinal"] = "CARDINAL";
31
+ SplineTypesEnum["Linear"] = "LINEAR";
32
+ SplineTypesEnum["CatmullRom"] = "CATMULLROM";
33
+ SplineTypesEnum["BSpline"] = "BSPLINE";
34
+ })(SplineTypesEnum || (SplineTypesEnum = {}));
35
+ var SplineToolActions;
36
+ (function (SplineToolActions) {
37
+ SplineToolActions["AddControlPoint"] = "addControlPoint";
38
+ SplineToolActions["DeleteControlPoint"] = "deleteControlPoint";
39
+ })(SplineToolActions || (SplineToolActions = {}));
40
+ class SplineROITool extends AnnotationTool {
41
+ constructor(toolProps = {}, defaultToolProps = {
42
+ supportedInteractionTypes: ['Mouse', 'Touch'],
43
+ configuration: {
44
+ preventHandleOutsideImage: false,
45
+ calculateStats: true,
46
+ getTextLines: defaultGetTextLines,
47
+ spline: {
48
+ configuration: {
49
+ [SplineTypesEnum.Cardinal]: {
50
+ Class: CardinalSpline,
51
+ scale: 0.5,
52
+ },
53
+ [SplineTypesEnum.CatmullRom]: {
54
+ Class: CatmullRomSpline,
55
+ },
56
+ [SplineTypesEnum.Linear]: {
57
+ Class: LinearSpline,
58
+ },
59
+ [SplineTypesEnum.BSpline]: {
60
+ Class: BSpline,
61
+ controlPointAdditionEnabled: false,
62
+ controlPointDeletionEnabled: false,
63
+ showControlPointsConnectors: true,
64
+ },
65
+ },
66
+ type: SplineTypesEnum.CatmullRom,
67
+ drawPreviewEnabled: true,
68
+ lastControlPointDeletionKeys: ['Backspace', 'Delete'],
69
+ },
70
+ actions: {
71
+ [SplineToolActions.AddControlPoint]: {
72
+ method: 'addControlPointCallback',
73
+ bindings: [
74
+ {
75
+ mouseButton: MouseBindings.Primary,
76
+ modifierKey: KeyboardBindings.Shift,
77
+ },
78
+ ],
79
+ },
80
+ [SplineToolActions.DeleteControlPoint]: {
81
+ method: 'deleteControlPointCallback',
82
+ bindings: [
83
+ {
84
+ mouseButton: MouseBindings.Primary,
85
+ modifierKey: KeyboardBindings.Ctrl,
86
+ },
87
+ ],
88
+ },
89
+ },
90
+ },
91
+ }) {
92
+ super(toolProps, defaultToolProps);
93
+ this.isHandleOutsideImage = false;
94
+ this.addNewAnnotation = (evt) => {
95
+ const eventDetail = evt.detail;
96
+ const { currentPoints, element } = eventDetail;
97
+ const { world: worldPos, canvas: canvasPos } = currentPoints;
98
+ const enabledElement = getEnabledElement(element);
99
+ const { viewport, renderingEngine } = enabledElement;
100
+ this.isDrawing = true;
101
+ const camera = viewport.getCamera();
102
+ const { viewPlaneNormal, viewUp } = camera;
103
+ const { type: splineType } = this.configuration.spline;
104
+ const splineConfig = this._getSplineConfig(splineType);
105
+ const spline = new splineConfig.Class();
106
+ const referencedImageId = this.getReferencedImageId(viewport, worldPos, viewPlaneNormal, viewUp);
107
+ const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
108
+ const annotation = {
109
+ highlighted: true,
110
+ invalidated: true,
111
+ metadata: {
112
+ toolName: this.getToolName(),
113
+ viewPlaneNormal: [...viewPlaneNormal],
114
+ viewUp: [...viewUp],
115
+ FrameOfReferenceUID,
116
+ referencedImageId,
117
+ },
118
+ data: {
119
+ handles: {
120
+ textBox: {
121
+ hasMoved: false,
122
+ worldPosition: [0, 0, 0],
123
+ worldBoundingBox: {
124
+ topLeft: [0, 0, 0],
125
+ topRight: [0, 0, 0],
126
+ bottomLeft: [0, 0, 0],
127
+ bottomRight: [0, 0, 0],
128
+ },
129
+ },
130
+ points: [[...worldPos]],
131
+ activeHandleIndex: null,
132
+ },
133
+ spline: {
134
+ type: splineConfig.type,
135
+ instance: spline,
136
+ resolution: splineConfig.resolution,
137
+ closed: false,
138
+ polyline: [],
139
+ },
140
+ cachedStats: {},
141
+ },
142
+ };
143
+ addAnnotation(annotation, element);
144
+ const viewportIdsToRender = getViewportIdsWithToolToRender(element, this.getToolName());
145
+ this.editData = {
146
+ annotation,
147
+ viewportIdsToRender,
148
+ movingTextBox: false,
149
+ newAnnotation: true,
150
+ hasMoved: false,
151
+ lastCanvasPoint: canvasPos,
152
+ };
153
+ this._activateDraw(element);
154
+ evt.preventDefault();
155
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
156
+ return annotation;
157
+ };
158
+ this.isPointNearTool = (element, annotation, canvasCoords, proximity) => {
159
+ const { instance: spline } = annotation.data.spline;
160
+ return spline.isPointNearCurve(canvasCoords, proximity);
161
+ };
162
+ this.toolSelectedCallback = (evt, annotation) => {
163
+ const eventDetail = evt.detail;
164
+ const { element } = eventDetail;
165
+ annotation.highlighted = true;
166
+ const viewportIdsToRender = getViewportIdsWithToolToRender(element, this.getToolName());
167
+ this.editData = {
168
+ annotation,
169
+ viewportIdsToRender,
170
+ movingTextBox: false,
171
+ };
172
+ const enabledElement = getEnabledElement(element);
173
+ const { renderingEngine } = enabledElement;
174
+ this._activateModify(element);
175
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
176
+ evt.preventDefault();
177
+ };
178
+ this.handleSelectedCallback = (evt, annotation, handle) => {
179
+ const eventDetail = evt.detail;
180
+ const { element } = eventDetail;
181
+ const { data } = annotation;
182
+ annotation.highlighted = true;
183
+ let movingTextBox = false;
184
+ let handleIndex;
185
+ if (handle.worldPosition) {
186
+ movingTextBox = true;
187
+ }
188
+ else {
189
+ const { points } = data.handles;
190
+ handleIndex = points.findIndex((p) => p === handle);
191
+ }
192
+ const viewportIdsToRender = getViewportIdsWithToolToRender(element, this.getToolName());
193
+ this.editData = {
194
+ annotation,
195
+ viewportIdsToRender,
196
+ handleIndex,
197
+ movingTextBox,
198
+ };
199
+ this._activateModify(element);
200
+ const enabledElement = getEnabledElement(element);
201
+ const { renderingEngine } = enabledElement;
202
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
203
+ evt.preventDefault();
204
+ };
205
+ this._endCallback = (evt) => {
206
+ const eventDetail = evt.detail;
207
+ const { element } = eventDetail;
208
+ const { annotation, viewportIdsToRender, newAnnotation } = this.editData;
209
+ const { data } = annotation;
210
+ data.handles.activeHandleIndex = null;
211
+ this._deactivateModify(element);
212
+ this._deactivateDraw(element);
213
+ resetElementCursor(element);
214
+ const enabledElement = getEnabledElement(element);
215
+ const { renderingEngine } = enabledElement;
216
+ if (this.isHandleOutsideImage &&
217
+ this.configuration.preventHandleOutsideImage) {
218
+ removeAnnotation(annotation.annotationUID);
219
+ }
220
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
221
+ if (newAnnotation) {
222
+ const eventType = Events.ANNOTATION_COMPLETED;
223
+ const eventDetail = {
224
+ annotation,
225
+ };
226
+ triggerEvent(eventTarget, eventType, eventDetail);
227
+ }
228
+ this.editData = null;
229
+ this.isDrawing = false;
230
+ };
231
+ this._keyDownCallback = (evt) => {
232
+ const eventDetail = evt.detail;
233
+ const { element } = eventDetail;
234
+ const key = eventDetail.key ?? '';
235
+ const { lastControlPointDeletionKeys } = this.configuration.spline;
236
+ const deleteLastPoint = lastControlPointDeletionKeys.includes(key);
237
+ if (!deleteLastPoint) {
238
+ return;
239
+ }
240
+ const { annotation } = this.editData;
241
+ const { data } = annotation;
242
+ if (data.handles.points.length === SPLINE_MIN_POINTS) {
243
+ this.cancel(element);
244
+ return;
245
+ }
246
+ else {
247
+ const controlPointIndex = data.handles.points.length - 1;
248
+ this._deleteControlPointByIndex(element, annotation, controlPointIndex);
249
+ }
250
+ evt.preventDefault();
251
+ };
252
+ this._mouseMoveCallback = (evt) => {
253
+ const { drawPreviewEnabled } = this.configuration.spline;
254
+ if (!drawPreviewEnabled) {
255
+ return;
256
+ }
257
+ const { element } = evt.detail;
258
+ const { renderingEngine } = getEnabledElement(element);
259
+ const viewportIdsToRender = getViewportIdsWithToolToRender(element, this.getToolName());
260
+ this.editData.lastCanvasPoint = evt.detail.currentPoints.canvas;
261
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
262
+ evt.preventDefault();
263
+ };
264
+ this._mouseDownCallback = (evt) => {
265
+ const doubleClick = evt.type === Events.MOUSE_DOUBLE_CLICK;
266
+ const { annotation, viewportIdsToRender } = this.editData;
267
+ const { data } = annotation;
268
+ if (data.spline.closed) {
269
+ return;
270
+ }
271
+ const eventDetail = evt.detail;
272
+ const { element } = eventDetail;
273
+ const { currentPoints } = eventDetail;
274
+ const { canvas: canvasPoint, world: worldPoint } = currentPoints;
275
+ const enabledElement = getEnabledElement(element);
276
+ const { renderingEngine } = enabledElement;
277
+ let closeSpline = data.handles.points.length >= 2 && doubleClick;
278
+ let addNewPoint = true;
279
+ if (data.handles.points.length >= 3) {
280
+ const { instance: spline } = data.spline;
281
+ const closestControlPoint = spline.getClosestControlPointWithinDistance(canvasPoint, SPLINE_CLICK_CLOSE_CURVE_DIST);
282
+ if (closestControlPoint?.index === 0) {
283
+ addNewPoint = false;
284
+ closeSpline = true;
285
+ }
286
+ }
287
+ if (addNewPoint) {
288
+ data.handles.points.push(worldPoint);
289
+ }
290
+ data.spline.closed = data.spline.closed || closeSpline;
291
+ annotation.invalidated = true;
292
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
293
+ if (data.spline.closed) {
294
+ this._endCallback(evt);
295
+ }
296
+ evt.preventDefault();
297
+ };
298
+ this._dragCallback = (evt) => {
299
+ this.isDrawing = true;
300
+ const eventDetail = evt.detail;
301
+ const { element } = eventDetail;
302
+ const { annotation, viewportIdsToRender, handleIndex, movingTextBox } = this.editData;
303
+ const { data } = annotation;
304
+ if (movingTextBox) {
305
+ const { deltaPoints } = eventDetail;
306
+ const worldPosDelta = deltaPoints.world;
307
+ const { textBox } = data.handles;
308
+ const { worldPosition } = textBox;
309
+ worldPosition[0] += worldPosDelta[0];
310
+ worldPosition[1] += worldPosDelta[1];
311
+ worldPosition[2] += worldPosDelta[2];
312
+ textBox.hasMoved = true;
313
+ }
314
+ else if (handleIndex === undefined) {
315
+ const { deltaPoints } = eventDetail;
316
+ const worldPosDelta = deltaPoints.world;
317
+ const points = data.handles.points;
318
+ points.forEach((point) => {
319
+ point[0] += worldPosDelta[0];
320
+ point[1] += worldPosDelta[1];
321
+ point[2] += worldPosDelta[2];
322
+ });
323
+ annotation.invalidated = true;
324
+ }
325
+ else {
326
+ const { currentPoints } = eventDetail;
327
+ const worldPos = currentPoints.world;
328
+ data.handles.points[handleIndex] = [...worldPos];
329
+ annotation.invalidated = true;
330
+ }
331
+ this.editData.hasMoved = true;
332
+ const enabledElement = getEnabledElement(element);
333
+ const { renderingEngine } = enabledElement;
334
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
335
+ };
336
+ this.cancel = (element) => {
337
+ if (!this.isDrawing) {
338
+ return;
339
+ }
340
+ this.isDrawing = false;
341
+ this._deactivateDraw(element);
342
+ this._deactivateModify(element);
343
+ resetElementCursor(element);
344
+ const { annotation, viewportIdsToRender, newAnnotation } = this.editData;
345
+ if (newAnnotation) {
346
+ removeAnnotation(annotation.annotationUID);
347
+ }
348
+ const enabledElement = getEnabledElement(element);
349
+ const { renderingEngine } = enabledElement;
350
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
351
+ this.editData = null;
352
+ return annotation.annotationUID;
353
+ };
354
+ this.triggerAnnotationModified = (annotation, enabledElement) => {
355
+ const { viewportId, renderingEngineId } = enabledElement;
356
+ const eventType = Events.ANNOTATION_MODIFIED;
357
+ const eventDetail = {
358
+ annotation,
359
+ viewportId,
360
+ renderingEngineId,
361
+ };
362
+ triggerEvent(eventTarget, eventType, eventDetail);
363
+ };
364
+ this._activateModify = (element) => {
365
+ state.isInteractingWithTool = true;
366
+ element.addEventListener(Events.MOUSE_UP, this._endCallback);
367
+ element.addEventListener(Events.MOUSE_DRAG, this._dragCallback);
368
+ element.addEventListener(Events.MOUSE_CLICK, this._endCallback);
369
+ element.addEventListener(Events.TOUCH_END, this._endCallback);
370
+ element.addEventListener(Events.TOUCH_DRAG, this._dragCallback);
371
+ element.addEventListener(Events.TOUCH_TAP, this._endCallback);
372
+ };
373
+ this._deactivateModify = (element) => {
374
+ state.isInteractingWithTool = false;
375
+ element.removeEventListener(Events.MOUSE_UP, this._endCallback);
376
+ element.removeEventListener(Events.MOUSE_DRAG, this._dragCallback);
377
+ element.removeEventListener(Events.MOUSE_CLICK, this._endCallback);
378
+ element.removeEventListener(Events.TOUCH_END, this._endCallback);
379
+ element.removeEventListener(Events.TOUCH_DRAG, this._dragCallback);
380
+ element.removeEventListener(Events.TOUCH_TAP, this._endCallback);
381
+ };
382
+ this._activateDraw = (element) => {
383
+ state.isInteractingWithTool = true;
384
+ element.addEventListener(Events.KEY_DOWN, this._keyDownCallback);
385
+ element.addEventListener(Events.MOUSE_MOVE, this._mouseMoveCallback);
386
+ element.addEventListener(Events.MOUSE_DOWN, this._mouseDownCallback);
387
+ element.addEventListener(Events.MOUSE_DOUBLE_CLICK, this._mouseDownCallback);
388
+ element.addEventListener(Events.TOUCH_TAP, this._mouseDownCallback);
389
+ };
390
+ this._deactivateDraw = (element) => {
391
+ state.isInteractingWithTool = false;
392
+ element.removeEventListener(Events.KEY_DOWN, this._keyDownCallback);
393
+ element.removeEventListener(Events.MOUSE_MOVE, this._mouseMoveCallback);
394
+ element.removeEventListener(Events.MOUSE_DOWN, this._mouseDownCallback);
395
+ element.removeEventListener(Events.MOUSE_DOUBLE_CLICK, this._mouseDownCallback);
396
+ element.removeEventListener(Events.TOUCH_TAP, this._mouseDownCallback);
397
+ };
398
+ this.renderAnnotation = (enabledElement, svgDrawingHelper) => {
399
+ let renderStatus = false;
400
+ const { viewport } = enabledElement;
401
+ const { worldToCanvas } = viewport;
402
+ const { element } = viewport;
403
+ if (!viewport.getRenderingEngine()) {
404
+ console.warn('Rendering Engine has been destroyed');
405
+ return renderStatus;
406
+ }
407
+ let annotations = getAnnotations(this.getToolName(), element);
408
+ if (!annotations?.length) {
409
+ return renderStatus;
410
+ }
411
+ annotations = this.filterInteractableAnnotationsForElement(element, annotations);
412
+ if (!annotations?.length) {
413
+ return renderStatus;
414
+ }
415
+ const targetId = this.getTargetId(viewport);
416
+ const newAnnotation = this.editData?.newAnnotation;
417
+ const styleSpecifier = {
418
+ toolGroupId: this.toolGroupId,
419
+ toolName: this.getToolName(),
420
+ viewportId: enabledElement.viewport.id,
421
+ };
422
+ for (let i = 0; i < annotations.length; i++) {
423
+ const annotation = annotations[i];
424
+ const { annotationUID, data, highlighted } = annotation;
425
+ const { handles } = data;
426
+ const { points: controlPoints, activeHandleIndex } = handles;
427
+ styleSpecifier.annotationUID = annotationUID;
428
+ const lineWidth = this.getStyle('lineWidth', styleSpecifier, annotation);
429
+ const lineDash = this.getStyle('lineDash', styleSpecifier, annotation);
430
+ const color = this.getStyle('color', styleSpecifier, annotation);
431
+ const canvasCoordinates = controlPoints.map((p) => worldToCanvas(p));
432
+ const { drawPreviewEnabled } = this.configuration.spline;
433
+ const splineType = annotation.data.spline.type;
434
+ const splineConfig = this._getSplineConfig(splineType);
435
+ const spline = this._updateSplineInstance(element, annotation);
436
+ const splinePolylineCanvas = spline.getPolylinePoints();
437
+ const splinePolylineWorld = [];
438
+ for (let i = 0, len = splinePolylineCanvas.length; i < len; i++) {
439
+ splinePolylineWorld.push(viewport.canvasToWorld(splinePolylineCanvas[i]));
440
+ }
441
+ data.spline.polyline = splinePolylineWorld;
442
+ if (!data.cachedStats[targetId] ||
443
+ data.cachedStats[targetId].areaUnit == null) {
444
+ data.cachedStats[targetId] = {
445
+ Modality: null,
446
+ area: null,
447
+ areaUnit: null,
448
+ };
449
+ this._calculateCachedStats(annotation, element);
450
+ }
451
+ else if (annotation.invalidated) {
452
+ this._throttledCalculateCachedStats(annotation, element);
453
+ }
454
+ let activeHandleCanvasCoords;
455
+ if (!isAnnotationVisible(annotationUID)) {
456
+ continue;
457
+ }
458
+ if (!isAnnotationLocked(annotation) &&
459
+ !this.editData &&
460
+ activeHandleIndex !== null) {
461
+ activeHandleCanvasCoords = [canvasCoordinates[activeHandleIndex]];
462
+ }
463
+ if (activeHandleCanvasCoords || newAnnotation || highlighted) {
464
+ const handleGroupUID = '0';
465
+ drawHandlesSvg(svgDrawingHelper, annotationUID, handleGroupUID, canvasCoordinates, {
466
+ color,
467
+ lineDash,
468
+ lineWidth,
469
+ handleRadius: '3',
470
+ });
471
+ }
472
+ if (drawPreviewEnabled &&
473
+ spline.numControlPoints > 1 &&
474
+ this.editData?.lastCanvasPoint &&
475
+ !spline.closed) {
476
+ const { lastCanvasPoint } = this.editData;
477
+ const previewPolylinePoints = spline.getPreviewPolylinePoints(lastCanvasPoint, SPLINE_CLICK_CLOSE_CURVE_DIST);
478
+ drawPolylineSvg(svgDrawingHelper, annotationUID, 'previewSplineChange', previewPolylinePoints, {
479
+ color: '#9EA0CA',
480
+ lineDash,
481
+ lineWidth,
482
+ });
483
+ }
484
+ if (splineConfig.showControlPointsConnectors) {
485
+ const controlPointsConnectors = [...canvasCoordinates];
486
+ if (spline.closed) {
487
+ controlPointsConnectors.push(canvasCoordinates[0]);
488
+ }
489
+ drawPolylineSvg(svgDrawingHelper, annotationUID, 'controlPointsConnectors', controlPointsConnectors, {
490
+ color: 'rgba(255, 255, 255, 0.5)',
491
+ lineDash,
492
+ lineWidth,
493
+ });
494
+ }
495
+ drawPolylineSvg(svgDrawingHelper, annotationUID, 'lineSegments', splinePolylineCanvas, {
496
+ color,
497
+ lineDash,
498
+ lineWidth,
499
+ });
500
+ this._renderStats(annotation, viewport, enabledElement, svgDrawingHelper);
501
+ renderStatus = true;
502
+ annotation.invalidated = false;
503
+ }
504
+ return renderStatus;
505
+ };
506
+ this._renderStats = (annotation, viewport, enabledElement, svgDrawingHelper) => {
507
+ const data = annotation.data;
508
+ const targetId = this.getTargetId(viewport);
509
+ if (!data.spline.closed) {
510
+ return;
511
+ }
512
+ const styleSpecifier = {
513
+ toolGroupId: this.toolGroupId,
514
+ toolName: this.getToolName(),
515
+ viewportId: enabledElement.viewport.id,
516
+ };
517
+ const options = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
518
+ if (!options.visibility) {
519
+ return;
520
+ }
521
+ const textLines = this.configuration.getTextLines(data, targetId);
522
+ if (!textLines || textLines.length === 0) {
523
+ return;
524
+ }
525
+ const canvasCoordinates = data.handles.points.map((p) => viewport.worldToCanvas(p));
526
+ if (!data.handles.textBox.hasMoved) {
527
+ const canvasTextBoxCoords = getTextBoxCoordsCanvas(canvasCoordinates);
528
+ data.handles.textBox.worldPosition =
529
+ viewport.canvasToWorld(canvasTextBoxCoords);
530
+ }
531
+ const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
532
+ const textBoxUID = 'textBox';
533
+ const boundingBox = drawLinkedTextBoxSvg(svgDrawingHelper, annotation.annotationUID ?? '', textBoxUID, textLines, textBoxPosition, canvasCoordinates, {}, options);
534
+ const { x: left, y: top, width, height } = boundingBox;
535
+ data.handles.textBox.worldBoundingBox = {
536
+ topLeft: viewport.canvasToWorld([left, top]),
537
+ topRight: viewport.canvasToWorld([left + width, top]),
538
+ bottomLeft: viewport.canvasToWorld([left, top + height]),
539
+ bottomRight: viewport.canvasToWorld([left + width, top + height]),
540
+ };
541
+ };
542
+ this.addControlPointCallback = (evt, annotation) => {
543
+ const { data } = annotation;
544
+ const splineType = data.spline.type;
545
+ const splineConfig = this._getSplineConfig(splineType);
546
+ const maxDist = splineConfig.controlPointAdditionDistance;
547
+ if (splineConfig.controlPointAdditionEnabled === false) {
548
+ return;
549
+ }
550
+ const eventDetail = evt.detail;
551
+ const { element } = eventDetail;
552
+ const enabledElement = getEnabledElement(element);
553
+ const { renderingEngine, viewport } = enabledElement;
554
+ const { canvasToWorld } = viewport;
555
+ const { instance: spline } = data.spline;
556
+ const canvasPos = evt.detail.currentPoints.canvas;
557
+ const closestPointInfo = spline.getClosestPoint(canvasPos);
558
+ if (closestPointInfo.distance > maxDist) {
559
+ return;
560
+ }
561
+ const { index, point: canvasPoint } = spline.addControlPointAtU(closestPointInfo.uValue);
562
+ data.handles.points.splice(index, 0, canvasToWorld(canvasPoint));
563
+ annotation.invalidated = true;
564
+ const viewportIdsToRender = getViewportIdsWithToolToRender(element, this.getToolName());
565
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
566
+ };
567
+ this.deleteControlPointCallback = (evt, annotation) => {
568
+ const splineType = annotation.data.spline.type;
569
+ const splineConfig = this._getSplineConfig(splineType);
570
+ const maxDist = splineConfig.controlPointDeletionDistance;
571
+ if (splineConfig.controlPointDeletionEnabled === false) {
572
+ return;
573
+ }
574
+ const eventDetail = evt.detail;
575
+ const { element, currentPoints } = eventDetail;
576
+ const { canvas: canvasPos } = currentPoints;
577
+ const { instance: spline } = annotation.data.spline;
578
+ const closestControlPoint = spline.getClosestControlPointWithinDistance(canvasPos, maxDist);
579
+ if (!closestControlPoint) {
580
+ return;
581
+ }
582
+ this._deleteControlPointByIndex(element, annotation, closestControlPoint.index);
583
+ };
584
+ this._calculateCachedStats = (annotation, element) => {
585
+ if (!this.configuration.calculateStats) {
586
+ return;
587
+ }
588
+ const data = annotation.data;
589
+ if (!data.spline.closed) {
590
+ return;
591
+ }
592
+ const enabledElement = getEnabledElement(element);
593
+ const { viewport, renderingEngine } = enabledElement;
594
+ const { cachedStats } = data;
595
+ const { polyline: points } = data.spline;
596
+ const targetIds = Object.keys(cachedStats);
597
+ for (let i = 0; i < targetIds.length; i++) {
598
+ const targetId = targetIds[i];
599
+ const image = this.getTargetIdImage(targetId, renderingEngine);
600
+ if (!image) {
601
+ continue;
602
+ }
603
+ const { metadata } = image;
604
+ const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p));
605
+ const canvasPoint = canvasCoordinates[0];
606
+ const originalWorldPoint = viewport.canvasToWorld(canvasPoint);
607
+ const deltaXPoint = viewport.canvasToWorld([
608
+ canvasPoint[0] + 1,
609
+ canvasPoint[1],
610
+ ]);
611
+ const deltaYPoint = viewport.canvasToWorld([
612
+ canvasPoint[0],
613
+ canvasPoint[1] + 1,
614
+ ]);
615
+ const deltaInX = vec3.distance(originalWorldPoint, deltaXPoint);
616
+ const deltaInY = vec3.distance(originalWorldPoint, deltaYPoint);
617
+ const scale = getCalibratedScale(image);
618
+ let area = math.polyline.calculateAreaOfPoints(canvasCoordinates) / scale / scale;
619
+ area *= deltaInX * deltaInY;
620
+ cachedStats[targetId] = {
621
+ Modality: metadata.Modality,
622
+ area,
623
+ areaUnit: getCalibratedAreaUnits(null, image),
624
+ };
625
+ }
626
+ this.triggerAnnotationModified(annotation, enabledElement);
627
+ return cachedStats;
628
+ };
629
+ this._throttledCalculateCachedStats = throttle(this._calculateCachedStats, 100, { trailing: true });
630
+ }
631
+ static { this.SplineTypes = SplineTypesEnum; }
632
+ static { this.Actions = SplineToolActions; }
633
+ _deleteControlPointByIndex(element, annotation, controlPointIndex) {
634
+ const enabledElement = getEnabledElement(element);
635
+ const { points: controlPoints } = annotation.data.handles;
636
+ if (controlPoints.length === 3) {
637
+ removeAnnotation(annotation.annotationUID);
638
+ }
639
+ else {
640
+ controlPoints.splice(controlPointIndex, 1);
641
+ }
642
+ const { renderingEngine } = enabledElement;
643
+ const viewportIdsToRender = getViewportIdsWithToolToRender(element, this.getToolName());
644
+ annotation.invalidated = true;
645
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
646
+ }
647
+ _getSplineConfig(type) {
648
+ const { configuration: config } = this;
649
+ const splineConfigs = config.spline.configuration;
650
+ return Object.assign({ type }, DEFAULT_SPLINE_CONFIG, splineConfigs[type]);
651
+ }
652
+ _updateSplineScale(spline, annotation) {
653
+ const splineType = annotation.data.spline.type;
654
+ const splineConfig = this._getSplineConfig(splineType);
655
+ if (!(spline instanceof CardinalSpline) ||
656
+ spline.fixedScale ||
657
+ splineConfig.scale === undefined ||
658
+ spline.scale === splineConfig.scale) {
659
+ return;
660
+ }
661
+ spline.scale = splineConfig.scale;
662
+ annotation.invalidated = true;
663
+ }
664
+ _updateSplineInstance(element, annotation) {
665
+ const enabledElement = getEnabledElement(element);
666
+ const { viewport } = enabledElement;
667
+ const { worldToCanvas } = viewport;
668
+ const { data } = annotation;
669
+ const { type: splineType, instance: spline } = annotation.data.spline;
670
+ const splineConfig = this._getSplineConfig(splineType);
671
+ const worldPoints = data.handles.points;
672
+ const canvasPoints = worldPoints.map(worldToCanvas);
673
+ spline.setControlPoints(canvasPoints);
674
+ spline.closed = !!data.spline?.closed;
675
+ if (spline.resolution !== splineConfig.resolution) {
676
+ spline.resolution = parseInt(splineConfig.resolution);
677
+ annotation.invalidated = true;
678
+ }
679
+ if (spline instanceof CardinalSpline &&
680
+ !spline.fixedScale &&
681
+ splineConfig.scale !== undefined &&
682
+ spline.scale !== splineConfig.scale) {
683
+ spline.scale = splineConfig.scale;
684
+ annotation.invalidated = true;
685
+ }
686
+ return spline;
687
+ }
688
+ }
689
+ function defaultGetTextLines(data, targetId) {
690
+ const cachedVolumeStats = data.cachedStats[targetId];
691
+ const { area, isEmptyArea, areaUnit } = cachedVolumeStats;
692
+ const textLines = [];
693
+ if (area) {
694
+ const areaLine = isEmptyArea
695
+ ? `Area: Oblique not supported`
696
+ : `Area: ${roundNumber(area)} ${areaUnit}`;
697
+ textLines.push(areaLine);
698
+ }
699
+ return textLines;
700
+ }
701
+ SplineROITool.toolName = 'SplineROI';
702
+ export default SplineROITool;
703
+ //# sourceMappingURL=SplineROITool.js.map