@cornerstonejs/tools 1.63.5 → 1.64.1
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/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.d.ts +3 -0
- package/dist/cjs/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.js +2 -0
- package/dist/cjs/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.js.map +1 -1
- package/dist/cjs/store/ToolGroupManager/ToolGroup.d.ts +3 -2
- package/dist/cjs/store/ToolGroupManager/ToolGroup.js +13 -5
- package/dist/cjs/store/ToolGroupManager/ToolGroup.js.map +1 -1
- package/dist/cjs/tools/CrosshairsTool.d.ts +1 -1
- package/dist/cjs/tools/annotation/PlanarFreehandROITool.js +1 -1
- package/dist/cjs/tools/annotation/PlanarFreehandROITool.js.map +1 -1
- package/dist/cjs/tools/annotation/SplineROITool.js +6 -4
- package/dist/cjs/tools/annotation/SplineROITool.js.map +1 -1
- package/dist/cjs/tools/annotation/planarFreehandROITool/drawLoop.js +4 -6
- package/dist/cjs/tools/annotation/planarFreehandROITool/drawLoop.js.map +1 -1
- package/dist/cjs/types/IToolGroup.d.ts +2 -2
- package/dist/cjs/types/index.d.ts +1 -1
- package/dist/cjs/utilities/contourSegmentation/addContourSegmentationAnnotation.js +3 -0
- package/dist/cjs/utilities/contourSegmentation/addContourSegmentationAnnotation.js.map +1 -1
- package/dist/cjs/utilities/contours/interpolation/createPolylineToolData.js +2 -4
- package/dist/cjs/utilities/contours/interpolation/createPolylineToolData.js.map +1 -1
- package/dist/cjs/utilities/contours/interpolation/interpolate.js +27 -17
- package/dist/cjs/utilities/contours/interpolation/interpolate.js.map +1 -1
- package/dist/cjs/utilities/contours/interpolation/selectHandles.js +2 -2
- package/dist/cjs/utilities/contours/interpolation/selectHandles.js.map +1 -1
- package/dist/cjs/utilities/contours/interpolation/updateChildInterpolationUID.d.ts +2 -0
- package/dist/cjs/utilities/contours/interpolation/updateChildInterpolationUID.js +39 -0
- package/dist/cjs/utilities/contours/interpolation/updateChildInterpolationUID.js.map +1 -0
- package/dist/cjs/utilities/getCalibratedUnits.js +4 -1
- package/dist/cjs/utilities/getCalibratedUnits.js.map +1 -1
- package/dist/cjs/utilities/math/vec2/liangBarksyClip.d.ts +1 -1
- package/dist/cjs/utilities/segmentation/InterpolationManager/InterpolationManager.js.map +1 -1
- package/dist/esm/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.js +1 -1
- package/dist/esm/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.js.map +1 -1
- package/dist/esm/store/ToolGroupManager/ToolGroup.js +13 -5
- package/dist/esm/store/ToolGroupManager/ToolGroup.js.map +1 -1
- package/dist/esm/tools/annotation/PlanarFreehandROITool.js +1 -1
- package/dist/esm/tools/annotation/PlanarFreehandROITool.js.map +1 -1
- package/dist/esm/tools/annotation/SplineROITool.js +6 -4
- package/dist/esm/tools/annotation/SplineROITool.js.map +1 -1
- package/dist/esm/tools/annotation/planarFreehandROITool/drawLoop.js +4 -6
- package/dist/esm/tools/annotation/planarFreehandROITool/drawLoop.js.map +1 -1
- package/dist/esm/utilities/contourSegmentation/addContourSegmentationAnnotation.js +3 -0
- package/dist/esm/utilities/contourSegmentation/addContourSegmentationAnnotation.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/interpolate.js +27 -17
- package/dist/esm/utilities/contours/interpolation/interpolate.js.map +1 -1
- package/dist/esm/utilities/contours/interpolation/selectHandles.js +2 -2
- package/dist/esm/utilities/contours/interpolation/selectHandles.js.map +1 -1
- package/dist/esm/utilities/contours/interpolation/updateChildInterpolationUID.js +13 -0
- package/dist/esm/utilities/contours/interpolation/updateChildInterpolationUID.js.map +1 -0
- package/dist/esm/utilities/getCalibratedUnits.js +4 -1
- package/dist/esm/utilities/getCalibratedUnits.js.map +1 -1
- package/dist/esm/utilities/segmentation/InterpolationManager/InterpolationManager.js.map +1 -1
- package/dist/types/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.d.ts +3 -0
- package/dist/types/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.d.ts.map +1 -1
- package/dist/types/store/ToolGroupManager/ToolGroup.d.ts +3 -2
- package/dist/types/store/ToolGroupManager/ToolGroup.d.ts.map +1 -1
- package/dist/types/tools/CrosshairsTool.d.ts +1 -1
- package/dist/types/tools/CrosshairsTool.d.ts.map +1 -1
- package/dist/types/tools/annotation/PlanarFreehandROITool.d.ts.map +1 -1
- package/dist/types/tools/annotation/SplineROITool.d.ts.map +1 -1
- package/dist/types/tools/annotation/planarFreehandROITool/drawLoop.d.ts.map +1 -1
- package/dist/types/types/IToolGroup.d.ts +2 -2
- package/dist/types/types/IToolGroup.d.ts.map +1 -1
- package/dist/types/types/index.d.ts +1 -1
- package/dist/types/types/index.d.ts.map +1 -1
- package/dist/types/utilities/contourSegmentation/addContourSegmentationAnnotation.d.ts.map +1 -1
- package/dist/types/utilities/contours/interpolation/createPolylineToolData.d.ts.map +1 -1
- package/dist/types/utilities/contours/interpolation/interpolate.d.ts.map +1 -1
- package/dist/types/utilities/contours/interpolation/selectHandles.d.ts.map +1 -1
- package/dist/types/utilities/contours/interpolation/updateChildInterpolationUID.d.ts +3 -0
- package/dist/types/utilities/contours/interpolation/updateChildInterpolationUID.d.ts.map +1 -0
- package/dist/types/utilities/getCalibratedUnits.d.ts.map +1 -1
- package/dist/types/utilities/math/vec2/liangBarksyClip.d.ts +1 -1
- package/dist/umd/index.js +1 -1
- package/dist/umd/index.js.map +1 -1
- package/package.json +3 -3
- package/src/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.ts +6 -1
- package/src/store/ToolGroupManager/ToolGroup.ts +28 -10
- package/src/tools/annotation/PlanarFreehandROITool.ts +3 -3
- package/src/tools/annotation/SplineROITool.ts +10 -5
- package/src/tools/annotation/planarFreehandROITool/drawLoop.ts +4 -7
- package/src/types/IToolGroup.ts +11 -2
- package/src/types/index.ts +1 -1
- package/src/utilities/contourSegmentation/addContourSegmentationAnnotation.ts +4 -0
- package/src/utilities/contours/interpolation/createPolylineToolData.ts +2 -1
- package/src/utilities/contours/interpolation/interpolate.ts +54 -44
- package/src/utilities/contours/interpolation/selectHandles.ts +3 -2
- package/src/utilities/contours/interpolation/updateChildInterpolationUID.ts +23 -0
- package/src/utilities/getCalibratedUnits.ts +7 -1
- package/src/utilities/segmentation/InterpolationManager/InterpolationManager.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/tools",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.64.1",
|
|
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.64.1",
|
|
33
33
|
"@icr/polyseg-wasm": "0.4.0",
|
|
34
34
|
"@types/offscreencanvas": "2019.7.3",
|
|
35
35
|
"comlink": "^4.4.1",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"type": "individual",
|
|
60
60
|
"url": "https://ohif.org/donate"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "b4141c95bbe62e39291512b58099c4aff8715fb3"
|
|
63
63
|
}
|
|
@@ -201,7 +201,12 @@ function findIntersectingContour(
|
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
-
|
|
204
|
+
/**
|
|
205
|
+
* Modifies the holeAnnotation to work as a contour hole in the targetAnnotation,
|
|
206
|
+
* displayed on the given viewport.
|
|
207
|
+
|
|
208
|
+
*/
|
|
209
|
+
export function createPolylineHole(
|
|
205
210
|
viewport: Types.IViewport,
|
|
206
211
|
targetAnnotation: ContourSegmentationAnnotation,
|
|
207
212
|
holeAnnotation: ContourSegmentationAnnotation
|
|
@@ -30,6 +30,8 @@ import { initElementCursor } from '../../cursors/elementCursor';
|
|
|
30
30
|
|
|
31
31
|
const { Active, Passive, Enabled, Disabled } = ToolModes;
|
|
32
32
|
|
|
33
|
+
const PRIMARY_BINDINGS = [{ mouseButton: MouseBindings.Primary }];
|
|
34
|
+
|
|
33
35
|
/**
|
|
34
36
|
* ToolGroup class which is a container for tools and their modes and states.
|
|
35
37
|
* In Cornerstone3DTools, you need to create a tool group in order to use the
|
|
@@ -424,7 +426,7 @@ export default class ToolGroup implements IToolGroup {
|
|
|
424
426
|
*/
|
|
425
427
|
public setToolPassive(
|
|
426
428
|
toolName: string,
|
|
427
|
-
options?: { removeAllBindings?: boolean }
|
|
429
|
+
options?: { removeAllBindings?: boolean | IToolBinding[] }
|
|
428
430
|
): void {
|
|
429
431
|
const toolInstance = this._toolInstances[toolName];
|
|
430
432
|
|
|
@@ -449,13 +451,18 @@ export default class ToolGroup implements IToolGroup {
|
|
|
449
451
|
}
|
|
450
452
|
);
|
|
451
453
|
|
|
452
|
-
const
|
|
454
|
+
const matchBindings = Array.isArray(options?.removeAllBindings)
|
|
455
|
+
? options.removeAllBindings
|
|
456
|
+
: this.getDefaultPrimaryBindings();
|
|
453
457
|
|
|
454
458
|
// Remove the primary button bindings without modifiers, if they exist
|
|
455
459
|
toolOptions.bindings = toolOptions.bindings.filter(
|
|
456
460
|
(binding) =>
|
|
457
461
|
options?.removeAllBindings !== true &&
|
|
458
|
-
(
|
|
462
|
+
!matchBindings.some((matchBinding) =>
|
|
463
|
+
hasSameBinding(binding, matchBinding)
|
|
464
|
+
)
|
|
465
|
+
//(binding.mouseButton !== defaultMousePrimary || binding.modifierKey)
|
|
459
466
|
);
|
|
460
467
|
// If there are other bindings, set the tool to be active
|
|
461
468
|
let mode = Passive;
|
|
@@ -681,12 +688,20 @@ export default class ToolGroup implements IToolGroup {
|
|
|
681
688
|
|
|
682
689
|
/**
|
|
683
690
|
* Returns the default mouse primary button.
|
|
684
|
-
*
|
|
685
691
|
*/
|
|
686
692
|
public getDefaultMousePrimary(): MouseBindings {
|
|
687
693
|
return MouseBindings.Primary;
|
|
688
694
|
}
|
|
689
695
|
|
|
696
|
+
/**
|
|
697
|
+
* Gets an array of bindings that is the full primary binding.
|
|
698
|
+
* Currently this is just the primary mouse button, but may be extended in the
|
|
699
|
+
* future to include touch or other binding types.
|
|
700
|
+
*/
|
|
701
|
+
public getDefaultPrimaryBindings(): IToolBinding[] {
|
|
702
|
+
return PRIMARY_BINDINGS;
|
|
703
|
+
}
|
|
704
|
+
|
|
690
705
|
/**
|
|
691
706
|
* Get the configuration of tool. It returns only the config for the given path (in case exists).
|
|
692
707
|
* ConfigurationPath is the the path of the property to get separated by '.'.
|
|
@@ -759,12 +774,9 @@ export default class ToolGroup implements IToolGroup {
|
|
|
759
774
|
* @returns A boolean value.
|
|
760
775
|
*/
|
|
761
776
|
private _hasMousePrimaryButtonBinding(toolOptions) {
|
|
762
|
-
const
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
(binding) =>
|
|
766
|
-
binding.mouseButton === defaultMousePrimary &&
|
|
767
|
-
binding.modifierKey === undefined
|
|
777
|
+
const primaryBindings = this.getDefaultPrimaryBindings();
|
|
778
|
+
return toolOptions?.bindings?.some((binding) =>
|
|
779
|
+
primaryBindings.some((primary) => hasSameBinding(binding, primary))
|
|
768
780
|
);
|
|
769
781
|
}
|
|
770
782
|
|
|
@@ -799,6 +811,9 @@ export default class ToolGroup implements IToolGroup {
|
|
|
799
811
|
}
|
|
800
812
|
}
|
|
801
813
|
|
|
814
|
+
/**
|
|
815
|
+
* Figure out if the two bindings are the same
|
|
816
|
+
*/
|
|
802
817
|
function hasSameBinding(
|
|
803
818
|
binding1: IToolBinding,
|
|
804
819
|
binding2: IToolBinding
|
|
@@ -806,6 +821,9 @@ function hasSameBinding(
|
|
|
806
821
|
if (binding1.mouseButton !== binding2.mouseButton) {
|
|
807
822
|
return false;
|
|
808
823
|
}
|
|
824
|
+
if (binding1.numTouchPoints !== binding2.numTouchPoints) {
|
|
825
|
+
return false;
|
|
826
|
+
}
|
|
809
827
|
|
|
810
828
|
return binding1.modifierKey === binding2.modifierKey;
|
|
811
829
|
}
|
|
@@ -372,7 +372,7 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool {
|
|
|
372
372
|
const enabledElement = getEnabledElement(element);
|
|
373
373
|
const { viewport } = enabledElement;
|
|
374
374
|
|
|
375
|
-
const points = annotation.data.contour
|
|
375
|
+
const { polyline: points } = annotation.data.contour;
|
|
376
376
|
|
|
377
377
|
// NOTE: It is implemented this way so that we do not double calculate
|
|
378
378
|
// points when number crunching adjacent line segments.
|
|
@@ -402,7 +402,7 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool {
|
|
|
402
402
|
return pointCanProjectOnLine(canvasCoords, pStart, pEnd, proximity);
|
|
403
403
|
};
|
|
404
404
|
|
|
405
|
-
cancel = (element: HTMLDivElement): void => {
|
|
405
|
+
public cancel = (element: HTMLDivElement): void => {
|
|
406
406
|
const isDrawing = this.isDrawing;
|
|
407
407
|
const isEditingOpen = this.isEditingOpen;
|
|
408
408
|
const isEditingClosed = this.isEditingClosed;
|
|
@@ -421,7 +421,7 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool {
|
|
|
421
421
|
* `handles`, which means `filterAnnotationsForDisplay` fails inside
|
|
422
422
|
* `filterAnnotationsWithinSlice`.
|
|
423
423
|
*/
|
|
424
|
-
filterInteractableAnnotationsForElement(
|
|
424
|
+
public filterInteractableAnnotationsForElement(
|
|
425
425
|
element: HTMLDivElement,
|
|
426
426
|
annotations: Annotations
|
|
427
427
|
): Annotations | undefined {
|
|
@@ -691,12 +691,17 @@ class SplineROITool extends ContourSegmentationBaseTool {
|
|
|
691
691
|
const splineConfig = this._getSplineConfig(splineType);
|
|
692
692
|
const spline = annotation.data.spline.instance;
|
|
693
693
|
|
|
694
|
+
const childAnnotations = getChildAnnotations(annotation);
|
|
695
|
+
const missingAnnotation = childAnnotations.findIndex((it) => !it);
|
|
696
|
+
if (missingAnnotation !== -1) {
|
|
697
|
+
// Child annotations go AWOL for a variety of reasons, so report is specifically here
|
|
698
|
+
throw new Error(
|
|
699
|
+
`Can't find annotation for child ${annotation.childAnnotationUIDs.join()}`
|
|
700
|
+
);
|
|
701
|
+
}
|
|
694
702
|
// Update current and all child annotations/splines
|
|
695
|
-
const splineAnnotationsGroup = [
|
|
696
|
-
annotation
|
|
697
|
-
...getChildAnnotations(annotation),
|
|
698
|
-
].filter((annotation) =>
|
|
699
|
-
this._isSplineROIAnnotation(annotation)
|
|
703
|
+
const splineAnnotationsGroup = [annotation, ...childAnnotations].filter(
|
|
704
|
+
(annotation) => this._isSplineROIAnnotation(annotation)
|
|
700
705
|
) as SplineROIAnnotation[];
|
|
701
706
|
|
|
702
707
|
splineAnnotationsGroup.forEach((annotation) => {
|
|
@@ -18,7 +18,7 @@ import { PlanarFreehandROIAnnotation } from '../../../types/ToolSpecificAnnotati
|
|
|
18
18
|
import findOpenUShapedContourVectorToPeak from './findOpenUShapedContourVectorToPeak';
|
|
19
19
|
import { polyline } from '../../../utilities/math';
|
|
20
20
|
import { removeAnnotation } from '../../../stateManagement/annotation/annotationState';
|
|
21
|
-
import
|
|
21
|
+
import { ContourWindingDirection } from '../../../types/ContourAnnotation';
|
|
22
22
|
|
|
23
23
|
const {
|
|
24
24
|
addCanvasPointsToArray,
|
|
@@ -234,19 +234,16 @@ function completeDrawClosedContour(
|
|
|
234
234
|
// Remove last point which will be a duplicate now.
|
|
235
235
|
canvasPoints.pop();
|
|
236
236
|
|
|
237
|
-
const clockwise = this.configuration.makeClockWise
|
|
238
|
-
? reverseIfAntiClockwise(canvasPoints)
|
|
239
|
-
: canvasPoints;
|
|
240
|
-
|
|
241
237
|
const updatedPoints = shouldSmooth(this.configuration, annotation)
|
|
242
|
-
? getInterpolatedPoints(this.configuration,
|
|
243
|
-
:
|
|
238
|
+
? getInterpolatedPoints(this.configuration, canvasPoints)
|
|
239
|
+
: canvasPoints;
|
|
244
240
|
|
|
245
241
|
this.updateContourPolyline(
|
|
246
242
|
annotation,
|
|
247
243
|
{
|
|
248
244
|
points: updatedPoints,
|
|
249
245
|
closed: true,
|
|
246
|
+
targetWindingDirection: ContourWindingDirection.Clockwise,
|
|
250
247
|
},
|
|
251
248
|
viewport
|
|
252
249
|
);
|
package/src/types/IToolGroup.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import type { Types } from '@cornerstonejs/core';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
IToolBinding,
|
|
4
|
+
SetToolBindingsType,
|
|
5
|
+
ToolOptionsType,
|
|
6
|
+
} from './ISetToolModeOptions';
|
|
3
7
|
import { MouseBindings } from '../enums';
|
|
4
8
|
import { ToolConfiguration } from '../types';
|
|
5
9
|
/**
|
|
6
10
|
* ToolGroup interface
|
|
11
|
+
* @deprecated - this is going away in favour of using the type import from the
|
|
12
|
+
* tool group itself.
|
|
7
13
|
*/
|
|
8
14
|
export default interface IToolGroup {
|
|
9
15
|
/** Unserializable instantiated tool classes, keyed by name */
|
|
@@ -44,7 +50,10 @@ export default interface IToolGroup {
|
|
|
44
50
|
};
|
|
45
51
|
/** Setting the tool to be Passive by its name*/
|
|
46
52
|
setToolPassive: {
|
|
47
|
-
(
|
|
53
|
+
(
|
|
54
|
+
toolName: string,
|
|
55
|
+
options?: { removeAllBindings?: boolean | IToolBinding[] }
|
|
56
|
+
): void;
|
|
48
57
|
};
|
|
49
58
|
/** Setting the tool to be Enabled by its name*/
|
|
50
59
|
setToolEnabled: {
|
package/src/types/index.ts
CHANGED
|
@@ -23,7 +23,7 @@ import type {
|
|
|
23
23
|
IToolBinding,
|
|
24
24
|
ToolOptionsType,
|
|
25
25
|
} from './ISetToolModeOptions';
|
|
26
|
-
import type IToolGroup from '
|
|
26
|
+
import type IToolGroup from '../store/ToolGroupManager/ToolGroup';
|
|
27
27
|
import type * as ToolSpecificAnnotationTypes from './ToolSpecificAnnotationTypes';
|
|
28
28
|
import type * as AnnotationStyle from './AnnotationStyle';
|
|
29
29
|
import type ToolHandle from './ToolHandle';
|
|
@@ -8,6 +8,10 @@ import { ContourSegmentationAnnotation } from '../../types';
|
|
|
8
8
|
export function addContourSegmentationAnnotation(
|
|
9
9
|
annotation: ContourSegmentationAnnotation
|
|
10
10
|
) {
|
|
11
|
+
if (annotation.parentAnnotationUID) {
|
|
12
|
+
// Don't add it for parent annotations - this happens during interpolation
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
11
15
|
if (!annotation.data.segmentation) {
|
|
12
16
|
throw new Error(
|
|
13
17
|
'addContourSegmentationAnnotation: annotation does not have a segmentation data'
|
|
@@ -31,6 +31,7 @@ export default function createPolylineToolData(
|
|
|
31
31
|
annotationUID: undefined,
|
|
32
32
|
cachedStats: {},
|
|
33
33
|
childAnnotationUIDs: [],
|
|
34
|
+
parentAnnotationUID: undefined,
|
|
34
35
|
});
|
|
35
36
|
Object.assign(annotation.data, {
|
|
36
37
|
handles: {
|
|
@@ -54,8 +55,8 @@ export default function createPolylineToolData(
|
|
|
54
55
|
},
|
|
55
56
|
},
|
|
56
57
|
contour: {
|
|
58
|
+
...referencedToolData.data.contour,
|
|
57
59
|
polyline,
|
|
58
|
-
closed: true,
|
|
59
60
|
},
|
|
60
61
|
});
|
|
61
62
|
|
|
@@ -10,6 +10,8 @@ import type { AnnotationInterpolationCompletedEventDetail } from '../../../types
|
|
|
10
10
|
import EventTypes from '../../../enums/Events';
|
|
11
11
|
import * as annotationState from '../../../stateManagement/annotation';
|
|
12
12
|
import selectHandles from './selectHandles';
|
|
13
|
+
import updateChildInterpolationUID from './updateChildInterpolationUID';
|
|
14
|
+
import { createPolylineHole } from '../../../eventListeners/annotations/contourSegmentation/contourSegmentationCompleted';
|
|
13
15
|
|
|
14
16
|
const { PointsManager } = utilities;
|
|
15
17
|
|
|
@@ -70,7 +72,8 @@ function interpolate(viewportData: InterpolationViewportData) {
|
|
|
70
72
|
* @returns null
|
|
71
73
|
*/
|
|
72
74
|
function startInterpolation(viewportData: InterpolationViewportData) {
|
|
73
|
-
const toolData = viewportData
|
|
75
|
+
const { annotation: toolData } = viewportData;
|
|
76
|
+
updateChildInterpolationUID(toolData);
|
|
74
77
|
const { interpolationData, interpolationList } =
|
|
75
78
|
findAnnotationsForInterpolation(toolData, viewportData) || {};
|
|
76
79
|
|
|
@@ -129,12 +132,10 @@ function _linearlyInterpolateBetween(
|
|
|
129
132
|
interpolationData,
|
|
130
133
|
eventData
|
|
131
134
|
) {
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
);
|
|
135
|
-
const c2 = _generateClosedContour(
|
|
136
|
-
interpolationData.get(annotationPair[1])[0].data.contour.polyline
|
|
137
|
-
);
|
|
135
|
+
const annotation0 = interpolationData.get(annotationPair[0])[0];
|
|
136
|
+
const annotation1 = interpolationData.get(annotationPair[1])[0];
|
|
137
|
+
const c1 = _generateClosedContour(annotation0.data.contour.polyline);
|
|
138
|
+
const c2 = _generateClosedContour(annotation1.data.contour.polyline);
|
|
138
139
|
|
|
139
140
|
const { c1Interp, c2Interp } = _generateInterpolationContourPair(c1, c2);
|
|
140
141
|
c1Interp.kIndex = annotationPair[0];
|
|
@@ -189,6 +190,8 @@ function _linearlyInterpolateContour(
|
|
|
189
190
|
) {
|
|
190
191
|
const [startIndex, endIndex] = annotationPair;
|
|
191
192
|
const zInterp = (sliceIndex - startIndex) / (endIndex - startIndex);
|
|
193
|
+
const annotation0 = interpolationData.get(startIndex)[0];
|
|
194
|
+
const annotation1 = interpolationData.get(endIndex)[0];
|
|
192
195
|
const interpolated3DPoints = _generateInterpolatedOpenContour(
|
|
193
196
|
c1Interp,
|
|
194
197
|
c2Interp,
|
|
@@ -196,9 +199,7 @@ function _linearlyInterpolateContour(
|
|
|
196
199
|
c1HasMoreNodes
|
|
197
200
|
);
|
|
198
201
|
|
|
199
|
-
const nearestAnnotation =
|
|
200
|
-
annotationPair[zInterp > 0.5 ? 1 : 0]
|
|
201
|
-
)[0];
|
|
202
|
+
const nearestAnnotation = zInterp > 0.5 ? annotation1 : annotation0;
|
|
202
203
|
|
|
203
204
|
const handlePoints = selectHandles(interpolated3DPoints);
|
|
204
205
|
|
|
@@ -255,8 +256,41 @@ function _addInterpolatedContour(
|
|
|
255
256
|
interpolatedAnnotation,
|
|
256
257
|
referencedToolData
|
|
257
258
|
);
|
|
259
|
+
|
|
260
|
+
const { parentAnnotationUID } = referencedToolData;
|
|
261
|
+
if (parentAnnotationUID) {
|
|
262
|
+
const parentReferenced =
|
|
263
|
+
annotationState.state.getAnnotation(parentAnnotationUID);
|
|
264
|
+
const parentAnnotation = _findExistingAnnotation(
|
|
265
|
+
parentReferenced,
|
|
266
|
+
sliceIndex,
|
|
267
|
+
eventData
|
|
268
|
+
);
|
|
269
|
+
createPolylineHole(viewport, parentAnnotation, interpolatedAnnotation);
|
|
270
|
+
}
|
|
258
271
|
}
|
|
259
272
|
|
|
273
|
+
/**
|
|
274
|
+
* Finds an existing annotation on the given slide, with the interpolation UID as
|
|
275
|
+
* specified in the referenced tool data.
|
|
276
|
+
*/
|
|
277
|
+
function _findExistingAnnotation(referencedToolData, sliceIndex, eventData) {
|
|
278
|
+
const { viewport } = eventData;
|
|
279
|
+
const annotations = annotationState.state.getAnnotations(
|
|
280
|
+
referencedToolData.metadata.toolName,
|
|
281
|
+
viewport.element
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
for (let i = 0; i < annotations.length; i++) {
|
|
285
|
+
const annotation = annotations[i] as InterpolationROIAnnotation;
|
|
286
|
+
if (
|
|
287
|
+
annotation.interpolationUID === referencedToolData.interpolationUID &&
|
|
288
|
+
annotation.metadata.sliceIndex === sliceIndex
|
|
289
|
+
) {
|
|
290
|
+
return annotation;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
260
294
|
/**
|
|
261
295
|
* _editInterpolatedContour - Edits an interpolated polygon on the imageId
|
|
262
296
|
* that corresponds to the specified ROIContour.
|
|
@@ -266,7 +300,6 @@ function _addInterpolatedContour(
|
|
|
266
300
|
* @param referencedToolData - type, The toolData of another polygon in the
|
|
267
301
|
* ROIContour, to assign appropriate metadata to the new polygon.
|
|
268
302
|
* @param eventData - object
|
|
269
|
-
* @returns null
|
|
270
303
|
*/
|
|
271
304
|
function _editInterpolatedContour(
|
|
272
305
|
interpolated3DPoints: PointsArray3,
|
|
@@ -275,46 +308,23 @@ function _editInterpolatedContour(
|
|
|
275
308
|
referencedToolData,
|
|
276
309
|
eventData
|
|
277
310
|
) {
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
311
|
+
const oldAnnotationData = _findExistingAnnotation(
|
|
312
|
+
referencedToolData,
|
|
313
|
+
sliceIndex,
|
|
314
|
+
eventData
|
|
282
315
|
);
|
|
283
316
|
|
|
284
|
-
// Find the index of the polygon on this slice corresponding to
|
|
285
|
-
// The ROIContour.
|
|
286
|
-
let toolDataIndex;
|
|
287
|
-
|
|
288
|
-
for (let i = 0; i < annotations.length; i++) {
|
|
289
|
-
const annotation = annotations[i] as InterpolationROIAnnotation;
|
|
290
|
-
if (
|
|
291
|
-
annotation.interpolationUID === referencedToolData.interpolationUID &&
|
|
292
|
-
annotation.metadata.sliceIndex === sliceIndex
|
|
293
|
-
) {
|
|
294
|
-
toolDataIndex = i;
|
|
295
|
-
break;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
if (toolDataIndex === undefined) {
|
|
299
|
-
console.warn(
|
|
300
|
-
'Unable to find referenced slice index in the tool data',
|
|
301
|
-
sliceIndex,
|
|
302
|
-
annotations
|
|
303
|
-
);
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
const oldToolData = annotations[toolDataIndex] as InterpolationROIAnnotation;
|
|
308
317
|
const points = interpolated3DPoints.points;
|
|
309
318
|
const interpolatedAnnotation = createPolylineToolData(
|
|
310
319
|
points,
|
|
311
320
|
handlePoints,
|
|
312
|
-
|
|
321
|
+
oldAnnotationData
|
|
313
322
|
);
|
|
314
|
-
//
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
323
|
+
// Does a real update here instead of an add/remove, which caused delete issues in child annotations
|
|
324
|
+
Object.assign(oldAnnotationData, {
|
|
325
|
+
metadata: interpolatedAnnotation.metadata,
|
|
326
|
+
data: interpolatedAnnotation.data,
|
|
327
|
+
});
|
|
318
328
|
}
|
|
319
329
|
|
|
320
330
|
/**
|
|
@@ -21,7 +21,7 @@ export default function selectHandles(
|
|
|
21
21
|
const { sources: destPoints } = handles;
|
|
22
22
|
const { length, sources: sourcePoints = [] } = polyline;
|
|
23
23
|
// The distance used for figuring out the local angle of a line
|
|
24
|
-
const distance =
|
|
24
|
+
const distance = 5;
|
|
25
25
|
if (length < distance * 3) {
|
|
26
26
|
return polyline.subselect(handleCount);
|
|
27
27
|
}
|
|
@@ -29,8 +29,9 @@ export default function selectHandles(
|
|
|
29
29
|
// variation between points in terms of the distance of a line angle, but
|
|
30
30
|
// also not too many handles either.
|
|
31
31
|
// On average, we get twice the interval between handles, so double the length here.
|
|
32
|
+
// Or, choose a longer interval if the handle count would have too many handles (too short an interval)
|
|
32
33
|
const interval = Math.floor(
|
|
33
|
-
Math.max((2 * length) / handleCount, distance *
|
|
34
|
+
Math.max((2 * length) / handleCount, distance * 2)
|
|
34
35
|
);
|
|
35
36
|
sourcePoints.forEach(() =>
|
|
36
37
|
destPoints.push(PointsManager.create3(handleCount))
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { InterpolationROIAnnotation } from '../../../types/ToolSpecificAnnotationTypes';
|
|
2
|
+
import * as annotationState from '../../../stateManagement/annotation';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Updates child annotation interpolation UIDs to be the parent interpolationUID
|
|
6
|
+
* followed by `-{index}` where the index is the hole/child index. This causes
|
|
7
|
+
* child annotations to be matched positionally within the parent.
|
|
8
|
+
*/
|
|
9
|
+
export default function updateChildInterpolationUID(
|
|
10
|
+
annotation: InterpolationROIAnnotation
|
|
11
|
+
) {
|
|
12
|
+
const { parentAnnotationUID, annotationUID } = annotation;
|
|
13
|
+
if (!parentAnnotationUID) {
|
|
14
|
+
return annotation.interpolationUID;
|
|
15
|
+
}
|
|
16
|
+
const parentAnnotation = annotationState.state.getAnnotation(
|
|
17
|
+
parentAnnotationUID
|
|
18
|
+
) as InterpolationROIAnnotation;
|
|
19
|
+
const { interpolationUID } = parentAnnotation;
|
|
20
|
+
const index = parentAnnotation.childAnnotationUIDs.indexOf(annotationUID);
|
|
21
|
+
annotation.interpolationUID = `${interpolationUID}-${index}`;
|
|
22
|
+
return annotation.interpolationUID;
|
|
23
|
+
}
|
|
@@ -173,7 +173,13 @@ const getCalibratedLengthUnitsAndScale = (image, handles) => {
|
|
|
173
173
|
}
|
|
174
174
|
} else if (calibration.scale) {
|
|
175
175
|
scale = calibration.scale;
|
|
176
|
-
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// everything except REGION/Uncalibratted
|
|
179
|
+
const types = [CalibrationTypes.ERMF, CalibrationTypes.USER, CalibrationTypes.ERROR, CalibrationTypes.PROJECTION];
|
|
180
|
+
|
|
181
|
+
if (types.includes(calibration?.type)) {
|
|
182
|
+
calibrationType = calibration.type;
|
|
177
183
|
}
|
|
178
184
|
|
|
179
185
|
return {
|
|
@@ -209,7 +209,6 @@ export default class InterpolationManager {
|
|
|
209
209
|
) {
|
|
210
210
|
return;
|
|
211
211
|
}
|
|
212
|
-
|
|
213
212
|
const viewport = getViewportForAnnotation(annotation);
|
|
214
213
|
if (!viewport) {
|
|
215
214
|
console.warn(
|
|
@@ -219,7 +218,8 @@ export default class InterpolationManager {
|
|
|
219
218
|
return;
|
|
220
219
|
}
|
|
221
220
|
if (annotation.autoGenerated) {
|
|
222
|
-
// Dont fire the annotation changed events here, as that leads to recursion
|
|
221
|
+
// Dont fire the annotation changed events here, as that leads to recursion,
|
|
222
|
+
// although this is in fact completing the event, so trigger the segmentation add
|
|
223
223
|
addContourSegmentationAnnotation(annotation);
|
|
224
224
|
annotation.autoGenerated = false;
|
|
225
225
|
}
|