@cornerstonejs/tools 4.22.13 → 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 (225) 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/init.js +2 -0
  18. package/dist/esm/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.js +10 -4
  19. package/dist/esm/stateManagement/segmentation/SegmentationRenderingEngine.js +23 -20
  20. package/dist/esm/stateManagement/segmentation/SegmentationRepresentationDisplayRegistry.d.ts +12 -0
  21. package/dist/esm/stateManagement/segmentation/SegmentationRepresentationDisplayRegistry.js +7 -0
  22. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.d.ts +1 -11
  23. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.js +28 -166
  24. package/dist/esm/stateManagement/segmentation/addColorLUT.js +7 -1
  25. package/dist/esm/stateManagement/segmentation/getCurrentLabelmapImageIdForViewport.js +16 -1
  26. package/dist/esm/stateManagement/segmentation/helpers/clearSegmentValue.js +9 -7
  27. package/dist/esm/stateManagement/segmentation/helpers/getSegmentationActor.d.ts +1 -1
  28. package/dist/esm/stateManagement/segmentation/helpers/getSegmentationActor.js +3 -2
  29. package/dist/esm/stateManagement/segmentation/helpers/getViewportLabelmapRenderMode.d.ts +5 -0
  30. package/dist/esm/stateManagement/segmentation/helpers/getViewportLabelmapRenderMode.js +58 -0
  31. package/dist/esm/stateManagement/segmentation/helpers/labelmapImageMapperSupport.d.ts +52 -0
  32. package/dist/esm/stateManagement/segmentation/helpers/labelmapImageMapperSupport.js +246 -0
  33. package/dist/esm/stateManagement/segmentation/helpers/labelmapSegmentationState.d.ts +1 -0
  34. package/dist/esm/stateManagement/segmentation/helpers/labelmapSegmentationState.js +1 -0
  35. package/dist/esm/stateManagement/segmentation/helpers/normalizeSegmentationInput.js +11 -1
  36. package/dist/esm/stateManagement/segmentation/internalAddSegmentationRepresentation.js +3 -3
  37. package/dist/esm/stateManagement/segmentation/labelmapModel/index.d.ts +9 -0
  38. package/dist/esm/stateManagement/segmentation/labelmapModel/index.js +7 -0
  39. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapEditTransaction.d.ts +54 -0
  40. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapEditTransaction.js +224 -0
  41. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageIdMapping.d.ts +6 -0
  42. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageIdMapping.js +39 -0
  43. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageReferenceResolver.d.ts +23 -0
  44. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapImageReferenceResolver.js +269 -0
  45. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLayerStore.d.ts +15 -0
  46. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLayerStore.js +160 -0
  47. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLegacyAdapter.d.ts +4 -0
  48. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapLegacyAdapter.js +42 -0
  49. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapSegmentBindings.d.ts +11 -0
  50. package/dist/esm/stateManagement/segmentation/labelmapModel/labelmapSegmentBindings.js +73 -0
  51. package/dist/esm/stateManagement/segmentation/labelmapModel/normalizeLabelmapSegmentationData.d.ts +17 -0
  52. package/dist/esm/stateManagement/segmentation/labelmapModel/normalizeLabelmapSegmentationData.js +75 -0
  53. package/dist/esm/stateManagement/segmentation/labelmapModel/privateLabelmap.d.ts +5 -0
  54. package/dist/esm/stateManagement/segmentation/labelmapModel/privateLabelmap.js +106 -0
  55. package/dist/esm/stateManagement/segmentation/models/SegmentModel.d.ts +11 -0
  56. package/dist/esm/stateManagement/segmentation/models/SegmentModel.js +19 -0
  57. package/dist/esm/stateManagement/segmentation/models/SegmentationModel.d.ts +12 -0
  58. package/dist/esm/stateManagement/segmentation/models/SegmentationModel.js +23 -0
  59. package/dist/esm/stateManagement/segmentation/removeSegmentationRepresentations.js +6 -10
  60. package/dist/esm/stateManagement/segmentation/segmentIndex.js +24 -0
  61. package/dist/esm/stateManagement/segmentation/segmentationEventManager.js +2 -9
  62. package/dist/esm/stateManagement/segmentation/segmentationState.d.ts +2 -1
  63. package/dist/esm/stateManagement/segmentation/segmentationState.js +4 -1
  64. package/dist/esm/store/state.js +2 -1
  65. package/dist/esm/synchronizers/callbacks/imageSliceSyncCallback.js +12 -3
  66. package/dist/esm/synchronizers/callbacks/presentationViewSyncCallback.js +5 -2
  67. package/dist/esm/synchronizers/callbacks/zoomPanSyncCallback.js +51 -3
  68. package/dist/esm/tools/AdvancedMagnifyTool.js +1 -1
  69. package/dist/esm/tools/CrosshairsTool.js +5 -5
  70. package/dist/esm/tools/OrientationControllerTool.js +1 -1
  71. package/dist/esm/tools/OrientationMarkerTool.js +4 -4
  72. package/dist/esm/tools/PanTool.js +26 -3
  73. package/dist/esm/tools/PlanarRotateTool.js +19 -4
  74. package/dist/esm/tools/ReferenceCursors.js +7 -1
  75. package/dist/esm/tools/SculptorTool/CircleSculptCursor.js +1 -1
  76. package/dist/esm/tools/TrackballRotateTool.js +3 -2
  77. package/dist/esm/tools/VolumeCroppingTool.js +3 -2
  78. package/dist/esm/tools/WindowLevelTool.d.ts +2 -1
  79. package/dist/esm/tools/WindowLevelTool.js +48 -4
  80. package/dist/esm/tools/ZoomTool.d.ts +8 -0
  81. package/dist/esm/tools/ZoomTool.js +92 -11
  82. package/dist/esm/tools/annotation/AngleTool.js +33 -31
  83. package/dist/esm/tools/annotation/ArrowAnnotateTool.js +30 -28
  84. package/dist/esm/tools/annotation/BidirectionalTool.js +51 -49
  85. package/dist/esm/tools/annotation/CircleROITool.js +49 -44
  86. package/dist/esm/tools/annotation/CobbAngleTool.js +1 -1
  87. package/dist/esm/tools/annotation/DragProbeTool.js +1 -1
  88. package/dist/esm/tools/annotation/ETDRSGridTool.js +1 -1
  89. package/dist/esm/tools/annotation/EllipticalROITool.js +42 -37
  90. package/dist/esm/tools/annotation/HeightTool.js +1 -1
  91. package/dist/esm/tools/annotation/KeyImageTool.js +11 -11
  92. package/dist/esm/tools/annotation/LabelTool.js +37 -35
  93. package/dist/esm/tools/annotation/LengthTool.js +35 -33
  94. package/dist/esm/tools/annotation/LivewireContourSegmentationTool.js +6 -4
  95. package/dist/esm/tools/annotation/LivewireContourTool.js +1 -1
  96. package/dist/esm/tools/annotation/PlanarFreehandContourSegmentationTool.js +6 -4
  97. package/dist/esm/tools/annotation/PlanarFreehandROITool.js +1 -1
  98. package/dist/esm/tools/annotation/ProbeTool.js +51 -46
  99. package/dist/esm/tools/annotation/RectangleROITool.js +42 -37
  100. package/dist/esm/tools/annotation/RegionSegmentPlusTool.js +1 -1
  101. package/dist/esm/tools/annotation/RegionSegmentTool.js +1 -1
  102. package/dist/esm/tools/annotation/SplineContourSegmentationTool.js +1 -1
  103. package/dist/esm/tools/annotation/SplineROITool.js +51 -49
  104. package/dist/esm/tools/annotation/UltrasoundDirectionalTool.js +1 -1
  105. package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/UltrasoundPleuraBLineTool.js +57 -55
  106. package/dist/esm/tools/annotation/VideoRedactionTool.js +1 -1
  107. package/dist/esm/tools/base/AnnotationDisplayTool.js +9 -6
  108. package/dist/esm/tools/base/AnnotationTool.js +2 -1
  109. package/dist/esm/tools/base/BaseTool.js +16 -10
  110. package/dist/esm/tools/base/ContourSegmentationBaseTool.js +1 -1
  111. package/dist/esm/tools/base/GrowCutBaseTool.js +2 -2
  112. package/dist/esm/tools/displayTools/Labelmap/addLabelmapToElement.d.ts +2 -4
  113. package/dist/esm/tools/displayTools/Labelmap/addLabelmapToElement.js +15 -85
  114. package/dist/esm/tools/displayTools/Labelmap/labelmapActorStyle.d.ts +5 -0
  115. package/dist/esm/tools/displayTools/Labelmap/labelmapActorStyle.js +191 -0
  116. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.d.ts +4 -3
  117. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.js +48 -209
  118. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/createLabelmapRenderPlan.d.ts +3 -0
  119. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/createLabelmapRenderPlan.js +51 -0
  120. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/index.d.ts +4 -0
  121. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/index.js +3 -0
  122. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/legacyVolumePlan.d.ts +14 -0
  123. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/legacyVolumePlan.js +143 -0
  124. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/planarGenericVolumeLabelmap.d.ts +40 -0
  125. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/planarGenericVolumeLabelmap.js +79 -0
  126. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/removeLabelmapRepresentationFromViewport.d.ts +3 -0
  127. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/removeLabelmapRepresentationFromViewport.js +18 -0
  128. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/resolveLabelmapRenderPlan.d.ts +9 -0
  129. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/resolveLabelmapRenderPlan.js +56 -0
  130. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/stackImagePlan.d.ts +11 -0
  131. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/stackImagePlan.js +35 -0
  132. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/types.d.ts +48 -0
  133. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/types.js +0 -0
  134. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/volumeSliceImageMapperPlan.d.ts +13 -0
  135. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan/volumeSliceImageMapperPlan.js +34 -0
  136. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan.d.ts +2 -0
  137. package/dist/esm/tools/displayTools/Labelmap/labelmapRenderPlan.js +1 -0
  138. package/dist/esm/tools/displayTools/Labelmap/labelmapRepresentationUID.d.ts +8 -0
  139. package/dist/esm/tools/displayTools/Labelmap/labelmapRepresentationUID.js +18 -0
  140. package/dist/esm/tools/displayTools/Labelmap/removeLabelmapFromElement.js +2 -5
  141. package/dist/esm/tools/displayTools/Labelmap/removeLabelmapRepresentationData.d.ts +3 -0
  142. package/dist/esm/tools/displayTools/Labelmap/removeLabelmapRepresentationData.js +16 -0
  143. package/dist/esm/tools/displayTools/Labelmap/syncStackLabelmapActors.d.ts +2 -0
  144. package/dist/esm/tools/displayTools/Labelmap/syncStackLabelmapActors.js +135 -0
  145. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapImageMapper.d.ts +16 -0
  146. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapImageMapper.js +267 -0
  147. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapSliceData.d.ts +27 -0
  148. package/dist/esm/tools/displayTools/Labelmap/volumeLabelmapSliceData.js +185 -0
  149. package/dist/esm/tools/displayTools/registerBuiltInSegmentationRepresentationDisplays.d.ts +1 -0
  150. package/dist/esm/tools/displayTools/registerBuiltInSegmentationRepresentationDisplays.js +16 -0
  151. package/dist/esm/tools/segmentation/BrushTool.d.ts +9 -2
  152. package/dist/esm/tools/segmentation/BrushTool.js +109 -25
  153. package/dist/esm/tools/segmentation/CircleScissorsTool.js +13 -6
  154. package/dist/esm/tools/segmentation/LabelmapBaseTool.d.ts +2 -3
  155. package/dist/esm/tools/segmentation/LabelmapBaseTool.js +77 -38
  156. package/dist/esm/tools/segmentation/LabelmapEditWithContour.js +3 -3
  157. package/dist/esm/tools/segmentation/PaintFillTool.js +11 -4
  158. package/dist/esm/tools/segmentation/RectangleROIStartEndThresholdTool.d.ts +2 -0
  159. package/dist/esm/tools/segmentation/RectangleROIStartEndThresholdTool.js +16 -8
  160. package/dist/esm/tools/segmentation/RectangleScissorsTool.js +13 -6
  161. package/dist/esm/tools/segmentation/SegmentBidirectionalTool.js +63 -61
  162. package/dist/esm/tools/segmentation/SegmentSelectTool.js +4 -4
  163. package/dist/esm/tools/segmentation/SphereScissorsTool.js +5 -1
  164. package/dist/esm/tools/segmentation/strategies/BrushStrategy.d.ts +7 -0
  165. package/dist/esm/tools/segmentation/strategies/BrushStrategy.js +47 -24
  166. package/dist/esm/tools/segmentation/strategies/compositions/circularCursor.js +49 -15
  167. package/dist/esm/tools/segmentation/strategies/compositions/determineSegmentIndex.js +2 -2
  168. package/dist/esm/tools/segmentation/strategies/compositions/dynamicThreshold.js +5 -1
  169. package/dist/esm/tools/segmentation/strategies/compositions/islandRemovalComposition.js +2 -2
  170. package/dist/esm/tools/segmentation/strategies/compositions/preview.js +2 -2
  171. package/dist/esm/tools/segmentation/strategies/compositions/setValue.js +14 -6
  172. package/dist/esm/tools/segmentation/strategies/utils/crossLayerErase.d.ts +4 -0
  173. package/dist/esm/tools/segmentation/strategies/utils/crossLayerErase.js +23 -0
  174. package/dist/esm/tools/segmentation/strategies/utils/getStrategyData.js +1 -1
  175. package/dist/esm/tools/segmentation/strategies/utils/handleUseSegmentCenterIndex.js +12 -11
  176. package/dist/esm/tools/segmentation/strategies/utils/labelmapOverlap.d.ts +4 -0
  177. package/dist/esm/tools/segmentation/strategies/utils/labelmapOverlap.js +41 -0
  178. package/dist/esm/tools/segmentation/strategies/utils/overwritePolicy.d.ts +3 -0
  179. package/dist/esm/tools/segmentation/strategies/utils/overwritePolicy.js +31 -0
  180. package/dist/esm/tools/segmentation/strategies/utils/segmentSeparation.d.ts +3 -0
  181. package/dist/esm/tools/segmentation/strategies/utils/segmentSeparation.js +38 -0
  182. package/dist/esm/tools/segmentation/utils/LazyBrushEditController.d.ts +19 -0
  183. package/dist/esm/tools/segmentation/utils/LazyBrushEditController.js +55 -0
  184. package/dist/esm/tools/segmentation/utils/lazyBrushPreview.d.ts +3 -0
  185. package/dist/esm/tools/segmentation/utils/lazyBrushPreview.js +34 -0
  186. package/dist/esm/tools/segmentation/utils/shouldUseLazyLabelmapEditing.d.ts +3 -0
  187. package/dist/esm/tools/segmentation/utils/shouldUseLazyLabelmapEditing.js +42 -0
  188. package/dist/esm/types/LabelmapToolOperationData.d.ts +5 -0
  189. package/dist/esm/types/LabelmapTypes.d.ts +29 -6
  190. package/dist/esm/types/SegmentationStateTypes.d.ts +4 -0
  191. package/dist/esm/utilities/calibrateImageSpacing.js +17 -2
  192. package/dist/esm/utilities/contours/AnnotationToPointData.js +1 -1
  193. package/dist/esm/utilities/getSphereBoundsInfo.js +5 -1
  194. package/dist/esm/utilities/getViewportICamera.d.ts +4 -0
  195. package/dist/esm/utilities/getViewportICamera.js +23 -0
  196. package/dist/esm/utilities/getViewportsForAnnotation.js +5 -1
  197. package/dist/esm/utilities/math/basic/BasicStatsCalculator.js +9 -7
  198. package/dist/esm/utilities/pointInSurroundingSphereCallback.js +8 -1
  199. package/dist/esm/utilities/segmentation/InterpolationManager/InterpolationManager.js +121 -118
  200. package/dist/esm/utilities/segmentation/SegmentStatsCalculator.js +5 -4
  201. package/dist/esm/utilities/segmentation/VolumetricCalculator.js +1 -1
  202. package/dist/esm/utilities/segmentation/createLabelmapVolumeForViewport.js +1 -1
  203. package/dist/esm/utilities/segmentation/getReferenceVolumeForSegmentation.js +1 -1
  204. package/dist/esm/utilities/segmentation/getReferenceVolumeForSegmentationVolume.js +11 -2
  205. package/dist/esm/utilities/segmentation/getSegmentIndexAtLabelmapBorder.js +36 -17
  206. package/dist/esm/utilities/segmentation/getSegmentIndexAtWorldPoint.js +42 -25
  207. package/dist/esm/utilities/segmentation/getUniqueSegmentIndices.js +3 -30
  208. package/dist/esm/utilities/segmentation/index.d.ts +2 -1
  209. package/dist/esm/utilities/segmentation/index.js +2 -1
  210. package/dist/esm/utilities/segmentation/utilsForWorker.js +2 -2
  211. package/dist/esm/utilities/segmentation/validateLabelmap.js +1 -1
  212. package/dist/esm/utilities/stackPrefetch/stackPrefetch.js +0 -1
  213. package/dist/esm/utilities/touch/index.js +3 -2
  214. package/dist/esm/utilities/viewportCapabilities.d.ts +16 -0
  215. package/dist/esm/utilities/viewportCapabilities.js +18 -0
  216. package/dist/esm/utilities/viewportFilters/filterViewportsWithParallelNormals.d.ts +1 -1
  217. package/dist/esm/utilities/viewportFilters/filterViewportsWithParallelNormals.js +12 -4
  218. package/dist/esm/utilities/viewportFilters/filterViewportsWithSameOrientation.d.ts +1 -1
  219. package/dist/esm/utilities/viewportFilters/filterViewportsWithSameOrientation.js +11 -4
  220. package/dist/esm/utilities/viewportFilters/getViewportIdsWithToolToRender.js +1 -1
  221. package/dist/esm/utilities/viewportPresentation.d.ts +3 -0
  222. package/dist/esm/utilities/viewportPresentation.js +26 -0
  223. package/dist/esm/version.d.ts +1 -1
  224. package/dist/esm/version.js +1 -1
  225. package/package.json +10 -10
@@ -0,0 +1,267 @@
1
+ import vtkImageMapper from '@kitware/vtk.js/Rendering/Core/ImageMapper';
2
+ import vtkImageSlice from '@kitware/vtk.js/Rendering/Core/ImageSlice';
3
+ import { ActorRenderMode, Enums } from '@cornerstonejs/core';
4
+ import { canRenderVolumeViewportLabelmapAsImage } from '../../../stateManagement/segmentation/helpers/labelmapImageMapperSupport';
5
+ import { getLabelmap, getOrCreateLabelmapVolume, getLabelmaps, getLabelmapForImageId, getLabelmapForVolumeId, } from '../../../stateManagement/segmentation/helpers/labelmapSegmentationState';
6
+ import { createLabelmapRepresentationUID, isLabelmapRepresentationUID, } from './labelmapRepresentationUID';
7
+ import { applyPlanarOverlayDepthOffset, createSliceImageData, getSliceRenderingCamera, getSliceState, } from './volumeLabelmapSliceData';
8
+ const OVERLAY_RENDERER_SUFFIX = 'labelmap-image-mapper-overlay';
9
+ function isPlanarSliceRenderingViewport(viewport) {
10
+ const compatibilityViewport = viewport;
11
+ return (compatibilityViewport.type === Enums.ViewportType.PLANAR_NEXT &&
12
+ typeof compatibilityViewport.addImages === 'function' &&
13
+ typeof compatibilityViewport.getCurrentImageId === 'function' &&
14
+ typeof compatibilityViewport.render === 'function');
15
+ }
16
+ function createActorEntry(args) {
17
+ const mapper = vtkImageMapper.newInstance();
18
+ mapper.setInputData(args.imageData);
19
+ const actor = vtkImageSlice.newInstance();
20
+ actor.setMapper(mapper);
21
+ return {
22
+ uid: args.representationUID,
23
+ actor,
24
+ actorMapper: {
25
+ actor,
26
+ mapper,
27
+ renderMode: ActorRenderMode.VTK_IMAGE,
28
+ },
29
+ referencedId: args.referencedId,
30
+ representationUID: args.representationUID,
31
+ };
32
+ }
33
+ function getOverlayRendererId(viewportId) {
34
+ return `${viewportId}::${OVERLAY_RENDERER_SUFFIX}`;
35
+ }
36
+ function getOrCreateOverlayRenderer(viewport) {
37
+ const renderingEngine = viewport.getRenderingEngine();
38
+ const offscreenMultiRenderWindow = renderingEngine.getOffscreenMultiRenderWindow(viewport.id);
39
+ const overlayRendererId = getOverlayRendererId(viewport.id);
40
+ const baseRenderer = viewport.getRenderer();
41
+ const baseViewport = baseRenderer.getViewport();
42
+ let overlayRenderer = offscreenMultiRenderWindow.getRenderer(overlayRendererId);
43
+ if (!overlayRenderer) {
44
+ const renderWindow = offscreenMultiRenderWindow.getRenderWindow();
45
+ if (renderWindow.getNumberOfLayers() < 2) {
46
+ renderWindow.setNumberOfLayers(2);
47
+ }
48
+ offscreenMultiRenderWindow.addRenderer({
49
+ viewport: baseViewport,
50
+ id: overlayRendererId,
51
+ background: [0, 0, 0],
52
+ });
53
+ overlayRenderer = offscreenMultiRenderWindow.getRenderer(overlayRendererId);
54
+ overlayRenderer.setLayer(1);
55
+ overlayRenderer.setPreserveDepthBuffer(false);
56
+ }
57
+ overlayRenderer.setActiveCamera(baseRenderer.getActiveCamera());
58
+ overlayRenderer.setViewport(baseViewport[0], baseViewport[1], baseViewport[2], baseViewport[3]);
59
+ return overlayRenderer;
60
+ }
61
+ function moveActorToOverlayRenderer(viewport, actorEntry) {
62
+ const baseRenderer = viewport.getRenderer();
63
+ const overlayRenderer = getOrCreateOverlayRenderer(viewport);
64
+ baseRenderer.removeActor(actorEntry.actor);
65
+ overlayRenderer.addActor(actorEntry.actor);
66
+ }
67
+ export function getVolumeLabelmapImageMapperRepresentationUIDs(viewport, segmentationId, segmentation) {
68
+ if (!canRenderVolumeViewportLabelmapAsImage(viewport)) {
69
+ return [];
70
+ }
71
+ const useStablePlanarUID = isPlanarSliceRenderingViewport(viewport);
72
+ return getLabelmaps(segmentation)
73
+ .map((layer) => {
74
+ const volume = getOrCreateLabelmapVolume(layer);
75
+ if (!volume) {
76
+ return;
77
+ }
78
+ const state = getSliceState(viewport, volume);
79
+ if (!state) {
80
+ return;
81
+ }
82
+ return createLabelmapRepresentationUID({
83
+ segmentationId,
84
+ referencedId: layer.labelmapId,
85
+ ...(useStablePlanarUID ? {} : { sliceStateKey: state.key }),
86
+ });
87
+ })
88
+ .filter((value) => !!value);
89
+ }
90
+ export async function addVolumeLabelmapImageMapperActors(args) {
91
+ const { viewport, segmentation, segmentationId } = args;
92
+ if (!canRenderVolumeViewportLabelmapAsImage(viewport)) {
93
+ return;
94
+ }
95
+ if (isPlanarSliceRenderingViewport(viewport)) {
96
+ await addPlanarLabelmapImageMapperActors({
97
+ viewport,
98
+ segmentation,
99
+ segmentationId,
100
+ });
101
+ return;
102
+ }
103
+ getLabelmaps(segmentation).forEach((layer) => {
104
+ const volume = getOrCreateLabelmapVolume(layer);
105
+ if (!volume) {
106
+ return;
107
+ }
108
+ const sliceData = createSliceImageData(volume, viewport);
109
+ if (!sliceData) {
110
+ return;
111
+ }
112
+ const representationUID = createLabelmapRepresentationUID({
113
+ segmentationId,
114
+ referencedId: layer.labelmapId,
115
+ sliceStateKey: sliceData.state.key,
116
+ });
117
+ const actorEntry = createActorEntry({
118
+ imageData: sliceData.imageData,
119
+ referencedId: layer.labelmapId,
120
+ representationUID,
121
+ });
122
+ viewport.addActor(actorEntry);
123
+ moveActorToOverlayRenderer(viewport, actorEntry);
124
+ });
125
+ }
126
+ export function updateVolumeLabelmapImageMapperActors(args) {
127
+ const { viewport, segmentation, segmentationId, actorEntries } = args;
128
+ if (!canRenderVolumeViewportLabelmapAsImage(viewport)) {
129
+ return;
130
+ }
131
+ if (isPlanarSliceRenderingViewport(viewport)) {
132
+ updatePlanarLabelmapImageMapperActors({
133
+ viewport,
134
+ segmentation,
135
+ segmentationId,
136
+ actorEntries,
137
+ });
138
+ return;
139
+ }
140
+ const actorEntriesByLabelmapId = new Map((actorEntries ?? viewport.getActors())
141
+ .filter((actorEntry) => isLabelmapRepresentationUID(actorEntry.representationUID, segmentationId))
142
+ .map((actorEntry) => [actorEntry.referencedId, actorEntry]));
143
+ getLabelmaps(segmentation).forEach((layer) => {
144
+ const actorEntry = actorEntriesByLabelmapId.get(layer.labelmapId);
145
+ if (!actorEntry) {
146
+ return;
147
+ }
148
+ const volume = getOrCreateLabelmapVolume(layer);
149
+ if (!volume) {
150
+ return;
151
+ }
152
+ const sliceData = createSliceImageData(volume, viewport);
153
+ if (!sliceData) {
154
+ return;
155
+ }
156
+ const mapper = actorEntry.actor.getMapper();
157
+ mapper.setInputData(sliceData.imageData);
158
+ mapper.modified();
159
+ actorEntry.actor.modified?.();
160
+ });
161
+ }
162
+ export function removeVolumeLabelmapImageMapperActors(viewport, segmentationId) {
163
+ if (!(viewport.type === Enums.ViewportType.ORTHOGRAPHIC)) {
164
+ return;
165
+ }
166
+ if (!canRenderVolumeViewportLabelmapAsImage(viewport)) {
167
+ return;
168
+ }
169
+ const renderingEngine = viewport.getRenderingEngine();
170
+ const offscreenMultiRenderWindow = renderingEngine.getOffscreenMultiRenderWindow(viewport.id);
171
+ const overlayRenderer = offscreenMultiRenderWindow.getRenderer(getOverlayRendererId(viewport.id));
172
+ if (!overlayRenderer) {
173
+ return;
174
+ }
175
+ viewport
176
+ .getActors()
177
+ .filter((actorEntry) => isLabelmapRepresentationUID(actorEntry.representationUID, segmentationId))
178
+ .forEach((actorEntry) => {
179
+ overlayRenderer.removeActor(actorEntry.actor);
180
+ });
181
+ if (!overlayRenderer.getActors().length) {
182
+ offscreenMultiRenderWindow.removeRenderer(getOverlayRendererId(viewport.id));
183
+ }
184
+ }
185
+ export function getLabelmapForActorReference(segmentation, referencedId) {
186
+ if (!referencedId) {
187
+ return;
188
+ }
189
+ return (getLabelmap(segmentation, referencedId) ??
190
+ getLabelmapForImageId(segmentation, referencedId) ??
191
+ getLabelmapForVolumeId(segmentation, referencedId) ??
192
+ getLabelmaps(segmentation).find((layer) => layer.volumeId === referencedId));
193
+ }
194
+ async function addPlanarLabelmapImageMapperActors(args) {
195
+ const { viewport, segmentation, segmentationId } = args;
196
+ for (const [index, layer] of getLabelmaps(segmentation).entries()) {
197
+ const volume = getOrCreateLabelmapVolume(layer);
198
+ if (!volume) {
199
+ continue;
200
+ }
201
+ const sliceData = createSliceImageData(volume, viewport);
202
+ if (!sliceData) {
203
+ continue;
204
+ }
205
+ const currentImageId = viewport.getCurrentImageId() ??
206
+ volume.imageIds[Math.min(Math.max(sliceData.state.sliceIndex, 0), Math.max(volume.imageIds.length - 1, 0))];
207
+ if (!currentImageId) {
208
+ continue;
209
+ }
210
+ const representationUID = createLabelmapRepresentationUID({
211
+ segmentationId,
212
+ referencedId: layer.labelmapId,
213
+ });
214
+ await viewport.addImages([
215
+ {
216
+ dataId: representationUID,
217
+ imageId: currentImageId,
218
+ imageData: sliceData.imageData,
219
+ reference: {
220
+ kind: 'segmentation',
221
+ segmentationId,
222
+ representationUID,
223
+ labelmapId: layer.labelmapId,
224
+ },
225
+ useWorldCoordinateImageData: true,
226
+ callback: ({ imageActor }) => {
227
+ const mapper = imageActor.getMapper();
228
+ const camera = getSliceRenderingCamera(viewport);
229
+ mapper.setInputData(sliceData.imageData);
230
+ mapper.modified();
231
+ if (camera) {
232
+ applyPlanarOverlayDepthOffset(imageActor, camera.viewPlaneNormal, index + 1);
233
+ }
234
+ },
235
+ },
236
+ ]);
237
+ }
238
+ viewport.render();
239
+ }
240
+ function updatePlanarLabelmapImageMapperActors(args) {
241
+ const { viewport, segmentation, segmentationId, actorEntries } = args;
242
+ const actorEntriesByLabelmapId = new Map((actorEntries ?? viewport.getActors())
243
+ .filter((actorEntry) => isLabelmapRepresentationUID(actorEntry.representationUID, segmentationId))
244
+ .map((actorEntry) => [actorEntry.referencedId, actorEntry]));
245
+ getLabelmaps(segmentation).forEach((layer, index) => {
246
+ const actorEntry = actorEntriesByLabelmapId.get(layer.labelmapId);
247
+ if (!actorEntry) {
248
+ return;
249
+ }
250
+ const volume = getOrCreateLabelmapVolume(layer);
251
+ if (!volume) {
252
+ return;
253
+ }
254
+ const sliceData = createSliceImageData(volume, viewport);
255
+ if (!sliceData) {
256
+ return;
257
+ }
258
+ const mapper = actorEntry.actor.getMapper();
259
+ mapper.setInputData(sliceData.imageData);
260
+ mapper.modified();
261
+ const camera = getSliceRenderingCamera(viewport);
262
+ if (camera) {
263
+ applyPlanarOverlayDepthOffset(actorEntry.actor, camera.viewPlaneNormal, index + 1);
264
+ }
265
+ actorEntry.actor.modified?.();
266
+ });
267
+ }
@@ -0,0 +1,27 @@
1
+ import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
2
+ import vtkImageSlice from '@kitware/vtk.js/Rendering/Core/ImageSlice';
3
+ import { type Types } from '@cornerstonejs/core';
4
+ type ImageMapperSliceState = {
5
+ key: string;
6
+ xAxis: number;
7
+ xSign: 1 | -1;
8
+ yAxis: number;
9
+ ySign: 1 | -1;
10
+ sliceAxis: number;
11
+ sliceIndex: number;
12
+ };
13
+ type SliceRenderingViewport = Types.IViewport & {
14
+ getCamera?: () => Pick<Types.ICamera, 'focalPoint' | 'viewPlaneNormal' | 'viewUp'>;
15
+ getResolvedView?: () => {
16
+ toICamera?: () => Pick<Types.ICamera, 'focalPoint' | 'viewPlaneNormal' | 'viewUp'>;
17
+ } | undefined;
18
+ };
19
+ declare function applyPlanarOverlayDepthOffset(actor: vtkImageSlice, viewPlaneNormal: Types.Point3, overlayOrder: number): void;
20
+ declare function getSliceRenderingCamera(viewport: SliceRenderingViewport): Pick<Types.ICamera, 'focalPoint' | 'viewPlaneNormal' | 'viewUp'> | undefined;
21
+ declare function getSliceState(viewport: SliceRenderingViewport, volume: Types.IImageVolume): ImageMapperSliceState | undefined;
22
+ declare function createSliceImageData(volume: Types.IImageVolume, viewport: SliceRenderingViewport): {
23
+ imageData: vtkImageData;
24
+ state: ImageMapperSliceState;
25
+ } | undefined;
26
+ export { applyPlanarOverlayDepthOffset, createSliceImageData, getSliceRenderingCamera, getSliceState, };
27
+ export type { ImageMapperSliceState, SliceRenderingViewport };
@@ -0,0 +1,185 @@
1
+ import vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';
2
+ import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
3
+ import vtkImageSlice from '@kitware/vtk.js/Rendering/Core/ImageSlice';
4
+ import { utilities } from '@cornerstonejs/core';
5
+ import { vec3 } from 'gl-matrix';
6
+ import { DIRECTION_ALIGNMENT_TOLERANCE } from '../../../stateManagement/segmentation/helpers/labelmapImageMapperSupport';
7
+ const PLANAR_OVERLAY_DEPTH_EPSILON = 1e-4;
8
+ function applyPlanarOverlayDepthOffset(actor, viewPlaneNormal, overlayOrder) {
9
+ if (overlayOrder <= 0) {
10
+ actor.setPosition(0, 0, 0);
11
+ return;
12
+ }
13
+ const [x, y, z] = vec3.normalize(vec3.create(), viewPlaneNormal);
14
+ const offset = overlayOrder * PLANAR_OVERLAY_DEPTH_EPSILON;
15
+ actor.setPosition(x * offset, y * offset, z * offset);
16
+ }
17
+ function matchAxis(vector, axes) {
18
+ let bestAxis = -1;
19
+ let bestDot = 0;
20
+ axes.forEach((axisVector, axis) => {
21
+ const dot = vec3.dot(vector, axisVector);
22
+ if (Math.abs(dot) > Math.abs(bestDot)) {
23
+ bestAxis = axis;
24
+ bestDot = dot;
25
+ }
26
+ });
27
+ if (bestAxis === -1 || Math.abs(bestDot) < DIRECTION_ALIGNMENT_TOLERANCE) {
28
+ return;
29
+ }
30
+ return {
31
+ axis: bestAxis,
32
+ sign: bestDot >= 0 ? 1 : -1,
33
+ };
34
+ }
35
+ function getSliceRenderingCamera(viewport) {
36
+ const resolvedCamera = viewport.getResolvedView?.()?.toICamera?.();
37
+ const normalizedResolvedCamera = normalizeSliceRenderingCamera(resolvedCamera);
38
+ if (normalizedResolvedCamera) {
39
+ return normalizedResolvedCamera;
40
+ }
41
+ const legacyCamera = viewport.getCamera?.();
42
+ const normalizedLegacyCamera = normalizeSliceRenderingCamera(legacyCamera);
43
+ return normalizedLegacyCamera;
44
+ }
45
+ function normalizeSliceRenderingCamera(camera) {
46
+ const candidate = camera;
47
+ const focalPoint = toPoint3(candidate?.focalPoint);
48
+ const viewPlaneNormal = toPoint3(candidate?.viewPlaneNormal);
49
+ const viewUp = toPoint3(candidate?.viewUp);
50
+ if (!focalPoint || !viewPlaneNormal || !viewUp) {
51
+ return;
52
+ }
53
+ return {
54
+ focalPoint,
55
+ viewPlaneNormal,
56
+ viewUp,
57
+ };
58
+ }
59
+ function toPoint3(value) {
60
+ const candidate = value;
61
+ if (!candidate || typeof candidate.length !== 'number') {
62
+ return;
63
+ }
64
+ if (candidate.length < 3) {
65
+ return;
66
+ }
67
+ const point = [
68
+ Number(candidate[0]),
69
+ Number(candidate[1]),
70
+ Number(candidate[2]),
71
+ ];
72
+ return point.every(Number.isFinite) ? point : undefined;
73
+ }
74
+ function getVolumeAxes(volume) {
75
+ const { direction } = volume;
76
+ return [
77
+ [direction[0], direction[1], direction[2]],
78
+ [direction[3], direction[4], direction[5]],
79
+ [direction[6], direction[7], direction[8]],
80
+ ];
81
+ }
82
+ function getSliceState(viewport, volume) {
83
+ const camera = getSliceRenderingCamera(viewport);
84
+ if (!camera) {
85
+ return;
86
+ }
87
+ const { viewPlaneNormal, viewUp, focalPoint } = camera;
88
+ const xDirection = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), viewPlaneNormal, viewUp));
89
+ const yDirection = vec3.normalize(vec3.create(), viewUp);
90
+ const axes = getVolumeAxes(volume);
91
+ const xAxis = matchAxis(xDirection, axes);
92
+ const yAxis = matchAxis(yDirection, axes);
93
+ const sliceAxis = matchAxis(viewPlaneNormal, axes);
94
+ if (!xAxis || !yAxis || !sliceAxis) {
95
+ return;
96
+ }
97
+ const distinctAxes = new Set([xAxis.axis, yAxis.axis, sliceAxis.axis]);
98
+ if (distinctAxes.size !== 3) {
99
+ return;
100
+ }
101
+ const continuousIndex = utilities.transformWorldToIndexContinuous(volume.imageData, focalPoint);
102
+ const sliceIndex = Math.floor(continuousIndex[sliceAxis.axis] + 0.5 - 1e-6);
103
+ if (sliceIndex < 0 || sliceIndex >= volume.dimensions[sliceAxis.axis]) {
104
+ return;
105
+ }
106
+ return {
107
+ key: [
108
+ sliceAxis.axis,
109
+ sliceIndex,
110
+ xAxis.axis,
111
+ xAxis.sign,
112
+ yAxis.axis,
113
+ yAxis.sign,
114
+ ].join(':'),
115
+ xAxis: xAxis.axis,
116
+ xSign: xAxis.sign,
117
+ yAxis: yAxis.axis,
118
+ ySign: yAxis.sign,
119
+ sliceAxis: sliceAxis.axis,
120
+ sliceIndex,
121
+ };
122
+ }
123
+ function createSliceImageData(volume, viewport) {
124
+ const state = getSliceState(viewport, volume);
125
+ if (!state) {
126
+ return;
127
+ }
128
+ const axisVectors = getVolumeAxes(volume);
129
+ const { dimensions, spacing, voxelManager } = volume;
130
+ const width = dimensions[state.xAxis];
131
+ const height = dimensions[state.yAxis];
132
+ const SliceDataConstructor = voxelManager.getConstructor();
133
+ const pixelData = new SliceDataConstructor(width * height);
134
+ const ijk = [0, 0, 0];
135
+ ijk[state.sliceAxis] = state.sliceIndex;
136
+ const xStart = state.xSign > 0 ? 0 : width - 1;
137
+ const xStep = state.xSign > 0 ? 1 : -1;
138
+ const yStart = state.ySign > 0 ? 0 : height - 1;
139
+ const yStep = state.ySign > 0 ? 1 : -1;
140
+ for (let y = 0, srcY = yStart; y < height; y++, srcY += yStep) {
141
+ ijk[state.yAxis] = srcY;
142
+ const rowOffset = y * width;
143
+ for (let x = 0, srcX = xStart; x < width; x++, srcX += xStep) {
144
+ ijk[state.xAxis] = srcX;
145
+ pixelData[rowOffset + x] = Number(voxelManager.getAtIJK(ijk[0], ijk[1], ijk[2]));
146
+ }
147
+ }
148
+ const originIndex = [0, 0, 0];
149
+ originIndex[state.sliceAxis] = state.sliceIndex;
150
+ originIndex[state.xAxis] = state.xSign > 0 ? 0 : width - 1;
151
+ originIndex[state.yAxis] = state.ySign > 0 ? 0 : height - 1;
152
+ const xDirection = axisVectors[state.xAxis].map((value) => value * state.xSign);
153
+ const yDirection = axisVectors[state.yAxis].map((value) => value * state.ySign);
154
+ const camera = getSliceRenderingCamera(viewport);
155
+ if (!camera) {
156
+ return;
157
+ }
158
+ const zDirection = vec3.normalize(vec3.create(), camera.viewPlaneNormal);
159
+ const dataType = vtkDataArray.getDataType(pixelData);
160
+ const scalarArray = vtkDataArray.newInstance({
161
+ dataType,
162
+ name: 'Pixels',
163
+ numberOfComponents: 1,
164
+ values: pixelData,
165
+ });
166
+ const imageData = vtkImageData.newInstance();
167
+ imageData.set({ dataType, numberOfComponents: 1 }, true);
168
+ imageData.setDimensions(width, height, 1);
169
+ imageData.setSpacing([spacing[state.xAxis], spacing[state.yAxis], 1]);
170
+ imageData.setDirection(new Float32Array([
171
+ ...xDirection,
172
+ ...yDirection,
173
+ zDirection[0],
174
+ zDirection[1],
175
+ zDirection[2],
176
+ ]));
177
+ imageData.setOrigin(utilities.transformIndexToWorld(volume.imageData, originIndex));
178
+ imageData.getPointData().setScalars(scalarArray);
179
+ imageData.modified();
180
+ return {
181
+ imageData,
182
+ state,
183
+ };
184
+ }
185
+ export { applyPlanarOverlayDepthOffset, createSliceImageData, getSliceRenderingCamera, getSliceState, };
@@ -0,0 +1 @@
1
+ export declare function registerBuiltInSegmentationRepresentationDisplays(): void;
@@ -0,0 +1,16 @@
1
+ import SegmentationRepresentations from '../../enums/SegmentationRepresentations';
2
+ import { registerSegmentationRepresentationDisplay, } from '../../stateManagement/segmentation/SegmentationRepresentationDisplayRegistry';
3
+ import contourDisplay from './Contour/contourDisplay';
4
+ import labelmapDisplay from './Labelmap/labelmapDisplay';
5
+ import surfaceDisplay from './Surface/surfaceDisplay';
6
+ let builtInDisplaysRegistered = false;
7
+ export function registerBuiltInSegmentationRepresentationDisplays() {
8
+ if (builtInDisplaysRegistered) {
9
+ return;
10
+ }
11
+ registerSegmentationRepresentationDisplay(SegmentationRepresentations.Labelmap, labelmapDisplay);
12
+ registerSegmentationRepresentationDisplay(SegmentationRepresentations.Contour, contourDisplay);
13
+ registerSegmentationRepresentationDisplay(SegmentationRepresentations.Surface, surfaceDisplay);
14
+ builtInDisplaysRegistered = true;
15
+ }
16
+ registerBuiltInSegmentationRepresentationDisplays();
@@ -4,11 +4,18 @@ import LabelmapBaseTool from './LabelmapBaseTool';
4
4
  declare class BrushTool extends LabelmapBaseTool {
5
5
  static toolName: any;
6
6
  private _lastDragInfo;
7
+ private _lazyEdit;
7
8
  constructor(toolProps?: PublicToolProps, defaultToolProps?: ToolProps);
8
- onSetToolPassive: (evt: any) => void;
9
+ onSetToolPassive: (_evt: any) => void;
9
10
  onSetToolEnabled: () => void;
10
- onSetToolDisabled: (evt: any) => void;
11
+ onSetToolDisabled: (_evt: any) => void;
11
12
  private disableCursor;
13
+ private _isLazyLabelmapEditingEnabled;
14
+ private _resetLazyEditState;
15
+ private _clearPendingLazyPreviewCleanup;
16
+ private _refreshCursor;
17
+ private _scheduleLazyPreviewCleanup;
18
+ private _captureLazyPreviewCircle;
12
19
  preMouseDownCallback: (evt: EventTypes.MouseDownActivateEventType) => boolean;
13
20
  mouseMoveCallback: (evt: EventTypes.InteractionEventType) => void;
14
21
  previewCallback: () => void;