@cornerstonejs/core 0.33.0 → 0.33.1

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.
@@ -33,9 +33,9 @@ const EPSILON = 1;
33
33
  class StackViewport extends Viewport {
34
34
  constructor(props) {
35
35
  super(props);
36
+ this.voiUpdatedWithSetProperties = false;
36
37
  this.invert = false;
37
38
  this.stackInvalidated = false;
38
- this.voiApplied = false;
39
39
  this._publishCalibratedEvent = false;
40
40
  this.resize = () => {
41
41
  if (this.useCPURendering) {
@@ -69,22 +69,16 @@ class StackViewport extends Viewport {
69
69
  return actor;
70
70
  };
71
71
  this.getProperties = () => {
72
+ const { voiRange, VOILUTFunction, interpolationType, invert } = this;
73
+ const rotation = this.getRotation();
72
74
  return {
73
- voiRange: this.voiRange,
74
- rotation: this.getRotation(),
75
- VOILUTFunction: this.VOILUTFunction,
76
- interpolationType: this.interpolationType,
77
- invert: this.invert,
75
+ voiRange,
76
+ VOILUTFunction,
77
+ interpolationType,
78
+ invert,
79
+ rotation,
78
80
  };
79
81
  };
80
- this.getRotation = () => {
81
- if (this.useCPURendering) {
82
- return this.getRotationCPU();
83
- }
84
- else {
85
- return this.getRotationGPU();
86
- }
87
- };
88
82
  this.getRotationCPU = () => {
89
83
  const { viewport } = this._cpuFallbackEnabledElement;
90
84
  return viewport.rotation;
@@ -101,18 +95,6 @@ class StackViewport extends Viewport {
101
95
  ? initialToCurrentViewUpAngle
102
96
  : (360 - initialToCurrentViewUpAngle) % 360;
103
97
  };
104
- this.canvasToWorld = (canvasPos) => {
105
- if (this.useCPURendering) {
106
- return this.canvasToWorldCPU(canvasPos);
107
- }
108
- return this.canvasToWorldGPU(canvasPos);
109
- };
110
- this.worldToCanvas = (worldPos) => {
111
- if (this.useCPURendering) {
112
- return this.worldToCanvasCPU(worldPos);
113
- }
114
- return this.worldToCanvasGPU(worldPos);
115
- };
116
98
  this.canvasToWorldCPU = (canvasPos) => {
117
99
  if (!this._cpuFallbackEnabledElement.image) {
118
100
  return;
@@ -225,9 +207,98 @@ class StackViewport extends Viewport {
225
207
  renderingEngineId: this.renderingEngineId,
226
208
  };
227
209
  };
210
+ this.renderingPipelineFunctions = {
211
+ getImageData: {
212
+ cpu: this.getImageDataCPU,
213
+ gpu: this.getImageDataGPU,
214
+ },
215
+ setColormap: {
216
+ cpu: this.setColormapCPU,
217
+ gpu: this.setColormapGPU,
218
+ },
219
+ getCamera: {
220
+ cpu: this.getCameraCPU,
221
+ gpu: super.getCamera,
222
+ },
223
+ setCamera: {
224
+ cpu: this.setCameraCPU,
225
+ gpu: super.setCamera,
226
+ },
227
+ setVOI: {
228
+ cpu: this.setVOICPU,
229
+ gpu: this.setVOIGPU,
230
+ },
231
+ getRotation: {
232
+ cpu: this.getRotationCPU,
233
+ gpu: this.getRotationGPU,
234
+ },
235
+ setInterpolationType: {
236
+ cpu: this.setInterpolationTypeCPU,
237
+ gpu: this.setInterpolationTypeGPU,
238
+ },
239
+ setInvertColor: {
240
+ cpu: this.setInvertColorCPU,
241
+ gpu: this.setInvertColorGPU,
242
+ },
243
+ resetCamera: {
244
+ cpu: (resetPan = true, resetZoom = true) => {
245
+ this.resetCameraCPU(resetPan, resetZoom);
246
+ return true;
247
+ },
248
+ gpu: (resetPan = true, resetZoom = true) => {
249
+ this.resetCameraGPU(resetPan, resetZoom);
250
+ return true;
251
+ },
252
+ },
253
+ canvasToWorld: {
254
+ cpu: this.canvasToWorldCPU,
255
+ gpu: this.canvasToWorldGPU,
256
+ },
257
+ worldToCanvas: {
258
+ cpu: this.worldToCanvasCPU,
259
+ gpu: this.worldToCanvasGPU,
260
+ },
261
+ getRenderer: {
262
+ cpu: () => this.getCPUFallbackError('getRenderer'),
263
+ gpu: super.getRenderer,
264
+ },
265
+ getDefaultActor: {
266
+ cpu: () => this.getCPUFallbackError('getDefaultActor'),
267
+ gpu: super.getDefaultActor,
268
+ },
269
+ getActors: {
270
+ cpu: () => this.getCPUFallbackError('getActors'),
271
+ gpu: super.getActors,
272
+ },
273
+ getActor: {
274
+ cpu: () => this.getCPUFallbackError('getActor'),
275
+ gpu: super.getActor,
276
+ },
277
+ setActors: {
278
+ cpu: () => this.getCPUFallbackError('setActors'),
279
+ gpu: super.setActors,
280
+ },
281
+ addActors: {
282
+ cpu: () => this.getCPUFallbackError('addActors'),
283
+ gpu: super.addActors,
284
+ },
285
+ addActor: {
286
+ cpu: () => this.getCPUFallbackError('addActor'),
287
+ gpu: super.addActor,
288
+ },
289
+ removeAllActors: {
290
+ cpu: () => this.getCPUFallbackError('removeAllActors'),
291
+ gpu: super.removeAllActors,
292
+ },
293
+ unsetColormap: {
294
+ cpu: this.unsetColormapCPU,
295
+ gpu: this.unsetColormapGPU,
296
+ },
297
+ };
228
298
  this.scaling = {};
229
299
  this.modality = null;
230
300
  this.useCPURendering = getShouldUseCPURendering();
301
+ this._configureRenderingPipeline();
231
302
  if (this.useCPURendering) {
232
303
  this._cpuFallbackEnabledElement = {
233
304
  canvas: this.canvas,
@@ -258,20 +329,21 @@ class StackViewport extends Viewport {
258
329
  static get useCustomRenderingPipeline() {
259
330
  return getShouldUseCPURendering();
260
331
  }
332
+ setUseCPURendering(value) {
333
+ this.useCPURendering = value;
334
+ this._configureRenderingPipeline();
335
+ }
336
+ _configureRenderingPipeline() {
337
+ for (const [funcName, functions] of Object.entries(this.renderingPipelineFunctions)) {
338
+ this[funcName] = this.useCPURendering ? functions.cpu : functions.gpu;
339
+ }
340
+ }
261
341
  initializeElementDisabledHandler() {
262
342
  eventTarget.addEventListener(Events.ELEMENT_DISABLED, function elementDisabledHandler() {
263
343
  clearTimeout(this.debouncedTimeout);
264
344
  eventTarget.removeEventListener(Events.ELEMENT_DISABLED, elementDisabledHandler);
265
345
  });
266
346
  }
267
- getImageData() {
268
- if (this.useCPURendering) {
269
- return this.getImageDataCPU();
270
- }
271
- else {
272
- return this.getImageDataGPU();
273
- }
274
- }
275
347
  getImageDataGPU() {
276
348
  const defaultActor = this.getDefaultActor();
277
349
  if (!defaultActor) {
@@ -332,28 +404,18 @@ class StackViewport extends Viewport {
332
404
  },
333
405
  };
334
406
  }
335
- buildMetadata(imageId) {
407
+ buildMetadata(image) {
408
+ const imageId = image.imageId;
336
409
  const { pixelRepresentation, bitsAllocated, bitsStored, highBit, photometricInterpretation, samplesPerPixel, } = metaData.get('imagePixelModule', imageId);
337
- const voiLutModule = metaData.get('voiLutModule', imageId);
338
- let windowWidth, windowCenter, voiLUTFunction;
339
- if (voiLutModule) {
340
- ({ windowWidth, windowCenter, voiLUTFunction } = voiLutModule);
341
- if (Array.isArray(windowWidth)) {
342
- windowWidth = windowWidth[0];
343
- }
344
- if (Array.isArray(windowCenter)) {
345
- windowCenter = windowCenter[0];
346
- }
347
- if (Object.values(VOILUTFunctionType).indexOf(voiLUTFunction) === -1) {
348
- voiLUTFunction = VOILUTFunctionType.LINEAR;
349
- }
350
- }
410
+ const { windowWidth, windowCenter, voiLUTFunction } = image;
351
411
  const { modality } = metaData.get('generalSeriesModule', imageId);
352
412
  const imageIdScalingFactor = metaData.get('scalingModule', imageId);
353
413
  if (modality === 'PT' && imageIdScalingFactor) {
354
414
  this._addScalingToViewport(imageIdScalingFactor);
355
415
  }
356
416
  this.modality = modality;
417
+ const voiLUTFunctionEnum = this._getValidVOILUTFunction(voiLUTFunction);
418
+ this.VOILUTFunction = voiLUTFunctionEnum;
357
419
  let imagePlaneModule = this._getImagePlaneModule(imageId);
358
420
  if (!this.useCPURendering) {
359
421
  imagePlaneModule = this.calibrateIfNecessary(imageId, imagePlaneModule);
@@ -369,8 +431,8 @@ class StackViewport extends Viewport {
369
431
  pixelRepresentation,
370
432
  windowWidth,
371
433
  windowCenter,
372
- voiLUTFunction,
373
434
  modality,
435
+ voiLUTFunction: voiLUTFunctionEnum,
374
436
  },
375
437
  };
376
438
  }
@@ -418,8 +480,9 @@ class StackViewport extends Viewport {
418
480
  return imagePlaneModule;
419
481
  }
420
482
  setProperties({ voiRange, VOILUTFunction, invert, interpolationType, rotation, } = {}, suppressEvents = false) {
421
- if (typeof voiRange !== 'undefined' || !this.voiApplied) {
422
- this.setVOI(voiRange, suppressEvents);
483
+ if (typeof voiRange !== 'undefined') {
484
+ const voiUpdatedWithSetProperties = true;
485
+ this.setVOI(voiRange, { suppressEvents, voiUpdatedWithSetProperties });
423
486
  }
424
487
  if (typeof VOILUTFunction !== 'undefined') {
425
488
  this.setVOILUTFunction(VOILUTFunction, suppressEvents);
@@ -438,6 +501,7 @@ class StackViewport extends Viewport {
438
501
  }
439
502
  resetProperties() {
440
503
  this.cpuRenderingInvalidated = true;
504
+ this.voiUpdatedWithSetProperties = false;
441
505
  this.fillWithBackgroundColor();
442
506
  if (this.useCPURendering) {
443
507
  this._cpuFallbackEnabledElement.renderingTools = {};
@@ -445,38 +509,36 @@ class StackViewport extends Viewport {
445
509
  this._resetProperties();
446
510
  this.render();
447
511
  }
448
- getCamera() {
449
- if (this.useCPURendering) {
450
- return this.getCameraCPU();
512
+ _resetProperties() {
513
+ let voiRange;
514
+ if (this._isCurrentImagePTPrescaled()) {
515
+ voiRange = this._getDefaultPTPrescaledVOIRange();
451
516
  }
452
517
  else {
453
- return super.getCamera();
518
+ voiRange = this._getVOIRangeForCurrentImage();
454
519
  }
520
+ this.setVOI(voiRange);
521
+ if (this.getRotation() !== 0) {
522
+ this.setRotation(0);
523
+ }
524
+ this.setInterpolationType(InterpolationType.LINEAR);
525
+ this.setInvertColor(false);
455
526
  }
456
- setCamera(cameraInterface, storeAsInitialCamera = false) {
457
- if (this.useCPURendering) {
458
- this.setCameraCPU(cameraInterface);
527
+ _setPropertiesFromCache() {
528
+ const { interpolationType, invert } = this;
529
+ let voiRange;
530
+ if (this.voiUpdatedWithSetProperties) {
531
+ voiRange = this.voiRange;
532
+ }
533
+ else if (this._isCurrentImagePTPrescaled()) {
534
+ voiRange = this._getDefaultPTPrescaledVOIRange();
459
535
  }
460
536
  else {
461
- super.setCamera(cameraInterface, storeAsInitialCamera);
537
+ voiRange = this._getVOIRangeForCurrentImage() ?? this.voiRange;
462
538
  }
463
- }
464
- _resetProperties() {
465
- this.voiApplied = false;
466
- this.setProperties({
467
- voiRange: this.initialVOIRange,
468
- rotation: 0,
469
- interpolationType: InterpolationType.LINEAR,
470
- invert: false,
471
- });
472
- }
473
- _setPropertiesFromCache() {
474
- const suppressEvents = true;
475
- this.setProperties({
476
- voiRange: this.voiRange,
477
- interpolationType: this.interpolationType,
478
- invert: this.invert,
479
- }, suppressEvents);
539
+ this.setVOI(voiRange);
540
+ this.setInterpolationType(interpolationType);
541
+ this.setInvertColor(invert);
480
542
  }
481
543
  getCameraCPU() {
482
544
  const { metadata, viewport } = this._cpuFallbackEnabledElement;
@@ -563,21 +625,11 @@ class StackViewport extends Viewport {
563
625
  this.flipVertical = viewport.vflip;
564
626
  }
565
627
  }
566
- setVOI(voiRange, suppressEvents) {
567
- if (this.useCPURendering) {
568
- this.setVOICPU(voiRange, suppressEvents);
569
- return;
570
- }
571
- this.setVOIGPU(voiRange, suppressEvents);
572
- }
573
628
  setRotation(rotation) {
574
629
  const previousCamera = this.getCamera();
575
- if (this.useCPURendering) {
576
- this.setRotationCPU(rotation);
577
- }
578
- else {
579
- this.setRotationGPU(rotation);
580
- }
630
+ this.useCPURendering
631
+ ? this.setRotationCPU(rotation)
632
+ : this.setRotationGPU(rotation);
581
633
  const camera = this.getCamera();
582
634
  const eventDetail = {
583
635
  previousCamera,
@@ -593,26 +645,15 @@ class StackViewport extends Viewport {
593
645
  if (this.useCPURendering) {
594
646
  throw new Error('VOI LUT function is not supported in CPU rendering');
595
647
  }
596
- if (Object.values(VOILUTFunctionType).indexOf(voiLUTFunction) === -1) {
597
- voiLUTFunction = VOILUTFunctionType.LINEAR;
648
+ const newVOILUTFunction = this._getValidVOILUTFunction(voiLUTFunction);
649
+ let forceRecreateLUTFunction = false;
650
+ if (this.VOILUTFunction !== VOILUTFunctionType.LINEAR &&
651
+ newVOILUTFunction === VOILUTFunctionType.LINEAR) {
652
+ forceRecreateLUTFunction = true;
598
653
  }
599
- this.VOILUTFunction = voiLUTFunction;
654
+ this.VOILUTFunction = newVOILUTFunction;
600
655
  const { voiRange } = this.getProperties();
601
- this.setVOI(voiRange, suppressEvents);
602
- }
603
- setInterpolationType(interpolationType) {
604
- if (this.useCPURendering) {
605
- this.setInterpolationTypeCPU(interpolationType);
606
- return;
607
- }
608
- this.setInterpolationTypeGPU(interpolationType);
609
- }
610
- setInvertColor(invert) {
611
- if (this.useCPURendering) {
612
- this.setInvertColorCPU(invert);
613
- return;
614
- }
615
- this.setInvertColorGPU(invert);
656
+ this.setVOI(voiRange, { suppressEvents, forceRecreateLUTFunction });
616
657
  }
617
658
  setRotationCPU(rotation) {
618
659
  const { viewport } = this._cpuFallbackEnabledElement;
@@ -643,12 +684,8 @@ class StackViewport extends Viewport {
643
684
  }
644
685
  setInterpolationTypeCPU(interpolationType) {
645
686
  const { viewport } = this._cpuFallbackEnabledElement;
646
- if (interpolationType === InterpolationType.LINEAR) {
647
- viewport.pixelReplication = false;
648
- }
649
- else {
650
- viewport.pixelReplication = true;
651
- }
687
+ viewport.pixelReplication =
688
+ interpolationType === InterpolationType.LINEAR ? false : true;
652
689
  this.interpolationType = interpolationType;
653
690
  }
654
691
  setInvertColorCPU(invert) {
@@ -684,7 +721,8 @@ class StackViewport extends Viewport {
684
721
  this.invert = invert;
685
722
  }
686
723
  }
687
- setVOICPU(voiRange, suppressEvents) {
724
+ setVOICPU(voiRange, options = {}) {
725
+ const { suppressEvents = false } = options;
688
726
  const { viewport, image } = this._cpuFallbackEnabledElement;
689
727
  if (!viewport || !image) {
690
728
  return;
@@ -712,7 +750,6 @@ class StackViewport extends Viewport {
712
750
  viewport.voi.windowWidth = windowWidth;
713
751
  viewport.voi.windowCenter = windowCenter;
714
752
  }
715
- this.voiApplied = true;
716
753
  this.voiRange = voiRange;
717
754
  const eventDetail = {
718
755
  viewportId: this.id,
@@ -722,7 +759,15 @@ class StackViewport extends Viewport {
722
759
  triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail);
723
760
  }
724
761
  }
725
- setVOIGPU(voiRange, suppressEvents) {
762
+ setVOIGPU(voiRange, options = {}) {
763
+ const { suppressEvents = false, forceRecreateLUTFunction = false, voiUpdatedWithSetProperties = false, } = options;
764
+ if (voiRange &&
765
+ this.voiRange &&
766
+ this.voiRange.lower === voiRange.lower &&
767
+ this.voiRange.upper === voiRange.upper &&
768
+ !forceRecreateLUTFunction) {
769
+ return;
770
+ }
726
771
  const defaultActor = this.getDefaultActor();
727
772
  if (!defaultActor) {
728
773
  return;
@@ -730,8 +775,7 @@ class StackViewport extends Viewport {
730
775
  if (!isImageActor(defaultActor)) {
731
776
  return;
732
777
  }
733
- const { actor } = defaultActor;
734
- const imageActor = actor;
778
+ const imageActor = defaultActor.actor;
735
779
  let voiRangeToUse = voiRange;
736
780
  if (typeof voiRangeToUse === 'undefined') {
737
781
  const imageData = imageActor.getMapper().getInputData();
@@ -740,43 +784,48 @@ class StackViewport extends Viewport {
740
784
  voiRangeToUse = maxVoiRange;
741
785
  }
742
786
  imageActor.getProperty().setUseLookupTableScalarRange(true);
743
- if (this.VOILUTFunction === VOILUTFunctionType.SAMPLED_SIGMOID) {
744
- const cfun = createSigmoidRGBTransferFunction(voiRangeToUse);
787
+ let transferFunction = imageActor.getProperty().getRGBTransferFunction(0);
788
+ const isSigmoidTFun = this.VOILUTFunction === VOILUTFunctionType.SAMPLED_SIGMOID;
789
+ if (isSigmoidTFun || !transferFunction || forceRecreateLUTFunction) {
790
+ const transferFunctionCreator = isSigmoidTFun
791
+ ? createSigmoidRGBTransferFunction
792
+ : createLinearRGBTransferFunction;
793
+ transferFunction = transferFunctionCreator(voiRangeToUse);
745
794
  if (this.invert) {
746
- invertRgbTransferFunction(cfun);
795
+ invertRgbTransferFunction(transferFunction);
747
796
  }
748
- imageActor.getProperty().setRGBTransferFunction(0, cfun);
797
+ imageActor.getProperty().setRGBTransferFunction(0, transferFunction);
749
798
  }
750
- else {
751
- const cfun = createLinearRGBTransferFunction(voiRangeToUse);
752
- if (this.invert) {
753
- invertRgbTransferFunction(cfun);
754
- }
755
- imageActor.getProperty().setRGBTransferFunction(0, cfun);
799
+ if (!isSigmoidTFun) {
800
+ transferFunction.setRange(voiRangeToUse.lower, voiRangeToUse.upper);
756
801
  }
757
- this.voiApplied = true;
758
802
  this.voiRange = voiRangeToUse;
759
- if (!suppressEvents) {
760
- const eventDetail = {
761
- viewportId: this.id,
762
- range: voiRangeToUse,
763
- VOILUTFunction: this.VOILUTFunction,
764
- };
765
- triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail);
803
+ if (!this.voiUpdatedWithSetProperties) {
804
+ this.voiUpdatedWithSetProperties = voiUpdatedWithSetProperties;
766
805
  }
806
+ if (suppressEvents) {
807
+ return;
808
+ }
809
+ const eventDetail = {
810
+ viewportId: this.id,
811
+ range: voiRangeToUse,
812
+ VOILUTFunction: this.VOILUTFunction,
813
+ };
814
+ triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail);
767
815
  }
768
816
  _addScalingToViewport(imageIdScalingFactor) {
769
- if (!this.scaling.PET) {
770
- const { suvbw, suvlbm, suvbsa } = imageIdScalingFactor;
771
- const petScaling = {};
772
- if (suvlbm) {
773
- petScaling.suvbwToSuvlbm = suvlbm / suvbw;
774
- }
775
- if (suvbsa) {
776
- petScaling.suvbwToSuvbsa = suvbsa / suvbw;
777
- }
778
- this.scaling.PET = petScaling;
817
+ if (this.scaling.PET) {
818
+ return;
819
+ }
820
+ const { suvbw, suvlbm, suvbsa } = imageIdScalingFactor;
821
+ const petScaling = {};
822
+ if (suvlbm) {
823
+ petScaling.suvbwToSuvlbm = suvlbm / suvbw;
779
824
  }
825
+ if (suvbsa) {
826
+ petScaling.suvbwToSuvbsa = suvbsa / suvbw;
827
+ }
828
+ this.scaling.PET = petScaling;
780
829
  }
781
830
  _getNumCompsFromPhotometricInterpretation(photometricInterpretation) {
782
831
  let numberOfComponents = 1;
@@ -788,7 +837,7 @@ class StackViewport extends Viewport {
788
837
  return numberOfComponents;
789
838
  }
790
839
  _getImageDataMetadata(image) {
791
- const { imagePlaneModule, imagePixelModule } = this.buildMetadata(image.imageId);
840
+ const { imagePlaneModule, imagePixelModule } = this.buildMetadata(image);
792
841
  let rowCosines, columnCosines;
793
842
  rowCosines = imagePlaneModule.rowCosines;
794
843
  columnCosines = imagePlaneModule.columnCosines;
@@ -870,8 +919,9 @@ class StackViewport extends Viewport {
870
919
  this.stackInvalidated = true;
871
920
  this.flipVertical = false;
872
921
  this.flipHorizontal = false;
873
- this.voiApplied = false;
874
- this._resetProperties();
922
+ this.voiRange = null;
923
+ this.interpolationType = InterpolationType.LINEAR;
924
+ this.invert = false;
875
925
  this.fillWithBackgroundColor();
876
926
  if (this.useCPURendering) {
877
927
  this._cpuFallbackEnabledElement.renderingTools = {};
@@ -936,12 +986,9 @@ class StackViewport extends Viewport {
936
986
  this._imageData.modified();
937
987
  }
938
988
  async _loadAndDisplayImage(imageId, imageIdIndex) {
939
- if (this.useCPURendering) {
940
- await this._loadAndDisplayImageCPU(imageId, imageIdIndex);
941
- }
942
- else {
943
- await this._loadAndDisplayImageGPU(imageId, imageIdIndex);
944
- }
989
+ await (this.useCPURendering
990
+ ? this._loadAndDisplayImageCPU(imageId, imageIdIndex)
991
+ : this._loadAndDisplayImageGPU(imageId, imageIdIndex));
945
992
  return imageId;
946
993
  }
947
994
  _loadAndDisplayImageCPU(imageId, imageIdIndex) {
@@ -950,6 +997,7 @@ class StackViewport extends Viewport {
950
997
  if (this.currentImageIdIndex !== imageIdIndex) {
951
998
  return;
952
999
  }
1000
+ image.isPreScaled = image.preScale?.scaled;
953
1001
  this.csImage = image;
954
1002
  const eventDetail = {
955
1003
  image,
@@ -960,7 +1008,6 @@ class StackViewport extends Viewport {
960
1008
  };
961
1009
  triggerEvent(this.element, Events.STACK_NEW_IMAGE, eventDetail);
962
1010
  const metadata = this._getImageDataMetadata(image);
963
- image.isPreScaled = image.preScale?.scaled;
964
1011
  const viewport = getDefaultViewport(this.canvas, image, this.modality, this._cpuFallbackEnabledElement.viewport.colormap);
965
1012
  this._cpuFallbackEnabledElement.image = image;
966
1013
  this._cpuFallbackEnabledElement.metadata = {
@@ -1020,6 +1067,7 @@ class StackViewport extends Viewport {
1020
1067
  if (this.currentImageIdIndex !== imageIdIndex) {
1021
1068
  return;
1022
1069
  }
1070
+ image.isPreScaled = image.preScale?.scaled;
1023
1071
  this.csImage = image;
1024
1072
  const eventDetail = {
1025
1073
  image,
@@ -1117,41 +1165,43 @@ class StackViewport extends Viewport {
1117
1165
  this.resetCameraNoEvent();
1118
1166
  this.triggerCameraEvent(this.getCamera(), previousCameraProps);
1119
1167
  activeCamera.setFreezeFocalPoint(true);
1120
- const { windowCenter, windowWidth, voiLUTFunction } = imagePixelModule;
1121
- let voiRange = typeof windowCenter === 'number' && typeof windowWidth === 'number'
1122
- ? windowLevelUtil.toLowHighRange(windowWidth, windowCenter)
1123
- : undefined;
1124
- const isPreScaled = this.csImage.isPreScaled || this.csImage.preScale?.scaled;
1125
- if (imagePixelModule.modality === 'PT' && isPreScaled) {
1126
- voiRange = { lower: 0, upper: 5 };
1127
- }
1128
- this.initialVOIRange = voiRange;
1129
- if (this.voiApplied && typeof voiRange === 'undefined') {
1130
- voiRange = this.voiRange;
1131
- }
1132
- if (Object.values(VOILUTFunctionType).indexOf(voiLUTFunction) === -1) {
1133
- this.VOILUTFunction = VOILUTFunctionType.LINEAR;
1134
- }
1135
- else {
1136
- this.VOILUTFunction = voiLUTFunction;
1137
- }
1138
- this.setProperties({ voiRange });
1139
- if (actor.getProperty().getRGBTransferFunction(0) === null) {
1140
- const cfun = createLinearRGBTransferFunction(voiRange);
1141
- actor.getProperty().setRGBTransferFunction(0, cfun);
1142
- }
1143
- let invert = false;
1144
- if (imagePixelModule.photometricInterpretation === 'MONOCHROME1') {
1145
- invert = true;
1146
- }
1147
- this.setProperties({ invert });
1148
- const { focalPoint } = this.getCamera();
1149
- this.cameraFocalPointOnRender = focalPoint;
1168
+ this.setVOI(this._getInitialVOIRange(image));
1169
+ this.setInvertColor(imagePixelModule.photometricInterpretation === 'MONOCHROME1');
1170
+ this.cameraFocalPointOnRender = this.getCamera().focalPoint;
1150
1171
  this.stackInvalidated = false;
1151
1172
  if (this._publishCalibratedEvent) {
1152
1173
  this.triggerCalibrationEvent();
1153
1174
  }
1154
1175
  }
1176
+ _getInitialVOIRange(image) {
1177
+ if (this.voiRange && this.voiUpdatedWithSetProperties) {
1178
+ return this.voiRange;
1179
+ }
1180
+ const { windowCenter, windowWidth } = image;
1181
+ let voiRange = this._getVOIRangeFromWindowLevel(windowWidth, windowCenter);
1182
+ voiRange = this._getPTPreScaledRange() || voiRange;
1183
+ return voiRange;
1184
+ }
1185
+ _getPTPreScaledRange() {
1186
+ if (!this._isCurrentImagePTPrescaled()) {
1187
+ return undefined;
1188
+ }
1189
+ return this._getDefaultPTPrescaledVOIRange();
1190
+ }
1191
+ _isCurrentImagePTPrescaled() {
1192
+ if (this.modality !== 'PT' || !this.csImage.isPreScaled) {
1193
+ return false;
1194
+ }
1195
+ return true;
1196
+ }
1197
+ _getDefaultPTPrescaledVOIRange() {
1198
+ return { lower: 0, upper: 5 };
1199
+ }
1200
+ _getVOIRangeFromWindowLevel(windowWidth, windowCenter) {
1201
+ return typeof windowCenter === 'number' && typeof windowWidth === 'number'
1202
+ ? windowLevelUtil.toLowHighRange(windowWidth, windowCenter)
1203
+ : undefined;
1204
+ }
1155
1205
  async _setImageIdIndex(imageIdIndex) {
1156
1206
  if (imageIdIndex >= this.imageIds.length) {
1157
1207
  throw new Error(`ImageIdIndex provided ${imageIdIndex} is invalid, the stack only has ${this.imageIds.length} elements`);
@@ -1161,15 +1211,6 @@ class StackViewport extends Viewport {
1161
1211
  const imageId = await this._loadAndDisplayImage(this.imageIds[imageIdIndex], imageIdIndex);
1162
1212
  return imageId;
1163
1213
  }
1164
- resetCamera(resetPan = true, resetZoom = true) {
1165
- if (this.useCPURendering) {
1166
- this.resetCameraCPU(resetPan, resetZoom);
1167
- }
1168
- else {
1169
- this.resetCameraGPU(resetPan, resetZoom);
1170
- }
1171
- return true;
1172
- }
1173
1214
  resetCameraCPU(resetPan, resetZoom) {
1174
1215
  const { image } = this._cpuFallbackEnabledElement;
1175
1216
  if (!image) {
@@ -1285,53 +1326,15 @@ class StackViewport extends Viewport {
1285
1326
  }
1286
1327
  this._publishCalibratedEvent = false;
1287
1328
  }
1288
- getRenderer() {
1289
- if (this.useCPURendering) {
1290
- throw this.getCPUFallbackError('getRenderer');
1291
- }
1292
- return super.getRenderer();
1293
- }
1294
- getDefaultActor() {
1295
- if (this.useCPURendering) {
1296
- throw this.getCPUFallbackError('getDefaultActor');
1297
- }
1298
- return super.getDefaultActor();
1329
+ _getVOIRangeForCurrentImage() {
1330
+ const { windowCenter, windowWidth } = this.csImage;
1331
+ return this._getVOIRangeFromWindowLevel(windowWidth, windowCenter);
1299
1332
  }
1300
- getActors() {
1301
- if (this.useCPURendering) {
1302
- throw this.getCPUFallbackError('getActors');
1303
- }
1304
- return super.getActors();
1305
- }
1306
- getActor(actorUID) {
1307
- if (this.useCPURendering) {
1308
- throw this.getCPUFallbackError('getActor');
1309
- }
1310
- return super.getActor(actorUID);
1311
- }
1312
- setActors(actors) {
1313
- if (this.useCPURendering) {
1314
- throw this.getCPUFallbackError('setActors');
1315
- }
1316
- return super.setActors(actors);
1317
- }
1318
- addActors(actors) {
1319
- if (this.useCPURendering) {
1320
- throw this.getCPUFallbackError('addActors');
1321
- }
1322
- return super.addActors(actors);
1323
- }
1324
- addActor(actorEntry) {
1325
- if (this.useCPURendering) {
1326
- throw this.getCPUFallbackError('addActor');
1327
- }
1328
- return super.addActor(actorEntry);
1329
- }
1330
- removeAllActors() {
1331
- if (this.useCPURendering) {
1332
- throw this.getCPUFallbackError('removeAllActors');
1333
+ _getValidVOILUTFunction(voiLUTFunction) {
1334
+ if (Object.values(VOILUTFunctionType).indexOf(voiLUTFunction) === -1) {
1335
+ voiLUTFunction = VOILUTFunctionType.LINEAR;
1333
1336
  }
1334
- return super.removeAllActors();
1337
+ return voiLUTFunction;
1335
1338
  }
1336
1339
  getCPUFallbackError(method) {
1337
1340
  return new Error(`method ${method} cannot be used during CPU Fallback mode`);
@@ -1342,22 +1345,6 @@ class StackViewport extends Viewport {
1342
1345
  renderingEngine.fillCanvasWithBackgroundColor(this.canvas, this.options.background);
1343
1346
  }
1344
1347
  }
1345
- setColormap(colormap) {
1346
- if (this.useCPURendering) {
1347
- this.setColormapCPU(colormap);
1348
- }
1349
- else {
1350
- this.setColormapGPU(colormap);
1351
- }
1352
- }
1353
- unsetColormap() {
1354
- if (this.useCPURendering) {
1355
- this.unsetColormapCPU();
1356
- }
1357
- else {
1358
- this.unsetColormapGPU();
1359
- }
1360
- }
1361
1348
  unsetColormapCPU() {
1362
1349
  delete this._cpuFallbackEnabledElement.viewport.colormap;
1363
1350
  this._cpuFallbackEnabledElement.renderingTools = {};