@kitware/vtk.js 33.0.0-beta.3 → 33.0.0-beta.5

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 (41) hide show
  1. package/BREAKING_CHANGES.md +2 -0
  2. package/Common/Core/DataArray.d.ts +17 -0
  3. package/Common/Core/DataArray.js +36 -0
  4. package/Rendering/Core/AbstractImageMapper.d.ts +81 -0
  5. package/Rendering/Core/AbstractImageMapper.js +5 -2
  6. package/Rendering/Core/AbstractPicker.d.ts +13 -13
  7. package/Rendering/Core/AbstractPicker.js +1 -1
  8. package/Rendering/Core/Actor2D.d.ts +22 -0
  9. package/Rendering/Core/Actor2D.js +1 -1
  10. package/Rendering/Core/CellPicker.js +4 -1
  11. package/Rendering/Core/ImageCPRMapper.js +5 -4
  12. package/Rendering/Core/ImageProperty.d.ts +20 -1
  13. package/Rendering/Core/ImageProperty.js +7 -5
  14. package/Rendering/Core/ImageResliceMapper.d.ts +1 -2
  15. package/Rendering/Core/ImageResliceMapper.js +5 -4
  16. package/Rendering/Core/Viewport.js +13 -3
  17. package/Rendering/Core/VolumeMapper.d.ts +70 -0
  18. package/Rendering/Core/VolumeMapper.js +10 -5
  19. package/Rendering/Core/VolumeProperty.d.ts +20 -1
  20. package/Rendering/Core/VolumeProperty.js +7 -5
  21. package/Rendering/Misc/SynchronizableRenderWindow/BehaviorManager/CameraSynchronizer.js +2 -2
  22. package/Rendering/OpenGL/Framebuffer.js +7 -1
  23. package/Rendering/OpenGL/ImageCPRMapper.js +59 -7
  24. package/Rendering/OpenGL/ImageMapper.js +71 -9
  25. package/Rendering/OpenGL/ImageResliceMapper.js +60 -9
  26. package/Rendering/OpenGL/OrderIndependentTranslucentPass.js +20 -3
  27. package/Rendering/OpenGL/PolyDataMapper.js +7 -1
  28. package/Rendering/OpenGL/Renderer.js +1 -1
  29. package/Rendering/OpenGL/SurfaceLIC/LineIntegralConvolution2D/pingpong.js +7 -1
  30. package/Rendering/OpenGL/SurfaceLIC/SurfaceLICInterface.js +20 -3
  31. package/Rendering/OpenGL/Texture.d.ts +131 -62
  32. package/Rendering/OpenGL/Texture.js +287 -48
  33. package/Rendering/OpenGL/VolumeMapper.js +70 -10
  34. package/Rendering/SceneGraph/ViewNode.js +12 -2
  35. package/Rendering/WebXR/RenderWindowHelper.js +9 -0
  36. package/Widgets/Core/WidgetManager.d.ts +12 -1
  37. package/Widgets/Representations/WidgetRepresentation.d.ts +1 -7
  38. package/Widgets/Widgets3D/ResliceCursorWidget.d.ts +1 -8
  39. package/macros.js +1 -1
  40. package/macros2.js +7 -2
  41. package/package.json +11 -11
@@ -228,7 +228,7 @@ function vtkVolumeProperty(publicAPI, model) {
228
228
  // Object factory
229
229
  // ----------------------------------------------------------------------------
230
230
 
231
- const DEFAULT_VALUES = {
231
+ const defaultValues = initialValues => ({
232
232
  colorMixPreset: ColorMixPreset.DEFAULT,
233
233
  independentComponents: true,
234
234
  interpolationType: InterpolationType.FAST_LINEAR,
@@ -254,14 +254,16 @@ const DEFAULT_VALUES = {
254
254
  // local ambient occlusion
255
255
  localAmbientOcclusion: false,
256
256
  LAOKernelSize: 15,
257
- LAOKernelRadius: 7
258
- };
257
+ LAOKernelRadius: 7,
258
+ updatedExtents: [],
259
+ ...initialValues
260
+ });
259
261
 
260
262
  // ----------------------------------------------------------------------------
261
263
 
262
264
  function extend(publicAPI, model) {
263
265
  let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
264
- Object.assign(model, DEFAULT_VALUES, initialValues);
266
+ Object.assign(model, defaultValues(initialValues));
265
267
 
266
268
  // Build VTK API
267
269
  macro.obj(publicAPI, model);
@@ -287,7 +289,7 @@ function extend(publicAPI, model) {
287
289
  }
288
290
  macro.setGet(publicAPI, model, ['colorMixPreset', 'independentComponents', 'interpolationType', 'shade', 'ambient', 'diffuse', 'specular', 'specularPower', 'useLabelOutline', 'labelOutlineOpacity',
289
291
  // Properties moved from volume mapper
290
- 'filterMode', 'preferSizeOverAccuracy', 'computeNormalFromOpacity', 'volumetricScatteringBlending', 'globalIlluminationReach', 'anisotropy', 'localAmbientOcclusion', 'LAOKernelSize', 'LAOKernelRadius']);
292
+ 'filterMode', 'preferSizeOverAccuracy', 'computeNormalFromOpacity', 'volumetricScatteringBlending', 'globalIlluminationReach', 'anisotropy', 'localAmbientOcclusion', 'LAOKernelSize', 'LAOKernelRadius', 'updatedExtents']);
291
293
 
292
294
  // Property moved from volume mapper
293
295
  macro.setGetArray(publicAPI, model, ['ipScalarRange'], 2);
@@ -33,8 +33,8 @@ function vtkCameraSynchronizer(publicAPI, model) {
33
33
  }
34
34
 
35
35
  // Update listeners automatically
36
- model._srcRendererChanged = updateListeners;
37
- model._dstRendererChanged = updateListeners;
36
+ model._onSrcRendererChanged = updateListeners;
37
+ model._onDstRendererChanged = updateListeners;
38
38
  function updatePreviousValues(position, focalPoint, viewUp) {
39
39
  if (cameraState[0] !== position[0] || cameraState[1] !== position[1] || cameraState[2] !== position[2] || cameraState[3] !== focalPoint[0] || cameraState[4] !== focalPoint[1] || cameraState[5] !== focalPoint[2] || cameraState[6] !== viewUp[0] || cameraState[7] !== viewUp[1] || cameraState[8] !== viewUp[2]) {
40
40
  cameraState[0] = position[0];
@@ -162,7 +162,13 @@ function vtkFramebuffer(publicAPI, model) {
162
162
  texture.setOpenGLRenderWindow(model._openGLRenderWindow);
163
163
  texture.setMinificationFilter(Filter.LINEAR);
164
164
  texture.setMagnificationFilter(Filter.LINEAR);
165
- texture.create2DFromRaw(model.glFramebuffer.width, model.glFramebuffer.height, 4, VtkDataTypes.UNSIGNED_CHAR, null);
165
+ texture.create2DFromRaw({
166
+ width: model.glFramebuffer.width,
167
+ height: model.glFramebuffer.height,
168
+ numComps: 4,
169
+ dataType: VtkDataTypes.UNSIGNED_CHAR,
170
+ data: null
171
+ });
166
172
  publicAPI.setColorBuffer(texture);
167
173
 
168
174
  // for now do not count on having a depth buffer texture
@@ -147,6 +147,7 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
147
147
  publicAPI.buildBufferObjects = (ren, actor) => {
148
148
  const image = model.currentImageDataInput;
149
149
  const centerline = model.currentCenterlineInput;
150
+ const property = actor.getProperty();
150
151
 
151
152
  // Rebuild the volumeTexture if the data has changed
152
153
  const scalars = image?.getPointData()?.getScalars();
@@ -156,6 +157,8 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
156
157
  const cachedScalarsEntry = model._openGLRenderWindow.getGraphicsResourceForObject(scalars);
157
158
  const volumeTextureHash = getImageDataHash(image, scalars);
158
159
  const reBuildTex = !cachedScalarsEntry?.oglObject?.getHandle() || cachedScalarsEntry?.hash !== volumeTextureHash;
160
+ const updatedExtents = property.getUpdatedExtents();
161
+ const hasUpdatedExtents = !!updatedExtents.length;
159
162
  if (reBuildTex) {
160
163
  model.volumeTexture = vtkOpenGLTexture.newInstance();
161
164
  model.volumeTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
@@ -164,7 +167,13 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
164
167
  // Use norm16 for scalar texture if the extension is available
165
168
  model.volumeTexture.setOglNorm16Ext(model.context.getExtension('EXT_texture_norm16'));
166
169
  model.volumeTexture.resetFormatAndType();
167
- model.volumeTexture.create3DFilterableFromDataArray(dims[0], dims[1], dims[2], scalars, model.renderable.getPreferSizeOverAccuracy());
170
+ model.volumeTexture.create3DFilterableFromDataArray({
171
+ width: dims[0],
172
+ height: dims[1],
173
+ depth: dims[2],
174
+ dataArray: scalars,
175
+ preferSizeOverAccuracy: model.renderable.getPreferSizeOverAccuracy()
176
+ });
168
177
  model._openGLRenderWindow.setGraphicsResourceForObject(scalars, model.volumeTexture, volumeTextureHash);
169
178
  if (scalars !== model._scalars) {
170
179
  model._openGLRenderWindow.registerGraphicsResourceUser(scalars, publicAPI);
@@ -174,6 +183,19 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
174
183
  } else {
175
184
  model.volumeTexture = cachedScalarsEntry.oglObject;
176
185
  }
186
+ if (hasUpdatedExtents) {
187
+ // If hasUpdatedExtents, then the texture is partially updated.
188
+ // clear the array to acknowledge the update.
189
+ property.setUpdatedExtents([]);
190
+ const dims = image.getDimensions();
191
+ model.volumeTexture.create3DFilterableFromDataArray({
192
+ width: dims[0],
193
+ height: dims[1],
194
+ depth: dims[2],
195
+ dataArray: scalars,
196
+ updatedExtents
197
+ });
198
+ }
177
199
 
178
200
  // Rebuild the color texture if needed
179
201
  const numComp = scalars.getNumberOfComponents();
@@ -190,7 +212,10 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
190
212
  const cachedColorEntry = model._openGLRenderWindow.getGraphicsResourceForObject(firstColorTransferFunc);
191
213
  const reBuildColorTexture = !cachedColorEntry?.oglObject?.getHandle() || cachedColorEntry?.hash !== colorTextureHash;
192
214
  if (reBuildColorTexture) {
193
- const cWidth = 1024;
215
+ let cWidth = model.renderable.getColorTextureWidth();
216
+ if (cWidth <= 0) {
217
+ cWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
218
+ }
194
219
  const cSize = cWidth * textureHeight * 3;
195
220
  const cTable = new Uint8ClampedArray(cSize);
196
221
  model.colorTexture = vtkOpenGLTexture.newInstance();
@@ -213,7 +238,13 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
213
238
  }
214
239
  }
215
240
  model.colorTexture.resetFormatAndType();
216
- model.colorTexture.create2DFromRaw(cWidth, textureHeight, 3, VtkDataTypes.UNSIGNED_CHAR, cTable);
241
+ model.colorTexture.create2DFromRaw({
242
+ width: cWidth,
243
+ height: textureHeight,
244
+ numComps: 3,
245
+ dataType: VtkDataTypes.UNSIGNED_CHAR,
246
+ data: cTable
247
+ });
217
248
  } else {
218
249
  for (let i = 0; i < cWidth * 3; ++i) {
219
250
  cTable[i] = 255.0 * i / ((cWidth - 1) * 3);
@@ -221,7 +252,13 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
221
252
  cTable[i + 2] = 255.0 * i / ((cWidth - 1) * 3);
222
253
  }
223
254
  model.colorTexture.resetFormatAndType();
224
- model.colorTexture.create2DFromRaw(cWidth, 1, 3, VtkDataTypes.UNSIGNED_CHAR, cTable);
255
+ model.colorTexture.create2DFromRaw({
256
+ width: cWidth,
257
+ height: 1,
258
+ numComps: 3,
259
+ dataType: VtkDataTypes.UNSIGNED_CHAR,
260
+ data: cTable
261
+ });
225
262
  }
226
263
  if (firstColorTransferFunc) {
227
264
  model._openGLRenderWindow.setGraphicsResourceForObject(firstColorTransferFunc, model.colorTexture, colorTextureHash);
@@ -247,7 +284,10 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
247
284
  const cachedPwfEntry = model._openGLRenderWindow.getGraphicsResourceForObject(firstPwFunc);
248
285
  const reBuildPwf = !cachedPwfEntry?.oglObject?.getHandle() || cachedPwfEntry?.hash !== pwfTextureHash;
249
286
  if (reBuildPwf) {
250
- const pwfWidth = 1024;
287
+ let pwfWidth = model.renderable.getOpacityTextureWidth();
288
+ if (pwfWidth <= 0) {
289
+ pwfWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
290
+ }
251
291
  const pwfSize = pwfWidth * textureHeight;
252
292
  const pwfTable = new Uint8ClampedArray(pwfSize);
253
293
  model.pwfTexture = vtkOpenGLTexture.newInstance();
@@ -277,12 +317,24 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
277
317
  }
278
318
  }
279
319
  model.pwfTexture.resetFormatAndType();
280
- model.pwfTexture.create2DFromRaw(pwfWidth, textureHeight, 1, VtkDataTypes.FLOAT, pwfFloatTable);
320
+ model.pwfTexture.create2DFromRaw({
321
+ width: pwfWidth,
322
+ height: textureHeight,
323
+ numComps: 1,
324
+ dataType: VtkDataTypes.FLOAT,
325
+ data: pwfFloatTable
326
+ });
281
327
  } else {
282
328
  // default is opaque
283
329
  pwfTable.fill(255.0);
284
330
  model.pwfTexture.resetFormatAndType();
285
- model.pwfTexture.create2DFromRaw(pwfWidth, 1, 1, VtkDataTypes.UNSIGNED_CHAR, pwfTable);
331
+ model.pwfTexture.create2DFromRaw({
332
+ width: pwfWidth,
333
+ height: 1,
334
+ numComps: 1,
335
+ dataType: VtkDataTypes.UNSIGNED_CHAR,
336
+ data: pwfTable
337
+ });
286
338
  }
287
339
  if (firstPwFunc) {
288
340
  model._openGLRenderWindow.setGraphicsResourceForObject(firstPwFunc, model.pwfTexture, pwfTextureHash);
@@ -590,7 +590,10 @@ function vtkOpenGLImageMapper(publicAPI, model) {
590
590
  resizable: true
591
591
  });
592
592
  model.colorTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
593
- const cWidth = 1024;
593
+ let cWidth = model.renderable.getColorTextureWidth();
594
+ if (cWidth <= 0) {
595
+ cWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
596
+ }
594
597
  const cSize = cWidth * textureHeight * 3;
595
598
  const cTable = new Uint8ClampedArray(cSize);
596
599
  // set interpolation on the texture based on property setting
@@ -619,14 +622,26 @@ function vtkOpenGLImageMapper(publicAPI, model) {
619
622
  }
620
623
  }
621
624
  model.colorTexture.resetFormatAndType();
622
- model.colorTexture.create2DFromRaw(cWidth, textureHeight, 3, VtkDataTypes.UNSIGNED_CHAR, cTable);
625
+ model.colorTexture.create2DFromRaw({
626
+ width: cWidth,
627
+ height: textureHeight,
628
+ numComps: 3,
629
+ dataType: VtkDataTypes.UNSIGNED_CHAR,
630
+ data: cTable
631
+ });
623
632
  } else {
624
633
  for (let i = 0; i < cWidth * 3; ++i) {
625
634
  cTable[i] = 255.0 * i / ((cWidth - 1) * 3);
626
635
  cTable[i + 1] = 255.0 * i / ((cWidth - 1) * 3);
627
636
  cTable[i + 2] = 255.0 * i / ((cWidth - 1) * 3);
628
637
  }
629
- model.colorTexture.create2DFromRaw(cWidth, 1, 3, VtkDataTypes.UNSIGNED_CHAR, cTable);
638
+ model.colorTexture.create2DFromRaw({
639
+ width: cWidth,
640
+ height: 1,
641
+ numComps: 3,
642
+ dataType: VtkDataTypes.UNSIGNED_CHAR,
643
+ data: cTable
644
+ });
630
645
  }
631
646
  if (firstColorTransferFunc) {
632
647
  model._openGLRenderWindow.setGraphicsResourceForObject(firstColorTransferFunc, model.colorTexture, cfunToString);
@@ -653,7 +668,10 @@ function vtkOpenGLImageMapper(publicAPI, model) {
653
668
  // rebuild opacity tfun?
654
669
  const reBuildPwf = !pwfTex?.oglObject?.getHandle() || pwfTex?.hash !== pwfunToString;
655
670
  if (reBuildPwf) {
656
- const pwfWidth = 1024;
671
+ let pwfWidth = model.renderable.getOpacityTextureWidth();
672
+ if (pwfWidth <= 0) {
673
+ pwfWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
674
+ }
657
675
  const pwfSize = pwfWidth * textureHeight;
658
676
  const pwfTable = new Uint8ClampedArray(pwfSize);
659
677
  model.pwfTexture = vtkOpenGLTexture.newInstance({
@@ -693,11 +711,23 @@ function vtkOpenGLImageMapper(publicAPI, model) {
693
711
  }
694
712
  }
695
713
  model.pwfTexture.resetFormatAndType();
696
- model.pwfTexture.create2DFromRaw(pwfWidth, textureHeight, 1, VtkDataTypes.FLOAT, pwfFloatTable);
714
+ model.pwfTexture.create2DFromRaw({
715
+ width: pwfWidth,
716
+ height: textureHeight,
717
+ numComps: 1,
718
+ dataType: VtkDataTypes.FLOAT,
719
+ data: pwfFloatTable
720
+ });
697
721
  } else {
698
722
  // default is opaque
699
723
  pwfTable.fill(255.0);
700
- model.pwfTexture.create2DFromRaw(pwfWidth, 1, 1, VtkDataTypes.UNSIGNED_CHAR, pwfTable);
724
+ model.pwfTexture.create2DFromRaw({
725
+ width: pwfWidth,
726
+ height: 1,
727
+ numComps: 1,
728
+ dataType: VtkDataTypes.UNSIGNED_CHAR,
729
+ data: pwfTable
730
+ });
701
731
  }
702
732
  if (firstPwFunc) {
703
733
  model._openGLRenderWindow.setGraphicsResourceForObject(firstPwFunc, model.pwfTexture, pwfunToString);
@@ -863,10 +893,33 @@ function vtkOpenGLImageMapper(publicAPI, model) {
863
893
  vtkErrorMacro('Reformat slicing not yet supported.');
864
894
  }
865
895
 
896
+ /**
897
+ *
898
+ * Fetch the ranges of the source volume, `imgScalars`, and use them when
899
+ * creating the texture. Whilst the pre-calculated ranges may not be
900
+ * strictly correct for the slice, it is guaranteed to be within the
901
+ * source volume's range.
902
+ *
903
+ * There is a significant performance improvement by pre-setting the range
904
+ * of the scalars array particularly when scrolling through the source
905
+ * volume as there is no need to calculate the range of the slice scalar.
906
+ *
907
+ * @type{ import("../../../interfaces").vtkRange[] }
908
+ */
909
+ const ranges = imgScalars.getRanges();
910
+
866
911
  // Don't share this resource as `scalars` is created in this function
867
912
  // so it is impossible to share
868
913
  model.openGLTexture.resetFormatAndType();
869
- model.openGLTexture.create2DFilterableFromRaw(dims[0], dims[1], numComp, imgScalars.getDataType(), scalars, model.renderable.getPreferSizeOverAccuracy?.());
914
+ model.openGLTexture.create2DFilterableFromRaw({
915
+ width: dims[0],
916
+ height: dims[1],
917
+ numComps: numComp,
918
+ dataType: imgScalars.getDataType(),
919
+ data: scalars,
920
+ preferSizeOverAccuracy: !!model.renderable.getPreferSizeOverAccuracy?.(),
921
+ ranges
922
+ });
870
923
  model.openGLTexture.activate();
871
924
  model.openGLTexture.sendParameters();
872
925
  model.openGLTexture.deactivate();
@@ -912,7 +965,10 @@ function vtkOpenGLImageMapper(publicAPI, model) {
912
965
  const toString = `${labelOutlineThicknessArray.join('-')}`;
913
966
  const reBuildL = !lTex?.oglObject?.getHandle() || lTex?.hash !== toString;
914
967
  if (reBuildL) {
915
- const lWidth = 1024;
968
+ let lWidth = model.renderable.getLabelOutlineTextureWidth();
969
+ if (lWidth <= 0) {
970
+ lWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
971
+ }
916
972
  const lHeight = 1;
917
973
  const lSize = lWidth * lHeight;
918
974
  const lTable = new Uint8Array(lSize);
@@ -933,7 +989,13 @@ function vtkOpenGLImageMapper(publicAPI, model) {
933
989
  model.labelOutlineThicknessTexture.setMagnificationFilter(Filter.NEAREST);
934
990
 
935
991
  // Create a 2D texture (acting as 1D) from the raw data
936
- model.labelOutlineThicknessTexture.create2DFromRaw(lWidth, lHeight, 1, VtkDataTypes.UNSIGNED_CHAR, lTable);
992
+ model.labelOutlineThicknessTexture.create2DFromRaw({
993
+ width: lWidth,
994
+ height: lHeight,
995
+ numComps: 1,
996
+ dataType: VtkDataTypes.UNSIGNED_CHAR,
997
+ data: lTable
998
+ });
937
999
  if (labelOutlineThicknessArray) {
938
1000
  model._openGLRenderWindow.setGraphicsResourceForObject(labelOutlineThicknessArray, model.labelOutlineThicknessTexture, toString);
939
1001
  if (labelOutlineThicknessArray !== model._labelOutlineThicknessArray) {
@@ -245,6 +245,7 @@ function vtkOpenGLImageResliceMapper(publicAPI, model) {
245
245
  return model.VBOBuildTime.getMTime() < imageData.getMTime();
246
246
  }) || model.VBOBuildTime.getMTime() < model.resliceGeom.getMTime() || model.scalarTextures.length !== model.currentValidInputs.length || !model.scalarTextures.every(texture => !!texture?.getHandle()) || !model.colorTexture?.getHandle() || !model.pwfTexture?.getHandle();
247
247
  publicAPI.buildBufferObjects = (ren, actor) => {
248
+ const actorProperties = actor.getProperties();
248
249
  model.currentValidInputs.forEach((_ref3, component) => {
249
250
  let {
250
251
  imageData
@@ -254,7 +255,10 @@ function vtkOpenGLImageResliceMapper(publicAPI, model) {
254
255
  const tex = model._openGLRenderWindow.getGraphicsResourceForObject(scalars);
255
256
  const scalarsHash = getImageDataHash(imageData, scalars);
256
257
  const reBuildTex = !tex?.oglObject?.getHandle() || tex?.hash !== scalarsHash;
257
- if (reBuildTex) {
258
+ const actorProperty = actorProperties[component];
259
+ const updatedExtents = actorProperty.getUpdatedExtents();
260
+ const hasUpdatedExtents = !!updatedExtents.length;
261
+ if (reBuildTex && !hasUpdatedExtents) {
258
262
  const newScalarTexture = vtkOpenGLTexture.newInstance();
259
263
  newScalarTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
260
264
  // Build the textures
@@ -262,17 +266,34 @@ function vtkOpenGLImageResliceMapper(publicAPI, model) {
262
266
  // Use norm16 for scalar texture if the extension is available
263
267
  newScalarTexture.setOglNorm16Ext(model.context.getExtension('EXT_texture_norm16'));
264
268
  newScalarTexture.resetFormatAndType();
265
- newScalarTexture.create3DFilterableFromDataArray(dims[0], dims[1], dims[2], scalars);
269
+ newScalarTexture.create3DFilterableFromDataArray({
270
+ width: dims[0],
271
+ height: dims[1],
272
+ depth: dims[2],
273
+ dataArray: scalars
274
+ });
266
275
  model._openGLRenderWindow.setGraphicsResourceForObject(scalars, newScalarTexture, scalarsHash);
267
276
  model.scalarTextures[component] = newScalarTexture;
268
277
  } else {
269
278
  model.scalarTextures[component] = tex.oglObject;
270
279
  }
280
+ if (hasUpdatedExtents) {
281
+ // If hasUpdatedExtents, then the texture is partially updated.
282
+ // clear the array to acknowledge the update.
283
+ actorProperty.setUpdatedExtents([]);
284
+ const dims = imageData.getDimensions();
285
+ model.scalarTextures[component].create3DFilterableFromDataArray({
286
+ width: dims[0],
287
+ height: dims[1],
288
+ depth: dims[2],
289
+ dataArray: scalars,
290
+ updatedExtents
291
+ });
292
+ }
271
293
  replaceGraphicsResource(model._openGLRenderWindow, model._scalarTexturesCore[component], scalars);
272
294
  model._scalarTexturesCore[component] = scalars;
273
295
  });
274
296
  const firstValidInput = model.currentValidInputs[0];
275
- const actorProperties = actor.getProperties();
276
297
  const firstActorProperty = actorProperties[firstValidInput.inputIndex];
277
298
  const iComps = firstActorProperty.getIndependentComponents();
278
299
  const numIComps = iComps ? model.numberOfComponents : 1;
@@ -286,7 +307,10 @@ function vtkOpenGLImageResliceMapper(publicAPI, model) {
286
307
  const cTex = model._openGLRenderWindow.getGraphicsResourceForObject(firstColorTransferFunc);
287
308
  const reBuildC = !cTex?.oglObject?.getHandle() || cTex?.hash !== colorFuncHash;
288
309
  if (reBuildC) {
289
- const cWidth = 1024;
310
+ let cWidth = model.renderable.getColorTextureWidth();
311
+ if (cWidth <= 0) {
312
+ cWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
313
+ }
290
314
  const cSize = cWidth * textureHeight * 3;
291
315
  const cTable = new Uint8ClampedArray(cSize);
292
316
  const newColorTexture = vtkOpenGLTexture.newInstance();
@@ -309,7 +333,13 @@ function vtkOpenGLImageResliceMapper(publicAPI, model) {
309
333
  }
310
334
  }
311
335
  newColorTexture.resetFormatAndType();
312
- newColorTexture.create2DFromRaw(cWidth, textureHeight, 3, VtkDataTypes.UNSIGNED_CHAR, cTable);
336
+ newColorTexture.create2DFromRaw({
337
+ width: cWidth,
338
+ height: textureHeight,
339
+ numComps: 3,
340
+ dataType: VtkDataTypes.UNSIGNED_CHAR,
341
+ data: cTable
342
+ });
313
343
  } else {
314
344
  for (let column = 0; column < cWidth * 3; ++column) {
315
345
  const opacity = 255.0 * column / ((cWidth - 1) * 3);
@@ -321,7 +351,13 @@ function vtkOpenGLImageResliceMapper(publicAPI, model) {
321
351
  }
322
352
  }
323
353
  newColorTexture.resetFormatAndType();
324
- newColorTexture.create2DFromRaw(cWidth, 1, 3, VtkDataTypes.UNSIGNED_CHAR, cTable);
354
+ newColorTexture.create2DFromRaw({
355
+ width: cWidth,
356
+ height: 1,
357
+ numComps: 3,
358
+ dataType: VtkDataTypes.UNSIGNED_CHAR,
359
+ data: cTable
360
+ });
325
361
  }
326
362
  if (firstColorTransferFunc) {
327
363
  model._openGLRenderWindow.setGraphicsResourceForObject(firstColorTransferFunc, newColorTexture, colorFuncHash);
@@ -345,7 +381,10 @@ function vtkOpenGLImageResliceMapper(publicAPI, model) {
345
381
  const pwfTex = model._openGLRenderWindow.getGraphicsResourceForObject(firstPwFunc);
346
382
  const reBuildPwf = !pwfTex?.oglObject?.getHandle() || pwfTex?.hash !== opacityFuncHash;
347
383
  if (reBuildPwf) {
348
- const pwfWidth = 1024;
384
+ let pwfWidth = model.renderable.getOpacityTextureWidth();
385
+ if (pwfWidth <= 0) {
386
+ pwfWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
387
+ }
349
388
  const pwfSize = pwfWidth * textureHeight;
350
389
  const pwfTable = new Uint8ClampedArray(pwfSize);
351
390
  const newOpacityTexture = vtkOpenGLTexture.newInstance();
@@ -375,12 +414,24 @@ function vtkOpenGLImageResliceMapper(publicAPI, model) {
375
414
  }
376
415
  }
377
416
  newOpacityTexture.resetFormatAndType();
378
- newOpacityTexture.create2DFromRaw(pwfWidth, textureHeight, 1, VtkDataTypes.FLOAT, pwfFloatTable);
417
+ newOpacityTexture.create2DFromRaw({
418
+ width: pwfWidth,
419
+ height: textureHeight,
420
+ numComps: 1,
421
+ dataType: VtkDataTypes.FLOAT,
422
+ data: pwfFloatTable
423
+ });
379
424
  } else {
380
425
  // default is opaque
381
426
  pwfTable.fill(255.0);
382
427
  newOpacityTexture.resetFormatAndType();
383
- newOpacityTexture.create2DFromRaw(pwfWidth, textureHeight, 1, VtkDataTypes.UNSIGNED_CHAR, pwfTable);
428
+ newOpacityTexture.create2DFromRaw({
429
+ width: pwfWidth,
430
+ height: textureHeight,
431
+ numComps: 1,
432
+ dataType: VtkDataTypes.UNSIGNED_CHAR,
433
+ data: pwfTable
434
+ });
384
435
  }
385
436
  if (firstPwFunc) {
386
437
  model._openGLRenderWindow.setGraphicsResourceForObject(firstPwFunc, newOpacityTexture, opacityFuncHash);
@@ -91,16 +91,33 @@ function vtkOpenGLOrderIndependentTranslucentPass(publicAPI, model) {
91
91
  model.translucentRGBATexture.setFormat(gl.RGBA);
92
92
  model.translucentRGBATexture.setOpenGLDataType(gl.HALF_FLOAT);
93
93
  model.translucentRGBATexture.setOpenGLRenderWindow(viewNode);
94
- model.translucentRGBATexture.create2DFromRaw(size[0], size[1], 4, 'Float32Array', null);
94
+ model.translucentRGBATexture.create2DFromRaw({
95
+ width: size[0],
96
+ height: size[1],
97
+ numComps: 4,
98
+ dataType: 'Float32Array',
99
+ data: null
100
+ });
95
101
  model.translucentRTexture = vtkOpenGLTexture.newInstance();
96
102
  model.translucentRTexture.setInternalFormat(gl.R16F);
97
103
  model.translucentRTexture.setFormat(gl.RED);
98
104
  model.translucentRTexture.setOpenGLDataType(gl.HALF_FLOAT);
99
105
  model.translucentRTexture.setOpenGLRenderWindow(viewNode);
100
- model.translucentRTexture.create2DFromRaw(size[0], size[1], 1, 'Float32Array', null);
106
+ model.translucentRTexture.create2DFromRaw({
107
+ width: size[0],
108
+ height: size[1],
109
+ numComps: 1,
110
+ dataType: 'Float32Array',
111
+ data: null
112
+ });
101
113
  model.translucentZTexture = vtkOpenGLTexture.newInstance();
102
114
  model.translucentZTexture.setOpenGLRenderWindow(viewNode);
103
- model.translucentZTexture.createDepthFromRaw(size[0], size[1], 'Float32Array', null);
115
+ model.translucentZTexture.createDepthFromRaw({
116
+ width: size[0],
117
+ height: size[1],
118
+ dataType: 'Float32Array',
119
+ data: null
120
+ });
104
121
  model.framebuffer.setColorBuffer(model.translucentRGBATexture, 0);
105
122
  model.framebuffer.setColorBuffer(model.translucentRTexture, 1);
106
123
  model.framebuffer.setDepthBuffer(model.translucentZTexture);
@@ -1014,7 +1014,13 @@ function vtkOpenGLPolyDataMapper(publicAPI, model) {
1014
1014
  const input = model.renderable.getColorTextureMap();
1015
1015
  const ext = input.getExtent();
1016
1016
  const inScalars = input.getPointData().getScalars();
1017
- tex.create2DFromRaw(ext[1] - ext[0] + 1, ext[3] - ext[2] + 1, inScalars.getNumberOfComponents(), inScalars.getDataType(), inScalars.getData());
1017
+ tex.create2DFromRaw({
1018
+ width: ext[1] - ext[0] + 1,
1019
+ height: ext[3] - ext[2] + 1,
1020
+ numComps: inScalars.getNumberOfComponents(),
1021
+ dataType: inScalars.getDataType(),
1022
+ data: inScalars.getData()
1023
+ });
1018
1024
  tex.activate();
1019
1025
  tex.sendParameters();
1020
1026
  tex.deactivate();
@@ -24,7 +24,7 @@ function vtkOpenGLRenderer(publicAPI, model) {
24
24
  publicAPI.updateLights();
25
25
  publicAPI.prepareNodes();
26
26
  publicAPI.addMissingNode(model.renderable.getActiveCamera());
27
- publicAPI.addMissingNodes(model.renderable.getViewPropsWithNestedProps());
27
+ publicAPI.addMissingNodes(model.renderable.getViewPropsWithNestedProps(), true);
28
28
  publicAPI.removeUnusedNodes();
29
29
  }
30
30
  };
@@ -64,7 +64,13 @@ function allocateBuffer(openGLRenderWindow, _ref, filter, wrapping) {
64
64
  });
65
65
  texture.setOpenGLRenderWindow(openGLRenderWindow);
66
66
  texture.setInternalFormat(gl.RGBA32F);
67
- texture.create2DFromRaw(width, height, 4, 'Float32Array', null);
67
+ texture.create2DFromRaw({
68
+ width,
69
+ height,
70
+ numComps: 4,
71
+ dataType: 'Float32Array',
72
+ data: null
73
+ });
68
74
  texture.activate();
69
75
  texture.sendParameters();
70
76
  texture.deactivate();
@@ -206,7 +206,13 @@ function vtkOpenGLSurfaceLICInterface(publicAPI, model) {
206
206
  autoParameters: false
207
207
  });
208
208
  texture.setOpenGLRenderWindow(model._openGLRenderWindow);
209
- texture.create2DFromRaw(length, length, 4, 'Float32Array', values);
209
+ texture.create2DFromRaw({
210
+ width: length,
211
+ height: length,
212
+ numComps: 4,
213
+ dataType: 'Float32Array',
214
+ data: values
215
+ });
210
216
  texture.activate();
211
217
  texture.sendParameters();
212
218
  texture.deactivate();
@@ -255,7 +261,13 @@ function vtkOpenGLSurfaceLICInterface(publicAPI, model) {
255
261
  });
256
262
  texture.setOpenGLRenderWindow(openGLRenderWindow);
257
263
  texture.setInternalFormat(gl.RGBA32F);
258
- texture.create2DFromRaw(...model.size, 4, 'Float32Array', null);
264
+ texture.create2DFromRaw({
265
+ width: model.size[0],
266
+ height: model.size[1],
267
+ numComps: 4,
268
+ dataType: 'Float32Array',
269
+ data: null
270
+ });
259
271
  texture.activate();
260
272
  texture.sendParameters();
261
273
  texture.deactivate();
@@ -269,7 +281,12 @@ function vtkOpenGLSurfaceLICInterface(publicAPI, model) {
269
281
  autoParameters: false
270
282
  });
271
283
  texture.setOpenGLRenderWindow(openGLRenderWindow);
272
- texture.createDepthFromRaw(...model.size, 'Float32Array', null);
284
+ texture.createDepthFromRaw({
285
+ width: model.size[0],
286
+ height: model.size[1],
287
+ dataType: 'Float32Array',
288
+ data: null
289
+ });
273
290
  texture.activate();
274
291
  texture.sendParameters();
275
292
  texture.deactivate();