@cornerstonejs/tools 1.51.4 → 1.52.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/drawPolyline.js +1 -1
- package/dist/cjs/drawingSvg/drawPolyline.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/stateManagement/annotation/helpers/state.d.ts +2 -1
- package/dist/cjs/stateManagement/annotation/helpers/state.js +2 -1
- package/dist/cjs/stateManagement/annotation/helpers/state.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 +10 -9
- package/dist/cjs/tools/annotation/LivewireContourTool.js +56 -43
- package/dist/cjs/tools/annotation/LivewireContourTool.js.map +1 -1
- package/dist/cjs/tools/annotation/PlanarFreehandROITool.js +2 -1
- package/dist/cjs/tools/annotation/PlanarFreehandROITool.js.map +1 -1
- package/dist/cjs/tools/annotation/SplineROITool.js +3 -3
- package/dist/cjs/tools/annotation/SplineROITool.js.map +1 -1
- package/dist/cjs/types/ContourSegmentationAnnotation.d.ts +8 -0
- package/dist/cjs/types/InterpolationTypes.d.ts +2 -0
- package/dist/cjs/types/ToolSpecificAnnotationTypes.d.ts +2 -5
- 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/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/segmentation/InterpolationManager/InterpolationManager.js +13 -3
- package/dist/cjs/utilities/segmentation/InterpolationManager/InterpolationManager.js.map +1 -1
- package/dist/esm/drawingSvg/drawPolyline.js +1 -1
- package/dist/esm/drawingSvg/drawPolyline.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/stateManagement/annotation/helpers/state.js +3 -2
- package/dist/esm/stateManagement/annotation/helpers/state.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 +57 -44
- 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 +3 -3
- package/dist/esm/tools/annotation/SplineROITool.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/livewire/LivewireScissors.js +46 -24
- package/dist/esm/utilities/livewire/LivewireScissors.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/enums/ChangeTypes.d.ts +2 -1
- package/dist/types/enums/ChangeTypes.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/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 +10 -9
- 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/types/ContourSegmentationAnnotation.d.ts +8 -0
- package/dist/types/types/ContourSegmentationAnnotation.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/ToolSpecificAnnotationTypes.d.ts +2 -5
- package/dist/types/types/ToolSpecificAnnotationTypes.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/livewire/LivewireScissors.d.ts +2 -1
- package/dist/types/utilities/livewire/LivewireScissors.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/drawPolyline.ts +1 -1
- package/src/enums/ChangeTypes.ts +4 -0
- package/src/eventDispatchers/keyboardEventHandlers/keyDown.ts +1 -1
- package/src/stateManagement/annotation/helpers/state.ts +4 -2
- package/src/tools/annotation/LivewireContourSegmentationTool.ts +151 -0
- package/src/tools/annotation/LivewireContourTool.ts +113 -82
- package/src/tools/annotation/PlanarFreehandROITool.ts +8 -3
- package/src/tools/annotation/SplineROITool.ts +3 -3
- package/src/types/ContourSegmentationAnnotation.ts +38 -0
- package/src/types/InterpolationTypes.ts +6 -0
- package/src/types/ToolSpecificAnnotationTypes.ts +7 -5
- 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/livewire/LivewireScissors.ts +65 -53
- 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,6 @@
|
|
|
1
|
+
import type { Types } from '@cornerstonejs/core';
|
|
1
2
|
import { ContourAnnotation } from './ContourAnnotation';
|
|
3
|
+
// Import the type so it isn't recursive imports
|
|
2
4
|
|
|
3
5
|
export type ContourSegmentationAnnotationData = {
|
|
4
6
|
autoGenerated?: boolean;
|
|
@@ -8,7 +10,43 @@ export type ContourSegmentationAnnotationData = {
|
|
|
8
10
|
segmentIndex: number;
|
|
9
11
|
segmentationRepresentationUID: string;
|
|
10
12
|
};
|
|
13
|
+
contour: {
|
|
14
|
+
/** The original polyline before livewire, to show comparison with
|
|
15
|
+
* regenerated data (eg based on spline or livewire changes).
|
|
16
|
+
*/
|
|
17
|
+
originalPolyline?: Types.Point3[];
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
handles: {
|
|
21
|
+
/**
|
|
22
|
+
* Segmentation contours can be interpolated between slices to produce
|
|
23
|
+
* intermediate data. The interpolation sources are source data for
|
|
24
|
+
* the interpolation corresponding to the handle points. The object
|
|
25
|
+
* will have the kIndex assigned so that one can determine relative slice
|
|
26
|
+
* locations that the handles are in originally.
|
|
27
|
+
*
|
|
28
|
+
* This does NOT necessarily correspond to the handles used on the original
|
|
29
|
+
* source data, but is the set of point uses to interpolate the current handles.
|
|
30
|
+
* That is, for linear interpolation:
|
|
31
|
+
* ```
|
|
32
|
+
* handles.points[i] = linear(interpolationSources[0].getPoint(i),
|
|
33
|
+
* interpolationSources[1].getPoint(i));
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* These are sometimes required for things like livewire which need to
|
|
37
|
+
* update the handle position with a snap to nearest live point or can
|
|
38
|
+
* be used as an indicator that interpolation has taken place.
|
|
39
|
+
*/
|
|
40
|
+
interpolationSources?: Types.PointsManager<Types.Point3>[];
|
|
11
41
|
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* This is called when interpolation is performed, and can be used to add
|
|
45
|
+
* data specific settings to the annotation instance.
|
|
46
|
+
*/
|
|
47
|
+
onInterpolationComplete?: (
|
|
48
|
+
annotation: ContourSegmentationAnnotation
|
|
49
|
+
) => unknown;
|
|
12
50
|
};
|
|
13
51
|
|
|
14
52
|
export type ContourSegmentationAnnotation = ContourAnnotation &
|
|
@@ -14,6 +14,8 @@ export type InterpolationViewportData = {
|
|
|
14
14
|
/** The viewport that this interpolation is occurring within */
|
|
15
15
|
viewport: Types.IViewport;
|
|
16
16
|
sliceData: Types.ImageSliceData;
|
|
17
|
+
/** True if the interpolation data is being regenerated because of an update */
|
|
18
|
+
isInterpolationUpdate?: boolean;
|
|
17
19
|
};
|
|
18
20
|
|
|
19
21
|
export type ImageInterpolationData = {
|
|
@@ -39,4 +41,8 @@ export type AcceptInterpolationSelector = {
|
|
|
39
41
|
* Applies just to the given segment index.
|
|
40
42
|
*/
|
|
41
43
|
segmentIndex?: number;
|
|
44
|
+
/**
|
|
45
|
+
* Only apply to the given slice index
|
|
46
|
+
*/
|
|
47
|
+
sliceIndex?: number;
|
|
42
48
|
};
|
|
@@ -141,11 +141,7 @@ export type SplineROIAnnotation = ContourAnnotation & {
|
|
|
141
141
|
export type SplineContourSegmentationAnnotation = SplineROIAnnotation &
|
|
142
142
|
ContourSegmentationAnnotationData;
|
|
143
143
|
|
|
144
|
-
export type LivewireContourAnnotation = ContourAnnotation
|
|
145
|
-
data: {
|
|
146
|
-
label?: string;
|
|
147
|
-
};
|
|
148
|
-
};
|
|
144
|
+
export type LivewireContourAnnotation = ContourAnnotation;
|
|
149
145
|
|
|
150
146
|
export type LivewireContourSegmentationAnnotation = LivewireContourAnnotation &
|
|
151
147
|
ContourSegmentationAnnotationData;
|
|
@@ -277,6 +273,12 @@ export type InterpolationROIAnnotation = ContourAnnotation & {
|
|
|
277
273
|
referencedSliceIndex?: number;
|
|
278
274
|
};
|
|
279
275
|
interpolationUID?: string;
|
|
276
|
+
/**
|
|
277
|
+
* A flag to track updates to annotations caused by things like
|
|
278
|
+
* spline or livewire regeenration of the data, and which should cause further
|
|
279
|
+
* updates to occur (or not as the tool decides).
|
|
280
|
+
*/
|
|
281
|
+
isInterpolationUpdate?: boolean;
|
|
280
282
|
};
|
|
281
283
|
|
|
282
284
|
export interface ArrowAnnotation extends Annotation {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getEnabledElement } from '@cornerstonejs/core';
|
|
2
|
+
|
|
1
3
|
import InterpolationManager from '../../segmentation/InterpolationManager/InterpolationManager';
|
|
2
4
|
import type { AcceptInterpolationSelector } from '../../../types/InterpolationTypes';
|
|
3
5
|
import type AnnotationGroupSelector from '../../../types/AnnotationGroupSelector';
|
|
@@ -5,7 +7,7 @@ import type AnnotationGroupSelector from '../../../types/AnnotationGroupSelector
|
|
|
5
7
|
/**
|
|
6
8
|
* Accepts interpolated annotations, marking them as autoGenerated false.
|
|
7
9
|
*
|
|
8
|
-
* @param annotationGroupSelector - viewport or FOR to select annotations
|
|
10
|
+
* @param annotationGroupSelector - viewport or FOR to select annotations on
|
|
9
11
|
* @param selector - nested selection criteria
|
|
10
12
|
*/
|
|
11
13
|
export default function acceptAutogeneratedInterpolations(
|
|
@@ -33,7 +33,13 @@ export default function createPolylineToolData(
|
|
|
33
33
|
});
|
|
34
34
|
Object.assign(annotation.data, {
|
|
35
35
|
handles: {
|
|
36
|
-
points: handlePoints || [],
|
|
36
|
+
points: handlePoints.points || handlePoints || [],
|
|
37
|
+
/**
|
|
38
|
+
* The interpolation sources contains the source points used for interpolating
|
|
39
|
+
* to generate the new handles. This allows performing other types of
|
|
40
|
+
* interpolation to generate the new handles, such as livewire.
|
|
41
|
+
*/
|
|
42
|
+
interpolationSources: handlePoints.sources,
|
|
37
43
|
activeHandleIndex: null,
|
|
38
44
|
textBox: {
|
|
39
45
|
hasMoved: false,
|
|
@@ -129,7 +129,8 @@ function _sliceNeedsInterpolating(
|
|
|
129
129
|
): boolean {
|
|
130
130
|
const annotations = interpolationData.get(sliceIndex);
|
|
131
131
|
return (
|
|
132
|
-
!annotations ||
|
|
132
|
+
!annotations?.length ||
|
|
133
|
+
(annotations.length === 1 && annotations[0].autoGenerated)
|
|
133
134
|
);
|
|
134
135
|
}
|
|
135
136
|
|
|
@@ -68,7 +68,9 @@ export default function getInterpolationData(
|
|
|
68
68
|
}
|
|
69
69
|
);
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
if (filteredInterpolatedAnnotations.length) {
|
|
72
|
+
interpolationDatas.set(i, filteredInterpolatedAnnotations);
|
|
73
|
+
}
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
return interpolationDatas;
|
|
@@ -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
|
}
|