@cornerstonejs/tools 1.70.6 → 1.70.8

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 (91) hide show
  1. package/dist/cjs/enums/Events.d.ts +2 -0
  2. package/dist/cjs/enums/Events.js +2 -0
  3. package/dist/cjs/enums/Events.js.map +1 -1
  4. package/dist/cjs/store/ToolGroupManager/ToolGroup.js +12 -0
  5. package/dist/cjs/store/ToolGroupManager/ToolGroup.js.map +1 -1
  6. package/dist/cjs/tools/OrientationMarkerTool.d.ts +0 -2
  7. package/dist/cjs/tools/OrientationMarkerTool.js +41 -27
  8. package/dist/cjs/tools/OrientationMarkerTool.js.map +1 -1
  9. package/dist/cjs/tools/annotation/BidirectionalTool.js +15 -8
  10. package/dist/cjs/tools/annotation/BidirectionalTool.js.map +1 -1
  11. package/dist/cjs/tools/annotation/CircleROITool.js +19 -18
  12. package/dist/cjs/tools/annotation/CircleROITool.js.map +1 -1
  13. package/dist/cjs/tools/annotation/EllipticalROITool.d.ts +1 -1
  14. package/dist/cjs/tools/annotation/EllipticalROITool.js +21 -20
  15. package/dist/cjs/tools/annotation/EllipticalROITool.js.map +1 -1
  16. package/dist/cjs/tools/annotation/PlanarFreehandROITool.js +27 -4
  17. package/dist/cjs/tools/annotation/PlanarFreehandROITool.js.map +1 -1
  18. package/dist/cjs/tools/annotation/RectangleROITool.js +18 -18
  19. package/dist/cjs/tools/annotation/RectangleROITool.js.map +1 -1
  20. package/dist/cjs/tools/annotation/SplineROITool.js +16 -2
  21. package/dist/cjs/tools/annotation/SplineROITool.js.map +1 -1
  22. package/dist/cjs/utilities/getCalibratedUnits.d.ts +1 -5
  23. package/dist/cjs/utilities/getCalibratedUnits.js +13 -45
  24. package/dist/cjs/utilities/getCalibratedUnits.js.map +1 -1
  25. package/dist/cjs/utilities/index.d.ts +2 -2
  26. package/dist/cjs/utilities/index.js +4 -4
  27. package/dist/cjs/utilities/index.js.map +1 -1
  28. package/dist/cjs/utilities/stackPrefetch/stackContextPrefetch.js +4 -2
  29. package/dist/cjs/utilities/stackPrefetch/stackContextPrefetch.js.map +1 -1
  30. package/dist/cjs/utilities/stackPrefetch/stackPrefetch.js +4 -2
  31. package/dist/cjs/utilities/stackPrefetch/stackPrefetch.js.map +1 -1
  32. package/dist/esm/enums/Events.js +2 -0
  33. package/dist/esm/enums/Events.js.map +1 -1
  34. package/dist/esm/store/ToolGroupManager/ToolGroup.js +12 -0
  35. package/dist/esm/store/ToolGroupManager/ToolGroup.js.map +1 -1
  36. package/dist/esm/tools/OrientationMarkerTool.js +42 -28
  37. package/dist/esm/tools/OrientationMarkerTool.js.map +1 -1
  38. package/dist/esm/tools/annotation/BidirectionalTool.js +16 -9
  39. package/dist/esm/tools/annotation/BidirectionalTool.js.map +1 -1
  40. package/dist/esm/tools/annotation/CircleROITool.js +21 -20
  41. package/dist/esm/tools/annotation/CircleROITool.js.map +1 -1
  42. package/dist/esm/tools/annotation/EllipticalROITool.js +23 -22
  43. package/dist/esm/tools/annotation/EllipticalROITool.js.map +1 -1
  44. package/dist/esm/tools/annotation/PlanarFreehandROITool.js +29 -6
  45. package/dist/esm/tools/annotation/PlanarFreehandROITool.js.map +1 -1
  46. package/dist/esm/tools/annotation/RectangleROITool.js +19 -19
  47. package/dist/esm/tools/annotation/RectangleROITool.js.map +1 -1
  48. package/dist/esm/tools/annotation/SplineROITool.js +17 -3
  49. package/dist/esm/tools/annotation/SplineROITool.js.map +1 -1
  50. package/dist/esm/utilities/getCalibratedUnits.js +13 -41
  51. package/dist/esm/utilities/getCalibratedUnits.js.map +1 -1
  52. package/dist/esm/utilities/index.js +2 -2
  53. package/dist/esm/utilities/index.js.map +1 -1
  54. package/dist/esm/utilities/stackPrefetch/stackContextPrefetch.js +4 -2
  55. package/dist/esm/utilities/stackPrefetch/stackContextPrefetch.js.map +1 -1
  56. package/dist/esm/utilities/stackPrefetch/stackPrefetch.js +4 -2
  57. package/dist/esm/utilities/stackPrefetch/stackPrefetch.js.map +1 -1
  58. package/dist/types/enums/Events.d.ts +2 -0
  59. package/dist/types/enums/Events.d.ts.map +1 -1
  60. package/dist/types/store/ToolGroupManager/ToolGroup.d.ts.map +1 -1
  61. package/dist/types/tools/OrientationMarkerTool.d.ts +0 -2
  62. package/dist/types/tools/OrientationMarkerTool.d.ts.map +1 -1
  63. package/dist/types/tools/annotation/BidirectionalTool.d.ts.map +1 -1
  64. package/dist/types/tools/annotation/CircleROITool.d.ts.map +1 -1
  65. package/dist/types/tools/annotation/EllipticalROITool.d.ts +1 -1
  66. package/dist/types/tools/annotation/EllipticalROITool.d.ts.map +1 -1
  67. package/dist/types/tools/annotation/PlanarFreehandROITool.d.ts.map +1 -1
  68. package/dist/types/tools/annotation/RectangleROITool.d.ts.map +1 -1
  69. package/dist/types/tools/annotation/SplineROITool.d.ts.map +1 -1
  70. package/dist/types/utilities/getCalibratedUnits.d.ts +1 -5
  71. package/dist/types/utilities/getCalibratedUnits.d.ts.map +1 -1
  72. package/dist/types/utilities/index.d.ts +2 -2
  73. package/dist/types/utilities/index.d.ts.map +1 -1
  74. package/dist/types/utilities/stackPrefetch/stackContextPrefetch.d.ts.map +1 -1
  75. package/dist/types/utilities/stackPrefetch/stackPrefetch.d.ts.map +1 -1
  76. package/dist/umd/index.js +1 -1
  77. package/dist/umd/index.js.map +1 -1
  78. package/package.json +3 -3
  79. package/src/enums/Events.ts +6 -0
  80. package/src/store/ToolGroupManager/ToolGroup.ts +16 -0
  81. package/src/tools/OrientationMarkerTool.ts +67 -49
  82. package/src/tools/annotation/BidirectionalTool.ts +28 -15
  83. package/src/tools/annotation/CircleROITool.ts +24 -25
  84. package/src/tools/annotation/EllipticalROITool.ts +28 -39
  85. package/src/tools/annotation/PlanarFreehandROITool.ts +56 -11
  86. package/src/tools/annotation/RectangleROITool.ts +23 -23
  87. package/src/tools/annotation/SplineROITool.ts +36 -4
  88. package/src/utilities/getCalibratedUnits.ts +18 -74
  89. package/src/utilities/index.ts +6 -6
  90. package/src/utilities/stackPrefetch/stackContextPrefetch.ts +6 -2
  91. package/src/utilities/stackPrefetch/stackPrefetch.ts +6 -2
@@ -7,10 +7,7 @@ import {
7
7
  } from '@cornerstonejs/core';
8
8
  import type { Types } from '@cornerstonejs/core';
9
9
 
10
- import {
11
- getCalibratedAreaUnits,
12
- getCalibratedScale,
13
- } from '../../utilities/getCalibratedUnits';
10
+ import { getCalibratedLengthUnitsAndScale } from '../../utilities/getCalibratedUnits';
14
11
  import { roundNumber } from '../../utilities';
15
12
  import throttle from '../../utilities/throttle';
16
13
  import {
@@ -878,37 +875,35 @@ class RectangleROITool extends AnnotationTool {
878
875
  }
879
876
 
880
877
  const { dimensions, imageData, metadata } = image;
881
- const scalarData =
882
- 'getScalarData' in image ? image.getScalarData() : image.scalarData;
883
878
 
884
- const worldPos1Index = transformWorldToIndex(imageData, worldPos1);
879
+ const pos1Index = transformWorldToIndex(imageData, worldPos1);
885
880
 
886
- worldPos1Index[0] = Math.floor(worldPos1Index[0]);
887
- worldPos1Index[1] = Math.floor(worldPos1Index[1]);
888
- worldPos1Index[2] = Math.floor(worldPos1Index[2]);
881
+ pos1Index[0] = Math.floor(pos1Index[0]);
882
+ pos1Index[1] = Math.floor(pos1Index[1]);
883
+ pos1Index[2] = Math.floor(pos1Index[2]);
889
884
 
890
- const worldPos2Index = transformWorldToIndex(imageData, worldPos2);
885
+ const pos2Index = transformWorldToIndex(imageData, worldPos2);
891
886
 
892
- worldPos2Index[0] = Math.floor(worldPos2Index[0]);
893
- worldPos2Index[1] = Math.floor(worldPos2Index[1]);
894
- worldPos2Index[2] = Math.floor(worldPos2Index[2]);
887
+ pos2Index[0] = Math.floor(pos2Index[0]);
888
+ pos2Index[1] = Math.floor(pos2Index[1]);
889
+ pos2Index[2] = Math.floor(pos2Index[2]);
895
890
 
896
891
  // Check if one of the indexes are inside the volume, this then gives us
897
892
  // Some area to do stats over.
898
893
 
899
- if (this._isInsideVolume(worldPos1Index, worldPos2Index, dimensions)) {
894
+ if (this._isInsideVolume(pos1Index, pos2Index, dimensions)) {
900
895
  this.isHandleOutsideImage = false;
901
896
 
902
897
  // Calculate index bounds to iterate over
903
898
 
904
- const iMin = Math.min(worldPos1Index[0], worldPos2Index[0]);
905
- const iMax = Math.max(worldPos1Index[0], worldPos2Index[0]);
899
+ const iMin = Math.min(pos1Index[0], pos2Index[0]);
900
+ const iMax = Math.max(pos1Index[0], pos2Index[0]);
906
901
 
907
- const jMin = Math.min(worldPos1Index[1], worldPos2Index[1]);
908
- const jMax = Math.max(worldPos1Index[1], worldPos2Index[1]);
902
+ const jMin = Math.min(pos1Index[1], pos2Index[1]);
903
+ const jMax = Math.max(pos1Index[1], pos2Index[1]);
909
904
 
910
- const kMin = Math.min(worldPos1Index[2], worldPos2Index[2]);
911
- const kMax = Math.max(worldPos1Index[2], worldPos2Index[2]);
905
+ const kMin = Math.min(pos1Index[2], pos2Index[2]);
906
+ const kMax = Math.max(pos1Index[2], pos2Index[2]);
912
907
 
913
908
  const boundsIJK = [
914
909
  [iMin, iMax],
@@ -922,7 +917,12 @@ class RectangleROITool extends AnnotationTool {
922
917
  worldPos1,
923
918
  worldPos2
924
919
  );
925
- const scale = getCalibratedScale(image);
920
+
921
+ const handles = [pos1Index, pos2Index];
922
+ const { scale, areaUnits } = getCalibratedLengthUnitsAndScale(
923
+ image,
924
+ handles
925
+ );
926
926
 
927
927
  const area = Math.abs(worldWidth * worldHeight) / (scale * scale);
928
928
 
@@ -959,7 +959,7 @@ class RectangleROITool extends AnnotationTool {
959
959
  max: stats.max?.value,
960
960
  statsArray: stats.array,
961
961
  pointsInShape: pointsInShape,
962
- areaUnit: getCalibratedAreaUnits(null, image),
962
+ areaUnit: areaUnits,
963
963
  modalityUnit,
964
964
  };
965
965
  } else {
@@ -37,8 +37,7 @@ import {
37
37
  throttle,
38
38
  roundNumber,
39
39
  triggerAnnotationRenderForViewportIds,
40
- getCalibratedScale,
41
- getCalibratedAreaUnits,
40
+ getCalibratedLengthUnitsAndScale,
42
41
  } from '../../utilities';
43
42
  import getMouseModifierKey from '../../eventDispatchers/shared/getMouseModifier';
44
43
  import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
@@ -1163,7 +1162,40 @@ class SplineROITool extends ContourSegmentationBaseTool {
1163
1162
  const deltaInX = vec3.distance(originalWorldPoint, deltaXPoint);
1164
1163
  const deltaInY = vec3.distance(originalWorldPoint, deltaYPoint);
1165
1164
 
1166
- const scale = getCalibratedScale(image);
1165
+ const { imageData } = image;
1166
+ const { scale, areaUnits } = getCalibratedLengthUnitsAndScale(
1167
+ image,
1168
+ () => {
1169
+ const {
1170
+ maxX: canvasMaxX,
1171
+ maxY: canvasMaxY,
1172
+ minX: canvasMinX,
1173
+ minY: canvasMinY,
1174
+ } = math.polyline.getAABB(canvasCoordinates);
1175
+
1176
+ const topLeftBBWorld = viewport.canvasToWorld([
1177
+ canvasMinX,
1178
+ canvasMinY,
1179
+ ]);
1180
+
1181
+ const topLeftBBIndex = utilities.transformWorldToIndex(
1182
+ imageData,
1183
+ topLeftBBWorld
1184
+ );
1185
+
1186
+ const bottomRightBBWorld = viewport.canvasToWorld([
1187
+ canvasMaxX,
1188
+ canvasMaxY,
1189
+ ]);
1190
+
1191
+ const bottomRightBBIndex = utilities.transformWorldToIndex(
1192
+ imageData,
1193
+ bottomRightBBWorld
1194
+ );
1195
+
1196
+ return [topLeftBBIndex, bottomRightBBIndex];
1197
+ }
1198
+ );
1167
1199
  let area = math.polyline.getArea(canvasCoordinates) / scale / scale;
1168
1200
 
1169
1201
  // Convert from canvas_pixels ^2 to mm^2
@@ -1172,7 +1204,7 @@ class SplineROITool extends ContourSegmentationBaseTool {
1172
1204
  cachedStats[targetId] = {
1173
1205
  Modality: metadata.Modality,
1174
1206
  area,
1175
- areaUnit: getCalibratedAreaUnits(null, image),
1207
+ areaUnit: areaUnits,
1176
1208
  };
1177
1209
  }
1178
1210
 
@@ -21,72 +21,7 @@ const UNIT_MAPPING = {
21
21
  };
22
22
 
23
23
  const EPS = 1e-3;
24
-
25
- /**
26
- * Extracts the length units and the type of calibration for those units
27
- * into the response. The length units will typically be either mm or px
28
- * while the calibration type can be any of a number of different calibration types.
29
- *
30
- * Volumetric images have no calibration type, so are just the raw mm.
31
- *
32
- * TODO: Handle region calibration
33
- *
34
- * @param handles - used to detect if the spacing information is different
35
- * between various points (eg angled ERMF or US Region).
36
- * Currently unused, but needed for correct US Region handling
37
- * @param image - to extract the calibration from
38
- * image.calibration - calibration value to extract units form
39
- * @returns String containing the units and type of calibration
40
- */
41
- const getCalibratedLengthUnits = (handles, image): string => {
42
- const { calibration, hasPixelSpacing } = image;
43
- // Anachronistic - moving to using calibration consistently, but not completed yet
44
- const units = hasPixelSpacing ? 'mm' : PIXEL_UNITS;
45
- if (
46
- !calibration ||
47
- (!calibration.type && !calibration.sequenceOfUltrasoundRegions)
48
- ) {
49
- return units;
50
- }
51
- if (calibration.type === CalibrationTypes.UNCALIBRATED) {
52
- return PIXEL_UNITS;
53
- }
54
- if (calibration.sequenceOfUltrasoundRegions) {
55
- return 'US Region';
56
- }
57
- return `${units} ${calibration.type}`;
58
- };
59
-
60
24
  const SQUARE = '\xb2';
61
- /**
62
- * Extracts the area units, including the squared sign plus calibration type.
63
- */
64
- const getCalibratedAreaUnits = (handles, image): string => {
65
- const { calibration, hasPixelSpacing } = image;
66
- const units = (hasPixelSpacing ? 'mm' : PIXEL_UNITS) + SQUARE;
67
- if (!calibration || !calibration.type) {
68
- return units;
69
- }
70
- if (calibration.sequenceOfUltrasoundRegions) {
71
- return 'US Region';
72
- }
73
- return `${units} ${calibration.type}`;
74
- };
75
-
76
- /**
77
- * Gets the scale divisor for converting from internal spacing to
78
- * image spacing for calibrated images.
79
- */
80
- const getCalibratedScale = (image, handles = []) => {
81
- if (image.calibration?.sequenceOfUltrasoundRegions) {
82
- // image.spacing / image.us.space
83
- } else if (image.calibration?.scale) {
84
- return image.calibration.scale;
85
- } else {
86
- return 1;
87
- }
88
- };
89
-
90
25
  /**
91
26
  * Extracts the calibrated length units, area units, and the scale
92
27
  * for converting from internal spacing to image spacing.
@@ -96,10 +31,9 @@ const getCalibratedScale = (image, handles = []) => {
96
31
  * @returns Object containing the units, area units, and scale
97
32
  */
98
33
  const getCalibratedLengthUnitsAndScale = (image, handles) => {
99
- const [imageIndex1, imageIndex2] = handles;
100
34
  const { calibration, hasPixelSpacing } = image;
101
35
  let units = hasPixelSpacing ? 'mm' : PIXEL_UNITS;
102
- const areaUnits = units + SQUARE;
36
+ let areaUnits = units + SQUARE;
103
37
  let scale = 1;
104
38
  let calibrationType = '';
105
39
 
@@ -115,6 +49,15 @@ const getCalibratedLengthUnitsAndScale = (image, handles) => {
115
49
  }
116
50
 
117
51
  if (calibration.sequenceOfUltrasoundRegions) {
52
+ let imageIndex1, imageIndex2;
53
+ if (Array.isArray(handles) && handles.length === 2) {
54
+ [imageIndex1, imageIndex2] = handles;
55
+ } else if (typeof handles === 'function') {
56
+ const points = handles();
57
+ imageIndex1 = points[0];
58
+ imageIndex2 = points[1];
59
+ }
60
+
118
61
  let regions = calibration.sequenceOfUltrasoundRegions.filter(
119
62
  (region) =>
120
63
  imageIndex1[0] >= region.regionLocationMinX0 &&
@@ -165,17 +108,23 @@ const getCalibratedLengthUnitsAndScale = (image, handles) => {
165
108
  );
166
109
 
167
110
  if (isSamePhysicalDelta) {
168
- scale = 1 / (physicalDeltaX * physicalDeltaY * 100);
111
+ // 1 to 1 aspect ratio, we use just one of them
112
+ scale = 1 / (physicalDeltaX * 10);
169
113
  calibrationType = 'US Region';
170
114
  units = 'mm';
115
+ areaUnits = 'mm' + SQUARE;
171
116
  } else {
117
+ // here we are showing at the aspect ratio of the physical delta
118
+ // if they are not the same, then we should show px, but the correct solution
119
+ // is to grab each point separately and scale them individually
120
+ // Todo: implement this
172
121
  return { units: PIXEL_UNITS, areaUnits: PIXEL_UNITS + SQUARE, scale };
173
122
  }
174
123
  } else if (calibration.scale) {
175
124
  scale = calibration.scale;
176
125
  }
177
126
 
178
- // everything except REGION/Uncalibratted
127
+ // everything except REGION/Uncalibrated
179
128
  const types = [
180
129
  CalibrationTypes.ERMF,
181
130
  CalibrationTypes.USER,
@@ -272,13 +221,8 @@ const getCalibratedProbeUnitsAndValue = (image, handles) => {
272
221
  */
273
222
  const getCalibratedAspect = (image) => image.calibration?.aspect || 1;
274
223
 
275
- export default getCalibratedLengthUnits;
276
-
277
224
  export {
278
- getCalibratedAreaUnits,
279
- getCalibratedLengthUnits,
280
225
  getCalibratedLengthUnitsAndScale,
281
- getCalibratedScale,
282
226
  getCalibratedAspect,
283
227
  getCalibratedProbeUnitsAndValue,
284
228
  };
@@ -12,9 +12,9 @@ import isObject from './isObject';
12
12
  import clip from './clip';
13
13
  import calibrateImageSpacing from './calibrateImageSpacing';
14
14
  import {
15
- getCalibratedLengthUnits,
16
- getCalibratedAreaUnits,
17
- getCalibratedScale,
15
+ getCalibratedLengthUnitsAndScale,
16
+ getCalibratedProbeUnitsAndValue,
17
+ getCalibratedAspect,
18
18
  } from './getCalibratedUnits';
19
19
  import triggerAnnotationRenderForViewportIds from './triggerAnnotationRenderForViewportIds';
20
20
  import triggerAnnotationRenderForToolGroupIds from './triggerAnnotationRenderForToolGroupIds';
@@ -67,9 +67,9 @@ export {
67
67
  touch,
68
68
  triggerEvent,
69
69
  calibrateImageSpacing,
70
- getCalibratedLengthUnits,
71
- getCalibratedAreaUnits,
72
- getCalibratedScale,
70
+ getCalibratedLengthUnitsAndScale,
71
+ getCalibratedProbeUnitsAndValue,
72
+ getCalibratedAspect,
73
73
  segmentation,
74
74
  contours,
75
75
  triggerAnnotationRenderForViewportIds,
@@ -217,7 +217,10 @@ function prefetch(element) {
217
217
  .loadAndCacheImage(imageId, options)
218
218
  .then(() => doneCallback(imageId));
219
219
 
220
- const { useNorm16Texture } = getCoreConfiguration().rendering;
220
+ const { useNorm16Texture, preferSizeOverAccuracy } =
221
+ getCoreConfiguration().rendering;
222
+
223
+ const useNativeDataType = useNorm16Texture || preferSizeOverAccuracy;
221
224
 
222
225
  indicesToRequestCopy.forEach((imageIdIndex) => {
223
226
  const imageId = stack.imageIds[imageIdIndex];
@@ -225,11 +228,12 @@ function prefetch(element) {
225
228
  // highest priority will be used for the request type in the imageRetrievalPool
226
229
  const options = {
227
230
  targetBuffer: {
228
- type: useNorm16Texture ? undefined : 'Float32Array',
231
+ type: useNativeDataType ? undefined : 'Float32Array',
229
232
  },
230
233
  preScale: {
231
234
  enabled: true,
232
235
  },
236
+ useNativeDataType,
233
237
  requestType,
234
238
  };
235
239
 
@@ -166,18 +166,22 @@ function prefetch(element) {
166
166
  const requestFn = (imageId, options) =>
167
167
  imageLoader.loadAndCacheImage(imageId, options);
168
168
 
169
- const { useNorm16Texture } = getCoreConfiguration().rendering;
169
+ const { useNorm16Texture, preferSizeOverAccuracy } =
170
+ getCoreConfiguration().rendering;
171
+
172
+ const useNativeDataType = useNorm16Texture || preferSizeOverAccuracy;
170
173
 
171
174
  imageIdsToPrefetch.forEach((imageId) => {
172
175
  // IMPORTANT: Request type should be passed if not the 'interaction'
173
176
  // highest priority will be used for the request type in the imageRetrievalPool
174
177
  const options = {
175
178
  targetBuffer: {
176
- type: useNorm16Texture ? undefined : 'Float32Array',
179
+ type: useNativeDataType ? undefined : 'Float32Array',
177
180
  },
178
181
  preScale: {
179
182
  enabled: true,
180
183
  },
184
+ useNativeDataType,
181
185
  requestType,
182
186
  };
183
187