@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,44 @@
|
|
|
1
|
+
import { Types } from '@cornerstonejs/core';
|
|
2
|
+
|
|
3
|
+
function dist2(p1: Types.Point2, p2: Types.Point2): number {
|
|
4
|
+
return (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Calculates the distance-squared of a point to a line
|
|
9
|
+
*
|
|
10
|
+
* @param lineStart - x,y coordinates of the start of the line
|
|
11
|
+
* @param lineEnd - x,y coordinates of the end of the line
|
|
12
|
+
* @param point - x,y of the point
|
|
13
|
+
* @returns distance-squared
|
|
14
|
+
*/
|
|
15
|
+
export default function distanceToPointSquared(
|
|
16
|
+
lineStart: Types.Point2,
|
|
17
|
+
lineEnd: Types.Point2,
|
|
18
|
+
point: Types.Point2
|
|
19
|
+
): number {
|
|
20
|
+
const d2 = dist2(lineStart, lineEnd);
|
|
21
|
+
|
|
22
|
+
if (d2 === 0) {
|
|
23
|
+
return dist2(point, lineStart);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const t =
|
|
27
|
+
((point[0] - lineStart[0]) * (lineEnd[0] - lineStart[0]) +
|
|
28
|
+
(point[1] - lineStart[1]) * (lineEnd[1] - lineStart[1])) /
|
|
29
|
+
d2;
|
|
30
|
+
|
|
31
|
+
if (t < 0) {
|
|
32
|
+
return dist2(point, lineStart);
|
|
33
|
+
}
|
|
34
|
+
if (t > 1) {
|
|
35
|
+
return dist2(point, lineEnd);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const pt: Types.Point2 = [
|
|
39
|
+
lineStart[0] + t * (lineEnd[0] - lineStart[0]),
|
|
40
|
+
lineStart[1] + t * (lineEnd[1] - lineStart[1]),
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
return dist2(point, pt);
|
|
44
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { Types } from '@cornerstonejs/core';
|
|
2
|
+
|
|
3
|
+
// Returns sign of number
|
|
4
|
+
function sign(x: any) {
|
|
5
|
+
return typeof x === 'number'
|
|
6
|
+
? x
|
|
7
|
+
? x < 0
|
|
8
|
+
? -1
|
|
9
|
+
: 1
|
|
10
|
+
: x === x
|
|
11
|
+
? 0
|
|
12
|
+
: NaN
|
|
13
|
+
: NaN;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Calculates the intersection point between two lines in the 2D plane
|
|
18
|
+
*
|
|
19
|
+
* @param line1Start - x,y coordinates of the start of the first line
|
|
20
|
+
* @param line1End - x,y coordinates of the end of the first line
|
|
21
|
+
* @param line2Start - x,y coordinates of the start of the second line
|
|
22
|
+
* @param line2End - x,y coordinates of the end of the second line
|
|
23
|
+
* @returns [x,y] - point x,y of the point
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
export default function intersectLine(
|
|
27
|
+
line1Start: Types.Point2,
|
|
28
|
+
line1End: Types.Point2,
|
|
29
|
+
line2Start: Types.Point2,
|
|
30
|
+
line2End: Types.Point2
|
|
31
|
+
): number[] {
|
|
32
|
+
const [x1, y1] = line1Start;
|
|
33
|
+
const [x2, y2] = line1End;
|
|
34
|
+
const [x3, y3] = line2Start;
|
|
35
|
+
const [x4, y4] = line2End;
|
|
36
|
+
|
|
37
|
+
// Compute a1, b1, c1, where line joining points 1 and 2 is "a1 x + b1 y + c1 = 0"
|
|
38
|
+
const a1 = y2 - y1;
|
|
39
|
+
const b1 = x1 - x2;
|
|
40
|
+
const c1 = x2 * y1 - x1 * y2;
|
|
41
|
+
|
|
42
|
+
// Compute r3 and r4
|
|
43
|
+
const r3 = a1 * x3 + b1 * y3 + c1;
|
|
44
|
+
const r4 = a1 * x4 + b1 * y4 + c1;
|
|
45
|
+
|
|
46
|
+
/* Check signs of r3 and r4. If both point 3 and point 4 lie on
|
|
47
|
+
* same side of line 1, the line segments do not intersect.
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
if (r3 !== 0 && r4 !== 0 && sign(r3) === sign(r4)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Compute a2, b2, c2
|
|
55
|
+
const a2 = y4 - y3;
|
|
56
|
+
const b2 = x3 - x4;
|
|
57
|
+
const c2 = x4 * y3 - x3 * y4;
|
|
58
|
+
|
|
59
|
+
// Compute r1 and r2
|
|
60
|
+
const r1 = a2 * x1 + b2 * y1 + c2;
|
|
61
|
+
const r2 = a2 * x2 + b2 * y2 + c2;
|
|
62
|
+
|
|
63
|
+
/* Check signs of r1 and r2. If both point 1 and point 2 lie
|
|
64
|
+
* on same side of second line segment, the line segments do
|
|
65
|
+
* not intersect.
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
if (r1 !== 0 && r2 !== 0 && sign(r1) === sign(r2)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* Line segments intersect: compute intersection point.
|
|
73
|
+
*/
|
|
74
|
+
|
|
75
|
+
const denom = a1 * b2 - a2 * b1;
|
|
76
|
+
let num;
|
|
77
|
+
|
|
78
|
+
/* The denom/2 is to get rounding instead of truncating. It
|
|
79
|
+
* is added or subtracted to the numerator, depending upon the
|
|
80
|
+
* sign of the numerator.
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
num = b1 * c2 - b2 * c1;
|
|
84
|
+
const x = num / denom;
|
|
85
|
+
|
|
86
|
+
num = a2 * c1 - a1 * c2;
|
|
87
|
+
const y = num / denom;
|
|
88
|
+
|
|
89
|
+
const intersectionPoint = [x, y];
|
|
90
|
+
|
|
91
|
+
return intersectionPoint;
|
|
92
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Types } from '@cornerstonejs/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Return the midpoint (think average) of all the provided points.
|
|
5
|
+
*/
|
|
6
|
+
const midPoint = (
|
|
7
|
+
...args: (Types.Point2 | Types.Point3)[]
|
|
8
|
+
): Types.Point2 | Types.Point3 => {
|
|
9
|
+
const ret =
|
|
10
|
+
args[0].length === 2 ? <Types.Point2>[0, 0] : <Types.Point3>[0, 0, 0];
|
|
11
|
+
const len = args.length;
|
|
12
|
+
for (const arg of args) {
|
|
13
|
+
ret[0] += arg[0] / len;
|
|
14
|
+
ret[1] += arg[1] / len;
|
|
15
|
+
if (ret.length === 3) ret[2] += arg[2] / len;
|
|
16
|
+
}
|
|
17
|
+
return ret;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const midPoint2 = midPoint as (...args: Types.Point2[]) => Types.Point2;
|
|
21
|
+
|
|
22
|
+
export default midPoint;
|
|
23
|
+
|
|
24
|
+
export { midPoint2 };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Types } from '@cornerstonejs/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Calculates the distance of a point to another point
|
|
5
|
+
*
|
|
6
|
+
* @param p1 - x,y of the point
|
|
7
|
+
* @param p2 - x,y of the point
|
|
8
|
+
* @returns distance
|
|
9
|
+
*/
|
|
10
|
+
export default function distanceToPoint(
|
|
11
|
+
p1: Types.Point2,
|
|
12
|
+
p2: Types.Point2
|
|
13
|
+
): number {
|
|
14
|
+
if (p1?.length !== 2 || p2?.length !== 2) {
|
|
15
|
+
throw Error('points should have 2 elements of [x, y]');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const [x1, y1] = p1;
|
|
19
|
+
const [x2, y2] = p2;
|
|
20
|
+
|
|
21
|
+
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
|
|
22
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { getEnabledElement } from '@cornerstonejs/core';
|
|
2
|
+
import type { Types } from '@cornerstonejs/core';
|
|
3
|
+
import { vec2, vec3 } from 'gl-matrix';
|
|
4
|
+
import { PlanarFreehandROICommonData } from './planarFreehandROIInternalTypes';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Adds one or more points to the array at a resolution defined by the underlying image.
|
|
8
|
+
*/
|
|
9
|
+
const addCanvasPointsToArray = (
|
|
10
|
+
element: HTMLDivElement,
|
|
11
|
+
canvasPoints: Types.Point2[],
|
|
12
|
+
newCanvasPoint: Types.Point2,
|
|
13
|
+
commonData: PlanarFreehandROICommonData
|
|
14
|
+
): number => {
|
|
15
|
+
const { xDir, yDir, spacing } = commonData;
|
|
16
|
+
const enabledElement = getEnabledElement(element);
|
|
17
|
+
const { viewport } = enabledElement;
|
|
18
|
+
|
|
19
|
+
const lastWorldPos = viewport.canvasToWorld(
|
|
20
|
+
canvasPoints[canvasPoints.length - 1]
|
|
21
|
+
);
|
|
22
|
+
const newWorldPos = viewport.canvasToWorld(newCanvasPoint);
|
|
23
|
+
|
|
24
|
+
const worldPosDiff = vec3.create();
|
|
25
|
+
|
|
26
|
+
vec3.subtract(worldPosDiff, newWorldPos, lastWorldPos);
|
|
27
|
+
|
|
28
|
+
const xDist = Math.abs(vec3.dot(worldPosDiff, xDir));
|
|
29
|
+
const yDist = Math.abs(vec3.dot(worldPosDiff, yDir));
|
|
30
|
+
|
|
31
|
+
const numPointsToAdd = Math.max(
|
|
32
|
+
Math.floor(xDist / spacing[0]),
|
|
33
|
+
Math.floor(yDist / spacing[0])
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
if (numPointsToAdd > 1) {
|
|
37
|
+
const lastCanvasPoint = canvasPoints[canvasPoints.length - 1];
|
|
38
|
+
|
|
39
|
+
const canvasDist = vec2.dist(lastCanvasPoint, newCanvasPoint);
|
|
40
|
+
|
|
41
|
+
const canvasDir = vec2.create();
|
|
42
|
+
|
|
43
|
+
vec2.subtract(canvasDir, newCanvasPoint, lastCanvasPoint);
|
|
44
|
+
|
|
45
|
+
vec2.set(canvasDir, canvasDir[0] / canvasDist, canvasDir[1] / canvasDist);
|
|
46
|
+
|
|
47
|
+
const distPerPoint = canvasDist / numPointsToAdd;
|
|
48
|
+
|
|
49
|
+
for (let i = 1; i <= numPointsToAdd; i++) {
|
|
50
|
+
canvasPoints.push([
|
|
51
|
+
lastCanvasPoint[0] + distPerPoint * canvasDir[0] * i,
|
|
52
|
+
lastCanvasPoint[1] + distPerPoint * canvasDir[1] * i,
|
|
53
|
+
]);
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
canvasPoints.push(newCanvasPoint);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return numPointsToAdd;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export default addCanvasPointsToArray;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Types } from '@cornerstonejs/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Calculates the area of an array of `Point2` points using the shoelace algorithm.
|
|
5
|
+
*
|
|
6
|
+
* The units of the area are in the same units as the points are in. E.g. if
|
|
7
|
+
* the points are in canvas, then the result is in canvas pixels ^2; If they are
|
|
8
|
+
* in mm, then the result is in mm^2; etc.
|
|
9
|
+
*/
|
|
10
|
+
export default function calculateAreaOfPoints(points: Types.Point2[]): number {
|
|
11
|
+
// Shoelace algorithm.
|
|
12
|
+
const n = points.length;
|
|
13
|
+
let area = 0.0;
|
|
14
|
+
let j = n - 1;
|
|
15
|
+
|
|
16
|
+
for (let i = 0; i < n; i++) {
|
|
17
|
+
area += (points[j][0] + points[i][0]) * (points[j][1] - points[i][1]);
|
|
18
|
+
j = i; // j is previous vertex to i
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Return absolute value of half the sum (half as summing up traingles).
|
|
22
|
+
return Math.abs(area / 2.0);
|
|
23
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { vec2 } from 'gl-matrix';
|
|
2
|
+
import type { Types } from '@cornerstonejs/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Orientation algoritm to determine if two lines cross.
|
|
6
|
+
* Credit and details: geeksforgeeks.org/check-if-two-given-line-segments-intersect/
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Checks whether the line (`p1`,`q1`) intersects any of the other lines in the
|
|
11
|
+
* `points`, and returns the first value.
|
|
12
|
+
*/
|
|
13
|
+
function getFirstIntersectionWithPolyline(
|
|
14
|
+
points: Types.Point2[],
|
|
15
|
+
p1: Types.Point2,
|
|
16
|
+
q1: Types.Point2,
|
|
17
|
+
closed = true
|
|
18
|
+
): Types.Point2 | undefined {
|
|
19
|
+
let initialI;
|
|
20
|
+
let j;
|
|
21
|
+
|
|
22
|
+
if (closed) {
|
|
23
|
+
j = points.length - 1;
|
|
24
|
+
initialI = 0;
|
|
25
|
+
} else {
|
|
26
|
+
j = 0;
|
|
27
|
+
initialI = 1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
for (let i = initialI; i < points.length; i++) {
|
|
31
|
+
const p2 = points[j];
|
|
32
|
+
const q2 = points[i];
|
|
33
|
+
|
|
34
|
+
if (doesIntersect(p1, q1, p2, q2)) {
|
|
35
|
+
return [j, i];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
j = i;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Checks whether the line (`p1`,`q1`) intersects any of the other lines in the
|
|
44
|
+
* `points`, and returns the closest value.
|
|
45
|
+
*/
|
|
46
|
+
function getClosestIntersectionWithPolyline(
|
|
47
|
+
points: Types.Point2[],
|
|
48
|
+
p1: Types.Point2,
|
|
49
|
+
q1: Types.Point2,
|
|
50
|
+
closed = true
|
|
51
|
+
): { segment: Types.Point2; distance: number } | undefined {
|
|
52
|
+
let initialI;
|
|
53
|
+
let j;
|
|
54
|
+
|
|
55
|
+
if (closed) {
|
|
56
|
+
j = points.length - 1;
|
|
57
|
+
initialI = 0;
|
|
58
|
+
} else {
|
|
59
|
+
j = 0;
|
|
60
|
+
initialI = 1;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const intersections = [];
|
|
64
|
+
|
|
65
|
+
for (let i = initialI; i < points.length; i++) {
|
|
66
|
+
const p2 = points[j];
|
|
67
|
+
const q2 = points[i];
|
|
68
|
+
|
|
69
|
+
if (doesIntersect(p1, q1, p2, q2)) {
|
|
70
|
+
intersections.push([j, i]);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
j = i;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (intersections.length === 0) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Find intersection closest to the start point
|
|
81
|
+
const distances = [];
|
|
82
|
+
|
|
83
|
+
intersections.forEach((intersection) => {
|
|
84
|
+
const intersectionPoints = [
|
|
85
|
+
points[intersection[0]],
|
|
86
|
+
points[intersection[1]],
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
const midpoint = [
|
|
90
|
+
(intersectionPoints[0][0] + intersectionPoints[1][0]) / 2,
|
|
91
|
+
(intersectionPoints[0][1] + intersectionPoints[1][1]) / 2,
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
distances.push(vec2.distance(<vec2>midpoint, p1));
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const minDistance = Math.min(...distances);
|
|
98
|
+
const indexOfMinDistance = distances.indexOf(minDistance);
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
segment: intersections[indexOfMinDistance],
|
|
102
|
+
distance: minDistance,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Checks whether the line (`p1`,`q1`) intersects the line (`p2`,`q2`) via an orientation algorithm.
|
|
108
|
+
*/
|
|
109
|
+
function doesIntersect(
|
|
110
|
+
p1: Types.Point2,
|
|
111
|
+
q1: Types.Point2,
|
|
112
|
+
p2: Types.Point2,
|
|
113
|
+
q2: Types.Point2
|
|
114
|
+
): boolean {
|
|
115
|
+
let result = false;
|
|
116
|
+
|
|
117
|
+
const orient = [
|
|
118
|
+
orientation(p1, q1, p2),
|
|
119
|
+
orientation(p1, q1, q2),
|
|
120
|
+
orientation(p2, q2, p1),
|
|
121
|
+
orientation(p2, q2, q1),
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
// General Case
|
|
125
|
+
if (orient[0] !== orient[1] && orient[2] !== orient[3]) {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Special Cases
|
|
130
|
+
if (orient[0] === 0 && onSegment(p1, p2, q1)) {
|
|
131
|
+
// If p1, q1 and p2 are colinear and p2 lies on segment p1q1
|
|
132
|
+
result = true;
|
|
133
|
+
} else if (orient[1] === 0 && onSegment(p1, q2, q1)) {
|
|
134
|
+
// If p1, q1 and p2 are colinear and q2 lies on segment p1q1
|
|
135
|
+
result = true;
|
|
136
|
+
} else if (orient[2] === 0 && onSegment(p2, p1, q2)) {
|
|
137
|
+
// If p2, q2 and p1 are colinear and p1 lies on segment p2q2
|
|
138
|
+
result = true;
|
|
139
|
+
} else if (orient[3] === 0 && onSegment(p2, q1, q2)) {
|
|
140
|
+
// If p2, q2 and q1 are colinear and q1 lies on segment p2q2
|
|
141
|
+
result = true;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Checks the orientation of 3 points, returns a 0, 1 or 2 based on
|
|
149
|
+
* the orientation of the points.
|
|
150
|
+
*/
|
|
151
|
+
function orientation(
|
|
152
|
+
p: Types.Point2,
|
|
153
|
+
q: Types.Point2,
|
|
154
|
+
r: Types.Point2
|
|
155
|
+
): number {
|
|
156
|
+
const orientationValue =
|
|
157
|
+
(q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1]);
|
|
158
|
+
|
|
159
|
+
if (orientationValue === 0) {
|
|
160
|
+
return 0; // Colinear
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return orientationValue > 0 ? 1 : 2;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Checks if point `q` lies on the segment (`p`,`r`).
|
|
168
|
+
*/
|
|
169
|
+
function onSegment(p: Types.Point2, q: Types.Point2, r: Types.Point2): boolean {
|
|
170
|
+
if (
|
|
171
|
+
q[0] <= Math.max(p[0], r[0]) &&
|
|
172
|
+
q[0] >= Math.min(p[0], r[0]) &&
|
|
173
|
+
q[1] <= Math.max(p[1], r[1]) &&
|
|
174
|
+
q[1] >= Math.min(p[1], r[1])
|
|
175
|
+
) {
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export { getFirstIntersectionWithPolyline, getClosestIntersectionWithPolyline };
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { StackViewport } from '@cornerstonejs/core';
|
|
2
|
+
import type { Types } from '@cornerstonejs/core';
|
|
3
|
+
import { vec3 } from 'gl-matrix';
|
|
4
|
+
|
|
5
|
+
const EPSILON = 1e-3;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Gets the desired spacing for points in the polyline for the
|
|
9
|
+
* `PlanarFreehandROITool` in the x and y canvas directions, as well as
|
|
10
|
+
* returning these canvas directions in world space.
|
|
11
|
+
*
|
|
12
|
+
* @param viewport - The Cornerstone3D `StackViewport` or `VolumeViewport`.
|
|
13
|
+
* @param subPixelResolution - The number to divide the image pixel spacing by
|
|
14
|
+
* to get the sub pixel spacing. E.g. `10` will return spacings 10x smaller than
|
|
15
|
+
* the native image spacing.
|
|
16
|
+
* @returns The spacings of the X and Y directions, and the 3D directions of the
|
|
17
|
+
* x and y directions.
|
|
18
|
+
*/
|
|
19
|
+
const getSubPixelSpacingAndXYDirections = (
|
|
20
|
+
viewport: Types.IStackViewport | Types.IVolumeViewport,
|
|
21
|
+
subPixelResolution: number
|
|
22
|
+
): { spacing: Types.Point2; xDir: Types.Point3; yDir: Types.Point3 } => {
|
|
23
|
+
let spacing;
|
|
24
|
+
let xDir;
|
|
25
|
+
let yDir;
|
|
26
|
+
|
|
27
|
+
if (viewport instanceof StackViewport) {
|
|
28
|
+
// Check XY directions
|
|
29
|
+
const imageData = viewport.getImageData();
|
|
30
|
+
|
|
31
|
+
xDir = imageData.direction.slice(0, 3);
|
|
32
|
+
yDir = imageData.direction.slice(3, 6);
|
|
33
|
+
|
|
34
|
+
spacing = imageData.spacing;
|
|
35
|
+
} else {
|
|
36
|
+
// Check volume directions
|
|
37
|
+
const imageData = viewport.getImageData();
|
|
38
|
+
const { direction, spacing: volumeSpacing } = imageData;
|
|
39
|
+
const { viewPlaneNormal, viewUp } = viewport.getCamera();
|
|
40
|
+
|
|
41
|
+
// Calculate size of spacing vector in normal direction
|
|
42
|
+
const iVector = direction.slice(0, 3) as Types.Point3;
|
|
43
|
+
const jVector = direction.slice(3, 6) as Types.Point3;
|
|
44
|
+
const kVector = direction.slice(6, 9) as Types.Point3;
|
|
45
|
+
|
|
46
|
+
const viewRight = vec3.create(); // Get the X direction of the viewport
|
|
47
|
+
|
|
48
|
+
vec3.cross(viewRight, <vec3>viewUp, <vec3>viewPlaneNormal);
|
|
49
|
+
|
|
50
|
+
const absViewRightDotI = Math.abs(vec3.dot(viewRight, iVector));
|
|
51
|
+
const absViewRightDotJ = Math.abs(vec3.dot(viewRight, jVector));
|
|
52
|
+
const absViewRightDotK = Math.abs(vec3.dot(viewRight, kVector));
|
|
53
|
+
|
|
54
|
+
// Get X spacing
|
|
55
|
+
let xSpacing;
|
|
56
|
+
if (Math.abs(1 - absViewRightDotI) < EPSILON) {
|
|
57
|
+
xSpacing = volumeSpacing[0];
|
|
58
|
+
xDir = iVector;
|
|
59
|
+
} else if (Math.abs(1 - absViewRightDotJ) < EPSILON) {
|
|
60
|
+
xSpacing = volumeSpacing[1];
|
|
61
|
+
xDir = jVector;
|
|
62
|
+
} else if (Math.abs(1 - absViewRightDotK) < EPSILON) {
|
|
63
|
+
xSpacing = volumeSpacing[2];
|
|
64
|
+
xDir = kVector;
|
|
65
|
+
} else {
|
|
66
|
+
throw new Error('No support yet for oblique plane planar contours');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const absViewPlaneNormalDotI = Math.abs(vec3.dot(viewPlaneNormal, iVector));
|
|
70
|
+
const absViewPlaneNormalDotJ = Math.abs(vec3.dot(viewPlaneNormal, jVector));
|
|
71
|
+
const absViewPlaneNormalDotK = Math.abs(vec3.dot(viewPlaneNormal, kVector));
|
|
72
|
+
|
|
73
|
+
// Get Y spacing
|
|
74
|
+
let ySpacing;
|
|
75
|
+
if (Math.abs(1 - absViewPlaneNormalDotI) < EPSILON) {
|
|
76
|
+
ySpacing = volumeSpacing[0];
|
|
77
|
+
yDir = iVector;
|
|
78
|
+
} else if (Math.abs(1 - absViewPlaneNormalDotJ) < EPSILON) {
|
|
79
|
+
ySpacing = volumeSpacing[1];
|
|
80
|
+
yDir = jVector;
|
|
81
|
+
} else if (Math.abs(1 - absViewPlaneNormalDotK) < EPSILON) {
|
|
82
|
+
ySpacing = volumeSpacing[2];
|
|
83
|
+
yDir = kVector;
|
|
84
|
+
} else {
|
|
85
|
+
throw new Error('No support yet for oblique plane planar contours');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
spacing = [xSpacing, ySpacing];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const subPixelSpacing: Types.Point2 = [
|
|
92
|
+
spacing[0] / subPixelResolution,
|
|
93
|
+
spacing[1] / subPixelResolution,
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
return { spacing: subPixelSpacing, xDir, yDir };
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export default getSubPixelSpacingAndXYDirections;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getFirstIntersectionWithPolyline,
|
|
3
|
+
getClosestIntersectionWithPolyline,
|
|
4
|
+
} from './getIntersectionWithPolyline';
|
|
5
|
+
import getSubPixelSpacingAndXYDirections from './getSubPixelSpacingAndXYDirections';
|
|
6
|
+
import pointsAreWithinCloseContourProximity from './pointsAreWithinCloseContourProximity';
|
|
7
|
+
import addCanvasPointsToArray from './addCanvasPointsToArray';
|
|
8
|
+
import pointCanProjectOnLine from './pointCanProjectOnLine';
|
|
9
|
+
import calculateAreaOfPoints from './calculateAreaOfPoints';
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
getFirstIntersectionWithPolyline,
|
|
13
|
+
getClosestIntersectionWithPolyline,
|
|
14
|
+
getSubPixelSpacingAndXYDirections,
|
|
15
|
+
pointsAreWithinCloseContourProximity,
|
|
16
|
+
addCanvasPointsToArray,
|
|
17
|
+
pointCanProjectOnLine,
|
|
18
|
+
calculateAreaOfPoints,
|
|
19
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Types } from '@cornerstonejs/core';
|
|
2
|
+
import { PlanarFreehandROIAnnotation } from '../../../types/ToolSpecificAnnotationTypes';
|
|
3
|
+
|
|
4
|
+
// Note: These types are internal to the drawing/editing processes of the tool.
|
|
5
|
+
|
|
6
|
+
type PlanarFreehandROIDrawData = {
|
|
7
|
+
polylineIndex: number;
|
|
8
|
+
canvasPoints: Types.Point2[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type PlanarFreehandROIEditData = {
|
|
12
|
+
prevCanvasPoints: Types.Point2[];
|
|
13
|
+
editCanvasPoints: Types.Point2[];
|
|
14
|
+
fusedCanvasPoints: Types.Point2[];
|
|
15
|
+
startCrossingIndex?: Types.Point2;
|
|
16
|
+
// The current index of the last node added to the (invisible) edit line being
|
|
17
|
+
// used to calculate the edit preview.
|
|
18
|
+
editIndex: number;
|
|
19
|
+
// The index on the prevCanvasPoints that the edit line should snap to in the
|
|
20
|
+
// edit preview.
|
|
21
|
+
snapIndex?: number;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type PlanarFreehandROICommonData = {
|
|
25
|
+
annotation: PlanarFreehandROIAnnotation;
|
|
26
|
+
viewportIdsToRender: string[];
|
|
27
|
+
spacing: Types.Point2;
|
|
28
|
+
xDir: Types.Point3;
|
|
29
|
+
yDir: Types.Point3;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export {
|
|
33
|
+
PlanarFreehandROIDrawData,
|
|
34
|
+
PlanarFreehandROIEditData,
|
|
35
|
+
PlanarFreehandROICommonData,
|
|
36
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { Types } from '@cornerstonejs/core';
|
|
2
|
+
import { vec2 } from 'gl-matrix';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns `true` if the point `p` can project onto point (`p1`, `p2`), and if
|
|
6
|
+
* this projected point is less than `proximity` units away.
|
|
7
|
+
*/
|
|
8
|
+
const pointCanProjectOnLine = (
|
|
9
|
+
p: Types.Point2,
|
|
10
|
+
p1: Types.Point2,
|
|
11
|
+
p2: Types.Point2,
|
|
12
|
+
proximity: number
|
|
13
|
+
): boolean => {
|
|
14
|
+
// Perfom checks in order of computational complexity.
|
|
15
|
+
const p1p = [p[0] - p1[0], p[1] - p1[1]];
|
|
16
|
+
const p1p2 = [p2[0] - p1[0], p2[1] - p1[1]];
|
|
17
|
+
|
|
18
|
+
const dot = p1p[0] * p1p2[0] + p1p[1] * p1p2[1];
|
|
19
|
+
|
|
20
|
+
// Dot product needs to be positive to be a candidate for projection onto line segment.
|
|
21
|
+
if (dot < 0) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const p1p2Mag = Math.sqrt(p1p2[0] * p1p2[0] + p1p2[1] * p1p2[1]);
|
|
26
|
+
|
|
27
|
+
if (p1p2Mag === 0) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const projectionVectorMag = dot / p1p2Mag;
|
|
32
|
+
const p1p2UnitVector = [p1p2[0] / p1p2Mag, p1p2[1] / p1p2Mag];
|
|
33
|
+
const projectionVector = [
|
|
34
|
+
p1p2UnitVector[0] * projectionVectorMag,
|
|
35
|
+
p1p2UnitVector[1] * projectionVectorMag,
|
|
36
|
+
];
|
|
37
|
+
const projectionPoint = <Types.Point2>[
|
|
38
|
+
p1[0] + projectionVector[0],
|
|
39
|
+
p1[1] + projectionVector[1],
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
const distance = vec2.distance(p, projectionPoint);
|
|
43
|
+
|
|
44
|
+
if (distance > proximity) {
|
|
45
|
+
// point is too far away.
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Check projects onto line segment.
|
|
50
|
+
if (vec2.distance(p1, projectionPoint) > vec2.distance(p1, p2)) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return true;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default pointCanProjectOnLine;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { vec2 } from 'gl-matrix';
|
|
2
|
+
import type { Types } from '@cornerstonejs/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns true if points `p1` and `p2` are within `closeContourProximity`.
|
|
6
|
+
*/
|
|
7
|
+
const pointsAreWithinCloseContourProximity = (
|
|
8
|
+
p1: Types.Point2,
|
|
9
|
+
p2: Types.Point2,
|
|
10
|
+
closeContourProximity: number
|
|
11
|
+
): boolean => {
|
|
12
|
+
return vec2.dist(p1, p2) < closeContourProximity;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default pointsAreWithinCloseContourProximity;
|