@cornerstonejs/tools 1.63.1 → 1.63.3
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/tools/annotation/KeyImageTool.d.ts +1 -29
- package/dist/cjs/tools/annotation/KeyImageTool.js +3 -30
- package/dist/cjs/tools/annotation/KeyImageTool.js.map +1 -1
- package/dist/cjs/tools/annotation/planarFreehandROITool/drawLoop.js +26 -11
- package/dist/cjs/tools/annotation/planarFreehandROITool/drawLoop.js.map +1 -1
- package/dist/cjs/tools/base/AnnotationTool.d.ts +3 -0
- package/dist/cjs/tools/base/AnnotationTool.js +41 -0
- package/dist/cjs/tools/base/AnnotationTool.js.map +1 -1
- package/dist/cjs/utilities/math/polyline/addCanvasPointsToArray.js +5 -0
- package/dist/cjs/utilities/math/polyline/addCanvasPointsToArray.js.map +1 -1
- package/dist/cjs/utilities/math/polyline/getSignedArea.js +3 -0
- package/dist/cjs/utilities/math/polyline/getSignedArea.js.map +1 -1
- package/dist/esm/tools/annotation/KeyImageTool.js +3 -30
- package/dist/esm/tools/annotation/KeyImageTool.js.map +1 -1
- package/dist/esm/tools/annotation/planarFreehandROITool/drawLoop.js +27 -12
- package/dist/esm/tools/annotation/planarFreehandROITool/drawLoop.js.map +1 -1
- package/dist/esm/tools/base/AnnotationTool.js +42 -1
- package/dist/esm/tools/base/AnnotationTool.js.map +1 -1
- package/dist/esm/utilities/math/polyline/addCanvasPointsToArray.js +5 -0
- package/dist/esm/utilities/math/polyline/addCanvasPointsToArray.js.map +1 -1
- package/dist/esm/utilities/math/polyline/getSignedArea.js +3 -0
- package/dist/esm/utilities/math/polyline/getSignedArea.js.map +1 -1
- package/dist/types/tools/annotation/KeyImageTool.d.ts +1 -29
- package/dist/types/tools/annotation/KeyImageTool.d.ts.map +1 -1
- package/dist/types/tools/annotation/planarFreehandROITool/drawLoop.d.ts.map +1 -1
- package/dist/types/tools/base/AnnotationTool.d.ts +3 -0
- package/dist/types/tools/base/AnnotationTool.d.ts.map +1 -1
- package/dist/types/utilities/math/polyline/addCanvasPointsToArray.d.ts.map +1 -1
- package/dist/types/utilities/math/polyline/getSignedArea.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/tools/annotation/KeyImageTool.ts +3 -31
- package/src/tools/annotation/planarFreehandROITool/drawLoop.ts +43 -13
- package/src/tools/base/AnnotationTool.ts +68 -2
- package/src/utilities/math/polyline/addCanvasPointsToArray.ts +6 -1
- package/src/utilities/math/polyline/getSignedArea.ts +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/tools",
|
|
3
|
-
"version": "1.63.
|
|
3
|
+
"version": "1.63.3",
|
|
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.63.
|
|
32
|
+
"@cornerstonejs/core": "^1.63.3",
|
|
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": "027b911678b62776ca4407fe900a47e1f5045e14"
|
|
63
63
|
}
|
|
@@ -89,37 +89,9 @@ class KeyImageTool extends AnnotationTool {
|
|
|
89
89
|
viewUp
|
|
90
90
|
);
|
|
91
91
|
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
annotationUID: null as string,
|
|
96
|
-
highlighted: true,
|
|
97
|
-
invalidated: true,
|
|
98
|
-
metadata: {
|
|
99
|
-
toolName: this.getToolName(),
|
|
100
|
-
viewPlaneNormal: <Types.Point3>[...viewPlaneNormal],
|
|
101
|
-
viewUp: <Types.Point3>[...viewUp],
|
|
102
|
-
FrameOfReferenceUID,
|
|
103
|
-
referencedImageId,
|
|
104
|
-
},
|
|
105
|
-
data: {
|
|
106
|
-
text: '',
|
|
107
|
-
handles: {
|
|
108
|
-
points: new Array<Types.Point3>(),
|
|
109
|
-
textBox: {
|
|
110
|
-
hasMoved: false,
|
|
111
|
-
worldPosition: <Types.Point3>[0, 0, 0],
|
|
112
|
-
worldBoundingBox: {
|
|
113
|
-
topLeft: <Types.Point3>[0, 0, 0],
|
|
114
|
-
topRight: <Types.Point3>[0, 0, 0],
|
|
115
|
-
bottomLeft: <Types.Point3>[0, 0, 0],
|
|
116
|
-
bottomRight: <Types.Point3>[0, 0, 0],
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
},
|
|
120
|
-
label: '',
|
|
121
|
-
},
|
|
122
|
-
};
|
|
92
|
+
const annotation = KeyImageTool.createAnnotation({
|
|
93
|
+
metadata: { ...viewport.getViewReference(), referencedImageId },
|
|
94
|
+
});
|
|
123
95
|
|
|
124
96
|
addAnnotation(annotation, element);
|
|
125
97
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getEnabledElement } from '@cornerstonejs/core';
|
|
1
|
+
import { getEnabledElement, utilities } from '@cornerstonejs/core';
|
|
2
2
|
import {
|
|
3
3
|
resetElementCursor,
|
|
4
4
|
hideElementCursor,
|
|
@@ -190,9 +190,9 @@ function mouseUpDrawCallback(evt: EventTypes.InteractionEventType): void {
|
|
|
190
190
|
this.configuration.closeContourProximity
|
|
191
191
|
)
|
|
192
192
|
) {
|
|
193
|
-
this.completeDrawOpenContour(element, contourHoleProcessingEnabled);
|
|
193
|
+
this.completeDrawOpenContour(element, { contourHoleProcessingEnabled });
|
|
194
194
|
} else {
|
|
195
|
-
this.completeDrawClosedContour(element, contourHoleProcessingEnabled);
|
|
195
|
+
this.completeDrawClosedContour(element, { contourHoleProcessingEnabled });
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
|
|
@@ -201,10 +201,19 @@ function mouseUpDrawCallback(evt: EventTypes.InteractionEventType): void {
|
|
|
201
201
|
*/
|
|
202
202
|
function completeDrawClosedContour(
|
|
203
203
|
element: HTMLDivElement,
|
|
204
|
-
|
|
204
|
+
options: {
|
|
205
|
+
contourHoleProcessingEnabled: boolean;
|
|
206
|
+
minPointsToSave: number;
|
|
207
|
+
}
|
|
205
208
|
): boolean {
|
|
206
209
|
this.removeCrossedLinesOnCompleteDraw();
|
|
210
|
+
|
|
207
211
|
const { canvasPoints } = this.drawData;
|
|
212
|
+
const { contourHoleProcessingEnabled, minPointsToSave } = options ?? {};
|
|
213
|
+
|
|
214
|
+
if (minPointsToSave && canvasPoints.length < minPointsToSave) {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
208
217
|
|
|
209
218
|
// check and halt if necessary the drawing process, last chance to complete drawing and fire events.
|
|
210
219
|
if (this.haltDrawing(element, canvasPoints)) {
|
|
@@ -280,7 +289,13 @@ function removeCrossedLinesOnCompleteDraw(): void {
|
|
|
280
289
|
if (lineSegment) {
|
|
281
290
|
const indexToRemoveUpTo = lineSegment[1];
|
|
282
291
|
|
|
283
|
-
|
|
292
|
+
// It is better to remove the last point when the user just moved the mouse
|
|
293
|
+
// cursor back than deleting the entire contour
|
|
294
|
+
if (indexToRemoveUpTo === 1) {
|
|
295
|
+
this.drawData.canvasPoints = canvasPoints.splice(1);
|
|
296
|
+
} else {
|
|
297
|
+
this.drawData.canvasPoints = canvasPoints.splice(0, indexToRemoveUpTo);
|
|
298
|
+
}
|
|
284
299
|
}
|
|
285
300
|
}
|
|
286
301
|
|
|
@@ -289,9 +304,12 @@ function removeCrossedLinesOnCompleteDraw(): void {
|
|
|
289
304
|
*/
|
|
290
305
|
function completeDrawOpenContour(
|
|
291
306
|
element: HTMLDivElement,
|
|
292
|
-
|
|
307
|
+
options: {
|
|
308
|
+
contourHoleProcessingEnabled: boolean;
|
|
309
|
+
}
|
|
293
310
|
): boolean {
|
|
294
311
|
const { canvasPoints } = this.drawData;
|
|
312
|
+
const { contourHoleProcessingEnabled } = options ?? {};
|
|
295
313
|
|
|
296
314
|
// check and halt if necessary the drawing process, last chance to complete drawing and fire events.
|
|
297
315
|
if (this.haltDrawing(element, canvasPoints)) {
|
|
@@ -392,7 +410,7 @@ function applyCreateOnCross(
|
|
|
392
410
|
): void {
|
|
393
411
|
const eventDetail = evt.detail;
|
|
394
412
|
const { element } = eventDetail;
|
|
395
|
-
const { canvasPoints } = this.drawData;
|
|
413
|
+
const { canvasPoints, contourHoleProcessingEnabled } = this.drawData;
|
|
396
414
|
const { annotation, viewportIdsToRender } = this.commonData;
|
|
397
415
|
|
|
398
416
|
// Add points between the end point and crossing point
|
|
@@ -405,12 +423,24 @@ function applyCreateOnCross(
|
|
|
405
423
|
// Remove last point which will be a duplicate now.
|
|
406
424
|
canvasPoints.pop();
|
|
407
425
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
426
|
+
const remainingPoints = canvasPoints.slice(crossingIndex);
|
|
427
|
+
const newArea = polyline.getArea(remainingPoints);
|
|
428
|
+
|
|
429
|
+
// User just moved the mouse back and the last points must be removed
|
|
430
|
+
// otherwise the entire contour drawn would be lost.
|
|
431
|
+
if (utilities.isEqual(newArea, 0)) {
|
|
432
|
+
canvasPoints.splice(crossingIndex + 1);
|
|
433
|
+
return;
|
|
411
434
|
}
|
|
412
435
|
|
|
413
|
-
|
|
436
|
+
canvasPoints.splice(0, crossingIndex);
|
|
437
|
+
|
|
438
|
+
// There is no contour with less than 3 points.
|
|
439
|
+
// It's possible to have a contour with very few points after removing
|
|
440
|
+
// crossed lines which is not enough to save as a contour.
|
|
441
|
+
const options = { contourHoleProcessingEnabled, minPointsToSave: 3 };
|
|
442
|
+
|
|
443
|
+
if (this.completeDrawClosedContour(element, options)) {
|
|
414
444
|
// pos complete operation
|
|
415
445
|
this.activateClosedContourEdit(evt, annotation, viewportIdsToRender);
|
|
416
446
|
}
|
|
@@ -433,9 +463,9 @@ function cancelDrawing(element: HTMLElement) {
|
|
|
433
463
|
this.configuration.closeContourProximity
|
|
434
464
|
)
|
|
435
465
|
) {
|
|
436
|
-
this.completeDrawOpenContour(element, contourHoleProcessingEnabled);
|
|
466
|
+
this.completeDrawOpenContour(element, { contourHoleProcessingEnabled });
|
|
437
467
|
} else {
|
|
438
|
-
this.completeDrawClosedContour(element, contourHoleProcessingEnabled);
|
|
468
|
+
this.completeDrawClosedContour(element, { contourHoleProcessingEnabled });
|
|
439
469
|
}
|
|
440
470
|
}
|
|
441
471
|
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
cache,
|
|
4
4
|
getEnabledElement,
|
|
5
5
|
metaData,
|
|
6
|
+
utilities as csUtils,
|
|
6
7
|
} from '@cornerstonejs/core';
|
|
7
8
|
import type { Types } from '@cornerstonejs/core';
|
|
8
9
|
|
|
@@ -19,11 +20,12 @@ import {
|
|
|
19
20
|
InteractionTypes,
|
|
20
21
|
ToolProps,
|
|
21
22
|
PublicToolProps,
|
|
22
|
-
IToolBinding,
|
|
23
23
|
} from '../../types';
|
|
24
|
+
import { addAnnotation } from '../../stateManagement/annotation/annotationState';
|
|
24
25
|
import { StyleSpecifier } from '../../types/AnnotationStyle';
|
|
26
|
+
import { triggerAnnotationModified } from '../../stateManagement/annotation/helpers/state';
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
/**
|
|
27
29
|
* Abstract class for tools which create and display annotations on the
|
|
28
30
|
* cornerstone3D canvas. In addition, it provides a base class for segmentation
|
|
29
31
|
* tools that require drawing an annotation before running the segmentation strategy
|
|
@@ -34,6 +36,70 @@ import { StyleSpecifier } from '../../types/AnnotationStyle';
|
|
|
34
36
|
* abstract methods.
|
|
35
37
|
*/
|
|
36
38
|
abstract class AnnotationTool extends AnnotationDisplayTool {
|
|
39
|
+
/**
|
|
40
|
+
* Creates a base annotation object, adding in any annotation base data provided
|
|
41
|
+
*/
|
|
42
|
+
public static createAnnotation(...annotationBaseData): Annotation {
|
|
43
|
+
let annotation: Annotation = {
|
|
44
|
+
annotationUID: null as string,
|
|
45
|
+
highlighted: true,
|
|
46
|
+
invalidated: true,
|
|
47
|
+
metadata: {
|
|
48
|
+
toolName: this.toolName,
|
|
49
|
+
},
|
|
50
|
+
data: {
|
|
51
|
+
text: '',
|
|
52
|
+
handles: {
|
|
53
|
+
points: new Array<Types.Point3>(),
|
|
54
|
+
textBox: {
|
|
55
|
+
hasMoved: false,
|
|
56
|
+
worldPosition: <Types.Point3>[0, 0, 0],
|
|
57
|
+
worldBoundingBox: {
|
|
58
|
+
topLeft: <Types.Point3>[0, 0, 0],
|
|
59
|
+
topRight: <Types.Point3>[0, 0, 0],
|
|
60
|
+
bottomLeft: <Types.Point3>[0, 0, 0],
|
|
61
|
+
bottomRight: <Types.Point3>[0, 0, 0],
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
label: '',
|
|
66
|
+
},
|
|
67
|
+
} as unknown as Annotation;
|
|
68
|
+
for (const baseData of annotationBaseData) {
|
|
69
|
+
annotation = csUtils.deepMerge(annotation, baseData);
|
|
70
|
+
}
|
|
71
|
+
return annotation;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Creates a new annotation for the given viewport. This just adds the
|
|
76
|
+
* viewport reference data to the metadata, and otherwise returns the
|
|
77
|
+
* static class createAnnotation data.
|
|
78
|
+
*/
|
|
79
|
+
public static createAnnotationForViewport(viewport, ...annotationBaseData) {
|
|
80
|
+
return this.createAnnotation(
|
|
81
|
+
{ metadata: viewport.getViewReference() },
|
|
82
|
+
...annotationBaseData
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Creates and adds an annotation of the given type, firing the annotation
|
|
88
|
+
* modified event on the new annotation.
|
|
89
|
+
* This implicitly uses the static class when you call it on the correct
|
|
90
|
+
* base class. For example, you can call the KeyImageTool.createAnnotation
|
|
91
|
+
* method on KeyImageTool.toolName by calling KeyImageTool.createAndAddAnnotation
|
|
92
|
+
*
|
|
93
|
+
*/
|
|
94
|
+
public static createAndAddAnnotation(viewport, ...annotationBaseData) {
|
|
95
|
+
const annotation = this.createAnnotationForViewport(
|
|
96
|
+
viewport,
|
|
97
|
+
...annotationBaseData
|
|
98
|
+
);
|
|
99
|
+
addAnnotation(annotation, viewport.element);
|
|
100
|
+
triggerAnnotationModified(annotation, viewport.element);
|
|
101
|
+
}
|
|
102
|
+
|
|
37
103
|
static toolName;
|
|
38
104
|
// ===================================================================
|
|
39
105
|
// Abstract Methods - Must be implemented.
|
|
@@ -16,11 +16,16 @@ const addCanvasPointsToArray = (
|
|
|
16
16
|
const enabledElement = getEnabledElement(element);
|
|
17
17
|
const { viewport } = enabledElement;
|
|
18
18
|
|
|
19
|
+
if (!canvasPoints.length) {
|
|
20
|
+
canvasPoints.push(newCanvasPoint);
|
|
21
|
+
console.log('>>>>> !canvasPoints. :: RETURN');
|
|
22
|
+
return 1;
|
|
23
|
+
}
|
|
24
|
+
|
|
19
25
|
const lastWorldPos = viewport.canvasToWorld(
|
|
20
26
|
canvasPoints[canvasPoints.length - 1]
|
|
21
27
|
);
|
|
22
28
|
const newWorldPos = viewport.canvasToWorld(newCanvasPoint);
|
|
23
|
-
|
|
24
29
|
const worldPosDiff = vec3.create();
|
|
25
30
|
|
|
26
31
|
vec3.subtract(worldPosDiff, newWorldPos, lastWorldPos);
|
|
@@ -13,6 +13,10 @@ import type { Types } from '@cornerstonejs/core';
|
|
|
13
13
|
* @returns Area of the polyline (with signal)
|
|
14
14
|
*/
|
|
15
15
|
export default function getSignedArea(polyline: Types.Point2[]): number {
|
|
16
|
+
if (polyline.length < 3) {
|
|
17
|
+
return 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
16
20
|
// Reference point can be any point on the same plane
|
|
17
21
|
const refPoint = polyline[0];
|
|
18
22
|
let area = 0;
|