@cornerstonejs/core 0.43.0 → 0.44.0

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 (57) hide show
  1. package/dist/cjs/RenderingEngine/BaseVolumeViewport.js +1 -1
  2. package/dist/cjs/RenderingEngine/BaseVolumeViewport.js.map +1 -1
  3. package/dist/cjs/RenderingEngine/StackViewport.d.ts +6 -2
  4. package/dist/cjs/RenderingEngine/StackViewport.js +95 -68
  5. package/dist/cjs/RenderingEngine/StackViewport.js.map +1 -1
  6. package/dist/cjs/RenderingEngine/Viewport.d.ts +2 -1
  7. package/dist/cjs/RenderingEngine/Viewport.js +1 -1
  8. package/dist/cjs/RenderingEngine/Viewport.js.map +1 -1
  9. package/dist/cjs/RenderingEngine/helpers/cpuFallback/rendering/renderColorImage.js +1 -1
  10. package/dist/cjs/index.d.ts +2 -2
  11. package/dist/cjs/index.js +2 -1
  12. package/dist/cjs/index.js.map +1 -1
  13. package/dist/cjs/init.d.ts +2 -1
  14. package/dist/cjs/init.js +18 -13
  15. package/dist/cjs/init.js.map +1 -1
  16. package/dist/cjs/types/IImage.d.ts +4 -3
  17. package/dist/cjs/types/IViewport.d.ts +1 -0
  18. package/dist/cjs/utilities/calibratedPixelSpacingMetadataProvider.d.ts +7 -2
  19. package/dist/cjs/utilities/calibratedPixelSpacingMetadataProvider.js +0 -3
  20. package/dist/cjs/utilities/calibratedPixelSpacingMetadataProvider.js.map +1 -1
  21. package/dist/cjs/utilities/loadImageToCanvas.js +1 -0
  22. package/dist/cjs/utilities/loadImageToCanvas.js.map +1 -1
  23. package/dist/esm/RenderingEngine/BaseVolumeViewport.js +1 -1
  24. package/dist/esm/RenderingEngine/BaseVolumeViewport.js.map +1 -1
  25. package/dist/esm/RenderingEngine/StackViewport.d.ts +6 -2
  26. package/dist/esm/RenderingEngine/StackViewport.js +99 -69
  27. package/dist/esm/RenderingEngine/StackViewport.js.map +1 -1
  28. package/dist/esm/RenderingEngine/Viewport.d.ts +2 -1
  29. package/dist/esm/RenderingEngine/Viewport.js +1 -1
  30. package/dist/esm/RenderingEngine/Viewport.js.map +1 -1
  31. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/renderColorImage.js +1 -1
  32. package/dist/esm/index.d.ts +2 -2
  33. package/dist/esm/index.js +2 -2
  34. package/dist/esm/index.js.map +1 -1
  35. package/dist/esm/init.d.ts +2 -1
  36. package/dist/esm/init.js +17 -13
  37. package/dist/esm/init.js.map +1 -1
  38. package/dist/esm/types/IImage.d.ts +4 -3
  39. package/dist/esm/types/IViewport.d.ts +1 -0
  40. package/dist/esm/utilities/calibratedPixelSpacingMetadataProvider.d.ts +7 -2
  41. package/dist/esm/utilities/calibratedPixelSpacingMetadataProvider.js +0 -3
  42. package/dist/esm/utilities/calibratedPixelSpacingMetadataProvider.js.map +1 -1
  43. package/dist/esm/utilities/loadImageToCanvas.js +1 -0
  44. package/dist/esm/utilities/loadImageToCanvas.js.map +1 -1
  45. package/dist/umd/index.js +1 -1
  46. package/dist/umd/index.js.map +1 -1
  47. package/package.json +4 -4
  48. package/src/RenderingEngine/BaseVolumeViewport.ts +1 -1
  49. package/src/RenderingEngine/StackViewport.ts +165 -92
  50. package/src/RenderingEngine/Viewport.ts +2 -1
  51. package/src/RenderingEngine/helpers/cpuFallback/rendering/renderColorImage.ts +1 -1
  52. package/src/index.ts +3 -1
  53. package/src/init.ts +42 -14
  54. package/src/types/IImage.ts +11 -3
  55. package/src/types/IViewport.ts +1 -0
  56. package/src/utilities/calibratedPixelSpacingMetadataProvider.ts +10 -6
  57. package/src/utilities/loadImageToCanvas.ts +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/core",
3
- "version": "0.43.0",
3
+ "version": "0.44.0",
4
4
  "description": "",
5
5
  "main": "dist/umd/index.js",
6
6
  "types": "dist/esm/index.d.ts",
@@ -27,7 +27,7 @@
27
27
  "webpack:watch": "webpack --mode development --progress --watch --config ./.webpack/webpack.dev.js"
28
28
  },
29
29
  "peerDependencies": {
30
- "@kitware/vtk.js": "26.5.6",
30
+ "@kitware/vtk.js": "27.3.1",
31
31
  "gl-matrix": "^3.4.3"
32
32
  },
33
33
  "dependencies": {
@@ -35,7 +35,7 @@
35
35
  "lodash.clonedeep": "4.5.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@kitware/vtk.js": "26.5.6",
38
+ "@kitware/vtk.js": "27.3.1",
39
39
  "detect-gpu": "^4.0.45",
40
40
  "gl-matrix": "^3.4.3",
41
41
  "resemblejs": "^4.1.0"
@@ -51,5 +51,5 @@
51
51
  "type": "individual",
52
52
  "url": "https://ohif.org/donate"
53
53
  },
54
- "gitHead": "cc3ce18f1c601fc911d8866987ae369a8f4c28df"
54
+ "gitHead": "06ba42597fb76be663ec565463e8ef4b2ac968c8"
55
55
  }
@@ -63,7 +63,7 @@ abstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {
63
63
  super(props);
64
64
 
65
65
  this.useCPURendering = getShouldUseCPURendering();
66
- this.use16BitTexture = this._shouldUse16BitTexture();
66
+ this.use16BitTexture = this._shouldUseNativeDataType();
67
67
 
68
68
  if (this.useCPURendering) {
69
69
  throw new Error(
@@ -56,7 +56,7 @@ import resize from './helpers/cpuFallback/rendering/resize';
56
56
 
57
57
  import resetCamera from './helpers/cpuFallback/rendering/resetCamera';
58
58
  import { Transform } from './helpers/cpuFallback/rendering/transform';
59
- import { getShouldUseCPURendering } from '../init';
59
+ import { getConfiguration, getShouldUseCPURendering } from '../init';
60
60
  import RequestType from '../enums/RequestType';
61
61
  import {
62
62
  StackViewportNewStackEventDetail,
@@ -66,7 +66,6 @@ import {
66
66
  import cache from '../cache';
67
67
  import correctShift from './helpers/cpuFallback/rendering/correctShift';
68
68
  import { ImageActor } from '../types/IActor';
69
- import isRgbaSourceRgbDest from './helpers/isRgbaSourceRgbDest';
70
69
  import createLinearRGBTransferFunction from '../utilities/createLinearRGBTransferFunction';
71
70
 
72
71
  const EPSILON = 1; // Slice Thickness
@@ -157,7 +156,12 @@ class StackViewport extends Viewport implements IStackViewport {
157
156
  private _cpuFallbackEnabledElement?: CPUFallbackEnabledElement;
158
157
  // CPU fallback
159
158
  private useCPURendering: boolean;
160
- private use16BitTexture = false;
159
+ // Since WebGL natively supports 8 bit int and Float32, we should check if
160
+ // extra configuration flags has been set to use native data type
161
+ // which would save a lot of memory and speed up rendering but it is not
162
+ // yet widely supported in all hardwares. This feature can be turned on
163
+ // by setting useNorm16Texture or preferSizeOverAccuracy in the configuration
164
+ private useNativeDataType = false;
161
165
  private cpuImagePixelData: number[];
162
166
  private cpuRenderingInvalidated: boolean;
163
167
  private csImage: IImage;
@@ -178,34 +182,12 @@ class StackViewport extends Viewport implements IStackViewport {
178
182
  this.scaling = {};
179
183
  this.modality = null;
180
184
  this.useCPURendering = getShouldUseCPURendering();
181
- this.use16BitTexture = this._shouldUse16BitTexture();
185
+ this.useNativeDataType = this._shouldUseNativeDataType();
182
186
  this._configureRenderingPipeline();
183
187
 
184
- if (this.useCPURendering) {
185
- this._cpuFallbackEnabledElement = {
186
- canvas: this.canvas,
187
- renderingTools: {},
188
- transform: new Transform(),
189
- viewport: { rotation: 0 },
190
- };
191
- } else {
192
- const renderer = this.getRenderer();
193
- const camera = vtkCamera.newInstance();
194
- renderer.setActiveCamera(camera);
195
-
196
- const viewPlaneNormal = <Point3>[0, 0, -1];
197
- this.initialViewUp = <Point3>[0, -1, 0];
198
-
199
- camera.setDirectionOfProjection(
200
- -viewPlaneNormal[0],
201
- -viewPlaneNormal[1],
202
- -viewPlaneNormal[2]
203
- );
204
- camera.setViewUp(...this.initialViewUp);
205
- camera.setParallelProjection(true);
206
- camera.setThicknessFromFocalPoint(0.1);
207
- camera.setFreezeFocalPoint(true);
208
- }
188
+ this.useCPURendering
189
+ ? this._resetCPUFallbackElement()
190
+ : this._resetGPUViewport();
209
191
 
210
192
  this.imageIds = [];
211
193
  this.currentImageIdIndex = 0;
@@ -216,21 +198,60 @@ class StackViewport extends Viewport implements IStackViewport {
216
198
  this.initializeElementDisabledHandler();
217
199
  }
218
200
 
201
+ public setUseCPURendering(value: boolean) {
202
+ this.useCPURendering = value;
203
+ this._configureRenderingPipeline();
204
+ }
205
+
219
206
  static get useCustomRenderingPipeline(): boolean {
220
207
  return getShouldUseCPURendering();
221
208
  }
222
209
 
223
- public setUseCPURendering(value: boolean) {
224
- this.useCPURendering = value;
210
+ public updateRenderingPipeline = () => {
225
211
  this._configureRenderingPipeline();
226
- }
212
+ };
227
213
 
228
214
  private _configureRenderingPipeline() {
215
+ this.useNativeDataType = this._shouldUseNativeDataType();
216
+ this.useCPURendering = getShouldUseCPURendering();
217
+
229
218
  for (const [funcName, functions] of Object.entries(
230
219
  this.renderingPipelineFunctions
231
220
  )) {
232
221
  this[funcName] = this.useCPURendering ? functions.cpu : functions.gpu;
233
222
  }
223
+
224
+ this.useCPURendering
225
+ ? this._resetCPUFallbackElement()
226
+ : this._resetGPUViewport();
227
+ }
228
+
229
+ private _resetCPUFallbackElement() {
230
+ this._cpuFallbackEnabledElement = {
231
+ canvas: this.canvas,
232
+ renderingTools: {},
233
+ transform: new Transform(),
234
+ viewport: { rotation: 0 },
235
+ };
236
+ }
237
+
238
+ private _resetGPUViewport() {
239
+ const renderer = this.getRenderer();
240
+ const camera = vtkCamera.newInstance();
241
+ renderer.setActiveCamera(camera);
242
+
243
+ const viewPlaneNormal = <Point3>[0, 0, -1];
244
+ this.initialViewUp = <Point3>[0, -1, 0];
245
+
246
+ camera.setDirectionOfProjection(
247
+ -viewPlaneNormal[0],
248
+ -viewPlaneNormal[1],
249
+ -viewPlaneNormal[2]
250
+ );
251
+ camera.setViewUp(...this.initialViewUp);
252
+ camera.setParallelProjection(true);
253
+ camera.setThicknessFromFocalPoint(0.1);
254
+ camera.setFreezeFocalPoint(true);
234
255
  }
235
256
 
236
257
  /**
@@ -500,6 +521,13 @@ class StackViewport extends Viewport implements IStackViewport {
500
521
 
501
522
  actor.setMapper(mapper);
502
523
 
524
+ const { preferSizeOverAccuracy } = getConfiguration().rendering;
525
+
526
+ if (preferSizeOverAccuracy) {
527
+ // @ts-ignore for now until vtk is updated
528
+ mapper.setPreferSizeOverAccuracy(true);
529
+ }
530
+
503
531
  if (imageData.getPointData().getNumberOfComponents() > 1) {
504
532
  actor.getProperty().setIndependentComponents(false);
505
533
  }
@@ -584,8 +612,10 @@ class StackViewport extends Viewport implements IStackViewport {
584
612
  return imagePlaneModule;
585
613
  }
586
614
 
587
- const [calibratedRowSpacing, calibratedColumnSpacing] =
588
- calibratedPixelSpacing;
615
+ const {
616
+ rowPixelSpacing: calibratedRowSpacing,
617
+ columnPixelSpacing: calibratedColumnSpacing,
618
+ } = calibratedPixelSpacing;
589
619
 
590
620
  // Todo: This is necessary in general, but breaks an edge case when an image
591
621
  // is calibrated to some other spacing, and it gets calibrated BACK to the
@@ -624,7 +654,9 @@ class StackViewport extends Viewport implements IStackViewport {
624
654
  calibratedColumnSpacing / imagePlaneModule.columnPixelSpacing,
625
655
  };
626
656
 
627
- // modify imagePlaneModule for actor to use calibrated spacing
657
+ // modify the calibration object to store the actual updated values applied
658
+ calibratedPixelSpacing.appliedSpacing = calibratedPixelSpacing;
659
+ // This updates the render copy
628
660
  imagePlaneModule.rowPixelSpacing = calibratedRowSpacing;
629
661
  imagePlaneModule.columnPixelSpacing = calibratedColumnSpacing;
630
662
  return imagePlaneModule;
@@ -634,6 +666,8 @@ class StackViewport extends Viewport implements IStackViewport {
634
666
  const { imageData } = imageDataMetadata;
635
667
  const [columnPixelSpacing, rowPixelSpacing] = imageData.getSpacing();
636
668
 
669
+ // modify the calibration object to store the actual updated values applied
670
+ calibratedPixelSpacing.appliedSpacing = calibratedPixelSpacing;
637
671
  imagePlaneModule.rowPixelSpacing = calibratedRowSpacing;
638
672
  imagePlaneModule.columnPixelSpacing = calibratedColumnSpacing;
639
673
 
@@ -1424,32 +1458,10 @@ class StackViewport extends Viewport implements IStackViewport {
1424
1458
  direction,
1425
1459
  dimensions,
1426
1460
  spacing,
1427
- bitsAllocated,
1428
1461
  numComps,
1429
- numVoxels,
1430
- TypedArray,
1462
+ pixelArray,
1431
1463
  }): void {
1432
- let pixelArray;
1433
- switch (bitsAllocated) {
1434
- case 8:
1435
- pixelArray = new Uint8Array(numVoxels * numComps);
1436
- break;
1437
- case 16:
1438
- if (this.use16BitTexture) {
1439
- pixelArray = new TypedArray(numVoxels * numComps);
1440
- } else {
1441
- pixelArray = new Float32Array(numVoxels * numComps);
1442
- }
1443
-
1444
- break;
1445
- case 24:
1446
- pixelArray = new Uint8Array(numVoxels * 3 * numComps);
1447
-
1448
- break;
1449
- default:
1450
- console.log('bit allocation not implemented');
1451
- }
1452
-
1464
+ // Todo: I guess nothing should be done for use16bit?
1453
1465
  const scalarArray = vtkDataArray.newInstance({
1454
1466
  name: 'Pixels',
1455
1467
  numberOfComponents: numComps,
@@ -1550,7 +1562,7 @@ class StackViewport extends Viewport implements IStackViewport {
1550
1562
  yVoxels === image.rows &&
1551
1563
  isEqual(imagePlaneModule.rowCosines, <Point3>rowCosines) &&
1552
1564
  isEqual(imagePlaneModule.columnCosines, <Point3>columnCosines) &&
1553
- (!this.use16BitTexture ||
1565
+ (!this.useNativeDataType ||
1554
1566
  dataType === image.getPixelData().constructor.name)
1555
1567
  );
1556
1568
  }
@@ -1571,8 +1583,12 @@ class StackViewport extends Viewport implements IStackViewport {
1571
1583
 
1572
1584
  this._imageData.setOrigin(origin);
1573
1585
 
1574
- // 1. Update the pixel data in the vtkImageData object with the pixelData
1575
- // from the loaded Cornerstone image
1586
+ // Update the pixel data in the vtkImageData object with the pixelData
1587
+ // from the loaded Cornerstone image
1588
+ this._updatePixelData(image);
1589
+ }
1590
+
1591
+ private _updatePixelData(image: IImage) {
1576
1592
  const pixelData = image.getPixelData();
1577
1593
  const scalars = this._imageData.getPointData().getScalars();
1578
1594
  const scalarData = scalars.getData() as
@@ -1581,24 +1597,21 @@ class StackViewport extends Viewport implements IStackViewport {
1581
1597
  | Uint16Array
1582
1598
  | Int16Array;
1583
1599
 
1584
- if (image.rgba || isRgbaSourceRgbDest(pixelData, scalarData)) {
1585
- if (!image.rgba) {
1586
- console.warn('rgba not specified but data looks rgba ish', image);
1587
- }
1588
- // if image is already cached with rgba for any reason (cpu fallback),
1589
- // we need to convert it to rgb for the pixel data set
1590
- // RGB case
1591
- const numPixels = pixelData.length / 4;
1592
-
1593
- let rgbIndex = 0;
1594
- let index = 0;
1595
-
1596
- for (let i = 0; i < numPixels; i++) {
1597
- scalarData[index++] = pixelData[rgbIndex++]; // red
1598
- scalarData[index++] = pixelData[rgbIndex++]; // green
1599
- scalarData[index++] = pixelData[rgbIndex++]; // blue
1600
- rgbIndex++; // skip alpha
1600
+ // if the color image is loaded with CPU previously, it loads it
1601
+ // with RGBA, and here we need to remove the A channel from the
1602
+ // pixel data.
1603
+ if (image.color && image.rgba) {
1604
+ const newPixelData = new Uint8Array(image.columns * image.rows * 3);
1605
+ for (let i = 0; i < image.columns * image.rows; i++) {
1606
+ newPixelData[i * 3] = pixelData[i * 4];
1607
+ newPixelData[i * 3 + 1] = pixelData[i * 4 + 1];
1608
+ newPixelData[i * 3 + 2] = pixelData[i * 4 + 2];
1601
1609
  }
1610
+ // modify the image object to have the correct pixel data for later
1611
+ // use.
1612
+ image.rgba = false;
1613
+ image.getPixelData = () => newPixelData;
1614
+ scalarData.set(newPixelData);
1602
1615
  } else {
1603
1616
  scalarData.set(pixelData);
1604
1617
  }
@@ -1645,6 +1658,50 @@ class StackViewport extends Viewport implements IStackViewport {
1645
1658
  return;
1646
1659
  }
1647
1660
 
1661
+ const pixelData = image.getPixelData();
1662
+
1663
+ // handle the case where the pixelData is a Float32Array
1664
+ // CPU path cannot handle it, it should be converted to Uint16Array
1665
+ // and via the Modality LUT we can display it properly
1666
+ if (pixelData instanceof Float32Array) {
1667
+ const floatMinMax = {
1668
+ min: image.maxPixelValue,
1669
+ max: image.minPixelValue,
1670
+ };
1671
+ const floatRange = Math.abs(floatMinMax.max - floatMinMax.min);
1672
+ const intRange = 65535;
1673
+ const slope = floatRange / intRange;
1674
+ const intercept = floatMinMax.min;
1675
+ const numPixels = pixelData.length;
1676
+ const intPixelData = new Uint16Array(numPixels);
1677
+
1678
+ let min = 65535;
1679
+
1680
+ let max = 0;
1681
+
1682
+ for (let i = 0; i < numPixels; i++) {
1683
+ const rescaledPixel = Math.floor(
1684
+ (pixelData[i] - intercept) / slope
1685
+ );
1686
+
1687
+ intPixelData[i] = rescaledPixel;
1688
+ min = Math.min(min, rescaledPixel);
1689
+ max = Math.max(max, rescaledPixel);
1690
+ }
1691
+
1692
+ // reset the properties since basically the image has changed
1693
+ image.minPixelValue = min;
1694
+ image.maxPixelValue = max;
1695
+ image.slope = slope;
1696
+ image.intercept = intercept;
1697
+ image.getPixelData = () => intPixelData;
1698
+
1699
+ image.preScale = {
1700
+ ...image.preScale,
1701
+ scaled: false,
1702
+ };
1703
+ }
1704
+
1648
1705
  image.isPreScaled = image.preScale?.scaled;
1649
1706
  this.csImage = image;
1650
1707
 
@@ -1667,6 +1724,12 @@ class StackViewport extends Viewport implements IStackViewport {
1667
1724
  this._cpuFallbackEnabledElement.viewport.colormap
1668
1725
  );
1669
1726
 
1727
+ const { windowCenter, windowWidth } = viewport.voi;
1728
+ this.voiRange = windowLevelUtil.toLowHighRange(
1729
+ windowWidth,
1730
+ windowCenter
1731
+ );
1732
+
1670
1733
  this._cpuFallbackEnabledElement.image = image;
1671
1734
  this._cpuFallbackEnabledElement.metadata = {
1672
1735
  ...metadata,
@@ -1741,9 +1804,6 @@ class StackViewport extends Viewport implements IStackViewport {
1741
1804
  const requestType = RequestType.Interaction;
1742
1805
  const additionalDetails = { imageId };
1743
1806
  const options = {
1744
- targetBuffer: {
1745
- type: this.use16BitTexture ? undefined : 'Float32Array',
1746
- },
1747
1807
  preScale: {
1748
1808
  enabled: true,
1749
1809
  },
@@ -1827,17 +1887,19 @@ class StackViewport extends Viewport implements IStackViewport {
1827
1887
  }
1828
1888
 
1829
1889
  /**
1830
- * CSWIL will automatically choose the array type when no targetBuffer
1831
- * is provided. When CSWIL is initialized, the use16bit should match
1832
- * the settings of cornerstone3D (either preferSizeOverAccuracy or norm16
1833
- * textures need to be enabled)
1890
+ * If use16bittexture is specified, the CSWIL will automatically choose the
1891
+ * array type when no targetBuffer is provided. When CSWIL is initialized,
1892
+ * the use16bit should match the settings of cornerstone3D (either preferSizeOverAccuracy
1893
+ * or norm16 textures need to be enabled)
1894
+ *
1895
+ * If use16bittexture is not specified, we force the Float32Array for now
1834
1896
  */
1835
1897
  const priority = -5;
1836
1898
  const requestType = RequestType.Interaction;
1837
1899
  const additionalDetails = { imageId };
1838
1900
  const options = {
1839
1901
  targetBuffer: {
1840
- type: this.use16BitTexture ? undefined : 'Float32Array',
1902
+ type: this.useNativeDataType ? undefined : 'Float32Array',
1841
1903
  },
1842
1904
  preScale: {
1843
1905
  enabled: true,
@@ -1946,9 +2008,7 @@ class StackViewport extends Viewport implements IStackViewport {
1946
2008
  direction,
1947
2009
  dimensions,
1948
2010
  spacing,
1949
- bitsAllocated,
1950
2011
  numComps,
1951
- numVoxels,
1952
2012
  imagePixelModule,
1953
2013
  } = this._getImageDataMetadata(image);
1954
2014
 
@@ -1959,10 +2019,8 @@ class StackViewport extends Viewport implements IStackViewport {
1959
2019
  direction,
1960
2020
  dimensions,
1961
2021
  spacing,
1962
- bitsAllocated,
1963
2022
  numComps,
1964
- numVoxels,
1965
- TypedArray: image.getPixelData().constructor,
2023
+ pixelArray: image.getPixelData(),
1966
2024
  });
1967
2025
 
1968
2026
  // Set the scalar data of the vtkImageData object from the Cornerstone
@@ -2574,10 +2632,25 @@ class StackViewport extends Viewport implements IStackViewport {
2574
2632
  private _getImagePlaneModule(imageId: string): ImagePlaneModule {
2575
2633
  const imagePlaneModule = metaData.get('imagePlaneModule', imageId);
2576
2634
 
2635
+ const calibratedPixelSpacing = metaData.get(
2636
+ 'calibratedPixelSpacing',
2637
+ imageId
2638
+ );
2639
+
2577
2640
  const newImagePlaneModule: ImagePlaneModule = {
2578
2641
  ...imagePlaneModule,
2579
2642
  };
2580
2643
 
2644
+ if (calibratedPixelSpacing?.appliedSpacing) {
2645
+ // Over-ride the image plane module spacing, as the measurement data
2646
+ // has already been created with the calibrated spacing provided from
2647
+ // down below inside calibrateIfNecessary
2648
+ const { rowPixelSpacing, columnPixelSpacing } =
2649
+ calibratedPixelSpacing.appliedSpacing;
2650
+ newImagePlaneModule.rowPixelSpacing = rowPixelSpacing;
2651
+ newImagePlaneModule.columnPixelSpacing = columnPixelSpacing;
2652
+ }
2653
+
2581
2654
  if (!newImagePlaneModule.columnPixelSpacing) {
2582
2655
  newImagePlaneModule.columnPixelSpacing = 1;
2583
2656
  this.hasPixelSpacing = false;
@@ -111,6 +111,7 @@ class Viewport implements IViewport {
111
111
  customRenderViewportToCanvas: () => unknown;
112
112
  resize: () => void;
113
113
  getProperties: () => void;
114
+ updateRenderingPipeline: () => void;
114
115
 
115
116
  static get useCustomRenderingPipeline(): boolean {
116
117
  return false;
@@ -1222,7 +1223,7 @@ class Viewport implements IViewport {
1222
1223
  return { widthWorld: maxX - minX, heightWorld: maxY - minY };
1223
1224
  }
1224
1225
 
1225
- protected _shouldUse16BitTexture() {
1226
+ protected _shouldUseNativeDataType() {
1226
1227
  const { useNorm16Texture, preferSizeOverAccuracy } =
1227
1228
  getConfiguration().rendering;
1228
1229
  return useNorm16Texture || preferSizeOverAccuracy;
@@ -75,7 +75,7 @@ function getRenderCanvas(
75
75
  // Fast drawing
76
76
  if (
77
77
  enabledElement.viewport.voi.windowWidth === 255 &&
78
- enabledElement.viewport.voi.windowCenter === 128 &&
78
+ enabledElement.viewport.voi.windowCenter === 127 &&
79
79
  enabledElement.viewport.invert === false &&
80
80
  image.getCanvas &&
81
81
  image.getCanvas()
package/src/index.ts CHANGED
@@ -33,6 +33,7 @@ import {
33
33
  getShouldUseSharedArrayBuffer,
34
34
  isCornerstoneInitialized,
35
35
  setUseCPURendering,
36
+ setPreferSizeOverAccuracy,
36
37
  setUseSharedArrayBuffer,
37
38
  resetUseCPURendering,
38
39
  resetUseSharedArrayBuffer,
@@ -70,7 +71,7 @@ export {
70
71
  // enums
71
72
  Enums,
72
73
  CONSTANTS,
73
- Events as EVENTS, // CornerstoneWADOImageLoader uses this, Todo: remove it after fixing wado
74
+ Events as EVENTS, // CornerstoneDICOMImageLoader uses this, Todo: remove it after fixing wado
74
75
  //
75
76
  Settings,
76
77
  // Rendering Engine
@@ -113,6 +114,7 @@ export {
113
114
  // CPU Rendering
114
115
  getShouldUseCPURendering,
115
116
  setUseCPURendering,
117
+ setPreferSizeOverAccuracy,
116
118
  resetUseCPURendering,
117
119
  // SharedArrayBuffer
118
120
  getShouldUseSharedArrayBuffer,
package/src/init.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { getGPUTier } from 'detect-gpu';
2
2
  import { SharedArrayBufferModes } from './enums';
3
+ import { getRenderingEngines } from './RenderingEngine/getRenderingEngine';
3
4
  let csRenderInitialized = false;
4
5
  let useSharedArrayBuffer = true;
5
6
  let sharedArrayBufferMode = SharedArrayBufferModes.TRUE;
@@ -10,8 +11,9 @@ import { Cornerstone3DConfig } from './types';
10
11
  const defaultConfig = {
11
12
  detectGPU: {},
12
13
  rendering: {
13
- preferSizeOverAccuracy: false,
14
14
  useCPURendering: false,
15
+ // GPU rendering options
16
+ preferSizeOverAccuracy: false,
15
17
  useNorm16Texture: false, // _hasNorm16TextureSupport(),
16
18
  strictZSpacingForVolumeViewport: true,
17
19
  },
@@ -22,8 +24,9 @@ const defaultConfig = {
22
24
  let config = {
23
25
  detectGPU: {},
24
26
  rendering: {
25
- preferSizeOverAccuracy: false,
26
27
  useCPURendering: false,
28
+ // GPU rendering options
29
+ preferSizeOverAccuracy: false,
27
30
  useNorm16Texture: false, // _hasNorm16TextureSupport(),
28
31
  strictZSpacingForVolumeViewport: true,
29
32
  },
@@ -68,21 +71,23 @@ function hasSharedArrayBuffer() {
68
71
  }
69
72
  }
70
73
 
71
- function _hasNorm16TextureSupport() {
72
- const gl = _getGLContext();
74
+ // Todo: commenting this out until proper support for int16 textures
75
+ // are added to browsers, current implementation is buggy
76
+ // function _hasNorm16TextureSupport() {
77
+ // const gl = _getGLContext();
73
78
 
74
- if (gl) {
75
- const ext = (gl as WebGL2RenderingContext).getExtension(
76
- 'EXT_texture_norm16'
77
- );
79
+ // if (gl) {
80
+ // const ext = (gl as WebGL2RenderingContext).getExtension(
81
+ // 'EXT_texture_norm16'
82
+ // );
78
83
 
79
- if (ext) {
80
- return true;
81
- }
82
- }
84
+ // if (ext) {
85
+ // return true;
86
+ // }
87
+ // }
83
88
 
84
- return false;
85
- }
89
+ // return false;
90
+ // }
86
91
 
87
92
  /**
88
93
  * Initialize the cornerstone-core. If the browser has a webgl context and
@@ -140,6 +145,13 @@ async function init(configuration = {}): Promise<boolean> {
140
145
  function setUseCPURendering(status: boolean): void {
141
146
  config.rendering.useCPURendering = status;
142
147
  csRenderInitialized = true;
148
+ _updateRenderingPipelinesForAllViewports();
149
+ }
150
+
151
+ function setPreferSizeOverAccuracy(status: boolean): void {
152
+ config.rendering.preferSizeOverAccuracy = status;
153
+ csRenderInitialized = true;
154
+ _updateRenderingPipelinesForAllViewports();
143
155
  }
144
156
 
145
157
  /**
@@ -150,6 +162,7 @@ function setUseCPURendering(status: boolean): void {
150
162
  */
151
163
  function resetUseCPURendering(): void {
152
164
  config.rendering.useCPURendering = !_hasActiveWebGLContext();
165
+ _updateRenderingPipelinesForAllViewports();
153
166
  }
154
167
 
155
168
  /**
@@ -225,6 +238,20 @@ function getConfiguration(): Cornerstone3DConfig {
225
238
 
226
239
  function setConfiguration(c: Cornerstone3DConfig) {
227
240
  config = c;
241
+ _updateRenderingPipelinesForAllViewports();
242
+ }
243
+
244
+ /**
245
+ * Update rendering pipelines for all viewports in all rendering engines.
246
+ * @returns {void}
247
+ * @category Initialization
248
+ */
249
+ function _updateRenderingPipelinesForAllViewports(): void {
250
+ getRenderingEngines().forEach((engine) =>
251
+ engine
252
+ .getViewports()
253
+ .forEach((viewport) => viewport.updateRenderingPipeline?.())
254
+ );
228
255
  }
229
256
 
230
257
  export {
@@ -234,6 +261,7 @@ export {
234
261
  isCornerstoneInitialized,
235
262
  setUseCPURendering,
236
263
  setUseSharedArrayBuffer,
264
+ setPreferSizeOverAccuracy,
237
265
  resetUseCPURendering,
238
266
  resetUseSharedArrayBuffer,
239
267
  getConfiguration,
@@ -2,6 +2,14 @@ import CPUFallbackLUT from './CPUFallbackLUT';
2
2
  import CPUFallbackColormap from './CPUFallbackColormap';
3
3
  import CPUFallbackEnabledElement from './CPUFallbackEnabledElement';
4
4
 
5
+ type PixelDataTypedArray =
6
+ | Float32Array
7
+ | Int16Array
8
+ | Uint16Array
9
+ | Uint8Array
10
+ | Int8Array
11
+ | Uint8ClampedArray;
12
+
5
13
  /**
6
14
  * Cornerstone Image interface, it is used for both CPU and GPU rendering
7
15
  */
@@ -14,9 +22,9 @@ interface IImage {
14
22
  /** preScale object */
15
23
  preScale?: {
16
24
  /** boolean flag to indicate whether the image has been scaled */
17
- scaled: boolean;
25
+ scaled?: boolean;
18
26
  /** scaling parameters */
19
- scalingParameters: {
27
+ scalingParameters?: {
20
28
  /** modality of the image */
21
29
  modality?: string;
22
30
  /** rescale slop */
@@ -42,7 +50,7 @@ interface IImage {
42
50
  /** voiLUTFunction from metadata */
43
51
  voiLUTFunction: string;
44
52
  /** function that returns the pixelData as an array */
45
- getPixelData: () => Array<number>;
53
+ getPixelData: () => PixelDataTypedArray;
46
54
  getCanvas: () => HTMLCanvasElement;
47
55
  /** image number of rows */
48
56
  rows: number;
@@ -101,6 +101,7 @@ interface IViewport {
101
101
  /** whether the viewport has custom rendering */
102
102
  customRenderViewportToCanvas: () => unknown;
103
103
  _getCorners(bounds: Array<number>): Array<number>[];
104
+ updateRenderingPipeline: () => void;
104
105
  }
105
106
 
106
107
  /**