@cornerstonejs/tools 1.52.0 → 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 +2 -10
- 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/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 +2 -1
- package/dist/cjs/stateManagement/annotation/helpers/state.js +14 -3
- 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.js +1 -1
- package/dist/cjs/tools/annotation/LivewireContourSegmentationTool.js.map +1 -1
- package/dist/cjs/tools/annotation/LivewireContourTool.d.ts +4 -3
- package/dist/cjs/tools/annotation/LivewireContourTool.js +26 -26
- package/dist/cjs/tools/annotation/LivewireContourTool.js.map +1 -1
- package/dist/cjs/tools/annotation/PlanarFreehandROITool.js +1 -0
- 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 +37 -18
- 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/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/SplineProps.d.ts +1 -0
- 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/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/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/esm/drawingSvg/drawPath.js +49 -0
- package/dist/esm/drawingSvg/drawPath.js.map +1 -0
- package/dist/esm/drawingSvg/drawPolyline.js +2 -10
- 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/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 +12 -2
- 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 +1 -1
- package/dist/esm/tools/annotation/LivewireContourSegmentationTool.js.map +1 -1
- package/dist/esm/tools/annotation/LivewireContourTool.js +28 -28
- package/dist/esm/tools/annotation/LivewireContourTool.js.map +1 -1
- package/dist/esm/tools/annotation/PlanarFreehandROITool.js +2 -1
- package/dist/esm/tools/annotation/PlanarFreehandROITool.js.map +1 -1
- package/dist/esm/tools/annotation/SplineROITool.js +37 -19
- 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/updateContourPolyline.js +38 -0
- package/dist/esm/utilities/contours/updateContourPolyline.js.map +1 -0
- 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/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/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 +2 -1
- 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/LivewireContourTool.d.ts +4 -3
- 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/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/SplineProps.d.ts +1 -0
- package/dist/types/types/SplineProps.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/updateContourPolyline.d.ts +11 -0
- package/dist/types/utilities/contours/updateContourPolyline.d.ts.map +1 -0
- 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/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 +12 -16
- package/src/drawingSvg/index.ts +2 -0
- 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 +29 -1
- 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 +1 -1
- package/src/tools/annotation/LivewireContourTool.ts +65 -38
- package/src/tools/annotation/PlanarFreehandROITool.ts +6 -1
- package/src/tools/annotation/SplineROITool.ts +75 -28
- 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/ContourTypes.ts +3 -0
- package/src/types/EventTypes.ts +9 -0
- package/src/types/ISpline.ts +3 -0
- package/src/types/SplineProps.ts +10 -0
- 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/updateContourPolyline.ts +74 -0
- 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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/tools",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.53.0",
|
|
4
4
|
"description": "Cornerstone3D Tools",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "dist/types/index.d.ts",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"webpack:watch": "webpack --mode development --progress --watch --config ./.webpack/webpack.dev.js"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@cornerstonejs/core": "^1.
|
|
32
|
+
"@cornerstonejs/core": "^1.53.0",
|
|
33
33
|
"comlink": "^4.4.1",
|
|
34
34
|
"lodash.clonedeep": "4.5.0",
|
|
35
35
|
"lodash.get": "^4.4.2"
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"type": "individual",
|
|
54
54
|
"url": "https://ohif.org/donate"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "881872ffe29341443f91cead0b810871a6a1929b"
|
|
57
57
|
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { Types } from '@cornerstonejs/core';
|
|
2
|
+
import _getHash from './_getHash';
|
|
3
|
+
import setNewAttributesIfValid from './setNewAttributesIfValid';
|
|
4
|
+
import setAttributesIfNecessary from './setAttributesIfNecessary';
|
|
5
|
+
import { SVGDrawingHelper } from '../types';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Draws an SVG path with the given points.
|
|
9
|
+
*
|
|
10
|
+
* The `closePath` option, if true, draws a closed path (last point
|
|
11
|
+
* connected to the first).
|
|
12
|
+
*/
|
|
13
|
+
export default function drawPath(
|
|
14
|
+
svgDrawingHelper: SVGDrawingHelper,
|
|
15
|
+
annotationUID: string,
|
|
16
|
+
pathUID: string,
|
|
17
|
+
points: Types.Point2[] | Types.Point2[][],
|
|
18
|
+
options: {
|
|
19
|
+
color?: string;
|
|
20
|
+
fillColor?: string;
|
|
21
|
+
fillOpacity?: number;
|
|
22
|
+
width?: number;
|
|
23
|
+
lineWidth?: number;
|
|
24
|
+
lineDash?: string;
|
|
25
|
+
closePath?: boolean;
|
|
26
|
+
}
|
|
27
|
+
): void {
|
|
28
|
+
// It may be a polyline with holes that will be an array with multiple
|
|
29
|
+
// 'points' arrays
|
|
30
|
+
const hasSubArrays =
|
|
31
|
+
points.length && points[0].length && Array.isArray(points[0][0]);
|
|
32
|
+
|
|
33
|
+
const pointsArrays = hasSubArrays ? points : [points];
|
|
34
|
+
const {
|
|
35
|
+
color = 'dodgerblue',
|
|
36
|
+
width = 10,
|
|
37
|
+
fillColor = 'none',
|
|
38
|
+
fillOpacity = 0,
|
|
39
|
+
lineWidth,
|
|
40
|
+
lineDash,
|
|
41
|
+
closePath = false,
|
|
42
|
+
} = options;
|
|
43
|
+
|
|
44
|
+
// for supporting both lineWidth and width options
|
|
45
|
+
const strokeWidth = lineWidth || width;
|
|
46
|
+
|
|
47
|
+
const svgns = 'http://www.w3.org/2000/svg';
|
|
48
|
+
const svgNodeHash = _getHash(annotationUID, 'path', pathUID);
|
|
49
|
+
const existingNode = svgDrawingHelper.getSvgNode(svgNodeHash);
|
|
50
|
+
let pointsAttribute = '';
|
|
51
|
+
|
|
52
|
+
for (let i = 0, numArrays = pointsArrays.length; i < numArrays; i++) {
|
|
53
|
+
const points = pointsArrays[i];
|
|
54
|
+
const numPoints = points.length;
|
|
55
|
+
|
|
56
|
+
if (numPoints < 2) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (let j = 0; j < numPoints; j++) {
|
|
61
|
+
const point = points[j];
|
|
62
|
+
const cmd = j ? 'L' : 'M';
|
|
63
|
+
|
|
64
|
+
pointsAttribute += `${cmd} ${point[0]},${point[1]} `;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (closePath) {
|
|
68
|
+
pointsAttribute += 'Z ';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!pointsAttribute) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const attributes = {
|
|
77
|
+
d: pointsAttribute,
|
|
78
|
+
stroke: color,
|
|
79
|
+
fill: fillColor,
|
|
80
|
+
'fill-opacity': fillOpacity,
|
|
81
|
+
'stroke-width': strokeWidth,
|
|
82
|
+
'stroke-dasharray': lineDash,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
if (existingNode) {
|
|
86
|
+
// This is run to avoid re-rendering annotations that actually haven't changed
|
|
87
|
+
setAttributesIfNecessary(attributes, existingNode);
|
|
88
|
+
|
|
89
|
+
svgDrawingHelper.setNodeTouched(svgNodeHash);
|
|
90
|
+
} else {
|
|
91
|
+
const newNode = document.createElementNS(svgns, 'path');
|
|
92
|
+
|
|
93
|
+
setNewAttributesIfValid(attributes, newNode);
|
|
94
|
+
svgDrawingHelper.appendNode(newNode, svgNodeHash);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -7,7 +7,7 @@ import { SVGDrawingHelper } from '../types';
|
|
|
7
7
|
/**
|
|
8
8
|
* Draws an SVG polyline with the given points.
|
|
9
9
|
*
|
|
10
|
-
* The `
|
|
10
|
+
* The `closePath` option, if true, draws a closed polyline, with the
|
|
11
11
|
* last point connected to the first.
|
|
12
12
|
*/
|
|
13
13
|
export default function drawPolyline(
|
|
@@ -22,26 +22,22 @@ export default function drawPolyline(
|
|
|
22
22
|
width?: number;
|
|
23
23
|
lineWidth?: number;
|
|
24
24
|
lineDash?: string;
|
|
25
|
-
|
|
25
|
+
closePath?: boolean;
|
|
26
26
|
}
|
|
27
27
|
): void {
|
|
28
28
|
if (points.length < 2) {
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
const {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
connectLastToFirst: false,
|
|
42
|
-
},
|
|
43
|
-
options
|
|
44
|
-
);
|
|
32
|
+
const {
|
|
33
|
+
color = 'dodgerblue',
|
|
34
|
+
width = 10,
|
|
35
|
+
fillColor = 'none',
|
|
36
|
+
fillOpacity = 0,
|
|
37
|
+
lineWidth,
|
|
38
|
+
lineDash,
|
|
39
|
+
closePath = false,
|
|
40
|
+
} = options;
|
|
45
41
|
|
|
46
42
|
// for supporting both lineWidth and width options
|
|
47
43
|
const strokeWidth = lineWidth || width;
|
|
@@ -56,7 +52,7 @@ export default function drawPolyline(
|
|
|
56
52
|
pointsAttribute += `${point[0].toFixed(1)}, ${point[1].toFixed(1)} `;
|
|
57
53
|
}
|
|
58
54
|
|
|
59
|
-
if (
|
|
55
|
+
if (closePath) {
|
|
60
56
|
const firstPoint = points[0];
|
|
61
57
|
|
|
62
58
|
pointsAttribute += `${firstPoint[0]}, ${firstPoint[1]}`;
|
package/src/drawingSvg/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import drawHandles from './drawHandles';
|
|
|
6
6
|
import drawHandle from './drawHandle';
|
|
7
7
|
import drawLine from './drawLine';
|
|
8
8
|
import drawPolyline from './drawPolyline';
|
|
9
|
+
import drawPath from './drawPath';
|
|
9
10
|
import drawLinkedTextBox from './drawLinkedTextBox';
|
|
10
11
|
import drawRect from './drawRect';
|
|
11
12
|
import drawTextBox from './drawTextBox';
|
|
@@ -23,6 +24,7 @@ export {
|
|
|
23
24
|
drawHandle,
|
|
24
25
|
drawLine,
|
|
25
26
|
drawPolyline,
|
|
27
|
+
drawPath,
|
|
26
28
|
drawLinkedTextBox,
|
|
27
29
|
drawRect,
|
|
28
30
|
drawTextBox,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ToolGroupManager } from '../../store';
|
|
2
|
-
import {
|
|
2
|
+
import { ToolModes } from '../../enums';
|
|
3
3
|
import { keyEventListener } from '../../eventListeners';
|
|
4
4
|
import { EventTypes } from '../../types';
|
|
5
5
|
import getMouseModifier from './getMouseModifier';
|
|
@@ -14,16 +14,24 @@ import {
|
|
|
14
14
|
getAnnotations,
|
|
15
15
|
addAnnotation,
|
|
16
16
|
removeAnnotation,
|
|
17
|
+
getChildAnnotations,
|
|
18
|
+
addChildAnnotation,
|
|
19
|
+
clearParentAnnotation,
|
|
17
20
|
} from '../../../stateManagement/annotation/annotationState';
|
|
18
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
AnnotationCompletedEventType,
|
|
23
|
+
ContourAnnotationCompletedEventDetail,
|
|
24
|
+
} from '../../../types/EventTypes';
|
|
19
25
|
import * as contourUtils from '../../../utilities/contours';
|
|
20
26
|
import * as contourSegUtils from '../../../utilities/contourSegmentation';
|
|
21
27
|
import { ToolGroupManager, hasTool as cstHasTool } from '../../../store';
|
|
22
28
|
import { PlanarFreehandContourSegmentationTool } from '../../../tools';
|
|
29
|
+
import type { ContourAnnotation } from '../../../types/ContourAnnotation';
|
|
30
|
+
import { ContourWindingDirection } from '../../../types/ContourAnnotation';
|
|
23
31
|
|
|
24
32
|
const DEFAULT_CONTOUR_SEG_TOOLNAME = 'PlanarFreehandContourSegmentationTool';
|
|
25
33
|
|
|
26
|
-
export default function contourSegmentationCompletedListener(
|
|
34
|
+
export default async function contourSegmentationCompletedListener(
|
|
27
35
|
evt: AnnotationCompletedEventType
|
|
28
36
|
) {
|
|
29
37
|
const sourceAnnotation = evt.detail
|
|
@@ -60,15 +68,28 @@ export default function contourSegmentationCompletedListener(
|
|
|
60
68
|
return;
|
|
61
69
|
}
|
|
62
70
|
|
|
63
|
-
const { targetAnnotation, targetPolyline } =
|
|
71
|
+
const { targetAnnotation, targetPolyline, isContourHole } =
|
|
72
|
+
targetAnnotationInfo;
|
|
64
73
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
74
|
+
if (isContourHole) {
|
|
75
|
+
const { contourHoleProcessingEnabled = false } =
|
|
76
|
+
evt.detail as ContourAnnotationCompletedEventDetail;
|
|
77
|
+
|
|
78
|
+
// Do not create holes when contourHoleProcessingEnabled is `false`
|
|
79
|
+
if (!contourHoleProcessingEnabled) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
createPolylineHole(viewport, targetAnnotation, sourceAnnotation);
|
|
84
|
+
} else {
|
|
85
|
+
combinePolylines(
|
|
86
|
+
viewport,
|
|
87
|
+
targetAnnotation,
|
|
88
|
+
targetPolyline,
|
|
89
|
+
sourceAnnotation,
|
|
90
|
+
sourcePolyline
|
|
91
|
+
);
|
|
92
|
+
}
|
|
72
93
|
}
|
|
73
94
|
|
|
74
95
|
function isFreehandContourSegToolRegistered(viewport: Types.IViewport) {
|
|
@@ -111,26 +132,16 @@ function convertContourPolylineToCanvasSpace(
|
|
|
111
132
|
return projectedPolyline;
|
|
112
133
|
}
|
|
113
134
|
|
|
114
|
-
function convertPolylineToWorldSpace(
|
|
115
|
-
polyline: Types.Point2[],
|
|
116
|
-
viewport: Types.IViewport
|
|
117
|
-
): Types.Point3[] {
|
|
118
|
-
const numPoints = polyline.length;
|
|
119
|
-
const projectedPolyline = new Array(numPoints);
|
|
120
|
-
|
|
121
|
-
for (let i = 0; i < numPoints; i++) {
|
|
122
|
-
projectedPolyline[i] = viewport.canvasToWorld(polyline[i]);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return projectedPolyline;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
135
|
function getValidContourSegmentationAnnotations(
|
|
129
136
|
sourceAnnotation: ContourSegmentationAnnotation
|
|
130
137
|
): ContourSegmentationAnnotation[] {
|
|
131
138
|
const { annotationUID: sourceAnnotationUID } = sourceAnnotation;
|
|
132
139
|
const { FrameOfReferenceUID } = sourceAnnotation.metadata;
|
|
133
140
|
|
|
141
|
+
if (!FrameOfReferenceUID) {
|
|
142
|
+
return [];
|
|
143
|
+
}
|
|
144
|
+
|
|
134
145
|
// Get all annotations and filter all contour segmentations locally
|
|
135
146
|
const toolName = undefined;
|
|
136
147
|
const annotationsGroups = getAnnotations(toolName, FrameOfReferenceUID);
|
|
@@ -157,6 +168,7 @@ function findIntersectingContour(
|
|
|
157
168
|
): {
|
|
158
169
|
targetAnnotation: ContourSegmentationAnnotation;
|
|
159
170
|
targetPolyline: Types.Point2[];
|
|
171
|
+
isContourHole: boolean;
|
|
160
172
|
} {
|
|
161
173
|
const sourceAABB = math.polyline.getAABB(sourcePolyline);
|
|
162
174
|
|
|
@@ -168,22 +180,81 @@ function findIntersectingContour(
|
|
|
168
180
|
);
|
|
169
181
|
|
|
170
182
|
const targetAABB = math.polyline.getAABB(targetPolyline);
|
|
171
|
-
const
|
|
172
|
-
|
|
183
|
+
const aabbIntersect = math.aabb.intersectAABB(sourceAABB, targetAABB);
|
|
184
|
+
const lineSegmentsIntersect =
|
|
185
|
+
aabbIntersect &&
|
|
173
186
|
math.polyline.intersectPolyline(sourcePolyline, targetPolyline);
|
|
187
|
+
const isContourHole =
|
|
188
|
+
aabbIntersect &&
|
|
189
|
+
!lineSegmentsIntersect &&
|
|
190
|
+
math.polyline.containsPoints(targetPolyline, sourcePolyline);
|
|
174
191
|
|
|
175
|
-
if (
|
|
176
|
-
return { targetAnnotation, targetPolyline };
|
|
192
|
+
if (lineSegmentsIntersect || isContourHole) {
|
|
193
|
+
return { targetAnnotation, targetPolyline, isContourHole };
|
|
177
194
|
}
|
|
178
195
|
}
|
|
179
196
|
}
|
|
180
197
|
|
|
181
|
-
function
|
|
198
|
+
function createPolylineHole(
|
|
199
|
+
viewport: Types.IViewport,
|
|
200
|
+
targetAnnotation: ContourSegmentationAnnotation,
|
|
201
|
+
holeAnnotation: ContourSegmentationAnnotation
|
|
202
|
+
) {
|
|
203
|
+
const { windingDirection: targetWindingDirection } =
|
|
204
|
+
targetAnnotation.data.contour;
|
|
205
|
+
const { windingDirection: holeWindingDirection } =
|
|
206
|
+
holeAnnotation.data.contour;
|
|
207
|
+
|
|
208
|
+
// Check if both normals are pointing to the same direction because the
|
|
209
|
+
// polyline for the hole needs to be in a different direction
|
|
210
|
+
// if (glMatrix.equals(1, dotNormals)) {
|
|
211
|
+
if (targetWindingDirection === holeWindingDirection) {
|
|
212
|
+
holeAnnotation.data.contour.polyline.reverse();
|
|
213
|
+
holeAnnotation.data.contour.windingDirection = targetWindingDirection * -1;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
addChildAnnotation(targetAnnotation, holeAnnotation);
|
|
217
|
+
|
|
218
|
+
const { element } = viewport;
|
|
219
|
+
const enabledElement = getEnabledElement(element);
|
|
220
|
+
const { renderingEngine } = enabledElement;
|
|
221
|
+
|
|
222
|
+
// Updating a Spline contours, for example, should also update freehand contours
|
|
223
|
+
const updatedToolNames = new Set([
|
|
224
|
+
DEFAULT_CONTOUR_SEG_TOOLNAME,
|
|
225
|
+
targetAnnotation.metadata.toolName,
|
|
226
|
+
holeAnnotation.metadata.toolName,
|
|
227
|
+
]);
|
|
228
|
+
|
|
229
|
+
for (const toolName of updatedToolNames.values()) {
|
|
230
|
+
const viewportIdsToRender = getViewportIdsWithToolToRender(
|
|
231
|
+
element,
|
|
232
|
+
toolName
|
|
233
|
+
);
|
|
234
|
+
triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function getContourHolesData(
|
|
239
|
+
viewport: Types.IViewport,
|
|
240
|
+
annotation: ContourAnnotation
|
|
241
|
+
) {
|
|
242
|
+
return getChildAnnotations(annotation).map((holeAnnotation) => {
|
|
243
|
+
const polyline = convertContourPolylineToCanvasSpace(
|
|
244
|
+
holeAnnotation.data.contour.polyline,
|
|
245
|
+
viewport
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
return { annotation: holeAnnotation, polyline };
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async function combinePolylines(
|
|
182
253
|
viewport: Types.IViewport,
|
|
183
|
-
sourceAnnotation: ContourSegmentationAnnotation,
|
|
184
|
-
sourcePolyline: Types.Point2[],
|
|
185
254
|
targetAnnotation: ContourSegmentationAnnotation,
|
|
186
|
-
targetPolyline: Types.Point2[]
|
|
255
|
+
targetPolyline: Types.Point2[],
|
|
256
|
+
sourceAnnotation: ContourSegmentationAnnotation,
|
|
257
|
+
sourcePolyline: Types.Point2[]
|
|
187
258
|
) {
|
|
188
259
|
const sourceStartPoint = sourcePolyline[0];
|
|
189
260
|
const mergePolylines = math.polyline.containsPoint(
|
|
@@ -191,6 +262,20 @@ function processContours(
|
|
|
191
262
|
sourceStartPoint
|
|
192
263
|
);
|
|
193
264
|
|
|
265
|
+
const contourHolesData = getContourHolesData(viewport, targetAnnotation);
|
|
266
|
+
const unassignedContourHolesSet = new Set(contourHolesData);
|
|
267
|
+
const reassignedContourHolesMap = new Map();
|
|
268
|
+
const assignHoleToPolyline = (parentPolyline, holeData) => {
|
|
269
|
+
let holes = reassignedContourHolesMap.get(parentPolyline);
|
|
270
|
+
|
|
271
|
+
if (!holes) {
|
|
272
|
+
holes = [];
|
|
273
|
+
reassignedContourHolesMap.set(parentPolyline, holes);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
holes.push(holeData);
|
|
277
|
+
unassignedContourHolesSet.delete(holeData);
|
|
278
|
+
};
|
|
194
279
|
const newPolylines = [];
|
|
195
280
|
|
|
196
281
|
if (mergePolylines) {
|
|
@@ -200,32 +285,58 @@ function processContours(
|
|
|
200
285
|
);
|
|
201
286
|
|
|
202
287
|
newPolylines.push(mergedPolyline);
|
|
288
|
+
|
|
289
|
+
// Keep all holes because the contour can only grow when merging and there
|
|
290
|
+
// is no chance for any hole to be removed
|
|
291
|
+
Array.from(unassignedContourHolesSet.keys()).forEach((holeData) =>
|
|
292
|
+
assignHoleToPolyline(mergedPolyline, holeData)
|
|
293
|
+
);
|
|
203
294
|
} else {
|
|
204
295
|
const subtractedPolylines = math.polyline.subtractPolylines(
|
|
205
296
|
targetPolyline,
|
|
206
297
|
sourcePolyline
|
|
207
298
|
);
|
|
208
299
|
|
|
209
|
-
subtractedPolylines.forEach((newPolyline) =>
|
|
210
|
-
newPolylines.push(newPolyline)
|
|
211
|
-
|
|
300
|
+
subtractedPolylines.forEach((newPolyline) => {
|
|
301
|
+
newPolylines.push(newPolyline);
|
|
302
|
+
|
|
303
|
+
Array.from(unassignedContourHolesSet.keys()).forEach((holeData) => {
|
|
304
|
+
const containsHole = math.polyline.containsPoints(
|
|
305
|
+
newPolyline,
|
|
306
|
+
holeData.polyline
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
if (containsHole) {
|
|
310
|
+
assignHoleToPolyline(newPolyline, holeData);
|
|
311
|
+
unassignedContourHolesSet.delete(holeData);
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
});
|
|
212
315
|
}
|
|
213
316
|
|
|
214
|
-
|
|
215
|
-
|
|
317
|
+
// Make sure the holes that will be added to the new annotation are not
|
|
318
|
+
// associated to the target annotation that will be deleted
|
|
319
|
+
Array.from(reassignedContourHolesMap.values()).forEach(
|
|
320
|
+
(contourHolesDataArray) =>
|
|
321
|
+
contourHolesDataArray.forEach((contourHoleData) =>
|
|
322
|
+
clearParentAnnotation(contourHoleData.annotation)
|
|
323
|
+
)
|
|
324
|
+
);
|
|
216
325
|
|
|
217
326
|
const { element } = viewport;
|
|
218
327
|
const enabledElement = getEnabledElement(element);
|
|
219
|
-
const { renderingEngine } = enabledElement;
|
|
220
328
|
const { metadata, data } = targetAnnotation;
|
|
221
329
|
const { handles, segmentation } = data;
|
|
222
330
|
const { textBox } = handles;
|
|
223
331
|
|
|
332
|
+
removeAnnotation(sourceAnnotation.annotationUID);
|
|
333
|
+
removeAnnotation(targetAnnotation.annotationUID);
|
|
334
|
+
|
|
224
335
|
for (let i = 0; i < newPolylines.length; i++) {
|
|
225
|
-
const polyline =
|
|
226
|
-
const startPoint = polyline[0];
|
|
227
|
-
const endPoint = polyline[polyline.length - 1];
|
|
228
|
-
const newAnnotation = {
|
|
336
|
+
const polyline = newPolylines[i];
|
|
337
|
+
const startPoint = viewport.canvasToWorld(polyline[0]);
|
|
338
|
+
const endPoint = viewport.canvasToWorld(polyline[polyline.length - 1]);
|
|
339
|
+
const newAnnotation: ContourAnnotation = {
|
|
229
340
|
metadata: {
|
|
230
341
|
...metadata,
|
|
231
342
|
toolName: DEFAULT_CONTOUR_SEG_TOOLNAME,
|
|
@@ -237,7 +348,7 @@ function processContours(
|
|
|
237
348
|
textBox: textBox ? { ...textBox } : undefined,
|
|
238
349
|
},
|
|
239
350
|
contour: {
|
|
240
|
-
polyline,
|
|
351
|
+
polyline: [],
|
|
241
352
|
closed: true,
|
|
242
353
|
},
|
|
243
354
|
segmentation: {
|
|
@@ -251,23 +362,48 @@ function processContours(
|
|
|
251
362
|
isVisible: undefined,
|
|
252
363
|
};
|
|
253
364
|
|
|
254
|
-
|
|
365
|
+
// Calling `updateContourPolyline` method instead of setting it locally
|
|
366
|
+
// because it is also responsible for checking/setting the winding direction.
|
|
367
|
+
contourUtils.updateContourPolyline(
|
|
368
|
+
newAnnotation,
|
|
369
|
+
{
|
|
370
|
+
points: polyline,
|
|
371
|
+
closed: true,
|
|
372
|
+
targetWindingDirection: ContourWindingDirection.Clockwise,
|
|
373
|
+
},
|
|
374
|
+
viewport
|
|
375
|
+
);
|
|
255
376
|
|
|
256
|
-
|
|
257
|
-
const updatedTtoolNames = new Set([
|
|
258
|
-
DEFAULT_CONTOUR_SEG_TOOLNAME,
|
|
259
|
-
targetAnnotation.metadata.toolName,
|
|
260
|
-
]);
|
|
377
|
+
addAnnotation(newAnnotation, element);
|
|
261
378
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
);
|
|
267
|
-
triggerAnnotationRenderForViewportIds(
|
|
268
|
-
renderingEngine,
|
|
269
|
-
viewportIdsToRender
|
|
379
|
+
reassignedContourHolesMap
|
|
380
|
+
.get(polyline)
|
|
381
|
+
?.forEach((holeData) =>
|
|
382
|
+
addChildAnnotation(newAnnotation, holeData.annotation)
|
|
270
383
|
);
|
|
271
|
-
}
|
|
272
384
|
}
|
|
385
|
+
|
|
386
|
+
updateViewports(enabledElement, targetAnnotation, sourceAnnotation);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function updateViewports(enabledElement, targetAnnotation, sourceAnnotation) {
|
|
390
|
+
const { viewport } = enabledElement;
|
|
391
|
+
const { element } = viewport;
|
|
392
|
+
const { renderingEngine } = enabledElement;
|
|
393
|
+
|
|
394
|
+
const updatedTtoolNames = new Set([
|
|
395
|
+
DEFAULT_CONTOUR_SEG_TOOLNAME,
|
|
396
|
+
targetAnnotation.metadata.toolName,
|
|
397
|
+
sourceAnnotation.metadata.toolName,
|
|
398
|
+
]);
|
|
399
|
+
|
|
400
|
+
for (const toolName of updatedTtoolNames.values()) {
|
|
401
|
+
const viewportIdsToRender = getViewportIdsWithToolToRender(
|
|
402
|
+
element,
|
|
403
|
+
toolName
|
|
404
|
+
);
|
|
405
|
+
triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return new Promise((resolve) => window.requestAnimationFrame(resolve));
|
|
273
409
|
}
|
|
@@ -59,6 +59,81 @@ function getAnnotations(
|
|
|
59
59
|
return manager.getAnnotations(groupKey, toolName) as Annotations;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Removes the association between the annotation passed as parameter and its
|
|
64
|
+
* parent in case it has one (eg: contour holes).
|
|
65
|
+
* @param annotation - Annotation
|
|
66
|
+
*/
|
|
67
|
+
function clearParentAnnotation(annotation: Annotation): void {
|
|
68
|
+
const { annotationUID: childUID, parentAnnotationUID } = annotation;
|
|
69
|
+
|
|
70
|
+
if (!parentAnnotationUID) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const parentAnnotation = getAnnotation(parentAnnotationUID);
|
|
75
|
+
const childUIDIndex = parentAnnotation.childAnnotationUIDs.indexOf(childUID);
|
|
76
|
+
|
|
77
|
+
parentAnnotation.childAnnotationUIDs.splice(childUIDIndex, 1);
|
|
78
|
+
annotation.parentAnnotationUID = undefined;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Creates a parent/child association between annotations.
|
|
83
|
+
* A annotation may have only one parent and multiple children (eg: a contour
|
|
84
|
+
* may have multiple holes in it).
|
|
85
|
+
* @param parentAnnotation - Parent annotation
|
|
86
|
+
* @param childAnnotation - Child annotation
|
|
87
|
+
*/
|
|
88
|
+
function addChildAnnotation(
|
|
89
|
+
parentAnnotation: Annotation,
|
|
90
|
+
childAnnotation: Annotation
|
|
91
|
+
): void {
|
|
92
|
+
const { annotationUID: parentUID } = parentAnnotation;
|
|
93
|
+
const { annotationUID: childUID } = childAnnotation;
|
|
94
|
+
|
|
95
|
+
// Make sure it is not associated with any other tool
|
|
96
|
+
clearParentAnnotation(childAnnotation);
|
|
97
|
+
|
|
98
|
+
if (!parentAnnotation.childAnnotationUIDs) {
|
|
99
|
+
parentAnnotation.childAnnotationUIDs = [];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Check if it is already a child
|
|
103
|
+
if (parentAnnotation.childAnnotationUIDs.includes(childUID)) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
parentAnnotation.childAnnotationUIDs.push(childUID);
|
|
108
|
+
childAnnotation.parentAnnotationUID = parentUID;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Returns the parent annotation of a given one since annotations can be
|
|
113
|
+
* associated in a parent/child way (eg: polyline holes)
|
|
114
|
+
* @param annotation - Annotation
|
|
115
|
+
* @returns Parent annotation
|
|
116
|
+
*/
|
|
117
|
+
function getParentAnnotation(annotation: Annotation) {
|
|
118
|
+
return annotation.parentAnnotationUID
|
|
119
|
+
? getAnnotation(annotation.parentAnnotationUID)
|
|
120
|
+
: undefined;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Returns all children annotation of a given one since annotations can be
|
|
125
|
+
* associated in a parent/child way (eg: polyline holes)
|
|
126
|
+
* @param annotation - Annotation
|
|
127
|
+
* @returns Child annotations
|
|
128
|
+
*/
|
|
129
|
+
function getChildAnnotations(annotation: Annotation) {
|
|
130
|
+
return (
|
|
131
|
+
annotation.childAnnotationUIDs?.map((childAnnotationUID) =>
|
|
132
|
+
getAnnotation(childAnnotationUID)
|
|
133
|
+
) ?? []
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
62
137
|
/**
|
|
63
138
|
* Add the annotation to the annotation manager along with the options that is
|
|
64
139
|
* used to filter the annotation manager and the annotation group that
|
|
@@ -137,6 +212,11 @@ function removeAnnotation(annotationUID: string): void {
|
|
|
137
212
|
return;
|
|
138
213
|
}
|
|
139
214
|
|
|
215
|
+
// Remove all child annotations first
|
|
216
|
+
annotation.childAnnotationUIDs?.forEach((childAnnotationUID) =>
|
|
217
|
+
removeAnnotation(childAnnotationUID)
|
|
218
|
+
);
|
|
219
|
+
|
|
140
220
|
manager.removeAnnotation(annotationUID);
|
|
141
221
|
|
|
142
222
|
// trigger annotation removed
|
|
@@ -169,8 +249,28 @@ function removeAllAnnotations(): void {
|
|
|
169
249
|
manager.removeAllAnnotations();
|
|
170
250
|
}
|
|
171
251
|
|
|
252
|
+
/**
|
|
253
|
+
* Invalidate current and all parent annotations (eg: contour holes)
|
|
254
|
+
* @param annotation - Annotation
|
|
255
|
+
*/
|
|
256
|
+
function invalidateAnnotation(annotation: Annotation): void {
|
|
257
|
+
let currAnnotation = annotation;
|
|
258
|
+
|
|
259
|
+
while (currAnnotation) {
|
|
260
|
+
currAnnotation.invalidated = true;
|
|
261
|
+
|
|
262
|
+
currAnnotation = currAnnotation.parentAnnotationUID
|
|
263
|
+
? getAnnotation(currAnnotation.parentAnnotationUID)
|
|
264
|
+
: undefined;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
172
268
|
export {
|
|
173
269
|
getAnnotations,
|
|
270
|
+
getParentAnnotation,
|
|
271
|
+
getChildAnnotations,
|
|
272
|
+
clearParentAnnotation,
|
|
273
|
+
addChildAnnotation,
|
|
174
274
|
getNumberOfAnnotations,
|
|
175
275
|
addAnnotation,
|
|
176
276
|
getAnnotation,
|
|
@@ -180,4 +280,5 @@ export {
|
|
|
180
280
|
setAnnotationManager,
|
|
181
281
|
getAnnotationManager,
|
|
182
282
|
resetAnnotationManager,
|
|
283
|
+
invalidateAnnotation,
|
|
183
284
|
};
|