@cornerstonejs/tools 3.24.0 → 3.25.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/esm/stateManagement/segmentation/utilities/convertContourHoles.d.ts +1 -0
- package/dist/esm/stateManagement/segmentation/utilities/convertContourHoles.js +66 -0
- package/dist/esm/stateManagement/segmentation/utilities/getAnnotationsUIDMapFromSegmentation.d.ts +1 -0
- package/dist/esm/stateManagement/segmentation/utilities/getAnnotationsUIDMapFromSegmentation.js +17 -0
- package/dist/esm/stateManagement/segmentation/utilities/index.d.ts +2 -0
- package/dist/esm/stateManagement/segmentation/utilities/index.js +3 -0
- package/dist/esm/stateManagement/segmentation/utilities/removeContourHoles.js +0 -1
- package/dist/esm/tools/annotation/SplineROITool.d.ts +2 -0
- package/dist/esm/tools/annotation/SplineROITool.js +18 -0
- package/dist/esm/types/index.d.ts +2 -1
- package/dist/esm/utilities/contourSegmentation/addPolylinesToSegmentation.d.ts +2 -1
- package/dist/esm/utilities/contourSegmentation/addPolylinesToSegmentation.js +3 -4
- package/dist/esm/utilities/contourSegmentation/areViewReferencesEqual.d.ts +2 -0
- package/dist/esm/utilities/contourSegmentation/areViewReferencesEqual.js +23 -0
- package/dist/esm/utilities/contourSegmentation/copyAnnotation.d.ts +3 -0
- package/dist/esm/utilities/contourSegmentation/copyAnnotation.js +86 -0
- package/dist/esm/utilities/contourSegmentation/getViewReferenceFromAnnotation.d.ts +3 -0
- package/dist/esm/utilities/contourSegmentation/getViewReferenceFromAnnotation.js +20 -0
- package/dist/esm/utilities/contourSegmentation/index.d.ts +7 -3
- package/dist/esm/utilities/contourSegmentation/index.js +7 -3
- package/dist/esm/utilities/contourSegmentation/logicalOperators.d.ts +21 -12
- package/dist/esm/utilities/contourSegmentation/logicalOperators.js +148 -43
- package/dist/esm/utilities/contourSegmentation/polylineInfoTypes.d.ts +9 -0
- package/dist/esm/utilities/contourSegmentation/polylineInfoTypes.js +0 -0
- package/dist/esm/utilities/contourSegmentation/polylineIntersect.d.ts +2 -0
- package/dist/esm/utilities/contourSegmentation/polylineIntersect.js +34 -0
- package/dist/esm/utilities/contourSegmentation/polylineSubtract.d.ts +6 -0
- package/dist/esm/utilities/contourSegmentation/polylineSubtract.js +67 -0
- package/dist/esm/utilities/contourSegmentation/polylineUnify.d.ts +6 -0
- package/dist/esm/utilities/contourSegmentation/polylineUnify.js +79 -0
- package/dist/esm/utilities/contourSegmentation/polylineXor.d.ts +2 -0
- package/dist/esm/utilities/contourSegmentation/polylineXor.js +41 -0
- package/dist/esm/utilities/contourSegmentation/sharedOperations.d.ts +2 -0
- package/dist/esm/utilities/contourSegmentation/sharedOperations.js +44 -0
- package/dist/esm/utilities/math/polyline/arePolylinesIdentical.d.ts +2 -0
- package/dist/esm/utilities/math/polyline/arePolylinesIdentical.js +53 -0
- package/dist/esm/utilities/math/polyline/combinePolyline.d.ts +1 -2
- package/dist/esm/utilities/math/polyline/combinePolyline.js +17 -47
- package/dist/esm/utilities/math/polyline/index.d.ts +5 -2
- package/dist/esm/utilities/math/polyline/index.js +5 -2
- package/dist/esm/utilities/math/polyline/intersectPolylines.d.ts +2 -0
- package/dist/esm/utilities/math/polyline/intersectPolylines.js +271 -0
- package/dist/esm/utilities/math/polyline/robustSegmentIntersection.d.ts +37 -0
- package/dist/esm/utilities/math/polyline/robustSegmentIntersection.js +78 -0
- package/dist/esm/utilities/math/polyline/subtractPolylines.d.ts +2 -0
- package/dist/esm/utilities/math/polyline/subtractPolylines.js +210 -0
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +3 -3
- package/dist/esm/utilities/contourSegmentation/unifyPolylineSets.d.ts +0 -31
- package/dist/esm/utilities/contourSegmentation/unifyPolylineSets.js +0 -110
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function convertContourHoles(segmentationId: string, segmentIndex: number, targetSegmentationId?: string, targetSegmentationIndex?: number): void;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { findContourHoles } from '../../../utilities/contours';
|
|
2
|
+
import { getAnnotation, clearParentAnnotation, } from '../../annotation/annotationState';
|
|
3
|
+
import { getSegmentation } from '../getSegmentation';
|
|
4
|
+
import { extractSegmentPolylines } from './extractSegmentPolylines';
|
|
5
|
+
export default function convertContourHoles(segmentationId, segmentIndex, targetSegmentationId, targetSegmentationIndex) {
|
|
6
|
+
const segmentation = getSegmentation(segmentationId);
|
|
7
|
+
if (!segmentation) {
|
|
8
|
+
console.warn(`Invalid segmentation given ${segmentationId}`);
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (!segmentation.representationData.Contour) {
|
|
12
|
+
console.warn(`No contour representation found for segmentation ${segmentationId}`);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const { annotationUIDsMap } = segmentation?.representationData.Contour || {};
|
|
16
|
+
if (!annotationUIDsMap) {
|
|
17
|
+
console.warn(`No annotation map found for segmentation ${segmentationId}`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const annotationsUIDsSet = annotationUIDsMap?.get(segmentIndex);
|
|
21
|
+
if (!annotationsUIDsSet) {
|
|
22
|
+
console.warn(`Segmentation index ${segmentIndex} has no annotations in segmentation ${segmentationId}`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
let targetUIDsSet;
|
|
26
|
+
if (targetSegmentationId && typeof targetSegmentationIndex === 'number') {
|
|
27
|
+
const targetSegmentation = getSegmentation(targetSegmentationId);
|
|
28
|
+
if (!targetSegmentation) {
|
|
29
|
+
console.warn(`Target segmentation ${targetSegmentationId} does not exist.`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (!targetSegmentation.representationData.Contour) {
|
|
33
|
+
console.warn(`No contour representation found for target segmentation ${targetSegmentationId}`);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
targetUIDsSet =
|
|
37
|
+
targetSegmentation.representationData.Contour.annotationUIDsMap.get(targetSegmentationIndex);
|
|
38
|
+
if (!targetUIDsSet) {
|
|
39
|
+
targetUIDsSet = new Set();
|
|
40
|
+
targetSegmentation.representationData.Contour.annotationUIDsMap.set(targetSegmentationIndex, targetUIDsSet);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const polylinesCanvasMap = extractSegmentPolylines(segmentationId, segmentIndex);
|
|
44
|
+
if (!polylinesCanvasMap) {
|
|
45
|
+
console.warn(`Error extracting contour data from segment ${segmentIndex} in segmentation ${segmentationId}`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const keys = Array.from(polylinesCanvasMap?.keys());
|
|
49
|
+
const polylines = keys.map((key) => polylinesCanvasMap.get(key));
|
|
50
|
+
const holeDetectionResults = findContourHoles(polylines);
|
|
51
|
+
if (holeDetectionResults?.length > 0) {
|
|
52
|
+
holeDetectionResults.forEach((hole) => {
|
|
53
|
+
hole.holeIndexes.forEach((index) => {
|
|
54
|
+
const annotation = getAnnotation(keys[index]);
|
|
55
|
+
clearParentAnnotation(annotation);
|
|
56
|
+
if (targetSegmentationId &&
|
|
57
|
+
typeof targetSegmentationIndex === 'number') {
|
|
58
|
+
targetUIDsSet.add(annotation.annotationUID);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
annotationsUIDsSet.add(annotation.annotationUID);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
package/dist/esm/stateManagement/segmentation/utilities/getAnnotationsUIDMapFromSegmentation.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getAnnotationsUIDMapFromSegmentation(segmentationId: string): Map<number, Set<string>>;
|
package/dist/esm/stateManagement/segmentation/utilities/getAnnotationsUIDMapFromSegmentation.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { getSegmentation } from '../getSegmentation';
|
|
2
|
+
export function getAnnotationsUIDMapFromSegmentation(segmentationId) {
|
|
3
|
+
const segmentation = getSegmentation(segmentationId);
|
|
4
|
+
if (!segmentation) {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
const contourRepresentationData = segmentation.representationData
|
|
8
|
+
?.Contour;
|
|
9
|
+
if (!contourRepresentationData) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const { annotationUIDsMap } = contourRepresentationData;
|
|
13
|
+
if (!annotationUIDsMap) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
return annotationUIDsMap;
|
|
17
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { getViewportAssociatedToSegmentation, getViewportWithMatchingViewPlaneNormal, } from './getViewportAssociatedToSegmentation';
|
|
2
|
+
export { getAnnotationsUIDMapFromSegmentation } from './getAnnotationsUIDMapFromSegmentation';
|
|
2
3
|
export { getAnnotationMapFromSegmentation } from './getAnnotationMapFromSegmentation';
|
|
3
4
|
export { default as decimateContours } from './decimateContours';
|
|
4
5
|
export { extractSegmentPolylines } from './extractSegmentPolylines';
|
|
@@ -6,3 +7,4 @@ export { removeCompleteContourAnnotation } from './removeCompleteContourAnnotati
|
|
|
6
7
|
export { default as removeContourHoles } from './removeContourHoles';
|
|
7
8
|
export { default as removeContourIslands } from './removeContourIslands';
|
|
8
9
|
export { default as smoothContours } from './smoothContours';
|
|
10
|
+
export { default as convertContourHoles } from './convertContourHoles';
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { getAnnotationsUIDMapFromSegmentation } from './getAnnotationsUIDMapFromSegmentation';
|
|
1
2
|
export { getViewportAssociatedToSegmentation, getViewportWithMatchingViewPlaneNormal, } from './getViewportAssociatedToSegmentation';
|
|
3
|
+
export { getAnnotationsUIDMapFromSegmentation } from './getAnnotationsUIDMapFromSegmentation';
|
|
2
4
|
export { getAnnotationMapFromSegmentation } from './getAnnotationMapFromSegmentation';
|
|
3
5
|
export { default as decimateContours } from './decimateContours';
|
|
4
6
|
export { extractSegmentPolylines } from './extractSegmentPolylines';
|
|
@@ -6,3 +8,4 @@ export { removeCompleteContourAnnotation } from './removeCompleteContourAnnotati
|
|
|
6
8
|
export { default as removeContourHoles } from './removeContourHoles';
|
|
7
9
|
export { default as removeContourIslands } from './removeContourIslands';
|
|
8
10
|
export { default as smoothContours } from './smoothContours';
|
|
11
|
+
export { default as convertContourHoles } from './convertContourHoles';
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { findContourHoles } from '../../../utilities/contours';
|
|
2
2
|
import { getAnnotation } from '../../annotation/annotationState';
|
|
3
|
-
import { triggerAnnotationRemoved } from '../../annotation/helpers/state';
|
|
4
3
|
import { getSegmentation } from '../getSegmentation';
|
|
5
4
|
import { extractSegmentPolylines } from './extractSegmentPolylines';
|
|
6
5
|
import { removeCompleteContourAnnotation } from './removeCompleteContourAnnotation';
|
|
@@ -64,6 +64,8 @@ declare class SplineROITool extends ContourSegmentationBaseTool {
|
|
|
64
64
|
protected isContourSegmentationTool(): boolean;
|
|
65
65
|
protected renderAnnotationInstance(renderContext: AnnotationRenderContext): boolean;
|
|
66
66
|
protected createInterpolatedSplineControl(annotation: any): void;
|
|
67
|
+
isSplineAnnotation(annotation: ContourAnnotation): boolean;
|
|
68
|
+
createSplineObjectFromType(annotation: ContourAnnotation, splineType: string): void;
|
|
67
69
|
protected createAnnotation(evt: EventTypes.InteractionEventType): ContourAnnotation;
|
|
68
70
|
private _renderStats;
|
|
69
71
|
addControlPointCallback: (evt: EventTypes.InteractionEventType, annotation: SplineROIAnnotation) => void;
|
|
@@ -41,6 +41,12 @@ var SplineToolActions;
|
|
|
41
41
|
SplineToolActions["AddControlPoint"] = "addControlPoint";
|
|
42
42
|
SplineToolActions["DeleteControlPoint"] = "deleteControlPoint";
|
|
43
43
|
})(SplineToolActions || (SplineToolActions = {}));
|
|
44
|
+
const splineToolNames = [
|
|
45
|
+
'CatmullRomSplineROI',
|
|
46
|
+
'LinearSplineROI',
|
|
47
|
+
'BSplineROI',
|
|
48
|
+
'CardinalSplineROI',
|
|
49
|
+
];
|
|
44
50
|
class SplineROITool extends ContourSegmentationBaseTool {
|
|
45
51
|
static { this.toolName = 'SplineROI'; }
|
|
46
52
|
static { this.SplineTypes = SplineTypesEnum; }
|
|
@@ -684,6 +690,18 @@ class SplineROITool extends ContourSegmentationBaseTool {
|
|
|
684
690
|
}
|
|
685
691
|
points.push(polyline[polyline.length - 1]);
|
|
686
692
|
}
|
|
693
|
+
isSplineAnnotation(annotation) {
|
|
694
|
+
return splineToolNames.includes(annotation?.metadata?.toolName);
|
|
695
|
+
}
|
|
696
|
+
createSplineObjectFromType(annotation, splineType) {
|
|
697
|
+
const splineConfig = this._getSplineConfig(splineType);
|
|
698
|
+
const spline = new splineConfig.Class();
|
|
699
|
+
annotation.data.spline = {
|
|
700
|
+
type: splineConfig.type,
|
|
701
|
+
instance: spline,
|
|
702
|
+
resolution: splineConfig.resolution,
|
|
703
|
+
};
|
|
704
|
+
}
|
|
687
705
|
createAnnotation(evt) {
|
|
688
706
|
const contourAnnotation = super.createAnnotation(evt);
|
|
689
707
|
const { world: worldPos } = evt.detail.currentPoints;
|
|
@@ -44,6 +44,7 @@ import type { SplineProps } from './SplineProps';
|
|
|
44
44
|
import type { BidirectionalData } from '../utilities/segmentation/createBidirectionalToolData';
|
|
45
45
|
import type { IBaseTool } from './IBaseTool';
|
|
46
46
|
import type { RepresentationStyle } from './../stateManagement/segmentation/SegmentationStyle';
|
|
47
|
+
import type { LogicalOperation } from '../utilities/contourSegmentation';
|
|
47
48
|
import type { LabelmapStyle, LabelmapSegmentationData, LabelmapSegmentationDataStack, LabelmapSegmentationDataVolume, BaseLabelmapStyle, InactiveLabelmapStyle } from './LabelmapTypes';
|
|
48
49
|
import type { SurfaceStyle, SurfaceSegmentationData, SurfaceStateStyles } from './SurfaceTypes';
|
|
49
|
-
export type { Annotation, Annotations, ContourAnnotationData, ContourAnnotation, ContourSegmentationAnnotationData, ContourSegmentationAnnotation, BidirectionalData, CanvasCoordinates, IAnnotationManager, InterpolationViewportData, ImageInterpolationData, GroupSpecificAnnotations, AnnotationState, AnnotationStyle, ToolSpecificAnnotationTypes, AnnotationGroupSelector, AnnotationRenderContext, PlanarBoundingBox, ToolProps, PublicToolProps, ToolConfiguration, EventTypes, IPoints, ITouchPoints, IDistance, IToolBinding, SetToolBindingsType, ToolOptionsType, InteractionTypes, ToolAction, IToolGroup, IToolClassReference, ISynchronizerEventHandler, ToolHandle, AnnotationHandle, TextBoxHandle, Segmentation, SegmentationRepresentation, SegmentationState, RepresentationData, RepresentationsData, SVGCursorDescriptor, SVGPoint, CINETypes, BoundsIJK, SVGDrawingHelper, FloodFillResult, FloodFillGetter, FloodFillOptions, ContourSegmentationData, ISculptToolShape, Statistics, NamedStatistics, LabelmapToolOperationData, LabelmapToolOperationDataStack, LabelmapToolOperationDataVolume, CardinalSplineProps, ClosestControlPoint, ClosestPoint, ClosestSplinePoint, ControlPointInfo, ISpline, SplineCurveSegment, SplineLineSegment, SplineProps, IBaseTool, RepresentationStyle, Segment, SegmentationPublicInput, LabelmapStyle, ContourStyle, SurfaceStyle, SurfaceSegmentationData, SurfaceStateStyles, LabelmapSegmentationData, LabelmapSegmentationDataStack, LabelmapSegmentationDataVolume, BaseLabelmapStyle, InactiveLabelmapStyle, };
|
|
50
|
+
export type { Annotation, Annotations, ContourAnnotationData, ContourAnnotation, ContourSegmentationAnnotationData, ContourSegmentationAnnotation, BidirectionalData, CanvasCoordinates, IAnnotationManager, InterpolationViewportData, ImageInterpolationData, GroupSpecificAnnotations, AnnotationState, AnnotationStyle, ToolSpecificAnnotationTypes, AnnotationGroupSelector, AnnotationRenderContext, PlanarBoundingBox, ToolProps, PublicToolProps, ToolConfiguration, EventTypes, IPoints, ITouchPoints, IDistance, IToolBinding, SetToolBindingsType, ToolOptionsType, InteractionTypes, ToolAction, IToolGroup, IToolClassReference, ISynchronizerEventHandler, ToolHandle, AnnotationHandle, TextBoxHandle, Segmentation, SegmentationRepresentation, SegmentationState, RepresentationData, RepresentationsData, SVGCursorDescriptor, SVGPoint, CINETypes, BoundsIJK, SVGDrawingHelper, FloodFillResult, FloodFillGetter, FloodFillOptions, ContourSegmentationData, ISculptToolShape, Statistics, NamedStatistics, LabelmapToolOperationData, LabelmapToolOperationDataStack, LabelmapToolOperationDataVolume, CardinalSplineProps, ClosestControlPoint, ClosestPoint, ClosestSplinePoint, ControlPointInfo, ISpline, SplineCurveSegment, SplineLineSegment, SplineProps, IBaseTool, RepresentationStyle, Segment, SegmentationPublicInput, LabelmapStyle, ContourStyle, SurfaceStyle, SurfaceSegmentationData, SurfaceStateStyles, LabelmapSegmentationData, LabelmapSegmentationDataStack, LabelmapSegmentationDataVolume, BaseLabelmapStyle, InactiveLabelmapStyle, LogicalOperation, };
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import type { Types } from '@cornerstonejs/core';
|
|
2
|
-
|
|
2
|
+
import type { PolylineInfoWorld } from './polylineInfoTypes';
|
|
3
|
+
export default function addPolylinesToSegmentation(viewport: Types.IViewport, annotationUIDsMap: Map<number, Set<string>>, segmentationId: string, polylinesInfo: PolylineInfoWorld[], segmentIndex: number): Map<number, Set<string>>;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { utilities } from '@cornerstonejs/core';
|
|
2
2
|
import { addAnnotation } from '../../stateManagement';
|
|
3
3
|
const DEFAULT_CONTOUR_SEG_TOOLNAME = 'PlanarFreehandContourSegmentationTool';
|
|
4
|
-
export default function addPolylinesToSegmentation(viewport, segmentationId,
|
|
5
|
-
|
|
6
|
-
polylines.forEach((polyline) => {
|
|
4
|
+
export default function addPolylinesToSegmentation(viewport, annotationUIDsMap, segmentationId, polylinesInfo, segmentIndex) {
|
|
5
|
+
polylinesInfo.forEach(({ polyline, viewReference }) => {
|
|
7
6
|
if (polyline.length < 3) {
|
|
8
7
|
return;
|
|
9
8
|
}
|
|
@@ -28,7 +27,7 @@ export default function addPolylinesToSegmentation(viewport, segmentationId, pol
|
|
|
28
27
|
isVisible: true,
|
|
29
28
|
metadata: {
|
|
30
29
|
toolName: DEFAULT_CONTOUR_SEG_TOOLNAME,
|
|
31
|
-
...
|
|
30
|
+
...viewReference,
|
|
32
31
|
},
|
|
33
32
|
};
|
|
34
33
|
addAnnotation(contourSegmentationAnnotation, viewport.element);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function areViewReferencesEqual(a, b) {
|
|
2
|
+
if (!a || !b) {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
5
|
+
if (a.FrameOfReferenceUID !== b.FrameOfReferenceUID) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
if (a.referencedImageId !== b.referencedImageId) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
if (!a.viewPlaneNormal || !b.viewPlaneNormal) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
if (a.viewPlaneNormal.length !== b.viewPlaneNormal.length) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
for (let i = 0; i < a.viewPlaneNormal.length; i++) {
|
|
18
|
+
if (a.viewPlaneNormal[i] !== b.viewPlaneNormal[i]) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ContourSegmentationAnnotation } from '../../types';
|
|
2
|
+
export declare function copyAnnotation(annotation: ContourSegmentationAnnotation, segmentationId: string, segmentIndex: number): ContourSegmentationAnnotation;
|
|
3
|
+
export declare function copyContourSegment(segmentationId: string, segmentIndex: number, targetSegmentationId: string, targetSegmentIndex: number): void;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { utilities } from '@cornerstonejs/core';
|
|
2
|
+
import { addAnnotation, getAnnotation } from '../../stateManagement';
|
|
3
|
+
import { getViewportAssociatedToSegmentation } from '../../stateManagement/segmentation/utilities/getViewportAssociatedToSegmentation';
|
|
4
|
+
import { getToolGroupForViewport } from '../../store/ToolGroupManager';
|
|
5
|
+
import { getAnnotationsUIDMapFromSegmentation } from '../../stateManagement/segmentation/utilities/getAnnotationsUIDMapFromSegmentation';
|
|
6
|
+
export function copyAnnotation(annotation, segmentationId, segmentIndex) {
|
|
7
|
+
const newAnnotation = {
|
|
8
|
+
annotationUID: utilities.uuidv4(),
|
|
9
|
+
data: {
|
|
10
|
+
contour: {
|
|
11
|
+
closed: true,
|
|
12
|
+
polyline: [],
|
|
13
|
+
},
|
|
14
|
+
segmentation: {
|
|
15
|
+
segmentationId,
|
|
16
|
+
segmentIndex,
|
|
17
|
+
},
|
|
18
|
+
handles: {},
|
|
19
|
+
},
|
|
20
|
+
handles: {},
|
|
21
|
+
highlighted: false,
|
|
22
|
+
autoGenerated: false,
|
|
23
|
+
invalidated: false,
|
|
24
|
+
isLocked: false,
|
|
25
|
+
isVisible: true,
|
|
26
|
+
metadata: {
|
|
27
|
+
...annotation.metadata,
|
|
28
|
+
toolName: annotation.metadata.toolName,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
newAnnotation.data.segmentation.segmentationId = segmentationId;
|
|
32
|
+
newAnnotation.data.segmentation.segmentIndex = segmentIndex;
|
|
33
|
+
if (annotation.data.contour?.polyline) {
|
|
34
|
+
newAnnotation.data.contour.polyline = [...annotation.data.contour.polyline];
|
|
35
|
+
}
|
|
36
|
+
if (annotation.data.handles?.points) {
|
|
37
|
+
newAnnotation.data.handles.points = annotation.data.handles.points.map((point) => [...point]);
|
|
38
|
+
}
|
|
39
|
+
return newAnnotation;
|
|
40
|
+
}
|
|
41
|
+
export function copyContourSegment(segmentationId, segmentIndex, targetSegmentationId, targetSegmentIndex) {
|
|
42
|
+
const annotationUIDsMap = getAnnotationsUIDMapFromSegmentation(segmentationId);
|
|
43
|
+
const targetAnnotationUIDsMap = getAnnotationsUIDMapFromSegmentation(targetSegmentationId);
|
|
44
|
+
if (!annotationUIDsMap || !targetAnnotationUIDsMap) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (!annotationUIDsMap?.has(segmentIndex)) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const annotationUIDs = annotationUIDsMap.get(segmentIndex);
|
|
51
|
+
const viewport = getViewportAssociatedToSegmentation(targetSegmentationId);
|
|
52
|
+
if (!viewport) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const toolGroup = getToolGroupForViewport(viewport.id);
|
|
56
|
+
const copyContourAnnotation = (annotation) => {
|
|
57
|
+
const newAnnotation = copyAnnotation(annotation, targetSegmentationId, targetSegmentIndex);
|
|
58
|
+
if (toolGroup) {
|
|
59
|
+
const instance = toolGroup.getToolInstance(annotation.metadata.toolName);
|
|
60
|
+
if (instance) {
|
|
61
|
+
if (typeof instance.isSplineAnnotation === 'function' &&
|
|
62
|
+
instance.isSplineAnnotation(annotation)) {
|
|
63
|
+
instance.createSplineObjectFromType(newAnnotation, annotation.data.spline.type);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
addAnnotation(newAnnotation, viewport.element);
|
|
68
|
+
newAnnotationsUID.add(newAnnotation.annotationUID);
|
|
69
|
+
return newAnnotation;
|
|
70
|
+
};
|
|
71
|
+
const newAnnotationsUID = new Set();
|
|
72
|
+
for (const annotationUID of annotationUIDs) {
|
|
73
|
+
const annotation = getAnnotation(annotationUID);
|
|
74
|
+
const newAnnotation = copyContourAnnotation(annotation);
|
|
75
|
+
if (annotation?.childAnnotationUIDs) {
|
|
76
|
+
newAnnotation.childAnnotationUIDs = [];
|
|
77
|
+
for (const childAnnotationUID of annotation.childAnnotationUIDs) {
|
|
78
|
+
const childAnnotation = getAnnotation(childAnnotationUID);
|
|
79
|
+
const newChildAnnotation = copyContourAnnotation(childAnnotation);
|
|
80
|
+
newChildAnnotation.parentAnnotationUID = newAnnotation.annotationUID;
|
|
81
|
+
newAnnotation.childAnnotationUIDs.push(newChildAnnotation.annotationUID);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
targetAnnotationUIDsMap.set(targetSegmentIndex, newAnnotationsUID);
|
|
86
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function getViewReferenceFromAnnotation(annotation) {
|
|
2
|
+
const { metadata } = annotation;
|
|
3
|
+
if (!metadata) {
|
|
4
|
+
return {};
|
|
5
|
+
}
|
|
6
|
+
const { FrameOfReferenceUID, referencedImageId, referencedImageURI, multiSliceReference, cameraFocalPoint, viewPlaneNormal, viewUp, sliceIndex, volumeId, bounds, } = metadata;
|
|
7
|
+
const viewReference = {
|
|
8
|
+
FrameOfReferenceUID,
|
|
9
|
+
referencedImageId,
|
|
10
|
+
referencedImageURI,
|
|
11
|
+
multiSliceReference,
|
|
12
|
+
cameraFocalPoint,
|
|
13
|
+
viewPlaneNormal,
|
|
14
|
+
viewUp,
|
|
15
|
+
sliceIndex,
|
|
16
|
+
volumeId,
|
|
17
|
+
bounds,
|
|
18
|
+
};
|
|
19
|
+
return viewReference;
|
|
20
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import areSameSegment from './areSameSegment';
|
|
2
2
|
import convertContourSegmentationAnnotation from './convertContourSegmentation';
|
|
3
|
-
import {
|
|
3
|
+
import { copyAnnotation, copyContourSegment } from './copyAnnotation';
|
|
4
|
+
export * from './logicalOperators';
|
|
4
5
|
export { default as isContourSegmentationAnnotation } from './isContourSegmentationAnnotation';
|
|
5
6
|
export { addContourSegmentationAnnotation } from './addContourSegmentationAnnotation';
|
|
6
7
|
export { removeContourSegmentationAnnotation } from './removeContourSegmentationAnnotation';
|
|
@@ -8,5 +9,8 @@ export { findAllIntersectingContours } from './getIntersectingAnnotations';
|
|
|
8
9
|
export { processMultipleIntersections } from './mergeMultipleAnnotations';
|
|
9
10
|
export { contourSegmentationOperation } from './contourSegmentationOperation';
|
|
10
11
|
export * from './sharedOperations';
|
|
11
|
-
export {
|
|
12
|
-
export
|
|
12
|
+
export { areSameSegment, convertContourSegmentationAnnotation, copyContourSegment, copyAnnotation, };
|
|
13
|
+
export * from './polylineUnify';
|
|
14
|
+
export * from './polylineSubtract';
|
|
15
|
+
export * from './polylineIntersect';
|
|
16
|
+
export * from './polylineXor';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import areSameSegment from './areSameSegment';
|
|
2
2
|
import convertContourSegmentationAnnotation from './convertContourSegmentation';
|
|
3
|
-
import {
|
|
3
|
+
import { copyAnnotation, copyContourSegment } from './copyAnnotation';
|
|
4
|
+
export * from './logicalOperators';
|
|
4
5
|
export { default as isContourSegmentationAnnotation } from './isContourSegmentationAnnotation';
|
|
5
6
|
export { addContourSegmentationAnnotation } from './addContourSegmentationAnnotation';
|
|
6
7
|
export { removeContourSegmentationAnnotation } from './removeContourSegmentationAnnotation';
|
|
@@ -8,5 +9,8 @@ export { findAllIntersectingContours } from './getIntersectingAnnotations';
|
|
|
8
9
|
export { processMultipleIntersections } from './mergeMultipleAnnotations';
|
|
9
10
|
export { contourSegmentationOperation } from './contourSegmentationOperation';
|
|
10
11
|
export * from './sharedOperations';
|
|
11
|
-
export {
|
|
12
|
-
export
|
|
12
|
+
export { areSameSegment, convertContourSegmentationAnnotation, copyContourSegment, copyAnnotation, };
|
|
13
|
+
export * from './polylineUnify';
|
|
14
|
+
export * from './polylineSubtract';
|
|
15
|
+
export * from './polylineIntersect';
|
|
16
|
+
export * from './polylineXor';
|
|
@@ -1,12 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export declare
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
export type SegmentInfo = {
|
|
2
|
+
segmentationId: string;
|
|
3
|
+
segmentIndex: number;
|
|
4
|
+
label?: string;
|
|
5
|
+
color?: string;
|
|
6
|
+
};
|
|
7
|
+
export type OperatorOptions = SegmentInfo;
|
|
8
|
+
export declare enum LogicalOperation {
|
|
9
|
+
Union = 0,
|
|
10
|
+
Subtract = 1,
|
|
11
|
+
Intersect = 2,
|
|
12
|
+
XOR = 3,
|
|
13
|
+
Copy = 4,
|
|
14
|
+
Delete = 5
|
|
15
|
+
}
|
|
16
|
+
export declare function add(segment1: SegmentInfo, segment2: SegmentInfo, options: OperatorOptions): void;
|
|
17
|
+
export declare function subtract(segment1: SegmentInfo, segment2: SegmentInfo, options: OperatorOptions): void;
|
|
18
|
+
export declare function intersect(segment1: SegmentInfo, segment2: SegmentInfo, options: OperatorOptions): void;
|
|
19
|
+
export declare function xor(segment1: SegmentInfo, segment2: SegmentInfo, options: OperatorOptions): void;
|
|
20
|
+
export declare function copy(segment: SegmentInfo, options: OperatorOptions): void;
|
|
21
|
+
export declare function deleteOperation(segment: SegmentInfo): void;
|