@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,612 @@
|
|
|
1
|
+
import { getEnabledElement } from '@cornerstonejs/core';
|
|
2
|
+
import type { Types } from '@cornerstonejs/core';
|
|
3
|
+
import { state } from '../../../store';
|
|
4
|
+
import { Events } from '../../../enums';
|
|
5
|
+
import {
|
|
6
|
+
resetElementCursor,
|
|
7
|
+
hideElementCursor,
|
|
8
|
+
} from '../../../cursors/elementCursor';
|
|
9
|
+
import type { EventTypes, Annotation } from '../../../types';
|
|
10
|
+
import { vec3, vec2 } from 'gl-matrix';
|
|
11
|
+
import { polyline } from '../../../utilities/math';
|
|
12
|
+
import {
|
|
13
|
+
shouldInterpolate,
|
|
14
|
+
getInterpolatedPoints,
|
|
15
|
+
} from '../../../utilities/planarFreehandROITool/interpolatePoints';
|
|
16
|
+
import triggerAnnotationRenderForViewportIds from '../../../utilities/triggerAnnotationRenderForViewportIds';
|
|
17
|
+
import findOpenUShapedContourVectorToPeak from './findOpenUShapedContourVectorToPeak';
|
|
18
|
+
|
|
19
|
+
const { addCanvasPointsToArray, getSubPixelSpacingAndXYDirections } = polyline;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Activates the open contour edit event loop.
|
|
23
|
+
*/
|
|
24
|
+
function activateOpenContourEdit(
|
|
25
|
+
evt: EventTypes.InteractionEventType,
|
|
26
|
+
annotation: Annotation,
|
|
27
|
+
viewportIdsToRender: string[]
|
|
28
|
+
): void {
|
|
29
|
+
this.isEditingOpen = true;
|
|
30
|
+
|
|
31
|
+
const eventDetail = evt.detail;
|
|
32
|
+
const { currentPoints, element } = eventDetail;
|
|
33
|
+
const canvasPos = currentPoints.canvas;
|
|
34
|
+
const enabledElement = getEnabledElement(element);
|
|
35
|
+
const { viewport } = enabledElement;
|
|
36
|
+
|
|
37
|
+
const prevCanvasPoints = annotation.data.polyline.map(viewport.worldToCanvas);
|
|
38
|
+
|
|
39
|
+
const { spacing, xDir, yDir } = getSubPixelSpacingAndXYDirections(
|
|
40
|
+
viewport,
|
|
41
|
+
this.configuration.subPixelResolution
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
this.editData = {
|
|
45
|
+
prevCanvasPoints,
|
|
46
|
+
editCanvasPoints: [canvasPos],
|
|
47
|
+
startCrossingIndex: undefined,
|
|
48
|
+
editIndex: 0,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
this.commonData = {
|
|
52
|
+
annotation,
|
|
53
|
+
viewportIdsToRender,
|
|
54
|
+
spacing,
|
|
55
|
+
xDir,
|
|
56
|
+
yDir,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
state.isInteractingWithTool = true;
|
|
60
|
+
|
|
61
|
+
element.addEventListener(
|
|
62
|
+
Events.MOUSE_UP,
|
|
63
|
+
this.mouseUpOpenContourEditCallback
|
|
64
|
+
);
|
|
65
|
+
element.addEventListener(
|
|
66
|
+
Events.MOUSE_DRAG,
|
|
67
|
+
this.mouseDragOpenContourEditCallback
|
|
68
|
+
);
|
|
69
|
+
element.addEventListener(
|
|
70
|
+
Events.MOUSE_CLICK,
|
|
71
|
+
this.mouseUpOpenContourEditCallback
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
element.addEventListener(
|
|
75
|
+
Events.TOUCH_END,
|
|
76
|
+
this.mouseUpOpenContourEditCallback
|
|
77
|
+
);
|
|
78
|
+
element.addEventListener(
|
|
79
|
+
Events.TOUCH_DRAG,
|
|
80
|
+
this.mouseDragOpenContourEditCallback
|
|
81
|
+
);
|
|
82
|
+
element.addEventListener(
|
|
83
|
+
Events.TOUCH_TAP,
|
|
84
|
+
this.mouseUpOpenContourEditCallback
|
|
85
|
+
);
|
|
86
|
+
hideElementCursor(element);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Deactivates and cleans up the closed contour edit event loop.
|
|
91
|
+
*/
|
|
92
|
+
function deactivateOpenContourEdit(element: HTMLDivElement) {
|
|
93
|
+
state.isInteractingWithTool = false;
|
|
94
|
+
|
|
95
|
+
element.removeEventListener(
|
|
96
|
+
Events.MOUSE_UP,
|
|
97
|
+
this.mouseUpOpenContourEditCallback
|
|
98
|
+
);
|
|
99
|
+
element.removeEventListener(
|
|
100
|
+
Events.MOUSE_DRAG,
|
|
101
|
+
this.mouseDragOpenContourEditCallback
|
|
102
|
+
);
|
|
103
|
+
element.removeEventListener(
|
|
104
|
+
Events.MOUSE_CLICK,
|
|
105
|
+
this.mouseUpOpenContourEditCallback
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
element.removeEventListener(
|
|
109
|
+
Events.TOUCH_END,
|
|
110
|
+
this.mouseUpOpenContourEditCallback
|
|
111
|
+
);
|
|
112
|
+
element.removeEventListener(
|
|
113
|
+
Events.TOUCH_DRAG,
|
|
114
|
+
this.mouseDragOpenContourEditCallback
|
|
115
|
+
);
|
|
116
|
+
element.removeEventListener(
|
|
117
|
+
Events.TOUCH_TAP,
|
|
118
|
+
this.mouseUpOpenContourEditCallback
|
|
119
|
+
);
|
|
120
|
+
resetElementCursor(element);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Adds points to the edit line and calculates the preview of the edit to render.
|
|
125
|
+
* Checks if an edit needs to be completed by crossing of lines, or by dragging
|
|
126
|
+
* the edit line past the end of the open contour.
|
|
127
|
+
*/
|
|
128
|
+
function mouseDragOpenContourEditCallback(
|
|
129
|
+
evt: EventTypes.InteractionEventType
|
|
130
|
+
): boolean {
|
|
131
|
+
const eventDetail = evt.detail;
|
|
132
|
+
const { currentPoints, element } = eventDetail;
|
|
133
|
+
const worldPos = currentPoints.world;
|
|
134
|
+
const canvasPos = currentPoints.canvas;
|
|
135
|
+
const enabledElement = getEnabledElement(element);
|
|
136
|
+
const { renderingEngine, viewport } = enabledElement;
|
|
137
|
+
|
|
138
|
+
const { viewportIdsToRender, xDir, yDir, spacing } = this.commonData;
|
|
139
|
+
const { editIndex, editCanvasPoints, startCrossingIndex } = this.editData;
|
|
140
|
+
|
|
141
|
+
const lastCanvasPoint = editCanvasPoints[editCanvasPoints.length - 1];
|
|
142
|
+
const lastWorldPoint = viewport.canvasToWorld(lastCanvasPoint);
|
|
143
|
+
|
|
144
|
+
const worldPosDiff = vec3.create();
|
|
145
|
+
|
|
146
|
+
vec3.subtract(worldPosDiff, worldPos, lastWorldPoint);
|
|
147
|
+
|
|
148
|
+
const xDist = Math.abs(vec3.dot(worldPosDiff, xDir));
|
|
149
|
+
const yDist = Math.abs(vec3.dot(worldPosDiff, yDir));
|
|
150
|
+
|
|
151
|
+
// Get pixel spacing in the direction.
|
|
152
|
+
// Check that we have moved at least one voxel in each direction.
|
|
153
|
+
|
|
154
|
+
if (xDist <= spacing[0] && yDist <= spacing[1]) {
|
|
155
|
+
// Haven't changed world point enough, don't render
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (startCrossingIndex !== undefined) {
|
|
160
|
+
// Edge case: If the edit line itself crosses, remove part of that edit line so we don't
|
|
161
|
+
// Get isolated regions.
|
|
162
|
+
this.checkAndRemoveCrossesOnEditLine(evt);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const numPointsAdded = addCanvasPointsToArray(
|
|
166
|
+
element,
|
|
167
|
+
editCanvasPoints,
|
|
168
|
+
canvasPos,
|
|
169
|
+
this.commonData
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
const currentEditIndex = editIndex + numPointsAdded;
|
|
173
|
+
|
|
174
|
+
this.editData.editIndex = currentEditIndex;
|
|
175
|
+
|
|
176
|
+
if (startCrossingIndex === undefined && editCanvasPoints.length > 1) {
|
|
177
|
+
this.checkForFirstCrossing(evt, false);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
this.editData.snapIndex = this.findSnapIndex();
|
|
181
|
+
|
|
182
|
+
this.editData.fusedCanvasPoints = this.fuseEditPointsWithOpenContour(evt);
|
|
183
|
+
|
|
184
|
+
if (
|
|
185
|
+
startCrossingIndex !== undefined &&
|
|
186
|
+
this.checkForSecondCrossing(evt, false)
|
|
187
|
+
) {
|
|
188
|
+
this.removePointsAfterSecondCrossing(false);
|
|
189
|
+
this.finishEditOpenOnSecondCrossing(evt);
|
|
190
|
+
} else if (this.checkIfShouldOverwriteAnEnd(evt)) {
|
|
191
|
+
this.openContourEditOverwriteEnd(evt);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Overwrite the end of the contour with the edit, and then switch to the
|
|
199
|
+
* open contour end edit loop.
|
|
200
|
+
*/
|
|
201
|
+
function openContourEditOverwriteEnd(
|
|
202
|
+
evt: EventTypes.InteractionEventType
|
|
203
|
+
): void {
|
|
204
|
+
const eventDetail = evt.detail;
|
|
205
|
+
const { element } = eventDetail;
|
|
206
|
+
const enabledElement = getEnabledElement(element);
|
|
207
|
+
const { viewport } = enabledElement;
|
|
208
|
+
const { annotation, viewportIdsToRender } = this.commonData;
|
|
209
|
+
const fusedCanvasPoints = this.fuseEditPointsForOpenContourEndEdit();
|
|
210
|
+
|
|
211
|
+
const worldPoints = fusedCanvasPoints.map((canvasPoint) =>
|
|
212
|
+
viewport.canvasToWorld(canvasPoint)
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
annotation.data.polyline = worldPoints;
|
|
216
|
+
annotation.data.isOpenContour = true;
|
|
217
|
+
// Note: Contours generate from fusedCanvasPoints will be in the direction
|
|
218
|
+
// with the last point being the current mouse position
|
|
219
|
+
annotation.data.handles.points = [
|
|
220
|
+
worldPoints[0],
|
|
221
|
+
worldPoints[worldPoints.length - 1],
|
|
222
|
+
];
|
|
223
|
+
annotation.data.handles.activeHandleIndex = 1;
|
|
224
|
+
|
|
225
|
+
this.triggerAnnotationModified(annotation, enabledElement);
|
|
226
|
+
|
|
227
|
+
this.isEditingOpen = false;
|
|
228
|
+
this.editData = undefined;
|
|
229
|
+
this.commonData = undefined;
|
|
230
|
+
|
|
231
|
+
// Jump to a normal line edit now.
|
|
232
|
+
this.deactivateOpenContourEdit(element);
|
|
233
|
+
this.activateOpenContourEndEdit(evt, annotation, viewportIdsToRender);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Checks if we are moving the `editCanvasPoints` past the end of one of the
|
|
238
|
+
* open contour's `prevCanvasPoint`s.
|
|
239
|
+
*/
|
|
240
|
+
function checkIfShouldOverwriteAnEnd(
|
|
241
|
+
evt: EventTypes.InteractionEventType
|
|
242
|
+
): boolean {
|
|
243
|
+
const eventDetail = evt.detail;
|
|
244
|
+
const { currentPoints, lastPoints } = eventDetail;
|
|
245
|
+
const canvasPos = currentPoints.canvas;
|
|
246
|
+
const lastCanvasPos = lastPoints.canvas;
|
|
247
|
+
|
|
248
|
+
const { snapIndex, prevCanvasPoints, startCrossingIndex } = this.editData;
|
|
249
|
+
|
|
250
|
+
if (startCrossingIndex === undefined || snapIndex === undefined) {
|
|
251
|
+
// Edit not started
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// No snap index can be found, so contour is being edited away from line.
|
|
256
|
+
if (snapIndex === -1) {
|
|
257
|
+
return true;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (snapIndex !== 0 && snapIndex !== prevCanvasPoints.length - 1) {
|
|
261
|
+
// Not snapping to final index
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Work out the angle between the last mouse move and
|
|
266
|
+
// And the current point to the snapped point.
|
|
267
|
+
const p1 = canvasPos;
|
|
268
|
+
const p2 = lastCanvasPos;
|
|
269
|
+
const p3 = prevCanvasPoints[snapIndex];
|
|
270
|
+
|
|
271
|
+
const a = vec2.create();
|
|
272
|
+
const b = vec2.create();
|
|
273
|
+
|
|
274
|
+
vec2.set(a, p1[0] - p2[0], p1[1] - p2[1]);
|
|
275
|
+
vec2.set(b, p1[0] - p3[0], p1[1] - p3[1]);
|
|
276
|
+
|
|
277
|
+
const aDotb = vec2.dot(a, b);
|
|
278
|
+
const magA = Math.sqrt(a[0] * a[0] + a[1] * a[1]);
|
|
279
|
+
const magB = Math.sqrt(b[0] * b[0] + b[1] * b[1]);
|
|
280
|
+
|
|
281
|
+
const theta = Math.acos(aDotb / (magA * magB));
|
|
282
|
+
|
|
283
|
+
if (theta < Math.PI / 2) {
|
|
284
|
+
return true;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* This method combines the contour before editing (prevCanvasPoints) with
|
|
292
|
+
* the current edit (editCanvasPoints), to produce a single contour ready for
|
|
293
|
+
* end editing.
|
|
294
|
+
*
|
|
295
|
+
* @privateRemarks In this method we use the following trick to find the
|
|
296
|
+
* optimal contour:
|
|
297
|
+
* - As the contour and the edit can be drawn with different chiralities, we find if
|
|
298
|
+
* the edit line aligns better with the intended cross points in its current order
|
|
299
|
+
* or reversed. We do this by minimising the distance between its ends and the
|
|
300
|
+
* intended crossing points.
|
|
301
|
+
*/
|
|
302
|
+
function fuseEditPointsForOpenContourEndEdit(): Types.Point2[] {
|
|
303
|
+
const { snapIndex, prevCanvasPoints, editCanvasPoints, startCrossingIndex } =
|
|
304
|
+
this.editData;
|
|
305
|
+
|
|
306
|
+
const newCanvasPoints = [];
|
|
307
|
+
|
|
308
|
+
// Note: Generated contours will both be in the direction with the
|
|
309
|
+
// last point being the current mouse position
|
|
310
|
+
|
|
311
|
+
if (snapIndex === 0) {
|
|
312
|
+
// end -> crossingpoint -> edit
|
|
313
|
+
// Add points from the end of the previous contour, to the crossing point.
|
|
314
|
+
for (let i = prevCanvasPoints.length - 1; i >= startCrossingIndex; i--) {
|
|
315
|
+
const canvasPoint = prevCanvasPoints[i];
|
|
316
|
+
|
|
317
|
+
newCanvasPoints.push([canvasPoint[0], canvasPoint[1]]);
|
|
318
|
+
}
|
|
319
|
+
} else {
|
|
320
|
+
// start -> crossingpoint -> edit
|
|
321
|
+
// Add points from the orignal contour origin up to the low index.
|
|
322
|
+
for (let i = 0; i < startCrossingIndex; i++) {
|
|
323
|
+
const canvasPoint = prevCanvasPoints[i];
|
|
324
|
+
|
|
325
|
+
newCanvasPoints.push([canvasPoint[0], canvasPoint[1]]);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const distanceBetweenCrossingIndexAndFirstPoint = vec2.distance(
|
|
330
|
+
prevCanvasPoints[startCrossingIndex],
|
|
331
|
+
editCanvasPoints[0]
|
|
332
|
+
);
|
|
333
|
+
|
|
334
|
+
const distanceBetweenCrossingIndexAndLastPoint = vec2.distance(
|
|
335
|
+
prevCanvasPoints[startCrossingIndex],
|
|
336
|
+
editCanvasPoints[editCanvasPoints.length - 1]
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
if (
|
|
340
|
+
distanceBetweenCrossingIndexAndFirstPoint <
|
|
341
|
+
distanceBetweenCrossingIndexAndLastPoint
|
|
342
|
+
) {
|
|
343
|
+
// In order
|
|
344
|
+
for (let i = 0; i < editCanvasPoints.length; i++) {
|
|
345
|
+
const canvasPoint = editCanvasPoints[i];
|
|
346
|
+
|
|
347
|
+
newCanvasPoints.push([canvasPoint[0], canvasPoint[1]]);
|
|
348
|
+
}
|
|
349
|
+
} else {
|
|
350
|
+
// reverse
|
|
351
|
+
for (let i = editCanvasPoints.length - 1; i >= 0; i--) {
|
|
352
|
+
const canvasPoint = editCanvasPoints[i];
|
|
353
|
+
|
|
354
|
+
newCanvasPoints.push([canvasPoint[0], canvasPoint[1]]);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return newCanvasPoints;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* This method combines the contour before editing (prevCanvasPoints) with
|
|
363
|
+
* the current edit (editCanvasPoints), to produce a renderable preview of the
|
|
364
|
+
* edit. Upon finishing the contour, the preview generated here is written back
|
|
365
|
+
* into the contour state.
|
|
366
|
+
*
|
|
367
|
+
* @privateRemarks In this method we use the following trick to find the
|
|
368
|
+
* optimal contour:
|
|
369
|
+
* - As the contour and the edit can be drawn with different chiralities, we find if
|
|
370
|
+
* the edit line aligns better with the intended cross points in its current order
|
|
371
|
+
* or reversed. We do this by minimising the distance between its ends and the
|
|
372
|
+
* intended crossing points.
|
|
373
|
+
*/
|
|
374
|
+
function fuseEditPointsWithOpenContour(
|
|
375
|
+
evt: EventTypes.InteractionEventType
|
|
376
|
+
): Types.Point2[] {
|
|
377
|
+
const { prevCanvasPoints, editCanvasPoints, startCrossingIndex, snapIndex } =
|
|
378
|
+
this.editData;
|
|
379
|
+
|
|
380
|
+
if (startCrossingIndex === undefined || snapIndex === undefined) {
|
|
381
|
+
return undefined;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const eventDetail = evt.detail;
|
|
385
|
+
const { element } = eventDetail;
|
|
386
|
+
|
|
387
|
+
// Augment the editCanvasPoints array, between the end of edit and the snap index.
|
|
388
|
+
const augmentedEditCanvasPoints = [...editCanvasPoints];
|
|
389
|
+
|
|
390
|
+
addCanvasPointsToArray(
|
|
391
|
+
element,
|
|
392
|
+
augmentedEditCanvasPoints,
|
|
393
|
+
prevCanvasPoints[snapIndex],
|
|
394
|
+
this.commonData
|
|
395
|
+
);
|
|
396
|
+
|
|
397
|
+
if (augmentedEditCanvasPoints.length > editCanvasPoints.length) {
|
|
398
|
+
// If any points added, remove the last point, which will be a clone of the snapIndex
|
|
399
|
+
augmentedEditCanvasPoints.pop();
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Calculate the distances between the first and last edit points and the origin of the
|
|
403
|
+
// Contour with the snap point. These will be used to see which way around the edit array should be
|
|
404
|
+
// Placed within the preview.
|
|
405
|
+
|
|
406
|
+
let lowIndex;
|
|
407
|
+
let highIndex;
|
|
408
|
+
|
|
409
|
+
if (startCrossingIndex > snapIndex) {
|
|
410
|
+
lowIndex = snapIndex;
|
|
411
|
+
highIndex = startCrossingIndex;
|
|
412
|
+
} else {
|
|
413
|
+
lowIndex = startCrossingIndex;
|
|
414
|
+
highIndex = snapIndex;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const distanceBetweenLowAndFirstPoint = vec2.distance(
|
|
418
|
+
prevCanvasPoints[lowIndex],
|
|
419
|
+
augmentedEditCanvasPoints[0]
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
const distanceBetweenLowAndLastPoint = vec2.distance(
|
|
423
|
+
prevCanvasPoints[lowIndex],
|
|
424
|
+
augmentedEditCanvasPoints[augmentedEditCanvasPoints.length - 1]
|
|
425
|
+
);
|
|
426
|
+
|
|
427
|
+
const distanceBetweenHighAndFirstPoint = vec2.distance(
|
|
428
|
+
prevCanvasPoints[highIndex],
|
|
429
|
+
augmentedEditCanvasPoints[0]
|
|
430
|
+
);
|
|
431
|
+
|
|
432
|
+
const distanceBetweenHighAndLastPoint = vec2.distance(
|
|
433
|
+
prevCanvasPoints[highIndex],
|
|
434
|
+
augmentedEditCanvasPoints[augmentedEditCanvasPoints.length - 1]
|
|
435
|
+
);
|
|
436
|
+
|
|
437
|
+
const pointsToRender = [];
|
|
438
|
+
|
|
439
|
+
// Add points from the orignal contour origin up to the low index.
|
|
440
|
+
for (let i = 0; i < lowIndex; i++) {
|
|
441
|
+
const canvasPoint = prevCanvasPoints[i];
|
|
442
|
+
|
|
443
|
+
pointsToRender.push([canvasPoint[0], canvasPoint[1]]);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Check which orientation of the edit line minimizes the distance between the
|
|
447
|
+
// origial contour low/high points and the start/end nodes of the edit line.
|
|
448
|
+
|
|
449
|
+
const inPlaceDistance =
|
|
450
|
+
distanceBetweenLowAndFirstPoint + distanceBetweenHighAndLastPoint;
|
|
451
|
+
|
|
452
|
+
const reverseDistance =
|
|
453
|
+
distanceBetweenLowAndLastPoint + distanceBetweenHighAndFirstPoint;
|
|
454
|
+
|
|
455
|
+
if (inPlaceDistance < reverseDistance) {
|
|
456
|
+
for (let i = 0; i < augmentedEditCanvasPoints.length; i++) {
|
|
457
|
+
const canvasPoint = augmentedEditCanvasPoints[i];
|
|
458
|
+
|
|
459
|
+
pointsToRender.push([canvasPoint[0], canvasPoint[1]]);
|
|
460
|
+
}
|
|
461
|
+
} else {
|
|
462
|
+
for (let i = augmentedEditCanvasPoints.length - 1; i >= 0; i--) {
|
|
463
|
+
const canvasPoint = augmentedEditCanvasPoints[i];
|
|
464
|
+
|
|
465
|
+
pointsToRender.push([canvasPoint[0], canvasPoint[1]]);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// Add points from the original contour's high index up to to its end point.
|
|
470
|
+
for (let i = highIndex; i < prevCanvasPoints.length; i++) {
|
|
471
|
+
const canvasPoint = prevCanvasPoints[i];
|
|
472
|
+
|
|
473
|
+
pointsToRender.push([canvasPoint[0], canvasPoint[1]]);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
return pointsToRender;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* On a second crossing, apply edit, and start a new edit from the crossing.
|
|
481
|
+
*/
|
|
482
|
+
function finishEditOpenOnSecondCrossing(
|
|
483
|
+
evt: EventTypes.InteractionEventType
|
|
484
|
+
): void {
|
|
485
|
+
const eventDetail = evt.detail;
|
|
486
|
+
const { element } = eventDetail;
|
|
487
|
+
const enabledElement = getEnabledElement(element);
|
|
488
|
+
const { viewport, renderingEngine } = enabledElement;
|
|
489
|
+
|
|
490
|
+
const { annotation, viewportIdsToRender } = this.commonData;
|
|
491
|
+
const { fusedCanvasPoints, editCanvasPoints } = this.editData;
|
|
492
|
+
|
|
493
|
+
const worldPoints = fusedCanvasPoints.map((canvasPoint) =>
|
|
494
|
+
viewport.canvasToWorld(canvasPoint)
|
|
495
|
+
);
|
|
496
|
+
|
|
497
|
+
annotation.data.polyline = worldPoints;
|
|
498
|
+
annotation.data.isOpenContour = true;
|
|
499
|
+
annotation.data.handles.points = [
|
|
500
|
+
worldPoints[0],
|
|
501
|
+
worldPoints[worldPoints.length - 1],
|
|
502
|
+
];
|
|
503
|
+
|
|
504
|
+
this.triggerAnnotationModified(annotation, enabledElement);
|
|
505
|
+
|
|
506
|
+
const lastEditCanvasPoint = editCanvasPoints.pop();
|
|
507
|
+
|
|
508
|
+
this.editData = {
|
|
509
|
+
prevCanvasPoints: fusedCanvasPoints,
|
|
510
|
+
editCanvasPoints: [lastEditCanvasPoint],
|
|
511
|
+
startCrossingIndex: undefined,
|
|
512
|
+
editIndex: 0,
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Completes the edit of the open contour when the mouse button is released.
|
|
520
|
+
*/
|
|
521
|
+
function mouseUpOpenContourEditCallback(
|
|
522
|
+
evt: EventTypes.InteractionEventType
|
|
523
|
+
): void {
|
|
524
|
+
const eventDetail = evt.detail;
|
|
525
|
+
const { element } = eventDetail;
|
|
526
|
+
|
|
527
|
+
this.completeOpenContourEdit(element);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Completes the edit of the open contour.
|
|
532
|
+
*/
|
|
533
|
+
function completeOpenContourEdit(element: HTMLDivElement) {
|
|
534
|
+
const enabledElement = getEnabledElement(element);
|
|
535
|
+
const { viewport, renderingEngine } = enabledElement;
|
|
536
|
+
|
|
537
|
+
const { annotation, viewportIdsToRender } = this.commonData;
|
|
538
|
+
const { fusedCanvasPoints, prevCanvasPoints } = this.editData;
|
|
539
|
+
|
|
540
|
+
if (fusedCanvasPoints) {
|
|
541
|
+
const updatedPoints = shouldInterpolate(this.configuration)
|
|
542
|
+
? getInterpolatedPoints(
|
|
543
|
+
this.configuration,
|
|
544
|
+
fusedCanvasPoints,
|
|
545
|
+
prevCanvasPoints
|
|
546
|
+
)
|
|
547
|
+
: fusedCanvasPoints;
|
|
548
|
+
|
|
549
|
+
const worldPoints = updatedPoints.map((canvasPoint) =>
|
|
550
|
+
viewport.canvasToWorld(canvasPoint)
|
|
551
|
+
);
|
|
552
|
+
annotation.data.polyline = worldPoints;
|
|
553
|
+
annotation.data.isOpenContour = true;
|
|
554
|
+
annotation.data.handles.points = [
|
|
555
|
+
worldPoints[0],
|
|
556
|
+
worldPoints[worldPoints.length - 1],
|
|
557
|
+
];
|
|
558
|
+
|
|
559
|
+
// If the annotation is an open U-shaped annotation, find the annotation vector.
|
|
560
|
+
if (annotation.data.isOpenUShapeContour) {
|
|
561
|
+
annotation.data.openUShapeContourVectorToPeak =
|
|
562
|
+
findOpenUShapedContourVectorToPeak(fusedCanvasPoints, viewport);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
this.triggerAnnotationModified(annotation, enabledElement);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
this.isEditingOpen = false;
|
|
569
|
+
this.editData = undefined;
|
|
570
|
+
this.commonData = undefined;
|
|
571
|
+
|
|
572
|
+
triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
|
|
573
|
+
|
|
574
|
+
this.deactivateOpenContourEdit(element);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Completes the edit on a cancel method call during the open
|
|
579
|
+
* contour edit loop.
|
|
580
|
+
*/
|
|
581
|
+
function cancelOpenContourEdit(element: HTMLDivElement) {
|
|
582
|
+
this.completeOpenContourEdit(element);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Registers the open contour edit loop to the tool instance.
|
|
587
|
+
*/
|
|
588
|
+
function registerOpenContourEditLoop(toolInstance) {
|
|
589
|
+
toolInstance.activateOpenContourEdit =
|
|
590
|
+
activateOpenContourEdit.bind(toolInstance);
|
|
591
|
+
toolInstance.deactivateOpenContourEdit =
|
|
592
|
+
deactivateOpenContourEdit.bind(toolInstance);
|
|
593
|
+
toolInstance.mouseDragOpenContourEditCallback =
|
|
594
|
+
mouseDragOpenContourEditCallback.bind(toolInstance);
|
|
595
|
+
toolInstance.mouseUpOpenContourEditCallback =
|
|
596
|
+
mouseUpOpenContourEditCallback.bind(toolInstance);
|
|
597
|
+
toolInstance.fuseEditPointsWithOpenContour =
|
|
598
|
+
fuseEditPointsWithOpenContour.bind(toolInstance);
|
|
599
|
+
toolInstance.finishEditOpenOnSecondCrossing =
|
|
600
|
+
finishEditOpenOnSecondCrossing.bind(toolInstance);
|
|
601
|
+
toolInstance.checkIfShouldOverwriteAnEnd =
|
|
602
|
+
checkIfShouldOverwriteAnEnd.bind(toolInstance);
|
|
603
|
+
toolInstance.fuseEditPointsForOpenContourEndEdit =
|
|
604
|
+
fuseEditPointsForOpenContourEndEdit.bind(toolInstance);
|
|
605
|
+
toolInstance.openContourEditOverwriteEnd =
|
|
606
|
+
openContourEditOverwriteEnd.bind(toolInstance);
|
|
607
|
+
toolInstance.cancelOpenContourEdit = cancelOpenContourEdit.bind(toolInstance);
|
|
608
|
+
toolInstance.completeOpenContourEdit =
|
|
609
|
+
completeOpenContourEdit.bind(toolInstance);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
export default registerOpenContourEditLoop;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { getEnabledElement } from '@cornerstonejs/core';
|
|
2
|
+
import { state } from '../../../store';
|
|
3
|
+
import { Events } from '../../../enums';
|
|
4
|
+
import { hideElementCursor } from '../../../cursors/elementCursor';
|
|
5
|
+
import type { EventTypes, Annotation } from '../../../types';
|
|
6
|
+
import { polyline } from '../../../utilities/math';
|
|
7
|
+
|
|
8
|
+
const { getSubPixelSpacingAndXYDirections } = polyline;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Activates the open contour end edit. This actually just sets up the state so
|
|
12
|
+
* that the tool thinks we are mid draw, and then jumps into the drawing loop.
|
|
13
|
+
*/
|
|
14
|
+
function activateOpenContourEndEdit(
|
|
15
|
+
evt: EventTypes.InteractionEventType,
|
|
16
|
+
annotation: Annotation,
|
|
17
|
+
viewportIdsToRender: string[]
|
|
18
|
+
): void {
|
|
19
|
+
this.isDrawing = true;
|
|
20
|
+
|
|
21
|
+
const eventDetail = evt.detail;
|
|
22
|
+
const { element } = eventDetail;
|
|
23
|
+
const enabledElement = getEnabledElement(element);
|
|
24
|
+
const { viewport } = enabledElement;
|
|
25
|
+
|
|
26
|
+
const { spacing, xDir, yDir } = getSubPixelSpacingAndXYDirections(
|
|
27
|
+
viewport,
|
|
28
|
+
this.configuration.subPixelResolution
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const canvasPoints = annotation.data.polyline.map(viewport.worldToCanvas);
|
|
32
|
+
const handleIndexGrabbed = annotation.data.handles.activeHandleIndex;
|
|
33
|
+
|
|
34
|
+
// If 0, invert point direction, if 1, keep point direction the same.
|
|
35
|
+
// This is so we can just jump as into the state as if the annotation was just being drawn.
|
|
36
|
+
if (handleIndexGrabbed === 0) {
|
|
37
|
+
canvasPoints.reverse();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
this.drawData = {
|
|
41
|
+
canvasPoints: canvasPoints,
|
|
42
|
+
polylineIndex: canvasPoints.length - 1,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
this.commonData = {
|
|
46
|
+
annotation,
|
|
47
|
+
viewportIdsToRender,
|
|
48
|
+
spacing,
|
|
49
|
+
xDir,
|
|
50
|
+
yDir,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
state.isInteractingWithTool = true;
|
|
54
|
+
|
|
55
|
+
// Jump into drawing loop.
|
|
56
|
+
element.addEventListener(Events.MOUSE_UP, this.mouseUpDrawCallback);
|
|
57
|
+
element.addEventListener(Events.MOUSE_DRAG, this.mouseDragDrawCallback);
|
|
58
|
+
element.addEventListener(Events.MOUSE_CLICK, this.mouseUpDrawCallback);
|
|
59
|
+
element.addEventListener(Events.TOUCH_END, this.mouseUpDrawCallback);
|
|
60
|
+
element.addEventListener(Events.TOUCH_DRAG, this.mouseDragDrawCallback);
|
|
61
|
+
element.addEventListener(Events.TOUCH_TAP, this.mouseUpDrawCallback);
|
|
62
|
+
|
|
63
|
+
hideElementCursor(element);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Registers the open contour end edit loop to the tool instance.
|
|
68
|
+
*/
|
|
69
|
+
function registerOpenContourEndEditLoop(toolInstance): void {
|
|
70
|
+
toolInstance.activateOpenContourEndEdit =
|
|
71
|
+
activateOpenContourEndEdit.bind(toolInstance);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export default registerOpenContourEndEditLoop;
|