@kitware/vtk.js 32.12.2 → 32.14.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.
@@ -122,6 +122,87 @@ export interface vtkAbstractImageMapper extends vtkAbstractMapper3D {
122
122
  * @param customDisplayExtent
123
123
  */
124
124
  setCustomDisplayExtentFrom(customDisplayExtent: number[]): boolean;
125
+
126
+ /**
127
+ * Set the opacity texture width.
128
+ *
129
+ * The default width (1024) should be fine in most instances.
130
+ * Only set this property if your opacity function range width is
131
+ * larger than 1024.
132
+ *
133
+ * A reasonable max texture size would be either 2048 or 4096, as those
134
+ * widths are supported by the vast majority of devices. Any width larger
135
+ * than that will have issues with device support.
136
+ *
137
+ * Specifying a width that is less than or equal to 0 will use the largest
138
+ * possible texture width on the device. Use this with caution! The max texture
139
+ * width of one device may not be the same for another device.
140
+ *
141
+ * You can find more information about supported texture widths at the following link:
142
+ * https://web3dsurvey.com/webgl/parameters/MAX_TEXTURE_SIZE
143
+ *
144
+ * @param {Number} width the texture width (defaults to 1024)
145
+ */
146
+ setOpacityTextureWidth(width: number): boolean;
147
+
148
+ /**
149
+ * Get the opacity texture width.
150
+ */
151
+ getOpacityTextureWidth(): number;
152
+
153
+ /**
154
+ * Set the color texture width.
155
+ *
156
+ * The default width (1024) should be fine in most instances.
157
+ * Only set this property if your color transfer function range width is
158
+ * larger than 1024.
159
+ *
160
+ * A reasonable max texture size would be either 2048 or 4096, as those
161
+ * widths are supported by the vast majority of devices. Any width larger
162
+ * than that will have issues with device support.
163
+ *
164
+ * Specifying a width that is less than or equal to 0 will use the largest
165
+ * possible texture width on the device. Use this with caution! The max texture
166
+ * width of one device may not be the same for another device.
167
+ *
168
+ * You can find more information about supported texture widths at the following link:
169
+ * https://web3dsurvey.com/webgl/parameters/MAX_TEXTURE_SIZE
170
+ *
171
+ * @param {Number} width the texture width (defaults to 1024)
172
+ */
173
+ setColorTextureWidth(width: number): boolean;
174
+
175
+ /**
176
+ * Get the color texture width.
177
+ */
178
+ getColorTextureWidth(): number;
179
+
180
+ /**
181
+ * Set the label outline texture width.
182
+ *
183
+ * The default width (1024) should be fine in most instances.
184
+ * Only set this property if you have more than 1024 labels
185
+ * that you want to render with thickness.
186
+ *
187
+ * A reasonable max texture size would be either 2048 or 4096, as those
188
+ * widths are supported by the vast majority of devices. Any width larger
189
+ * than that will have issues with device support.
190
+ *
191
+ * Specifying a width that is less than or equal to 0 will use the largest
192
+ * possible texture width on the device. Use this with caution! The max texture
193
+ * width of one device may not be the same for another device.
194
+ *
195
+ * You can find more information about supported texture widths at the following link:
196
+ * https://web3dsurvey.com/webgl/parameters/MAX_TEXTURE_SIZE
197
+ *
198
+ * @param {Number} width the texture width (defaults to 1024)
199
+ */
200
+ setLabelOutlineTextureWidth(width: number): boolean;
201
+
202
+ /**
203
+ * Get the label outline texture width.
204
+ */
205
+ getLabelOutlineTextureWidth(): number;
125
206
  }
126
207
 
127
208
  /**
@@ -24,7 +24,10 @@ const DEFAULT_VALUES = {
24
24
  slice: 0,
25
25
  customDisplayExtent: [0, 0, 0, 0, 0, 0],
26
26
  useCustomExtents: false,
27
- backgroundColor: [0, 0, 0, 1]
27
+ backgroundColor: [0, 0, 0, 1],
28
+ colorTextureWidth: 1024,
29
+ opacityTextureWidth: 1024,
30
+ labelOutlineTextureWidth: 1024
28
31
  };
29
32
 
30
33
  // ----------------------------------------------------------------------------
@@ -35,7 +38,7 @@ function extend(publicAPI, model) {
35
38
 
36
39
  // Build VTK API
37
40
  vtkAbstractMapper3D.extend(publicAPI, model, initialValues);
38
- macro.setGet(publicAPI, model, ['slice', 'useCustomExtents']);
41
+ macro.setGet(publicAPI, model, ['slice', 'useCustomExtents', 'colorTextureWidth', 'opacityTextureWidth', 'labelOutlineTextureWidth']);
39
42
  macro.setGetArray(publicAPI, model, ['customDisplayExtent'], 6);
40
43
  macro.setGetArray(publicAPI, model, ['backgroundColor'], 4);
41
44
  vtkAbstractImageMapper(publicAPI, model);
@@ -54,6 +54,28 @@ export interface vtkActor2D extends vtkProp {
54
54
  */
55
55
  getMapper(): vtkMapper2D;
56
56
 
57
+ /**
58
+ * Set the layer number for this 2D actor.
59
+ * The scenegraph uses this layer number to sort actor 2D overlays/underlays on top of each other.
60
+ * The actor2D with the highest layer number is going to be rendered at the very front i.e. it is
61
+ * the top-most layer.
62
+ * If two actor2D instances share the same layer number, they are rendered in the order in which
63
+ * they were added to the renderer via `addActor` or `addActor2D`.
64
+ * By default, each actor2D has a layer number of 0.
65
+ */
66
+ setLayerNumber(layer: number): void;
67
+
68
+ /**
69
+ * Get the layer number for this 2D actor.
70
+ * The scenegraph uses this layer number to sort actor 2D overlays/underlays on top of each other.
71
+ * The actor2D with the highest layer number is going to be rendered at the very front i.e. it is
72
+ * the top-most layer.
73
+ * If two actor2D instances share the same layer number, they are rendered in the order in which
74
+ * they were added to the renderer via `addActor` or `addActor2D`.
75
+ * By default, each actor2D has a layer number of 0.
76
+ */
77
+ getLayerNumber(): number;
78
+
57
79
  /**
58
80
  *
59
81
  */
@@ -145,7 +145,7 @@ function extend(publicAPI, model) {
145
145
 
146
146
  // Build VTK API
147
147
  macro.set(publicAPI, model, ['property']);
148
- macro.setGet(publicAPI, model, ['mapper']);
148
+ macro.setGet(publicAPI, model, ['mapper', 'layerNumber']);
149
149
 
150
150
  // Object methods
151
151
  vtkActor2D(publicAPI, model);
@@ -219,7 +219,10 @@ function vtkCellPicker(publicAPI, model) {
219
219
 
220
220
  // calculate opacity table
221
221
  const numIComps = 1;
222
- const oWidth = 1024;
222
+ let oWidth = mapper.getOpacityTextureWidth();
223
+ if (oWidth <= 0) {
224
+ oWidth = 1024;
225
+ }
223
226
  const tmpTable = new Float32Array(oWidth);
224
227
  const opacityArray = new Float32Array(oWidth);
225
228
  let ofun;
@@ -46,10 +46,20 @@ function vtkViewport(publicAPI, model) {
46
46
  return allProps;
47
47
  }
48
48
  publicAPI.getViewPropsWithNestedProps = () => {
49
- const allPropsArray = [];
50
- for (let i = 0; i < model.props.length; i++) {
51
- gatherProps(model.props[i], allPropsArray);
49
+ let allPropsArray = [];
50
+ // Handle actor2D instances separately so that they can be overlayed and layered
51
+ const actors2D = publicAPI.getActors2D();
52
+ // Sort the actor2D list using its layer number
53
+ actors2D.sort((a, b) => a.getLayerNumber() - b.getLayerNumber());
54
+ // Filter out all the actor2D instances
55
+ const newPropList = model.props.filter(item => !actors2D.includes(item));
56
+ for (let i = 0; i < newPropList.length; i++) {
57
+ gatherProps(newPropList[i], allPropsArray);
52
58
  }
59
+ // Finally, add the actor2D props at the end of the list
60
+ // This works because, when traversing the render pass in vtkOpenGLRenderer, the children are
61
+ // traversed in the order that they are added to the list
62
+ allPropsArray = allPropsArray.concat(actors2D);
53
63
  return allPropsArray;
54
64
  };
55
65
  publicAPI.addActor2D = publicAPI.addViewProp;
@@ -318,6 +318,76 @@ export interface vtkVolumeMapper extends vtkAbstractMapper3D {
318
318
  *
319
319
  */
320
320
  update(): void;
321
+
322
+ /**
323
+ * Set the opacity texture width.
324
+ *
325
+ * The default width (1024) should be fine in most instances.
326
+ * Only set this property if your opacity function range width is
327
+ * larger than 1024.
328
+ *
329
+ * @param {Number} width the texture width (defaults to 1024)
330
+ */
331
+ setOpacityTextureWidth(width: number): boolean;
332
+
333
+ /**
334
+ * Get the opacity texture width.
335
+ */
336
+ getOpacityTextureWidth(): number;
337
+
338
+ /**
339
+ * Set the color texture width.
340
+ *
341
+ * The default width (1024) should be fine in most instances.
342
+ * Only set this property if your color transfer function range width is
343
+ * larger than 1024.
344
+ *
345
+ * A reasonable max texture size would be either 2048 or 4096, as those
346
+ * widths are supported by the vast majority of devices. Any width larger
347
+ * than that will have issues with device support.
348
+ *
349
+ * Specifying a width that is less than or equal to 0 will use the largest
350
+ * possible texture width on the device. Use this with caution! The max texture
351
+ * width of one device may not be the same for another device.
352
+ *
353
+ * You can find more information about supported texture widths at the following link:
354
+ * https://web3dsurvey.com/webgl/parameters/MAX_TEXTURE_SIZE
355
+ *
356
+ * @param {Number} width the texture width (defaults to 1024)
357
+ */
358
+ setColorTextureWidth(width: number): boolean;
359
+
360
+ /**
361
+ * Get the color texture width.
362
+ */
363
+ getColorTextureWidth(): number;
364
+
365
+ /**
366
+ * Set the label outline texture width.
367
+ *
368
+ * The default width (1024) should be fine in most instances.
369
+ * Only set this property if you have more than 1024 labels
370
+ * that you want to render with thickness.
371
+ *
372
+ * A reasonable max texture size would be either 2048 or 4096, as those
373
+ * widths are supported by the vast majority of devices. Any width larger
374
+ * than that will have issues with device support.
375
+ *
376
+ * Specifying a width that is less than or equal to 0 will use the largest
377
+ * possible texture width on the device. Use this with caution! The max texture
378
+ * width of one device may not be the same for another device.
379
+ *
380
+ * You can find more information about supported texture widths at the following link:
381
+ * https://web3dsurvey.com/webgl/parameters/MAX_TEXTURE_SIZE
382
+ *
383
+ * @param {Number} width the texture width (defaults to 1024)
384
+ */
385
+ setLabelOutlineTextureWidth(width: number): boolean;
386
+
387
+ /**
388
+ * Get the label outline texture width.
389
+ */
390
+ getLabelOutlineTextureWidth(): number;
321
391
  }
322
392
 
323
393
  /**
@@ -126,6 +126,9 @@ const defaultValues = initialValues => ({
126
126
  LAOKernelSize: 15,
127
127
  LAOKernelRadius: 7,
128
128
  updatedExtents: [],
129
+ colorTextureWidth: 1024,
130
+ opacityTextureWidth: 1024,
131
+ labelOutlineTextureWidth: 1024,
129
132
  ...initialValues
130
133
  });
131
134
 
@@ -135,7 +138,7 @@ function extend(publicAPI, model) {
135
138
  let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
136
139
  Object.assign(model, defaultValues(initialValues));
137
140
  vtkAbstractMapper3D.extend(publicAPI, model, initialValues);
138
- macro.setGet(publicAPI, model, ['sampleDistance', 'imageSampleDistance', 'maximumSamplesPerRay', 'autoAdjustSampleDistances', 'initialInteractionScale', 'interactionSampleDistanceFactor', 'blendMode', 'filterMode', 'preferSizeOverAccuracy', 'computeNormalFromOpacity', 'volumetricScatteringBlending', 'globalIlluminationReach', 'volumeShadowSamplingDistFactor', 'anisotropy', 'localAmbientOcclusion', 'LAOKernelSize', 'LAOKernelRadius', 'updatedExtents']);
141
+ macro.setGet(publicAPI, model, ['sampleDistance', 'imageSampleDistance', 'maximumSamplesPerRay', 'autoAdjustSampleDistances', 'initialInteractionScale', 'interactionSampleDistanceFactor', 'blendMode', 'filterMode', 'preferSizeOverAccuracy', 'computeNormalFromOpacity', 'volumetricScatteringBlending', 'globalIlluminationReach', 'volumeShadowSamplingDistFactor', 'anisotropy', 'localAmbientOcclusion', 'LAOKernelSize', 'LAOKernelRadius', 'updatedExtents', 'colorTextureWidth', 'opacityTextureWidth', 'labelOutlineTextureWidth']);
139
142
  macro.setGetArray(publicAPI, model, ['ipScalarRange'], 2);
140
143
  macro.event(publicAPI, model, 'lightingActivated');
141
144
 
@@ -195,7 +195,10 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
195
195
  const cachedColorEntry = model._openGLRenderWindow.getGraphicsResourceForObject(colorTransferFunc);
196
196
  const reBuildColorTexture = !cachedColorEntry?.oglObject?.getHandle() || cachedColorEntry?.hash !== colorTextureHash;
197
197
  if (reBuildColorTexture) {
198
- const cWidth = 1024;
198
+ let cWidth = model.renderable.getColorTextureWidth();
199
+ if (cWidth <= 0) {
200
+ cWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
201
+ }
199
202
  const cSize = cWidth * textureHeight * 3;
200
203
  const cTable = new Uint8ClampedArray(cSize);
201
204
  model.colorTexture = vtkOpenGLTexture.newInstance();
@@ -248,7 +251,10 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
248
251
  const cachedPwfEntry = model._openGLRenderWindow.getGraphicsResourceForObject(pwFunc);
249
252
  const reBuildPwf = !cachedPwfEntry?.oglObject?.getHandle() || cachedPwfEntry?.hash !== pwfTextureHash;
250
253
  if (reBuildPwf) {
251
- const pwfWidth = 1024;
254
+ let pwfWidth = model.renderable.getOpacityTextureWidth();
255
+ if (pwfWidth <= 0) {
256
+ pwfWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
257
+ }
252
258
  const pwfSize = pwfWidth * textureHeight;
253
259
  const pwfTable = new Uint8ClampedArray(pwfSize);
254
260
  model.pwfTexture = vtkOpenGLTexture.newInstance();
@@ -594,7 +594,10 @@ function vtkOpenGLImageMapper(publicAPI, model) {
594
594
  resizable: true
595
595
  });
596
596
  model.colorTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
597
- const cWidth = 1024;
597
+ let cWidth = model.renderable.getColorTextureWidth();
598
+ if (cWidth <= 0) {
599
+ cWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
600
+ }
598
601
  const cSize = cWidth * textureHeight * 3;
599
602
  const cTable = new Uint8ClampedArray(cSize);
600
603
  // set interpolation on the texture based on property setting
@@ -653,7 +656,10 @@ function vtkOpenGLImageMapper(publicAPI, model) {
653
656
  // rebuild opacity tfun?
654
657
  const reBuildPwf = !pwfTex?.oglObject?.getHandle() || pwfTex?.hash !== pwfunToString;
655
658
  if (reBuildPwf) {
656
- const pwfWidth = 1024;
659
+ let pwfWidth = model.renderable.getOpacityTextureWidth();
660
+ if (pwfWidth <= 0) {
661
+ pwfWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
662
+ }
657
663
  const pwfSize = pwfWidth * textureHeight;
658
664
  const pwfTable = new Uint8ClampedArray(pwfSize);
659
665
  model.pwfTexture = vtkOpenGLTexture.newInstance({
@@ -927,7 +933,10 @@ function vtkOpenGLImageMapper(publicAPI, model) {
927
933
  const toString = `${labelOutlineThicknessArray.join('-')}`;
928
934
  const reBuildL = !lTex?.oglObject?.getHandle() || lTex?.hash !== toString;
929
935
  if (reBuildL) {
930
- const lWidth = 1024;
936
+ let lWidth = model.renderable.getLabelOutlineTextureWidth();
937
+ if (lWidth <= 0) {
938
+ lWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
939
+ }
931
940
  const lHeight = 1;
932
941
  const lSize = lWidth * lHeight;
933
942
  const lTable = new Uint8Array(lSize);
@@ -223,7 +223,10 @@ function vtkOpenGLImageResliceMapper(publicAPI, model) {
223
223
  const cTex = model._openGLRenderWindow.getGraphicsResourceForObject(colorTransferFunc);
224
224
  const reBuildC = !cTex?.oglObject?.getHandle() || cTex?.hash !== toString;
225
225
  if (reBuildC) {
226
- const cWidth = 1024;
226
+ let cWidth = model.renderable.getColorTextureWidth();
227
+ if (cWidth <= 0) {
228
+ cWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
229
+ }
227
230
  const cSize = cWidth * textureHeight * 3;
228
231
  const cTable = new Uint8ClampedArray(cSize);
229
232
  model.colorTexture = vtkOpenGLTexture.newInstance();
@@ -277,7 +280,10 @@ function vtkOpenGLImageResliceMapper(publicAPI, model) {
277
280
  // rebuild opacity tfun?
278
281
  const reBuildPwf = !pwfTex?.oglObject?.getHandle() || pwfTex?.hash !== toString;
279
282
  if (reBuildPwf) {
280
- const pwfWidth = 1024;
283
+ let pwfWidth = model.renderable.getOpacityTextureWidth();
284
+ if (pwfWidth <= 0) {
285
+ pwfWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
286
+ }
281
287
  const pwfSize = pwfWidth * textureHeight;
282
288
  const pwfTable = new Uint8ClampedArray(pwfSize);
283
289
  model.pwfTexture = vtkOpenGLTexture.newInstance();
@@ -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
  };
@@ -1053,7 +1053,10 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
1053
1053
  model.opacityTexture = vtkOpenGLTexture.newInstance();
1054
1054
  model.opacityTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
1055
1055
  // rebuild opacity tfun?
1056
- const oWidth = 1024;
1056
+ let oWidth = model.renderable.getOpacityTextureWidth();
1057
+ if (oWidth <= 0) {
1058
+ oWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
1059
+ }
1057
1060
  const oSize = oWidth * 2 * numIComps;
1058
1061
  const ofTable = new Float32Array(oSize);
1059
1062
  const tmpTable = new Float32Array(oWidth);
@@ -1105,7 +1108,10 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
1105
1108
  if (reBuildC) {
1106
1109
  model.colorTexture = vtkOpenGLTexture.newInstance();
1107
1110
  model.colorTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
1108
- const cWidth = 1024;
1111
+ let cWidth = model.renderable.getColorTextureWidth();
1112
+ if (cWidth <= 0) {
1113
+ cWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
1114
+ }
1109
1115
  const cSize = cWidth * 2 * numIComps * 3;
1110
1116
  const cTable = new Uint8ClampedArray(cSize);
1111
1117
  const tmpTable = new Float32Array(cWidth * 3);
@@ -1239,7 +1245,10 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
1239
1245
  if (reBuildL) {
1240
1246
  model.labelOutlineThicknessTexture = vtkOpenGLTexture.newInstance();
1241
1247
  model.labelOutlineThicknessTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
1242
- const lWidth = 1024;
1248
+ let lWidth = model.renderable.getLabelOutlineTextureWidth();
1249
+ if (lWidth <= 0) {
1250
+ lWidth = model.context.getParameter(model.context.MAX_TEXTURE_SIZE);
1251
+ }
1243
1252
  const lHeight = 1;
1244
1253
  const lSize = lWidth * lHeight;
1245
1254
  const lTable = new Uint8Array(lSize);
@@ -105,13 +105,23 @@ function vtkViewNode(publicAPI, model) {
105
105
 
106
106
  // add missing nodes/children for the passed in renderables. This should
107
107
  // be called only in between prepareNodes and removeUnusedNodes
108
- publicAPI.addMissingNodes = dataObjs => {
108
+ publicAPI.addMissingNodes = function (dataObjs) {
109
+ let enforceOrder = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
109
110
  if (!dataObjs || !dataObjs.length) {
110
111
  return;
111
112
  }
112
113
  for (let index = 0; index < dataObjs.length; ++index) {
113
114
  const dobj = dataObjs[index];
114
- publicAPI.addMissingNode(dobj);
115
+ const node = publicAPI.addMissingNode(dobj);
116
+ if (enforceOrder && node !== undefined && model.children[index] !== node) {
117
+ for (let i = index + 1; i < model.children.length; ++i) {
118
+ if (model.children[i] === node) {
119
+ model.children.splice(i, 1);
120
+ model.children.splice(index, 0, node);
121
+ break;
122
+ }
123
+ }
124
+ }
115
125
  }
116
126
  };
117
127
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitware/vtk.js",
3
- "version": "32.12.2",
3
+ "version": "32.14.0",
4
4
  "description": "Visualization Toolkit for the Web",
5
5
  "keywords": [
6
6
  "3d",