@kitware/vtk.js 34.8.0 → 34.9.1

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.
@@ -0,0 +1,120 @@
1
+ import { m as macro } from '../../macros2.js';
2
+ import vtkMouseCameraTrackballPanManipulator from './MouseCameraTrackballPanManipulator.js';
3
+ import { mat4, vec3 } from 'gl-matrix';
4
+
5
+ // ----------------------------------------------------------------------------
6
+ // Helper functions for center of rotation adjustment
7
+ // ----------------------------------------------------------------------------
8
+
9
+ /**
10
+ * Transforms a vector by the transformation delta between two matrices.
11
+ *
12
+ * @param {Object} tempObjects - Temporary matrices/vectors for computation
13
+ * @param {mat4} beforeMatrix - Matrix before transformation
14
+ * @param {mat4} afterMatrix - Matrix after transformation
15
+ * @param {Array} vector - Vector to transform [x, y, z]
16
+ * @returns {Array} Transformed vector [x, y, z]
17
+ */
18
+ function transformVectorByTransformation(tempObjects, beforeMatrix, afterMatrix, vector) {
19
+ const {
20
+ matrixA,
21
+ matrixB,
22
+ newCenter
23
+ } = tempObjects;
24
+
25
+ // The view matrix from vtk.js is row-major, but gl-matrix expects column-major.
26
+ // We need to transpose them before use.
27
+ mat4.transpose(matrixA, beforeMatrix);
28
+ mat4.transpose(matrixB, afterMatrix);
29
+ mat4.invert(matrixB, matrixB);
30
+
31
+ // Compute delta transformation matrix
32
+ mat4.multiply(matrixA, matrixB, matrixA);
33
+ vec3.transformMat4(newCenter, vector, matrixA);
34
+ return newCenter;
35
+ }
36
+
37
+ /**
38
+ * Computes the new center of rotation based on camera movement.
39
+ * When the camera moves (pan), the center of rotation should move
40
+ * by the same transformation.
41
+ *
42
+ * @param {Object} tempObjects - Temporary matrices/vectors for computation
43
+ * @param {Object} renderer - VTK renderer
44
+ * @param {mat4} beforeCameraMatrix - Camera view matrix before movement
45
+ * @param {Array} oldCenterOfRotation - Previous center of rotation [x, y, z]
46
+ * @returns {Array} New center of rotation [x, y, z]
47
+ */
48
+ function computeNewCenterOfRotation(tempObjects, renderer, beforeCameraMatrix, oldCenterOfRotation) {
49
+ const cam = renderer.getActiveCamera();
50
+ if (!cam || !beforeCameraMatrix) {
51
+ return oldCenterOfRotation;
52
+ }
53
+ const afterMatrixRowMajor = cam.getViewMatrix();
54
+ return transformVectorByTransformation(tempObjects, beforeCameraMatrix, afterMatrixRowMajor, oldCenterOfRotation);
55
+ }
56
+ function getCameraMatrix(renderer, tempMatrix) {
57
+ const cam = renderer.getActiveCamera();
58
+ if (cam) {
59
+ mat4.copy(tempMatrix, cam.getViewMatrix());
60
+ return tempMatrix;
61
+ }
62
+ return null;
63
+ }
64
+ function vtkMouseCameraTrackballPanManipulatorAutoCenter(publicAPI, model) {
65
+ model.classHierarchy.push('vtkMouseCameraTrackballPanManipulatorAutoCenter');
66
+ const tempCameraMatrix = mat4.create();
67
+ const tempComputeObjects = {
68
+ matrixA: mat4.create(),
69
+ matrixB: mat4.create(),
70
+ newCenter: vec3.create()
71
+ };
72
+ const superOnMouseMove = publicAPI.onMouseMove;
73
+ publicAPI.onMouseMove = (interactor, renderer, position) => {
74
+ if (!position) {
75
+ return;
76
+ }
77
+ const beforeCameraMatrix = getCameraMatrix(renderer, tempCameraMatrix);
78
+ superOnMouseMove(interactor, renderer, position);
79
+ if (beforeCameraMatrix && model.center) {
80
+ const newCenter = computeNewCenterOfRotation(tempComputeObjects, renderer, beforeCameraMatrix, model.center);
81
+ publicAPI.setCenter(newCenter);
82
+ const style = interactor.getInteractorStyle();
83
+ if (style && style.setCenterOfRotation) {
84
+ style.setCenterOfRotation(newCenter);
85
+ }
86
+ }
87
+ };
88
+ }
89
+
90
+ // ----------------------------------------------------------------------------
91
+ // Object factory
92
+ // ----------------------------------------------------------------------------
93
+
94
+ const DEFAULT_VALUES = {};
95
+
96
+ // ----------------------------------------------------------------------------
97
+
98
+ function extend(publicAPI, model) {
99
+ let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
100
+ Object.assign(model, DEFAULT_VALUES, initialValues);
101
+
102
+ // Inheritance
103
+ vtkMouseCameraTrackballPanManipulator.extend(publicAPI, model, initialValues);
104
+
105
+ // Object specific methods
106
+ vtkMouseCameraTrackballPanManipulatorAutoCenter(publicAPI, model);
107
+ }
108
+
109
+ // ----------------------------------------------------------------------------
110
+
111
+ const newInstance = macro.newInstance(extend, 'vtkMouseCameraTrackballPanManipulatorAutoCenter');
112
+
113
+ // ----------------------------------------------------------------------------
114
+
115
+ var index = {
116
+ newInstance,
117
+ extend
118
+ };
119
+
120
+ export { index as default, extend, newInstance };
@@ -1,7 +1,6 @@
1
1
  import { m as macro } from '../../macros2.js';
2
2
  import { MouseButton } from '../../Rendering/Core/RenderWindowInteractor/Constants.js';
3
3
  import vtkInteractorStyle from '../../Rendering/Core/InteractorStyle.js';
4
- import { mat4, vec3 } from 'gl-matrix';
5
4
 
6
5
  const {
7
6
  vtkDebugMacro
@@ -102,62 +101,6 @@ function dollyByFactor(interactor, renderer, factor) {
102
101
  renderer.updateLightsGeometryToFollowCamera();
103
102
  }
104
103
  }
105
- function getCameraMatrix(renderer, tempMatrix) {
106
- const cam = renderer.getActiveCamera();
107
- if (cam) {
108
- mat4.copy(tempMatrix, cam.getViewMatrix());
109
- return tempMatrix;
110
- }
111
- return null;
112
- }
113
-
114
- /**
115
- * Transforms a vector by the transformation delta between two matrices.
116
- *
117
- * @param {Object} tempObjects - Temporary matrices/vectors for computation
118
- * @param {mat4} beforeMatrix - Matrix before transformation
119
- * @param {mat4} afterMatrix - Matrix after transformation
120
- * @param {Array} vector - Vector to transform [x, y, z]
121
- * @returns {Array} Transformed vector [x, y, z]
122
- */
123
- function transformVectorByTransformation(tempObjects, beforeMatrix, afterMatrix, vector) {
124
- const {
125
- matrixA,
126
- matrixB,
127
- newCenter
128
- } = tempObjects;
129
-
130
- // The view matrix from vtk.js is row-major, but gl-matrix expects column-major.
131
- // We need to transpose them before use.
132
- mat4.transpose(matrixA, beforeMatrix);
133
- mat4.transpose(matrixB, afterMatrix);
134
- mat4.invert(matrixB, matrixB);
135
-
136
- // Compute delta transformation matrix
137
- mat4.multiply(matrixA, matrixB, matrixA);
138
- vec3.transformMat4(newCenter, vector, matrixA);
139
- return newCenter;
140
- }
141
-
142
- /**
143
- * Computes the new center of rotation based on camera movement.
144
- * When the camera moves (pan), the center of rotation should move
145
- * by the same transformation to maintain consistent rotation behavior.
146
- *
147
- * @param {Object} tempObjects - Temporary matrices/vectors for computation
148
- * @param {Object} renderer - VTK renderer
149
- * @param {mat4} beforeCameraMatrix - Camera view matrix before movement
150
- * @param {Array} oldCenterOfRotation - Previous center of rotation [x, y, z]
151
- * @returns {Array} New center of rotation [x, y, z]
152
- */
153
- function computeNewCenterOfRotation(tempObjects, renderer, beforeCameraMatrix, oldCenterOfRotation) {
154
- const cam = renderer.getActiveCamera();
155
- if (!cam || !beforeCameraMatrix) {
156
- return oldCenterOfRotation;
157
- }
158
- const afterMatrixRowMajor = cam.getViewMatrix();
159
- return transformVectorByTransformation(tempObjects, beforeCameraMatrix, afterMatrixRowMajor, oldCenterOfRotation);
160
- }
161
104
 
162
105
  // ----------------------------------------------------------------------------
163
106
  // Static API
@@ -176,14 +119,6 @@ const STATIC = {
176
119
  function vtkInteractorStyleManipulator(publicAPI, model) {
177
120
  // Set our className
178
121
  model.classHierarchy.push('vtkInteractorStyleManipulator');
179
-
180
- // Initialize temporary objects to reduce garbage collection
181
- const tempCameraMatrix = mat4.create();
182
- const tempComputeObjects = {
183
- matrixA: mat4.create(),
184
- matrixB: mat4.create(),
185
- newCenter: vec3.create()
186
- };
187
122
  model.currentVRManipulators = new Map();
188
123
  model.mouseManipulators = [];
189
124
  model.keyboardManipulators = [];
@@ -480,11 +415,7 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
480
415
  publicAPI.handleMouseMove = callData => {
481
416
  model.cachedMousePosition = callData.position;
482
417
  if (model.currentManipulator && model.currentManipulator.onMouseMove) {
483
- const renderer = model.getRenderer(callData);
484
- const beforeCameraMatrix = getCameraMatrix(renderer, tempCameraMatrix);
485
- model.currentManipulator.onMouseMove(model._interactor, renderer, callData.position);
486
- const newCenter = computeNewCenterOfRotation(tempComputeObjects, renderer, beforeCameraMatrix, model.centerOfRotation);
487
- publicAPI.setCenterOfRotation(newCenter);
418
+ model.currentManipulator.onMouseMove(model._interactor, model.getRenderer(callData), callData.position);
488
419
  publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
489
420
  }
490
421
  };
@@ -627,7 +558,6 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
627
558
  //----------------------------------------------------------------------------
628
559
  publicAPI.handlePan = callData => {
629
560
  const renderer = model.getRenderer(callData);
630
- const beforeCameraMatrix = getCameraMatrix(renderer, tempCameraMatrix);
631
561
  let count = model.gestureManipulators.length;
632
562
  let actionCount = 0;
633
563
  while (count--) {
@@ -638,8 +568,6 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
638
568
  }
639
569
  }
640
570
  if (actionCount) {
641
- const newCenter = computeNewCenterOfRotation(tempComputeObjects, renderer, beforeCameraMatrix, model.centerOfRotation);
642
- publicAPI.setCenterOfRotation(newCenter);
643
571
  publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
644
572
  }
645
573
  };
package/README.md CHANGED
@@ -48,8 +48,8 @@ In general VTK tries to be as portable as possible; the specific configurations
48
48
 
49
49
  vtk.js supports the following development environments:
50
50
 
51
- - Node 14+
52
- - NPM 7+
51
+ - Node 22+
52
+ - NPM 10+
53
53
 
54
54
  and we use [@babel/preset-env](https://www.npmjs.com/package/@babel/preset-env) with the [defaults](https://github.com/Kitware/vtk-js/blob/master/.browserslistrc) set of [browsers target](https://browserl.ist/?q=defaults).
55
55
  But when built from source this could be adjusted to support any browser as long they provide WebGL.
@@ -78,4 +78,3 @@ See [Copyright.txt][] for details.
78
78
  ## Contributing
79
79
 
80
80
  See [CONTRIBUTING.md](CONTRIBUTING.md) for instructions on how to contribute.
81
-
@@ -384,7 +384,7 @@ function addTriangle(layers, a, b, c, verticesArray, uvArray, colorArray, color)
384
384
  uvArray.push(uv[0], uv[1]);
385
385
  });
386
386
  if (colorArray && color) {
387
- for (let i = 0; i < 3; ++i) colorArray.push(color[0], color[1], color[2]);
387
+ for (let i = 0; i < 3; ++i) colorArray.push(color[0] * 255, color[1] * 255, color[2] * 255);
388
388
  }
389
389
  }
390
390
 
@@ -417,7 +417,7 @@ function addQuad(layers, a, b, c, d, verticesArray, uvArray, colorArray, color)
417
417
  uvArray.push(uvs[2][0], uvs[2][1]);
418
418
  uvArray.push(uvs[3][0], uvs[3][1]);
419
419
  if (colorArray && color) {
420
- for (let i = 0; i < 6; ++i) colorArray.push(color[0], color[1], color[2]);
420
+ for (let i = 0; i < 6; ++i) colorArray.push(color[0] * 255, color[1] * 255, color[2] * 255);
421
421
  }
422
422
  }
423
423
 
@@ -258,7 +258,7 @@ function vtkVectorText(publicAPI, model) {
258
258
  let letterIndex = 0;
259
259
  model.shapes.forEach(shape => {
260
260
  let color = null;
261
- if (typeof model.perLetterFaceColors === 'function') {
261
+ if (model.perLetterFaceColors) {
262
262
  color = model.perLetterFaceColors(letterIndex) || [1, 1, 1];
263
263
  }
264
264
  addShape(shape, offsetSize, color);
@@ -285,12 +285,12 @@ function vtkVectorText(publicAPI, model) {
285
285
  polyData.setPolys(cells);
286
286
 
287
287
  // Set points (vertices)
288
- polyData.getPoints().setData(new Float32Array(model.verticesArray), 3);
288
+ polyData.getPoints().setData(Float32Array.from(model.verticesArray), 3);
289
289
 
290
290
  // Set texture coordinates
291
291
  const da = vtkDataArray.newInstance({
292
292
  numberOfComponents: 2,
293
- values: new Float32Array(model.uvArray),
293
+ values: Float32Array.from(model.uvArray),
294
294
  name: 'TEXCOORD_0'
295
295
  });
296
296
  pointData.addArray(da);
@@ -300,7 +300,7 @@ function vtkVectorText(publicAPI, model) {
300
300
  if (model.colorArray && model.colorArray.length) {
301
301
  const ca = vtkDataArray.newInstance({
302
302
  numberOfComponents: 3,
303
- values: new Float32Array(model.colorArray),
303
+ values: Uint8Array.from(model.colorArray),
304
304
  name: 'Colors'
305
305
  });
306
306
  pointData.addArray(ca);
@@ -5,7 +5,9 @@ import vtkHardwareSelector from './HardwareSelector.js';
5
5
  import vtkProperty from '../Core/Property.js';
6
6
  import vtkOpenGLPolyDataMapper from './PolyDataMapper.js';
7
7
  import vtkShaderProgram from './ShaderProgram.js';
8
+ import { computeCoordShiftAndScale } from './CellArrayBufferObject/helpers.js';
8
9
  import { registerOverride } from './ViewNodeFactory.js';
10
+ import { primTypes } from './Helper.js';
9
11
 
10
12
  const {
11
13
  vtkErrorMacro
@@ -25,6 +27,17 @@ const StartEvent = {
25
27
  const EndEvent = {
26
28
  type: 'EndEvent'
27
29
  };
30
+ const MAT4_BYTE_SIZE = 64;
31
+ const MAT4_ELEMENT_COUNT = 16;
32
+ function applyShiftScaleToMat(mat, shift, scale) {
33
+ // the translation component of a 4x4 column-major matrix
34
+ mat[12] = (mat[12] - shift[0]) * scale[0];
35
+ mat[13] = (mat[13] - shift[1]) * scale[1];
36
+ mat[14] = (mat[14] - shift[2]) * scale[2];
37
+ mat[0] *= scale[0];
38
+ mat[5] *= scale[1];
39
+ mat[10] *= scale[2];
40
+ }
28
41
 
29
42
  // ----------------------------------------------------------------------------
30
43
  // vtkOpenGLSphereMapper methods
@@ -389,9 +402,15 @@ function vtkOpenGLGlyph3DMapper(publicAPI, model) {
389
402
  return false;
390
403
  };
391
404
  publicAPI.buildBufferObjects = (ren, actor) => {
405
+ const garray = model.renderable.getMatrixArray();
406
+ const pts = model.renderable.getInputData(0).getPoints();
407
+ const {
408
+ useShiftAndScale,
409
+ coordShift,
410
+ coordScale
411
+ } = computeCoordShiftAndScale(pts);
392
412
  if (model.hardwareSupport) {
393
413
  // update the buffer objects if needed
394
- const garray = model.renderable.getMatrixArray();
395
414
  const narray = model.renderable.getNormalArray();
396
415
  const carray = model.renderable.getColorArray();
397
416
  if (!model.matrixBuffer) {
@@ -404,6 +423,13 @@ function vtkOpenGLGlyph3DMapper(publicAPI, model) {
404
423
  model.pickBuffer = vtkBufferObject.newInstance();
405
424
  model.pickBuffer.setOpenGLRenderWindow(model._openGLRenderWindow);
406
425
  }
426
+ if (useShiftAndScale) {
427
+ const buf = garray.buffer;
428
+ for (let ptIdx = 0; ptIdx < garray.byteLength; ptIdx += MAT4_BYTE_SIZE) {
429
+ const mat = new Float32Array(buf, ptIdx, MAT4_ELEMENT_COUNT);
430
+ applyShiftScaleToMat(mat, coordShift, coordScale);
431
+ }
432
+ }
407
433
  if (model.renderable.getBuildTime().getMTime() > model.glyphBOBuildTime.getMTime()) {
408
434
  model.matrixBuffer.upload(garray, ObjectType.ARRAY_BUFFER);
409
435
  model.normalBuffer.upload(narray, ObjectType.ARRAY_BUFFER);
@@ -430,7 +456,15 @@ function vtkOpenGLGlyph3DMapper(publicAPI, model) {
430
456
  model.glyphBOBuildTime.modified();
431
457
  }
432
458
  }
433
- return superClass.buildBufferObjects(ren, actor);
459
+ superClass.buildBufferObjects(ren, actor);
460
+
461
+ // apply shift + scale to primitives AFTER vtkOpenGLPolyDataMapper.buildBufferObjects
462
+ // so that the Glyph3DMapper gets the last say in the shift + scale
463
+ if (useShiftAndScale) {
464
+ for (let i = primTypes.Start; i < primTypes.End; i++) {
465
+ model.primitives[i].getCABO().setCoordShiftAndScale(coordShift, coordScale);
466
+ }
467
+ }
434
468
  };
435
469
  }
436
470
 
@@ -186,12 +186,23 @@ function vtkWidgetManager(publicAPI, model) {
186
186
  model._interactor.render();
187
187
  }
188
188
  }
189
+ const deactivateAllWidgets = () => {
190
+ let wantRender = false;
191
+ for (let i = 0; i < model.widgets.length; i++) {
192
+ const w = model.widgets[i];
193
+ wantRender ||= !!w.getActiveState();
194
+ w.deactivateAllHandles();
195
+ }
196
+ if (wantRender) model._interactor.render();
197
+ };
189
198
  const handleEvent = async function (callData) {
190
199
  let fromTouchEvent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
191
200
  if (!model.isAnimating && model.pickingEnabled && callData.pokedRenderer === model._renderer) {
192
201
  const callID = Symbol('UpdateSelection');
193
202
  model._currentUpdateSelectionCallID = callID;
194
203
  await updateSelection(callData, fromTouchEvent, callID);
204
+ } else {
205
+ deactivateAllWidgets();
195
206
  }
196
207
  };
197
208
  function updateWidgetForRender(w) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitware/vtk.js",
3
- "version": "34.8.0",
3
+ "version": "34.9.1",
4
4
  "description": "Visualization Toolkit for the Web",
5
5
  "keywords": [
6
6
  "3d",
@@ -30,7 +30,7 @@
30
30
  "main": "./index.js",
31
31
  "module": "./index.js",
32
32
  "dependencies": {
33
- "@babel/runtime": "7.22.11",
33
+ "@babel/runtime": "^7.28.2",
34
34
  "@types/webxr": "^0.5.5",
35
35
  "commander": "9.2.0",
36
36
  "d3-scale": "4.0.2",
@@ -67,7 +67,7 @@
67
67
  "babel-loader": "8.2.5",
68
68
  "babel-plugin-istanbul": "6.1.1",
69
69
  "buffer": "6.0.3",
70
- "commitizen": "4.2.5",
70
+ "commitizen": "^4.3.1",
71
71
  "concurrently": "7.1.0",
72
72
  "copy-webpack-plugin": "10.2.4",
73
73
  "cross-env": "7.0.3",
@@ -125,7 +125,7 @@
125
125
  "webpack-bundle-analyzer": "4.5.0",
126
126
  "webpack-cli": "4.9.2",
127
127
  "webpack-dashboard": "3.3.7",
128
- "webpack-dev-server": "4.9.0",
128
+ "webpack-dev-server": "^5.2.2",
129
129
  "webpack-merge": "5.8.0",
130
130
  "webpack-notifier": "1.15.0",
131
131
  "wslink": "1.12.4",
@@ -238,5 +238,6 @@
238
238
  "publishConfig": {
239
239
  "access": "public"
240
240
  },
241
+ "type": "module",
241
242
  "types": "./index.d.ts"
242
243
  }