@cornerstonejs/core 3.0.0-beta.2 → 3.0.0-beta.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/esm/cache/cache.d.ts +3 -0
- package/dist/esm/cache/cache.js +24 -0
- package/dist/esm/utilities/VoxelManager.js +10 -3
- package/dist/esm/utilities/calculateSpacingBetweenImageIds.d.ts +1 -0
- package/dist/esm/utilities/calculateSpacingBetweenImageIds.js +71 -0
- package/dist/esm/utilities/fnv1aHash.d.ts +1 -0
- package/dist/esm/utilities/fnv1aHash.js +9 -0
- package/dist/esm/utilities/index.d.ts +3 -1
- package/dist/esm/utilities/index.js +3 -1
- package/dist/esm/utilities/pointInShapeCallback.js +10 -4
- package/dist/esm/utilities/sortImageIdsAndGetSpacing.js +3 -35
- package/dist/esm/webWorkerManager/webWorkerManager.js +2 -0
- package/package.json +2 -2
|
@@ -3,10 +3,13 @@ import { ImageQualityStatus } from '../enums';
|
|
|
3
3
|
declare class Cache {
|
|
4
4
|
private readonly _imageCache;
|
|
5
5
|
private readonly _volumeCache;
|
|
6
|
+
private readonly _imageIdsToVolumeIdCache;
|
|
6
7
|
private readonly _geometryCache;
|
|
7
8
|
private _imageCacheSize;
|
|
8
9
|
private _maxCacheSize;
|
|
9
10
|
private _geometryCacheSize;
|
|
11
|
+
generateVolumeId(imageIds: string[]): string;
|
|
12
|
+
getImageIdsForVolumeId(volumeId: string): string[];
|
|
10
13
|
setMaxCacheSize: (newMaxCacheSize: number) => void;
|
|
11
14
|
isCacheable: (byteLength: any) => boolean;
|
|
12
15
|
getMaxCacheSize: () => number;
|
package/dist/esm/cache/cache.js
CHANGED
|
@@ -3,11 +3,13 @@ import imageIdToURI from '../utilities/imageIdToURI';
|
|
|
3
3
|
import eventTarget from '../eventTarget';
|
|
4
4
|
import Events from '../enums/Events';
|
|
5
5
|
import { ImageQualityStatus } from '../enums';
|
|
6
|
+
import fnv1aHash from '../utilities/fnv1aHash';
|
|
6
7
|
const ONE_GB = 1073741824;
|
|
7
8
|
class Cache {
|
|
8
9
|
constructor() {
|
|
9
10
|
this._imageCache = new Map();
|
|
10
11
|
this._volumeCache = new Map();
|
|
12
|
+
this._imageIdsToVolumeIdCache = new Map();
|
|
11
13
|
this._geometryCache = new Map();
|
|
12
14
|
this._imageCacheSize = 0;
|
|
13
15
|
this._maxCacheSize = 3 * ONE_GB;
|
|
@@ -284,6 +286,28 @@ class Cache {
|
|
|
284
286
|
return cachedGeometry.geometryLoadObject;
|
|
285
287
|
};
|
|
286
288
|
}
|
|
289
|
+
generateVolumeId(imageIds) {
|
|
290
|
+
const imageURIs = imageIds.map(imageIdToURI).sort();
|
|
291
|
+
let combinedHash = 0x811c9dc5;
|
|
292
|
+
for (const id of imageURIs) {
|
|
293
|
+
const idHash = fnv1aHash(id);
|
|
294
|
+
for (let i = 0; i < idHash.length; i++) {
|
|
295
|
+
combinedHash ^= idHash.charCodeAt(i);
|
|
296
|
+
combinedHash +=
|
|
297
|
+
(combinedHash << 1) +
|
|
298
|
+
(combinedHash << 4) +
|
|
299
|
+
(combinedHash << 7) +
|
|
300
|
+
(combinedHash << 8) +
|
|
301
|
+
(combinedHash << 24);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return `volume-${(combinedHash >>> 0).toString(36)}`;
|
|
305
|
+
}
|
|
306
|
+
getImageIdsForVolumeId(volumeId) {
|
|
307
|
+
return Array.from(this._imageIdsToVolumeIdCache.entries())
|
|
308
|
+
.filter(([_, id]) => id === volumeId)
|
|
309
|
+
.map(([key]) => key);
|
|
310
|
+
}
|
|
287
311
|
getBytesAvailable() {
|
|
288
312
|
return this.getMaxCacheSize() - this.getCacheSize();
|
|
289
313
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { vec3 } from 'gl-matrix';
|
|
2
1
|
import cache from '../cache/cache';
|
|
3
2
|
import RLEVoxelMap from './RLEVoxelMap';
|
|
4
3
|
import isEqual from './isEqual';
|
|
@@ -521,7 +520,15 @@ export default class VoxelManager {
|
|
|
521
520
|
const sliceEnd = sliceStart + sliceSize;
|
|
522
521
|
const sliceData = new SliceDataConstructor(sliceSize);
|
|
523
522
|
sliceData.set(scalarData.subarray(sliceStart, sliceEnd));
|
|
524
|
-
imageVoxelManager.scalarData
|
|
523
|
+
if (imageVoxelManager.scalarData) {
|
|
524
|
+
imageVoxelManager.scalarData.set(sliceData);
|
|
525
|
+
imageVoxelManager.modifiedSlices.add(sliceIndex);
|
|
526
|
+
}
|
|
527
|
+
else {
|
|
528
|
+
for (let i = 0; i < sliceSize; i++) {
|
|
529
|
+
imageVoxelManager.setAtIndex(i, sliceData[i]);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
525
532
|
for (let i = 0; i < sliceData.length; i++) {
|
|
526
533
|
const value = sliceData[i];
|
|
527
534
|
minValue = Math.min(minValue, value);
|
|
@@ -546,7 +553,7 @@ export default class VoxelManager {
|
|
|
546
553
|
};
|
|
547
554
|
return voxelManager;
|
|
548
555
|
}
|
|
549
|
-
static createScalarVolumeVoxelManager({ dimensions, scalarData, numberOfComponents
|
|
556
|
+
static createScalarVolumeVoxelManager({ dimensions, scalarData, numberOfComponents, }) {
|
|
550
557
|
if (dimensions.length !== 3) {
|
|
551
558
|
throw new Error('Dimensions must be provided as [number, number, number] for [width, height, depth]');
|
|
552
559
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function calculateSpacingBetweenImageIds(imageIds: string[]): number;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { vec3 } from 'gl-matrix';
|
|
2
|
+
import * as metaData from '../metaData';
|
|
3
|
+
import { getConfiguration } from '../init';
|
|
4
|
+
export default function calculateSpacingBetweenImageIds(imageIds) {
|
|
5
|
+
const { imagePositionPatient: referenceImagePositionPatient, imageOrientationPatient, } = metaData.get('imagePlaneModule', imageIds[0]);
|
|
6
|
+
const rowCosineVec = vec3.fromValues(imageOrientationPatient[0], imageOrientationPatient[1], imageOrientationPatient[2]);
|
|
7
|
+
const colCosineVec = vec3.fromValues(imageOrientationPatient[3], imageOrientationPatient[4], imageOrientationPatient[5]);
|
|
8
|
+
const scanAxisNormal = vec3.create();
|
|
9
|
+
vec3.cross(scanAxisNormal, rowCosineVec, colCosineVec);
|
|
10
|
+
const refIppVec = vec3.fromValues(referenceImagePositionPatient[0], referenceImagePositionPatient[1], referenceImagePositionPatient[2]);
|
|
11
|
+
const usingWadoUri = imageIds[0].split(':')[0] === 'wadouri';
|
|
12
|
+
let spacing;
|
|
13
|
+
function getDistance(imageId) {
|
|
14
|
+
const { imagePositionPatient } = metaData.get('imagePlaneModule', imageId);
|
|
15
|
+
const positionVector = vec3.create();
|
|
16
|
+
const ippVec = vec3.fromValues(imagePositionPatient[0], imagePositionPatient[1], imagePositionPatient[2]);
|
|
17
|
+
vec3.sub(positionVector, refIppVec, ippVec);
|
|
18
|
+
return vec3.dot(positionVector, scanAxisNormal);
|
|
19
|
+
}
|
|
20
|
+
if (!usingWadoUri) {
|
|
21
|
+
const distanceImagePairs = imageIds.map((imageId) => {
|
|
22
|
+
const distance = getDistance(imageId);
|
|
23
|
+
return {
|
|
24
|
+
distance,
|
|
25
|
+
imageId,
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
distanceImagePairs.sort((a, b) => b.distance - a.distance);
|
|
29
|
+
const numImages = distanceImagePairs.length;
|
|
30
|
+
spacing =
|
|
31
|
+
Math.abs(distanceImagePairs[numImages - 1].distance -
|
|
32
|
+
distanceImagePairs[0].distance) /
|
|
33
|
+
(numImages - 1);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const prefetchedImageIds = [
|
|
37
|
+
imageIds[0],
|
|
38
|
+
imageIds[Math.floor(imageIds.length / 2)],
|
|
39
|
+
];
|
|
40
|
+
const firstImageDistance = getDistance(prefetchedImageIds[0]);
|
|
41
|
+
const middleImageDistance = getDistance(prefetchedImageIds[1]);
|
|
42
|
+
const metadataForMiddleImage = metaData.get('imagePlaneModule', prefetchedImageIds[1]);
|
|
43
|
+
if (!metadataForMiddleImage) {
|
|
44
|
+
throw new Error('Incomplete metadata required for volume construction.');
|
|
45
|
+
}
|
|
46
|
+
const positionVector = vec3.create();
|
|
47
|
+
const middleIppVec = vec3.fromValues(metadataForMiddleImage.imagePositionPatient[0], metadataForMiddleImage.imagePositionPatient[1], metadataForMiddleImage.imagePositionPatient[2]);
|
|
48
|
+
vec3.sub(positionVector, refIppVec, middleIppVec);
|
|
49
|
+
const distanceBetweenFirstAndMiddleImages = vec3.dot(positionVector, scanAxisNormal);
|
|
50
|
+
spacing =
|
|
51
|
+
Math.abs(distanceBetweenFirstAndMiddleImages) /
|
|
52
|
+
Math.floor(imageIds.length / 2);
|
|
53
|
+
}
|
|
54
|
+
const { sliceThickness, spacingBetweenSlices } = metaData.get('imagePlaneModule', imageIds[0]);
|
|
55
|
+
const { strictZSpacingForVolumeViewport } = getConfiguration().rendering;
|
|
56
|
+
if (spacing === 0 && !strictZSpacingForVolumeViewport) {
|
|
57
|
+
if (spacingBetweenSlices) {
|
|
58
|
+
console.debug('Could not calculate spacing. Using spacingBetweenSlices');
|
|
59
|
+
spacing = spacingBetweenSlices;
|
|
60
|
+
}
|
|
61
|
+
else if (sliceThickness) {
|
|
62
|
+
console.debug('Could not calculate spacing and no spacingBetweenSlices. Using sliceThickness');
|
|
63
|
+
spacing = sliceThickness;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.debug('Could not calculate spacing. The VolumeViewport visualization is compromised. Setting spacing to 1 to render');
|
|
67
|
+
spacing = 1;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return spacing;
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function fnv1aHash(str: string): string;
|
|
@@ -77,6 +77,7 @@ import * as color from './color';
|
|
|
77
77
|
import { deepEqual } from './deepEqual';
|
|
78
78
|
import type { IViewport } from '../types/IViewport';
|
|
79
79
|
import FrameRange from './FrameRange';
|
|
80
|
+
import fnv1aHash from './fnv1aHash';
|
|
80
81
|
import getDynamicVolumeInfo from './getDynamicVolumeInfo';
|
|
81
82
|
import autoLoad from './autoLoad';
|
|
82
83
|
import scaleArray from './scaleArray';
|
|
@@ -87,5 +88,6 @@ import scroll from './scroll';
|
|
|
87
88
|
import clip from './clip';
|
|
88
89
|
import createSubVolume from './createSubVolume';
|
|
89
90
|
import getVolumeDirectionVectors from './getVolumeDirectionVectors';
|
|
91
|
+
import calculateSpacingBetweenImageIds from './calculateSpacingBetweenImageIds';
|
|
90
92
|
declare const getViewportModality: (viewport: IViewport, volumeId?: string) => string;
|
|
91
|
-
export { FrameRange, eventListener, csUtils as invertRgbTransferFunction, createSigmoidRGBTransferFunction, getVoiFromSigmoidRGBTransferFunction, createLinearRGBTransferFunction, scaleRgbTransferFunction, triggerEvent, imageIdToURI, calibratedPixelSpacingMetadataProvider, clamp, uuidv4, planar, getMinMax, getRuntimeId, isEqual, isEqualAbs, isEqualNegative, isOpposite, getViewportModality, windowLevel, convertToGrayscale, getClosestImageId, getSpacingInNormalDirection, getTargetVolumeAndSpacingInNormalDir, getVolumeActorCorners, indexWithinDimensions, getVolumeViewportsContainingSameVolumes, getViewportsWithVolumeId, transformWorldToIndex, transformIndexToWorld, loadImageToCanvas, renderToCanvasCPU, renderToCanvasGPU, worldToImageCoords, imageToWorldCoords, getVolumeSliceRangeInfo, getVolumeViewportScrollInfo, getSliceRange, snapFocalPointToSlice, getImageSliceDataForVolumeViewport, isImageActor, isPTPrescaledWithSUV, actorIsA, getViewportsWithImageURI, getClosestStackImageIndexForPoint, getCurrentVolumeViewportSlice, calculateViewportsSpatialRegistration, spatialRegistrationMetadataProvider, getViewportImageCornersInWorld, hasNaNValues, applyPreset, deepMerge, PointsManager, getScalingParameters, colormap, getImageLegacy, ProgressiveIterator, decimate, imageRetrieveMetadataProvider, transferFunctionUtils, updateVTKImageDataWithCornerstoneImage, sortImageIdsAndGetSpacing, makeVolumeMetadata, isValidVolume, genericMetadataProvider, isVideoTransferSyntax, HistoryMemo, generateVolumePropsFromImageIds, getBufferConfiguration, VoxelManager, RLEVoxelMap, convertStackToVolumeViewport, convertVolumeToStackViewport, roundNumber, roundToPrecision, getViewportImageIds, getRandomSampleFromArray, getVolumeId, color, hasFloatScalingParameters, getDynamicVolumeInfo, autoLoad, scaleArray, deepClone, splitImageIdsBy4DTags, pointInShapeCallback, deepEqual, jumpToSlice, scroll, clip, transformWorldToIndexContinuous, createSubVolume, getVolumeDirectionVectors, };
|
|
93
|
+
export { FrameRange, eventListener, csUtils as invertRgbTransferFunction, createSigmoidRGBTransferFunction, getVoiFromSigmoidRGBTransferFunction, createLinearRGBTransferFunction, scaleRgbTransferFunction, triggerEvent, imageIdToURI, fnv1aHash, calibratedPixelSpacingMetadataProvider, clamp, uuidv4, planar, getMinMax, getRuntimeId, isEqual, isEqualAbs, isEqualNegative, isOpposite, getViewportModality, windowLevel, convertToGrayscale, getClosestImageId, getSpacingInNormalDirection, getTargetVolumeAndSpacingInNormalDir, getVolumeActorCorners, indexWithinDimensions, getVolumeViewportsContainingSameVolumes, getViewportsWithVolumeId, transformWorldToIndex, transformIndexToWorld, loadImageToCanvas, renderToCanvasCPU, renderToCanvasGPU, worldToImageCoords, imageToWorldCoords, getVolumeSliceRangeInfo, getVolumeViewportScrollInfo, getSliceRange, snapFocalPointToSlice, getImageSliceDataForVolumeViewport, isImageActor, isPTPrescaledWithSUV, actorIsA, getViewportsWithImageURI, getClosestStackImageIndexForPoint, getCurrentVolumeViewportSlice, calculateViewportsSpatialRegistration, spatialRegistrationMetadataProvider, getViewportImageCornersInWorld, hasNaNValues, applyPreset, deepMerge, PointsManager, getScalingParameters, colormap, getImageLegacy, ProgressiveIterator, decimate, imageRetrieveMetadataProvider, transferFunctionUtils, updateVTKImageDataWithCornerstoneImage, sortImageIdsAndGetSpacing, makeVolumeMetadata, isValidVolume, genericMetadataProvider, isVideoTransferSyntax, HistoryMemo, generateVolumePropsFromImageIds, getBufferConfiguration, VoxelManager, RLEVoxelMap, convertStackToVolumeViewport, convertVolumeToStackViewport, roundNumber, roundToPrecision, getViewportImageIds, getRandomSampleFromArray, getVolumeId, color, hasFloatScalingParameters, getDynamicVolumeInfo, autoLoad, scaleArray, deepClone, splitImageIdsBy4DTags, pointInShapeCallback, deepEqual, jumpToSlice, scroll, clip, transformWorldToIndexContinuous, createSubVolume, getVolumeDirectionVectors, calculateSpacingBetweenImageIds, };
|
|
@@ -76,6 +76,7 @@ import * as transferFunctionUtils from './transferFunctionUtils';
|
|
|
76
76
|
import * as color from './color';
|
|
77
77
|
import { deepEqual } from './deepEqual';
|
|
78
78
|
import FrameRange from './FrameRange';
|
|
79
|
+
import fnv1aHash from './fnv1aHash';
|
|
79
80
|
import { _getViewportModality } from './getViewportModality';
|
|
80
81
|
import cache from '../cache/cache';
|
|
81
82
|
import getDynamicVolumeInfo from './getDynamicVolumeInfo';
|
|
@@ -88,5 +89,6 @@ import scroll from './scroll';
|
|
|
88
89
|
import clip from './clip';
|
|
89
90
|
import createSubVolume from './createSubVolume';
|
|
90
91
|
import getVolumeDirectionVectors from './getVolumeDirectionVectors';
|
|
92
|
+
import calculateSpacingBetweenImageIds from './calculateSpacingBetweenImageIds';
|
|
91
93
|
const getViewportModality = (viewport, volumeId) => _getViewportModality(viewport, volumeId, cache.getVolume);
|
|
92
|
-
export { FrameRange, eventListener, csUtils as invertRgbTransferFunction, createSigmoidRGBTransferFunction, getVoiFromSigmoidRGBTransferFunction, createLinearRGBTransferFunction, scaleRgbTransferFunction, triggerEvent, imageIdToURI, calibratedPixelSpacingMetadataProvider, clamp, uuidv4, planar, getMinMax, getRuntimeId, isEqual, isEqualAbs, isEqualNegative, isOpposite, getViewportModality, windowLevel, convertToGrayscale, getClosestImageId, getSpacingInNormalDirection, getTargetVolumeAndSpacingInNormalDir, getVolumeActorCorners, indexWithinDimensions, getVolumeViewportsContainingSameVolumes, getViewportsWithVolumeId, transformWorldToIndex, transformIndexToWorld, loadImageToCanvas, renderToCanvasCPU, renderToCanvasGPU, worldToImageCoords, imageToWorldCoords, getVolumeSliceRangeInfo, getVolumeViewportScrollInfo, getSliceRange, snapFocalPointToSlice, getImageSliceDataForVolumeViewport, isImageActor, isPTPrescaledWithSUV, actorIsA, getViewportsWithImageURI, getClosestStackImageIndexForPoint, getCurrentVolumeViewportSlice, calculateViewportsSpatialRegistration, spatialRegistrationMetadataProvider, getViewportImageCornersInWorld, hasNaNValues, applyPreset, deepMerge, PointsManager, getScalingParameters, colormap, getImageLegacy, ProgressiveIterator, decimate, imageRetrieveMetadataProvider, transferFunctionUtils, updateVTKImageDataWithCornerstoneImage, sortImageIdsAndGetSpacing, makeVolumeMetadata, isValidVolume, genericMetadataProvider, isVideoTransferSyntax, HistoryMemo, generateVolumePropsFromImageIds, getBufferConfiguration, VoxelManager, RLEVoxelMap, convertStackToVolumeViewport, convertVolumeToStackViewport, roundNumber, roundToPrecision, getViewportImageIds, getRandomSampleFromArray, getVolumeId, color, hasFloatScalingParameters, getDynamicVolumeInfo, autoLoad, scaleArray, deepClone, splitImageIdsBy4DTags, pointInShapeCallback, deepEqual, jumpToSlice, scroll, clip, transformWorldToIndexContinuous, createSubVolume, getVolumeDirectionVectors, };
|
|
94
|
+
export { FrameRange, eventListener, csUtils as invertRgbTransferFunction, createSigmoidRGBTransferFunction, getVoiFromSigmoidRGBTransferFunction, createLinearRGBTransferFunction, scaleRgbTransferFunction, triggerEvent, imageIdToURI, fnv1aHash, calibratedPixelSpacingMetadataProvider, clamp, uuidv4, planar, getMinMax, getRuntimeId, isEqual, isEqualAbs, isEqualNegative, isOpposite, getViewportModality, windowLevel, convertToGrayscale, getClosestImageId, getSpacingInNormalDirection, getTargetVolumeAndSpacingInNormalDir, getVolumeActorCorners, indexWithinDimensions, getVolumeViewportsContainingSameVolumes, getViewportsWithVolumeId, transformWorldToIndex, transformIndexToWorld, loadImageToCanvas, renderToCanvasCPU, renderToCanvasGPU, worldToImageCoords, imageToWorldCoords, getVolumeSliceRangeInfo, getVolumeViewportScrollInfo, getSliceRange, snapFocalPointToSlice, getImageSliceDataForVolumeViewport, isImageActor, isPTPrescaledWithSUV, actorIsA, getViewportsWithImageURI, getClosestStackImageIndexForPoint, getCurrentVolumeViewportSlice, calculateViewportsSpatialRegistration, spatialRegistrationMetadataProvider, getViewportImageCornersInWorld, hasNaNValues, applyPreset, deepMerge, PointsManager, getScalingParameters, colormap, getImageLegacy, ProgressiveIterator, decimate, imageRetrieveMetadataProvider, transferFunctionUtils, updateVTKImageDataWithCornerstoneImage, sortImageIdsAndGetSpacing, makeVolumeMetadata, isValidVolume, genericMetadataProvider, isVideoTransferSyntax, HistoryMemo, generateVolumePropsFromImageIds, getBufferConfiguration, VoxelManager, RLEVoxelMap, convertStackToVolumeViewport, convertVolumeToStackViewport, roundNumber, roundToPrecision, getViewportImageIds, getRandomSampleFromArray, getVolumeId, color, hasFloatScalingParameters, getDynamicVolumeInfo, autoLoad, scaleArray, deepClone, splitImageIdsBy4DTags, pointInShapeCallback, deepEqual, jumpToSlice, scroll, clip, transformWorldToIndexContinuous, createSubVolume, getVolumeDirectionVectors, calculateSpacingBetweenImageIds, };
|
|
@@ -6,10 +6,16 @@ export function pointInShapeCallback(imageData, options) {
|
|
|
6
6
|
scalarData = imageData.getScalarData();
|
|
7
7
|
}
|
|
8
8
|
else {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
.
|
|
12
|
-
|
|
9
|
+
const scalars = imageData.getPointData().getScalars();
|
|
10
|
+
if (scalars) {
|
|
11
|
+
scalarData = scalars.getData();
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
const { voxelManager } = imageData.get('voxelManager') || {};
|
|
15
|
+
if (voxelManager) {
|
|
16
|
+
scalarData = voxelManager.getCompleteScalarDataArray();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
13
19
|
}
|
|
14
20
|
const dimensions = imageData.getDimensions();
|
|
15
21
|
const defaultBoundsIJK = [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { vec3 } from 'gl-matrix';
|
|
2
2
|
import * as metaData from '../metaData';
|
|
3
|
-
import
|
|
3
|
+
import calculateSpacingBetweenImageIds from './calculateSpacingBetweenImageIds';
|
|
4
4
|
export default function sortImageIdsAndGetSpacing(imageIds, scanAxisNormal) {
|
|
5
5
|
const { imagePositionPatient: referenceImagePositionPatient, imageOrientationPatient, } = metaData.get('imagePlaneModule', imageIds[0]);
|
|
6
6
|
if (!scanAxisNormal) {
|
|
@@ -9,11 +9,9 @@ export default function sortImageIdsAndGetSpacing(imageIds, scanAxisNormal) {
|
|
|
9
9
|
scanAxisNormal = vec3.create();
|
|
10
10
|
vec3.cross(scanAxisNormal, rowCosineVec, colCosineVec);
|
|
11
11
|
}
|
|
12
|
-
const refIppVec = vec3.create();
|
|
13
12
|
const usingWadoUri = imageIds[0].split(':')[0] === 'wadouri';
|
|
14
|
-
|
|
13
|
+
const zSpacing = calculateSpacingBetweenImageIds(imageIds);
|
|
15
14
|
let sortedImageIds;
|
|
16
|
-
let zSpacing;
|
|
17
15
|
function getDistance(imageId) {
|
|
18
16
|
const { imagePositionPatient } = metaData.get('imagePlaneModule', imageId);
|
|
19
17
|
const positionVector = vec3.create();
|
|
@@ -30,11 +28,6 @@ export default function sortImageIdsAndGetSpacing(imageIds, scanAxisNormal) {
|
|
|
30
28
|
});
|
|
31
29
|
distanceImagePairs.sort((a, b) => b.distance - a.distance);
|
|
32
30
|
sortedImageIds = distanceImagePairs.map((a) => a.imageId);
|
|
33
|
-
const numImages = distanceImagePairs.length;
|
|
34
|
-
zSpacing =
|
|
35
|
-
Math.abs(distanceImagePairs[numImages - 1].distance -
|
|
36
|
-
distanceImagePairs[0].distance) /
|
|
37
|
-
(numImages - 1);
|
|
38
31
|
}
|
|
39
32
|
else {
|
|
40
33
|
const prefetchedImageIds = [
|
|
@@ -47,33 +40,8 @@ export default function sortImageIdsAndGetSpacing(imageIds, scanAxisNormal) {
|
|
|
47
40
|
if (firstImageDistance - middleImageDistance < 0) {
|
|
48
41
|
sortedImageIds.reverse();
|
|
49
42
|
}
|
|
50
|
-
const metadataForMiddleImage = metaData.get('imagePlaneModule', prefetchedImageIds[1]);
|
|
51
|
-
if (!metadataForMiddleImage) {
|
|
52
|
-
throw new Error('Incomplete metadata required for volume construction.');
|
|
53
|
-
}
|
|
54
|
-
const positionVector = vec3.create();
|
|
55
|
-
vec3.sub(positionVector, referenceImagePositionPatient, metadataForMiddleImage.imagePositionPatient);
|
|
56
|
-
const distanceBetweenFirstAndMiddleImages = vec3.dot(positionVector, scanAxisNormal);
|
|
57
|
-
zSpacing =
|
|
58
|
-
Math.abs(distanceBetweenFirstAndMiddleImages) /
|
|
59
|
-
Math.floor(imageIds.length / 2);
|
|
60
|
-
}
|
|
61
|
-
const { imagePositionPatient: origin, sliceThickness, spacingBetweenSlices, } = metaData.get('imagePlaneModule', sortedImageIds[0]);
|
|
62
|
-
const { strictZSpacingForVolumeViewport } = getConfiguration().rendering;
|
|
63
|
-
if (zSpacing === 0 && !strictZSpacingForVolumeViewport) {
|
|
64
|
-
if (spacingBetweenSlices) {
|
|
65
|
-
console.log('Could not calculate zSpacing. Using spacingBetweenSlices');
|
|
66
|
-
zSpacing = spacingBetweenSlices;
|
|
67
|
-
}
|
|
68
|
-
else if (sliceThickness) {
|
|
69
|
-
console.log('Could not calculate zSpacing and no spacingBetweenSlices. Using sliceThickness');
|
|
70
|
-
zSpacing = sliceThickness;
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
console.log('Could not calculate zSpacing. The VolumeViewport visualization is compromised. Setting zSpacing to 1 to render');
|
|
74
|
-
zSpacing = 1;
|
|
75
|
-
}
|
|
76
43
|
}
|
|
44
|
+
const { imagePositionPatient: origin } = metaData.get('imagePlaneModule', sortedImageIds[0]);
|
|
77
45
|
const result = {
|
|
78
46
|
zSpacing,
|
|
79
47
|
origin,
|
|
@@ -27,6 +27,7 @@ class CentralizedWorkerManager {
|
|
|
27
27
|
autoTerminateOnIdle: autoTerminateOnIdle.enabled,
|
|
28
28
|
idleCheckIntervalId: null,
|
|
29
29
|
idleTimeThreshold: autoTerminateOnIdle.idleTimeThreshold,
|
|
30
|
+
options: options,
|
|
30
31
|
};
|
|
31
32
|
workerProperties.loadCounters = Array(maxWorkerInstances).fill(0);
|
|
32
33
|
workerProperties.lastActiveTime = Array(maxWorkerInstances).fill(null);
|
|
@@ -84,6 +85,7 @@ class CentralizedWorkerManager {
|
|
|
84
85
|
}
|
|
85
86
|
const workerProperties = this.workerRegistry[workerName];
|
|
86
87
|
workerProperties.processing = true;
|
|
88
|
+
args = { ...args, ...workerProperties.options };
|
|
87
89
|
const results = await api[methodName](args, ...finalCallbacks);
|
|
88
90
|
workerProperties.processing = false;
|
|
89
91
|
workerProperties.lastActiveTime[index] = Date.now();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/core",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.3",
|
|
4
4
|
"description": "Cornerstone3D Core",
|
|
5
5
|
"module": "./dist/esm/index.js",
|
|
6
6
|
"types": "./dist/esm/index.d.ts",
|
|
@@ -82,5 +82,5 @@
|
|
|
82
82
|
"type": "individual",
|
|
83
83
|
"url": "https://ohif.org/donate"
|
|
84
84
|
},
|
|
85
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "d2b29db96b3ecf98c9e9f0591978423dc9f6cb3f"
|
|
86
86
|
}
|