@kitware/vtk.js 32.10.0 → 32.11.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.
@@ -83,6 +83,23 @@ export interface vtkDataArray extends vtkObject {
83
83
  */
84
84
  setRange(rangeValue: vtkRange, componentIndex: number): Range;
85
85
 
86
+ /**
87
+ * Returns an array of the ranges for each component of the DataArray.
88
+ * Defaults to computing all the ranges if they aren't already computed.
89
+ *
90
+ * If the number of components is greater than 1, the last element in the
91
+ * ranges array is the min,max magnitude of the dataset. This is the same as
92
+ * calling `getRange(-1)`.
93
+ *
94
+ * Passing `getRanges(false)` will return a clone of the ranges that have
95
+ * already been computed. This is useful when you want to avoid recomputing
96
+ * the ranges, which can be expensive.
97
+ *
98
+ * @param {boolean} [computeRanges] (default: true)
99
+ * @returns {vtkRange[]}
100
+ */
101
+ getRanges(computeRanges: boolean): vtkRange[];
102
+
86
103
  /**
87
104
  * Set the given tuple at the given index.
88
105
  * @param {Number} idx
@@ -268,6 +268,35 @@ function vtkDataArray(publicAPI, model) {
268
268
  model.rangeTuple[1] = range.max;
269
269
  return model.rangeTuple;
270
270
  };
271
+ publicAPI.getRanges = function () {
272
+ let computeRanges = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
273
+ if (!computeRanges) {
274
+ return structuredClone(model.ranges);
275
+ }
276
+ /** @type {import('../../../interfaces').vtkRange[]} */
277
+ const ranges = [];
278
+ for (let i = 0; i < model.numberOfComponents; i++) {
279
+ const [min, max] = publicAPI.getRange(i);
280
+ /** @type {import('../../../interfaces').vtkRange} */
281
+ const range = {
282
+ min,
283
+ max
284
+ };
285
+ ranges.push(range);
286
+ }
287
+ // where the number of components is greater than 1, the last element in
288
+ // the range array is the min,max magnitude of the entire dataset.
289
+ if (model.numberOfComponents > 1) {
290
+ const [min, max] = publicAPI.getRange(-1);
291
+ /** @type {import('../../../interfaces').vtkRange} */
292
+ const range = {
293
+ min,
294
+ max
295
+ };
296
+ ranges.push(range);
297
+ }
298
+ return ranges;
299
+ };
271
300
  publicAPI.setTuple = (idx, tuple) => {
272
301
  const offset = idx * model.numberOfComponents;
273
302
  for (let i = 0; i < model.numberOfComponents; i++) {
@@ -426,12 +455,19 @@ function vtkDataArray(publicAPI, model) {
426
455
  }
427
456
  return sortedObj;
428
457
  };
458
+
459
+ /**
460
+ * @param {import("./index").vtkDataArray} other
461
+ */
429
462
  publicAPI.deepCopy = other => {
430
463
  // Retain current dataType and array reference before shallowCopy call.
431
464
  const currentType = publicAPI.getDataType();
432
465
  const currentArray = model.values;
433
466
  publicAPI.shallowCopy(other);
434
467
 
468
+ // set the ranges
469
+ model.ranges = structuredClone(other.getRanges());
470
+
435
471
  // Avoid array reallocation if size already sufficient
436
472
  // and dataTypes match.
437
473
  if (currentArray?.length >= other.getNumberOfValues() && currentType === other.getDataType()) {
@@ -863,10 +863,25 @@ function vtkOpenGLImageMapper(publicAPI, model) {
863
863
  vtkErrorMacro('Reformat slicing not yet supported.');
864
864
  }
865
865
 
866
+ /**
867
+ *
868
+ * Fetch the ranges of the source volume, `imgScalars`, and use them when
869
+ * creating the texture. Whilst the pre-calculated ranges may not be
870
+ * strictly correct for the slice, it is guaranteed to be within the
871
+ * source volume's range.
872
+ *
873
+ * There is a significant performance improvement by pre-setting the range
874
+ * of the scalars array particularly when scrolling through the source
875
+ * volume as there is no need to calculate the range of the slice scalar.
876
+ *
877
+ * @type{ import("../../../interfaces").vtkRange[] }
878
+ */
879
+ const ranges = imgScalars.getRanges();
880
+
866
881
  // Don't share this resource as `scalars` is created in this function
867
882
  // so it is impossible to share
868
883
  model.openGLTexture.resetFormatAndType();
869
- model.openGLTexture.create2DFilterableFromRaw(dims[0], dims[1], numComp, imgScalars.getDataType(), scalars, model.renderable.getPreferSizeOverAccuracy?.());
884
+ model.openGLTexture.create2DFilterableFromRaw(dims[0], dims[1], numComp, imgScalars.getDataType(), scalars, model.renderable.getPreferSizeOverAccuracy?.(), ranges);
870
885
  model.openGLTexture.activate();
871
886
  model.openGLTexture.sendParameters();
872
887
  model.openGLTexture.deactivate();
@@ -3,7 +3,7 @@ import vtkOpenGLRenderWindow from './RenderWindow';
3
3
  import { Nullable } from './../../types';
4
4
  import { VtkDataTypes } from './../../Common/Core/DataArray';
5
5
  import { vtkViewNode } from './../SceneGraph/ViewNode';
6
- import { vtkObject } from './../../interfaces';
6
+ import { vtkObject, vtkRange } from './../../interfaces';
7
7
 
8
8
  /**
9
9
  * Initial values for creating a new instance of vtkOpenGLTexture.
@@ -244,7 +244,8 @@ export interface vtkOpenGLTexture extends vtkViewNode {
244
244
  * @param numComps The number of components in the texture.
245
245
  * @param dataType The data type of the texture.
246
246
  * @param data The raw data for the texture.
247
- * @param preferSizeOverAccuracy Whether to prefer texture size over accuracy.
247
+ * @param [preferSizeOverAccuracy=false] Whether to prefer texture size over accuracy. Defaults to false.
248
+ * @param [ranges] The precomputed ranges of the data (optional). Provided to prevent computation of the data ranges.
248
249
  * @returns {boolean} True if the texture was successfully created, false otherwise.
249
250
  */
250
251
  create2DFilterableFromRaw(
@@ -253,7 +254,8 @@ export interface vtkOpenGLTexture extends vtkViewNode {
253
254
  numComps: number,
254
255
  dataType: VtkDataTypes,
255
256
  data: any,
256
- preferSizeOverAccuracy: boolean
257
+ preferSizeOverAccuracy?: boolean,
258
+ ranges?: vtkRange[]
257
259
  ): boolean;
258
260
 
259
261
  /**
@@ -299,7 +301,10 @@ export interface vtkOpenGLTexture extends vtkViewNode {
299
301
  * @param dataType The data type of the texture.
300
302
  * @param values The raw data for the texture.
301
303
  * @param preferSizeOverAccuracy Whether to prefer texture size over accuracy.
302
- * @returns {boolean} True if the texture was successfully created, false otherwise.
304
+ * @param [ranges] The precomputed ranges of the data (optional). Provided to
305
+ * prevent computation of the data ranges.
306
+ * @returns {boolean} True if the texture was successfully created, false
307
+ * otherwise.
303
308
  */
304
309
  create3DFilterableFromRaw(
305
310
  width: number,
@@ -308,7 +313,8 @@ export interface vtkOpenGLTexture extends vtkViewNode {
308
313
  numComps: number,
309
314
  dataType: VtkDataTypes,
310
315
  values: any,
311
- preferSizeOverAccuracy: boolean
316
+ preferSizeOverAccuracy: boolean,
317
+ ranges?: vtkRange[]
312
318
  ): boolean;
313
319
 
314
320
  /**
@@ -986,10 +986,12 @@ function vtkOpenGLTexture(publicAPI, model) {
986
986
  }
987
987
  publicAPI.create2DFilterableFromRaw = function (width, height, numberOfComponents, dataType, values) {
988
988
  let preferSizeOverAccuracy = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
989
+ let ranges = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : undefined;
989
990
  return publicAPI.create2DFilterableFromDataArray(width, height, vtkDataArray.newInstance({
990
991
  numberOfComponents,
991
992
  dataType,
992
- values
993
+ values,
994
+ ranges
993
995
  }), preferSizeOverAccuracy);
994
996
  };
995
997
  publicAPI.create2DFilterableFromDataArray = function (width, height, dataArray) {
@@ -1129,10 +1131,12 @@ function vtkOpenGLTexture(publicAPI, model) {
1129
1131
  // Prefer create3DFilterableFromDataArray to enable caching of min and max values
1130
1132
  publicAPI.create3DFilterableFromRaw = function (width, height, depth, numberOfComponents, dataType, values) {
1131
1133
  let preferSizeOverAccuracy = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false;
1134
+ let ranges = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : undefined;
1132
1135
  return publicAPI.create3DFilterableFromDataArray(width, height, depth, vtkDataArray.newInstance({
1133
1136
  numberOfComponents,
1134
1137
  dataType,
1135
- values
1138
+ values,
1139
+ ranges
1136
1140
  }), preferSizeOverAccuracy);
1137
1141
  };
1138
1142
 
@@ -140,6 +140,15 @@ function vtkWebXRRenderWindowHelper(publicAPI, model) {
140
140
  model.renderWindow.getRenderable().getInteractor().returnFromXRAnimation();
141
141
  const gl = model.renderWindow.get3DContext();
142
142
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
143
+
144
+ // Remove controllers ray
145
+ const ren = model.renderWindow.getRenderable().getRenderers()[0];
146
+ model.xrSession.inputSources.forEach(inputSource => {
147
+ if (model.inputSourceToRay[inputSource.handedness]) {
148
+ ren.removeActor(model.inputSourceToRay[inputSource.handedness].actor);
149
+ model.inputSourceToRay[inputSource.handedness].visible = false;
150
+ }
151
+ });
143
152
  await model.xrSession.end().catch(error => {
144
153
  if (!(error instanceof DOMException)) {
145
154
  throw error;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitware/vtk.js",
3
- "version": "32.10.0",
3
+ "version": "32.11.0",
4
4
  "description": "Visualization Toolkit for the Web",
5
5
  "keywords": [
6
6
  "3d",