@cornerstonejs/core 0.36.3 → 0.36.4

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 (223) hide show
  1. package/dist/cjs/utilities/getSliceRange.js +2 -1
  2. package/dist/cjs/utilities/getSliceRange.js.map +1 -1
  3. package/dist/esm/utilities/getSliceRange.js +2 -1
  4. package/dist/esm/utilities/getSliceRange.js.map +1 -1
  5. package/dist/umd/index.js +1 -1
  6. package/dist/umd/index.js.map +1 -1
  7. package/package.json +4 -3
  8. package/src/RenderingEngine/BaseVolumeViewport.ts +847 -0
  9. package/src/RenderingEngine/RenderingEngine.ts +1364 -0
  10. package/src/RenderingEngine/StackViewport.ts +2690 -0
  11. package/src/RenderingEngine/Viewport.ts +1244 -0
  12. package/src/RenderingEngine/VolumeViewport.ts +420 -0
  13. package/src/RenderingEngine/VolumeViewport3D.ts +42 -0
  14. package/src/RenderingEngine/getRenderingEngine.ts +34 -0
  15. package/src/RenderingEngine/helpers/addVolumesToViewports.ts +52 -0
  16. package/src/RenderingEngine/helpers/cpuFallback/colors/colormap.ts +343 -0
  17. package/src/RenderingEngine/helpers/cpuFallback/colors/index.ts +4 -0
  18. package/src/RenderingEngine/helpers/cpuFallback/colors/lookupTable.ts +469 -0
  19. package/src/RenderingEngine/helpers/cpuFallback/drawImageSync.ts +58 -0
  20. package/src/RenderingEngine/helpers/cpuFallback/rendering/calculateTransform.ts +136 -0
  21. package/src/RenderingEngine/helpers/cpuFallback/rendering/canvasToPixel.ts +25 -0
  22. package/src/RenderingEngine/helpers/cpuFallback/rendering/computeAutoVoi.ts +47 -0
  23. package/src/RenderingEngine/helpers/cpuFallback/rendering/correctShift.ts +38 -0
  24. package/src/RenderingEngine/helpers/cpuFallback/rendering/createViewport.ts +64 -0
  25. package/src/RenderingEngine/helpers/cpuFallback/rendering/doesImageNeedToBeRendered.ts +36 -0
  26. package/src/RenderingEngine/helpers/cpuFallback/rendering/fitToWindow.ts +22 -0
  27. package/src/RenderingEngine/helpers/cpuFallback/rendering/generateColorLUT.ts +60 -0
  28. package/src/RenderingEngine/helpers/cpuFallback/rendering/generateLut.ts +83 -0
  29. package/src/RenderingEngine/helpers/cpuFallback/rendering/getDefaultViewport.ts +88 -0
  30. package/src/RenderingEngine/helpers/cpuFallback/rendering/getImageFitScale.ts +52 -0
  31. package/src/RenderingEngine/helpers/cpuFallback/rendering/getImageSize.ts +55 -0
  32. package/src/RenderingEngine/helpers/cpuFallback/rendering/getLut.ts +53 -0
  33. package/src/RenderingEngine/helpers/cpuFallback/rendering/getModalityLut.ts +55 -0
  34. package/src/RenderingEngine/helpers/cpuFallback/rendering/getTransform.ts +17 -0
  35. package/src/RenderingEngine/helpers/cpuFallback/rendering/getVOILut.ts +74 -0
  36. package/src/RenderingEngine/helpers/cpuFallback/rendering/initializeRenderCanvas.ts +37 -0
  37. package/src/RenderingEngine/helpers/cpuFallback/rendering/lutMatches.ts +21 -0
  38. package/src/RenderingEngine/helpers/cpuFallback/rendering/now.ts +13 -0
  39. package/src/RenderingEngine/helpers/cpuFallback/rendering/pixelToCanvas.ts +22 -0
  40. package/src/RenderingEngine/helpers/cpuFallback/rendering/renderColorImage.ts +193 -0
  41. package/src/RenderingEngine/helpers/cpuFallback/rendering/renderGrayscaleImage.ts +166 -0
  42. package/src/RenderingEngine/helpers/cpuFallback/rendering/renderPseudoColorImage.ts +203 -0
  43. package/src/RenderingEngine/helpers/cpuFallback/rendering/resetCamera.ts +32 -0
  44. package/src/RenderingEngine/helpers/cpuFallback/rendering/resize.ts +109 -0
  45. package/src/RenderingEngine/helpers/cpuFallback/rendering/saveLastRendered.ts +36 -0
  46. package/src/RenderingEngine/helpers/cpuFallback/rendering/setDefaultViewport.ts +17 -0
  47. package/src/RenderingEngine/helpers/cpuFallback/rendering/setToPixelCoordinateSystem.ts +32 -0
  48. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedColorPixelDataToCanvasImageData.ts +58 -0
  49. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageData.ts +76 -0
  50. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataColorLUT.ts +60 -0
  51. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPET.ts +50 -0
  52. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUT.ts +66 -0
  53. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUTPET.ts +68 -0
  54. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataRGBA.ts +81 -0
  55. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedRGBAPixelDataToCanvasImageData.ts +56 -0
  56. package/src/RenderingEngine/helpers/cpuFallback/rendering/transform.ts +126 -0
  57. package/src/RenderingEngine/helpers/cpuFallback/rendering/validator.ts +31 -0
  58. package/src/RenderingEngine/helpers/createVolumeActor.ts +103 -0
  59. package/src/RenderingEngine/helpers/createVolumeMapper.ts +37 -0
  60. package/src/RenderingEngine/helpers/getOrCreateCanvas.ts +58 -0
  61. package/src/RenderingEngine/helpers/index.ts +15 -0
  62. package/src/RenderingEngine/helpers/isRgbaSourceRgbDest.ts +1 -0
  63. package/src/RenderingEngine/helpers/setDefaultVolumeVOI.ts +227 -0
  64. package/src/RenderingEngine/helpers/setVolumesForViewports.ts +52 -0
  65. package/src/RenderingEngine/helpers/viewportTypeToViewportClass.ts +14 -0
  66. package/src/RenderingEngine/helpers/viewportTypeUsesCustomRenderingPipeline.ts +7 -0
  67. package/src/RenderingEngine/helpers/volumeNewImageEventDispatcher.ts +75 -0
  68. package/src/RenderingEngine/index.ts +23 -0
  69. package/src/RenderingEngine/renderingEngineCache.ts +43 -0
  70. package/src/RenderingEngine/vtkClasses/index.js +11 -0
  71. package/src/RenderingEngine/vtkClasses/vtkOffscreenMultiRenderWindow.js +149 -0
  72. package/src/RenderingEngine/vtkClasses/vtkSharedVolumeMapper.js +52 -0
  73. package/src/RenderingEngine/vtkClasses/vtkSlabCamera.d.ts +781 -0
  74. package/src/RenderingEngine/vtkClasses/vtkSlabCamera.js +155 -0
  75. package/src/RenderingEngine/vtkClasses/vtkStreamingOpenGLRenderWindow.js +47 -0
  76. package/src/RenderingEngine/vtkClasses/vtkStreamingOpenGLTexture.js +272 -0
  77. package/src/RenderingEngine/vtkClasses/vtkStreamingOpenGLViewNodeFactory.js +159 -0
  78. package/src/RenderingEngine/vtkClasses/vtkStreamingOpenGLVolumeMapper.js +319 -0
  79. package/src/Settings.ts +294 -0
  80. package/src/cache/cache.ts +854 -0
  81. package/src/cache/classes/Contour.ts +70 -0
  82. package/src/cache/classes/ContourSet.ts +151 -0
  83. package/src/cache/classes/ImageVolume.ts +155 -0
  84. package/src/cache/index.ts +5 -0
  85. package/src/constants/cpuColormaps.ts +1537 -0
  86. package/src/constants/epsilon.ts +3 -0
  87. package/src/constants/index.ts +13 -0
  88. package/src/constants/mprCameraValues.ts +20 -0
  89. package/src/constants/rendering.ts +8 -0
  90. package/src/constants/viewportPresets.ts +357 -0
  91. package/src/enums/BlendModes.ts +23 -0
  92. package/src/enums/ContourType.ts +6 -0
  93. package/src/enums/Events.ts +196 -0
  94. package/src/enums/GeometryType.ts +5 -0
  95. package/src/enums/InterpolationType.ts +13 -0
  96. package/src/enums/OrientationAxis.ts +8 -0
  97. package/src/enums/RequestType.ts +13 -0
  98. package/src/enums/SharedArrayBufferModes.ts +11 -0
  99. package/src/enums/VOILUTFunctionType.ts +10 -0
  100. package/src/enums/ViewportType.ts +21 -0
  101. package/src/enums/index.ts +23 -0
  102. package/src/eventTarget.ts +67 -0
  103. package/src/getEnabledElement.ts +105 -0
  104. package/src/global.ts +8 -0
  105. package/src/index.ts +123 -0
  106. package/src/init.ts +247 -0
  107. package/src/loaders/geometryLoader.ts +108 -0
  108. package/src/loaders/imageLoader.ts +298 -0
  109. package/src/loaders/volumeLoader.ts +477 -0
  110. package/src/metaData.ts +84 -0
  111. package/src/requestPool/imageLoadPoolManager.ts +43 -0
  112. package/src/requestPool/imageRetrievalPoolManager.ts +25 -0
  113. package/src/requestPool/requestPoolManager.ts +329 -0
  114. package/src/types/ActorSliceRange.ts +17 -0
  115. package/src/types/CPUFallbackColormap.ts +23 -0
  116. package/src/types/CPUFallbackColormapData.ts +12 -0
  117. package/src/types/CPUFallbackColormapsData.ts +7 -0
  118. package/src/types/CPUFallbackEnabledElement.ts +71 -0
  119. package/src/types/CPUFallbackLUT.ts +5 -0
  120. package/src/types/CPUFallbackLookupTable.ts +17 -0
  121. package/src/types/CPUFallbackRenderingTools.ts +25 -0
  122. package/src/types/CPUFallbackTransform.ts +16 -0
  123. package/src/types/CPUFallbackViewport.ts +29 -0
  124. package/src/types/CPUFallbackViewportDisplayedArea.ts +15 -0
  125. package/src/types/CPUIImageData.ts +47 -0
  126. package/src/types/ContourData.ts +19 -0
  127. package/src/types/Cornerstone3DConfig.ts +31 -0
  128. package/src/types/CustomEventType.ts +14 -0
  129. package/src/types/EventTypes.ts +403 -0
  130. package/src/types/FlipDirection.ts +9 -0
  131. package/src/types/IActor.ts +23 -0
  132. package/src/types/ICache.ts +28 -0
  133. package/src/types/ICachedGeometry.ts +13 -0
  134. package/src/types/ICachedImage.ts +13 -0
  135. package/src/types/ICachedVolume.ts +12 -0
  136. package/src/types/ICamera.ts +36 -0
  137. package/src/types/IContour.ts +18 -0
  138. package/src/types/IContourSet.ts +56 -0
  139. package/src/types/IDynamicImageVolume.ts +18 -0
  140. package/src/types/IEnabledElement.ts +21 -0
  141. package/src/types/IGeometry.ts +12 -0
  142. package/src/types/IImage.ts +113 -0
  143. package/src/types/IImageData.ts +45 -0
  144. package/src/types/IImageVolume.ts +78 -0
  145. package/src/types/ILoadObject.ts +36 -0
  146. package/src/types/IRegisterImageLoader.ts +10 -0
  147. package/src/types/IRenderingEngine.ts +28 -0
  148. package/src/types/IStackViewport.ts +138 -0
  149. package/src/types/IStreamingImageVolume.ts +13 -0
  150. package/src/types/IStreamingVolumeProperties.ts +14 -0
  151. package/src/types/IViewport.ts +149 -0
  152. package/src/types/IViewportId.ts +9 -0
  153. package/src/types/IVolume.ts +45 -0
  154. package/src/types/IVolumeInput.ts +36 -0
  155. package/src/types/IVolumeViewport.ts +141 -0
  156. package/src/types/ImageLoaderFn.ts +16 -0
  157. package/src/types/ImageSliceData.ts +6 -0
  158. package/src/types/Mat3.ts +16 -0
  159. package/src/types/Metadata.ts +39 -0
  160. package/src/types/OrientationVectors.ts +36 -0
  161. package/src/types/Plane.ts +6 -0
  162. package/src/types/Point2.ts +6 -0
  163. package/src/types/Point3.ts +6 -0
  164. package/src/types/Point4.ts +6 -0
  165. package/src/types/ScalingParameters.ts +27 -0
  166. package/src/types/StackViewportProperties.ts +25 -0
  167. package/src/types/TransformMatrix2D.ts +4 -0
  168. package/src/types/ViewportInputOptions.ts +21 -0
  169. package/src/types/ViewportPreset.ts +14 -0
  170. package/src/types/VolumeLoaderFn.ts +18 -0
  171. package/src/types/VolumeViewportProperties.ts +14 -0
  172. package/src/types/index.ts +157 -0
  173. package/src/types/voi.ts +15 -0
  174. package/src/utilities/actorCheck.ts +24 -0
  175. package/src/utilities/applyPreset.ts +132 -0
  176. package/src/utilities/calculateViewportsSpatialRegistration.ts +74 -0
  177. package/src/utilities/calibratedPixelSpacingMetadataProvider.ts +38 -0
  178. package/src/utilities/createFloat32SharedArray.ts +45 -0
  179. package/src/utilities/createInt16SharedArray.ts +43 -0
  180. package/src/utilities/createLinearRGBTransferFunction.ts +22 -0
  181. package/src/utilities/createSigmoidRGBTransferFunction.ts +63 -0
  182. package/src/utilities/createUInt16SharedArray.ts +43 -0
  183. package/src/utilities/createUint8SharedArray.ts +45 -0
  184. package/src/utilities/deepFreeze.ts +19 -0
  185. package/src/utilities/deepMerge.ts +81 -0
  186. package/src/utilities/getClosestImageId.ts +80 -0
  187. package/src/utilities/getClosestStackImageIndexForPoint.ts +116 -0
  188. package/src/utilities/getImageSliceDataForVolumeViewport.ts +61 -0
  189. package/src/utilities/getMinMax.ts +31 -0
  190. package/src/utilities/getRuntimeId.ts +54 -0
  191. package/src/utilities/getScalarDataType.ts +31 -0
  192. package/src/utilities/getScalingParameters.ts +35 -0
  193. package/src/utilities/getSliceRange.ts +86 -0
  194. package/src/utilities/getSpacingInNormalDirection.ts +44 -0
  195. package/src/utilities/getTargetVolumeAndSpacingInNormalDir.ts +126 -0
  196. package/src/utilities/getViewportImageCornersInWorld.ts +102 -0
  197. package/src/utilities/getViewportsWithImageURI.ts +46 -0
  198. package/src/utilities/getViewportsWithVolumeId.ts +38 -0
  199. package/src/utilities/getVoiFromSigmoidRGBTransferFunction.ts +23 -0
  200. package/src/utilities/getVolumeActorCorners.ts +24 -0
  201. package/src/utilities/getVolumeSliceRangeInfo.ts +52 -0
  202. package/src/utilities/getVolumeViewportScrollInfo.ts +32 -0
  203. package/src/utilities/getVolumeViewportsContainingSameVolumes.ts +58 -0
  204. package/src/utilities/hasNaNValues.ts +12 -0
  205. package/src/utilities/imageIdToURI.ts +10 -0
  206. package/src/utilities/imageToWorldCoords.ts +54 -0
  207. package/src/utilities/index.ts +100 -0
  208. package/src/utilities/indexWithinDimensions.ts +27 -0
  209. package/src/utilities/invertRgbTransferFunction.ts +36 -0
  210. package/src/utilities/isEqual.ts +27 -0
  211. package/src/utilities/isOpposite.ts +23 -0
  212. package/src/utilities/isTypedArray.ts +20 -0
  213. package/src/utilities/loadImageToCanvas.ts +80 -0
  214. package/src/utilities/planar.ts +91 -0
  215. package/src/utilities/renderToCanvas.ts +32 -0
  216. package/src/utilities/scaleRgbTransferFunction.ts +37 -0
  217. package/src/utilities/snapFocalPointToSlice.ts +78 -0
  218. package/src/utilities/spatialRegistrationMetadataProvider.ts +50 -0
  219. package/src/utilities/transformWorldToIndex.ts +16 -0
  220. package/src/utilities/triggerEvent.ts +38 -0
  221. package/src/utilities/uuidv4.ts +13 -0
  222. package/src/utilities/windowLevel.ts +39 -0
  223. package/src/utilities/worldToImageCoords.ts +64 -0
@@ -0,0 +1,227 @@
1
+ import {
2
+ VolumeActor,
3
+ IImageVolume,
4
+ VOIRange,
5
+ ScalingParameters,
6
+ } from '../../types';
7
+ import { loadAndCacheImage } from '../../loaders/imageLoader';
8
+ import * as metaData from '../../metaData';
9
+ import { getMinMax, windowLevel } from '../../utilities';
10
+ import { RequestType } from '../../enums';
11
+
12
+ const PRIORITY = 0;
13
+ const REQUEST_TYPE = RequestType.Prefetch;
14
+
15
+ /**
16
+ * It sets the default window level of an image volume based on the VOI.
17
+ * It first look for the VOI in the metadata and if it is not found, it
18
+ * loads the middle slice image (middle imageId) and based on its min
19
+ * and max pixel values, it calculates the VOI.
20
+ * Finally it sets the VOI on the volumeActor transferFunction
21
+ * @param volumeActor - The volume actor
22
+ * @param imageVolume - The image volume that we want to set the VOI for.
23
+ */
24
+ async function setDefaultVolumeVOI(
25
+ volumeActor: VolumeActor,
26
+ imageVolume: IImageVolume,
27
+ use16BitTexture: boolean
28
+ ): Promise<void> {
29
+ let voi = getVOIFromMetadata(imageVolume);
30
+
31
+ if (!voi) {
32
+ voi = await getVOIFromMinMax(imageVolume, use16BitTexture);
33
+ }
34
+
35
+ if (!voi || voi.lower === undefined || voi.upper === undefined) {
36
+ throw new Error(
37
+ 'Could not get VOI from metadata, nor from the min max of the image middle slice'
38
+ );
39
+ }
40
+
41
+ voi = handlePreScaledVolume(imageVolume, voi);
42
+ const { lower, upper } = voi;
43
+
44
+ volumeActor
45
+ .getProperty()
46
+ .getRGBTransferFunction(0)
47
+ .setMappingRange(lower, upper);
48
+ }
49
+
50
+ function handlePreScaledVolume(imageVolume: IImageVolume, voi: VOIRange) {
51
+ const imageIds = imageVolume.imageIds;
52
+ const imageIdIndex = Math.floor(imageIds.length / 2);
53
+ const imageId = imageIds[imageIdIndex];
54
+
55
+ const generalSeriesModule =
56
+ metaData.get('generalSeriesModule', imageId) || {};
57
+
58
+ /**
59
+ * If the volume is prescaled and the modality is PT Sometimes you get super high
60
+ * values at the peak and it skews the min/max so nothing useful is displayed
61
+ * Therefore, we follow the majority of other viewers and we set the min/max
62
+ * for the scaled PT to be 0, 5
63
+ */
64
+ if (generalSeriesModule.modality === 'PT' && imageVolume.isPrescaled) {
65
+ return {
66
+ lower: 0,
67
+ upper: 5,
68
+ };
69
+ }
70
+
71
+ return voi;
72
+ }
73
+
74
+ /**
75
+ * Get the VOI from the metadata of the middle slice of the image volume. It checks
76
+ * the metadata for the VOI and if it is not found, it returns null
77
+ *
78
+ * @param imageVolume - The image volume that we want to get the VOI from.
79
+ * @returns VOIRange with lower and upper values
80
+ */
81
+ function getVOIFromMetadata(imageVolume: IImageVolume): VOIRange {
82
+ const { imageIds } = imageVolume;
83
+
84
+ const imageIdIndex = Math.floor(imageIds.length / 2);
85
+ const imageId = imageIds[imageIdIndex];
86
+
87
+ const voiLutModule = metaData.get('voiLutModule', imageId);
88
+
89
+ if (voiLutModule && voiLutModule.windowWidth && voiLutModule.windowCenter) {
90
+ const { windowWidth, windowCenter } = voiLutModule;
91
+
92
+ const voi = {
93
+ windowWidth: Array.isArray(windowWidth) ? windowWidth[0] : windowWidth,
94
+ windowCenter: Array.isArray(windowCenter)
95
+ ? windowCenter[0]
96
+ : windowCenter,
97
+ };
98
+
99
+ const { lower, upper } = windowLevel.toLowHighRange(
100
+ Number(voi.windowWidth),
101
+ Number(voi.windowCenter)
102
+ );
103
+
104
+ return {
105
+ lower,
106
+ upper,
107
+ };
108
+ }
109
+ }
110
+
111
+ /**
112
+ * It loads the middle slice image (middle imageId) and based on its min
113
+ * and max pixel values, it calculates the VOI.
114
+ *
115
+ * @param imageVolume - The image volume that we want to get the VOI from.
116
+ * @returns The VOIRange with lower and upper values
117
+ */
118
+ async function getVOIFromMinMax(
119
+ imageVolume: IImageVolume,
120
+ use16BitTexture: boolean
121
+ ): Promise<VOIRange> {
122
+ const { imageIds } = imageVolume;
123
+ const scalarData = imageVolume.getScalarData();
124
+
125
+ // Get the middle image from the list of imageIds
126
+ const imageIdIndex = Math.floor(imageIds.length / 2);
127
+ const imageId = imageVolume.imageIds[imageIdIndex];
128
+ const generalSeriesModule =
129
+ metaData.get('generalSeriesModule', imageId) || {};
130
+ const { modality } = generalSeriesModule;
131
+ const modalityLutModule = metaData.get('modalityLutModule', imageId) || {};
132
+
133
+ const numImages = imageIds.length;
134
+ const bytesPerImage = scalarData.byteLength / numImages;
135
+ const voxelsPerImage = scalarData.length / numImages;
136
+ const bytePerPixel = scalarData.BYTES_PER_ELEMENT;
137
+
138
+ const scalingParameters: ScalingParameters = {
139
+ rescaleSlope: modalityLutModule.rescaleSlope,
140
+ rescaleIntercept: modalityLutModule.rescaleIntercept,
141
+ modality,
142
+ };
143
+
144
+ let scalingParametersToUse;
145
+ if (modality === 'PT') {
146
+ const suvFactor = metaData.get('scalingModule', imageId);
147
+
148
+ if (suvFactor) {
149
+ scalingParametersToUse = {
150
+ ...scalingParameters,
151
+ suvbw: suvFactor.suvbw,
152
+ };
153
+ }
154
+ }
155
+
156
+ const byteOffset = imageIdIndex * bytesPerImage;
157
+
158
+ const options = {
159
+ targetBuffer: {
160
+ type: use16BitTexture ? undefined : 'Float32Array',
161
+ },
162
+ priority: PRIORITY,
163
+ requestType: REQUEST_TYPE,
164
+ preScale: {
165
+ enabled: true,
166
+ scalingParameters: scalingParametersToUse,
167
+ },
168
+ };
169
+
170
+ // Loading the middle slice image for a volume has two scenarios, the first one is that
171
+ // uses the same volumeLoader which might not resolve to an image (since for performance
172
+ // reasons volumes' pixelData is set via offset and length on the volume arrayBuffer
173
+ // when each slice is loaded). The second scenario is that the image might not reach
174
+ // to the volumeLoader, and an already cached image (with Image object) is used
175
+ // instead. For the first scenario, we use the arrayBuffer of the volume to get the correct
176
+ // slice for the imageScalarData, and for the second scenario we use the getPixelData
177
+ // on the Cornerstone IImage object to get the pixel data.
178
+ const image = await loadAndCacheImage(imageId, options);
179
+
180
+ let imageScalarData;
181
+ if (!image) {
182
+ imageScalarData = _getImageScalarDataFromImageVolume(
183
+ imageVolume,
184
+ byteOffset,
185
+ bytePerPixel,
186
+ voxelsPerImage
187
+ );
188
+ } else {
189
+ imageScalarData = image.getPixelData();
190
+ }
191
+
192
+ // Get the min and max pixel values of the middle slice
193
+ const { min, max } = getMinMax(imageScalarData);
194
+
195
+ return {
196
+ lower: min,
197
+ upper: max,
198
+ };
199
+ }
200
+
201
+ function _getImageScalarDataFromImageVolume(
202
+ imageVolume,
203
+ byteOffset,
204
+ bytePerPixel,
205
+ voxelsPerImage
206
+ ) {
207
+ const { scalarData } = imageVolume;
208
+ const { volumeBuffer } = scalarData;
209
+ if (scalarData.BYTES_PER_ELEMENT !== bytePerPixel) {
210
+ byteOffset *= scalarData.BYTES_PER_ELEMENT / bytePerPixel;
211
+ }
212
+
213
+ const TypedArray = scalarData.constructor;
214
+ const imageScalarData = new TypedArray(voxelsPerImage);
215
+
216
+ const volumeBufferView = new TypedArray(
217
+ volumeBuffer,
218
+ byteOffset,
219
+ voxelsPerImage
220
+ );
221
+
222
+ imageScalarData.set(volumeBufferView);
223
+
224
+ return imageScalarData;
225
+ }
226
+
227
+ export default setDefaultVolumeVOI;
@@ -0,0 +1,52 @@
1
+ import BaseVolumeViewport from '../BaseVolumeViewport';
2
+ import type {
3
+ IVolumeInput,
4
+ IRenderingEngine,
5
+ IVolumeViewport,
6
+ } from '../../types';
7
+
8
+ /**
9
+ * Similar to {@link addVolumesToViewports} it adds volumes to viewports; however,
10
+ * this method will Set the volumes on the viewports which means that the previous
11
+ * volumes will be removed.
12
+ *
13
+ * @param renderingEngine - The rendering engine to use to get viewports from
14
+ * @param volumeInputs - Array of volume inputs including volumeId. Other properties
15
+ * such as visibility, callback, blendMode, slabThickness are optional
16
+ * @param viewportIds - Array of viewport IDs to add the volume to
17
+ * @param immediateRender - If true, the volumes will be rendered immediately
18
+ * @returns A promise that resolves when all volumes have been added
19
+ */
20
+ async function setVolumesForViewports(
21
+ renderingEngine: IRenderingEngine,
22
+ volumeInputs: Array<IVolumeInput>,
23
+ viewportIds: Array<string>,
24
+ immediateRender = false,
25
+ suppressEvents = false
26
+ ): Promise<void> {
27
+ // Check if all viewports are volumeViewports
28
+ viewportIds.forEach((viewportId) => {
29
+ const viewport = renderingEngine.getViewport(viewportId);
30
+
31
+ if (!viewport) {
32
+ throw new Error(`Viewport with Id ${viewportId} does not exist`);
33
+ }
34
+
35
+ // if not instance of BaseVolumeViewport, throw
36
+ if (!(viewport instanceof BaseVolumeViewport)) {
37
+ throw new Error('setVolumesForViewports only supports VolumeViewport and VolumeViewport3D');
38
+ }
39
+ });
40
+
41
+ const setVolumePromises = viewportIds.map(async (viewportId) => {
42
+ const viewport = renderingEngine.getViewport(viewportId) as IVolumeViewport;
43
+
44
+ await viewport.setVolumes(volumeInputs, immediateRender, suppressEvents);
45
+ });
46
+
47
+ await Promise.all(setVolumePromises);
48
+
49
+ return;
50
+ }
51
+
52
+ export default setVolumesForViewports;
@@ -0,0 +1,14 @@
1
+ // TODO -> Eventually we'll need to register to this list
2
+ import StackViewport from '../StackViewport';
3
+ import VolumeViewport from '../VolumeViewport';
4
+ import ViewportType from '../../enums/ViewportType';
5
+ import VolumeViewport3D from '../VolumeViewport3D';
6
+
7
+ const viewportTypeToViewportClass = {
8
+ [ViewportType.ORTHOGRAPHIC]: VolumeViewport,
9
+ [ViewportType.PERSPECTIVE]: VolumeViewport,
10
+ [ViewportType.STACK]: StackViewport,
11
+ [ViewportType.VOLUME_3D]: VolumeViewport3D,
12
+ };
13
+
14
+ export default viewportTypeToViewportClass;
@@ -0,0 +1,7 @@
1
+ import viewportTypeToViewportClass from './viewportTypeToViewportClass';
2
+
3
+ export default function viewportTypeUsesCustomRenderingPipeline(
4
+ viewportType: string
5
+ ) {
6
+ return viewportTypeToViewportClass[viewportType].useCustomRenderingPipeline;
7
+ }
@@ -0,0 +1,75 @@
1
+ import {
2
+ getImageSliceDataForVolumeViewport,
3
+ triggerEvent,
4
+ } from '../../utilities';
5
+ import { EventTypes } from '../../types';
6
+ import { Events } from '../../enums';
7
+ import { getRenderingEngine } from '../getRenderingEngine';
8
+ import BaseVolumeViewport from '../BaseVolumeViewport';
9
+
10
+ // Keeping track of previous imageIndex for each viewportId
11
+ type VolumeImageState = Record<string, number>;
12
+
13
+ const state: VolumeImageState = {};
14
+
15
+ export function resetVolumeNewImageState(viewportId: string): void {
16
+ if (state[viewportId] !== undefined) {
17
+ delete state[viewportId];
18
+ }
19
+ }
20
+
21
+ /**
22
+ * It captures the camera modified event and with the camera focal point and viewPlaneNomad
23
+ * it calculates the image index in the view direction. Finally it triggers
24
+ * a VOLUME_NEW_IMAGE event with the image index.
25
+ *
26
+ * @internal
27
+ *
28
+ * @param cameraEvent - The camera modified event
29
+ * @param viewportImageData - The image data of the viewport
30
+ */
31
+ function volumeNewImageEventDispatcher(
32
+ cameraEvent: EventTypes.CameraModifiedEvent
33
+ ): void {
34
+ const { renderingEngineId, viewportId } = cameraEvent.detail;
35
+ const renderingEngine = getRenderingEngine(renderingEngineId);
36
+ const viewport = renderingEngine.getViewport(viewportId);
37
+
38
+ if (!(viewport instanceof BaseVolumeViewport)) {
39
+ throw new Error(
40
+ `volumeNewImageEventDispatcher: viewport is not a BaseVolumeViewport`
41
+ );
42
+ }
43
+
44
+ if (state[viewport.id] === undefined) {
45
+ state[viewport.id] = 0;
46
+ }
47
+
48
+ const sliceData = getImageSliceDataForVolumeViewport(viewport);
49
+
50
+ if (!sliceData) {
51
+ console.warn(
52
+ `volumeNewImageEventDispatcher: sliceData is undefined for viewport ${viewport.id}`
53
+ );
54
+ return;
55
+ }
56
+
57
+ const { numberOfSlices, imageIndex } = sliceData;
58
+
59
+ if (state[viewport.id] === imageIndex) {
60
+ return;
61
+ }
62
+
63
+ state[viewport.id] = imageIndex;
64
+
65
+ const eventDetail: EventTypes.VolumeNewImageEventDetail = {
66
+ imageIndex,
67
+ viewportId,
68
+ renderingEngineId,
69
+ numberOfSlices,
70
+ };
71
+
72
+ triggerEvent(viewport.element, Events.VOLUME_NEW_IMAGE, eventDetail);
73
+ }
74
+
75
+ export default volumeNewImageEventDispatcher;
@@ -0,0 +1,23 @@
1
+ import RenderingEngine from './RenderingEngine';
2
+ import getRenderingEngine from './getRenderingEngine';
3
+ import VolumeViewport from './VolumeViewport';
4
+ import StackViewport from './StackViewport';
5
+ import VolumeViewport3D from './VolumeViewport3D';
6
+ import {
7
+ createVolumeActor,
8
+ createVolumeMapper,
9
+ getOrCreateCanvas,
10
+ } from './helpers';
11
+
12
+ export {
13
+ getRenderingEngine,
14
+ RenderingEngine,
15
+ VolumeViewport,
16
+ VolumeViewport3D,
17
+ createVolumeActor,
18
+ createVolumeMapper,
19
+ getOrCreateCanvas,
20
+ StackViewport,
21
+ };
22
+
23
+ export default RenderingEngine;
@@ -0,0 +1,43 @@
1
+ import type { IRenderingEngine } from '../types';
2
+
3
+ const cache = {};
4
+
5
+ const renderingEngineCache = {
6
+ /**
7
+ * Returns the `RenderingEngine` instance with the given `id`.
8
+ *
9
+ * @param id - The `id` of the `RenderingEngine` instance to fetch.
10
+ * @returns The `RenderingEngine` instance.
11
+ */
12
+ get: (id: string): IRenderingEngine => {
13
+ return cache[id];
14
+ },
15
+ /**
16
+ * Adds the `RenderingEngine` instance to the cache.
17
+ *
18
+ * @param re - The `RenderingEngine` to add.
19
+ */
20
+ set: (re: IRenderingEngine): void => {
21
+ const renderingEngineId = re.id;
22
+
23
+ cache[renderingEngineId] = re;
24
+ },
25
+ /**
26
+ * Deletes the `RenderingEngine` instance from the cache.
27
+ *
28
+ * @param id - The `id` of the `RenderingEngine` instance to delete.
29
+ * @returns True if the delete was successful.
30
+ */
31
+ delete: (id: string) => {
32
+ return delete cache[id];
33
+ },
34
+
35
+ getAll: (): Array<IRenderingEngine> => {
36
+ const renderingEngineIds = Object.keys(cache);
37
+ const renderingEngines = renderingEngineIds.map((id) => cache[id]);
38
+
39
+ return renderingEngines;
40
+ },
41
+ };
42
+
43
+ export default renderingEngineCache;
@@ -0,0 +1,11 @@
1
+ import vtkOffscreenMultiRenderWindow from './vtkOffscreenMultiRenderWindow';
2
+ import vtkSharedVolumeMapper from './vtkSharedVolumeMapper';
3
+ import vtkStreamingOpenGLTexture from './vtkStreamingOpenGLTexture';
4
+ import vtkSlabCamera from './vtkSlabCamera';
5
+
6
+ export {
7
+ vtkOffscreenMultiRenderWindow,
8
+ vtkSharedVolumeMapper,
9
+ vtkStreamingOpenGLTexture,
10
+ vtkSlabCamera,
11
+ };
@@ -0,0 +1,149 @@
1
+ import macro from '@kitware/vtk.js/macros';
2
+ import vtkStreamingOpenGLRenderWindow from './vtkStreamingOpenGLRenderWindow';
3
+ import vtkRenderer from '@kitware/vtk.js/Rendering/Core/Renderer';
4
+ import vtkRenderWindow from '@kitware/vtk.js/Rendering/Core/RenderWindow';
5
+ import vtkRenderWindowInteractor from '@kitware/vtk.js/Rendering/Core/RenderWindowInteractor';
6
+
7
+ // Load basic classes for vtk() factory
8
+ import '@kitware/vtk.js/Common/Core/Points';
9
+ import '@kitware/vtk.js/Common/Core/DataArray';
10
+ import '@kitware/vtk.js/Common/DataModel/PolyData';
11
+ import '@kitware/vtk.js/Rendering/Core/Actor';
12
+ import '@kitware/vtk.js/Rendering/Core/Mapper';
13
+
14
+ /**
15
+ * vtkOffscreenMultiRenderWindow - A class to deal with offscreen rendering with multiple renderers.
16
+ *
17
+ * This class is based on the vtkGenericRenderWindow with two key differences:
18
+ * - the vtkGenericRenderWindow had a renderer at the top level, with helpers to get it from the renderWindow.
19
+ * although you could add more renderers, this gave special status to the first viewport. Which was confusing.
20
+ * - When checking the size of the container element we no longer check the client size, as the canvas is offscreen.
21
+ * - We aren't using interactor styles, so don't set one up.
22
+ *
23
+ * Additionally this class has some new helpers to easily add/associate renderers to different viewportIds.
24
+ *
25
+ *
26
+ * @param {*} publicAPI The public API to extend
27
+ * @param {*} model The private model to extend.
28
+ */
29
+ function vtkOffscreenMultiRenderWindow(publicAPI, model) {
30
+ // Capture resize trigger method to remove from publicAPI
31
+ const invokeResize = publicAPI.invokeResize;
32
+ delete publicAPI.invokeResize;
33
+
34
+ // VTK renderWindow. No renderers set by default
35
+ model.renderWindow = vtkRenderWindow.newInstance();
36
+ model.rendererMap = {};
37
+
38
+ // OpenGLRenderWindow
39
+ model.openGLRenderWindow = vtkStreamingOpenGLRenderWindow.newInstance();
40
+ model.renderWindow.addView(model.openGLRenderWindow);
41
+
42
+ // Interactor
43
+ model.interactor = vtkRenderWindowInteractor.newInstance();
44
+ model.interactor.setView(model.openGLRenderWindow);
45
+ model.interactor.initialize();
46
+
47
+ publicAPI.addRenderer = ({ viewport, id, background }) => {
48
+ const renderer = vtkRenderer.newInstance({
49
+ viewport,
50
+ background: background || model.background,
51
+ });
52
+
53
+ model.renderWindow.addRenderer(renderer);
54
+ model.rendererMap[id] = renderer;
55
+ };
56
+
57
+ publicAPI.destroy = () => {
58
+ const rwi = model.renderWindow.getInteractor();
59
+ rwi.delete();
60
+ };
61
+
62
+ publicAPI.removeRenderer = (id) => {
63
+ const renderer = publicAPI.getRenderer(id);
64
+ model.renderWindow.removeRenderer(renderer);
65
+ renderer.delete();
66
+ delete model.rendererMap[id];
67
+ };
68
+
69
+ publicAPI.getRenderer = (id) => {
70
+ return model.rendererMap[id];
71
+ };
72
+
73
+ publicAPI.getRenderers = () => {
74
+ const { rendererMap } = model;
75
+
76
+ const renderers = Object.keys(rendererMap).map((id) => {
77
+ return { id, renderer: rendererMap[id] };
78
+ });
79
+
80
+ return renderers;
81
+ };
82
+
83
+ // Handle window resize
84
+ publicAPI.resize = () => {
85
+ if (model.container) {
86
+ // Don't use getBoundingClientRect() as in vtkGenericRenderWindow as is an offscreen canvas.
87
+ const { width, height } = model.container;
88
+
89
+ // Note: we do not scale by devicePixelRatio here because it has already
90
+ // been done when adding the offscreenCanvas viewport representations
91
+ model.openGLRenderWindow.setSize(Math.floor(width), Math.floor(height));
92
+ invokeResize();
93
+ model.renderWindow.render();
94
+ }
95
+ };
96
+
97
+ // Handle DOM container relocation
98
+ publicAPI.setContainer = (el) => {
99
+ // Switch container
100
+ model.container = el;
101
+ model.openGLRenderWindow.setContainer(model.container);
102
+ };
103
+
104
+ // Properly release GL context
105
+ publicAPI.delete = macro.chain(
106
+ publicAPI.setContainer,
107
+ publicAPI.destroy,
108
+ model.openGLRenderWindow.delete,
109
+ publicAPI.delete
110
+ );
111
+
112
+ publicAPI.resize();
113
+ }
114
+
115
+ // ----------------------------------------------------------------------------
116
+ // Object factory
117
+ // ----------------------------------------------------------------------------
118
+
119
+ const DEFAULT_VALUES = {
120
+ background: [0.0, 0.0, 0.0],
121
+ container: null,
122
+ };
123
+
124
+ // ----------------------------------------------------------------------------
125
+
126
+ export function extend(publicAPI, model, initialValues = {}) {
127
+ Object.assign(model, DEFAULT_VALUES, initialValues);
128
+
129
+ // Object methods
130
+ macro.obj(publicAPI, model);
131
+ macro.get(publicAPI, model, [
132
+ 'renderWindow',
133
+ 'openGLRenderWindow',
134
+ 'interactor',
135
+ 'container',
136
+ ]);
137
+ macro.event(publicAPI, model, 'resize');
138
+
139
+ // Object specific methods
140
+ vtkOffscreenMultiRenderWindow(publicAPI, model);
141
+ }
142
+
143
+ // ----------------------------------------------------------------------------
144
+
145
+ export const newInstance = macro.newInstance(extend);
146
+
147
+ // ----------------------------------------------------------------------------
148
+
149
+ export default { newInstance, extend };
@@ -0,0 +1,52 @@
1
+ import macro from '@kitware/vtk.js/macros';
2
+ import vtkVolumeMapper from '@kitware/vtk.js/Rendering/Core/VolumeMapper';
3
+
4
+ /**
5
+ * vtkSharedVolumeMapper - A derived class of the core vtkVolumeMapper class
6
+ * the scalar texture in as an argument. This is so we can share the same texture
7
+ * memory across different mappers/actors, so we don't duplicate memory usage.
8
+ *
9
+ *
10
+ *
11
+ * @param {*} publicAPI The public API to extend
12
+ * @param {*} model The private model to extend.
13
+ * @hidden
14
+ */
15
+ function vtkSharedVolumeMapper(publicAPI, model) {
16
+ model.classHierarchy.push('vtkSharedVolumeMapper');
17
+
18
+ const superDelete = publicAPI.delete;
19
+ publicAPI.delete = () => {
20
+ model.scalarTexture = null;
21
+ superDelete();
22
+ };
23
+ }
24
+
25
+ // ----------------------------------------------------------------------------
26
+ // Object factory
27
+ // ----------------------------------------------------------------------------
28
+
29
+ // ----------------------------------------------------------------------------
30
+
31
+ const DEFAULT_VALUES = {
32
+ scalarTexture: null,
33
+ };
34
+
35
+ export function extend(publicAPI, model, initialValues = {}) {
36
+ Object.assign(model, DEFAULT_VALUES, initialValues);
37
+
38
+ vtkVolumeMapper.extend(publicAPI, model, initialValues);
39
+
40
+ macro.setGet(publicAPI, model, ['scalarTexture']);
41
+
42
+ // Object methods
43
+ vtkSharedVolumeMapper(publicAPI, model);
44
+ }
45
+
46
+ // ----------------------------------------------------------------------------
47
+
48
+ export const newInstance = macro.newInstance(extend, 'vtkSharedVolumeMapper');
49
+
50
+ // ----------------------------------------------------------------------------
51
+
52
+ export default { newInstance, extend };