@cornerstonejs/tools 1.72.5 → 1.72.6
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/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.js +3 -0
- package/dist/cjs/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.js.map +1 -1
- package/dist/cjs/stateManagement/annotation/utilities/defineProperties.d.ts +4 -0
- package/dist/cjs/stateManagement/annotation/utilities/defineProperties.js +27 -0
- package/dist/cjs/stateManagement/annotation/utilities/defineProperties.js.map +1 -0
- package/dist/cjs/types/AnnotationTypes.d.ts +2 -2
- package/dist/cjs/utilities/annotationHydration.d.ts +7 -0
- package/dist/cjs/utilities/annotationHydration.js +84 -0
- package/dist/cjs/utilities/annotationHydration.js.map +1 -0
- package/dist/cjs/utilities/index.d.ts +2 -1
- package/dist/cjs/utilities/index.js +3 -1
- package/dist/cjs/utilities/index.js.map +1 -1
- package/dist/esm/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.js +3 -0
- package/dist/esm/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.js.map +1 -1
- package/dist/esm/stateManagement/annotation/utilities/defineProperties.js +23 -0
- package/dist/esm/stateManagement/annotation/utilities/defineProperties.js.map +1 -0
- package/dist/esm/utilities/annotationHydration.js +83 -0
- package/dist/esm/utilities/annotationHydration.js.map +1 -0
- package/dist/esm/utilities/index.js +2 -1
- package/dist/esm/utilities/index.js.map +1 -1
- package/dist/types/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.d.ts.map +1 -1
- package/dist/types/stateManagement/annotation/utilities/defineProperties.d.ts +5 -0
- package/dist/types/stateManagement/annotation/utilities/defineProperties.d.ts.map +1 -0
- package/dist/types/types/AnnotationTypes.d.ts +2 -2
- package/dist/types/types/AnnotationTypes.d.ts.map +1 -1
- package/dist/types/utilities/annotationHydration.d.ts +8 -0
- package/dist/types/utilities/annotationHydration.d.ts.map +1 -0
- package/dist/types/utilities/index.d.ts +2 -1
- package/dist/types/utilities/index.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/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts +7 -0
- package/src/stateManagement/annotation/utilities/defineProperties.ts +26 -0
- package/src/types/AnnotationTypes.ts +2 -2
- package/src/utilities/annotationHydration.ts +143 -0
- package/src/utilities/index.ts +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/tools",
|
|
3
|
-
"version": "1.72.
|
|
3
|
+
"version": "1.72.6",
|
|
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.72.
|
|
32
|
+
"@cornerstonejs/core": "^1.72.6",
|
|
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": "992f6c69b8f57a3344a1e8ec676376be693ec555"
|
|
63
63
|
}
|
|
@@ -19,6 +19,11 @@ import {
|
|
|
19
19
|
import { checkAndDefineIsLockedProperty } from './annotationLocking';
|
|
20
20
|
import { checkAndDefineIsVisibleProperty } from './annotationVisibility';
|
|
21
21
|
|
|
22
|
+
import {
|
|
23
|
+
checkAndDefineTextBoxProperty,
|
|
24
|
+
checkAndDefineCachedStatsProperty,
|
|
25
|
+
} from './utilities/defineProperties';
|
|
26
|
+
|
|
22
27
|
/**
|
|
23
28
|
* This is the default annotation manager. It stores annotations by default
|
|
24
29
|
* based on the FrameOfReferenceUID. However, it is possible to override the
|
|
@@ -236,6 +241,8 @@ class FrameOfReferenceSpecificAnnotationManager implements IAnnotationManager {
|
|
|
236
241
|
toolSpecificAnnotations.push(annotation);
|
|
237
242
|
checkAndDefineIsLockedProperty(annotation);
|
|
238
243
|
checkAndDefineIsVisibleProperty(annotation);
|
|
244
|
+
checkAndDefineTextBoxProperty(annotation);
|
|
245
|
+
checkAndDefineCachedStatsProperty(annotation);
|
|
239
246
|
};
|
|
240
247
|
|
|
241
248
|
/**
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Annotation } from '../../../types';
|
|
2
|
+
|
|
3
|
+
const checkAndDefineTextBoxProperty = (annotation: Annotation) => {
|
|
4
|
+
if (!annotation.data) {
|
|
5
|
+
annotation.data = {};
|
|
6
|
+
}
|
|
7
|
+
if (!annotation.data.handles) {
|
|
8
|
+
annotation.data.handles = {};
|
|
9
|
+
}
|
|
10
|
+
if (!annotation.data.handles.textBox) {
|
|
11
|
+
annotation.data.handles.textBox = {};
|
|
12
|
+
}
|
|
13
|
+
return annotation;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const checkAndDefineCachedStatsProperty = (annotation: Annotation) => {
|
|
17
|
+
if (!annotation.data) {
|
|
18
|
+
annotation.data = {};
|
|
19
|
+
}
|
|
20
|
+
if (!annotation.data.cachedStats) {
|
|
21
|
+
annotation.data.cachedStats = {};
|
|
22
|
+
}
|
|
23
|
+
return annotation;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { checkAndDefineTextBoxProperty, checkAndDefineCachedStatsProperty };
|
|
@@ -55,9 +55,9 @@ type Annotation = {
|
|
|
55
55
|
/** annotation text box information */
|
|
56
56
|
textBox?: {
|
|
57
57
|
/** whether the text box has moved */
|
|
58
|
-
hasMoved
|
|
58
|
+
hasMoved?: boolean;
|
|
59
59
|
/** the world location of the text box */
|
|
60
|
-
worldPosition
|
|
60
|
+
worldPosition?: Types.Point3;
|
|
61
61
|
/** text box bounding box information */
|
|
62
62
|
worldBoundingBox?: {
|
|
63
63
|
/** Top left location of the text box in the world space */
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Types,
|
|
3
|
+
utilities,
|
|
4
|
+
BaseVolumeViewport,
|
|
5
|
+
StackViewport,
|
|
6
|
+
cache,
|
|
7
|
+
metaData,
|
|
8
|
+
} from '@cornerstonejs/core';
|
|
9
|
+
import { Annotation } from '../types';
|
|
10
|
+
import { addAnnotation } from '../stateManagement';
|
|
11
|
+
import { vec3 } from 'gl-matrix';
|
|
12
|
+
|
|
13
|
+
function annotationHydration(
|
|
14
|
+
viewport: Types.IViewport,
|
|
15
|
+
toolName: string,
|
|
16
|
+
worldPoints: Types.Point3[],
|
|
17
|
+
options?: {
|
|
18
|
+
FrameOfReferenceUID?: string;
|
|
19
|
+
annotationUID?: string;
|
|
20
|
+
}
|
|
21
|
+
): Annotation {
|
|
22
|
+
const viewReference = viewport.getViewReference();
|
|
23
|
+
const { viewPlaneNormal, FrameOfReferenceUID } = viewReference;
|
|
24
|
+
const annotation = {
|
|
25
|
+
annotationUID: options?.annotationUID || utilities.uuidv4(),
|
|
26
|
+
data: {
|
|
27
|
+
handles: {
|
|
28
|
+
points: worldPoints,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
highlighted: false,
|
|
32
|
+
autoGenerated: false,
|
|
33
|
+
invalidated: false,
|
|
34
|
+
isLocked: false,
|
|
35
|
+
isVisible: true,
|
|
36
|
+
metadata: {
|
|
37
|
+
toolName,
|
|
38
|
+
viewPlaneNormal,
|
|
39
|
+
FrameOfReferenceUID,
|
|
40
|
+
referencedImageId: getReferencedImageId(
|
|
41
|
+
viewport,
|
|
42
|
+
worldPoints[0],
|
|
43
|
+
viewPlaneNormal
|
|
44
|
+
),
|
|
45
|
+
...options,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
addAnnotation(annotation, viewport.element);
|
|
49
|
+
return annotation;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getReferencedImageId(
|
|
53
|
+
viewport: Types.IViewport,
|
|
54
|
+
worldPos: Types.Point3,
|
|
55
|
+
viewPlaneNormal: Types.Point3
|
|
56
|
+
): string {
|
|
57
|
+
let referencedImageId;
|
|
58
|
+
|
|
59
|
+
if (viewport instanceof StackViewport) {
|
|
60
|
+
referencedImageId = getClosestImageIdForStackViewport(
|
|
61
|
+
viewport,
|
|
62
|
+
worldPos,
|
|
63
|
+
viewPlaneNormal
|
|
64
|
+
);
|
|
65
|
+
} else if (viewport instanceof BaseVolumeViewport) {
|
|
66
|
+
const targetId = getTargetId(viewport);
|
|
67
|
+
const volumeId = utilities.getVolumeId(targetId);
|
|
68
|
+
const imageVolume = cache.getVolume(volumeId);
|
|
69
|
+
|
|
70
|
+
referencedImageId = utilities.getClosestImageId(
|
|
71
|
+
imageVolume,
|
|
72
|
+
worldPos,
|
|
73
|
+
viewPlaneNormal
|
|
74
|
+
);
|
|
75
|
+
} else {
|
|
76
|
+
throw new Error(
|
|
77
|
+
'getReferencedImageId: viewport must be a StackViewport or BaseVolumeViewport'
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return referencedImageId;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function getTargetId(viewport: Types.IViewport): string | undefined {
|
|
85
|
+
const targetId = viewport.getReferenceId?.();
|
|
86
|
+
if (targetId) {
|
|
87
|
+
return targetId;
|
|
88
|
+
}
|
|
89
|
+
if (viewport instanceof BaseVolumeViewport) {
|
|
90
|
+
return `volumeId:${getTargetVolumeId(viewport)}`;
|
|
91
|
+
}
|
|
92
|
+
throw new Error('getTargetId: viewport must have a getTargetId method');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function getTargetVolumeId(viewport: Types.IViewport): string | undefined {
|
|
96
|
+
const actorEntries = viewport.getActors();
|
|
97
|
+
|
|
98
|
+
if (!actorEntries) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
return actorEntries.find(
|
|
102
|
+
(actorEntry) => actorEntry.actor.getClassName() === 'vtkVolume'
|
|
103
|
+
)?.uid;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function getClosestImageIdForStackViewport(
|
|
107
|
+
viewport: StackViewport,
|
|
108
|
+
worldPos: Types.Point3,
|
|
109
|
+
viewPlaneNormal: Types.Point3
|
|
110
|
+
): string {
|
|
111
|
+
const imageIds = viewport.getImageIds();
|
|
112
|
+
if (!imageIds || !imageIds.length) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const distanceImagePairs = imageIds.map((imageId) => {
|
|
117
|
+
const { imagePositionPatient } = metaData.get('imagePlaneModule', imageId);
|
|
118
|
+
const distance = calculateDistanceToImage(
|
|
119
|
+
worldPos,
|
|
120
|
+
imagePositionPatient,
|
|
121
|
+
viewPlaneNormal
|
|
122
|
+
);
|
|
123
|
+
return { imageId, distance };
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
distanceImagePairs.sort((a, b) => a.distance - b.distance);
|
|
127
|
+
|
|
128
|
+
return distanceImagePairs[0].imageId;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function calculateDistanceToImage(
|
|
132
|
+
worldPos: Types.Point3,
|
|
133
|
+
ImagePositionPatient: Types.Point3,
|
|
134
|
+
viewPlaneNormal: Types.Point3
|
|
135
|
+
): number {
|
|
136
|
+
const dir = vec3.create();
|
|
137
|
+
vec3.sub(dir, worldPos, ImagePositionPatient);
|
|
138
|
+
|
|
139
|
+
const dot = vec3.dot(dir, viewPlaneNormal);
|
|
140
|
+
|
|
141
|
+
return Math.abs(dot);
|
|
142
|
+
}
|
|
143
|
+
export { annotationHydration };
|
package/src/utilities/index.ts
CHANGED
|
@@ -28,7 +28,7 @@ import { pointToString } from './pointToString';
|
|
|
28
28
|
import annotationFrameRange from './annotationFrameRange';
|
|
29
29
|
import pointInSurroundingSphereCallback from './pointInSurroundingSphereCallback';
|
|
30
30
|
import getViewportForAnnotation from './getViewportForAnnotation';
|
|
31
|
-
|
|
31
|
+
import { annotationHydration } from './annotationHydration';
|
|
32
32
|
// name spaces
|
|
33
33
|
import * as contours from './contours';
|
|
34
34
|
import * as segmentation from './segmentation';
|
|
@@ -97,4 +97,5 @@ export {
|
|
|
97
97
|
voi,
|
|
98
98
|
annotationFrameRange,
|
|
99
99
|
contourSegmentation,
|
|
100
|
+
annotationHydration,
|
|
100
101
|
};
|