@cornerstonejs/tools 5.0.0-beta.1 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/dist/esm/config.d.ts +4 -0
  2. package/dist/esm/drawingSvg/drawPath.d.ts +3 -0
  3. package/dist/esm/drawingSvg/drawPath.js +4 -1
  4. package/dist/esm/eventListeners/keyboard/keyDownListener.js +2 -2
  5. package/dist/esm/eventListeners/mouse/getMouseEventPoints.d.ts +1 -1
  6. package/dist/esm/eventListeners/mouse/getMouseEventPoints.js +19 -1
  7. package/dist/esm/eventListeners/mouse/mouseDoubleClickListener.js +8 -1
  8. package/dist/esm/eventListeners/mouse/mouseDownListener.js +37 -5
  9. package/dist/esm/eventListeners/mouse/mouseMoveListener.js +3 -0
  10. package/dist/esm/eventListeners/segmentation/imageChangeEventListener.js +60 -92
  11. package/dist/esm/eventListeners/segmentation/labelmap/onLabelmapSegmentationDataModified.js +49 -21
  12. package/dist/esm/eventListeners/segmentation/labelmap/performStackLabelmapUpdate.js +7 -13
  13. package/dist/esm/eventListeners/segmentation/labelmap/performVolumeLabelmapUpdate.js +44 -18
  14. package/dist/esm/eventListeners/touch/getTouchEventPoints.js +27 -4
  15. package/dist/esm/eventListeners/touch/touchStartListener.js +27 -9
  16. package/dist/esm/eventListeners/wheel/wheelListener.js +5 -1
  17. package/dist/esm/index.d.ts +2 -2
  18. package/dist/esm/index.js +2 -2
  19. package/dist/esm/init.js +2 -0
  20. package/dist/esm/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.js +10 -4
  21. package/dist/esm/stateManagement/segmentation/SegmentationRenderingEngine.js +23 -20
  22. package/dist/esm/stateManagement/segmentation/SegmentationRepresentationDisplayRegistry.d.ts +12 -0
  23. package/dist/esm/stateManagement/segmentation/SegmentationRepresentationDisplayRegistry.js +7 -0
  24. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.d.ts +1 -10
  25. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.js +28 -149
  26. package/dist/esm/stateManagement/segmentation/addColorLUT.js +7 -1
  27. package/dist/esm/stateManagement/segmentation/getCurrentLabelmapImageIdForViewport.js +16 -1
  28. package/dist/esm/stateManagement/segmentation/helpers/clearSegmentValue.js +9 -7
  29. package/dist/esm/stateManagement/segmentation/helpers/getSegmentationActor.d.ts +1 -1
  30. package/dist/esm/stateManagement/segmentation/helpers/getSegmentationActor.js +3 -2
  31. package/dist/esm/stateManagement/segmentation/helpers/getViewportLabelmapRenderMode.d.ts +5 -0
  32. package/dist/esm/stateManagement/segmentation/helpers/getViewportLabelmapRenderMode.js +58 -0
  33. package/dist/esm/stateManagement/segmentation/helpers/labelmapImageMapperSupport.d.ts +52 -0
  34. package/dist/esm/stateManagement/segmentation/helpers/labelmapImageMapperSupport.js +246 -0
  35. package/dist/esm/stateManagement/segmentation/helpers/labelmapSegmentationState.d.ts +1 -0
  36. package/dist/esm/stateManagement/segmentation/helpers/labelmapSegmentationState.js +1 -0
  37. package/dist/esm/stateManagement/segmentation/helpers/normalizeSegmentationInput.js +12 -1
  38. package/dist/esm/stateManagement/segmentation/internalAddSegmentationRepresentation.js +3 -3
  39. package/dist/esm/stateManagement/segmentation/labelmapModel/index.d.ts +9 -0
  40. package/dist/esm/stateManagement/segmentation/labelmapModel/index.js +7 -0
  41. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapEditTransaction.d.ts +54 -0
  42. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapEditTransaction.js +224 -0
  43. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageIdMapping.d.ts +6 -0
  44. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageIdMapping.js +39 -0
  45. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageReferenceResolver.d.ts +23 -0
  46. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageReferenceResolver.js +269 -0
  47. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLayerStore.d.ts +15 -0
  48. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLayerStore.js +160 -0
  49. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLegacyAdapter.d.ts +4 -0
  50. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLegacyAdapter.js +42 -0
  51. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapSegmentBindings.d.ts +11 -0
  52. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapSegmentBindings.js +73 -0
  53. package/dist/esm/stateManagement/segmentation/labelmapModel/normalizeLabelmapSegmentationData.d.ts +17 -0
  54. package/dist/esm/stateManagement/segmentation/labelmapModel/normalizeLabelmapSegmentationData.js +75 -0
  55. package/dist/esm/stateManagement/segmentation/labelmapModel/privateLabelmap.d.ts +5 -0
  56. package/dist/esm/stateManagement/segmentation/labelmapModel/privateLabelmap.js +106 -0
  57. package/dist/esm/stateManagement/segmentation/models/SegmentModel.d.ts +11 -0
  58. package/dist/esm/stateManagement/segmentation/models/SegmentModel.js +19 -0
  59. package/dist/esm/stateManagement/segmentation/models/SegmentationModel.d.ts +12 -0
  60. package/dist/esm/stateManagement/segmentation/models/SegmentationModel.js +23 -0
  61. package/dist/esm/stateManagement/segmentation/removeSegmentationRepresentations.js +6 -10
  62. package/dist/esm/stateManagement/segmentation/segmentIndex.js +24 -0
  63. package/dist/esm/stateManagement/segmentation/segmentationEventManager.js +2 -9
  64. package/dist/esm/stateManagement/segmentation/segmentationState.d.ts +2 -1
  65. package/dist/esm/stateManagement/segmentation/segmentationState.js +4 -1
  66. package/dist/esm/store/SynchronizerManager/Synchronizer.d.ts +3 -1
  67. package/dist/esm/store/state.js +2 -1
  68. package/dist/esm/synchronizers/callbacks/imageSliceSyncCallback.js +12 -3
  69. package/dist/esm/synchronizers/callbacks/presentationViewSyncCallback.js +5 -2
  70. package/dist/esm/synchronizers/callbacks/zoomPanSyncCallback.js +51 -3
  71. package/dist/esm/synchronizers/synchronizers/createPresentationViewSynchronizer.d.ts +1 -1
  72. package/dist/esm/tools/AdvancedMagnifyTool.js +4 -1
  73. package/dist/esm/tools/CrosshairsTool.d.ts +4 -0
  74. package/dist/esm/tools/CrosshairsTool.js +95 -41
  75. package/dist/esm/tools/MagnifyTool.js +3 -1
  76. package/dist/esm/tools/OrientationControllerTool.d.ts +45 -0
  77. package/dist/esm/tools/OrientationControllerTool.js +454 -0
  78. package/dist/esm/tools/OrientationMarkerTool.js +4 -4
  79. package/dist/esm/tools/PanTool.js +26 -3
  80. package/dist/esm/tools/PlanarRotateTool.js +19 -4
  81. package/dist/esm/tools/ReferenceCursors.js +7 -1
  82. package/dist/esm/tools/SculptorTool/CircleSculptCursor.js +1 -1
  83. package/dist/esm/tools/TrackballRotateTool.js +3 -2
  84. package/dist/esm/tools/VolumeCroppingControlTool.d.ts +10 -35
  85. package/dist/esm/tools/VolumeCroppingControlTool.js +179 -699
  86. package/dist/esm/tools/VolumeCroppingTool.d.ts +34 -32
  87. package/dist/esm/tools/VolumeCroppingTool.js +813 -532
  88. package/dist/esm/tools/WindowLevelTool.d.ts +2 -1
  89. package/dist/esm/tools/WindowLevelTool.js +48 -4
  90. package/dist/esm/tools/ZoomTool.d.ts +8 -0
  91. package/dist/esm/tools/ZoomTool.js +92 -11
  92. package/dist/esm/tools/annotation/AngleTool.js +38 -32
  93. package/dist/esm/tools/annotation/ArrowAnnotateTool.js +30 -28
  94. package/dist/esm/tools/annotation/BidirectionalTool.js +51 -49
  95. package/dist/esm/tools/annotation/CircleROITool.d.ts +1 -0
  96. package/dist/esm/tools/annotation/CircleROITool.js +89 -51
  97. package/dist/esm/tools/annotation/CobbAngleTool.js +1 -1
  98. package/dist/esm/tools/annotation/DragProbeTool.js +1 -1
  99. package/dist/esm/tools/annotation/ETDRSGridTool.js +1 -1
  100. package/dist/esm/tools/annotation/EllipticalROITool.js +46 -39
  101. package/dist/esm/tools/annotation/HeightTool.js +1 -1
  102. package/dist/esm/tools/annotation/KeyImageTool.js +11 -11
  103. package/dist/esm/tools/annotation/LabelTool.js +37 -35
  104. package/dist/esm/tools/annotation/LengthTool.js +35 -33
  105. package/dist/esm/tools/annotation/LivewireContourSegmentationTool.js +6 -4
  106. package/dist/esm/tools/annotation/LivewireContourTool.js +4 -8
  107. package/dist/esm/tools/annotation/PlanarFreehandContourSegmentationTool.js +6 -4
  108. package/dist/esm/tools/annotation/PlanarFreehandROITool.js +3 -4
  109. package/dist/esm/tools/annotation/ProbeTool.js +66 -56
  110. package/dist/esm/tools/annotation/RectangleROITool.js +48 -37
  111. package/dist/esm/tools/annotation/RegionSegmentPlusTool.js +1 -1
  112. package/dist/esm/tools/annotation/RegionSegmentTool.js +1 -1
  113. package/dist/esm/tools/annotation/SplineContourSegmentationTool.js +1 -1
  114. package/dist/esm/tools/annotation/SplineROITool.js +60 -56
  115. package/dist/esm/tools/annotation/UltrasoundDirectionalTool.js +1 -1
  116. package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/UltrasoundPleuraBLineTool.js +57 -55
  117. package/dist/esm/tools/annotation/VideoRedactionTool.js +1 -1
  118. package/dist/esm/tools/base/AnnotationDisplayTool.js +9 -6
  119. package/dist/esm/tools/base/AnnotationTool.js +2 -1
  120. package/dist/esm/tools/base/BaseTool.js +16 -10
  121. package/dist/esm/tools/base/ContourSegmentationBaseTool.js +1 -1
  122. package/dist/esm/tools/base/GrowCutBaseTool.js +2 -2
  123. package/dist/esm/tools/displayTools/Labelmap/addLabelmapToElement.d.ts +2 -4
  124. package/dist/esm/tools/displayTools/Labelmap/addLabelmapToElement.js +15 -85
  125. package/dist/esm/tools/displayTools/Labelmap/labelmapActorStyle.d.ts +5 -0
  126. package/dist/esm/tools/displayTools/Labelmap/labelmapActorStyle.js +191 -0
  127. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.d.ts +4 -3
  128. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.js +48 -209
  129. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/createLabelmapRenderPlan.d.ts +3 -0
  130. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/createLabelmapRenderPlan.js +51 -0
  131. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/index.d.ts +4 -0
  132. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/index.js +3 -0
  133. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/legacyVolumePlan.d.ts +14 -0
  134. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/legacyVolumePlan.js +143 -0
  135. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/planarGenericVolumeLabelmap.d.ts +40 -0
  136. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/planarGenericVolumeLabelmap.js +79 -0
  137. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/removeLabelmapRepresentationFromViewport.d.ts +3 -0
  138. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/removeLabelmapRepresentationFromViewport.js +18 -0
  139. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/resolveLabelmapRenderPlan.d.ts +9 -0
  140. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/resolveLabelmapRenderPlan.js +56 -0
  141. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/stackImagePlan.d.ts +11 -0
  142. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/stackImagePlan.js +35 -0
  143. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/types.d.ts +48 -0
  144. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/types.js +0 -0
  145. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/volumeSliceImageMapperPlan.d.ts +13 -0
  146. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/volumeSliceImageMapperPlan.js +34 -0
  147. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan.d.ts +2 -0
  148. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan.js +1 -0
  149. package/dist/esm/tools/displayTools/Labelmap/labelmapRepresentationUID.d.ts +8 -0
  150. package/dist/esm/tools/displayTools/Labelmap/labelmapRepresentationUID.js +18 -0
  151. package/dist/esm/tools/displayTools/Labelmap/removeLabelmapFromElement.js +2 -2
  152. package/dist/esm/tools/displayTools/Labelmap/removeLabelmapRepresentationData.d.ts +3 -0
  153. package/dist/esm/tools/displayTools/Labelmap/removeLabelmapRepresentationData.js +16 -0
  154. package/dist/esm/tools/displayTools/Labelmap/syncStackLabelmapActors.d.ts +2 -0
  155. package/dist/esm/tools/displayTools/Labelmap/syncStackLabelmapActors.js +135 -0
  156. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapImageMapper.d.ts +16 -0
  157. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapImageMapper.js +267 -0
  158. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapSliceData.d.ts +27 -0
  159. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapSliceData.js +185 -0
  160. package/dist/esm/tools/displayTools/registerBuiltInSegmentationRepresentationDisplays.d.ts +1 -0
  161. package/dist/esm/tools/displayTools/registerBuiltInSegmentationRepresentationDisplays.js +16 -0
  162. package/dist/esm/tools/index.d.ts +2 -1
  163. package/dist/esm/tools/index.js +2 -1
  164. package/dist/esm/tools/segmentation/BrushTool.d.ts +9 -2
  165. package/dist/esm/tools/segmentation/BrushTool.js +123 -26
  166. package/dist/esm/tools/segmentation/CircleScissorsTool.js +19 -36
  167. package/dist/esm/tools/segmentation/LabelmapBaseTool.d.ts +2 -3
  168. package/dist/esm/tools/segmentation/LabelmapBaseTool.js +77 -46
  169. package/dist/esm/tools/segmentation/LabelmapEditWithContour.js +3 -3
  170. package/dist/esm/tools/segmentation/PaintFillTool.js +11 -4
  171. package/dist/esm/tools/segmentation/RectangleROIStartEndThresholdTool.d.ts +2 -0
  172. package/dist/esm/tools/segmentation/RectangleROIStartEndThresholdTool.js +16 -8
  173. package/dist/esm/tools/segmentation/RectangleScissorsTool.js +13 -6
  174. package/dist/esm/tools/segmentation/SegmentBidirectionalTool.js +63 -61
  175. package/dist/esm/tools/segmentation/SegmentSelectTool.js +4 -4
  176. package/dist/esm/tools/segmentation/SphereScissorsTool.js +11 -31
  177. package/dist/esm/tools/segmentation/strategies/BrushStrategy.d.ts +7 -0
  178. package/dist/esm/tools/segmentation/strategies/BrushStrategy.js +47 -24
  179. package/dist/esm/tools/segmentation/strategies/compositions/circularCursor.js +49 -21
  180. package/dist/esm/tools/segmentation/strategies/compositions/determineSegmentIndex.js +2 -2
  181. package/dist/esm/tools/segmentation/strategies/compositions/dynamicThreshold.js +5 -1
  182. package/dist/esm/tools/segmentation/strategies/compositions/islandRemovalComposition.js +2 -2
  183. package/dist/esm/tools/segmentation/strategies/compositions/preview.js +2 -2
  184. package/dist/esm/tools/segmentation/strategies/compositions/setValue.js +14 -6
  185. package/dist/esm/tools/segmentation/strategies/fillCircle.d.ts +3 -1
  186. package/dist/esm/tools/segmentation/strategies/fillCircle.js +38 -31
  187. package/dist/esm/tools/segmentation/strategies/fillSphere.js +11 -3
  188. package/dist/esm/tools/segmentation/strategies/utils/crossLayerErase.d.ts +4 -0
  189. package/dist/esm/tools/segmentation/strategies/utils/crossLayerErase.js +23 -0
  190. package/dist/esm/tools/segmentation/strategies/utils/getStrategyData.js +1 -1
  191. package/dist/esm/tools/segmentation/strategies/utils/handleUseSegmentCenterIndex.js +12 -11
  192. package/dist/esm/tools/segmentation/strategies/utils/labelmapOverlap.d.ts +4 -0
  193. package/dist/esm/tools/segmentation/strategies/utils/labelmapOverlap.js +41 -0
  194. package/dist/esm/tools/segmentation/strategies/utils/overwritePolicy.d.ts +3 -0
  195. package/dist/esm/tools/segmentation/strategies/utils/overwritePolicy.js +31 -0
  196. package/dist/esm/tools/segmentation/strategies/utils/segmentSeparation.d.ts +3 -0
  197. package/dist/esm/tools/segmentation/strategies/utils/segmentSeparation.js +38 -0
  198. package/dist/esm/tools/segmentation/utils/LazyBrushEditController.d.ts +19 -0
  199. package/dist/esm/tools/segmentation/utils/LazyBrushEditController.js +55 -0
  200. package/dist/esm/tools/segmentation/utils/lazyBrushPreview.d.ts +3 -0
  201. package/dist/esm/tools/segmentation/utils/lazyBrushPreview.js +34 -0
  202. package/dist/esm/tools/segmentation/utils/shouldUseLazyLabelmapEditing.d.ts +3 -0
  203. package/dist/esm/tools/segmentation/utils/shouldUseLazyLabelmapEditing.js +42 -0
  204. package/dist/esm/types/ISynchronizerEventHandler.d.ts +2 -1
  205. package/dist/esm/types/LabelmapToolOperationData.d.ts +5 -0
  206. package/dist/esm/types/LabelmapTypes.d.ts +29 -6
  207. package/dist/esm/types/SegmentationStateTypes.d.ts +6 -0
  208. package/dist/esm/utilities/calibrateImageSpacing.js +17 -2
  209. package/dist/esm/utilities/contours/AnnotationToPointData.js +1 -1
  210. package/dist/esm/utilities/draw3D/addLine3DBetweenPoints.d.ts +7 -0
  211. package/dist/esm/utilities/draw3D/addLine3DBetweenPoints.js +34 -0
  212. package/dist/esm/utilities/draw3D/calculateAdaptiveSphereRadius.d.ts +6 -0
  213. package/dist/esm/utilities/draw3D/calculateAdaptiveSphereRadius.js +7 -0
  214. package/dist/esm/utilities/draw3D/index.d.ts +2 -0
  215. package/dist/esm/utilities/draw3D/index.js +2 -0
  216. package/dist/esm/utilities/drawing/getTextBoxCoordsCanvas.js +22 -14
  217. package/dist/esm/utilities/getCenterAndRadiusInCanvas.d.ts +6 -0
  218. package/dist/esm/utilities/getCenterAndRadiusInCanvas.js +26 -0
  219. package/dist/esm/utilities/getEllipseWorldCoordinates.d.ts +2 -0
  220. package/dist/esm/utilities/getEllipseWorldCoordinates.js +26 -0
  221. package/dist/esm/utilities/getSphereBoundsInfo.js +5 -1
  222. package/dist/esm/utilities/getViewportICamera.d.ts +4 -0
  223. package/dist/esm/utilities/getViewportICamera.js +23 -0
  224. package/dist/esm/utilities/getViewportsForAnnotation.js +5 -1
  225. package/dist/esm/utilities/index.d.ts +2 -1
  226. package/dist/esm/utilities/index.js +2 -1
  227. package/dist/esm/utilities/interactionDragCoordinator.d.ts +5 -0
  228. package/dist/esm/utilities/interactionDragCoordinator.js +16 -0
  229. package/dist/esm/utilities/math/basic/BasicStatsCalculator.js +9 -7
  230. package/dist/esm/utilities/pointInSurroundingSphereCallback.js +8 -1
  231. package/dist/esm/utilities/segmentation/InterpolationManager/InterpolationManager.js +121 -118
  232. package/dist/esm/utilities/segmentation/SegmentStatsCalculator.js +5 -4
  233. package/dist/esm/utilities/segmentation/VolumetricCalculator.js +1 -1
  234. package/dist/esm/utilities/segmentation/createLabelmapVolumeForViewport.js +1 -1
  235. package/dist/esm/utilities/segmentation/getReferenceVolumeForSegmentation.js +1 -1
  236. package/dist/esm/utilities/segmentation/getReferenceVolumeForSegmentationVolume.js +11 -2
  237. package/dist/esm/utilities/segmentation/getSegmentIndexAtLabelmapBorder.js +36 -17
  238. package/dist/esm/utilities/segmentation/getSegmentIndexAtWorldPoint.js +42 -25
  239. package/dist/esm/utilities/segmentation/getUniqueSegmentIndices.js +3 -30
  240. package/dist/esm/utilities/segmentation/index.d.ts +2 -1
  241. package/dist/esm/utilities/segmentation/index.js +2 -1
  242. package/dist/esm/utilities/segmentation/utilsForWorker.js +6 -2
  243. package/dist/esm/utilities/segmentation/validateLabelmap.js +1 -1
  244. package/dist/esm/utilities/stackPrefetch/stackPrefetch.js +0 -1
  245. package/dist/esm/utilities/touch/index.js +3 -2
  246. package/dist/esm/utilities/viewportCapabilities.d.ts +16 -0
  247. package/dist/esm/utilities/viewportCapabilities.js +18 -0
  248. package/dist/esm/utilities/viewportFilters/filterViewportsWithParallelNormals.d.ts +1 -1
  249. package/dist/esm/utilities/viewportFilters/filterViewportsWithParallelNormals.js +12 -4
  250. package/dist/esm/utilities/viewportFilters/filterViewportsWithSameOrientation.d.ts +1 -1
  251. package/dist/esm/utilities/viewportFilters/filterViewportsWithSameOrientation.js +11 -4
  252. package/dist/esm/utilities/viewportFilters/getViewportIdsWithToolToRender.js +1 -1
  253. package/dist/esm/utilities/viewportPresentation.d.ts +3 -0
  254. package/dist/esm/utilities/viewportPresentation.js +26 -0
  255. package/dist/esm/utilities/volumeCropping/computePlanePlaneIntersection.d.ts +6 -0
  256. package/dist/esm/utilities/volumeCropping/computePlanePlaneIntersection.js +37 -0
  257. package/dist/esm/utilities/volumeCropping/constants.d.ts +31 -0
  258. package/dist/esm/utilities/volumeCropping/constants.js +31 -0
  259. package/dist/esm/utilities/volumeCropping/copyClippingPlanes.d.ts +2 -0
  260. package/dist/esm/utilities/volumeCropping/copyClippingPlanes.js +6 -0
  261. package/dist/esm/utilities/volumeCropping/extractVolumeDirectionVectors.d.ts +9 -0
  262. package/dist/esm/utilities/volumeCropping/extractVolumeDirectionVectors.js +9 -0
  263. package/dist/esm/utilities/volumeCropping/findLineBoundsIntersection.d.ts +5 -0
  264. package/dist/esm/utilities/volumeCropping/findLineBoundsIntersection.js +50 -0
  265. package/dist/esm/utilities/volumeCropping/getColorKeyForPlaneIndex.d.ts +1 -0
  266. package/dist/esm/utilities/volumeCropping/getColorKeyForPlaneIndex.js +13 -0
  267. package/dist/esm/utilities/volumeCropping/getOrientationFromNormal.d.ts +2 -0
  268. package/dist/esm/utilities/volumeCropping/getOrientationFromNormal.js +19 -0
  269. package/dist/esm/utilities/volumeCropping/index.d.ts +9 -0
  270. package/dist/esm/utilities/volumeCropping/index.js +9 -0
  271. package/dist/esm/utilities/volumeCropping/parseCornerKey.d.ts +8 -0
  272. package/dist/esm/utilities/volumeCropping/parseCornerKey.js +11 -0
  273. package/dist/esm/utilities/volumeCropping/types.d.ts +5 -0
  274. package/dist/esm/utilities/volumeCropping/types.js +0 -0
  275. package/dist/esm/utilities/vtkjs/AnnotatedRhombicuboctahedronActor/index.d.ts +31 -0
  276. package/dist/esm/utilities/vtkjs/AnnotatedRhombicuboctahedronActor/index.js +391 -0
  277. package/dist/esm/utilities/vtkjs/OrientationControllerWidget/index.d.ts +69 -0
  278. package/dist/esm/utilities/vtkjs/OrientationControllerWidget/index.js +804 -0
  279. package/dist/esm/utilities/vtkjs/RhombicuboctahedronSource/index.d.ts +7 -0
  280. package/dist/esm/utilities/vtkjs/RhombicuboctahedronSource/index.js +144 -0
  281. package/dist/esm/utilities/vtkjs/index.d.ts +3 -0
  282. package/dist/esm/utilities/vtkjs/index.js +3 -0
  283. package/dist/esm/version.d.ts +1 -1
  284. package/dist/esm/version.js +1 -1
  285. package/package.json +10 -9
@@ -1,10 +1,12 @@
1
- import { cache, getEnabledElement, utilities as csUtils, BaseVolumeViewport, } from '@cornerstonejs/core';
1
+ import { BaseVolumeViewport, cache, getEnabledElement, utilities as csUtils, } from '@cornerstonejs/core';
2
2
  import { BaseTool } from '../base';
3
3
  import { SegmentationRepresentations } from '../../enums';
4
4
  import { triggerSegmentationDataModified } from '../../stateManagement/segmentation/triggerSegmentationEvents';
5
5
  import { segmentLocking, activeSegmentation, segmentIndex as segmentIndexController, } from '../../stateManagement/segmentation';
6
6
  import floodFill from '../../utilities/segmentation/floodFill';
7
7
  import { getCurrentLabelmapImageIdForViewport, getSegmentation, } from '../../stateManagement/segmentation/segmentationState';
8
+ import getViewportLabelmapRenderMode from '../../stateManagement/segmentation/helpers/getViewportLabelmapRenderMode';
9
+ import { getOrCreateLabelmapVolume, resolveLabelmapForSegment, } from '../../stateManagement/segmentation/helpers/labelmapSegmentationState';
8
10
  const { transformWorldToIndex, isEqual } = csUtils;
9
11
  class PaintFillTool extends BaseTool {
10
12
  constructor(toolProps = {}, defaultToolProps = {
@@ -32,9 +34,14 @@ class PaintFillTool extends BaseTool {
32
34
  let index;
33
35
  let voxelManager;
34
36
  this.doneEditMemo();
35
- if (viewport instanceof BaseVolumeViewport) {
36
- const { volumeId } = representationData[SegmentationRepresentations.Labelmap];
37
- const segmentation = cache.getVolume(volumeId);
37
+ const viewportRenderMode = getViewportLabelmapRenderMode(viewport);
38
+ if (viewportRenderMode === 'volume' ||
39
+ viewport instanceof BaseVolumeViewport) {
40
+ const layer = resolveLabelmapForSegment(getSegmentation(segmentationId), segmentIndex);
41
+ const segmentation = layer ? getOrCreateLabelmapVolume(layer) : undefined;
42
+ if (!segmentation) {
43
+ return;
44
+ }
38
45
  ({ dimensions, direction } = segmentation);
39
46
  voxelManager = segmentation.voxelManager;
40
47
  index = transformWorldToIndex(segmentation.imageData, worldPos);
@@ -16,6 +16,8 @@ declare class RectangleROIStartEndThresholdTool extends RectangleROITool {
16
16
  isDrawing: boolean;
17
17
  isHandleOutsideImage: boolean;
18
18
  constructor(toolProps?: PublicToolProps, defaultToolProps?: ToolProps);
19
+ private _isCoordinateTuple;
20
+ private _resolveViewPlaneCoordinate;
19
21
  addNewAnnotation: (evt: EventTypes.InteractionEventType) => {
20
22
  highlighted: boolean;
21
23
  invalidated: boolean;
@@ -137,6 +137,7 @@ class RectangleROIStartEndThresholdTool extends RectangleROITool {
137
137
  }
138
138
  const targetId = this.getTargetId(enabledElement.viewport);
139
139
  const imageVolume = cache.getVolume(targetId.split(/volumeId:|\?/)[1]);
140
+ this._computeProjectionPoints(annotation, imageVolume);
140
141
  this._computePointsInsideVolume(annotation, targetId, imageVolume, enabledElement);
141
142
  triggerAnnotationRenderForViewportIds(viewportIdsToRender);
142
143
  if (newAnnotation) {
@@ -172,19 +173,16 @@ class RectangleROIStartEndThresholdTool extends RectangleROITool {
172
173
  const color = this.getStyle('color', styleSpecifier, annotation);
173
174
  const focalPoint = viewport.getCamera().focalPoint;
174
175
  const viewplaneNormal = viewport.getCamera().viewPlaneNormal;
175
- let startCoord = startCoordinate;
176
- let endCoord = endCoordinate;
177
- if (Array.isArray(startCoordinate)) {
178
- startCoord = this._getCoordinateForViewplaneNormal(startCoord, viewplaneNormal);
176
+ let startCoord = this._resolveViewPlaneCoordinate(startCoordinate, viewplaneNormal);
177
+ let endCoord = this._resolveViewPlaneCoordinate(endCoordinate, viewplaneNormal);
178
+ if (this._isCoordinateTuple(startCoordinate)) {
179
179
  const indexOfDirection = this._getIndexOfCoordinatesForViewplaneNormal(viewplaneNormal);
180
180
  data.handles.points.forEach((point) => {
181
181
  point[indexOfDirection] = startCoord;
182
182
  });
183
183
  data.startCoordinate = startCoord;
184
184
  }
185
- if (Array.isArray(endCoordinate)) {
186
- endCoord = this._getCoordinateForViewplaneNormal(endCoord, viewplaneNormal);
187
- data.endCoordinate = endCoord;
185
+ if (this._isCoordinateTuple(endCoordinate)) {
188
186
  data.endCoordinate = endCoord;
189
187
  }
190
188
  const roundedStartCoord = csUtils.roundToPrecision(startCoord);
@@ -264,11 +262,21 @@ class RectangleROIStartEndThresholdTool extends RectangleROITool {
264
262
  this._throttledCalculateCachedStats = debounce(this._calculateCachedStatsTool, this.configuration.throttleTimeout);
265
263
  }
266
264
  }
265
+ _isCoordinateTuple(value) {
266
+ return Array.isArray(value) || ArrayBuffer.isView(value);
267
+ }
268
+ _resolveViewPlaneCoordinate(coordinate, viewPlaneNormal) {
269
+ if (this._isCoordinateTuple(coordinate)) {
270
+ return this._getCoordinateForViewplaneNormal(coordinate, viewPlaneNormal);
271
+ }
272
+ return coordinate;
273
+ }
267
274
  _computeProjectionPoints(annotation, imageVolume) {
268
275
  const { data, metadata } = annotation;
269
276
  const { viewPlaneNormal, spacingInNormal } = metadata;
270
277
  const { imageData } = imageVolume;
271
- const { startCoordinate, endCoordinate } = data;
278
+ const startCoordinate = this._resolveViewPlaneCoordinate(data.startCoordinate, viewPlaneNormal);
279
+ const endCoordinate = this._resolveViewPlaneCoordinate(data.endCoordinate, viewPlaneNormal);
272
280
  const { points } = data.handles;
273
281
  const startIJK = transformWorldToIndex(imageData, points[0]);
274
282
  const endIJK = transformWorldToIndex(imageData, points[0]);
@@ -1,4 +1,4 @@
1
- import { BaseVolumeViewport, cache, getEnabledElement, } from '@cornerstonejs/core';
1
+ import { BaseVolumeViewport, getEnabledElement } from '@cornerstonejs/core';
2
2
  import { BaseTool } from '../base';
3
3
  import { fillInsideRectangle } from './strategies/fillRectangle';
4
4
  import { eraseInsideRectangle } from './strategies/eraseRectangle';
@@ -9,7 +9,9 @@ import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCur
9
9
  import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
10
10
  import { config as segmentationConfig, segmentLocking, segmentIndex as segmentIndexController, activeSegmentation, } from '../../stateManagement/segmentation';
11
11
  import { getCurrentLabelmapImageIdForViewport, getSegmentation, } from '../../stateManagement/segmentation/segmentationState';
12
+ import getViewportLabelmapRenderMode from '../../stateManagement/segmentation/helpers/getViewportLabelmapRenderMode';
12
13
  import LabelmapBaseTool from './LabelmapBaseTool';
14
+ import { getOrCreateLabelmapVolume, resolveLabelmapForSegment, } from '../../stateManagement/segmentation/helpers/labelmapSegmentationState';
13
15
  class RectangleScissorsTool extends LabelmapBaseTool {
14
16
  constructor(toolProps = {}, defaultToolProps = {
15
17
  supportedInteractionTypes: ['Mouse', 'Touch'],
@@ -84,13 +86,18 @@ class RectangleScissorsTool extends LabelmapBaseTool {
84
86
  referencedVolumeId: null,
85
87
  imageId: null,
86
88
  };
87
- if (viewport instanceof BaseVolumeViewport) {
88
- const { volumeId } = labelmapData;
89
- const segmentation = cache.getVolume(volumeId);
89
+ const viewportRenderMode = getViewportLabelmapRenderMode(viewport);
90
+ if (viewportRenderMode === 'volume' ||
91
+ viewport instanceof BaseVolumeViewport) {
92
+ const layer = resolveLabelmapForSegment(getSegmentation(segmentationId), segmentIndex);
93
+ const segmentation = layer ? getOrCreateLabelmapVolume(layer) : undefined;
94
+ if (!segmentation) {
95
+ return;
96
+ }
90
97
  this.editData = {
91
98
  ...this.editData,
92
- volumeId,
93
- referencedVolumeId: segmentation.referencedVolumeId,
99
+ volumeId: segmentation.volumeId,
100
+ referencedVolumeId: layer?.referencedVolumeId ?? segmentation.referencedVolumeId,
94
101
  };
95
102
  }
96
103
  else {
@@ -1,3 +1,4 @@
1
+ var _a;
1
2
  import { getEnabledElement, utilities as csUtils, getEnabledElementByViewportId, utilities, } from '@cornerstonejs/core';
2
3
  import { addAnnotation, getAllAnnotations, getAnnotations, removeAnnotation, } from '../../stateManagement/annotation/annotationState';
3
4
  import { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking';
@@ -9,7 +10,6 @@ import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnota
9
10
  import BidirectionalTool from '../annotation/BidirectionalTool';
10
11
  import { getSegmentIndexColor } from '../../stateManagement/segmentation/config/segmentationColor';
11
12
  class SegmentBidirectionalTool extends BidirectionalTool {
12
- static { this.toolName = 'SegmentBidirectional'; }
13
13
  constructor(toolProps = {}) {
14
14
  super(toolProps);
15
15
  this.renderAnnotation = (enabledElement, svgDrawingHelper) => {
@@ -173,68 +173,70 @@ class SegmentBidirectionalTool extends BidirectionalTool {
173
173
  triggerAnnotationRenderForViewportIds(viewportIdsToRender);
174
174
  return annotation;
175
175
  }
176
- static { this.hydrate = (viewportId, axis, options) => {
177
- const enabledElement = getEnabledElementByViewportId(viewportId);
178
- if (!enabledElement) {
179
- return;
180
- }
181
- const { viewport } = enabledElement;
182
- const existingAnnotations = getAllAnnotations();
183
- const toolAnnotations = existingAnnotations.filter((annotation) => annotation.metadata.toolName === 'SegmentBidirectional');
184
- const existingAnnotation = toolAnnotations.find((annotation) => {
185
- const { metadata } = annotation;
186
- if (metadata.segmentIndex === options?.segmentIndex &&
187
- metadata.segmentationId === options?.segmentationId) {
188
- return true;
189
- }
190
- return false;
191
- });
192
- if (existingAnnotation) {
193
- removeAnnotation(existingAnnotation.annotationUID);
176
+ }
177
+ _a = SegmentBidirectionalTool;
178
+ SegmentBidirectionalTool.toolName = 'SegmentBidirectional';
179
+ SegmentBidirectionalTool.hydrate = (viewportId, axis, options) => {
180
+ const enabledElement = getEnabledElementByViewportId(viewportId);
181
+ if (!enabledElement) {
182
+ return;
183
+ }
184
+ const { viewport } = enabledElement;
185
+ const existingAnnotations = getAllAnnotations();
186
+ const toolAnnotations = existingAnnotations.filter((annotation) => annotation.metadata.toolName === 'SegmentBidirectional');
187
+ const existingAnnotation = toolAnnotations.find((annotation) => {
188
+ const { metadata } = annotation;
189
+ if (metadata.segmentIndex === options?.segmentIndex &&
190
+ metadata.segmentationId === options?.segmentationId) {
191
+ return true;
194
192
  }
195
- const { FrameOfReferenceUID, referencedImageId, viewPlaneNormal, instance, } = this.hydrateBase(SegmentBidirectionalTool, enabledElement, axis[0], options);
196
- const [majorAxis, minorAxis] = axis;
197
- const [major0, major1] = majorAxis;
198
- const [minor0, minor1] = minorAxis;
199
- const points = [major0, major1, minor0, minor1];
200
- const { toolInstance, ...serializableOptions } = options || {};
201
- const annotation = {
202
- annotationUID: options?.annotationUID || utilities.uuidv4(),
203
- data: {
204
- handles: {
205
- points,
206
- activeHandleIndex: null,
207
- textBox: {
208
- hasMoved: false,
209
- worldPosition: [0, 0, 0],
210
- worldBoundingBox: {
211
- topLeft: [0, 0, 0],
212
- topRight: [0, 0, 0],
213
- bottomLeft: [0, 0, 0],
214
- bottomRight: [0, 0, 0],
215
- },
193
+ return false;
194
+ });
195
+ if (existingAnnotation) {
196
+ removeAnnotation(existingAnnotation.annotationUID);
197
+ }
198
+ const { FrameOfReferenceUID, referencedImageId, viewPlaneNormal, instance, } = _a.hydrateBase(_a, enabledElement, axis[0], options);
199
+ const [majorAxis, minorAxis] = axis;
200
+ const [major0, major1] = majorAxis;
201
+ const [minor0, minor1] = minorAxis;
202
+ const points = [major0, major1, minor0, minor1];
203
+ const { toolInstance, ...serializableOptions } = options || {};
204
+ const annotation = {
205
+ annotationUID: options?.annotationUID || utilities.uuidv4(),
206
+ data: {
207
+ handles: {
208
+ points,
209
+ activeHandleIndex: null,
210
+ textBox: {
211
+ hasMoved: false,
212
+ worldPosition: [0, 0, 0],
213
+ worldBoundingBox: {
214
+ topLeft: [0, 0, 0],
215
+ topRight: [0, 0, 0],
216
+ bottomLeft: [0, 0, 0],
217
+ bottomRight: [0, 0, 0],
216
218
  },
217
219
  },
218
- cachedStats: {},
219
220
  },
220
- highlighted: false,
221
- autoGenerated: false,
222
- invalidated: false,
223
- isLocked: false,
224
- isVisible: true,
225
- metadata: {
226
- segmentIndex: options?.segmentIndex,
227
- segmentationId: options?.segmentationId,
228
- toolName: instance.getToolName(),
229
- viewPlaneNormal,
230
- FrameOfReferenceUID,
231
- referencedImageId,
232
- ...serializableOptions,
233
- },
234
- };
235
- addAnnotation(annotation, viewport.element);
236
- triggerAnnotationRenderForViewportIds([viewport.id]);
237
- return annotation;
238
- }; }
239
- }
221
+ cachedStats: {},
222
+ },
223
+ highlighted: false,
224
+ autoGenerated: false,
225
+ invalidated: false,
226
+ isLocked: false,
227
+ isVisible: true,
228
+ metadata: {
229
+ segmentIndex: options?.segmentIndex,
230
+ segmentationId: options?.segmentationId,
231
+ toolName: instance.getToolName(),
232
+ viewPlaneNormal,
233
+ FrameOfReferenceUID,
234
+ referencedImageId,
235
+ ...serializableOptions,
236
+ },
237
+ };
238
+ addAnnotation(annotation, viewport.element);
239
+ triggerAnnotationRenderForViewportIds([viewport.id]);
240
+ return annotation;
241
+ };
240
242
  export default SegmentBidirectionalTool;
@@ -8,10 +8,6 @@ import { getHoveredContourSegmentationAnnotation, getSegmentIndexAtLabelmapBorde
8
8
  import { state } from '../../store/state';
9
9
  import { ToolModes } from '../../enums';
10
10
  class SegmentSelectTool extends BaseTool {
11
- static { this.SelectMode = {
12
- Inside: 'Inside',
13
- Border: 'Border',
14
- }; }
15
11
  constructor(toolProps = {}, defaultToolProps = {
16
12
  supportedInteractionTypes: ['Mouse', 'Touch'],
17
13
  configuration: {
@@ -98,5 +94,9 @@ class SegmentSelectTool extends BaseTool {
98
94
  triggerAnnotationRenderForViewportIds(viewportIds);
99
95
  }
100
96
  }
97
+ SegmentSelectTool.SelectMode = {
98
+ Inside: 'Inside',
99
+ Border: 'Border',
100
+ };
101
101
  SegmentSelectTool.toolName = 'SegmentSelectTool';
102
102
  export default SegmentSelectTool;
@@ -8,6 +8,9 @@ import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnota
8
8
  import { config as segmentationConfig, segmentLocking, segmentIndex as segmentIndexController, activeSegmentation, } from '../../stateManagement/segmentation';
9
9
  import { getSegmentation } from '../../stateManagement/segmentation/segmentationState';
10
10
  import LabelmapBaseTool from './LabelmapBaseTool';
11
+ import getViewportICamera from '../../utilities/getViewportICamera';
12
+ import getEllipseWorldCoordinates from '../../utilities/getEllipseWorldCoordinates';
13
+ import { getCenterAndRadiusInCanvas } from '../../utilities/getCenterAndRadiusInCanvas';
11
14
  class SphereScissorsTool extends LabelmapBaseTool {
12
15
  constructor(toolProps = {}, defaultToolProps = {
13
16
  supportedInteractionTypes: ['Mouse', 'Touch'],
@@ -33,8 +36,11 @@ class SphereScissorsTool extends LabelmapBaseTool {
33
36
  const enabledElement = getEnabledElement(element);
34
37
  const { viewport } = enabledElement;
35
38
  this.isDrawing = true;
36
- const camera = viewport.getCamera();
39
+ const camera = getViewportICamera(viewport);
37
40
  const { viewPlaneNormal, viewUp } = camera;
41
+ if (!viewPlaneNormal || !viewUp) {
42
+ throw new Error('Unable to resolve viewport view plane for scissors tool');
43
+ }
38
44
  const activeSegmentationRepresentation = activeSegmentation.getActiveSegmentation(viewport.id);
39
45
  if (!activeSegmentationRepresentation) {
40
46
  throw new Error('No active segmentation detected, create one before using scissors tool');
@@ -114,28 +120,9 @@ class SphereScissorsTool extends LabelmapBaseTool {
114
120
  const { canvasToWorld } = viewport;
115
121
  const { annotation, viewportIdsToRender, centerCanvas } = this.editData;
116
122
  const { data } = annotation;
117
- const dX = Math.abs(currentCanvasPoints[0] - centerCanvas[0]);
118
- const dY = Math.abs(currentCanvasPoints[1] - centerCanvas[1]);
119
- const radius = Math.sqrt(dX * dX + dY * dY);
120
- const bottomCanvas = [
121
- centerCanvas[0],
122
- centerCanvas[1] + radius,
123
- ];
124
- const topCanvas = [centerCanvas[0], centerCanvas[1] - radius];
125
- const leftCanvas = [
126
- centerCanvas[0] - radius,
127
- centerCanvas[1],
128
- ];
129
- const rightCanvas = [
130
- centerCanvas[0] + radius,
131
- centerCanvas[1],
132
- ];
133
- data.handles.points = [
134
- canvasToWorld(bottomCanvas),
135
- canvasToWorld(topCanvas),
136
- canvasToWorld(leftCanvas),
137
- canvasToWorld(rightCanvas),
138
- ];
123
+ const centerWorld = canvasToWorld(centerCanvas);
124
+ const currentWorld = canvasToWorld(currentCanvasPoints);
125
+ data.handles.points = getEllipseWorldCoordinates([centerWorld, currentWorld], viewport);
139
126
  annotation.invalidated = true;
140
127
  this.editData.hasMoved = true;
141
128
  triggerAnnotationRenderForViewportIds(viewportIdsToRender);
@@ -201,14 +188,7 @@ class SphereScissorsTool extends LabelmapBaseTool {
201
188
  const annotationUID = annotation.annotationUID;
202
189
  const data = annotation.data;
203
190
  const { points } = data.handles;
204
- const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p));
205
- const bottom = canvasCoordinates[0];
206
- const top = canvasCoordinates[1];
207
- const center = [
208
- Math.floor((bottom[0] + top[0]) / 2),
209
- Math.floor((bottom[1] + top[1]) / 2),
210
- ];
211
- const radius = Math.abs(bottom[1] - Math.floor((bottom[1] + top[1]) / 2));
191
+ const { center, radius } = getCenterAndRadiusInCanvas(points, viewport);
212
192
  const color = `rgb(${toolMetadata.segmentColor.slice(0, 3)})`;
213
193
  if (!viewport.getRenderingEngine()) {
214
194
  console.warn('Rendering Engine has been destroyed');
@@ -3,6 +3,7 @@ import { StrategyCallbacks } from '../../../enums';
3
3
  import type { LabelmapToolOperationDataAny } from '../../../types/LabelmapToolOperationData';
4
4
  import type vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
5
5
  import type { LabelmapMemo } from '../../../utilities/segmentation/createLabelmapMemo';
6
+ import type { LabelmapEditTransaction } from '../../../stateManagement/segmentation/helpers/labelmapSegmentationState';
6
7
  export type InitializedOperationData = LabelmapToolOperationDataAny & {
7
8
  operationName?: string;
8
9
  centerSegmentIndexInfo: {
@@ -48,6 +49,12 @@ export type InitializedOperationData = LabelmapToolOperationDataAny & {
48
49
  };
49
50
  memo?: LabelmapMemo;
50
51
  modified?: boolean;
52
+ previewOnHover?: boolean;
53
+ labelValue?: number;
54
+ labelmapId?: string;
55
+ overwriteSegmentIndices?: number[];
56
+ imageId?: string;
57
+ labelmapEditTransaction?: LabelmapEditTransaction;
51
58
  };
52
59
  export type StrategyFunction = (operationData: InitializedOperationData, ...args: any[]) => unknown;
53
60
  export type CompositionInstance = {
@@ -1,30 +1,10 @@
1
- import { utilities as csUtils } from '@cornerstonejs/core';
2
1
  import { triggerSegmentationDataModified } from '../../../stateManagement/segmentation/triggerSegmentationEvents';
3
2
  import compositions from './compositions';
4
3
  import { getStrategyData } from './utils/getStrategyData';
5
4
  import { StrategyCallbacks } from '../../../enums';
6
- export default class BrushStrategy {
7
- static { this.COMPOSITIONS = compositions; }
8
- static { this.childFunctions = {
9
- [StrategyCallbacks.OnInteractionStart]: addListMethod(StrategyCallbacks.OnInteractionStart, StrategyCallbacks.Initialize),
10
- [StrategyCallbacks.OnInteractionEnd]: addListMethod(StrategyCallbacks.OnInteractionEnd, StrategyCallbacks.Initialize),
11
- [StrategyCallbacks.Fill]: addListMethod(StrategyCallbacks.Fill),
12
- [StrategyCallbacks.Initialize]: addListMethod(StrategyCallbacks.Initialize),
13
- [StrategyCallbacks.CreateIsInThreshold]: addSingletonMethod(StrategyCallbacks.CreateIsInThreshold),
14
- [StrategyCallbacks.Interpolate]: addListMethod(StrategyCallbacks.Interpolate, StrategyCallbacks.Initialize),
15
- [StrategyCallbacks.AcceptPreview]: addListMethod(StrategyCallbacks.AcceptPreview, StrategyCallbacks.Initialize),
16
- [StrategyCallbacks.RejectPreview]: addListMethod(StrategyCallbacks.RejectPreview, StrategyCallbacks.Initialize),
17
- [StrategyCallbacks.INTERNAL_setValue]: addSingletonMethod(StrategyCallbacks.INTERNAL_setValue),
18
- [StrategyCallbacks.Preview]: addSingletonMethod(StrategyCallbacks.Preview, false),
19
- [StrategyCallbacks.ComputeInnerCircleRadius]: addListMethod(StrategyCallbacks.ComputeInnerCircleRadius),
20
- [StrategyCallbacks.EnsureSegmentationVolumeFor3DManipulation]: addListMethod(StrategyCallbacks.EnsureSegmentationVolumeFor3DManipulation),
21
- [StrategyCallbacks.EnsureImageVolumeFor3DManipulation]: addListMethod(StrategyCallbacks.EnsureImageVolumeFor3DManipulation),
22
- [StrategyCallbacks.AddPreview]: addListMethod(StrategyCallbacks.AddPreview),
23
- [StrategyCallbacks.GetStatistics]: addSingletonMethod(StrategyCallbacks.GetStatistics),
24
- [StrategyCallbacks.CalculateCursorGeometry]: addSingletonMethod(StrategyCallbacks.CalculateCursorGeometry, true),
25
- [StrategyCallbacks.RenderCursor]: addSingletonMethod(StrategyCallbacks.RenderCursor, true),
26
- compositions: null,
27
- }; }
5
+ import { eraseCrossLayerOverwrites, prepareOverlapOperationData, } from './utils/labelmapOverlap';
6
+ import { shouldUseLazyLabelmapEditing } from '../utils/shouldUseLazyLabelmapEditing';
7
+ class BrushStrategy {
28
8
  constructor(name, ...initializers) {
29
9
  this._initialize = [];
30
10
  this._fill = [];
@@ -34,9 +14,30 @@ export default class BrushStrategy {
34
14
  if (!initializedData) {
35
15
  return;
36
16
  }
17
+ const isLazyLabelmapEditing = shouldUseLazyLabelmapEditing(initializedData.viewport);
18
+ const shouldPrepareOverlap = !isLazyLabelmapEditing || !initializedData.previewOnHover;
19
+ const originalSegmentationVoxelManager = initializedData.segmentationVoxelManager;
20
+ const originalSegmentationImageData = initializedData.segmentationImageData;
21
+ if (shouldPrepareOverlap) {
22
+ prepareOverlapOperationData(initializedData);
23
+ }
24
+ if (initializedData.memo?.segmentationVoxelManager !==
25
+ initializedData.segmentationVoxelManager) {
26
+ initializedData.memo = initializedData.createMemo(initializedData.segmentationId, initializedData.segmentationVoxelManager);
27
+ }
28
+ if (initializedData.segmentationVoxelManager !==
29
+ originalSegmentationVoxelManager ||
30
+ initializedData.segmentationImageData !== originalSegmentationImageData) {
31
+ this._initialize.forEach((func) => func(initializedData));
32
+ }
37
33
  this._fill.forEach((func) => func(initializedData));
38
34
  const { segmentationVoxelManager, segmentIndex } = initializedData;
39
- triggerSegmentationDataModified(initializedData.segmentationId, segmentationVoxelManager.getArrayOfModifiedSlices(), segmentIndex);
35
+ const crossLayerModifiedSlices = eraseCrossLayerOverwrites(initializedData);
36
+ const modifiedSlices = new Set([
37
+ ...(segmentationVoxelManager.getArrayOfModifiedSlices() ?? []),
38
+ ...crossLayerModifiedSlices,
39
+ ]);
40
+ triggerSegmentationDataModified(initializedData.segmentationId, Array.from(modifiedSlices), segmentIndex);
40
41
  return initializedData;
41
42
  };
42
43
  this.onInteractionStart = (enabledElement, operationData) => {
@@ -116,6 +117,28 @@ export default class BrushStrategy {
116
117
  return initializedData;
117
118
  }
118
119
  }
120
+ BrushStrategy.COMPOSITIONS = compositions;
121
+ BrushStrategy.childFunctions = {
122
+ [StrategyCallbacks.OnInteractionStart]: addListMethod(StrategyCallbacks.OnInteractionStart, StrategyCallbacks.Initialize),
123
+ [StrategyCallbacks.OnInteractionEnd]: addListMethod(StrategyCallbacks.OnInteractionEnd, StrategyCallbacks.Initialize),
124
+ [StrategyCallbacks.Fill]: addListMethod(StrategyCallbacks.Fill),
125
+ [StrategyCallbacks.Initialize]: addListMethod(StrategyCallbacks.Initialize),
126
+ [StrategyCallbacks.CreateIsInThreshold]: addSingletonMethod(StrategyCallbacks.CreateIsInThreshold),
127
+ [StrategyCallbacks.Interpolate]: addListMethod(StrategyCallbacks.Interpolate, StrategyCallbacks.Initialize),
128
+ [StrategyCallbacks.AcceptPreview]: addListMethod(StrategyCallbacks.AcceptPreview, StrategyCallbacks.Initialize),
129
+ [StrategyCallbacks.RejectPreview]: addListMethod(StrategyCallbacks.RejectPreview, StrategyCallbacks.Initialize),
130
+ [StrategyCallbacks.INTERNAL_setValue]: addSingletonMethod(StrategyCallbacks.INTERNAL_setValue),
131
+ [StrategyCallbacks.Preview]: addSingletonMethod(StrategyCallbacks.Preview, false),
132
+ [StrategyCallbacks.ComputeInnerCircleRadius]: addListMethod(StrategyCallbacks.ComputeInnerCircleRadius),
133
+ [StrategyCallbacks.EnsureSegmentationVolumeFor3DManipulation]: addListMethod(StrategyCallbacks.EnsureSegmentationVolumeFor3DManipulation),
134
+ [StrategyCallbacks.EnsureImageVolumeFor3DManipulation]: addListMethod(StrategyCallbacks.EnsureImageVolumeFor3DManipulation),
135
+ [StrategyCallbacks.AddPreview]: addListMethod(StrategyCallbacks.AddPreview),
136
+ [StrategyCallbacks.GetStatistics]: addSingletonMethod(StrategyCallbacks.GetStatistics),
137
+ [StrategyCallbacks.CalculateCursorGeometry]: addSingletonMethod(StrategyCallbacks.CalculateCursorGeometry, true),
138
+ [StrategyCallbacks.RenderCursor]: addSingletonMethod(StrategyCallbacks.RenderCursor, true),
139
+ compositions: null,
140
+ };
141
+ export default BrushStrategy;
119
142
  function addListMethod(name, createInitialized) {
120
143
  const listName = `_${name}`;
121
144
  return (brushStrategy, func) => {
@@ -1,6 +1,7 @@
1
1
  import { vec3 } from 'gl-matrix';
2
2
  import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
3
- import { drawCircle as drawCircleSvg } from '../../../../drawingSvg';
3
+ import { drawCircle as drawCircleSvg, drawPath as drawPathSvg, } from '../../../../drawingSvg';
4
+ import getViewportICamera from '../../../../utilities/getViewportICamera';
4
5
  export default {
5
6
  [StrategyCallbacks.CalculateCursorGeometry]: function (enabledElement, operationData) {
6
7
  if (!operationData) {
@@ -8,8 +9,11 @@ export default {
8
9
  }
9
10
  const { configuration, activeStrategy, hoverData } = operationData;
10
11
  const { viewport } = enabledElement;
11
- const camera = viewport.getCamera();
12
+ const camera = getViewportICamera(viewport);
12
13
  const { brushSize } = configuration;
14
+ if (!camera.viewUp || !camera.viewPlaneNormal) {
15
+ return;
16
+ }
13
17
  const viewUp = vec3.fromValues(camera.viewUp[0], camera.viewUp[1], camera.viewUp[2]);
14
18
  const viewPlaneNormal = vec3.fromValues(camera.viewPlaneNormal[0], camera.viewPlaneNormal[1], camera.viewPlaneNormal[2]);
15
19
  const viewRight = vec3.create();
@@ -44,6 +48,7 @@ export default {
44
48
  leftCursorInWorld,
45
49
  rightCursorInWorld,
46
50
  ];
51
+ data.editPoints = [...data.handles.points];
47
52
  const strategy = configuration.strategies[activeStrategy];
48
53
  if (typeof strategy?.computeInnerCircleRadius === 'function') {
49
54
  strategy.computeInnerCircleRadius({
@@ -64,35 +69,58 @@ export default {
64
69
  if (!toolMetadata) {
65
70
  return;
66
71
  }
67
- const annotationUID = toolMetadata.brushCursorUID;
72
+ const annotationUID = toolMetadata.brushCursorUID || 'brushCursor';
68
73
  const data = brushCursor.data;
69
- const { points } = data.handles;
70
- const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p));
71
- const bottom = canvasCoordinates[0];
72
- const top = canvasCoordinates[1];
73
- const center = [
74
- Math.floor((bottom[0] + top[0]) / 2),
75
- Math.floor((bottom[1] + top[1]) / 2),
76
- ];
77
- const radius = Math.abs(bottom[1] - Math.floor((bottom[1] + top[1]) / 2));
78
74
  const color = `rgb(${toolMetadata.segmentColor?.slice(0, 3) || [0, 0, 0]})`;
79
75
  if (!viewport.getRenderingEngine()) {
80
76
  console.warn('Rendering Engine has been destroyed');
81
77
  return;
82
78
  }
83
- const circleUID = '0';
84
- drawCircleSvg(svgDrawingHelper, annotationUID, circleUID, center, radius, {
85
- color,
86
- lineDash: this.centerSegmentIndexInfo.segmentIndex === 0 ? [1, 2] : null,
87
- });
79
+ const points = data.handles?.points || [];
80
+ const totalCircles = Math.floor((points?.length || 0) / 4);
81
+ const circleGeometries = [];
82
+ for (let i = 0; i < points.length; i += 4) {
83
+ const circlePoints = points.slice(i, i + 4);
84
+ if (circlePoints.length < 2) {
85
+ continue;
86
+ }
87
+ const canvasCoordinates = circlePoints.map((p) => viewport.worldToCanvas(p));
88
+ const bottom = canvasCoordinates[0];
89
+ const top = canvasCoordinates[1];
90
+ const center = [
91
+ Math.floor((bottom[0] + top[0]) / 2),
92
+ Math.floor((bottom[1] + top[1]) / 2),
93
+ ];
94
+ const radius = Math.round(Math.abs(bottom[1] - center[1]));
95
+ circleGeometries.push({ center, radius });
96
+ }
97
+ const currentCircle = circleGeometries[circleGeometries.length - 1];
98
+ if (circleGeometries.length > 1) {
99
+ drawPathSvg(svgDrawingHelper, annotationUID, 'stroke-preview', circleGeometries.map((circle) => circle.center), {
100
+ color,
101
+ lineWidth: currentCircle.radius * 2,
102
+ strokeOpacity: 0.35,
103
+ lineCap: 'round',
104
+ lineJoin: 'round',
105
+ lineDash: this.centerSegmentIndexInfo.segmentIndex === 0 ? '6,4' : undefined,
106
+ });
107
+ }
108
+ if (currentCircle) {
109
+ drawCircleSvg(svgDrawingHelper, annotationUID, 'current-circle', currentCircle.center, currentCircle.radius, {
110
+ color,
111
+ lineWidth: 2,
112
+ strokeOpacity: 1,
113
+ lineDash: this.centerSegmentIndexInfo.segmentIndex === 0 ? [1, 2] : null,
114
+ }, 'brush-cursor');
115
+ }
88
116
  const { dynamicRadiusInCanvas } = configuration?.threshold || {
89
117
  dynamicRadiusInCanvas: 0,
90
118
  };
91
- if (dynamicRadiusInCanvas) {
92
- const circleUID1 = '1';
93
- drawCircleSvg(svgDrawingHelper, annotationUID, circleUID1, center, dynamicRadiusInCanvas, {
119
+ if (dynamicRadiusInCanvas && currentCircle) {
120
+ const circleUID1 = 'dynamic-radius';
121
+ drawCircleSvg(svgDrawingHelper, annotationUID, circleUID1, currentCircle.center, dynamicRadiusInCanvas, {
94
122
  color,
95
- });
123
+ }, 'brush-cursor');
96
124
  }
97
125
  },
98
126
  };
@@ -1,7 +1,7 @@
1
1
  import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
2
2
  export default {
3
3
  [StrategyCallbacks.OnInteractionStart]: (operationData) => {
4
- const { segmentIndex, previewSegmentIndex, segmentationVoxelManager, centerIJK, viewPlaneNormal, segmentationImageData, configuration, } = operationData;
4
+ const { segmentIndex, labelValue, previewSegmentIndex, segmentationVoxelManager, centerIJK, viewPlaneNormal, segmentationImageData, configuration, } = operationData;
5
5
  if (!configuration?.useCenterSegmentIndex) {
6
6
  operationData.centerSegmentIndexInfo.segmentIndex = null;
7
7
  operationData.centerSegmentIndexInfo.hasSegmentIndex = false;
@@ -23,7 +23,7 @@ export default {
23
23
  nestedBounds[2] = [centerIJK[2], centerIJK[2]];
24
24
  }
25
25
  const callback = ({ value }) => {
26
- hasSegmentIndex ||= value === segmentIndex;
26
+ hasSegmentIndex ||= value === (labelValue ?? segmentIndex);
27
27
  hasPreviewIndex ||= value === previewSegmentIndex;
28
28
  };
29
29
  segmentationVoxelManager.forEach(callback, {
@@ -1,5 +1,6 @@
1
1
  import { vec3 } from 'gl-matrix';
2
2
  import StrategyCallbacks from '../../../../enums/StrategyCallbacks';
3
+ import getViewportICamera from '../../../../utilities/getViewportICamera';
3
4
  export default {
4
5
  [StrategyCallbacks.Initialize]: (operationData) => {
5
6
  const { operationName, centerIJK, segmentationVoxelManager, imageVoxelManager, configuration, segmentIndex, viewport, } = operationData;
@@ -13,7 +14,10 @@ export default {
13
14
  const boundsIJK = segmentationVoxelManager.getBoundsIJK();
14
15
  const { range: oldThreshold, dynamicRadius = 0 } = configuration.threshold;
15
16
  const useDelta = oldThreshold ? 0 : dynamicRadius;
16
- const { viewPlaneNormal } = viewport.getCamera();
17
+ const { viewPlaneNormal } = getViewportICamera(viewport);
18
+ if (!viewPlaneNormal) {
19
+ return;
20
+ }
17
21
  const nestedBounds = boundsIJK.map((ijk, idx) => {
18
22
  const [min, max] = ijk;
19
23
  return [