@cornerstonejs/tools 0.56.2 → 0.56.4
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.
- package/package.json +5 -4
- package/src/constants/COLOR_LUT.ts +262 -0
- package/src/constants/index.ts +3 -0
- package/src/cursors/ImageMouseCursor.ts +39 -0
- package/src/cursors/MouseCursor.ts +114 -0
- package/src/cursors/SVGCursorDescriptor.ts +462 -0
- package/src/cursors/SVGMouseCursor.ts +145 -0
- package/src/cursors/elementCursor.ts +69 -0
- package/src/cursors/index.ts +24 -0
- package/src/cursors/setCursorForElement.ts +33 -0
- package/src/drawingSvg/_getHash.ts +9 -0
- package/src/drawingSvg/_setAttributesIfNecessary.ts +13 -0
- package/src/drawingSvg/_setNewAttributesIfValid.ts +10 -0
- package/src/drawingSvg/clearByToolType.ts +26 -0
- package/src/drawingSvg/draw.ts +16 -0
- package/src/drawingSvg/drawArrow.ts +82 -0
- package/src/drawingSvg/drawCircle.ts +62 -0
- package/src/drawingSvg/drawEllipse.ts +71 -0
- package/src/drawingSvg/drawHandles.ts +87 -0
- package/src/drawingSvg/drawLine.ts +70 -0
- package/src/drawingSvg/drawLink.ts +76 -0
- package/src/drawingSvg/drawLinkedTextBox.ts +64 -0
- package/src/drawingSvg/drawPolyline.ts +80 -0
- package/src/drawingSvg/drawRect.ts +70 -0
- package/src/drawingSvg/drawTextBox.ts +213 -0
- package/src/drawingSvg/getSvgDrawingHelper.ts +98 -0
- package/src/drawingSvg/index.ts +23 -0
- package/src/enums/AnnotationStyleStates.ts +22 -0
- package/src/enums/Events.ts +242 -0
- package/src/enums/SegmentationRepresentations.ts +12 -0
- package/src/enums/ToolBindings.ts +37 -0
- package/src/enums/ToolModes.ts +31 -0
- package/src/enums/Touch.ts +8 -0
- package/src/enums/index.js +16 -0
- package/src/eventDispatchers/annotationModifiedEventDispatcher.ts +41 -0
- package/src/eventDispatchers/cameraModifiedEventDispatcher.ts +41 -0
- package/src/eventDispatchers/imageRenderedEventDispatcher.ts +37 -0
- package/src/eventDispatchers/imageSpacingCalibratedEventDispatcher.ts +50 -0
- package/src/eventDispatchers/index.js +15 -0
- package/src/eventDispatchers/keyboardEventHandlers/index.js +4 -0
- package/src/eventDispatchers/keyboardEventHandlers/keyDown.ts +29 -0
- package/src/eventDispatchers/keyboardEventHandlers/keyUp.ts +33 -0
- package/src/eventDispatchers/keyboardToolEventDispatcher.ts +28 -0
- package/src/eventDispatchers/mouseEventHandlers/index.js +19 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseClick.ts +13 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseDoubleClick.ts +13 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseDown.ts +196 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseDownActivate.ts +35 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseDrag.ts +25 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseMove.ts +70 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseUp.ts +9 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseWheel.ts +13 -0
- package/src/eventDispatchers/mouseToolEventDispatcher.ts +64 -0
- package/src/eventDispatchers/shared/customCallbackHandler.ts +73 -0
- package/src/eventDispatchers/shared/getActiveToolForKeyboardEvent.ts +58 -0
- package/src/eventDispatchers/shared/getActiveToolForMouseEvent.ts +61 -0
- package/src/eventDispatchers/shared/getActiveToolForTouchEvent.ts +64 -0
- package/src/eventDispatchers/shared/getMouseModifier.ts +30 -0
- package/src/eventDispatchers/shared/getToolsWithModesForMouseEvent.ts +56 -0
- package/src/eventDispatchers/shared/getToolsWithModesForTouchEvent.ts +54 -0
- package/src/eventDispatchers/touchEventHandlers/index.js +15 -0
- package/src/eventDispatchers/touchEventHandlers/touchDrag.ts +23 -0
- package/src/eventDispatchers/touchEventHandlers/touchEnd.ts +9 -0
- package/src/eventDispatchers/touchEventHandlers/touchPress.ts +13 -0
- package/src/eventDispatchers/touchEventHandlers/touchStart.ts +174 -0
- package/src/eventDispatchers/touchEventHandlers/touchStartActivate.ts +36 -0
- package/src/eventDispatchers/touchEventHandlers/touchTap.ts +9 -0
- package/src/eventDispatchers/touchToolEventDispatcher.ts +51 -0
- package/src/eventListeners/annotations/annotationModifiedListener.ts +22 -0
- package/src/eventListeners/annotations/annotationSelectionListener.ts +29 -0
- package/src/eventListeners/annotations/index.ts +4 -0
- package/src/eventListeners/index.ts +28 -0
- package/src/eventListeners/keyboard/index.ts +16 -0
- package/src/eventListeners/keyboard/keyDownListener.ts +99 -0
- package/src/eventListeners/mouse/getMouseEventPoints.ts +66 -0
- package/src/eventListeners/mouse/index.ts +55 -0
- package/src/eventListeners/mouse/mouseDoubleClickListener.ts +55 -0
- package/src/eventListeners/mouse/mouseDownListener.ts +519 -0
- package/src/eventListeners/mouse/mouseMoveListener.ts +33 -0
- package/src/eventListeners/segmentation/index.ts +11 -0
- package/src/eventListeners/segmentation/segmentationDataModifiedEventListener.ts +61 -0
- package/src/eventListeners/segmentation/segmentationModifiedEventListener.ts +32 -0
- package/src/eventListeners/segmentation/segmentationRepresentationModifiedEventListener.ts +15 -0
- package/src/eventListeners/segmentation/segmentationRepresentationRemovedEventListener.ts +16 -0
- package/src/eventListeners/touch/getTouchEventPoints.ts +75 -0
- package/src/eventListeners/touch/index.ts +37 -0
- package/src/eventListeners/touch/preventGhostClick.js +72 -0
- package/src/eventListeners/touch/touchStartListener.ts +499 -0
- package/src/eventListeners/wheel/index.ts +27 -0
- package/src/eventListeners/wheel/normalizeWheel.ts +69 -0
- package/src/eventListeners/wheel/wheelListener.ts +51 -0
- package/src/index.ts +133 -0
- package/src/init.ts +187 -0
- package/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts +399 -0
- package/src/stateManagement/annotation/annotationLocking.ts +178 -0
- package/src/stateManagement/annotation/annotationSelection.ts +163 -0
- package/src/stateManagement/annotation/annotationState.ts +180 -0
- package/src/stateManagement/annotation/annotationVisibility.ts +156 -0
- package/src/stateManagement/annotation/config/ToolStyle.ts +265 -0
- package/src/stateManagement/annotation/config/getFont.ts +36 -0
- package/src/stateManagement/annotation/config/getState.ts +26 -0
- package/src/stateManagement/annotation/config/helpers.ts +55 -0
- package/src/stateManagement/annotation/config/index.ts +5 -0
- package/src/stateManagement/annotation/helpers/state.ts +83 -0
- package/src/stateManagement/annotation/index.ts +15 -0
- package/src/stateManagement/index.js +40 -0
- package/src/stateManagement/segmentation/SegmentationStateManager.ts +491 -0
- package/src/stateManagement/segmentation/activeSegmentation.ts +60 -0
- package/src/stateManagement/segmentation/addSegmentationRepresentations.ts +77 -0
- package/src/stateManagement/segmentation/addSegmentations.ts +27 -0
- package/src/stateManagement/segmentation/config/index.ts +29 -0
- package/src/stateManagement/segmentation/config/segmentationColor.ts +132 -0
- package/src/stateManagement/segmentation/config/segmentationConfig.ts +195 -0
- package/src/stateManagement/segmentation/config/segmentationVisibility.ts +171 -0
- package/src/stateManagement/segmentation/helpers/index.ts +3 -0
- package/src/stateManagement/segmentation/helpers/normalizeSegmentationInput.ts +35 -0
- package/src/stateManagement/segmentation/helpers/validateSegmentationInput.ts +41 -0
- package/src/stateManagement/segmentation/index.ts +22 -0
- package/src/stateManagement/segmentation/removeSegmentationsFromToolGroup.ts +85 -0
- package/src/stateManagement/segmentation/segmentIndex.ts +38 -0
- package/src/stateManagement/segmentation/segmentLocking.ts +72 -0
- package/src/stateManagement/segmentation/segmentationState.ts +429 -0
- package/src/stateManagement/segmentation/triggerSegmentationEvents.ts +157 -0
- package/src/store/SynchronizerManager/Synchronizer.ts +344 -0
- package/src/store/SynchronizerManager/createSynchronizer.ts +41 -0
- package/src/store/SynchronizerManager/destroy.ts +14 -0
- package/src/store/SynchronizerManager/destroySynchronizer.ts +25 -0
- package/src/store/SynchronizerManager/getAllSynchronizers.ts +12 -0
- package/src/store/SynchronizerManager/getSynchronizer.ts +13 -0
- package/src/store/SynchronizerManager/getSynchronizersForViewport.ts +44 -0
- package/src/store/SynchronizerManager/index.js +15 -0
- package/src/store/ToolGroupManager/ToolGroup.ts +679 -0
- package/src/store/ToolGroupManager/createToolGroup.ts +33 -0
- package/src/store/ToolGroupManager/destroy.ts +24 -0
- package/src/store/ToolGroupManager/destroyToolGroup.ts +26 -0
- package/src/store/ToolGroupManager/getAllToolGroups.ts +12 -0
- package/src/store/ToolGroupManager/getToolGroup.ts +14 -0
- package/src/store/ToolGroupManager/getToolGroupForViewport.ts +44 -0
- package/src/store/ToolGroupManager/getToolGroupsWithToolName.ts +33 -0
- package/src/store/ToolGroupManager/index.ts +17 -0
- package/src/store/addEnabledElement.ts +137 -0
- package/src/store/addTool.ts +56 -0
- package/src/store/cancelActiveManipulations.ts +30 -0
- package/src/store/filterMoveableAnnotationTools.ts +61 -0
- package/src/store/filterToolsWithAnnotationsForElement.ts +51 -0
- package/src/store/filterToolsWithMoveableHandles.ts +51 -0
- package/src/store/index.ts +29 -0
- package/src/store/removeEnabledElement.ts +132 -0
- package/src/store/state.ts +57 -0
- package/src/store/svgNodeCache.ts +7 -0
- package/src/synchronizers/callbacks/areViewportsCoplanar .ts +12 -0
- package/src/synchronizers/callbacks/cameraSyncCallback.ts +33 -0
- package/src/synchronizers/callbacks/stackImageSyncCallback.ts +157 -0
- package/src/synchronizers/callbacks/voiSyncCallback.ts +51 -0
- package/src/synchronizers/callbacks/zoomPanSyncCallback.ts +43 -0
- package/src/synchronizers/index.ts +11 -0
- package/src/synchronizers/synchronizers/createCameraPositionSynchronizer.ts +25 -0
- package/src/synchronizers/synchronizers/createStackImageSynchronizer.ts +25 -0
- package/src/synchronizers/synchronizers/createVOISynchronizer.ts +24 -0
- package/src/synchronizers/synchronizers/createZoomPanSynchronizer.ts +25 -0
- package/src/synchronizers/synchronizers/index.ts +11 -0
- package/src/tools/CrosshairsTool.ts +2693 -0
- package/src/tools/MIPJumpToClickTool.ts +99 -0
- package/src/tools/MagnifyTool.ts +319 -0
- package/src/tools/PanTool.ts +58 -0
- package/src/tools/PlanarRotateTool.ts +77 -0
- package/src/tools/ReferenceCursors.ts +466 -0
- package/src/tools/ReferenceLinesTool.ts +279 -0
- package/src/tools/ScaleOverlayTool.ts +685 -0
- package/src/tools/StackScrollTool.ts +97 -0
- package/src/tools/StackScrollToolMouseWheelTool.ts +58 -0
- package/src/tools/TrackballRotateTool.ts +141 -0
- package/src/tools/VolumeRotateMouseWheelTool.ts +86 -0
- package/src/tools/WindowLevelTool.ts +260 -0
- package/src/tools/ZoomTool.ts +293 -0
- package/src/tools/annotation/AngleTool.ts +835 -0
- package/src/tools/annotation/ArrowAnnotateTool.ts +820 -0
- package/src/tools/annotation/BidirectionalTool.ts +1350 -0
- package/src/tools/annotation/CircleROITool.ts +1070 -0
- package/src/tools/annotation/CobbAngleTool.ts +815 -0
- package/src/tools/annotation/DragProbeTool.ts +213 -0
- package/src/tools/annotation/EllipticalROITool.ts +1223 -0
- package/src/tools/annotation/LengthTool.ts +861 -0
- package/src/tools/annotation/PlanarFreehandROITool.ts +636 -0
- package/src/tools/annotation/ProbeTool.ts +681 -0
- package/src/tools/annotation/RectangleROITool.ts +1028 -0
- package/src/tools/annotation/planarFreehandROITool/closedContourEditLoop.ts +488 -0
- package/src/tools/annotation/planarFreehandROITool/drawLoop.ts +462 -0
- package/src/tools/annotation/planarFreehandROITool/editLoopCommon.ts +331 -0
- package/src/tools/annotation/planarFreehandROITool/findOpenUShapedContourVectorToPeak.ts +74 -0
- package/src/tools/annotation/planarFreehandROITool/openContourEditLoop.ts +612 -0
- package/src/tools/annotation/planarFreehandROITool/openContourEndEditLoop.ts +74 -0
- package/src/tools/annotation/planarFreehandROITool/renderMethods.ts +407 -0
- package/src/tools/base/AnnotationDisplayTool.ts +228 -0
- package/src/tools/base/AnnotationTool.ts +307 -0
- package/src/tools/base/BaseTool.ts +215 -0
- package/src/tools/base/index.ts +4 -0
- package/src/tools/displayTools/Contour/addContourToElement.ts +135 -0
- package/src/tools/displayTools/Contour/contourDisplay.ts +252 -0
- package/src/tools/displayTools/Contour/index.ts +3 -0
- package/src/tools/displayTools/Contour/removeContourFromElement.ts +35 -0
- package/src/tools/displayTools/Labelmap/addLabelmapToElement.ts +57 -0
- package/src/tools/displayTools/Labelmap/index.ts +4 -0
- package/src/tools/displayTools/Labelmap/labelmapConfig.ts +37 -0
- package/src/tools/displayTools/Labelmap/labelmapDisplay.ts +461 -0
- package/src/tools/displayTools/Labelmap/removeLabelmapFromElement.ts +27 -0
- package/src/tools/displayTools/Labelmap/validateRepresentationData.ts +30 -0
- package/src/tools/displayTools/SegmentationDisplayTool.ts +198 -0
- package/src/tools/index.ts +84 -0
- package/src/tools/segmentation/BrushTool.ts +474 -0
- package/src/tools/segmentation/CircleScissorsTool.ts +365 -0
- package/src/tools/segmentation/PaintFillTool.ts +370 -0
- package/src/tools/segmentation/RectangleROIStartEndThresholdTool.ts +471 -0
- package/src/tools/segmentation/RectangleROIThresholdTool.ts +281 -0
- package/src/tools/segmentation/RectangleScissorsTool.ts +382 -0
- package/src/tools/segmentation/SphereScissorsTool.ts +368 -0
- package/src/tools/segmentation/strategies/eraseCircle.ts +30 -0
- package/src/tools/segmentation/strategies/eraseRectangle.ts +81 -0
- package/src/tools/segmentation/strategies/eraseSphere.ts +27 -0
- package/src/tools/segmentation/strategies/fillCircle.ts +185 -0
- package/src/tools/segmentation/strategies/fillRectangle.ts +110 -0
- package/src/tools/segmentation/strategies/fillSphere.ts +88 -0
- package/src/tools/segmentation/strategies/index.ts +9 -0
- package/src/types/AnnotationGroupSelector.ts +7 -0
- package/src/types/AnnotationStyle.ts +42 -0
- package/src/types/AnnotationTypes.ts +109 -0
- package/src/types/BoundsIJK.ts +5 -0
- package/src/types/CINETypes.ts +32 -0
- package/src/types/ContourTypes.ts +26 -0
- package/src/types/CursorTypes.ts +12 -0
- package/src/types/EventTypes.ts +657 -0
- package/src/types/FloodFillTypes.ts +19 -0
- package/src/types/IAnnotationManager.ts +89 -0
- package/src/types/IDistance.ts +16 -0
- package/src/types/IPoints.ts +18 -0
- package/src/types/ISetToolModeOptions.ts +29 -0
- package/src/types/ISynchronizerEventHandler.ts +11 -0
- package/src/types/IToolClassReference.ts +5 -0
- package/src/types/IToolGroup.ts +72 -0
- package/src/types/ITouchPoints.ts +14 -0
- package/src/types/InteractionTypes.ts +6 -0
- package/src/types/InternalToolTypes.ts +19 -0
- package/src/types/JumpToSliceOptions.ts +7 -0
- package/src/types/LabelmapTypes.ts +41 -0
- package/src/types/PlanarBoundingBox.ts +8 -0
- package/src/types/SVGDrawingHelper.ts +10 -0
- package/src/types/ScrollOptions.ts +9 -0
- package/src/types/SegmentationStateTypes.ts +248 -0
- package/src/types/ToolHandle.ts +26 -0
- package/src/types/ToolProps.ts +16 -0
- package/src/types/ToolSpecificAnnotationTypes.ts +311 -0
- package/src/types/index.ts +115 -0
- package/src/utilities/boundingBox/extend2DBoundingBoxInViewAxis.ts +29 -0
- package/src/utilities/boundingBox/getBoundingBoxAroundShape.ts +57 -0
- package/src/utilities/boundingBox/index.ts +4 -0
- package/src/utilities/calibrateImageSpacing.ts +46 -0
- package/src/utilities/cine/events.ts +9 -0
- package/src/utilities/cine/index.ts +5 -0
- package/src/utilities/cine/playClip.ts +435 -0
- package/src/utilities/cine/state.ts +18 -0
- package/src/utilities/clip.js +30 -0
- package/src/utilities/debounce.js +217 -0
- package/src/utilities/drawing/getTextBoxCoordsCanvas.ts +45 -0
- package/src/utilities/drawing/index.ts +3 -0
- package/src/utilities/dynamicVolume/getDataInTime.ts +110 -0
- package/src/utilities/dynamicVolume/index.ts +2 -0
- package/src/utilities/getAnnotationNearPoint.ts +130 -0
- package/src/utilities/getModalityUnit.ts +11 -0
- package/src/utilities/getToolsWithModesForElement.ts +52 -0
- package/src/utilities/index.ts +68 -0
- package/src/utilities/isObject.js +29 -0
- package/src/utilities/math/angle/angleBetweenLines.ts +29 -0
- package/src/utilities/math/circle/_types.ts +6 -0
- package/src/utilities/math/circle/getCanvasCircleCorners.ts +23 -0
- package/src/utilities/math/circle/getCanvasCircleRadius.ts +16 -0
- package/src/utilities/math/circle/index.ts +4 -0
- package/src/utilities/math/ellipse/getCanvasEllipseCorners.ts +26 -0
- package/src/utilities/math/ellipse/index.ts +4 -0
- package/src/utilities/math/ellipse/pointInEllipse.ts +38 -0
- package/src/utilities/math/ellipse/pointInEllipsoidWithConstraint.ts +35 -0
- package/src/utilities/math/index.ts +8 -0
- package/src/utilities/math/line/distanceToPoint.ts +24 -0
- package/src/utilities/math/line/distanceToPointSquared.ts +44 -0
- package/src/utilities/math/line/index.ts +5 -0
- package/src/utilities/math/line/intersectLine.ts +92 -0
- package/src/utilities/math/midPoint.ts +24 -0
- package/src/utilities/math/point/distanceToPoint.ts +22 -0
- package/src/utilities/math/point/index.ts +3 -0
- package/src/utilities/math/polyline/addCanvasPointsToArray.ts +62 -0
- package/src/utilities/math/polyline/calculateAreaOfPoints.ts +23 -0
- package/src/utilities/math/polyline/getIntersectionWithPolyline.ts +182 -0
- package/src/utilities/math/polyline/getSubPixelSpacingAndXYDirections.ts +99 -0
- package/src/utilities/math/polyline/index.ts +19 -0
- package/src/utilities/math/polyline/planarFreehandROIInternalTypes.ts +36 -0
- package/src/utilities/math/polyline/pointCanProjectOnLine.ts +57 -0
- package/src/utilities/math/polyline/pointsAreWithinCloseContourProximity.ts +15 -0
- package/src/utilities/math/rectangle/distanceToPoint.ts +82 -0
- package/src/utilities/math/rectangle/index.ts +3 -0
- package/src/utilities/math/sphere/index.ts +3 -0
- package/src/utilities/math/sphere/pointInSphere.ts +31 -0
- package/src/utilities/math/vec2/findClosestPoint.ts +40 -0
- package/src/utilities/math/vec2/index.ts +4 -0
- package/src/utilities/math/vec2/liangBarksyClip.ts +84 -0
- package/src/utilities/orientation/getOrientationStringLPS.ts +52 -0
- package/src/utilities/orientation/index.ts +4 -0
- package/src/utilities/orientation/invertOrientationStringLPS.ts +21 -0
- package/src/utilities/planar/filterAnnotationsForDisplay.ts +68 -0
- package/src/utilities/planar/filterAnnotationsWithinSlice.ts +85 -0
- package/src/utilities/planar/getPointInLineOfSightWithCriteria.ts +104 -0
- package/src/utilities/planar/getWorldWidthAndHeightFromCorners.ts +51 -0
- package/src/utilities/planar/getWorldWidthAndHeightFromTwoPoints.ts +51 -0
- package/src/utilities/planar/index.ts +18 -0
- package/src/utilities/planarFreehandROITool/index.ts +7 -0
- package/src/utilities/planarFreehandROITool/interpolateAnnotation.ts +87 -0
- package/src/utilities/planarFreehandROITool/interpolatePoints.ts +214 -0
- package/src/utilities/planarFreehandROITool/interpolation/algorithms/bspline.ts +55 -0
- package/src/utilities/planarFreehandROITool/interpolation/interpolateSegmentPoints.ts +90 -0
- package/src/utilities/pointInShapeCallback.ts +138 -0
- package/src/utilities/pointInSurroundingSphereCallback.ts +188 -0
- package/src/utilities/rectangleROITool/getBoundsIJKFromRectangleAnnotations.ts +76 -0
- package/src/utilities/rectangleROITool/index.ts +3 -0
- package/src/utilities/scroll.ts +62 -0
- package/src/utilities/segmentation/brushSizeForToolGroup.ts +72 -0
- package/src/utilities/segmentation/brushThresholdForToolGroup.ts +65 -0
- package/src/utilities/segmentation/createLabelmapVolumeForViewport.ts +74 -0
- package/src/utilities/segmentation/createMergedLabelmapForIndex.ts +65 -0
- package/src/utilities/segmentation/floodFill.ts +194 -0
- package/src/utilities/segmentation/getDefaultRepresentationConfig.ts +20 -0
- package/src/utilities/segmentation/index.ts +33 -0
- package/src/utilities/segmentation/isValidRepresentationConfig.ts +22 -0
- package/src/utilities/segmentation/rectangleROIThresholdVolumeByRange.ts +91 -0
- package/src/utilities/segmentation/thresholdSegmentationByRange.ts +129 -0
- package/src/utilities/segmentation/thresholdVolumeByRange.ts +150 -0
- package/src/utilities/segmentation/triggerSegmentationRender.ts +206 -0
- package/src/utilities/segmentation/utilities.ts +116 -0
- package/src/utilities/stackPrefetch/index.ts +8 -0
- package/src/utilities/stackPrefetch/stackPrefetch.ts +405 -0
- package/src/utilities/stackPrefetch/state.ts +17 -0
- package/src/utilities/throttle.js +69 -0
- package/src/utilities/touch/index.ts +246 -0
- package/src/utilities/triggerAnnotationRender.ts +237 -0
- package/src/utilities/triggerAnnotationRenderForViewportIds.ts +18 -0
- package/src/utilities/viewport/index.ts +5 -0
- package/src/utilities/viewport/isViewportPreScaled.ts +24 -0
- package/src/utilities/viewport/jumpToSlice.ts +73 -0
- package/src/utilities/viewport/jumpToWorld.ts +58 -0
- package/src/utilities/viewportFilters/filterViewportsWithFrameOfReferenceUID.ts +28 -0
- package/src/utilities/viewportFilters/filterViewportsWithParallelNormals.ts +26 -0
- package/src/utilities/viewportFilters/filterViewportsWithSameOrientation.ts +15 -0
- package/src/utilities/viewportFilters/filterViewportsWithToolEnabled.ts +72 -0
- package/src/utilities/viewportFilters/getViewportIdsWithToolToRender.ts +45 -0
- package/src/utilities/viewportFilters/index.ts +11 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
import vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunction';
|
|
2
|
+
import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
cache,
|
|
6
|
+
getEnabledElementByIds,
|
|
7
|
+
Types,
|
|
8
|
+
utilities,
|
|
9
|
+
} from '@cornerstonejs/core';
|
|
10
|
+
|
|
11
|
+
import Representations from '../../../enums/SegmentationRepresentations';
|
|
12
|
+
import * as SegmentationConfig from '../../../stateManagement/segmentation/config/segmentationConfig';
|
|
13
|
+
import * as SegmentationState from '../../../stateManagement/segmentation/segmentationState';
|
|
14
|
+
import { getToolGroup } from '../../../store/ToolGroupManager';
|
|
15
|
+
import type { LabelmapConfig } from '../../../types/LabelmapTypes';
|
|
16
|
+
import {
|
|
17
|
+
RepresentationPublicInput,
|
|
18
|
+
SegmentationRepresentationConfig,
|
|
19
|
+
ToolGroupSpecificRepresentation,
|
|
20
|
+
} from '../../../types/SegmentationStateTypes';
|
|
21
|
+
|
|
22
|
+
import addLabelmapToElement from './addLabelmapToElement';
|
|
23
|
+
|
|
24
|
+
import removeLabelmapFromElement from './removeLabelmapFromElement';
|
|
25
|
+
|
|
26
|
+
const MAX_NUMBER_COLORS = 255;
|
|
27
|
+
const labelMapConfigCache = new Map();
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* For each viewport, in the toolGroup it adds the segmentation labelmap
|
|
31
|
+
* representation to its viewports.
|
|
32
|
+
* @param toolGroup - the tool group that contains the viewports
|
|
33
|
+
* @param representationInput - The segmentation representation input
|
|
34
|
+
* @param toolGroupSpecificConfig - The configuration object for toolGroup
|
|
35
|
+
*
|
|
36
|
+
* @returns The UID of the new segmentation representation
|
|
37
|
+
*/
|
|
38
|
+
async function addSegmentationRepresentation(
|
|
39
|
+
toolGroupId: string,
|
|
40
|
+
representationInput: RepresentationPublicInput,
|
|
41
|
+
toolGroupSpecificConfig?: SegmentationRepresentationConfig
|
|
42
|
+
): Promise<string> {
|
|
43
|
+
const { segmentationId } = representationInput;
|
|
44
|
+
const segmentationRepresentationUID = utilities.uuidv4();
|
|
45
|
+
|
|
46
|
+
// Todo: make these configurable during representation input by user
|
|
47
|
+
const segmentsHidden = new Set() as Set<number>;
|
|
48
|
+
const colorLUTIndex = 0;
|
|
49
|
+
const active = true;
|
|
50
|
+
const cfun = vtkColorTransferFunction.newInstance();
|
|
51
|
+
const ofun = vtkPiecewiseFunction.newInstance();
|
|
52
|
+
|
|
53
|
+
ofun.addPoint(0, 0);
|
|
54
|
+
|
|
55
|
+
const toolGroupSpecificRepresentation: ToolGroupSpecificRepresentation = {
|
|
56
|
+
segmentationId,
|
|
57
|
+
segmentationRepresentationUID,
|
|
58
|
+
type: Representations.Labelmap,
|
|
59
|
+
segmentsHidden,
|
|
60
|
+
colorLUTIndex,
|
|
61
|
+
active,
|
|
62
|
+
segmentationRepresentationSpecificConfig: {},
|
|
63
|
+
segmentSpecificConfig: {},
|
|
64
|
+
config: {
|
|
65
|
+
cfun,
|
|
66
|
+
ofun,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// Update the toolGroup specific configuration
|
|
71
|
+
if (toolGroupSpecificConfig) {
|
|
72
|
+
// Since setting configuration on toolGroup will trigger a segmentationRepresentation
|
|
73
|
+
// update event, we don't want to trigger the event twice, so we suppress
|
|
74
|
+
// the first one
|
|
75
|
+
const currentToolGroupConfig =
|
|
76
|
+
SegmentationConfig.getToolGroupSpecificConfig(toolGroupId);
|
|
77
|
+
|
|
78
|
+
const mergedConfig = utilities.deepMerge(
|
|
79
|
+
currentToolGroupConfig,
|
|
80
|
+
toolGroupSpecificConfig
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
SegmentationConfig.setToolGroupSpecificConfig(toolGroupId, {
|
|
84
|
+
renderInactiveSegmentations:
|
|
85
|
+
mergedConfig.renderInactiveSegmentations || true,
|
|
86
|
+
representations: {
|
|
87
|
+
...mergedConfig.representations,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
SegmentationState.addSegmentationRepresentation(
|
|
93
|
+
toolGroupId,
|
|
94
|
+
toolGroupSpecificRepresentation
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
return segmentationRepresentationUID;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* For each viewport, and for each segmentation, set the segmentation for the viewport's enabled element
|
|
102
|
+
* Initializes the global and viewport specific state for the segmentation in the
|
|
103
|
+
* SegmentationStateManager.
|
|
104
|
+
* @param toolGroup - the tool group that contains the viewports
|
|
105
|
+
* @param segmentationRepresentationUID - The uid of the segmentation representation
|
|
106
|
+
* @param renderImmediate - If true, there will be a render call after the labelmap is removed
|
|
107
|
+
*/
|
|
108
|
+
function removeSegmentationRepresentation(
|
|
109
|
+
toolGroupId: string,
|
|
110
|
+
segmentationRepresentationUID: string,
|
|
111
|
+
renderImmediate = false
|
|
112
|
+
): void {
|
|
113
|
+
_removeLabelmapFromToolGroupViewports(
|
|
114
|
+
toolGroupId,
|
|
115
|
+
segmentationRepresentationUID
|
|
116
|
+
);
|
|
117
|
+
SegmentationState.removeSegmentationRepresentation(
|
|
118
|
+
toolGroupId,
|
|
119
|
+
segmentationRepresentationUID
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
if (renderImmediate) {
|
|
123
|
+
const viewportsInfo = getToolGroup(toolGroupId).getViewportsInfo();
|
|
124
|
+
viewportsInfo.forEach(({ viewportId, renderingEngineId }) => {
|
|
125
|
+
const enabledElement = getEnabledElementByIds(
|
|
126
|
+
viewportId,
|
|
127
|
+
renderingEngineId
|
|
128
|
+
);
|
|
129
|
+
enabledElement.viewport.render();
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* It takes the enabled element, the segmentation Id, and the configuration, and
|
|
136
|
+
* it sets the segmentation for the enabled element as a labelmap
|
|
137
|
+
* @param enabledElement - The cornerstone enabled element
|
|
138
|
+
* @param segmentationId - The id of the segmentation to be rendered.
|
|
139
|
+
* @param configuration - The configuration object for the labelmap.
|
|
140
|
+
*/
|
|
141
|
+
async function render(
|
|
142
|
+
viewport: Types.IVolumeViewport,
|
|
143
|
+
representation: ToolGroupSpecificRepresentation,
|
|
144
|
+
toolGroupConfig: SegmentationRepresentationConfig
|
|
145
|
+
): Promise<void> {
|
|
146
|
+
const {
|
|
147
|
+
colorLUTIndex,
|
|
148
|
+
active,
|
|
149
|
+
segmentationId,
|
|
150
|
+
segmentationRepresentationUID,
|
|
151
|
+
segmentsHidden,
|
|
152
|
+
config: renderingConfig,
|
|
153
|
+
} = representation;
|
|
154
|
+
|
|
155
|
+
const segmentation = SegmentationState.getSegmentation(segmentationId);
|
|
156
|
+
const labelmapData =
|
|
157
|
+
segmentation.representationData[Representations.Labelmap];
|
|
158
|
+
const { volumeId: labelmapUID } = labelmapData;
|
|
159
|
+
|
|
160
|
+
const labelmap = cache.getVolume(labelmapUID);
|
|
161
|
+
|
|
162
|
+
if (!labelmap) {
|
|
163
|
+
throw new Error(`No Labelmap found for volumeId: ${labelmapUID}`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
let actorEntry = viewport.getActor(segmentationRepresentationUID);
|
|
167
|
+
|
|
168
|
+
if (!actorEntry) {
|
|
169
|
+
const segmentation = SegmentationState.getSegmentation(segmentationId);
|
|
170
|
+
const { volumeId } =
|
|
171
|
+
segmentation.representationData[Representations.Labelmap];
|
|
172
|
+
// only add the labelmap to ToolGroup viewports if it is not already added
|
|
173
|
+
await _addLabelmapToViewport(
|
|
174
|
+
viewport,
|
|
175
|
+
volumeId,
|
|
176
|
+
segmentationRepresentationUID
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
actorEntry = viewport.getActor(segmentationRepresentationUID);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const { cfun, ofun } = renderingConfig;
|
|
183
|
+
|
|
184
|
+
const renderInactiveSegmentations =
|
|
185
|
+
toolGroupConfig.renderInactiveSegmentations;
|
|
186
|
+
|
|
187
|
+
_setLabelmapColorAndOpacity(
|
|
188
|
+
viewport.id,
|
|
189
|
+
actorEntry,
|
|
190
|
+
cfun,
|
|
191
|
+
ofun,
|
|
192
|
+
colorLUTIndex,
|
|
193
|
+
toolGroupConfig.representations[Representations.Labelmap],
|
|
194
|
+
representation,
|
|
195
|
+
active,
|
|
196
|
+
renderInactiveSegmentations,
|
|
197
|
+
segmentsHidden
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function _setLabelmapColorAndOpacity(
|
|
202
|
+
viewportId: string,
|
|
203
|
+
actorEntry: Types.ActorEntry,
|
|
204
|
+
cfun: vtkColorTransferFunction,
|
|
205
|
+
ofun: vtkPiecewiseFunction,
|
|
206
|
+
colorLUTIndex: number,
|
|
207
|
+
toolGroupLabelmapConfig: LabelmapConfig,
|
|
208
|
+
segmentationRepresentation: ToolGroupSpecificRepresentation,
|
|
209
|
+
isActiveLabelmap: boolean,
|
|
210
|
+
renderInactiveSegmentations: boolean,
|
|
211
|
+
segmentsHidden: Set<number>
|
|
212
|
+
): void {
|
|
213
|
+
const { segmentSpecificConfig, segmentationRepresentationSpecificConfig } =
|
|
214
|
+
segmentationRepresentation;
|
|
215
|
+
|
|
216
|
+
const segmentationRepresentationLabelmapConfig =
|
|
217
|
+
segmentationRepresentationSpecificConfig[Representations.Labelmap];
|
|
218
|
+
|
|
219
|
+
// Note: MAX_NUMBER_COLORS = 256 is needed because the current method to generate
|
|
220
|
+
// the default color table uses RGB.
|
|
221
|
+
const colorLUT = SegmentationState.getColorLUT(colorLUTIndex);
|
|
222
|
+
const numColors = Math.min(256, colorLUT.length);
|
|
223
|
+
const volumeActor = actorEntry.actor as Types.VolumeActor;
|
|
224
|
+
const { uid: actorUID } = actorEntry;
|
|
225
|
+
|
|
226
|
+
// Note: right now outlineWidth and renderOutline are not configurable
|
|
227
|
+
// at the segment level, so we don't need to check for segment specific
|
|
228
|
+
// configuration in the loop, Todo: make them configurable at the segment level
|
|
229
|
+
const { outlineWidth, renderOutline, outlineOpacity } = _getLabelmapConfig(
|
|
230
|
+
toolGroupLabelmapConfig,
|
|
231
|
+
segmentationRepresentationLabelmapConfig,
|
|
232
|
+
isActiveLabelmap
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
for (let i = 0; i < numColors; i++) {
|
|
236
|
+
const segmentIndex = i;
|
|
237
|
+
const segmentColor = colorLUT[segmentIndex];
|
|
238
|
+
|
|
239
|
+
const segmentSpecificLabelmapConfig =
|
|
240
|
+
segmentSpecificConfig[segmentIndex]?.[Representations.Labelmap];
|
|
241
|
+
|
|
242
|
+
const { fillAlpha, outlineWidth, renderFill, renderOutline } =
|
|
243
|
+
_getLabelmapConfig(
|
|
244
|
+
toolGroupLabelmapConfig,
|
|
245
|
+
segmentationRepresentationLabelmapConfig,
|
|
246
|
+
isActiveLabelmap,
|
|
247
|
+
segmentSpecificLabelmapConfig
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
const { forceOpacityUpdate, forceColorUpdate } =
|
|
251
|
+
_needsTransferFunctionUpdate(viewportId, actorUID, segmentIndex, {
|
|
252
|
+
fillAlpha,
|
|
253
|
+
renderFill,
|
|
254
|
+
renderOutline,
|
|
255
|
+
segmentColor,
|
|
256
|
+
outlineWidth,
|
|
257
|
+
segmentsHidden,
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
if (forceColorUpdate) {
|
|
261
|
+
cfun.addRGBPoint(
|
|
262
|
+
segmentIndex,
|
|
263
|
+
segmentColor[0] / MAX_NUMBER_COLORS,
|
|
264
|
+
segmentColor[1] / MAX_NUMBER_COLORS,
|
|
265
|
+
segmentColor[2] / MAX_NUMBER_COLORS
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (forceOpacityUpdate) {
|
|
270
|
+
if (renderFill) {
|
|
271
|
+
const segmentOpacity = segmentsHidden.has(segmentIndex)
|
|
272
|
+
? 0
|
|
273
|
+
: (segmentColor[3] / 255) * fillAlpha;
|
|
274
|
+
|
|
275
|
+
ofun.removePoint(segmentIndex);
|
|
276
|
+
ofun.addPointLong(segmentIndex, segmentOpacity, 0.5, 1.0);
|
|
277
|
+
} else {
|
|
278
|
+
ofun.addPointLong(segmentIndex, 0.01, 0.5, 1.0);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
volumeActor.getProperty().setRGBTransferFunction(0, cfun);
|
|
284
|
+
|
|
285
|
+
ofun.setClamping(false);
|
|
286
|
+
volumeActor.getProperty().setScalarOpacity(0, ofun);
|
|
287
|
+
|
|
288
|
+
volumeActor.getProperty().setInterpolationTypeToNearest();
|
|
289
|
+
|
|
290
|
+
volumeActor.getProperty().setUseLabelOutline(renderOutline);
|
|
291
|
+
|
|
292
|
+
// @ts-ignore: setLabelOutlineWidth is not in the vtk.d.ts apparently
|
|
293
|
+
volumeActor.getProperty().setLabelOutlineOpacity(outlineOpacity);
|
|
294
|
+
volumeActor.getProperty().setLabelOutlineThickness(outlineWidth);
|
|
295
|
+
|
|
296
|
+
// Set visibility based on whether actor visibility is specifically asked
|
|
297
|
+
// to be turned on/off (on by default) AND whether is is in active but
|
|
298
|
+
// we are rendering inactive labelmap
|
|
299
|
+
const visible = isActiveLabelmap || renderInactiveSegmentations;
|
|
300
|
+
volumeActor.setVisibility(visible);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function _getLabelmapConfig(
|
|
304
|
+
toolGroupLabelmapConfig: LabelmapConfig,
|
|
305
|
+
segmentationRepresentationLabelmapConfig: LabelmapConfig,
|
|
306
|
+
isActiveLabelmap: boolean,
|
|
307
|
+
segmentsLabelmapConfig?: LabelmapConfig
|
|
308
|
+
) {
|
|
309
|
+
const segmentLabelmapConfig = segmentsLabelmapConfig || {};
|
|
310
|
+
|
|
311
|
+
const configToUse = {
|
|
312
|
+
...toolGroupLabelmapConfig,
|
|
313
|
+
...segmentationRepresentationLabelmapConfig,
|
|
314
|
+
...segmentLabelmapConfig,
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
const fillAlpha = isActiveLabelmap
|
|
318
|
+
? configToUse.fillAlpha
|
|
319
|
+
: configToUse.fillAlphaInactive;
|
|
320
|
+
const outlineWidth = isActiveLabelmap
|
|
321
|
+
? configToUse.outlineWidthActive
|
|
322
|
+
: configToUse.outlineWidthInactive;
|
|
323
|
+
|
|
324
|
+
const renderFill = isActiveLabelmap
|
|
325
|
+
? configToUse.renderFill
|
|
326
|
+
: configToUse.renderFillInactive;
|
|
327
|
+
|
|
328
|
+
const renderOutline = configToUse.renderOutline;
|
|
329
|
+
|
|
330
|
+
const outlineOpacity = isActiveLabelmap
|
|
331
|
+
? configToUse.outlineOpacity
|
|
332
|
+
: configToUse.outlineOpacityInactive;
|
|
333
|
+
|
|
334
|
+
return {
|
|
335
|
+
fillAlpha,
|
|
336
|
+
outlineWidth,
|
|
337
|
+
renderFill,
|
|
338
|
+
renderOutline,
|
|
339
|
+
outlineOpacity,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function _needsTransferFunctionUpdate(
|
|
344
|
+
viewportId: string,
|
|
345
|
+
actorUID: string,
|
|
346
|
+
segmentIndex: number,
|
|
347
|
+
{
|
|
348
|
+
fillAlpha,
|
|
349
|
+
renderFill,
|
|
350
|
+
renderOutline,
|
|
351
|
+
segmentColor,
|
|
352
|
+
outlineWidth,
|
|
353
|
+
segmentsHidden,
|
|
354
|
+
}: {
|
|
355
|
+
fillAlpha: number;
|
|
356
|
+
renderFill: boolean;
|
|
357
|
+
renderOutline: boolean;
|
|
358
|
+
outlineWidth: number;
|
|
359
|
+
segmentColor: number[];
|
|
360
|
+
segmentsHidden: Set<number>;
|
|
361
|
+
}
|
|
362
|
+
) {
|
|
363
|
+
const cacheUID = `${viewportId}-${actorUID}-${segmentIndex}`;
|
|
364
|
+
const oldConfig = labelMapConfigCache.get(cacheUID);
|
|
365
|
+
|
|
366
|
+
if (!oldConfig) {
|
|
367
|
+
labelMapConfigCache.set(cacheUID, {
|
|
368
|
+
fillAlpha,
|
|
369
|
+
renderFill,
|
|
370
|
+
renderOutline,
|
|
371
|
+
outlineWidth,
|
|
372
|
+
segmentColor,
|
|
373
|
+
segmentsHidden: new Set(segmentsHidden), // Create a copy
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
return {
|
|
377
|
+
forceOpacityUpdate: true,
|
|
378
|
+
forceColorUpdate: true,
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const {
|
|
383
|
+
fillAlpha: oldFillAlpha,
|
|
384
|
+
renderFill: oldRenderFill,
|
|
385
|
+
renderOutline: oldRenderOutline,
|
|
386
|
+
outlineWidth: oldOutlineWidth,
|
|
387
|
+
segmentColor: oldSegmentColor,
|
|
388
|
+
segmentsHidden: oldSegmentsHidden,
|
|
389
|
+
} = oldConfig;
|
|
390
|
+
|
|
391
|
+
const forceColorUpdate =
|
|
392
|
+
oldSegmentColor[0] !== segmentColor[0] ||
|
|
393
|
+
oldSegmentColor[1] !== segmentColor[1] ||
|
|
394
|
+
oldSegmentColor[2] !== segmentColor[2];
|
|
395
|
+
|
|
396
|
+
const forceOpacityUpdate =
|
|
397
|
+
oldSegmentColor[3] !== segmentColor[3] ||
|
|
398
|
+
oldFillAlpha !== fillAlpha ||
|
|
399
|
+
oldRenderFill !== renderFill ||
|
|
400
|
+
oldRenderOutline !== renderOutline ||
|
|
401
|
+
oldOutlineWidth !== outlineWidth ||
|
|
402
|
+
oldSegmentsHidden.has(segmentIndex) !== segmentsHidden.has(segmentIndex);
|
|
403
|
+
|
|
404
|
+
// update the cache
|
|
405
|
+
labelMapConfigCache.set(cacheUID, {
|
|
406
|
+
fillAlpha,
|
|
407
|
+
renderFill,
|
|
408
|
+
renderOutline,
|
|
409
|
+
outlineWidth,
|
|
410
|
+
segmentColor,
|
|
411
|
+
segmentsHidden: new Set(segmentsHidden), // Create a copy
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
return {
|
|
415
|
+
forceOpacityUpdate,
|
|
416
|
+
forceColorUpdate,
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
function _removeLabelmapFromToolGroupViewports(
|
|
421
|
+
toolGroupId: string,
|
|
422
|
+
segmentationRepresentationUID: string
|
|
423
|
+
): void {
|
|
424
|
+
const toolGroup = getToolGroup(toolGroupId);
|
|
425
|
+
|
|
426
|
+
if (toolGroup === undefined) {
|
|
427
|
+
throw new Error(`ToolGroup with ToolGroupId ${toolGroupId} does not exist`);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const { viewportsInfo } = toolGroup;
|
|
431
|
+
|
|
432
|
+
for (const viewportInfo of viewportsInfo) {
|
|
433
|
+
const { viewportId, renderingEngineId } = viewportInfo;
|
|
434
|
+
const enabledElement = getEnabledElementByIds(
|
|
435
|
+
viewportId,
|
|
436
|
+
renderingEngineId
|
|
437
|
+
);
|
|
438
|
+
removeLabelmapFromElement(
|
|
439
|
+
enabledElement.viewport.element,
|
|
440
|
+
segmentationRepresentationUID
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
async function _addLabelmapToViewport(
|
|
446
|
+
viewport: Types.IVolumeViewport,
|
|
447
|
+
volumeId: string,
|
|
448
|
+
segmentationRepresentationUID: string
|
|
449
|
+
): Promise<void> {
|
|
450
|
+
await addLabelmapToElement(
|
|
451
|
+
viewport.element,
|
|
452
|
+
volumeId,
|
|
453
|
+
segmentationRepresentationUID
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
export default {
|
|
458
|
+
render,
|
|
459
|
+
addSegmentationRepresentation,
|
|
460
|
+
removeSegmentationRepresentation,
|
|
461
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getEnabledElement } from '@cornerstonejs/core';
|
|
2
|
+
import type { Types } from '@cornerstonejs/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Remove the labelmap segmentation representation from the viewport's HTML Element.
|
|
6
|
+
* NOTE: This function should not be called directly.
|
|
7
|
+
*
|
|
8
|
+
* @param element - The element that the segmentation is being added to.
|
|
9
|
+
* @param segmentationRepresentationUID - The UID of the labelmap representation to remove.
|
|
10
|
+
* @param removeFromCache - boolean
|
|
11
|
+
*
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
function removeLabelmapFromElement(
|
|
15
|
+
element: HTMLDivElement,
|
|
16
|
+
segmentationRepresentationUID: string,
|
|
17
|
+
removeFromCache = false // Todo
|
|
18
|
+
): void {
|
|
19
|
+
const enabledElement = getEnabledElement(element);
|
|
20
|
+
const { viewport } = enabledElement;
|
|
21
|
+
|
|
22
|
+
(viewport as Types.IVolumeViewport).removeVolumeActors([
|
|
23
|
+
segmentationRepresentationUID,
|
|
24
|
+
]);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default removeLabelmapFromElement;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { SegmentationPublicInput } from '../../../types/SegmentationStateTypes';
|
|
2
|
+
import { cache } from '@cornerstonejs/core';
|
|
3
|
+
import { LabelmapSegmentationData } from '../../../types/LabelmapTypes';
|
|
4
|
+
|
|
5
|
+
function validate(segmentationInput: SegmentationPublicInput): void {
|
|
6
|
+
if (!segmentationInput.representation.data) {
|
|
7
|
+
throw new Error(
|
|
8
|
+
'The segmentationInput.representationData.data is undefined, please provide a valid representationData.data'
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const representationData = segmentationInput.representation
|
|
13
|
+
.data as LabelmapSegmentationData;
|
|
14
|
+
|
|
15
|
+
if (!representationData.volumeId) {
|
|
16
|
+
throw new Error(
|
|
17
|
+
'The segmentationInput.representationData.volumeId is undefined, please provide a valid representationData.volumeId'
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const cachedVolume = cache.getVolume(representationData.volumeId);
|
|
22
|
+
|
|
23
|
+
if (!cachedVolume) {
|
|
24
|
+
throw new Error(
|
|
25
|
+
`volumeId of ${representationData.volumeId} not found in cache, you should load and cache volume before adding segmentation`
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default validate;
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getEnabledElementByIds,
|
|
3
|
+
Types,
|
|
4
|
+
utilities as csUtils,
|
|
5
|
+
} from '@cornerstonejs/core';
|
|
6
|
+
import Representations from '../../enums/SegmentationRepresentations';
|
|
7
|
+
import { config as segmentationConfig } from '../../stateManagement/segmentation';
|
|
8
|
+
import { setSegmentationVisibility } from '../../stateManagement/segmentation/config/segmentationVisibility';
|
|
9
|
+
import { getSegmentationRepresentations } from '../../stateManagement/segmentation/segmentationState';
|
|
10
|
+
import { getToolGroup } from '../../store/ToolGroupManager';
|
|
11
|
+
import { PublicToolProps, ToolProps } from '../../types';
|
|
12
|
+
import { BaseTool } from '../base';
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
SegmentationRepresentationConfig,
|
|
16
|
+
ToolGroupSpecificRepresentation,
|
|
17
|
+
} from '../../types/SegmentationStateTypes';
|
|
18
|
+
import { contourDisplay } from './Contour';
|
|
19
|
+
import { labelmapDisplay } from './Labelmap';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* In Cornerstone3DTools, displaying of segmentations are handled by the SegmentationDisplayTool.
|
|
23
|
+
* Generally, any Segmentation can be viewed in various representations such as
|
|
24
|
+
* labelmap (3d), contours, surface etc. As of now, Cornerstone3DTools only implements
|
|
25
|
+
* Labelmap representation.
|
|
26
|
+
*
|
|
27
|
+
* SegmentationDisplayTool works at ToolGroup level, and is responsible for displaying the
|
|
28
|
+
* segmentation representation for ALL viewports of a toolGroup, this way we can support complex
|
|
29
|
+
* scenarios for displaying segmentations.
|
|
30
|
+
*
|
|
31
|
+
* Current Limitations:
|
|
32
|
+
* - Only supports rendering of the volumetric segmentations in 3D space. (StackViewport segmentations are not supported yet)
|
|
33
|
+
* - Labelmap representation is the only supported representation for now.
|
|
34
|
+
*
|
|
35
|
+
* Similar to other tools in Cornerstone3DTools, the SegmentationDisplayTool should
|
|
36
|
+
* be added to the CornerstoneTools by calling cornerstoneTools.addTool(SegmentationDisplayTool)
|
|
37
|
+
* and a toolGroup should be created for it using the ToolGroupManager API, finally
|
|
38
|
+
* viewports information such as viewportId and renderingEngineId should be provided
|
|
39
|
+
* to the toolGroup and the SegmentationDisplayTool should be set to be activated.
|
|
40
|
+
*
|
|
41
|
+
*
|
|
42
|
+
*/
|
|
43
|
+
class SegmentationDisplayTool extends BaseTool {
|
|
44
|
+
static toolName;
|
|
45
|
+
constructor(
|
|
46
|
+
toolProps: PublicToolProps = {},
|
|
47
|
+
defaultToolProps: ToolProps = {
|
|
48
|
+
configuration: {},
|
|
49
|
+
}
|
|
50
|
+
) {
|
|
51
|
+
super(toolProps, defaultToolProps);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
onSetToolEnabled(): void {
|
|
55
|
+
const toolGroupId = this.toolGroupId;
|
|
56
|
+
const toolGroupSegmentationRepresentations =
|
|
57
|
+
getSegmentationRepresentations(toolGroupId);
|
|
58
|
+
|
|
59
|
+
if (
|
|
60
|
+
!toolGroupSegmentationRepresentations ||
|
|
61
|
+
toolGroupSegmentationRepresentations.length === 0
|
|
62
|
+
) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// for each segmentationData, make the visibility true
|
|
67
|
+
toolGroupSegmentationRepresentations.forEach(
|
|
68
|
+
(segmentationRepresentation) => {
|
|
69
|
+
setSegmentationVisibility(
|
|
70
|
+
toolGroupId,
|
|
71
|
+
segmentationRepresentation.segmentationRepresentationUID,
|
|
72
|
+
true
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
onSetToolDisabled(): void {
|
|
79
|
+
const toolGroupId = this.toolGroupId;
|
|
80
|
+
const toolGroupSegmentationRepresentations =
|
|
81
|
+
getSegmentationRepresentations(toolGroupId);
|
|
82
|
+
|
|
83
|
+
if (
|
|
84
|
+
!toolGroupSegmentationRepresentations ||
|
|
85
|
+
toolGroupSegmentationRepresentations.length === 0
|
|
86
|
+
) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// for each segmentationData, make the visibility false
|
|
91
|
+
toolGroupSegmentationRepresentations.forEach(
|
|
92
|
+
(segmentationRepresentation) => {
|
|
93
|
+
setSegmentationVisibility(
|
|
94
|
+
toolGroupId,
|
|
95
|
+
segmentationRepresentation.segmentationRepresentationUID,
|
|
96
|
+
false
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* It is used to trigger the render for each segmentations in the toolGroup.
|
|
104
|
+
* Based on the segmentation representation type, it will call the corresponding
|
|
105
|
+
* render function.
|
|
106
|
+
*
|
|
107
|
+
* @param toolGroupId - the toolGroupId
|
|
108
|
+
*/
|
|
109
|
+
renderSegmentation = (toolGroupId: string): void => {
|
|
110
|
+
const toolGroup = getToolGroup(toolGroupId);
|
|
111
|
+
|
|
112
|
+
if (!toolGroup) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const toolGroupSegmentationRepresentations =
|
|
117
|
+
getSegmentationRepresentations(toolGroupId);
|
|
118
|
+
|
|
119
|
+
if (
|
|
120
|
+
!toolGroupSegmentationRepresentations ||
|
|
121
|
+
toolGroupSegmentationRepresentations.length === 0
|
|
122
|
+
) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// toolGroup Viewports
|
|
127
|
+
const toolGroupViewports = toolGroup.viewportsInfo.map(
|
|
128
|
+
({ renderingEngineId, viewportId }) => {
|
|
129
|
+
const enabledElement = getEnabledElementByIds(
|
|
130
|
+
viewportId,
|
|
131
|
+
renderingEngineId
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
if (enabledElement) {
|
|
135
|
+
return enabledElement.viewport;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
// Render each segmentationData, in each viewport in the toolGroup
|
|
141
|
+
const segmentationRenderList = toolGroupSegmentationRepresentations.map(
|
|
142
|
+
(representation: ToolGroupSpecificRepresentation) => {
|
|
143
|
+
const config = this._getMergedRepresentationsConfig(toolGroupId);
|
|
144
|
+
|
|
145
|
+
const viewportsRenderList = [];
|
|
146
|
+
for (const viewport of toolGroupViewports) {
|
|
147
|
+
if (representation.type == Representations.Labelmap) {
|
|
148
|
+
viewportsRenderList.push(
|
|
149
|
+
labelmapDisplay.render(
|
|
150
|
+
viewport as Types.IVolumeViewport,
|
|
151
|
+
representation,
|
|
152
|
+
config
|
|
153
|
+
)
|
|
154
|
+
);
|
|
155
|
+
} else if (representation.type == Representations.Contour) {
|
|
156
|
+
viewportsRenderList.push(
|
|
157
|
+
contourDisplay.render(
|
|
158
|
+
viewport as Types.IVolumeViewport,
|
|
159
|
+
representation,
|
|
160
|
+
config
|
|
161
|
+
)
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return viewportsRenderList;
|
|
167
|
+
}
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
Promise.allSettled(segmentationRenderList).then(() => {
|
|
171
|
+
// for all viewports in the toolGroup trigger a re-render
|
|
172
|
+
toolGroupViewports.forEach((viewport) => {
|
|
173
|
+
viewport.render();
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Merge the toolGroup specific configuration with the default global configuration
|
|
180
|
+
* @param toolGroupId
|
|
181
|
+
* @returns
|
|
182
|
+
*/
|
|
183
|
+
_getMergedRepresentationsConfig(
|
|
184
|
+
toolGroupId: string
|
|
185
|
+
): SegmentationRepresentationConfig {
|
|
186
|
+
const toolGroupConfig =
|
|
187
|
+
segmentationConfig.getToolGroupSpecificConfig(toolGroupId);
|
|
188
|
+
const globalConfig = segmentationConfig.getGlobalConfig();
|
|
189
|
+
|
|
190
|
+
// merge two configurations and override the global config
|
|
191
|
+
const mergedConfig = csUtils.deepMerge(globalConfig, toolGroupConfig);
|
|
192
|
+
|
|
193
|
+
return mergedConfig;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
SegmentationDisplayTool.toolName = 'SegmentationDisplay';
|
|
198
|
+
export default SegmentationDisplayTool;
|