@kitware/vtk.js 28.4.0 → 28.5.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.
@@ -68,6 +68,21 @@ export interface vtkVolumeMapper extends vtkAbstractMapper {
68
68
  */
69
69
  getAutoAdjustSampleDistances(): boolean;
70
70
 
71
+ /**
72
+ * Get at what scale the quality is reduced when interacting for the first time with the volume
73
+ * It should should be set before any call to render for this volume
74
+ * The higher the scale is, the lower the quality of rendering is during interaction
75
+ * @default 16
76
+ */
77
+ getInitialInteractionScale(): number;
78
+
79
+ /**
80
+ * Get by how much the sample distance should be increased when interacting
81
+ * This feature is only implemented in the OpenGL volume mapper
82
+ * @default 4
83
+ */
84
+ getInteractionSampleDistanceFactor(): number;
85
+
71
86
  /**
72
87
  *
73
88
  */
@@ -188,6 +203,18 @@ export interface vtkVolumeMapper extends vtkAbstractMapper {
188
203
  */
189
204
  setAutoAdjustSampleDistances(autoAdjustSampleDistances: boolean): boolean;
190
205
 
206
+ /**
207
+ *
208
+ * @param initialInteractionScale
209
+ */
210
+ setInitialInteractionScale(initialInteractionScale: number): boolean;
211
+
212
+ /**
213
+ *
214
+ * @param interactionSampleDistanceFactor
215
+ */
216
+ setInteractionSampleDistanceFactor(interactionSampleDistanceFactor: number): boolean;
217
+
191
218
  /**
192
219
  * Set the normal computation to be dependent on the transfer function.
193
220
  * By default, the mapper relies on the scalar gradient for computing normals at sample locations
@@ -147,6 +147,8 @@ var DEFAULT_VALUES = {
147
147
  imageSampleDistance: 1.0,
148
148
  maximumSamplesPerRay: 1000,
149
149
  autoAdjustSampleDistances: true,
150
+ initialInteractionScale: 1.0,
151
+ interactionSampleDistanceFactor: 1.0,
150
152
  blendMode: BlendMode.COMPOSITE_BLEND,
151
153
  ipScalarRange: [-1000000.0, 1000000.0],
152
154
  filterMode: FilterMode.OFF,
@@ -169,7 +171,7 @@ function extend(publicAPI, model) {
169
171
  var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
170
172
  Object.assign(model, DEFAULT_VALUES, initialValues);
171
173
  vtkAbstractMapper.extend(publicAPI, model, initialValues);
172
- macro.setGet(publicAPI, model, ['sampleDistance', 'imageSampleDistance', 'maximumSamplesPerRay', 'autoAdjustSampleDistances', 'blendMode', 'filterMode', 'preferSizeOverAccuracy', 'computeNormalFromOpacity', 'volumetricScatteringBlending', 'globalIlluminationReach', 'volumeShadowSamplingDistFactor', 'anisotropy', 'localAmbientOcclusion', 'LAOKernelSize', 'LAOKernelRadius']);
174
+ macro.setGet(publicAPI, model, ['sampleDistance', 'imageSampleDistance', 'maximumSamplesPerRay', 'autoAdjustSampleDistances', 'initialInteractionScale', 'interactionSampleDistanceFactor', 'blendMode', 'filterMode', 'preferSizeOverAccuracy', 'computeNormalFromOpacity', 'volumetricScatteringBlending', 'globalIlluminationReach', 'volumeShadowSamplingDistFactor', 'anisotropy', 'localAmbientOcclusion', 'LAOKernelSize', 'LAOKernelRadius']);
173
175
  macro.setGetArray(publicAPI, model, ['ipScalarRange'], 2);
174
176
  macro.event(publicAPI, model, 'lightingActivated'); // Object methods
175
177
 
@@ -377,24 +377,6 @@ export interface vtkOpenGLRenderWindow extends vtkOpenGLRenderWindowBase {
377
377
  */
378
378
  getSize(): Vector2;
379
379
 
380
- /**
381
- *
382
- * @param {Vector2} size
383
- */
384
- setVrResolution(size: Vector2): void;
385
-
386
- /**
387
- *
388
- * @param {Number} x
389
- * @param {Number} y
390
- */
391
- setVrResolution(x: number, y: number): void;
392
-
393
- /**
394
- *
395
- */
396
- getVrResolution(): Vector2;
397
-
398
380
  /**
399
381
  * Scales the size of a browser CSS pixel to a rendered canvas pixel.
400
382
  * `const renderedPixelWidth = cssPixelWidth * apiRenderWindow.getComputedDevicePixelRatio()`
@@ -93,9 +93,7 @@ function vtkOpenGLRenderWindow(publicAPI, model) {
93
93
 
94
94
 
95
95
  model.canvas.addEventListener('webglcontextlost', _preventDefault, false);
96
- model.canvas.addEventListener('webglcontextrestored', publicAPI.restoreContext, false); // Cache the value here as calling it on each frame is expensive
97
-
98
- var isImmersiveVrSupported = navigator.xr !== undefined && navigator.xr.isSessionSupported('immersive-vr'); // Auto update style
96
+ model.canvas.addEventListener('webglcontextrestored', publicAPI.restoreContext, false); // Auto update style
99
97
 
100
98
  var previousSize = [0, 0];
101
99
 
@@ -233,12 +231,7 @@ function vtkOpenGLRenderWindow(publicAPI, model) {
233
231
  alpha: true,
234
232
  powerPreference: 'high-performance'
235
233
  };
236
- var result = null; // Do we have webxr support
237
-
238
- if (isImmersiveVrSupported) {
239
- publicAPI.invokeHaveVRDisplay();
240
- }
241
-
234
+ var result = null;
242
235
  var webgl2Supported = typeof WebGL2RenderingContext !== 'undefined';
243
236
  model.webgl2 = false;
244
237
 
@@ -988,8 +981,7 @@ function extend(publicAPI, model) {
988
981
  model.shaderCache.setOpenGLRenderWindow(publicAPI); // setup default forward pass rendering
989
982
 
990
983
  model.renderPasses[0] = vtkForwardPass.newInstance();
991
- macro.event(publicAPI, model, 'imageReady');
992
- macro.event(publicAPI, model, 'haveVRDisplay'); // Build VTK API
984
+ macro.event(publicAPI, model, 'imageReady'); // Build VTK API
993
985
 
994
986
  macro.get(publicAPI, model, ['shaderCache', 'textureUnitManager', 'webgl2', 'vrDisplay', 'useBackgroundImage', 'xrSupported', 'activeFramebuffer']);
995
987
  macro.setGet(publicAPI, model, ['initialized', 'context', 'canvas', 'renderPasses', 'notifyStartCaptureImage', 'defaultToWebgl2', 'cursor', 'useOffScreen']);
@@ -145,7 +145,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
145
145
  var spc = model.currentInput.getSpacing();
146
146
  var vsize = new Float64Array(3);
147
147
  vec3.set(vsize, (ext[1] - ext[0]) * spc[0], (ext[3] - ext[2]) * spc[1], (ext[5] - ext[4]) * spc[2]);
148
- var maxSamples = vec3.length(vsize) / model.renderable.getSampleDistance();
148
+ var maxSamples = vec3.length(vsize) / publicAPI.getCurrentSampleDistance(ren);
149
149
  FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::MaximumSamplesValue', "".concat(Math.ceil(maxSamples))).result; // set light complexity
150
150
 
151
151
  FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::LightComplexity', "#define vtkLightComplexity ".concat(model.lastLightComplexity)).result; // set shadow blending flag
@@ -297,7 +297,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
297
297
  var spc = model.currentInput.getSpacing();
298
298
  var vsize = new Float64Array(3);
299
299
  vec3.set(vsize, (ext[1] - ext[0]) * spc[0], (ext[3] - ext[2]) * spc[1], (ext[5] - ext[4]) * spc[2]);
300
- var maxSamples = vec3.length(vsize) / model.renderable.getSampleDistance();
300
+ var maxSamples = vec3.length(vsize) / publicAPI.getCurrentSampleDistance(ren);
301
301
  var state = {
302
302
  interpolationType: actor.getProperty().getInterpolationType(),
303
303
  useLabelOutline: actor.getProperty().getUseLabelOutline(),
@@ -372,7 +372,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
372
372
  }
373
373
 
374
374
  program.setUniformi('texture1', model.scalarTexture.getTextureUnit());
375
- program.setUniformf('sampleDistance', model.renderable.getSampleDistance());
375
+ program.setUniformf('sampleDistance', publicAPI.getCurrentSampleDistance(ren));
376
376
  var volInfo = model.scalarTexture.getVolumeInfo();
377
377
  var ipScalarRange = model.renderable.getIpScalarRange();
378
378
  var minVals = [];
@@ -467,7 +467,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
467
467
  mat4.multiply(model.idxToView, model.modelToView, i2wmat4);
468
468
  mat3.multiply(model.idxNormalMatrix, keyMats.normalMatrix, actMats.normalMatrix);
469
469
  mat3.multiply(model.idxNormalMatrix, model.idxNormalMatrix, model.currentInput.getDirectionByReference());
470
- var maxSamples = vec3.length(vsize) / model.renderable.getSampleDistance();
470
+ var maxSamples = vec3.length(vsize) / publicAPI.getCurrentSampleDistance(ren);
471
471
 
472
472
  if (maxSamples > model.renderable.getMaximumSamplesPerRay()) {
473
473
  vtkWarningMacro("The number of steps required ".concat(Math.ceil(maxSamples), " is larger than the\n specified maximum number of steps ").concat(model.renderable.getMaximumSamplesPerRay(), ".\n Please either change the\n volumeMapper sampleDistance or its maximum number of samples."));
@@ -817,8 +817,25 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
817
817
  return [lowerLeftU, lowerLeftV];
818
818
  };
819
819
 
820
+ publicAPI.getCurrentSampleDistance = function (ren) {
821
+ var rwi = ren.getVTKWindow().getInteractor();
822
+ var baseSampleDistance = model.renderable.getSampleDistance();
823
+
824
+ if (rwi.isAnimating()) {
825
+ var factor = model.renderable.getInteractionSampleDistanceFactor();
826
+ return baseSampleDistance * factor;
827
+ }
828
+
829
+ return baseSampleDistance;
830
+ };
831
+
820
832
  publicAPI.renderPieceStart = function (ren, actor) {
821
833
  var rwi = ren.getVTKWindow().getInteractor();
834
+
835
+ if (!model._lastScale) {
836
+ model._lastScale = model.renderable.getInitialInteractionScale();
837
+ }
838
+
822
839
  model._useSmallViewport = false;
823
840
 
824
841
  if (rwi.isAnimating() && model._lastScale > 1.5) {
@@ -849,18 +866,16 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
849
866
  } else {
850
867
  model._lastScale = model.renderable.getImageSampleDistance() * model.renderable.getImageSampleDistance();
851
868
  }
852
-
853
- var size = model._openGLRenderWindow.getFramebufferSize();
854
-
855
- model._smallViewportWidth = Math.ceil(size[0] / Math.sqrt(model._lastScale));
856
- model._smallViewportHeight = Math.ceil(size[1] / Math.sqrt(model._lastScale));
857
869
  });
858
870
  } // use/create/resize framebuffer if needed
859
871
 
860
872
 
861
873
  if (model._useSmallViewport) {
862
- var size = model._openGLRenderWindow.getFramebufferSize(); // adjust viewportSize to always be at most the dest fo size
874
+ var size = model._openGLRenderWindow.getFramebufferSize();
863
875
 
876
+ var scaleFactor = 1 / Math.sqrt(model._lastScale);
877
+ model._smallViewportWidth = Math.ceil(scaleFactor * size[0]);
878
+ model._smallViewportHeight = Math.ceil(scaleFactor * size[1]); // adjust viewportSize to always be at most the dest fo size
864
879
 
865
880
  if (model._smallViewportHeight > size[1]) {
866
881
  model._smallViewportHeight = size[1];
@@ -1063,7 +1078,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
1063
1078
 
1064
1079
  for (var c = 0; c < numIComps; ++c) {
1065
1080
  var ofun = vprop.getScalarOpacity(c);
1066
- var opacityFactor = model.renderable.getSampleDistance() / vprop.getScalarOpacityUnitDistance(c);
1081
+ var opacityFactor = publicAPI.getCurrentSampleDistance(ren) / vprop.getScalarOpacityUnitDistance(c);
1067
1082
  var oRange = ofun.getRange();
1068
1083
  ofun.getTable(oRange[0], oRange[1], oWidth, tmpTable, 1); // adjust for sample distance etc
1069
1084
 
@@ -1251,8 +1266,7 @@ function extend(publicAPI, model) {
1251
1266
  model.idxNormalMatrix = mat3.identity(new Float64Array(9));
1252
1267
  model.modelToView = mat4.identity(new Float64Array(16));
1253
1268
  model.projectionToView = mat4.identity(new Float64Array(16));
1254
- model.projectionToWorld = mat4.identity(new Float64Array(16));
1255
- model._lastScale = 1.0; // Build VTK API
1269
+ model.projectionToWorld = mat4.identity(new Float64Array(16)); // Build VTK API
1256
1270
 
1257
1271
  setGet(publicAPI, model, ['context']); // Object methods
1258
1272
 
@@ -187,15 +187,16 @@ function vtkWebGPUVolumePass(publicAPI, model) {
187
187
  }, publicAPI.delete);
188
188
 
189
189
  publicAPI.computeTiming = function (viewNode) {
190
- model._useSmallViewport = false;
191
190
  var rwi = viewNode.getRenderable().getInteractor();
192
191
 
193
- if (rwi.isAnimating() && model._lastScale > 1.5) {
194
- if (!model._smallViewportHeight) {
195
- model._smallViewportWidth = Math.ceil(viewNode.getCanvas().width / Math.sqrt(model._lastScale));
196
- model._smallViewportHeight = Math.ceil(viewNode.getCanvas().height / Math.sqrt(model._lastScale));
197
- }
192
+ if (model._lastScale == null) {
193
+ var firstMapper = model.volumes[0].getRenderable().getMapper();
194
+ model._lastScale = firstMapper.getInitialInteractionScale() || 1.0;
195
+ }
198
196
 
197
+ model._useSmallViewport = false;
198
+
199
+ if (rwi.isAnimating() && model._lastScale > 1.5) {
199
200
  model._useSmallViewport = true;
200
201
  }
201
202
 
@@ -222,9 +223,6 @@ function vtkWebGPUVolumePass(publicAPI, model) {
222
223
 
223
224
  if (model._lastScale < 1.5) {
224
225
  model._lastScale = 1.5;
225
- } else {
226
- model._smallViewportWidth = Math.ceil(viewNode.getCanvas().width / Math.sqrt(model._lastScale));
227
- model._smallViewportHeight = Math.ceil(viewNode.getCanvas().height / Math.sqrt(model._lastScale));
228
226
  }
229
227
  });
230
228
  }
@@ -240,6 +238,10 @@ function vtkWebGPUVolumePass(publicAPI, model) {
240
238
  var height = model._colorTextureView.getTexture().getHeight();
241
239
 
242
240
  if (model._useSmallViewport) {
241
+ var canvas = viewNode.getCanvas();
242
+ var scaleFactor = 1 / Math.sqrt(model._lastScale);
243
+ model._smallViewportWidth = Math.ceil(scaleFactor * canvas.width);
244
+ model._smallViewportHeight = Math.ceil(scaleFactor * canvas.height);
243
245
  width = model._smallViewportWidth;
244
246
  height = model._smallViewportHeight;
245
247
  }
@@ -655,7 +657,6 @@ function extend(publicAPI, model) {
655
657
  Object.assign(model, DEFAULT_VALUES, initialValues); // Build VTK API
656
658
 
657
659
  vtkRenderPass.extend(publicAPI, model, initialValues);
658
- model._lastScale = 2.0;
659
660
  model._mapper = vtkWebGPUSimpleMapper.newInstance();
660
661
 
661
662
  model._mapper.setFragmentShaderTemplate(DepthBoundsFS);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitware/vtk.js",
3
- "version": "28.4.0",
3
+ "version": "28.5.0",
4
4
  "description": "Visualization Toolkit for the Web",
5
5
  "keywords": [
6
6
  "3d",