@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.
Files changed (37) hide show
  1. package/dist/cjs/tools/annotation/KeyImageTool.d.ts +1 -29
  2. package/dist/cjs/tools/annotation/KeyImageTool.js +3 -30
  3. package/dist/cjs/tools/annotation/KeyImageTool.js.map +1 -1
  4. package/dist/cjs/tools/annotation/planarFreehandROITool/drawLoop.js +26 -11
  5. package/dist/cjs/tools/annotation/planarFreehandROITool/drawLoop.js.map +1 -1
  6. package/dist/cjs/tools/base/AnnotationTool.d.ts +3 -0
  7. package/dist/cjs/tools/base/AnnotationTool.js +41 -0
  8. package/dist/cjs/tools/base/AnnotationTool.js.map +1 -1
  9. package/dist/cjs/utilities/math/polyline/addCanvasPointsToArray.js +5 -0
  10. package/dist/cjs/utilities/math/polyline/addCanvasPointsToArray.js.map +1 -1
  11. package/dist/cjs/utilities/math/polyline/getSignedArea.js +3 -0
  12. package/dist/cjs/utilities/math/polyline/getSignedArea.js.map +1 -1
  13. package/dist/esm/tools/annotation/KeyImageTool.js +3 -30
  14. package/dist/esm/tools/annotation/KeyImageTool.js.map +1 -1
  15. package/dist/esm/tools/annotation/planarFreehandROITool/drawLoop.js +27 -12
  16. package/dist/esm/tools/annotation/planarFreehandROITool/drawLoop.js.map +1 -1
  17. package/dist/esm/tools/base/AnnotationTool.js +42 -1
  18. package/dist/esm/tools/base/AnnotationTool.js.map +1 -1
  19. package/dist/esm/utilities/math/polyline/addCanvasPointsToArray.js +5 -0
  20. package/dist/esm/utilities/math/polyline/addCanvasPointsToArray.js.map +1 -1
  21. package/dist/esm/utilities/math/polyline/getSignedArea.js +3 -0
  22. package/dist/esm/utilities/math/polyline/getSignedArea.js.map +1 -1
  23. package/dist/types/tools/annotation/KeyImageTool.d.ts +1 -29
  24. package/dist/types/tools/annotation/KeyImageTool.d.ts.map +1 -1
  25. package/dist/types/tools/annotation/planarFreehandROITool/drawLoop.d.ts.map +1 -1
  26. package/dist/types/tools/base/AnnotationTool.d.ts +3 -0
  27. package/dist/types/tools/base/AnnotationTool.d.ts.map +1 -1
  28. package/dist/types/utilities/math/polyline/addCanvasPointsToArray.d.ts.map +1 -1
  29. package/dist/types/utilities/math/polyline/getSignedArea.d.ts.map +1 -1
  30. package/dist/umd/index.js +1 -1
  31. package/dist/umd/index.js.map +1 -1
  32. package/package.json +3 -3
  33. package/src/tools/annotation/KeyImageTool.ts +3 -31
  34. package/src/tools/annotation/planarFreehandROITool/drawLoop.ts +43 -13
  35. package/src/tools/base/AnnotationTool.ts +68 -2
  36. package/src/utilities/math/polyline/addCanvasPointsToArray.ts +6 -1
  37. 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.1",
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.1",
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": "e4fcacba07b254d69218c70e5e549a696115f008"
62
+ "gitHead": "027b911678b62776ca4407fe900a47e1f5045e14"
63
63
  }
@@ -89,37 +89,9 @@ class KeyImageTool extends AnnotationTool {
89
89
  viewUp
90
90
  );
91
91
 
92
- const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
93
-
94
- const annotation = {
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
- contourHoleProcessingEnabled: boolean
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
- this.drawData.canvasPoints = canvasPoints.splice(0, indexToRemoveUpTo);
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
- contourHoleProcessingEnabled: boolean
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
- // Remove points up to just before the crossing index
409
- for (let i = 0; i < crossingIndex; i++) {
410
- canvasPoints.shift();
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
- if (this.completeDrawClosedContour(element)) {
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
- /**-q
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;