@cornerstonejs/tools 0.56.1 → 0.56.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/tools/CrosshairsTool.d.ts +1 -0
- package/dist/cjs/tools/CrosshairsTool.js +4 -1
- package/dist/cjs/tools/CrosshairsTool.js.map +1 -1
- package/dist/esm/tools/CrosshairsTool.d.ts +1 -0
- package/dist/esm/tools/CrosshairsTool.js +4 -1
- package/dist/esm/tools/CrosshairsTool.js.map +1 -1
- package/dist/umd/index.js +1 -1
- package/dist/umd/index.js.map +1 -1
- 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,188 @@
|
|
|
1
|
+
import { utilities as csUtils } from '@cornerstonejs/core';
|
|
2
|
+
import type { Types } from '@cornerstonejs/core';
|
|
3
|
+
|
|
4
|
+
import type { vtkImageData } from '@kitware/vtk.js/Common/DataModel/ImageData';
|
|
5
|
+
import { vec3 } from 'gl-matrix';
|
|
6
|
+
import { pointInSphere } from './math/sphere';
|
|
7
|
+
import pointInShapeCallback, {
|
|
8
|
+
PointInShapeCallback,
|
|
9
|
+
} from './pointInShapeCallback';
|
|
10
|
+
import { BoundsIJK } from '../types';
|
|
11
|
+
import { getBoundingBoxAroundShape } from './boundingBox';
|
|
12
|
+
|
|
13
|
+
const { transformWorldToIndex } = csUtils;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Given an imageData, and the great circle top and bottom points of a sphere,
|
|
17
|
+
* this function will run the callback for each point of the imageData that is
|
|
18
|
+
* within the sphere defined by the great circle points. If the viewport
|
|
19
|
+
* is provided, region of interest will be an accurate approximation of the
|
|
20
|
+
* sphere (using viewport camera), and the resulting performance will be
|
|
21
|
+
* better.
|
|
22
|
+
*
|
|
23
|
+
* @privateRemarks great circle also known as orthodrome is the intersection of
|
|
24
|
+
* the sphere and the plane that passes through the center of the sphere
|
|
25
|
+
*
|
|
26
|
+
* @param imageData - The volume imageData
|
|
27
|
+
* @param circlePoints - bottom and top points of the great circle in world coordinates
|
|
28
|
+
* @param callback - A callback function that will be called for each point in the shape.
|
|
29
|
+
*/
|
|
30
|
+
export default function pointInSurroundingSphereCallback(
|
|
31
|
+
imageData: vtkImageData,
|
|
32
|
+
circlePoints: [Types.Point3, Types.Point3],
|
|
33
|
+
callback: PointInShapeCallback,
|
|
34
|
+
viewport?: Types.IVolumeViewport
|
|
35
|
+
): void {
|
|
36
|
+
// We can run the sphere equation to determine if a point is inside
|
|
37
|
+
// the sphere; however, since the imageData dimensions can be quite large, we
|
|
38
|
+
// can narrow down the search by estimating the bounds of the sphere in index
|
|
39
|
+
// space.
|
|
40
|
+
const { boundsIJK, centerWorld, radiusWorld } = _getBounds(
|
|
41
|
+
circlePoints,
|
|
42
|
+
imageData,
|
|
43
|
+
viewport
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const sphereObj = {
|
|
47
|
+
center: centerWorld,
|
|
48
|
+
radius: radiusWorld,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
pointInShapeCallback(
|
|
52
|
+
imageData,
|
|
53
|
+
(pointLPS) => pointInSphere(sphereObj, pointLPS),
|
|
54
|
+
callback,
|
|
55
|
+
boundsIJK
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function _getBounds(
|
|
60
|
+
circlePoints: [Types.Point3, Types.Point3],
|
|
61
|
+
imageData: vtkImageData,
|
|
62
|
+
viewport
|
|
63
|
+
): {
|
|
64
|
+
boundsIJK: BoundsIJK;
|
|
65
|
+
centerWorld: Types.Point3;
|
|
66
|
+
radiusWorld: number;
|
|
67
|
+
} {
|
|
68
|
+
const [bottom, top] = circlePoints;
|
|
69
|
+
|
|
70
|
+
// Sphere center in world
|
|
71
|
+
const centerWorld = vec3.fromValues(
|
|
72
|
+
(bottom[0] + top[0]) / 2,
|
|
73
|
+
(bottom[1] + top[1]) / 2,
|
|
74
|
+
(bottom[2] + top[2]) / 2
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// sphere radius in world
|
|
78
|
+
const radiusWorld = vec3.distance(bottom, top) / 2;
|
|
79
|
+
|
|
80
|
+
let boundsIJK;
|
|
81
|
+
|
|
82
|
+
if (!viewport) {
|
|
83
|
+
// If no viewport is provide (no camera), we can estimate the bounding box
|
|
84
|
+
// of the sphere in index space.
|
|
85
|
+
// This is done by calculating the maximum value for radius in the index
|
|
86
|
+
// space (since the radius is in world space, we need to convert it to index, and
|
|
87
|
+
// each dimensions can have a different scale factor). Therefore, by finding
|
|
88
|
+
// the minimum spacing value in the imageData, we can calculate the maximum
|
|
89
|
+
// radius in index space and use that to calculate the bounds of the sphere
|
|
90
|
+
// This will not be accurate, but it is a good first approximation.
|
|
91
|
+
// sphere center in index
|
|
92
|
+
const centerIJK = transformWorldToIndex(
|
|
93
|
+
imageData,
|
|
94
|
+
centerWorld as Types.Point3
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const spacings = imageData.getSpacing();
|
|
98
|
+
const minSpacing = Math.min(...spacings);
|
|
99
|
+
|
|
100
|
+
const maxRadiusIJK = Math.ceil(radiusWorld / minSpacing);
|
|
101
|
+
|
|
102
|
+
boundsIJK = [
|
|
103
|
+
[centerIJK[0] - maxRadiusIJK, centerIJK[0] + maxRadiusIJK],
|
|
104
|
+
[centerIJK[1] - maxRadiusIJK, centerIJK[1] + maxRadiusIJK],
|
|
105
|
+
[centerIJK[2] - maxRadiusIJK, centerIJK[2] + maxRadiusIJK],
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
boundsIJK,
|
|
110
|
+
centerWorld: centerWorld as Types.Point3,
|
|
111
|
+
radiusWorld,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
boundsIJK = _computeBoundsIJKWithCamera(
|
|
116
|
+
imageData,
|
|
117
|
+
viewport,
|
|
118
|
+
circlePoints,
|
|
119
|
+
centerWorld,
|
|
120
|
+
radiusWorld
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
boundsIJK,
|
|
125
|
+
centerWorld: centerWorld as Types.Point3,
|
|
126
|
+
radiusWorld,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function _computeBoundsIJKWithCamera(
|
|
131
|
+
imageData,
|
|
132
|
+
viewport,
|
|
133
|
+
circlePoints,
|
|
134
|
+
centerWorld,
|
|
135
|
+
radiusWorld
|
|
136
|
+
) {
|
|
137
|
+
const [bottom, top] = circlePoints;
|
|
138
|
+
|
|
139
|
+
const dimensions = imageData.getDimensions() as Types.Point3;
|
|
140
|
+
const camera = viewport.getCamera();
|
|
141
|
+
|
|
142
|
+
// Calculate viewRight from the camera, this will get used in order to
|
|
143
|
+
// calculate circles topLeft and bottomRight on different planes of intersection
|
|
144
|
+
// between sphere and viewPlane
|
|
145
|
+
const viewUp = vec3.fromValues(
|
|
146
|
+
camera.viewUp[0],
|
|
147
|
+
camera.viewUp[1],
|
|
148
|
+
camera.viewUp[2]
|
|
149
|
+
);
|
|
150
|
+
const viewPlaneNormal = vec3.fromValues(
|
|
151
|
+
camera.viewPlaneNormal[0],
|
|
152
|
+
camera.viewPlaneNormal[1],
|
|
153
|
+
camera.viewPlaneNormal[2]
|
|
154
|
+
);
|
|
155
|
+
const viewRight = vec3.create();
|
|
156
|
+
|
|
157
|
+
vec3.cross(viewRight, viewUp, viewPlaneNormal);
|
|
158
|
+
|
|
159
|
+
// we need to find the bounding box of the sphere in the image, e.g., the
|
|
160
|
+
// topLeftWorld and bottomRightWorld points of the bounding box.
|
|
161
|
+
// We go from the sphereCenter in the normal direction of amount radius, and
|
|
162
|
+
// we go left to find the topLeftWorld point of the bounding box. Next we go
|
|
163
|
+
// in the opposite direction and go right to find the bottomRightWorld point
|
|
164
|
+
// of the bounding box.
|
|
165
|
+
const topLeftWorld = vec3.create();
|
|
166
|
+
const bottomRightWorld = vec3.create();
|
|
167
|
+
|
|
168
|
+
vec3.scaleAndAdd(topLeftWorld, top, viewPlaneNormal, radiusWorld);
|
|
169
|
+
vec3.scaleAndAdd(bottomRightWorld, bottom, viewPlaneNormal, -radiusWorld);
|
|
170
|
+
|
|
171
|
+
// go in the direction of viewRight with the value of radius
|
|
172
|
+
vec3.scaleAndAdd(topLeftWorld, topLeftWorld, viewRight, -radiusWorld);
|
|
173
|
+
vec3.scaleAndAdd(bottomRightWorld, bottomRightWorld, viewRight, radiusWorld);
|
|
174
|
+
|
|
175
|
+
// convert the world coordinates to index coordinates
|
|
176
|
+
|
|
177
|
+
const sphereCornersIJK = [
|
|
178
|
+
<Types.Point3>transformWorldToIndex(imageData, <Types.Point3>topLeftWorld),
|
|
179
|
+
<Types.Point3>(
|
|
180
|
+
transformWorldToIndex(imageData, <Types.Point3>bottomRightWorld)
|
|
181
|
+
),
|
|
182
|
+
];
|
|
183
|
+
|
|
184
|
+
// get the bounding box of the sphere in the image
|
|
185
|
+
const boundsIJK = getBoundingBoxAroundShape(sphereCornersIJK, dimensions);
|
|
186
|
+
|
|
187
|
+
return boundsIJK;
|
|
188
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { utilities as csUtils } from '@cornerstonejs/core';
|
|
2
|
+
import type { Types } from '@cornerstonejs/core';
|
|
3
|
+
import getBoundingBoxAroundShape from '../boundingBox/getBoundingBoxAroundShape';
|
|
4
|
+
import extend2DBoundingBoxInViewAxis from '../boundingBox/extend2DBoundingBoxInViewAxis';
|
|
5
|
+
|
|
6
|
+
type Options = {
|
|
7
|
+
numSlicesToProject?: number;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
function getBoundsIJKFromRectangleAnnotations(
|
|
11
|
+
annotations,
|
|
12
|
+
referenceVolume,
|
|
13
|
+
options = {} as Options
|
|
14
|
+
) {
|
|
15
|
+
const AllBoundsIJK = [];
|
|
16
|
+
annotations.forEach((annotation) => {
|
|
17
|
+
const { data } = annotation;
|
|
18
|
+
const { points } = data.handles;
|
|
19
|
+
|
|
20
|
+
const { imageData, dimensions } = referenceVolume;
|
|
21
|
+
|
|
22
|
+
let pointsToUse = points;
|
|
23
|
+
// If the tool is a 2D tool but has projection points, use them
|
|
24
|
+
if (data.cachedStats?.projectionPoints) {
|
|
25
|
+
const { projectionPoints } = data.cachedStats;
|
|
26
|
+
pointsToUse = [].concat(...projectionPoints); // cannot use flat() because of typescript compiler right now
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const rectangleCornersIJK = pointsToUse.map(
|
|
30
|
+
(world) => csUtils.transformWorldToIndex(imageData, world) as Types.Point3
|
|
31
|
+
);
|
|
32
|
+
let boundsIJK = getBoundingBoxAroundShape(rectangleCornersIJK, dimensions);
|
|
33
|
+
|
|
34
|
+
// If the tool is 2D but it is configured to project to X amount of slices
|
|
35
|
+
// Don't project the slices if projectionPoints have been used to define the extents
|
|
36
|
+
if (options.numSlicesToProject && !data.cachedStats?.projectionPoints) {
|
|
37
|
+
boundsIJK = extend2DBoundingBoxInViewAxis(
|
|
38
|
+
boundsIJK,
|
|
39
|
+
options.numSlicesToProject
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
AllBoundsIJK.push(boundsIJK);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
if (AllBoundsIJK.length === 1) {
|
|
47
|
+
return AllBoundsIJK[0];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Get the intersection of all the bounding boxes
|
|
51
|
+
// This is the bounding box that contains all the ROIs
|
|
52
|
+
const boundsIJK = AllBoundsIJK.reduce(
|
|
53
|
+
(accumulator, currentValue) => {
|
|
54
|
+
return {
|
|
55
|
+
iMin: Math.min(accumulator.iMin, currentValue.iMin),
|
|
56
|
+
jMin: Math.min(accumulator.jMin, currentValue.jMin),
|
|
57
|
+
kMin: Math.min(accumulator.kMin, currentValue.kMin),
|
|
58
|
+
iMax: Math.max(accumulator.iMax, currentValue.iMax),
|
|
59
|
+
jMax: Math.max(accumulator.jMax, currentValue.jMax),
|
|
60
|
+
kMax: Math.max(accumulator.kMax, currentValue.kMax),
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
iMin: Infinity,
|
|
65
|
+
jMin: Infinity,
|
|
66
|
+
kMin: Infinity,
|
|
67
|
+
iMax: -Infinity,
|
|
68
|
+
jMax: -Infinity,
|
|
69
|
+
kMax: -Infinity,
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
return boundsIJK;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default getBoundsIJKFromRectangleAnnotations;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {
|
|
2
|
+
StackViewport,
|
|
3
|
+
Types,
|
|
4
|
+
VolumeViewport,
|
|
5
|
+
utilities as csUtils,
|
|
6
|
+
} from '@cornerstonejs/core';
|
|
7
|
+
import { ScrollOptions } from '../types';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* It scrolls one slice in the Stack or Volume Viewport, it uses the options provided
|
|
11
|
+
* to determine the slice to scroll to. For Stack Viewport, it scrolls in the 1 or -1
|
|
12
|
+
* direction, for Volume Viewport, it uses the camera and focal point to determine the
|
|
13
|
+
* slice to scroll to based on the spacings.
|
|
14
|
+
* @param viewport - The viewport in which to scroll
|
|
15
|
+
* @param options - Options to use for scrolling, including direction, invert, and volumeId
|
|
16
|
+
* @returns
|
|
17
|
+
*/
|
|
18
|
+
export default function scroll(
|
|
19
|
+
viewport: Types.IStackViewport | Types.IVolumeViewport,
|
|
20
|
+
options: ScrollOptions
|
|
21
|
+
): void {
|
|
22
|
+
const { type: viewportType } = viewport;
|
|
23
|
+
const { volumeId, delta } = options;
|
|
24
|
+
|
|
25
|
+
if (viewport instanceof StackViewport) {
|
|
26
|
+
viewport.scroll(delta, options.debounceLoading, options.loop);
|
|
27
|
+
} else if (viewport instanceof VolumeViewport) {
|
|
28
|
+
scrollVolume(viewport, volumeId, delta);
|
|
29
|
+
} else {
|
|
30
|
+
throw new Error(`Not implemented for Viewport Type: ${viewportType}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function scrollVolume(
|
|
35
|
+
viewport: VolumeViewport,
|
|
36
|
+
volumeId: string,
|
|
37
|
+
delta: number
|
|
38
|
+
) {
|
|
39
|
+
const sliceRangeInfo = csUtils.getVolumeSliceRangeInfo(viewport, volumeId);
|
|
40
|
+
|
|
41
|
+
if (!sliceRangeInfo) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const { sliceRange, spacingInNormalDirection, camera } = sliceRangeInfo;
|
|
46
|
+
const { focalPoint, viewPlaneNormal, position } = camera;
|
|
47
|
+
|
|
48
|
+
const { newFocalPoint, newPosition } = csUtils.snapFocalPointToSlice(
|
|
49
|
+
focalPoint,
|
|
50
|
+
position,
|
|
51
|
+
sliceRange,
|
|
52
|
+
viewPlaneNormal,
|
|
53
|
+
spacingInNormalDirection,
|
|
54
|
+
delta
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
viewport.setCamera({
|
|
58
|
+
focalPoint: newFocalPoint,
|
|
59
|
+
position: newPosition,
|
|
60
|
+
});
|
|
61
|
+
viewport.render();
|
|
62
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { getToolGroup } from '../../store/ToolGroupManager';
|
|
2
|
+
import BrushTool from '../../tools/segmentation/BrushTool';
|
|
3
|
+
import triggerAnnotationRenderForViewportIds from '../triggerAnnotationRenderForViewportIds';
|
|
4
|
+
import { getRenderingEngine } from '@cornerstonejs/core';
|
|
5
|
+
import getBrushToolInstances from './utilities';
|
|
6
|
+
|
|
7
|
+
export function setBrushSizeForToolGroup(
|
|
8
|
+
toolGroupId: string,
|
|
9
|
+
brushSize: number
|
|
10
|
+
): void {
|
|
11
|
+
const toolGroup = getToolGroup(toolGroupId);
|
|
12
|
+
|
|
13
|
+
if (toolGroup === undefined) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const brushBasedToolInstances = getBrushToolInstances(toolGroupId);
|
|
18
|
+
|
|
19
|
+
brushBasedToolInstances.forEach((tool: BrushTool) => {
|
|
20
|
+
tool.configuration.brushSize = brushSize;
|
|
21
|
+
|
|
22
|
+
// Invalidate the brush being rendered so it can update.
|
|
23
|
+
tool.invalidateBrushCursor();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Trigger an annotation render for any viewports on the toolgroup
|
|
27
|
+
const viewportsInfo = toolGroup.getViewportsInfo();
|
|
28
|
+
|
|
29
|
+
const viewportsInfoArray = Object.keys(viewportsInfo).map(
|
|
30
|
+
(key) => viewportsInfo[key]
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
if (!viewportsInfoArray.length) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const { renderingEngineId } = viewportsInfoArray[0];
|
|
38
|
+
|
|
39
|
+
// Use helper to get array of viewportIds, or we just end up doing this mapping
|
|
40
|
+
// ourselves here.
|
|
41
|
+
const viewportIds = toolGroup.getViewportIds();
|
|
42
|
+
|
|
43
|
+
const renderingEngine = getRenderingEngine(renderingEngineId);
|
|
44
|
+
|
|
45
|
+
triggerAnnotationRenderForViewportIds(renderingEngine, viewportIds);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function getBrushSizeForToolGroup(toolGroupId: string): void {
|
|
49
|
+
const toolGroup = getToolGroup(toolGroupId);
|
|
50
|
+
|
|
51
|
+
if (toolGroup === undefined) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const toolInstances = toolGroup._toolInstances;
|
|
56
|
+
|
|
57
|
+
if (!Object.keys(toolInstances).length) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const brushBasedToolInstances = getBrushToolInstances(toolGroupId);
|
|
62
|
+
|
|
63
|
+
// one is enough as they share the same brush size
|
|
64
|
+
const brushToolInstance = brushBasedToolInstances[0];
|
|
65
|
+
|
|
66
|
+
if (!brushToolInstance) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// TODO -> Assumes the brush sizes are the same and set via these helpers.
|
|
71
|
+
return brushToolInstance.configuration.brushSize;
|
|
72
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Types } from '@cornerstonejs/core';
|
|
2
|
+
import { getToolGroup } from '../../store/ToolGroupManager';
|
|
3
|
+
import triggerAnnotationRenderForViewportIds from '../triggerAnnotationRenderForViewportIds';
|
|
4
|
+
import { getRenderingEngine } from '@cornerstonejs/core';
|
|
5
|
+
import getBrushToolInstances from './utilities';
|
|
6
|
+
|
|
7
|
+
export function setBrushThresholdForToolGroup(
|
|
8
|
+
toolGroupId: string,
|
|
9
|
+
threshold: Types.Point2
|
|
10
|
+
) {
|
|
11
|
+
const toolGroup = getToolGroup(toolGroupId);
|
|
12
|
+
|
|
13
|
+
if (toolGroup === undefined) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const brushBasedToolInstances = getBrushToolInstances(toolGroupId);
|
|
18
|
+
|
|
19
|
+
brushBasedToolInstances.forEach((tool) => {
|
|
20
|
+
tool.configuration.strategySpecificConfiguration.THRESHOLD_INSIDE_CIRCLE.threshold =
|
|
21
|
+
threshold;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Trigger an annotation render for any viewports on the toolgroup
|
|
25
|
+
const viewportsInfo = toolGroup.getViewportsInfo();
|
|
26
|
+
|
|
27
|
+
if (!viewportsInfo.length) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const { renderingEngineId } = viewportsInfo[0];
|
|
32
|
+
|
|
33
|
+
// Use helper to get array of viewportIds, or we just end up doing this mapping
|
|
34
|
+
// ourselves here.
|
|
35
|
+
const viewportIds = toolGroup.getViewportIds();
|
|
36
|
+
|
|
37
|
+
const renderingEngine = getRenderingEngine(renderingEngineId);
|
|
38
|
+
|
|
39
|
+
triggerAnnotationRenderForViewportIds(renderingEngine, viewportIds);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function getBrushThresholdForToolGroup(toolGroupId: string) {
|
|
43
|
+
const toolGroup = getToolGroup(toolGroupId);
|
|
44
|
+
|
|
45
|
+
if (toolGroup === undefined) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const toolInstances = toolGroup._toolInstances;
|
|
50
|
+
|
|
51
|
+
if (!Object.keys(toolInstances).length) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const brushBasedToolInstances = getBrushToolInstances(toolGroupId);
|
|
56
|
+
const brushToolInstance = brushBasedToolInstances[0];
|
|
57
|
+
|
|
58
|
+
if (!brushToolInstance) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// TODO -> Assumes the
|
|
63
|
+
return brushToolInstance.configuration.strategySpecificConfiguration
|
|
64
|
+
.THRESHOLD_INSIDE_CIRCLE.threshold;
|
|
65
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { _cloneDeep } from 'lodash.clonedeep';
|
|
2
|
+
import {
|
|
3
|
+
getEnabledElementByIds,
|
|
4
|
+
volumeLoader,
|
|
5
|
+
VolumeViewport,
|
|
6
|
+
utilities as csUtils,
|
|
7
|
+
} from '@cornerstonejs/core';
|
|
8
|
+
import type { Types } from '@cornerstonejs/core';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Create a new 3D segmentation volume from the default imageData presented in
|
|
12
|
+
* the first actor of the viewport. It looks at the metadata of the imageData
|
|
13
|
+
* to determine the volume dimensions and spacing if particular options are not provided.
|
|
14
|
+
*
|
|
15
|
+
* @param viewportId - The Id of the viewport from which to derive the volume from.
|
|
16
|
+
* @param renderingEngineId - The Id of the rendering engine the viewport belongs to.
|
|
17
|
+
* @param [segmentationId] - The Id to name the generated segmentation. Autogenerated if not given.
|
|
18
|
+
* @param [options] - LabelmapOptions
|
|
19
|
+
* @returns A promise that resolves to the Id of the new labelmap volume.
|
|
20
|
+
*/
|
|
21
|
+
export default async function createLabelmapVolumeForViewport(input: {
|
|
22
|
+
viewportId: string;
|
|
23
|
+
renderingEngineId: string;
|
|
24
|
+
segmentationId?: string;
|
|
25
|
+
options?: {
|
|
26
|
+
volumeId?: string;
|
|
27
|
+
scalarData?: Float32Array | Uint8Array | Uint16Array | Int16Array;
|
|
28
|
+
targetBuffer?: {
|
|
29
|
+
type: 'Float32Array' | 'Uint8Array' | 'Uint16Array' | 'Int8Array';
|
|
30
|
+
};
|
|
31
|
+
metadata?: any;
|
|
32
|
+
dimensions?: Types.Point3;
|
|
33
|
+
spacing?: Types.Point3;
|
|
34
|
+
origin?: Types.Point3;
|
|
35
|
+
direction?: Float32Array;
|
|
36
|
+
};
|
|
37
|
+
}): Promise<string> {
|
|
38
|
+
const { viewportId, renderingEngineId, options } = input;
|
|
39
|
+
let { segmentationId } = input;
|
|
40
|
+
const enabledElement = getEnabledElementByIds(viewportId, renderingEngineId);
|
|
41
|
+
|
|
42
|
+
if (!enabledElement) {
|
|
43
|
+
throw new Error('element disabled');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const { viewport } = enabledElement;
|
|
47
|
+
if (!(viewport instanceof VolumeViewport)) {
|
|
48
|
+
throw new Error('Segmentation only supports VolumeViewport');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const { uid } = viewport.getDefaultActor();
|
|
52
|
+
|
|
53
|
+
if (segmentationId === undefined) {
|
|
54
|
+
// Name the segmentation volume with the viewport Id
|
|
55
|
+
segmentationId = `${uid}-based-segmentation-${
|
|
56
|
+
options?.volumeId ?? csUtils.uuidv4().slice(0, 8)
|
|
57
|
+
}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (options) {
|
|
61
|
+
// create a new labelmap with its own properties
|
|
62
|
+
// This allows creation of a higher resolution labelmap vs reference volume
|
|
63
|
+
const properties = _cloneDeep(options);
|
|
64
|
+
await volumeLoader.createLocalVolume(properties, segmentationId);
|
|
65
|
+
} else {
|
|
66
|
+
// create a labelmap from a reference volume
|
|
67
|
+
const { uid: volumeId } = viewport.getDefaultActor();
|
|
68
|
+
await volumeLoader.createAndCacheDerivedVolume(volumeId, {
|
|
69
|
+
volumeId: segmentationId,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return segmentationId;
|
|
74
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Types } from '@cornerstonejs/core';
|
|
2
|
+
import { volumeLoader, utilities as csUtils } from '@cornerstonejs/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Given a list of labelmaps (with the possibility of overlapping regions), and
|
|
6
|
+
* a segmentIndex it creates a new labelmap with the same dimensions as the input labelmaps,
|
|
7
|
+
* but merges them into a single labelmap for the segmentIndex. It wipes out
|
|
8
|
+
* all other segment Indices. This is useful for calculating statistics regarding
|
|
9
|
+
* a specific segment when there are overlapping regions between labelmap (e.g. TMTV)
|
|
10
|
+
*
|
|
11
|
+
* @param labelmaps - Array of labelmaps
|
|
12
|
+
* @param segmentIndex - The segment index to merge
|
|
13
|
+
* @returns Merged labelmap
|
|
14
|
+
*/
|
|
15
|
+
function createMergedLabelmapForIndex(
|
|
16
|
+
labelmaps: Array<Types.IImageVolume>,
|
|
17
|
+
segmentIndex = 1,
|
|
18
|
+
volumeId = 'mergedLabelmap'
|
|
19
|
+
): Types.IImageVolume {
|
|
20
|
+
labelmaps.forEach(({ direction, dimensions, origin, spacing }) => {
|
|
21
|
+
if (
|
|
22
|
+
!csUtils.isEqual(dimensions, labelmaps[0].dimensions) ||
|
|
23
|
+
!csUtils.isEqual(direction, labelmaps[0].direction) ||
|
|
24
|
+
!csUtils.isEqual(spacing, labelmaps[0].spacing) ||
|
|
25
|
+
!csUtils.isEqual(origin, labelmaps[0].origin)
|
|
26
|
+
) {
|
|
27
|
+
throw new Error('labelmaps must have the same size and shape');
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const labelmap = labelmaps[0];
|
|
32
|
+
|
|
33
|
+
const arrayType = (labelmap.getScalarData() as any).constructor;
|
|
34
|
+
const outputData = new arrayType(labelmap.getScalarData().length);
|
|
35
|
+
|
|
36
|
+
labelmaps.forEach((labelmap) => {
|
|
37
|
+
const scalarData = labelmap.getScalarData();
|
|
38
|
+
for (let i = 0; i < scalarData.length; i++) {
|
|
39
|
+
if (scalarData[i] === segmentIndex) {
|
|
40
|
+
outputData[i] = segmentIndex;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const options = {
|
|
46
|
+
scalarData: outputData,
|
|
47
|
+
metadata: labelmap.metadata,
|
|
48
|
+
spacing: labelmap.spacing,
|
|
49
|
+
origin: labelmap.origin,
|
|
50
|
+
direction: labelmap.direction,
|
|
51
|
+
dimensions: labelmap.dimensions,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const preventCache = true;
|
|
55
|
+
// Todo: following should be async
|
|
56
|
+
const mergedVolume = volumeLoader.createLocalVolume(
|
|
57
|
+
options,
|
|
58
|
+
volumeId,
|
|
59
|
+
preventCache
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
return mergedVolume;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export default createMergedLabelmapForIndex;
|