@kitware/vtk.js 28.11.1 → 28.12.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.
@@ -12,6 +12,7 @@ const {
12
12
  // ----------------------------------------------------------------------------
13
13
  // Global methods
14
14
  // ----------------------------------------------------------------------------
15
+ const EPSILON = 1e-6;
15
16
 
16
17
  // Original source from https://www.npmjs.com/package/compute-range
17
18
  // Modified to accept type arrays
@@ -305,6 +306,24 @@ function vtkDataArray(publicAPI, model) {
305
306
  const idx = model.size / model.numberOfComponents;
306
307
  return publicAPI.insertTuples(idx, tuples);
307
308
  };
309
+ publicAPI.findTuple = function (tuple) {
310
+ let precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : EPSILON;
311
+ for (let i = 0; i < model.size; i += model.numberOfComponents) {
312
+ if (Math.abs(tuple[0] - model.values[i]) <= precision) {
313
+ let match = true;
314
+ for (let j = 1; j < model.numberOfComponents; ++j) {
315
+ if (Math.abs(tuple[j] - model.values[i + j]) > precision) {
316
+ match = false;
317
+ break;
318
+ }
319
+ }
320
+ if (match) {
321
+ return i / model.numberOfComponents;
322
+ }
323
+ }
324
+ }
325
+ return -1;
326
+ };
308
327
  publicAPI.getTuple = function (idx) {
309
328
  let tupleToFill = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
310
329
  const numberOfComponents = model.numberOfComponents || 1;
@@ -1,96 +1,105 @@
1
- import vtkDataArray from './DataArray';
2
- import { Bounds, TypedArray } from './../../types';
3
-
4
- /**
5
- *
6
- */
7
- export interface IPointsInitialValues {
8
- empty?: boolean;
9
- numberOfComponents?: number;
10
- bounds?: Bounds;
11
- }
12
-
13
- export interface vtkPoints extends vtkDataArray {
14
-
15
- /**
16
- * Trigger the computation of bounds
17
- */
18
- computeBounds(): Bounds;
19
-
20
- /**
21
- * Get the bounds for this mapper as [xmin, xmax, ymin, ymax,zmin, zmax].
22
- * @return {Bounds} The bounds for the mapper.
23
- */
24
- getBounds(): Bounds;
25
-
26
- /**
27
- * Get the coordinate of a point.
28
- * @param {Number} idx The index of point.
29
- * @param {Number[]|TypedArray} [tupleToFill] (default [])
30
- * @returns {Number[]|TypedArray}
31
- */
32
- getPoint(idx: number, tupleToFill?: number[]|TypedArray): number[]|TypedArray;
33
-
34
- /**
35
- * Get the number of points for this object can hold.
36
- */
37
- getNumberOfPoints(): number;
38
-
39
- /**
40
- * Set the number of points for this object to hold.
41
- *
42
- * ```js
43
- * points.getData()[0] = x;
44
- * points.getData()[1] = y;
45
- * points.getData()[2] = z;
46
- * ```
47
- *
48
- * @param {Number} nbPoints
49
- * @param {Number} [dimension]
50
- */
51
- setNumberOfPoints(nbPoints: number, dimension?: number): void;
52
-
53
- /**
54
- * Set the (x,y,z) coordinates of a point based on its index.
55
- * @param {Number} idx The index of point.
56
- * @param {Number} x The x coordinate.
57
- * @param {Number} y The y coordinate.
58
- * @param {Number} z The z coordinate.
59
- */
60
- setPoint(idx: number, x: number, y: number, z: number): void;
61
-
62
- /**
63
- * Insert the (x,y,z) coordinates of a point at the next available slot.
64
- * @param {Number} x The x coordinate.
65
- * @param {Number} y The y coordinate.
66
- * @param {Number} z The z coordinate.
67
- */
68
- insertNextPoint(x: number, y: number, z: number): void;
69
- }
70
-
71
- /**
72
- * Method used to decorate a given object (publicAPI+model) with vtkPoints characteristics.
73
- *
74
- * @param publicAPI object on which methods will be bounds (public)
75
- * @param model object on which data structure will be bounds (protected)
76
- * @param {IPointsInitialValues} [initialValues] (default: {})
77
- */
78
- export function extend(publicAPI: object, model: object, initialValues?: IPointsInitialValues): void;
79
-
80
- /**
81
- * Method used to create a new instance of vtkPoints
82
- * @param {IPointsInitialValues} [initialValues] for pre-setting some of its content
83
- */
84
- export function newInstance(initialValues?: IPointsInitialValues): vtkPoints;
85
-
86
-
87
- /**
88
- * vtkPoints represents 3D points. The data model for vtkPoints is an array
89
- * of vx-vy-vz triplets accessible by (point or cell) id.
90
- */
91
-
92
- export declare const vtkPoints: {
93
- newInstance: typeof newInstance;
94
- extend: typeof extend;
95
- }
96
- export default vtkPoints;
1
+ import vtkDataArray from './DataArray';
2
+ import { Bounds, TypedArray } from './../../types';
3
+
4
+ /**
5
+ *
6
+ */
7
+ export interface IPointsInitialValues {
8
+ empty?: boolean;
9
+ numberOfComponents?: number;
10
+ bounds?: Bounds;
11
+ }
12
+
13
+ export interface vtkPoints extends vtkDataArray {
14
+
15
+ /**
16
+ * Trigger the computation of bounds
17
+ */
18
+ computeBounds(): Bounds;
19
+
20
+ /**
21
+ * Get the bounds for this mapper as [xmin, xmax, ymin, ymax,zmin, zmax].
22
+ * @return {Bounds} The bounds for the mapper.
23
+ */
24
+ getBounds(): Bounds;
25
+
26
+ /**
27
+ * Get the coordinate of a point.
28
+ * @param {Number} idx The index of point.
29
+ * @param {Number[]|TypedArray} [tupleToFill] (default [])
30
+ * @returns {Number[]|TypedArray}
31
+ */
32
+ getPoint(idx: number, tupleToFill?: number[]|TypedArray): number[]|TypedArray;
33
+
34
+ /**
35
+ * Convenient method to search a point in the array.
36
+ * This is a naïve search. Consider using a "locator" instead.
37
+ * @param {Array<Number>|TypedArray} pointToSearch
38
+ * @param {Number} precision (1e-6 by default)
39
+ * @returns {Number} the index of the point if found, -1 otherwise.
40
+ */
41
+ findPoint(pointToSearch: Array<number>|TypedArray, precision?: number): number;
42
+
43
+ /**
44
+ * Get the number of points for this object can hold.
45
+ */
46
+ getNumberOfPoints(): number;
47
+
48
+ /**
49
+ * Set the number of points for this object to hold.
50
+ *
51
+ * ```js
52
+ * points.getData()[0] = x;
53
+ * points.getData()[1] = y;
54
+ * points.getData()[2] = z;
55
+ * ```
56
+ *
57
+ * @param {Number} nbPoints
58
+ * @param {Number} [dimension]
59
+ */
60
+ setNumberOfPoints(nbPoints: number, dimension?: number): void;
61
+
62
+ /**
63
+ * Set the (x,y,z) coordinates of a point based on its index.
64
+ * @param {Number} idx The index of point.
65
+ * @param {Number} x The x coordinate.
66
+ * @param {Number} y The y coordinate.
67
+ * @param {Number} z The z coordinate.
68
+ */
69
+ setPoint(idx: number, x: number, y: number, z: number): void;
70
+
71
+ /**
72
+ * Insert the (x,y,z) coordinates of a point at the next available slot.
73
+ * @param {Number} x The x coordinate.
74
+ * @param {Number} y The y coordinate.
75
+ * @param {Number} z The z coordinate.
76
+ */
77
+ insertNextPoint(x: number, y: number, z: number): void;
78
+ }
79
+
80
+ /**
81
+ * Method used to decorate a given object (publicAPI+model) with vtkPoints characteristics.
82
+ *
83
+ * @param publicAPI object on which methods will be bounds (public)
84
+ * @param model object on which data structure will be bounds (protected)
85
+ * @param {IPointsInitialValues} [initialValues] (default: {})
86
+ */
87
+ export function extend(publicAPI: object, model: object, initialValues?: IPointsInitialValues): void;
88
+
89
+ /**
90
+ * Method used to create a new instance of vtkPoints
91
+ * @param {IPointsInitialValues} [initialValues] for pre-setting some of its content
92
+ */
93
+ export function newInstance(initialValues?: IPointsInitialValues): vtkPoints;
94
+
95
+
96
+ /**
97
+ * vtkPoints represents 3D points. The data model for vtkPoints is an array
98
+ * of vx-vy-vz triplets accessible by (point or cell) id.
99
+ */
100
+
101
+ export declare const vtkPoints: {
102
+ newInstance: typeof newInstance;
103
+ extend: typeof extend;
104
+ }
105
+ export default vtkPoints;
@@ -33,6 +33,7 @@ function vtkPoints(publicAPI, model) {
33
33
  publicAPI.setTuple(idx, xyz);
34
34
  };
35
35
  publicAPI.getPoint = publicAPI.getTuple;
36
+ publicAPI.findPoint = publicAPI.findTuple;
36
37
  publicAPI.insertNextPoint = (x, y, z) => publicAPI.insertNextTuple([x, y, z]);
37
38
  publicAPI.getBounds = () => {
38
39
  if (publicAPI.getNumberOfComponents() === 3) {
@@ -8,20 +8,25 @@ function initPolyIterator(pd) {
8
8
  const polys = pd.getPolys().getData();
9
9
  const strips = pd.getStrips().getData();
10
10
  const it = {
11
+ cellSize: 0,
12
+ cell: [],
11
13
  done: false,
12
14
  polyIdx: 0,
13
15
  stripIdx: 0,
14
16
  remainingStripLength: 0,
15
17
  // returns a single poly cell
16
18
  next() {
17
- let ret = null;
18
19
  if (it.polyIdx < polys.length) {
19
- const cellSize = polys[it.polyIdx];
20
+ it.cellSize = polys[it.polyIdx];
20
21
  const start = it.polyIdx + 1;
21
- const end = start + cellSize;
22
+ const end = start + it.cellSize;
22
23
  it.polyIdx = end;
23
- ret = polys.subarray(start, end);
24
+ let p = 0;
25
+ for (let i = start; i < end; ++i) {
26
+ it.cell[p++] = polys[i];
27
+ }
24
28
  } else if (it.stripIdx < strips.length) {
29
+ it.cellSize = 3;
25
30
  if (it.remainingStripLength === 0) {
26
31
  it.remainingStripLength = strips[it.stripIdx] - 2; // sliding window of 3 points
27
32
  // stripIdx points to the last point in a triangle 3-tuple
@@ -31,14 +36,18 @@ function initPolyIterator(pd) {
31
36
  const end = it.stripIdx + 1;
32
37
  it.stripIdx++;
33
38
  it.remainingStripLength--;
34
- ret = strips.subarray(start, end);
35
- } else if (it.done) {
39
+ let p = 0;
40
+ for (let i = start; i < end; ++i) {
41
+ it.cell[p++] = strips[i];
42
+ }
43
+ } else if (!it.done) {
44
+ it.done = true;
45
+ } else {
36
46
  throw new Error('Iterator is done');
37
47
  }
38
- it.done = it.polyIdx >= polys.length && it.stripIdx >= strips.length;
39
- return ret;
40
48
  }
41
49
  };
50
+ it.next();
42
51
  return it;
43
52
  }
44
53
 
@@ -82,32 +91,29 @@ function vtkCutter(publicAPI, model) {
82
91
  const crossedEdges = [];
83
92
  const x1 = new Array(3);
84
93
  const x2 = new Array(3);
94
+ const cellPointsScalars = [];
95
+
85
96
  // Loop over all cells; get scalar values for all cell points
86
97
  // and process each cell.
87
98
  /* eslint-disable no-continue */
88
- const it = initPolyIterator(input);
89
- while (!it.done) {
99
+ for (const it = initPolyIterator(input); !it.done; it.next()) {
90
100
  // cell contains the point IDs/indices
91
- const cell = it.next();
92
101
 
93
102
  // Check that cells have at least 3 points
94
- if (cell.length <= 2) {
103
+ if (it.cellSize <= 2) {
95
104
  continue;
96
105
  }
97
106
 
98
107
  // Get associated scalar of points that constitute the current cell
99
- const cellPointsScalars = [];
100
- let pointIndex;
101
- for (let i = 0; i < cell.length; i++) {
102
- pointIndex = cell[i];
103
- cellPointsScalars.push(model.cutScalars[pointIndex]);
108
+ for (let i = 0; i < it.cellSize;) {
109
+ cellPointsScalars[i] = model.cutScalars[it.cell[i++]];
104
110
  }
105
111
 
106
112
  // Check if all cell points are on same side (same side == cell not crossed by cut function)
107
113
  // TODO: won't work if one point scalar is = 0 ?
108
114
  const sideFirstPoint = cellPointsScalars[0] > 0;
109
115
  let allPointsSameSide = true;
110
- for (let i = 1; i < cellPointsScalars.length; i++) {
116
+ for (let i = 1; i < it.cell.length; i++) {
111
117
  const sideCurrentPoint = cellPointsScalars[i] > 0;
112
118
  if (sideCurrentPoint !== sideFirstPoint) {
113
119
  allPointsSameSide = false;
@@ -122,8 +128,8 @@ function vtkCutter(publicAPI, model) {
122
128
 
123
129
  // Find and compute edges which intersect cells
124
130
  const intersectedEdgesList = [];
125
- for (let i = 0; i < cell.length; i++) {
126
- const idNext = i + 1 === cell.length ? 0 : i + 1;
131
+ for (let i = 0; i < it.cellSize; i++) {
132
+ const idNext = i + 1 === it.cellSize ? 0 : i + 1;
127
133
 
128
134
  // Go to next edge if edge is not crossed
129
135
  // TODO: in most come cases, (numberOfPointsInCell - 1) or 0 edges of the cell
@@ -152,8 +158,8 @@ function vtkCutter(publicAPI, model) {
152
158
  }
153
159
 
154
160
  // points position
155
- const pointID1 = cell[e1];
156
- const pointID2 = cell[e2];
161
+ const pointID1 = it.cell[e1];
162
+ const pointID2 = it.cell[e2];
157
163
  x1[0] = pointsData[pointID1 * 3];
158
164
  x1[1] = pointsData[pointID1 * 3 + 1];
159
165
  x1[2] = pointsData[pointID1 * 3 + 2];
@@ -11,14 +11,17 @@ import vtkTriangle from '../../Common/DataModel/Triangle.js';
11
11
  function vtkPolyDataNormals(publicAPI, model) {
12
12
  // Set our className
13
13
  model.classHierarchy.push('vtkPolyDataNormals');
14
- publicAPI.vtkPolyDataNormalsExecute = (pointsData, polysData) => {
14
+ publicAPI.vtkPolyDataNormalsExecute = (numberOfPolys, polysData, pointsData) => {
15
15
  if (!pointsData) {
16
16
  return null;
17
17
  }
18
- const normalsData = new Float32Array(pointsData.length);
18
+ const pointNormals = new Float32Array(pointsData.length);
19
+ const cellNormals = new Float32Array(3 * numberOfPolys);
20
+ let cellNormalComponent = 0;
19
21
  let numberOfPoints = 0;
20
22
  const polysDataLength = polysData.length;
21
23
  const cellPointIds = [0, 0, 0];
24
+ const cellNormal = [0, 0, 0];
22
25
  for (let c = 0; c < polysDataLength; c += numberOfPoints + 1) {
23
26
  numberOfPoints = polysData[c];
24
27
  if (numberOfPoints < 3) {
@@ -28,26 +31,35 @@ function vtkPolyDataNormals(publicAPI, model) {
28
31
  for (let i = 1; i <= 3; ++i) {
29
32
  cellPointIds[i - 1] = 3 * polysData[c + i];
30
33
  }
31
- const cellNormal = [];
32
34
  vtkTriangle.computeNormal(pointsData.slice(cellPointIds[0], cellPointIds[0] + 3), pointsData.slice(cellPointIds[1], cellPointIds[1] + 3), pointsData.slice(cellPointIds[2], cellPointIds[2] + 3), cellNormal);
33
- for (let i = 1; i <= numberOfPoints; ++i) {
34
- let pointId = 3 * polysData[c + i];
35
- normalsData[pointId] += cellNormal[0];
36
- normalsData[++pointId] += cellNormal[1];
37
- normalsData[++pointId] += cellNormal[2];
35
+ cellNormals[cellNormalComponent++] = cellNormal[0];
36
+ cellNormals[cellNormalComponent++] = cellNormal[1];
37
+ cellNormals[cellNormalComponent++] = cellNormal[2];
38
+ if (model.computePointNormals) {
39
+ for (let i = 1; i <= numberOfPoints; ++i) {
40
+ let pointId = 3 * polysData[c + i];
41
+ pointNormals[pointId] += cellNormal[0];
42
+ pointNormals[++pointId] += cellNormal[1];
43
+ pointNormals[++pointId] += cellNormal[2];
44
+ }
38
45
  }
39
46
  }
40
47
 
41
- /* Normalize normals */
42
-
43
- for (let i = 0; i < pointsData.length;) {
44
- const pointNormal = normalsData.slice(i, i + 3);
45
- vtkMath.normalize(pointNormal);
46
- normalsData[i++] = pointNormal[0];
47
- normalsData[i++] = pointNormal[1];
48
- normalsData[i++] = pointNormal[2];
48
+ // Normalize point normals.
49
+ // A point normal is the sum of all the cell normals the point belongs to
50
+ if (model.computePointNormals) {
51
+ const pointNormal = [0, 0, 0];
52
+ for (let i = 0; i < pointsData.length;) {
53
+ pointNormal[0] = pointNormals[i];
54
+ pointNormal[1] = pointNormals[i + 1];
55
+ pointNormal[2] = pointNormals[i + 2];
56
+ vtkMath.normalize(pointNormal);
57
+ pointNormals[i++] = pointNormal[0];
58
+ pointNormals[i++] = pointNormal[1];
59
+ pointNormals[i++] = pointNormal[2];
60
+ }
49
61
  }
50
- return normalsData;
62
+ return [cellNormals, pointNormals];
51
63
  };
52
64
  publicAPI.requestData = (inData, outData) => {
53
65
  const numberOfInputs = publicAPI.getNumberOfInputPorts();
@@ -58,12 +70,7 @@ function vtkPolyDataNormals(publicAPI, model) {
58
70
  if (!input) {
59
71
  return;
60
72
  }
61
- const outputNormalsData = publicAPI.vtkPolyDataNormalsExecute(input.getPoints().getData(), input.getPolys().getData());
62
73
  const output = vtkPolyData.newInstance();
63
- const outputNormals = vtkDataArray.newInstance({
64
- numberOfComponents: 3,
65
- values: outputNormalsData
66
- });
67
74
  output.setPoints(input.getPoints());
68
75
  output.setVerts(input.getVerts());
69
76
  output.setLines(input.getLines());
@@ -72,7 +79,23 @@ function vtkPolyDataNormals(publicAPI, model) {
72
79
  output.getPointData().passData(input.getPointData());
73
80
  output.getCellData().passData(input.getCellData());
74
81
  output.getFieldData().passData(input.getFieldData());
75
- output.getPointData().setNormals(outputNormals);
82
+ const [cellNormals, pointNormals] = publicAPI.vtkPolyDataNormalsExecute(input.getNumberOfPolys(), input.getPolys().getData(), input.getPoints().getData());
83
+ if (model.computePointNormals) {
84
+ const outputPointNormals = vtkDataArray.newInstance({
85
+ numberOfComponents: 3,
86
+ name: 'Normals',
87
+ values: pointNormals
88
+ });
89
+ output.getPointData().setNormals(outputPointNormals);
90
+ }
91
+ if (model.computeCellNormals) {
92
+ const outputCellNormals = vtkDataArray.newInstance({
93
+ numberOfComponents: 3,
94
+ name: 'Normals',
95
+ values: cellNormals
96
+ });
97
+ output.getCellData().setNormals(outputCellNormals);
98
+ }
76
99
  outData[0] = output;
77
100
  };
78
101
  }
@@ -82,6 +105,8 @@ function vtkPolyDataNormals(publicAPI, model) {
82
105
  // ----------------------------------------------------------------------------
83
106
  function defaultValues(initialValues) {
84
107
  return {
108
+ computeCellNormals: false,
109
+ computePointNormals: true,
85
110
  ...initialValues
86
111
  };
87
112
  }
@@ -98,6 +123,7 @@ function extend(publicAPI, model) {
98
123
  /* Also make it an algorithm with one input and one output */
99
124
 
100
125
  macro.algo(publicAPI, model, 1, 1);
126
+ macro.setGet(publicAPI, model, ['computeCellNormals', 'computePointNormals']);
101
127
 
102
128
  /* Object specific methods */
103
129
 
@@ -1,4 +1,4 @@
1
- import { Bounds } from './../../types';
1
+ import { Bounds, Nullable, vtkPipelineConnection } from './../../types';
2
2
  import vtkMapper, { IMapperInitialValues } from './Mapper';
3
3
  import { OrientationModes, ScaleModes } from './Glyph3DMapper/Constants';
4
4
 
@@ -87,6 +87,12 @@ export interface vtkGlyph3DMapper extends vtkMapper {
87
87
  */
88
88
  getPrimitiveCount(): IPrimitiveCount;
89
89
 
90
+ /**
91
+ * Sets the name of the array to use as orientation.
92
+ * @param {String} arrayName Name of the array
93
+ */
94
+ setOrientationArray(arrayName: Nullable<string>): boolean;
95
+
90
96
  /**
91
97
  * Orientation mode indicates if the OrientationArray provides the direction
92
98
  * vector for the orientation or the rotations around each axes.
@@ -138,6 +144,13 @@ export interface vtkGlyph3DMapper extends vtkMapper {
138
144
  * Set scale to `SCALE_BY_CONSTANT`
139
145
  */
140
146
  setScaleModeToScaleByConstant(): boolean;
147
+
148
+ /**
149
+ * Convenient method to set the source glyph connection
150
+ * @param {vtkPipelineConnection} outputPort The output port of the glyph source.
151
+ */
152
+ setSourceConnection(outputPort: vtkPipelineConnection): void;
153
+
141
154
  }
142
155
 
143
156
  /**
@@ -112,6 +112,7 @@ function vtkGlyph3DMapper(publicAPI, model) {
112
112
  model.normalArray = new Float32Array(9 * numPts);
113
113
  const nbuff = model.normalArray.buffer;
114
114
  const tuple = [];
115
+ const orientation = [];
115
116
  for (let i = 0; i < numPts; ++i) {
116
117
  const z = new Float32Array(mbuff, i * 64, 16);
117
118
  trans[0] = pts[i * 3];
@@ -119,7 +120,6 @@ function vtkGlyph3DMapper(publicAPI, model) {
119
120
  trans[2] = pts[i * 3 + 2];
120
121
  mat4.translate(z, identity, trans);
121
122
  if (oArray) {
122
- const orientation = [];
123
123
  oArray.getTuple(i, orientation);
124
124
  switch (model.orientationMode) {
125
125
  case OrientationModes.MATRIX:
@@ -244,6 +244,7 @@ function vtkGlyph3DMapper(publicAPI, model) {
244
244
  };
245
245
  return pcount;
246
246
  };
247
+ publicAPI.setSourceConnection = outputPort => publicAPI.setInputConnection(outputPort, 1);
247
248
  }
248
249
 
249
250
  // ----------------------------------------------------------------------------
@@ -257,11 +257,27 @@ export interface vtkImageMapper extends vtkAbstractImageMapper {
257
257
  */
258
258
  getSlicingModeNormal(): number[];
259
259
 
260
+ /**
261
+ * Get the slicing mode.
262
+ */
263
+ getSlicingMode(): SlicingMode;
264
+
260
265
  /**
261
266
  * Set the slicing mode.
262
- * @param {Number} mode The slicing mode.
267
+ * @param {SlicingMode} mode The slicing mode.
268
+ */
269
+ setSlicingMode(mode: SlicingMode): boolean;
270
+
271
+ /**
272
+ * Get the preference to use halfFloat representation of float
273
+ */
274
+ getPreferSizeOverAccuracy(): boolean;
275
+
276
+ /**
277
+ * Set the preference to use halfFloat representation of float
278
+ * @param {Boolean} preferSizeOverAccuracy
263
279
  */
264
- setSlicingMode(mode: number): boolean;
280
+ setPreferSizeOverAccuracy(preferSizeOverAccuracy: boolean): boolean;
265
281
  }
266
282
 
267
283
  /**
@@ -17,7 +17,11 @@ const {
17
17
  // Global methods
18
18
  // ----------------------------------------------------------------------------
19
19
 
20
- const EMPTY_MOUSE_EVENT = new MouseEvent('');
20
+ const EMPTY_MOUSE_EVENT = {
21
+ ctrlKey: false,
22
+ altKey: false,
23
+ shiftKey: false
24
+ };
21
25
  const deviceInputMap = {
22
26
  'xr-standard': [Input.Trigger, Input.Grip, Input.TrackPad, Input.Thumbstick, Input.A, Input.B]
23
27
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitware/vtk.js",
3
- "version": "28.11.1",
3
+ "version": "28.12.0",
4
4
  "description": "Visualization Toolkit for the Web",
5
5
  "keywords": [
6
6
  "3d",