@cornerstonejs/tools 1.51.5 → 1.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/drawingSvg/drawPath.d.ts +11 -0
- package/dist/cjs/drawingSvg/drawPath.js +55 -0
- package/dist/cjs/drawingSvg/drawPath.js.map +1 -0
- package/dist/cjs/drawingSvg/drawPolyline.d.ts +1 -1
- package/dist/cjs/drawingSvg/drawPolyline.js +3 -11
- package/dist/cjs/drawingSvg/drawPolyline.js.map +1 -1
- package/dist/cjs/drawingSvg/index.d.ts +2 -1
- package/dist/cjs/drawingSvg/index.js +3 -1
- package/dist/cjs/drawingSvg/index.js.map +1 -1
- package/dist/cjs/enums/ChangeTypes.d.ts +2 -1
- package/dist/cjs/enums/ChangeTypes.js +1 -0
- package/dist/cjs/enums/ChangeTypes.js.map +1 -1
- package/dist/cjs/eventDispatchers/keyboardEventHandlers/keyDown.js +1 -1
- package/dist/cjs/eventDispatchers/keyboardEventHandlers/keyDown.js.map +1 -1
- package/dist/cjs/eventDispatchers/shared/getActiveToolForMouseEvent.js.map +1 -1
- package/dist/cjs/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.d.ts +1 -1
- package/dist/cjs/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.js +165 -78
- package/dist/cjs/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.js.map +1 -1
- package/dist/cjs/stateManagement/annotation/annotationState.d.ts +6 -1
- package/dist/cjs/stateManagement/annotation/annotationState.js +49 -1
- package/dist/cjs/stateManagement/annotation/annotationState.js.map +1 -1
- package/dist/cjs/stateManagement/annotation/helpers/state.d.ts +4 -2
- package/dist/cjs/stateManagement/annotation/helpers/state.js +16 -4
- package/dist/cjs/stateManagement/annotation/helpers/state.js.map +1 -1
- package/dist/cjs/stateManagement/index.d.ts +6 -1
- package/dist/cjs/stateManagement/index.js +6 -1
- package/dist/cjs/stateManagement/index.js.map +1 -1
- package/dist/cjs/store/ToolGroupManager/ToolGroup.d.ts +3 -1
- package/dist/cjs/store/ToolGroupManager/ToolGroup.js +3 -2
- package/dist/cjs/store/ToolGroupManager/ToolGroup.js.map +1 -1
- package/dist/cjs/tools/SegmentationIntersectionTool.js +1 -1
- package/dist/cjs/tools/SegmentationIntersectionTool.js.map +1 -1
- package/dist/cjs/tools/annotation/LivewireContourSegmentationTool.d.ts +4 -0
- package/dist/cjs/tools/annotation/LivewireContourSegmentationTool.js +82 -0
- package/dist/cjs/tools/annotation/LivewireContourSegmentationTool.js.map +1 -1
- package/dist/cjs/tools/annotation/LivewireContourTool.d.ts +13 -11
- package/dist/cjs/tools/annotation/LivewireContourTool.js +78 -65
- package/dist/cjs/tools/annotation/LivewireContourTool.js.map +1 -1
- package/dist/cjs/tools/annotation/PlanarFreehandROITool.js +3 -1
- package/dist/cjs/tools/annotation/PlanarFreehandROITool.js.map +1 -1
- package/dist/cjs/tools/annotation/SplineROITool.d.ts +6 -3
- package/dist/cjs/tools/annotation/SplineROITool.js +40 -21
- package/dist/cjs/tools/annotation/SplineROITool.js.map +1 -1
- package/dist/cjs/tools/annotation/planarFreehandROITool/closedContourEditLoop.js +12 -7
- package/dist/cjs/tools/annotation/planarFreehandROITool/closedContourEditLoop.js.map +1 -1
- package/dist/cjs/tools/annotation/planarFreehandROITool/drawLoop.js +24 -18
- package/dist/cjs/tools/annotation/planarFreehandROITool/drawLoop.js.map +1 -1
- package/dist/cjs/tools/annotation/planarFreehandROITool/openContourEditLoop.js +16 -10
- package/dist/cjs/tools/annotation/planarFreehandROITool/openContourEditLoop.js.map +1 -1
- package/dist/cjs/tools/annotation/planarFreehandROITool/renderMethods.js +19 -7
- package/dist/cjs/tools/annotation/planarFreehandROITool/renderMethods.js.map +1 -1
- package/dist/cjs/tools/annotation/splines/LinearSpline.js +1 -1
- package/dist/cjs/tools/annotation/splines/LinearSpline.js.map +1 -1
- package/dist/cjs/tools/annotation/splines/Spline.d.ts +2 -0
- package/dist/cjs/tools/annotation/splines/Spline.js +7 -3
- package/dist/cjs/tools/annotation/splines/Spline.js.map +1 -1
- package/dist/cjs/tools/base/AnnotationTool.js.map +1 -1
- package/dist/cjs/tools/base/ContourBaseTool.d.ts +1 -0
- package/dist/cjs/tools/base/ContourBaseTool.js +18 -1
- package/dist/cjs/tools/base/ContourBaseTool.js.map +1 -1
- package/dist/cjs/tools/base/ContourSegmentationBaseTool.js +4 -0
- package/dist/cjs/tools/base/ContourSegmentationBaseTool.js.map +1 -1
- package/dist/cjs/tools/displayTools/Contour/contourConfig.js +1 -0
- package/dist/cjs/tools/displayTools/Contour/contourConfig.js.map +1 -1
- package/dist/cjs/types/AnnotationTypes.d.ts +2 -0
- package/dist/cjs/types/ContourAnnotation.d.ts +6 -0
- package/dist/cjs/types/ContourAnnotation.js +7 -0
- package/dist/cjs/types/ContourAnnotation.js.map +1 -1
- package/dist/cjs/types/ContourSegmentationAnnotation.d.ts +8 -0
- package/dist/cjs/types/ContourTypes.d.ts +1 -0
- package/dist/cjs/types/EventTypes.d.ts +4 -1
- package/dist/cjs/types/ISpline.d.ts +1 -0
- package/dist/cjs/types/InterpolationTypes.d.ts +2 -0
- package/dist/cjs/types/SplineProps.d.ts +1 -0
- package/dist/cjs/types/ToolSpecificAnnotationTypes.d.ts +2 -5
- package/dist/cjs/utilities/contours/getContourHolesDataCanvas.d.ts +3 -0
- package/dist/cjs/utilities/contours/getContourHolesDataCanvas.js +21 -0
- package/dist/cjs/utilities/contours/getContourHolesDataCanvas.js.map +1 -0
- package/dist/cjs/utilities/contours/getContourHolesDataWorld.d.ts +3 -0
- package/dist/cjs/utilities/contours/getContourHolesDataWorld.js +10 -0
- package/dist/cjs/utilities/contours/getContourHolesDataWorld.js.map +1 -0
- package/dist/cjs/utilities/contours/index.d.ts +4 -1
- package/dist/cjs/utilities/contours/index.js +7 -1
- package/dist/cjs/utilities/contours/index.js.map +1 -1
- package/dist/cjs/utilities/contours/interpolation/acceptAutogeneratedInterpolations.js.map +1 -1
- package/dist/cjs/utilities/contours/interpolation/createPolylineToolData.js +2 -1
- package/dist/cjs/utilities/contours/interpolation/createPolylineToolData.js.map +1 -1
- package/dist/cjs/utilities/contours/interpolation/findAnnotationForInterpolation.js +2 -1
- package/dist/cjs/utilities/contours/interpolation/findAnnotationForInterpolation.js.map +1 -1
- package/dist/cjs/utilities/contours/interpolation/getInterpolationData.js +3 -1
- package/dist/cjs/utilities/contours/interpolation/getInterpolationData.js.map +1 -1
- package/dist/cjs/utilities/contours/interpolation/interpolate.d.ts +8 -0
- package/dist/cjs/utilities/contours/interpolation/interpolate.js +56 -42
- package/dist/cjs/utilities/contours/interpolation/interpolate.js.map +1 -1
- package/dist/cjs/utilities/contours/interpolation/selectHandles.d.ts +4 -0
- package/dist/cjs/utilities/contours/interpolation/selectHandles.js +170 -0
- package/dist/cjs/utilities/contours/interpolation/selectHandles.js.map +1 -0
- package/dist/cjs/utilities/contours/updateContourPolyline.d.ts +10 -0
- package/dist/cjs/utilities/contours/updateContourPolyline.js +64 -0
- package/dist/cjs/utilities/contours/updateContourPolyline.js.map +1 -0
- package/dist/cjs/utilities/livewire/LivewireScissors.d.ts +2 -1
- package/dist/cjs/utilities/livewire/LivewireScissors.js +46 -24
- package/dist/cjs/utilities/livewire/LivewireScissors.js.map +1 -1
- package/dist/cjs/utilities/math/polyline/containsPoints.d.ts +2 -0
- package/dist/cjs/utilities/math/polyline/containsPoints.js +16 -0
- package/dist/cjs/utilities/math/polyline/containsPoints.js.map +1 -0
- package/dist/cjs/utilities/math/polyline/getWindingDirection.d.ts +2 -0
- package/dist/cjs/utilities/math/polyline/getWindingDirection.js +12 -0
- package/dist/cjs/utilities/math/polyline/getWindingDirection.js.map +1 -0
- package/dist/cjs/utilities/math/polyline/index.d.ts +3 -1
- package/dist/cjs/utilities/math/polyline/index.js +5 -1
- package/dist/cjs/utilities/math/polyline/index.js.map +1 -1
- package/dist/cjs/utilities/math/polyline/planarFreehandROIInternalTypes.d.ts +1 -0
- package/dist/cjs/utilities/segmentation/InterpolationManager/InterpolationManager.js +13 -3
- package/dist/cjs/utilities/segmentation/InterpolationManager/InterpolationManager.js.map +1 -1
- package/dist/esm/drawingSvg/drawPath.js +49 -0
- package/dist/esm/drawingSvg/drawPath.js.map +1 -0
- package/dist/esm/drawingSvg/drawPolyline.js +3 -11
- package/dist/esm/drawingSvg/drawPolyline.js.map +1 -1
- package/dist/esm/drawingSvg/index.js +2 -1
- package/dist/esm/drawingSvg/index.js.map +1 -1
- package/dist/esm/enums/ChangeTypes.js +1 -0
- package/dist/esm/enums/ChangeTypes.js.map +1 -1
- package/dist/esm/eventDispatchers/keyboardEventHandlers/keyDown.js +1 -1
- package/dist/esm/eventDispatchers/keyboardEventHandlers/keyDown.js.map +1 -1
- package/dist/esm/eventDispatchers/shared/getActiveToolForMouseEvent.js.map +1 -1
- package/dist/esm/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.js +106 -32
- package/dist/esm/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.js.map +1 -1
- package/dist/esm/stateManagement/annotation/annotationState.js +42 -1
- package/dist/esm/stateManagement/annotation/annotationState.js.map +1 -1
- package/dist/esm/stateManagement/annotation/helpers/state.js +15 -4
- package/dist/esm/stateManagement/annotation/helpers/state.js.map +1 -1
- package/dist/esm/stateManagement/index.js +2 -2
- package/dist/esm/stateManagement/index.js.map +1 -1
- package/dist/esm/store/ToolGroupManager/ToolGroup.js +3 -2
- package/dist/esm/store/ToolGroupManager/ToolGroup.js.map +1 -1
- package/dist/esm/tools/SegmentationIntersectionTool.js +1 -1
- package/dist/esm/tools/SegmentationIntersectionTool.js.map +1 -1
- package/dist/esm/tools/annotation/LivewireContourSegmentationTool.js +81 -0
- package/dist/esm/tools/annotation/LivewireContourSegmentationTool.js.map +1 -1
- package/dist/esm/tools/annotation/LivewireContourTool.js +80 -67
- package/dist/esm/tools/annotation/LivewireContourTool.js.map +1 -1
- package/dist/esm/tools/annotation/PlanarFreehandROITool.js +3 -1
- package/dist/esm/tools/annotation/PlanarFreehandROITool.js.map +1 -1
- package/dist/esm/tools/annotation/SplineROITool.js +40 -22
- package/dist/esm/tools/annotation/SplineROITool.js.map +1 -1
- package/dist/esm/tools/annotation/planarFreehandROITool/closedContourEditLoop.js +12 -7
- package/dist/esm/tools/annotation/planarFreehandROITool/closedContourEditLoop.js.map +1 -1
- package/dist/esm/tools/annotation/planarFreehandROITool/drawLoop.js +25 -19
- package/dist/esm/tools/annotation/planarFreehandROITool/drawLoop.js.map +1 -1
- package/dist/esm/tools/annotation/planarFreehandROITool/openContourEditLoop.js +16 -10
- package/dist/esm/tools/annotation/planarFreehandROITool/openContourEditLoop.js.map +1 -1
- package/dist/esm/tools/annotation/planarFreehandROITool/renderMethods.js +20 -8
- package/dist/esm/tools/annotation/planarFreehandROITool/renderMethods.js.map +1 -1
- package/dist/esm/tools/annotation/splines/LinearSpline.js +1 -1
- package/dist/esm/tools/annotation/splines/LinearSpline.js.map +1 -1
- package/dist/esm/tools/annotation/splines/Spline.js +5 -1
- package/dist/esm/tools/annotation/splines/Spline.js.map +1 -1
- package/dist/esm/tools/base/AnnotationTool.js.map +1 -1
- package/dist/esm/tools/base/ContourBaseTool.js +20 -3
- package/dist/esm/tools/base/ContourBaseTool.js.map +1 -1
- package/dist/esm/tools/base/ContourSegmentationBaseTool.js +4 -0
- package/dist/esm/tools/base/ContourSegmentationBaseTool.js.map +1 -1
- package/dist/esm/tools/displayTools/Contour/contourConfig.js +1 -0
- package/dist/esm/tools/displayTools/Contour/contourConfig.js.map +1 -1
- package/dist/esm/types/ContourAnnotation.js +6 -1
- package/dist/esm/types/ContourAnnotation.js.map +1 -1
- package/dist/esm/utilities/contours/getContourHolesDataCanvas.js +15 -0
- package/dist/esm/utilities/contours/getContourHolesDataCanvas.js.map +1 -0
- package/dist/esm/utilities/contours/getContourHolesDataWorld.js +6 -0
- package/dist/esm/utilities/contours/getContourHolesDataWorld.js.map +1 -0
- package/dist/esm/utilities/contours/index.js +4 -1
- package/dist/esm/utilities/contours/index.js.map +1 -1
- package/dist/esm/utilities/contours/interpolation/acceptAutogeneratedInterpolations.js.map +1 -1
- package/dist/esm/utilities/contours/interpolation/createPolylineToolData.js +2 -1
- package/dist/esm/utilities/contours/interpolation/createPolylineToolData.js.map +1 -1
- package/dist/esm/utilities/contours/interpolation/findAnnotationForInterpolation.js +2 -1
- package/dist/esm/utilities/contours/interpolation/findAnnotationForInterpolation.js.map +1 -1
- package/dist/esm/utilities/contours/interpolation/getInterpolationData.js +3 -1
- package/dist/esm/utilities/contours/interpolation/getInterpolationData.js.map +1 -1
- package/dist/esm/utilities/contours/interpolation/interpolate.js +57 -43
- package/dist/esm/utilities/contours/interpolation/interpolate.js.map +1 -1
- package/dist/esm/utilities/contours/interpolation/selectHandles.js +164 -0
- package/dist/esm/utilities/contours/interpolation/selectHandles.js.map +1 -0
- package/dist/esm/utilities/contours/updateContourPolyline.js +38 -0
- package/dist/esm/utilities/contours/updateContourPolyline.js.map +1 -0
- package/dist/esm/utilities/livewire/LivewireScissors.js +46 -24
- package/dist/esm/utilities/livewire/LivewireScissors.js.map +1 -1
- package/dist/esm/utilities/math/polyline/containsPoints.js +10 -0
- package/dist/esm/utilities/math/polyline/containsPoints.js.map +1 -0
- package/dist/esm/utilities/math/polyline/getWindingDirection.js +6 -0
- package/dist/esm/utilities/math/polyline/getWindingDirection.js.map +1 -0
- package/dist/esm/utilities/math/polyline/index.js +3 -1
- package/dist/esm/utilities/math/polyline/index.js.map +1 -1
- package/dist/esm/utilities/segmentation/InterpolationManager/InterpolationManager.js +13 -3
- package/dist/esm/utilities/segmentation/InterpolationManager/InterpolationManager.js.map +1 -1
- package/dist/types/drawingSvg/drawPath.d.ts +12 -0
- package/dist/types/drawingSvg/drawPath.d.ts.map +1 -0
- package/dist/types/drawingSvg/drawPolyline.d.ts +1 -1
- package/dist/types/drawingSvg/drawPolyline.d.ts.map +1 -1
- package/dist/types/drawingSvg/index.d.ts +2 -1
- package/dist/types/drawingSvg/index.d.ts.map +1 -1
- package/dist/types/enums/ChangeTypes.d.ts +2 -1
- package/dist/types/enums/ChangeTypes.d.ts.map +1 -1
- package/dist/types/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.d.ts +1 -1
- package/dist/types/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.d.ts.map +1 -1
- package/dist/types/stateManagement/annotation/annotationState.d.ts +6 -1
- package/dist/types/stateManagement/annotation/annotationState.d.ts.map +1 -1
- package/dist/types/stateManagement/annotation/helpers/state.d.ts +4 -2
- package/dist/types/stateManagement/annotation/helpers/state.d.ts.map +1 -1
- package/dist/types/stateManagement/index.d.ts +6 -1
- package/dist/types/store/ToolGroupManager/ToolGroup.d.ts +3 -1
- package/dist/types/store/ToolGroupManager/ToolGroup.d.ts.map +1 -1
- package/dist/types/tools/annotation/LivewireContourSegmentationTool.d.ts +4 -0
- package/dist/types/tools/annotation/LivewireContourSegmentationTool.d.ts.map +1 -1
- package/dist/types/tools/annotation/LivewireContourTool.d.ts +13 -11
- package/dist/types/tools/annotation/LivewireContourTool.d.ts.map +1 -1
- package/dist/types/tools/annotation/PlanarFreehandROITool.d.ts.map +1 -1
- package/dist/types/tools/annotation/SplineROITool.d.ts +6 -3
- package/dist/types/tools/annotation/SplineROITool.d.ts.map +1 -1
- package/dist/types/tools/annotation/planarFreehandROITool/closedContourEditLoop.d.ts.map +1 -1
- package/dist/types/tools/annotation/planarFreehandROITool/drawLoop.d.ts.map +1 -1
- package/dist/types/tools/annotation/planarFreehandROITool/openContourEditLoop.d.ts.map +1 -1
- package/dist/types/tools/annotation/planarFreehandROITool/renderMethods.d.ts.map +1 -1
- package/dist/types/tools/annotation/splines/Spline.d.ts +2 -0
- package/dist/types/tools/annotation/splines/Spline.d.ts.map +1 -1
- package/dist/types/tools/base/AnnotationTool.d.ts.map +1 -1
- package/dist/types/tools/base/ContourBaseTool.d.ts +1 -0
- package/dist/types/tools/base/ContourBaseTool.d.ts.map +1 -1
- package/dist/types/tools/base/ContourSegmentationBaseTool.d.ts.map +1 -1
- package/dist/types/tools/displayTools/Contour/contourConfig.d.ts.map +1 -1
- package/dist/types/types/AnnotationTypes.d.ts +2 -0
- package/dist/types/types/AnnotationTypes.d.ts.map +1 -1
- package/dist/types/types/ContourAnnotation.d.ts +6 -0
- package/dist/types/types/ContourAnnotation.d.ts.map +1 -1
- package/dist/types/types/ContourSegmentationAnnotation.d.ts +8 -0
- package/dist/types/types/ContourSegmentationAnnotation.d.ts.map +1 -1
- package/dist/types/types/ContourTypes.d.ts +1 -0
- package/dist/types/types/ContourTypes.d.ts.map +1 -1
- package/dist/types/types/EventTypes.d.ts +4 -1
- package/dist/types/types/EventTypes.d.ts.map +1 -1
- package/dist/types/types/ISpline.d.ts +1 -0
- package/dist/types/types/ISpline.d.ts.map +1 -1
- package/dist/types/types/InterpolationTypes.d.ts +2 -0
- package/dist/types/types/InterpolationTypes.d.ts.map +1 -1
- package/dist/types/types/SplineProps.d.ts +1 -0
- package/dist/types/types/SplineProps.d.ts.map +1 -1
- package/dist/types/types/ToolSpecificAnnotationTypes.d.ts +2 -5
- package/dist/types/types/ToolSpecificAnnotationTypes.d.ts.map +1 -1
- package/dist/types/utilities/contours/getContourHolesDataCanvas.d.ts +4 -0
- package/dist/types/utilities/contours/getContourHolesDataCanvas.d.ts.map +1 -0
- package/dist/types/utilities/contours/getContourHolesDataWorld.d.ts +4 -0
- package/dist/types/utilities/contours/getContourHolesDataWorld.d.ts.map +1 -0
- package/dist/types/utilities/contours/index.d.ts +4 -1
- package/dist/types/utilities/contours/index.d.ts.map +1 -1
- package/dist/types/utilities/contours/interpolation/acceptAutogeneratedInterpolations.d.ts.map +1 -1
- package/dist/types/utilities/contours/interpolation/createPolylineToolData.d.ts.map +1 -1
- package/dist/types/utilities/contours/interpolation/findAnnotationForInterpolation.d.ts.map +1 -1
- package/dist/types/utilities/contours/interpolation/getInterpolationData.d.ts.map +1 -1
- package/dist/types/utilities/contours/interpolation/interpolate.d.ts +8 -0
- package/dist/types/utilities/contours/interpolation/interpolate.d.ts.map +1 -1
- package/dist/types/utilities/contours/interpolation/selectHandles.d.ts +5 -0
- package/dist/types/utilities/contours/interpolation/selectHandles.d.ts.map +1 -0
- package/dist/types/utilities/contours/updateContourPolyline.d.ts +11 -0
- package/dist/types/utilities/contours/updateContourPolyline.d.ts.map +1 -0
- package/dist/types/utilities/livewire/LivewireScissors.d.ts +2 -1
- package/dist/types/utilities/livewire/LivewireScissors.d.ts.map +1 -1
- package/dist/types/utilities/math/polyline/containsPoints.d.ts +3 -0
- package/dist/types/utilities/math/polyline/containsPoints.d.ts.map +1 -0
- package/dist/types/utilities/math/polyline/getWindingDirection.d.ts +3 -0
- package/dist/types/utilities/math/polyline/getWindingDirection.d.ts.map +1 -0
- package/dist/types/utilities/math/polyline/index.d.ts +3 -1
- package/dist/types/utilities/math/polyline/index.d.ts.map +1 -1
- package/dist/types/utilities/math/polyline/planarFreehandROIInternalTypes.d.ts +1 -0
- package/dist/types/utilities/math/polyline/planarFreehandROIInternalTypes.d.ts.map +1 -1
- package/dist/types/utilities/segmentation/InterpolationManager/InterpolationManager.d.ts.map +1 -1
- package/dist/umd/index.js +1 -1
- package/dist/umd/index.js.map +1 -1
- package/package.json +3 -3
- package/src/drawingSvg/drawPath.ts +96 -0
- package/src/drawingSvg/drawPolyline.ts +13 -17
- package/src/drawingSvg/index.ts +2 -0
- package/src/enums/ChangeTypes.ts +4 -0
- package/src/eventDispatchers/keyboardEventHandlers/keyDown.ts +1 -1
- package/src/eventDispatchers/shared/getActiveToolForMouseEvent.ts +1 -1
- package/src/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.ts +194 -58
- package/src/stateManagement/annotation/annotationState.ts +101 -0
- package/src/stateManagement/annotation/helpers/state.ts +33 -3
- package/src/stateManagement/index.js +10 -0
- package/src/store/ToolGroupManager/ToolGroup.ts +9 -2
- package/src/tools/SegmentationIntersectionTool.ts +1 -1
- package/src/tools/annotation/LivewireContourSegmentationTool.ts +151 -0
- package/src/tools/annotation/LivewireContourTool.ts +172 -114
- package/src/tools/annotation/PlanarFreehandROITool.ts +13 -3
- package/src/tools/annotation/SplineROITool.ts +78 -31
- package/src/tools/annotation/planarFreehandROITool/closedContourEditLoop.ts +20 -11
- package/src/tools/annotation/planarFreehandROITool/drawLoop.ts +40 -21
- package/src/tools/annotation/planarFreehandROITool/openContourEditLoop.ts +28 -13
- package/src/tools/annotation/planarFreehandROITool/renderMethods.ts +28 -10
- package/src/tools/annotation/splines/LinearSpline.ts +1 -1
- package/src/tools/annotation/splines/Spline.ts +13 -1
- package/src/tools/base/AnnotationTool.ts +1 -0
- package/src/tools/base/ContourBaseTool.ts +45 -3
- package/src/tools/base/ContourSegmentationBaseTool.ts +6 -0
- package/src/tools/displayTools/Contour/contourConfig.ts +1 -0
- package/src/types/AnnotationTypes.ts +14 -0
- package/src/types/ContourAnnotation.ts +13 -0
- package/src/types/ContourSegmentationAnnotation.ts +38 -0
- package/src/types/ContourTypes.ts +3 -0
- package/src/types/EventTypes.ts +9 -0
- package/src/types/ISpline.ts +3 -0
- package/src/types/InterpolationTypes.ts +6 -0
- package/src/types/SplineProps.ts +10 -0
- package/src/types/ToolSpecificAnnotationTypes.ts +7 -5
- package/src/utilities/contours/getContourHolesDataCanvas.ts +33 -0
- package/src/utilities/contours/getContourHolesDataWorld.ts +19 -0
- package/src/utilities/contours/index.ts +6 -0
- package/src/utilities/contours/interpolation/acceptAutogeneratedInterpolations.ts +3 -1
- package/src/utilities/contours/interpolation/createPolylineToolData.ts +7 -1
- package/src/utilities/contours/interpolation/findAnnotationForInterpolation.ts +2 -1
- package/src/utilities/contours/interpolation/getInterpolationData.ts +3 -1
- package/src/utilities/contours/interpolation/interpolate.ts +94 -75
- package/src/utilities/contours/interpolation/selectHandles.ts +240 -0
- package/src/utilities/contours/updateContourPolyline.ts +74 -0
- package/src/utilities/livewire/LivewireScissors.ts +65 -53
- package/src/utilities/math/polyline/containsPoint.ts +1 -1
- package/src/utilities/math/polyline/containsPoints.ts +22 -0
- package/src/utilities/math/polyline/getWindingDirection.ts +14 -0
- package/src/utilities/math/polyline/index.ts +4 -0
- package/src/utilities/math/polyline/planarFreehandROIInternalTypes.ts +1 -0
- package/src/utilities/segmentation/InterpolationManager/InterpolationManager.ts +39 -4
- package/dist/cjs/utilities/contours/PointsArray.d.ts +0 -29
- package/dist/cjs/utilities/contours/PointsArray.js +0 -104
- package/dist/cjs/utilities/contours/PointsArray.js.map +0 -1
- package/dist/esm/utilities/contours/PointsArray.js +0 -98
- package/dist/esm/utilities/contours/PointsArray.js.map +0 -1
- package/dist/types/utilities/contours/PointsArray.d.ts +0 -30
- package/dist/types/utilities/contours/PointsArray.d.ts.map +0 -1
- package/src/utilities/contours/PointsArray.ts +0 -165
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { triggerEvent } from '@cornerstonejs/core';
|
|
1
|
+
import { triggerEvent, utilities } from '@cornerstonejs/core';
|
|
2
2
|
import type { Types } from '@cornerstonejs/core';
|
|
3
3
|
import { vec3 } from 'gl-matrix';
|
|
4
4
|
|
|
@@ -9,13 +9,20 @@ import type { InterpolationROIAnnotation } from '../../../types/ToolSpecificAnno
|
|
|
9
9
|
import type { AnnotationInterpolationCompletedEventDetail } from '../../../types/EventTypes';
|
|
10
10
|
import EventTypes from '../../../enums/Events';
|
|
11
11
|
import * as annotationState from '../../../stateManagement/annotation';
|
|
12
|
-
import
|
|
12
|
+
import selectHandles from './selectHandles';
|
|
13
|
+
|
|
14
|
+
const { PointsManager } = utilities;
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
17
|
* An XYZ encoded points that also includes an indicator I for whether the
|
|
16
18
|
* point is included in the original contour.
|
|
17
19
|
*/
|
|
18
|
-
type PointsXYZI = Types.PointsXYZ & {
|
|
20
|
+
export type PointsXYZI = Types.PointsXYZ & {
|
|
21
|
+
I?: boolean[];
|
|
22
|
+
kIndex?: number;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type PointsArray3 = Types.PointsManager<Types.Point3> & {
|
|
19
26
|
I?: boolean[];
|
|
20
27
|
};
|
|
21
28
|
|
|
@@ -25,7 +32,13 @@ let interpolating = false;
|
|
|
25
32
|
|
|
26
33
|
/**
|
|
27
34
|
* interpolate - Interpolate missing contours in the ROIContours.
|
|
28
|
-
* If input is tool data collection, it is expected to be sorted in the order
|
|
35
|
+
* If input is tool data collection, it is expected to be sorted in the order
|
|
36
|
+
* of stack image in which it was drawn.
|
|
37
|
+
*
|
|
38
|
+
* This is performed in a microtask in order to avoid delaying the event handler
|
|
39
|
+
* excessively, but to ensure it is completed before the data is additionally
|
|
40
|
+
* changed. It was originally done in a setTimeout, but that allowed the data
|
|
41
|
+
* to be updated between calls, causing issues with the interpolation process.
|
|
29
42
|
*
|
|
30
43
|
* @param viewportData - Object
|
|
31
44
|
* @returns null
|
|
@@ -35,11 +48,24 @@ function interpolate(viewportData: InterpolationViewportData) {
|
|
|
35
48
|
return;
|
|
36
49
|
}
|
|
37
50
|
interpolating = true;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
51
|
+
const { isInterpolationUpdate, annotation } = viewportData;
|
|
52
|
+
queueMicrotask(() => {
|
|
53
|
+
try {
|
|
54
|
+
if (isInterpolationUpdate) {
|
|
55
|
+
annotation.isInterpolationUpdate = true;
|
|
56
|
+
// This may not be true long term, but treat it as user generated for
|
|
57
|
+
// this run.
|
|
58
|
+
annotation.autoGenerated = false;
|
|
59
|
+
}
|
|
60
|
+
startInterpolation(viewportData);
|
|
61
|
+
} finally {
|
|
62
|
+
interpolating = false;
|
|
63
|
+
if (isInterpolationUpdate) {
|
|
64
|
+
// Reset the auto generated flag
|
|
65
|
+
annotation.autoGenerated = true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
43
69
|
}
|
|
44
70
|
|
|
45
71
|
/**
|
|
@@ -111,6 +137,8 @@ function _linearlyInterpolateBetween(
|
|
|
111
137
|
);
|
|
112
138
|
|
|
113
139
|
const { c1Interp, c2Interp } = _generateInterpolationContourPair(c1, c2);
|
|
140
|
+
c1Interp.kIndex = annotationPair[0];
|
|
141
|
+
c2Interp.kIndex = annotationPair[1];
|
|
114
142
|
|
|
115
143
|
// Using the newly constructed contours, interpolate each ROI.
|
|
116
144
|
indices.forEach(function (index) {
|
|
@@ -126,6 +154,16 @@ function _linearlyInterpolateBetween(
|
|
|
126
154
|
});
|
|
127
155
|
}
|
|
128
156
|
|
|
157
|
+
function getPointCount(pointArray) {
|
|
158
|
+
let sum = 0;
|
|
159
|
+
for (let i = 0; i < pointArray.I.length; i++) {
|
|
160
|
+
if (pointArray.I[i]) {
|
|
161
|
+
sum++;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return sum;
|
|
165
|
+
}
|
|
166
|
+
|
|
129
167
|
/**
|
|
130
168
|
* _linearlyInterpolateContour - Inserts a linearly interpolated contour at
|
|
131
169
|
* specified slice index.
|
|
@@ -133,7 +171,7 @@ function _linearlyInterpolateBetween(
|
|
|
133
171
|
* @param c1Interp - object, The first reference contour.
|
|
134
172
|
* @param c2Interp - object, The second reference contour.
|
|
135
173
|
* @param sliceIndex - Number, The slice index to interpolate.
|
|
136
|
-
* @param annotationPair - Number[], The slice
|
|
174
|
+
* @param annotationPair - Number[], The slice indices of the reference contours.
|
|
137
175
|
* @param interpolationData - object[], Data for the slice location of contours
|
|
138
176
|
* for the ROIContour.
|
|
139
177
|
* @param c1HasMoreNodes - boolean, True if c1 has more nodes than c2.
|
|
@@ -162,17 +200,7 @@ function _linearlyInterpolateContour(
|
|
|
162
200
|
annotationPair[zInterp > 0.5 ? 1 : 0]
|
|
163
201
|
)[0];
|
|
164
202
|
|
|
165
|
-
|
|
166
|
-
// enough handles for use.
|
|
167
|
-
const handleCount = Math.round(
|
|
168
|
-
Math.max(
|
|
169
|
-
8,
|
|
170
|
-
interpolationData.get(startIndex)[0].data.handles.points.length,
|
|
171
|
-
interpolationData.get(endIndex)[0].data.handles.points.length,
|
|
172
|
-
interpolated3DPoints.x.length / 50
|
|
173
|
-
)
|
|
174
|
-
);
|
|
175
|
-
const handlePoints = _subselect(interpolated3DPoints, handleCount);
|
|
203
|
+
const handlePoints = selectHandles(interpolated3DPoints);
|
|
176
204
|
|
|
177
205
|
if (interpolationData.has(sliceIndex)) {
|
|
178
206
|
_editInterpolatedContour(
|
|
@@ -193,25 +221,6 @@ function _linearlyInterpolateContour(
|
|
|
193
221
|
}
|
|
194
222
|
}
|
|
195
223
|
|
|
196
|
-
function _subselect(points, count = 10) {
|
|
197
|
-
const handles = [];
|
|
198
|
-
const { length } = points.x;
|
|
199
|
-
if (!length) {
|
|
200
|
-
return handles;
|
|
201
|
-
}
|
|
202
|
-
for (let i = 0; i < count; i++) {
|
|
203
|
-
const handleIndex = Math.floor((length * i) / count);
|
|
204
|
-
handles.push(
|
|
205
|
-
vec3.fromValues(
|
|
206
|
-
points.x[handleIndex],
|
|
207
|
-
points.y[handleIndex],
|
|
208
|
-
points.z[handleIndex]
|
|
209
|
-
)
|
|
210
|
-
);
|
|
211
|
-
}
|
|
212
|
-
return handles;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
224
|
/**
|
|
216
225
|
* _addInterpolatedContour - Adds a new contour to the imageId.
|
|
217
226
|
*
|
|
@@ -223,13 +232,13 @@ function _subselect(points, count = 10) {
|
|
|
223
232
|
* @returns null
|
|
224
233
|
*/
|
|
225
234
|
function _addInterpolatedContour(
|
|
226
|
-
interpolated3DPoints:
|
|
227
|
-
handlePoints:
|
|
235
|
+
interpolated3DPoints: PointsArray3,
|
|
236
|
+
handlePoints: PointsArray3,
|
|
228
237
|
sliceIndex: number,
|
|
229
238
|
referencedToolData,
|
|
230
239
|
eventData
|
|
231
240
|
) {
|
|
232
|
-
const points =
|
|
241
|
+
const points = interpolated3DPoints.points;
|
|
233
242
|
const { viewport } = eventData;
|
|
234
243
|
|
|
235
244
|
const interpolatedAnnotation = createPolylineToolData(
|
|
@@ -242,7 +251,7 @@ function _addInterpolatedContour(
|
|
|
242
251
|
interpolatedAnnotation.metadata.referencedImageId = targetId;
|
|
243
252
|
interpolatedAnnotation.metadata.referencedSliceIndex = sliceIndex;
|
|
244
253
|
annotationState.state.addAnnotation(interpolatedAnnotation, viewport.element);
|
|
245
|
-
referencedToolData.
|
|
254
|
+
referencedToolData.onInterpolationComplete?.(
|
|
246
255
|
interpolatedAnnotation,
|
|
247
256
|
referencedToolData
|
|
248
257
|
);
|
|
@@ -260,8 +269,8 @@ function _addInterpolatedContour(
|
|
|
260
269
|
* @returns null
|
|
261
270
|
*/
|
|
262
271
|
function _editInterpolatedContour(
|
|
263
|
-
interpolated3DPoints:
|
|
264
|
-
handlePoints:
|
|
272
|
+
interpolated3DPoints: PointsArray3,
|
|
273
|
+
handlePoints: PointsArray3,
|
|
265
274
|
sliceIndex,
|
|
266
275
|
referencedToolData,
|
|
267
276
|
eventData
|
|
@@ -296,7 +305,7 @@ function _editInterpolatedContour(
|
|
|
296
305
|
}
|
|
297
306
|
|
|
298
307
|
const oldToolData = annotations[toolDataIndex] as InterpolationROIAnnotation;
|
|
299
|
-
const points =
|
|
308
|
+
const points = interpolated3DPoints.points;
|
|
300
309
|
const interpolatedAnnotation = createPolylineToolData(
|
|
301
310
|
points,
|
|
302
311
|
handlePoints,
|
|
@@ -327,22 +336,39 @@ function _generateInterpolatedOpenContour(
|
|
|
327
336
|
c2ir,
|
|
328
337
|
zInterp,
|
|
329
338
|
c1HasMoreNodes
|
|
330
|
-
):
|
|
331
|
-
const cInterp = {
|
|
332
|
-
x: [],
|
|
333
|
-
y: [],
|
|
334
|
-
z: [],
|
|
335
|
-
};
|
|
336
|
-
|
|
339
|
+
): PointsArray3 {
|
|
337
340
|
const indices = c1HasMoreNodes ? c1ir.I : c2ir.I;
|
|
338
341
|
|
|
342
|
+
const c1 = PointsManager.fromXYZ(c1ir);
|
|
343
|
+
const c2 = PointsManager.fromXYZ(c2ir);
|
|
344
|
+
const { length } = c1;
|
|
345
|
+
const cInterp = PointsManager.create3(length) as PointsArray3;
|
|
346
|
+
|
|
347
|
+
const vecSubtract = vec3.create();
|
|
348
|
+
const vecResult = vec3.create();
|
|
349
|
+
const c1Source = PointsManager.create3(length);
|
|
350
|
+
c1Source.kIndex = c1ir.kIndex;
|
|
351
|
+
const c2Source = PointsManager.create3(length);
|
|
352
|
+
c2Source.kIndex = c2ir.kIndex;
|
|
353
|
+
|
|
339
354
|
for (let i = 0; i < c1ir.x.length; i++) {
|
|
340
355
|
if (indices[i]) {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
356
|
+
const c1point = c1.getPoint(i);
|
|
357
|
+
const c2point = c2.getPoint(i);
|
|
358
|
+
c1Source.push(c1point);
|
|
359
|
+
c2Source.push(c2point);
|
|
360
|
+
vec3.sub(vecSubtract, c2point, c1point);
|
|
361
|
+
cInterp.push(
|
|
362
|
+
vec3.scaleAndAdd(
|
|
363
|
+
vecResult,
|
|
364
|
+
c1point,
|
|
365
|
+
vecSubtract,
|
|
366
|
+
zInterp
|
|
367
|
+
) as Types.Point3
|
|
368
|
+
);
|
|
344
369
|
}
|
|
345
370
|
}
|
|
371
|
+
cInterp.sources = [c1Source, c2Source];
|
|
346
372
|
|
|
347
373
|
return cInterp;
|
|
348
374
|
}
|
|
@@ -370,12 +396,12 @@ function _generateInterpolationContourPair(c1, c2) {
|
|
|
370
396
|
const numNodes1 = interpNodes + c2.x.length;
|
|
371
397
|
const numNodes2 = interpNodes + c1.x.length;
|
|
372
398
|
|
|
373
|
-
//
|
|
399
|
+
// concatenate p && cumPerimNorm
|
|
374
400
|
const perim1Interp = _getInterpolatedPerim(numNodes1, cumPerim1Norm);
|
|
375
401
|
const perim2Interp = _getInterpolatedPerim(numNodes2, cumPerim2Norm);
|
|
376
402
|
|
|
377
|
-
const perim1Ind = _getIndicatorArray(
|
|
378
|
-
const perim2Ind = _getIndicatorArray(
|
|
403
|
+
const perim1Ind = _getIndicatorArray(numNodes1 - 2, c1.x.length);
|
|
404
|
+
const perim2Ind = _getIndicatorArray(numNodes2 - 2, c2.x.length);
|
|
379
405
|
|
|
380
406
|
const nodesPerSegment1 = _getNodesPerSegment(perim1Interp, perim1Ind);
|
|
381
407
|
const nodesPerSegment2 = _getNodesPerSegment(perim2Interp, perim2Ind);
|
|
@@ -398,13 +424,13 @@ function _generateInterpolationContourPair(c1, c2) {
|
|
|
398
424
|
* @returns An object containing the two reduced contours.
|
|
399
425
|
*/
|
|
400
426
|
function _reduceContoursToOriginNodes(c1i: PointsXYZI, c2i: PointsXYZI) {
|
|
401
|
-
const c1Interp = {
|
|
427
|
+
const c1Interp: PointsXYZI = {
|
|
402
428
|
x: [],
|
|
403
429
|
y: [],
|
|
404
430
|
z: [],
|
|
405
431
|
I: [],
|
|
406
432
|
};
|
|
407
|
-
const c2Interp = {
|
|
433
|
+
const c2Interp: PointsXYZI = {
|
|
408
434
|
x: [],
|
|
409
435
|
y: [],
|
|
410
436
|
z: [],
|
|
@@ -505,7 +531,7 @@ function _shiftCircularArray(arr, count) {
|
|
|
505
531
|
* per line segment.
|
|
506
532
|
* @returns object, The super sampled contour.
|
|
507
533
|
*/
|
|
508
|
-
function _getSuperSampledContour(c, nodesPerSegment) {
|
|
534
|
+
function _getSuperSampledContour(c, nodesPerSegment): PointsXYZI {
|
|
509
535
|
const ci = {
|
|
510
536
|
x: [],
|
|
511
537
|
y: [],
|
|
@@ -593,17 +619,10 @@ function _getNodesPerSegment(perimInterp, perimInd) {
|
|
|
593
619
|
* @param numNodes - Number, The number of nodes added.
|
|
594
620
|
* @returns boolean[], The indicator array of original node locations.
|
|
595
621
|
*/
|
|
596
|
-
function _getIndicatorArray(
|
|
597
|
-
const perimInd =
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
perimInd.push(false);
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
for (let i = 0; i < contour.x.length; i++) {
|
|
604
|
-
perimInd.push(true);
|
|
605
|
-
}
|
|
606
|
-
|
|
622
|
+
function _getIndicatorArray(numFalse, numTrue) {
|
|
623
|
+
const perimInd = new Array(numFalse + numTrue);
|
|
624
|
+
perimInd.fill(false, 0, numFalse);
|
|
625
|
+
perimInd.fill(true, numFalse, numFalse + numTrue);
|
|
607
626
|
return perimInd;
|
|
608
627
|
}
|
|
609
628
|
|
|
@@ -619,7 +638,7 @@ function _getInterpolatedPerim(numNodes, cumPerimNorm) {
|
|
|
619
638
|
const diff = 1 / (numNodes - 1);
|
|
620
639
|
const linspace = [diff];
|
|
621
640
|
|
|
622
|
-
// Length - 2 as we are discarding 0
|
|
641
|
+
// Length - 2 as we are discarding 0 and 1 for efficiency (no need to calculate them).
|
|
623
642
|
for (let i = 1; i < numNodes - 2; i++) {
|
|
624
643
|
linspace.push(linspace[linspace.length - 1] + diff);
|
|
625
644
|
}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { vec3 } from 'gl-matrix';
|
|
2
|
+
import { utilities } from '@cornerstonejs/core';
|
|
3
|
+
import type { PointsArray3 } from './interpolate';
|
|
4
|
+
import { add } from '@kitware/vtk.js/Common/Core/Math';
|
|
5
|
+
|
|
6
|
+
const { PointsManager } = utilities;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Selects handles by looking for local maximums in the angle that the local
|
|
10
|
+
* vector makes
|
|
11
|
+
*
|
|
12
|
+
* @param polyline - an array of points, usually the polyline for the contour to
|
|
13
|
+
* select handles from.
|
|
14
|
+
* @param handleCount - a guideline for how many handles to create
|
|
15
|
+
*/
|
|
16
|
+
export default function selectHandles(
|
|
17
|
+
polyline: PointsArray3,
|
|
18
|
+
handleCount = 8
|
|
19
|
+
): PointsArray3 {
|
|
20
|
+
const handles = PointsManager.create3(handleCount) as PointsArray3;
|
|
21
|
+
handles.sources = [];
|
|
22
|
+
const { sources: destPoints } = handles;
|
|
23
|
+
const { length, sources: sourcePoints = [] } = polyline;
|
|
24
|
+
const distance = 6;
|
|
25
|
+
if (length < distance * 3) {
|
|
26
|
+
console.log('Adding subselect handles', handleCount, length);
|
|
27
|
+
return polyline.subselect(handleCount);
|
|
28
|
+
}
|
|
29
|
+
const interval = Math.min(30, Math.floor(length / 3));
|
|
30
|
+
sourcePoints.forEach(() =>
|
|
31
|
+
destPoints.push(PointsManager.create3(handleCount))
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const dotValues = createDotValues(polyline, distance);
|
|
35
|
+
|
|
36
|
+
const minimumRegions = findMinimumRegions(dotValues, handleCount);
|
|
37
|
+
const indices = [];
|
|
38
|
+
if (minimumRegions?.length > 2) {
|
|
39
|
+
let lastHandle = -1;
|
|
40
|
+
const thirdInterval = interval / 3;
|
|
41
|
+
minimumRegions.forEach((region) => {
|
|
42
|
+
const [start, , end] = region;
|
|
43
|
+
const midIndex = Math.ceil((start + end) / 2);
|
|
44
|
+
if (end - lastHandle < thirdInterval) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (midIndex - start > 2 * thirdInterval) {
|
|
48
|
+
addInterval(indices, lastHandle, start, interval, length);
|
|
49
|
+
lastHandle = addInterval(indices, start, midIndex, interval, length);
|
|
50
|
+
} else {
|
|
51
|
+
lastHandle = addInterval(
|
|
52
|
+
indices,
|
|
53
|
+
lastHandle,
|
|
54
|
+
midIndex,
|
|
55
|
+
interval,
|
|
56
|
+
length
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
if (end - lastHandle > thirdInterval) {
|
|
60
|
+
lastHandle = addInterval(indices, lastHandle, end, interval, length);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
const firstHandle = indices[0];
|
|
64
|
+
const lastDistance = indexValue(firstHandle + length - lastHandle, length);
|
|
65
|
+
// Check that there is enough space between the last and first handle to
|
|
66
|
+
// need an extra handle.
|
|
67
|
+
if (lastDistance > 2 * thirdInterval) {
|
|
68
|
+
addInterval(
|
|
69
|
+
indices,
|
|
70
|
+
lastHandle,
|
|
71
|
+
// Don't add a point too close to the first handle
|
|
72
|
+
firstHandle - thirdInterval,
|
|
73
|
+
interval,
|
|
74
|
+
length
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
const interval = Math.floor(length / handleCount);
|
|
79
|
+
addInterval(indices, -1, length - interval, interval, length);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
indices.forEach((index) => {
|
|
83
|
+
const point = polyline.getPointArray(index);
|
|
84
|
+
handles.push(point);
|
|
85
|
+
sourcePoints.forEach((source, destSourceIndex) =>
|
|
86
|
+
destPoints[destSourceIndex].push(source.getPoint(index))
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
return handles;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Creates an array of the dot products between each point in the points array
|
|
94
|
+
* and a point +/- distance from that point, unitized to vector length 1.
|
|
95
|
+
* That is, this is a measure of the angle at the given point, where 1 is a
|
|
96
|
+
* straight line, and -1 is a 180 degree angle change.
|
|
97
|
+
*
|
|
98
|
+
* @param polyline - the array of Point3 values
|
|
99
|
+
* @param distance - previous/next distance to use for the vectors for the dot product
|
|
100
|
+
* @returns - Float32Array of dot products, one per point in the source array.
|
|
101
|
+
*/
|
|
102
|
+
export function createDotValues(
|
|
103
|
+
polyline: PointsArray3,
|
|
104
|
+
distance = 6
|
|
105
|
+
): Float32Array {
|
|
106
|
+
const { length } = polyline;
|
|
107
|
+
const prevVec3 = vec3.create();
|
|
108
|
+
const nextVec3 = vec3.create();
|
|
109
|
+
const dotValues = new Float32Array(length);
|
|
110
|
+
|
|
111
|
+
for (let i = 0; i < length; i++) {
|
|
112
|
+
const point = polyline.getPoint(i);
|
|
113
|
+
const prevPoint = polyline.getPoint(i - distance);
|
|
114
|
+
const nextPoint = polyline.getPoint((i + distance) % length);
|
|
115
|
+
vec3.sub(prevVec3, point, prevPoint);
|
|
116
|
+
vec3.sub(nextVec3, nextPoint, point);
|
|
117
|
+
const dot =
|
|
118
|
+
vec3.dot(prevVec3, nextVec3) / (vec3.len(prevVec3) * vec3.len(nextVec3));
|
|
119
|
+
dotValues[i] = dot;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return dotValues;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Finds minimum regions in the dot products. These are detected as
|
|
127
|
+
* center points of the dot values regions having a minimum value - that is,
|
|
128
|
+
* where the direction of the line is changing fastest.
|
|
129
|
+
*/
|
|
130
|
+
function findMinimumRegions(dotValues, handleCount) {
|
|
131
|
+
const { max, deviation } = getStats(dotValues);
|
|
132
|
+
const { length } = dotValues;
|
|
133
|
+
// Fallback for very uniform ojects.
|
|
134
|
+
if (deviation < 0.01 || length < handleCount * 3) {
|
|
135
|
+
// TODO - create handleCount evenly spaced handles
|
|
136
|
+
return [0, Math.floor(length / 3), Math.floor((length * 2) / 3)];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const inflection = [];
|
|
140
|
+
let pair = null;
|
|
141
|
+
let minValue;
|
|
142
|
+
let minIndex = 0;
|
|
143
|
+
|
|
144
|
+
for (let i = 0; i < length; i++) {
|
|
145
|
+
const dot = dotValues[i];
|
|
146
|
+
if (dot < max - deviation) {
|
|
147
|
+
if (pair) {
|
|
148
|
+
pair[2] = i;
|
|
149
|
+
if (dot < minValue) {
|
|
150
|
+
minValue = dot;
|
|
151
|
+
minIndex = i;
|
|
152
|
+
}
|
|
153
|
+
pair[1] = minIndex;
|
|
154
|
+
} else {
|
|
155
|
+
minValue = dot;
|
|
156
|
+
minIndex = i;
|
|
157
|
+
pair = [i, i, i];
|
|
158
|
+
}
|
|
159
|
+
} else {
|
|
160
|
+
if (pair) {
|
|
161
|
+
inflection.push(pair);
|
|
162
|
+
pair = null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (pair) {
|
|
167
|
+
if (inflection[0][0] === 0) {
|
|
168
|
+
inflection[0][0] = pair[0];
|
|
169
|
+
} else {
|
|
170
|
+
pair[1] = minIndex;
|
|
171
|
+
pair[2] = length - 1;
|
|
172
|
+
inflection.push(pair);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return inflection;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Adds points in between the start and finish.
|
|
181
|
+
* This is currently just the center point for short values and the start/center/end
|
|
182
|
+
* for ranges where the distance between these is at least the increment.
|
|
183
|
+
*/
|
|
184
|
+
export function addInterval(indices, start, finish, interval, length) {
|
|
185
|
+
if (finish < start) {
|
|
186
|
+
// Always want a positive distance even if the long way round
|
|
187
|
+
finish += length;
|
|
188
|
+
}
|
|
189
|
+
const distance = finish - start;
|
|
190
|
+
const count = Math.ceil(distance / interval);
|
|
191
|
+
if (count <= 0) {
|
|
192
|
+
if (indices[indices.length - 1] !== finish) {
|
|
193
|
+
indices.push(indexValue(finish, length));
|
|
194
|
+
}
|
|
195
|
+
return finish;
|
|
196
|
+
}
|
|
197
|
+
// Don't add the start index, and always add the end index
|
|
198
|
+
for (let i = 1; i <= count; i++) {
|
|
199
|
+
const index = indexValue(start + (i * distance) / count, length);
|
|
200
|
+
indices.push(index);
|
|
201
|
+
}
|
|
202
|
+
return indices[indices.length - 1];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Gets the index value of a closed polyline, rounding the value and
|
|
207
|
+
* doing the module operation as required.
|
|
208
|
+
*/
|
|
209
|
+
function indexValue(v, length) {
|
|
210
|
+
return (Math.round(v) + length) % length;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Gets statistics on the provided array numbers.
|
|
215
|
+
*/
|
|
216
|
+
function getStats(dotValues) {
|
|
217
|
+
const { length } = dotValues;
|
|
218
|
+
let sum = 0;
|
|
219
|
+
let min = Infinity;
|
|
220
|
+
let max = -Infinity;
|
|
221
|
+
let sumSq = 0;
|
|
222
|
+
for (let i = 0; i < length; i++) {
|
|
223
|
+
const dot = dotValues[i];
|
|
224
|
+
sum += dot;
|
|
225
|
+
min = Math.min(min, dot);
|
|
226
|
+
max = Math.max(max, dot);
|
|
227
|
+
}
|
|
228
|
+
const mean = sum / length;
|
|
229
|
+
for (let i = 0; i < length; i++) {
|
|
230
|
+
const valueDiff = dotValues[i] - mean;
|
|
231
|
+
sumSq += valueDiff * valueDiff;
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
mean,
|
|
235
|
+
max,
|
|
236
|
+
min,
|
|
237
|
+
sumSq,
|
|
238
|
+
deviation: Math.sqrt(sumSq / length),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { utilities as csUtils } from '@cornerstonejs/core';
|
|
2
|
+
import { Types } from '@cornerstonejs/core';
|
|
3
|
+
import type { ContourAnnotation } from '../../types';
|
|
4
|
+
import type { ContourWindingDirection } from '../../types/ContourAnnotation';
|
|
5
|
+
import * as math from '../math';
|
|
6
|
+
import {
|
|
7
|
+
getParentAnnotation,
|
|
8
|
+
invalidateAnnotation,
|
|
9
|
+
} from '../../stateManagement';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Update the contour polyline data
|
|
13
|
+
* @param annotation - Contour annotation
|
|
14
|
+
* @param viewport - Viewport
|
|
15
|
+
* @param polylineData - Polyline data (points, winding direction and closed)
|
|
16
|
+
* @param transforms - Methods to convert points to/from canvas and world spaces
|
|
17
|
+
*/
|
|
18
|
+
export default function updateContourPolyline(
|
|
19
|
+
annotation: ContourAnnotation,
|
|
20
|
+
polylineData: {
|
|
21
|
+
points: Types.Point2[];
|
|
22
|
+
closed?: boolean;
|
|
23
|
+
targetWindingDirection?: ContourWindingDirection;
|
|
24
|
+
},
|
|
25
|
+
transforms: {
|
|
26
|
+
canvasToWorld: (point: Types.Point2) => Types.Point3;
|
|
27
|
+
}
|
|
28
|
+
) {
|
|
29
|
+
const { canvasToWorld } = transforms;
|
|
30
|
+
const { data } = annotation;
|
|
31
|
+
const { points: polyline, targetWindingDirection } = polylineData;
|
|
32
|
+
let { closed } = polylineData;
|
|
33
|
+
const numPoints = polyline.length;
|
|
34
|
+
const polylineWorldPoints = new Array(numPoints);
|
|
35
|
+
const currentWindingDirection = math.polyline.getWindingDirection(polyline);
|
|
36
|
+
const parentAnnotation = getParentAnnotation(annotation) as ContourAnnotation;
|
|
37
|
+
|
|
38
|
+
if (closed === undefined) {
|
|
39
|
+
let currentClosedState = false;
|
|
40
|
+
|
|
41
|
+
// With two points it is just a line and do not make sense to consider it closed
|
|
42
|
+
if (polyline.length > 3) {
|
|
43
|
+
const lastToFirstDist = math.point.distanceToPointSquared(
|
|
44
|
+
polyline[0],
|
|
45
|
+
polyline[numPoints - 1]
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
currentClosedState = csUtils.isEqual(0, lastToFirstDist);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
closed = currentClosedState;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// It must be in the opposite direction if it is a child annotation (hole)
|
|
55
|
+
let windingDirection = parentAnnotation
|
|
56
|
+
? parentAnnotation.data.contour.windingDirection * -1
|
|
57
|
+
: targetWindingDirection;
|
|
58
|
+
|
|
59
|
+
if (windingDirection === undefined) {
|
|
60
|
+
windingDirection = currentWindingDirection;
|
|
61
|
+
} else if (windingDirection !== currentWindingDirection) {
|
|
62
|
+
polyline.reverse();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
for (let i = 0; i < numPoints; i++) {
|
|
66
|
+
polylineWorldPoints[i] = canvasToWorld(polyline[i]);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
data.contour.polyline = polylineWorldPoints;
|
|
70
|
+
data.contour.closed = closed;
|
|
71
|
+
data.contour.windingDirection = windingDirection;
|
|
72
|
+
|
|
73
|
+
invalidateAnnotation(annotation);
|
|
74
|
+
}
|