@cornerstonejs/core 2.0.0-beta.21 → 2.0.0-beta.23

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 (74) hide show
  1. package/dist/esm/RenderingEngine/BaseVolumeViewport.d.ts +1 -1
  2. package/dist/esm/RenderingEngine/BaseVolumeViewport.js +16 -6
  3. package/dist/esm/RenderingEngine/RenderingEngine.d.ts +1 -2
  4. package/dist/esm/RenderingEngine/RenderingEngine.js +2 -1
  5. package/dist/esm/RenderingEngine/StackViewport.d.ts +1 -3
  6. package/dist/esm/RenderingEngine/StackViewport.js +15 -8
  7. package/dist/esm/RenderingEngine/VideoViewport.js +2 -2
  8. package/dist/esm/RenderingEngine/Viewport.js +4 -1
  9. package/dist/esm/RenderingEngine/VolumeViewport.d.ts +1 -1
  10. package/dist/esm/RenderingEngine/VolumeViewport.js +8 -3
  11. package/dist/esm/RenderingEngine/WSIViewport.js +1 -1
  12. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/renderPseudoColorImage.js +1 -1
  13. package/dist/esm/RenderingEngine/helpers/createVolumeActor.js +1 -1
  14. package/dist/esm/RenderingEngine/helpers/setDefaultVolumeVOI.js +3 -2
  15. package/dist/esm/RenderingEngine/helpers/volumeNewImageEventDispatcher.js +4 -4
  16. package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLTexture.js +1 -1
  17. package/dist/esm/cache/cache.js +2 -1
  18. package/dist/esm/cache/classes/BaseStreamingImageVolume.d.ts +85 -0
  19. package/dist/esm/cache/classes/BaseStreamingImageVolume.js +339 -0
  20. package/dist/esm/cache/classes/ImageVolume.js +2 -1
  21. package/dist/esm/cache/classes/StreamingDynamicImageVolume.d.ts +52 -0
  22. package/dist/esm/cache/classes/StreamingDynamicImageVolume.js +81 -0
  23. package/dist/esm/cache/classes/StreamingImageVolume.d.ts +8 -0
  24. package/dist/esm/cache/classes/StreamingImageVolume.js +21 -0
  25. package/dist/esm/cache/index.d.ts +4 -3
  26. package/dist/esm/cache/index.js +4 -3
  27. package/dist/esm/enums/Events.d.ts +2 -1
  28. package/dist/esm/enums/Events.js +1 -0
  29. package/dist/esm/index.d.ts +8 -3
  30. package/dist/esm/index.js +8 -3
  31. package/dist/esm/init.js +1 -1
  32. package/dist/esm/loaders/ProgressiveRetrieveImages.js +4 -2
  33. package/dist/esm/loaders/cornerstoneStreamingDynamicImageVolumeLoader.d.ts +10 -0
  34. package/dist/esm/loaders/cornerstoneStreamingDynamicImageVolumeLoader.js +58 -0
  35. package/dist/esm/loaders/cornerstoneStreamingImageVolumeLoader.d.ts +12 -0
  36. package/dist/esm/loaders/cornerstoneStreamingImageVolumeLoader.js +73 -0
  37. package/dist/esm/loaders/geometryLoader.js +1 -1
  38. package/dist/esm/loaders/imageLoader.js +6 -2
  39. package/dist/esm/loaders/volumeLoader.d.ts +1 -0
  40. package/dist/esm/loaders/volumeLoader.js +34 -5
  41. package/dist/esm/requestPool/requestPoolManager.js +1 -1
  42. package/dist/esm/types/CPUFallbackEnabledElement.d.ts +1 -39
  43. package/dist/esm/types/IImage.d.ts +37 -2
  44. package/dist/esm/types/ImageLoadRequests.d.ts +24 -0
  45. package/dist/esm/types/ImageLoadRequests.js +1 -0
  46. package/dist/esm/types/index.d.ts +3 -2
  47. package/dist/esm/utilities/VoxelManager.js +1 -1
  48. package/dist/esm/utilities/autoLoad.d.ts +2 -0
  49. package/dist/esm/utilities/autoLoad.js +28 -0
  50. package/dist/esm/utilities/calculateViewportsSpatialRegistration.js +3 -3
  51. package/dist/esm/utilities/convertVolumeToStackViewport.js +2 -1
  52. package/dist/esm/utilities/getClosestStackImageIndexForPoint.js +2 -2
  53. package/dist/esm/utilities/getDynamicVolumeInfo.d.ts +6 -0
  54. package/dist/esm/utilities/getDynamicVolumeInfo.js +7 -0
  55. package/dist/esm/utilities/getImageLegacy.js +1 -1
  56. package/dist/esm/utilities/getScalingParameters.js +4 -4
  57. package/dist/esm/utilities/getViewportImageIds.js +1 -1
  58. package/dist/esm/utilities/imageToWorldCoords.js +2 -2
  59. package/dist/esm/utilities/index.d.ts +5 -1
  60. package/dist/esm/utilities/index.js +6 -2
  61. package/dist/esm/utilities/isValidVolume.js +1 -1
  62. package/dist/esm/utilities/loadImageToCanvas.js +1 -1
  63. package/dist/esm/utilities/makeVolumeMetadata.js +5 -5
  64. package/dist/esm/utilities/scaleArray.d.ts +2 -0
  65. package/dist/esm/utilities/scaleArray.js +15 -0
  66. package/dist/esm/utilities/sortImageIdsAndGetSpacing.js +2 -1
  67. package/dist/esm/utilities/splitImageIdsBy4DTags.d.ts +5 -0
  68. package/dist/esm/utilities/splitImageIdsBy4DTags.js +161 -0
  69. package/dist/esm/utilities/worldToImageCoords.js +2 -2
  70. package/dist/umd/index.js +1 -1
  71. package/dist/umd/index.js.map +1 -1
  72. package/package.json +3 -2
  73. package/dist/esm/utilities/isTypedArray.d.ts +0 -1
  74. package/dist/esm/utilities/isTypedArray.js +0 -11
@@ -0,0 +1,339 @@
1
+ import * as metaData from '../../metaData';
2
+ import { Events, ImageQualityStatus, RequestType } from '../../enums';
3
+ import eventTarget from '../../eventTarget';
4
+ import imageLoadPoolManager from '../../requestPool/imageLoadPoolManager';
5
+ import { ProgressiveIterator, imageRetrieveMetadataProvider, hasFloatScalingParameters, autoLoad, triggerEvent, } from '../../utilities';
6
+ import ImageVolume from './ImageVolume';
7
+ import ProgressiveRetrieveImages from '../../loaders/ProgressiveRetrieveImages';
8
+ import { canRenderFloatTextures } from '../../init';
9
+ import { loadAndCacheImage } from '../../loaders/imageLoader';
10
+ import StreamingImageVolume from './StreamingImageVolume';
11
+ const requestTypeDefault = RequestType.Prefetch;
12
+ export default class BaseStreamingImageVolume extends ImageVolume {
13
+ constructor(imageVolumeProperties, streamingProperties) {
14
+ super(imageVolumeProperties);
15
+ this.framesLoaded = 0;
16
+ this.framesProcessed = 0;
17
+ this.framesUpdated = 0;
18
+ this.autoRenderOnLoad = true;
19
+ this.cachedFrames = [];
20
+ this.reRenderTarget = 0;
21
+ this.reRenderFraction = 2;
22
+ this.imagesLoader = this;
23
+ this.cancelLoading = () => {
24
+ const { loadStatus } = this;
25
+ if (!loadStatus || !loadStatus.loading) {
26
+ return;
27
+ }
28
+ loadStatus.loading = false;
29
+ loadStatus.cancelled = true;
30
+ this.clearLoadCallbacks();
31
+ const filterFunction = ({ additionalDetails }) => {
32
+ return additionalDetails.volumeId !== this.volumeId;
33
+ };
34
+ imageLoadPoolManager.filterRequests(filterFunction);
35
+ };
36
+ this.load = (callback) => {
37
+ const { imageIds, loadStatus, numFrames } = this;
38
+ const { transferSyntaxUID } = metaData.get('transferSyntax', imageIds[0]) || {};
39
+ const imageRetrieveConfiguration = metaData.get(imageRetrieveMetadataProvider.IMAGE_RETRIEVE_CONFIGURATION, this.volumeId, transferSyntaxUID, 'volume');
40
+ this.imagesLoader = imageRetrieveConfiguration
41
+ ? (imageRetrieveConfiguration.create ||
42
+ ProgressiveRetrieveImages.createProgressive)(imageRetrieveConfiguration)
43
+ : this;
44
+ if (loadStatus.loading === true) {
45
+ return;
46
+ }
47
+ const { loaded } = this.loadStatus;
48
+ const totalNumFrames = imageIds.length;
49
+ if (loaded) {
50
+ if (callback) {
51
+ callback({
52
+ success: true,
53
+ framesLoaded: totalNumFrames,
54
+ framesProcessed: totalNumFrames,
55
+ numFrames,
56
+ totalNumFrames,
57
+ });
58
+ }
59
+ return;
60
+ }
61
+ if (callback) {
62
+ this.loadStatus.callbacks.push(callback);
63
+ }
64
+ this._prefetchImageIds();
65
+ };
66
+ this.loadStatus = streamingProperties.loadStatus;
67
+ }
68
+ invalidateVolume(immediate) {
69
+ const { vtkOpenGLTexture } = this;
70
+ const { numFrames } = this;
71
+ for (let i = 0; i < numFrames; i++) {
72
+ vtkOpenGLTexture.setUpdatedFrame(i);
73
+ }
74
+ this.modified();
75
+ if (immediate) {
76
+ autoLoad(this.volumeId);
77
+ }
78
+ }
79
+ clearLoadCallbacks() {
80
+ this.loadStatus.callbacks = [];
81
+ }
82
+ callLoadStatusCallback(evt) {
83
+ const { framesUpdated, framesProcessed, totalNumFrames } = evt;
84
+ const { volumeId, reRenderFraction, loadStatus, metadata } = this;
85
+ const { FrameOfReferenceUID } = metadata;
86
+ if (this.autoRenderOnLoad) {
87
+ if (framesUpdated > this.reRenderTarget ||
88
+ framesProcessed === totalNumFrames) {
89
+ this.reRenderTarget += reRenderFraction;
90
+ autoLoad(volumeId);
91
+ }
92
+ }
93
+ if (framesProcessed === totalNumFrames) {
94
+ loadStatus.callbacks.forEach((callback) => callback(evt));
95
+ const eventDetail = {
96
+ FrameOfReferenceUID,
97
+ volumeId: volumeId,
98
+ };
99
+ triggerEvent(eventTarget, Events.IMAGE_VOLUME_LOADING_COMPLETED, eventDetail);
100
+ }
101
+ }
102
+ updateTextureAndTriggerEvents(imageIdIndex, imageId, imageQualityStatus = ImageQualityStatus.FULL_RESOLUTION) {
103
+ const frameIndex = this.imageIdIndexToFrameIndex(imageIdIndex);
104
+ const { cachedFrames, numFrames, totalNumFrames } = this;
105
+ const { FrameOfReferenceUID } = this.metadata;
106
+ const currentStatus = cachedFrames[frameIndex];
107
+ if (currentStatus > imageQualityStatus) {
108
+ return;
109
+ }
110
+ if (cachedFrames[frameIndex] === ImageQualityStatus.FULL_RESOLUTION) {
111
+ return;
112
+ }
113
+ const complete = imageQualityStatus === ImageQualityStatus.FULL_RESOLUTION;
114
+ cachedFrames[imageIdIndex] = imageQualityStatus;
115
+ this.framesUpdated++;
116
+ if (complete) {
117
+ this.framesLoaded++;
118
+ this.framesProcessed++;
119
+ }
120
+ const eventDetail = {
121
+ FrameOfReferenceUID,
122
+ volumeId: this.volumeId,
123
+ numberOfFrames: numFrames,
124
+ framesProcessed: this.framesProcessed,
125
+ };
126
+ triggerEvent(eventTarget, Events.IMAGE_VOLUME_MODIFIED, eventDetail);
127
+ if (complete && this.framesProcessed === this.totalNumFrames) {
128
+ this.loadStatus.loaded = true;
129
+ this.loadStatus.loading = false;
130
+ }
131
+ this.callLoadStatusCallback({
132
+ success: true,
133
+ imageIdIndex,
134
+ imageId,
135
+ framesLoaded: this.framesLoaded,
136
+ framesProcessed: this.framesProcessed,
137
+ framesUpdated: this.framesUpdated,
138
+ numFrames,
139
+ totalNumFrames,
140
+ complete,
141
+ imageQualityStatus,
142
+ });
143
+ this.vtkOpenGLTexture.setUpdatedFrame(frameIndex);
144
+ if (this.loadStatus.loaded) {
145
+ this.loadStatus.callbacks = [];
146
+ }
147
+ }
148
+ successCallback(imageId, image) {
149
+ const imageIdIndex = this.getImageIdIndex(imageId);
150
+ const { imageQualityStatus } = image;
151
+ if (this.loadStatus.cancelled) {
152
+ console.warn('volume load cancelled, returning for imageIdIndex: ', imageIdIndex);
153
+ return;
154
+ }
155
+ return this.updateTextureAndTriggerEvents(imageIdIndex, imageId, imageQualityStatus);
156
+ }
157
+ errorCallback(imageId, permanent, error) {
158
+ if (!permanent) {
159
+ return;
160
+ }
161
+ const { totalNumFrames, numFrames } = this;
162
+ const imageIdIndex = this.getImageIdIndex(imageId);
163
+ this.framesProcessed++;
164
+ if (this.framesProcessed === totalNumFrames) {
165
+ this.loadStatus.loaded = true;
166
+ this.loadStatus.loading = false;
167
+ }
168
+ this.callLoadStatusCallback({
169
+ success: false,
170
+ imageId,
171
+ imageIdIndex,
172
+ error,
173
+ framesLoaded: this.framesLoaded,
174
+ framesProcessed: this.framesProcessed,
175
+ framesUpdated: this.framesUpdated,
176
+ numFrames,
177
+ totalNumFrames,
178
+ });
179
+ if (this.loadStatus.loaded) {
180
+ this.loadStatus.callbacks = [];
181
+ }
182
+ const eventDetail = {
183
+ error,
184
+ imageIdIndex,
185
+ imageId,
186
+ };
187
+ triggerEvent(eventTarget, Events.IMAGE_LOAD_ERROR, eventDetail);
188
+ }
189
+ getLoaderImageOptions(imageId) {
190
+ const { transferSyntaxUID: transferSyntaxUID } = metaData.get('transferSyntax', imageId) || {};
191
+ const imagePlaneModule = metaData.get('imagePlaneModule', imageId) || {};
192
+ const { rows, columns } = imagePlaneModule;
193
+ const imageIdIndex = this.getImageIdIndex(imageId);
194
+ const modalityLutModule = metaData.get('modalityLutModule', imageId) || {};
195
+ const generalSeriesModule = metaData.get('generalSeriesModule', imageId) || {};
196
+ const scalingParameters = {
197
+ rescaleSlope: modalityLutModule.rescaleSlope,
198
+ rescaleIntercept: modalityLutModule.rescaleIntercept,
199
+ modality: generalSeriesModule.modality,
200
+ };
201
+ if (scalingParameters.modality === 'PT') {
202
+ const suvFactor = metaData.get('scalingModule', imageId);
203
+ if (suvFactor) {
204
+ this._addScalingToVolume(suvFactor);
205
+ scalingParameters.suvbw = suvFactor.suvbw;
206
+ }
207
+ }
208
+ const floatAfterScale = hasFloatScalingParameters(scalingParameters);
209
+ const allowFloatRendering = canRenderFloatTextures();
210
+ this.isPreScaled = true;
211
+ if (scalingParameters &&
212
+ scalingParameters.rescaleSlope !== undefined &&
213
+ scalingParameters.rescaleIntercept !== undefined) {
214
+ const { rescaleSlope, rescaleIntercept } = scalingParameters;
215
+ this.isPreScaled =
216
+ typeof rescaleSlope === 'number' &&
217
+ typeof rescaleIntercept === 'number';
218
+ }
219
+ if (!allowFloatRendering && floatAfterScale) {
220
+ this.isPreScaled = false;
221
+ }
222
+ const targetBuffer = {
223
+ type: this.dataType,
224
+ rows,
225
+ columns,
226
+ };
227
+ return {
228
+ targetBuffer,
229
+ allowFloatRendering,
230
+ preScale: {
231
+ enabled: this.isPreScaled,
232
+ scalingParameters,
233
+ },
234
+ transferPixelData: true,
235
+ requestType: requestTypeDefault,
236
+ transferSyntaxUID,
237
+ additionalDetails: {
238
+ imageId,
239
+ imageIdIndex,
240
+ volumeId: this.volumeId,
241
+ },
242
+ };
243
+ }
244
+ callLoadImage(imageId, imageIdIndex, options) {
245
+ const { cachedFrames } = this;
246
+ if (cachedFrames[imageIdIndex] === ImageQualityStatus.FULL_RESOLUTION) {
247
+ return;
248
+ }
249
+ const handleImageCacheAdded = (event) => {
250
+ const { image } = event.detail;
251
+ if (image.imageId === imageId) {
252
+ this.vtkOpenGLTexture.setUpdatedFrame(imageIdIndex);
253
+ eventTarget.removeEventListener(Events.IMAGE_CACHE_IMAGE_ADDED, handleImageCacheAdded);
254
+ }
255
+ };
256
+ eventTarget.addEventListener(Events.IMAGE_CACHE_IMAGE_ADDED, handleImageCacheAdded);
257
+ const uncompressedIterator = ProgressiveIterator.as(loadAndCacheImage(imageId, options));
258
+ return uncompressedIterator.forEach((image) => {
259
+ this.successCallback(imageId, image);
260
+ }, this.errorCallback.bind(this, imageIdIndex, imageId));
261
+ }
262
+ getImageIdsRequests(imageIds, priorityDefault) {
263
+ this.totalNumFrames = this.imageIds.length;
264
+ const autoRenderPercentage = 2;
265
+ if (this.autoRenderOnLoad) {
266
+ this.reRenderFraction =
267
+ this.totalNumFrames * (autoRenderPercentage / 100);
268
+ this.reRenderTarget = this.reRenderFraction;
269
+ }
270
+ const requests = imageIds.map((imageId) => {
271
+ const imageIdIndex = this.getImageIdIndex(imageId);
272
+ const requestType = requestTypeDefault;
273
+ const priority = priorityDefault;
274
+ const options = this.getLoaderImageOptions(imageId);
275
+ return {
276
+ callLoadImage: this.callLoadImage.bind(this),
277
+ imageId,
278
+ imageIdIndex,
279
+ options,
280
+ priority,
281
+ requestType,
282
+ additionalDetails: {
283
+ volumeId: this.volumeId,
284
+ },
285
+ };
286
+ });
287
+ return requests;
288
+ }
289
+ getImageLoadRequests(priority) {
290
+ throw new Error('Abstract method');
291
+ }
292
+ getImageIdsToLoad() {
293
+ throw new Error('Abstract method');
294
+ }
295
+ loadImages() {
296
+ this.loadStatus.loading = true;
297
+ const requests = this.getImageLoadRequests(5);
298
+ requests.reverse().forEach((request) => {
299
+ if (!request) {
300
+ return;
301
+ }
302
+ const { callLoadImage, imageId, imageIdIndex, options, priority, requestType, additionalDetails, } = request;
303
+ imageLoadPoolManager.addRequest(callLoadImage.bind(this, imageId, imageIdIndex, options), requestType, additionalDetails, priority);
304
+ });
305
+ return Promise.resolve(true);
306
+ }
307
+ _prefetchImageIds() {
308
+ this.loadStatus.loading = true;
309
+ const imageIds = [...this.getImageIdsToLoad()];
310
+ imageIds.reverse();
311
+ this.totalNumFrames = this.imageIds.length;
312
+ const autoRenderPercentage = 2;
313
+ if (this.autoRenderOnLoad) {
314
+ this.reRenderFraction =
315
+ this.totalNumFrames * (autoRenderPercentage / 100);
316
+ this.reRenderTarget = this.reRenderFraction;
317
+ }
318
+ return this.imagesLoader.loadImages(imageIds, this).catch((e) => {
319
+ console.debug('progressive loading failed to complete', e);
320
+ });
321
+ }
322
+ _addScalingToVolume(suvFactor) {
323
+ if (this.scaling) {
324
+ return;
325
+ }
326
+ const { suvbw, suvlbm, suvbsa } = suvFactor;
327
+ const petScaling = {};
328
+ if (suvlbm) {
329
+ petScaling.suvbwToSuvlbm = suvlbm / suvbw;
330
+ }
331
+ if (suvbsa) {
332
+ petScaling.suvbwToSuvbsa = suvbsa / suvbw;
333
+ }
334
+ if (suvbw) {
335
+ petScaling.suvbw = suvbw;
336
+ }
337
+ this.scaling = { PT: petScaling };
338
+ }
339
+ }
@@ -1,5 +1,6 @@
1
1
  import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
2
- import { imageIdToURI, VoxelManager } from '../../utilities';
2
+ import imageIdToURI from '../../utilities/imageIdToURI';
3
+ import VoxelManager from '../../utilities/VoxelManager';
3
4
  import { vtkStreamingOpenGLTexture } from '../../RenderingEngine/vtkClasses';
4
5
  import cache from '../cache';
5
6
  export class ImageVolume {
@@ -0,0 +1,52 @@
1
+ import type { IDynamicImageVolume, ImageVolumeProps, IStreamingVolumeProperties } from '../../types';
2
+ import BaseStreamingImageVolume from './BaseStreamingImageVolume';
3
+ export default class StreamingDynamicImageVolume extends BaseStreamingImageVolume implements IDynamicImageVolume {
4
+ private _timePointIndex;
5
+ private _splittingTag;
6
+ private _imageIdGroups;
7
+ numTimePoints: number;
8
+ constructor(imageVolumeProperties: ImageVolumeProps & {
9
+ splittingTag: string;
10
+ imageIdGroups: string[][];
11
+ }, streamingProperties: IStreamingVolumeProperties);
12
+ private _getImageIdsToLoad;
13
+ private _getImageIdRequests;
14
+ getImageIdsToLoad(): string[];
15
+ get timePointIndex(): number;
16
+ set timePointIndex(index: number);
17
+ scroll(delta: number): void;
18
+ getCurrentTimePointImageIds(): string[];
19
+ flatImageIdIndexToTimePointIndex(flatImageIdIndex: number): number;
20
+ flatImageIdIndexToImageIdIndex(flatImageIdIndex: number): number;
21
+ get splittingTag(): string;
22
+ getImageLoadRequests: (priority: number) => {
23
+ callLoadImage: (imageId: any, imageIdIndex: any, options: any) => any;
24
+ imageId: string;
25
+ imageIdIndex: number;
26
+ options: {
27
+ targetBuffer: {
28
+ type: import("../../types").PixelDataTypedArrayString;
29
+ rows: any;
30
+ columns: any;
31
+ };
32
+ allowFloatRendering: boolean;
33
+ preScale: {
34
+ enabled: boolean;
35
+ scalingParameters: import("../../types").ScalingParameters;
36
+ };
37
+ transferPixelData: boolean;
38
+ requestType: import("../../enums").RequestType;
39
+ transferSyntaxUID: any;
40
+ additionalDetails: {
41
+ imageId: string;
42
+ imageIdIndex: number;
43
+ volumeId: string;
44
+ };
45
+ };
46
+ priority: number;
47
+ requestType: import("../../enums").RequestType;
48
+ additionalDetails: {
49
+ volumeId: string;
50
+ };
51
+ }[];
52
+ }
@@ -0,0 +1,81 @@
1
+ import { Events } from '../../enums';
2
+ import eventTarget from '../../eventTarget';
3
+ import { triggerEvent } from '../../utilities';
4
+ import BaseStreamingImageVolume from './BaseStreamingImageVolume';
5
+ export default class StreamingDynamicImageVolume extends BaseStreamingImageVolume {
6
+ constructor(imageVolumeProperties, streamingProperties) {
7
+ super(imageVolumeProperties, streamingProperties);
8
+ this._timePointIndex = 0;
9
+ this._getImageIdRequests = (imageIds, priority) => {
10
+ return this.getImageIdsRequests(imageIds, priority);
11
+ };
12
+ this.getImageLoadRequests = (priority) => {
13
+ const imageIds = this.getImageIdsToLoad();
14
+ return this._getImageIdRequests(imageIds, priority);
15
+ };
16
+ const { imageIdGroups, splittingTag } = imageVolumeProperties;
17
+ this._splittingTag = splittingTag;
18
+ this._imageIdGroups = imageIdGroups;
19
+ this.numTimePoints = this._imageIdGroups.length;
20
+ }
21
+ _getImageIdsToLoad() {
22
+ const imageIdGroups = this._imageIdGroups;
23
+ const initialImageIdGroupIndex = this._timePointIndex;
24
+ const imageIds = [...imageIdGroups[initialImageIdGroupIndex]];
25
+ let leftIndex = initialImageIdGroupIndex - 1;
26
+ let rightIndex = initialImageIdGroupIndex + 1;
27
+ while (leftIndex >= 0 || rightIndex < imageIdGroups.length) {
28
+ if (leftIndex >= 0) {
29
+ imageIds.push(...imageIdGroups[leftIndex--]);
30
+ }
31
+ if (rightIndex < imageIdGroups.length) {
32
+ imageIds.push(...imageIdGroups[rightIndex++]);
33
+ }
34
+ }
35
+ return imageIds;
36
+ }
37
+ getImageIdsToLoad() {
38
+ return this._getImageIdsToLoad();
39
+ }
40
+ get timePointIndex() {
41
+ return this._timePointIndex;
42
+ }
43
+ set timePointIndex(index) {
44
+ if (this._timePointIndex === index) {
45
+ return;
46
+ }
47
+ this._timePointIndex = index;
48
+ this.voxelManager.setTimePoint(index);
49
+ this.invalidateVolume(true);
50
+ triggerEvent(eventTarget, Events.DYNAMIC_VOLUME_TIME_POINT_INDEX_CHANGED, {
51
+ volumeId: this.volumeId,
52
+ imageIdGroupIndex: index,
53
+ numImageIdGroups: this.numTimePoints,
54
+ splittingTag: this.splittingTag,
55
+ });
56
+ }
57
+ scroll(delta) {
58
+ const newIndex = this._timePointIndex + delta;
59
+ if (newIndex < 0) {
60
+ this.timePointIndex = this.numTimePoints - 1;
61
+ }
62
+ else if (newIndex >= this.numTimePoints) {
63
+ this.timePointIndex = 0;
64
+ }
65
+ else {
66
+ this.timePointIndex = newIndex;
67
+ }
68
+ }
69
+ getCurrentTimePointImageIds() {
70
+ return this._imageIdGroups[this._timePointIndex];
71
+ }
72
+ flatImageIdIndexToTimePointIndex(flatImageIdIndex) {
73
+ return Math.floor(flatImageIdIndex / this._imageIdGroups[0].length);
74
+ }
75
+ flatImageIdIndexToImageIdIndex(flatImageIdIndex) {
76
+ return flatImageIdIndex % this._imageIdGroups[0].length;
77
+ }
78
+ get splittingTag() {
79
+ return this._splittingTag;
80
+ }
81
+ }
@@ -0,0 +1,8 @@
1
+ import type { ImageLoadRequests, ImageVolumeProps, IStreamingVolumeProperties, PixelDataTypedArray } from '../../types';
2
+ import BaseStreamingImageVolume from './BaseStreamingImageVolume';
3
+ export default class StreamingImageVolume extends BaseStreamingImageVolume {
4
+ constructor(imageVolumeProperties: ImageVolumeProps, streamingProperties: IStreamingVolumeProperties);
5
+ getScalarData(): PixelDataTypedArray;
6
+ getImageLoadRequests(priority: number): ImageLoadRequests[];
7
+ getImageIdsToLoad: () => string[];
8
+ }
@@ -0,0 +1,21 @@
1
+ import BaseStreamingImageVolume from './BaseStreamingImageVolume';
2
+ export default class StreamingImageVolume extends BaseStreamingImageVolume {
3
+ constructor(imageVolumeProperties, streamingProperties) {
4
+ if (!imageVolumeProperties.imageIds) {
5
+ imageVolumeProperties.imageIds = streamingProperties.imageIds;
6
+ }
7
+ super(imageVolumeProperties, streamingProperties);
8
+ this.getImageIdsToLoad = () => {
9
+ const { imageIds } = this;
10
+ this.numFrames = imageIds.length;
11
+ return imageIds;
12
+ };
13
+ }
14
+ getScalarData() {
15
+ return this.voxelManager.getScalarData();
16
+ }
17
+ getImageLoadRequests(priority) {
18
+ const { imageIds } = this;
19
+ return this.getImageIdsRequests(imageIds, priority);
20
+ }
21
+ }
@@ -1,5 +1,6 @@
1
- import cache, { Cache } from './cache';
1
+ import { Cache } from './cache';
2
2
  import ImageVolume from './classes/ImageVolume';
3
3
  import { Surface } from './classes/Surface';
4
- export { ImageVolume, Cache, Surface };
5
- export default cache;
4
+ import StreamingImageVolume from './classes/StreamingImageVolume';
5
+ import StreamingDynamicImageVolume from './classes/StreamingDynamicImageVolume';
6
+ export { ImageVolume, Cache, Surface, StreamingImageVolume, StreamingDynamicImageVolume, };
@@ -1,5 +1,6 @@
1
- import cache, { Cache } from './cache';
1
+ import { Cache } from './cache';
2
2
  import ImageVolume from './classes/ImageVolume';
3
3
  import { Surface } from './classes/Surface';
4
- export { ImageVolume, Cache, Surface };
5
- export default cache;
4
+ import StreamingImageVolume from './classes/StreamingImageVolume';
5
+ import StreamingDynamicImageVolume from './classes/StreamingDynamicImageVolume';
6
+ export { ImageVolume, Cache, Surface, StreamingImageVolume, StreamingDynamicImageVolume, };
@@ -33,6 +33,7 @@ declare enum Events {
33
33
  VOLUME_VIEWPORT_SCROLL = "VOLUME_VIEWPORT_SCROLL",
34
34
  CLIPPING_PLANES_UPDATED = "CORNERSTONE_CLIPPING_PLANES_UPDATED",
35
35
  WEB_WORKER_PROGRESS = "CORNERSTONE_WEB_WORKER_PROGRESS",
36
- COLORMAP_MODIFIED = "CORNERSTONE_COLORMAP_MODIFIED"
36
+ COLORMAP_MODIFIED = "CORNERSTONE_COLORMAP_MODIFIED",
37
+ DYNAMIC_VOLUME_TIME_POINT_INDEX_CHANGED = "DYNAMIC_VOLUME_TIME_POINT_INDEX_CHANGED"
37
38
  }
38
39
  export default Events;
@@ -35,5 +35,6 @@ var Events;
35
35
  Events["CLIPPING_PLANES_UPDATED"] = "CORNERSTONE_CLIPPING_PLANES_UPDATED";
36
36
  Events["WEB_WORKER_PROGRESS"] = "CORNERSTONE_WEB_WORKER_PROGRESS";
37
37
  Events["COLORMAP_MODIFIED"] = "CORNERSTONE_COLORMAP_MODIFIED";
38
+ Events["DYNAMIC_VOLUME_TIME_POINT_INDEX_CHANGED"] = "DYNAMIC_VOLUME_TIME_POINT_INDEX_CHANGED";
38
39
  })(Events || (Events = {}));
39
40
  export default Events;
@@ -1,8 +1,10 @@
1
1
  import * as Enums from './enums';
2
2
  import * as CONSTANTS from './constants';
3
3
  import { Events } from './enums';
4
- import { createVolumeActor, createVolumeMapper, getOrCreateCanvas } from './RenderingEngine';
5
4
  import RenderingEngine from './RenderingEngine';
5
+ import createVolumeActor from './RenderingEngine/helpers/createVolumeActor';
6
+ import createVolumeMapper from './RenderingEngine/helpers/createVolumeMapper';
7
+ import getOrCreateCanvas from './RenderingEngine/helpers/getOrCreateCanvas';
6
8
  import VolumeViewport from './RenderingEngine/VolumeViewport';
7
9
  import VolumeViewport3D from './RenderingEngine/VolumeViewport3D';
8
10
  import BaseVolumeViewport from './RenderingEngine/BaseVolumeViewport';
@@ -12,7 +14,8 @@ import WSIViewport from './RenderingEngine/WSIViewport';
12
14
  import Viewport from './RenderingEngine/Viewport';
13
15
  import eventTarget from './eventTarget';
14
16
  import { getRenderingEngine, getRenderingEngines } from './RenderingEngine/getRenderingEngine';
15
- import cache, { ImageVolume, Surface } from './cache';
17
+ import { ImageVolume, Surface } from './cache';
18
+ import cache from './cache/cache';
16
19
  import imageRetrievalPoolManager from './requestPool/imageRetrievalPoolManager';
17
20
  import imageLoadPoolManager from './requestPool/imageLoadPoolManager';
18
21
  import getEnabledElement, { getEnabledElementByIds, getEnabledElementByViewportId, getEnabledElements } from './getEnabledElement';
@@ -28,6 +31,8 @@ import type { IRetrieveConfiguration, IImagesLoader, RetrieveOptions, RetrieveSt
28
31
  import * as utilities from './utilities';
29
32
  import { registerImageLoader } from './loaders/imageLoader';
30
33
  import triggerEvent from './utilities/triggerEvent';
34
+ import { cornerstoneStreamingImageVolumeLoader } from './loaders/cornerstoneStreamingImageVolumeLoader';
35
+ import { cornerstoneStreamingDynamicImageVolumeLoader } from './loaders/cornerstoneStreamingDynamicImageVolumeLoader';
31
36
  import { setVolumesForViewports, addVolumesToViewports, addImageSlicesToViewports } from './RenderingEngine/helpers';
32
37
  export type { Types, IRetrieveConfiguration, RetrieveOptions, RetrieveStage, ImageLoadListener, IImagesLoader, };
33
- export { init, isCornerstoneInitialized, peerImport, getConfiguration, setConfiguration, getWebWorkerManager, canRenderFloatTextures, Enums, CONSTANTS, Events as EVENTS, Settings, BaseVolumeViewport, VolumeViewport, VolumeViewport3D, Viewport, StackViewport, VideoViewport, WSIViewport, RenderingEngine, ImageVolume, Surface, getRenderingEngine, getRenderingEngines, getEnabledElement, getEnabledElementByIds, getEnabledElements, getEnabledElementByViewportId, createVolumeActor, getOrCreateCanvas, createVolumeMapper, cache, eventTarget, triggerEvent, imageLoader, registerImageLoader, volumeLoader, metaData, utilities, setVolumesForViewports, addVolumesToViewports, addImageSlicesToViewports, imageLoadPoolManager as requestPoolManager, imageRetrievalPoolManager, imageLoadPoolManager, getShouldUseCPURendering, setUseCPURendering, setPreferSizeOverAccuracy, resetUseCPURendering, geometryLoader, ProgressiveRetrieveImages, };
38
+ export { init, isCornerstoneInitialized, peerImport, getConfiguration, setConfiguration, getWebWorkerManager, canRenderFloatTextures, Enums, CONSTANTS, Events as EVENTS, Settings, BaseVolumeViewport, VolumeViewport, VolumeViewport3D, Viewport, StackViewport, VideoViewport, WSIViewport, RenderingEngine, ImageVolume, Surface, getRenderingEngine, getRenderingEngines, getEnabledElement, getEnabledElementByIds, getEnabledElements, getEnabledElementByViewportId, createVolumeActor, getOrCreateCanvas, createVolumeMapper, cache, eventTarget, triggerEvent, imageLoader, registerImageLoader, volumeLoader, metaData, utilities, setVolumesForViewports, addVolumesToViewports, addImageSlicesToViewports, imageLoadPoolManager as requestPoolManager, imageRetrievalPoolManager, imageLoadPoolManager, getShouldUseCPURendering, setUseCPURendering, setPreferSizeOverAccuracy, resetUseCPURendering, geometryLoader, ProgressiveRetrieveImages, cornerstoneStreamingImageVolumeLoader, cornerstoneStreamingDynamicImageVolumeLoader, };
package/dist/esm/index.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import * as Enums from './enums';
2
2
  import * as CONSTANTS from './constants';
3
3
  import { Events } from './enums';
4
- import { createVolumeActor, createVolumeMapper, getOrCreateCanvas, } from './RenderingEngine';
5
4
  import RenderingEngine from './RenderingEngine';
5
+ import createVolumeActor from './RenderingEngine/helpers/createVolumeActor';
6
+ import createVolumeMapper from './RenderingEngine/helpers/createVolumeMapper';
7
+ import getOrCreateCanvas from './RenderingEngine/helpers/getOrCreateCanvas';
6
8
  import VolumeViewport from './RenderingEngine/VolumeViewport';
7
9
  import VolumeViewport3D from './RenderingEngine/VolumeViewport3D';
8
10
  import BaseVolumeViewport from './RenderingEngine/BaseVolumeViewport';
@@ -12,7 +14,8 @@ import WSIViewport from './RenderingEngine/WSIViewport';
12
14
  import Viewport from './RenderingEngine/Viewport';
13
15
  import eventTarget from './eventTarget';
14
16
  import { getRenderingEngine, getRenderingEngines, } from './RenderingEngine/getRenderingEngine';
15
- import cache, { ImageVolume, Surface } from './cache';
17
+ import { ImageVolume, Surface } from './cache';
18
+ import cache from './cache/cache';
16
19
  import imageRetrievalPoolManager from './requestPool/imageRetrievalPoolManager';
17
20
  import imageLoadPoolManager from './requestPool/imageLoadPoolManager';
18
21
  import getEnabledElement, { getEnabledElementByIds, getEnabledElementByViewportId, getEnabledElements, } from './getEnabledElement';
@@ -26,5 +29,7 @@ import ProgressiveRetrieveImages from './loaders/ProgressiveRetrieveImages';
26
29
  import * as utilities from './utilities';
27
30
  import { registerImageLoader } from './loaders/imageLoader';
28
31
  import triggerEvent from './utilities/triggerEvent';
32
+ import { cornerstoneStreamingImageVolumeLoader } from './loaders/cornerstoneStreamingImageVolumeLoader';
33
+ import { cornerstoneStreamingDynamicImageVolumeLoader } from './loaders/cornerstoneStreamingDynamicImageVolumeLoader';
29
34
  import { setVolumesForViewports, addVolumesToViewports, addImageSlicesToViewports, } from './RenderingEngine/helpers';
30
- export { init, isCornerstoneInitialized, peerImport, getConfiguration, setConfiguration, getWebWorkerManager, canRenderFloatTextures, Enums, CONSTANTS, Events as EVENTS, Settings, BaseVolumeViewport, VolumeViewport, VolumeViewport3D, Viewport, StackViewport, VideoViewport, WSIViewport, RenderingEngine, ImageVolume, Surface, getRenderingEngine, getRenderingEngines, getEnabledElement, getEnabledElementByIds, getEnabledElements, getEnabledElementByViewportId, createVolumeActor, getOrCreateCanvas, createVolumeMapper, cache, eventTarget, triggerEvent, imageLoader, registerImageLoader, volumeLoader, metaData, utilities, setVolumesForViewports, addVolumesToViewports, addImageSlicesToViewports, imageLoadPoolManager as requestPoolManager, imageRetrievalPoolManager, imageLoadPoolManager, getShouldUseCPURendering, setUseCPURendering, setPreferSizeOverAccuracy, resetUseCPURendering, geometryLoader, ProgressiveRetrieveImages, };
35
+ export { init, isCornerstoneInitialized, peerImport, getConfiguration, setConfiguration, getWebWorkerManager, canRenderFloatTextures, Enums, CONSTANTS, Events as EVENTS, Settings, BaseVolumeViewport, VolumeViewport, VolumeViewport3D, Viewport, StackViewport, VideoViewport, WSIViewport, RenderingEngine, ImageVolume, Surface, getRenderingEngine, getRenderingEngines, getEnabledElement, getEnabledElementByIds, getEnabledElements, getEnabledElementByViewportId, createVolumeActor, getOrCreateCanvas, createVolumeMapper, cache, eventTarget, triggerEvent, imageLoader, registerImageLoader, volumeLoader, metaData, utilities, setVolumesForViewports, addVolumesToViewports, addImageSlicesToViewports, imageLoadPoolManager as requestPoolManager, imageRetrievalPoolManager, imageLoadPoolManager, getShouldUseCPURendering, setUseCPURendering, setPreferSizeOverAccuracy, resetUseCPURendering, geometryLoader, ProgressiveRetrieveImages, cornerstoneStreamingImageVolumeLoader, cornerstoneStreamingDynamicImageVolumeLoader, };
package/dist/esm/init.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { getRenderingEngines } from './RenderingEngine/getRenderingEngine';
2
2
  let csRenderInitialized = false;
3
- import { deepMerge } from './utilities';
3
+ import deepMerge from './utilities/deepMerge';
4
4
  import CentralizedWebWorkerManager from './webWorkerManager/webWorkerManager';
5
5
  const defaultConfig = {
6
6
  gpuTier: { tier: 2 },
@@ -2,10 +2,12 @@ import singleRetrieveStages from './configuration/singleRetrieve';
2
2
  import sequentialRetrieveStages from './configuration/sequentialRetrieve';
3
3
  import interleavedRetrieveStages from './configuration/interleavedRetrieve';
4
4
  import { loadAndCacheImage } from './imageLoader';
5
- import { triggerEvent, ProgressiveIterator, decimate } from '../utilities';
5
+ import triggerEvent from '../utilities/triggerEvent';
6
+ import ProgressiveIterator from '../utilities/ProgressiveIterator';
7
+ import decimate from '../utilities/decimate';
6
8
  import imageLoadPoolManager from '../requestPool/imageLoadPoolManager';
7
9
  import { ImageQualityStatus, RequestType, Events } from '../enums';
8
- import cache from '../cache';
10
+ import cache from '../cache/cache';
9
11
  import eventTarget from '../eventTarget';
10
12
  import { fillNearbyFrames } from './fillNearbyFrames';
11
13
  export { sequentialRetrieveStages, interleavedRetrieveStages, singleRetrieveStages, };
@@ -0,0 +1,10 @@
1
+ import { StreamingDynamicImageVolume } from '../cache';
2
+ interface IVolumeLoader {
3
+ promise: Promise<StreamingDynamicImageVolume>;
4
+ cancel: () => void;
5
+ decache: () => void;
6
+ }
7
+ declare function cornerstoneStreamingDynamicImageVolumeLoader(volumeId: string, options: {
8
+ imageIds: string[];
9
+ }): IVolumeLoader;
10
+ export { cornerstoneStreamingDynamicImageVolumeLoader };