@kitware/vtk.js 35.0.0 → 35.2.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.
@@ -90,6 +90,34 @@ export function newInstance(initialValues?: ISphereInitialValues): vtkSphere;
90
90
  */
91
91
  declare function evaluate(radius: number, center: Vector3, x: Vector3): number;
92
92
 
93
+ /**
94
+ * Approximate bounding sphere for a point set represented as a flat xyz array.
95
+ * Returns `[cx, cy, cz, r]`.
96
+ *
97
+ * @param {Array<number>|TypedArray} pts flat xyz point coordinates
98
+ * @param {number} [numPts] number of points to process
99
+ * @param {number[]} [hints] two point ids expected to be far apart
100
+ */
101
+ declare function computeBoundingSphere(
102
+ pts: Array<number> | ArrayLike<number>,
103
+ numPts?: number,
104
+ hints?: number[]
105
+ ): [number, number, number, number];
106
+
107
+ /**
108
+ * Approximate bounding sphere for an array of spheres `[x, y, z, r]`.
109
+ * Returns `[cx, cy, cz, r]`.
110
+ *
111
+ * @param {Array<Vector4>} spheres list of spheres
112
+ * @param {number} [numSpheres] number of spheres to process
113
+ * @param {number[]} [hints] two sphere ids expected to be far apart
114
+ */
115
+ declare function computeBoundingSphereFromSpheres(
116
+ spheres: Array<[number, number, number, number]>,
117
+ numSpheres?: number,
118
+ hints?: number[]
119
+ ): [number, number, number, number];
120
+
93
121
  /**
94
122
  * vtkSphere provides methods for creating a 1D cubic spline object from given
95
123
  * parameters, and allows for the calculation of the spline value and derivative
@@ -99,5 +127,7 @@ export declare const vtkSphere: {
99
127
  newInstance: typeof newInstance;
100
128
  extend: typeof extend;
101
129
  evaluate: typeof evaluate;
130
+ computeBoundingSphere: typeof computeBoundingSphere;
131
+ computeBoundingSphereFromSpheres: typeof computeBoundingSphereFromSpheres;
102
132
  };
103
133
  export default vtkSphere;
@@ -1,5 +1,6 @@
1
1
  import { m as macro } from '../../macros2.js';
2
2
  import vtkImplicitFunction from './ImplicitFunction.js';
3
+ import { f as distance2BetweenPoints } from '../Core/Math/index.js';
3
4
 
4
5
  // ----------------------------------------------------------------------------
5
6
  // Global methods
@@ -13,13 +14,200 @@ function evaluate(radius, center, xyz) {
13
14
  const r = [(xyz[0] - center[0]) / radius[0], (xyz[1] - center[1]) / radius[1], (xyz[2] - center[2]) / radius[2]];
14
15
  return r[0] * r[0] + r[1] * r[1] + r[2] * r[2] - 1;
15
16
  }
17
+ function setPointFromArray(dst, pts, pointId) {
18
+ const offset = 3 * pointId;
19
+ dst[0] = pts[offset];
20
+ dst[1] = pts[offset + 1];
21
+ dst[2] = pts[offset + 2];
22
+ }
23
+ function copyPoint(dst, src) {
24
+ dst[0] = src[0];
25
+ dst[1] = src[1];
26
+ dst[2] = src[2];
27
+ }
28
+ function copySphere(dst, src) {
29
+ dst[0] = src[0];
30
+ dst[1] = src[1];
31
+ dst[2] = src[2];
32
+ dst[3] = src[3];
33
+ }
34
+
35
+ // Inspired by Graphics Gems Vol. I ("An Efficient Bounding Sphere" by Jack Ritter).
36
+ function computeBoundingSphere(pts, numPts, hints) {
37
+ const actualNumPts = numPts ?? Math.floor(pts.length / 3);
38
+ const sphere = [0, 0, 0, 0];
39
+ if (actualNumPts < 1) {
40
+ return sphere;
41
+ }
42
+ const d1 = [0, 0, 0];
43
+ const d2 = [0, 0, 0];
44
+ if (hints && hints.length >= 2) {
45
+ setPointFromArray(d1, pts, hints[0]);
46
+ setPointFromArray(d2, pts, hints[1]);
47
+ } else {
48
+ const xMin = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE];
49
+ const yMin = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE];
50
+ const zMin = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE];
51
+ const xMax = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE];
52
+ const yMax = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE];
53
+ const zMax = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE];
54
+ const p = [0, 0, 0];
55
+ for (let i = 0; i < actualNumPts; i++) {
56
+ setPointFromArray(p, pts, i);
57
+ if (p[0] < xMin[0]) copyPoint(xMin, p);
58
+ if (p[0] > xMax[0]) copyPoint(xMax, p);
59
+ if (p[1] < yMin[1]) copyPoint(yMin, p);
60
+ if (p[1] > yMax[1]) copyPoint(yMax, p);
61
+ if (p[2] < zMin[2]) copyPoint(zMin, p);
62
+ if (p[2] > zMax[2]) copyPoint(zMax, p);
63
+ }
64
+ const xSpan = distance2BetweenPoints(xMax, xMin);
65
+ const ySpan = distance2BetweenPoints(yMax, yMin);
66
+ const zSpan = distance2BetweenPoints(zMax, zMin);
67
+ if (xSpan > ySpan) {
68
+ if (xSpan > zSpan) {
69
+ copyPoint(d1, xMin);
70
+ copyPoint(d2, xMax);
71
+ } else {
72
+ copyPoint(d1, zMin);
73
+ copyPoint(d2, zMax);
74
+ }
75
+ } else if (ySpan > zSpan) {
76
+ copyPoint(d1, yMin);
77
+ copyPoint(d2, yMax);
78
+ } else {
79
+ copyPoint(d1, zMin);
80
+ copyPoint(d2, zMax);
81
+ }
82
+ }
83
+ sphere[0] = (d1[0] + d2[0]) / 2;
84
+ sphere[1] = (d1[1] + d2[1]) / 2;
85
+ sphere[2] = (d1[2] + d2[2]) / 2;
86
+ let r2 = distance2BetweenPoints(d1, d2) / 4;
87
+ sphere[3] = Math.sqrt(r2);
88
+ const p = [0, 0, 0];
89
+ for (let i = 0; i < actualNumPts; i++) {
90
+ setPointFromArray(p, pts, i);
91
+ const dist2 = distance2BetweenPoints(p, sphere);
92
+ if (dist2 > r2) {
93
+ const dist = Math.sqrt(dist2);
94
+ sphere[3] = (sphere[3] + dist) / 2;
95
+ r2 = sphere[3] * sphere[3];
96
+ const delta = dist - sphere[3];
97
+ sphere[0] = (sphere[3] * sphere[0] + delta * p[0]) / dist;
98
+ sphere[1] = (sphere[3] * sphere[1] + delta * p[1]) / dist;
99
+ sphere[2] = (sphere[3] * sphere[2] + delta * p[2]) / dist;
100
+ }
101
+ }
102
+ return sphere;
103
+ }
104
+ function computeBoundingSphereFromSpheres(spheres, numSpheres, hints) {
105
+ const actualNumSpheres = numSpheres ?? spheres.length;
106
+ const sphere = [0, 0, 0, 0];
107
+ if (actualNumSpheres < 1) {
108
+ return sphere;
109
+ }
110
+ if (actualNumSpheres === 1) {
111
+ copySphere(sphere, spheres[0]);
112
+ return sphere;
113
+ }
114
+ const s1 = [0, 0, 0, 0];
115
+ const s2 = [0, 0, 0, 0];
116
+ if (hints && hints.length >= 2) {
117
+ copySphere(s1, spheres[hints[0]]);
118
+ copySphere(s2, spheres[hints[1]]);
119
+ } else {
120
+ const xMin = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, 0];
121
+ const yMin = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, 0];
122
+ const zMin = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, 0];
123
+ const xMax = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, 0];
124
+ const yMax = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, 0];
125
+ const zMax = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, 0];
126
+ for (let i = 0; i < actualNumSpheres; i++) {
127
+ const s = spheres[i];
128
+ if (s[0] - s[3] < xMin[0] - xMin[3]) copySphere(xMin, s);
129
+ if (s[0] + s[3] > xMax[0] + xMax[3]) copySphere(xMax, s);
130
+ if (s[1] - s[3] < yMin[1] - yMin[3]) copySphere(yMin, s);
131
+ if (s[1] + s[3] > yMax[1] + yMax[3]) copySphere(yMax, s);
132
+ if (s[2] - s[3] < zMin[2] - zMin[3]) copySphere(zMin, s);
133
+ if (s[2] + s[3] > zMax[2] + zMax[3]) copySphere(zMax, s);
134
+ }
135
+ const xSpan = (xMax[0] + xMax[3] - (xMin[0] - xMin[3])) * (xMax[0] + xMax[3] - (xMin[0] - xMin[3])) + (xMax[1] + xMax[3] - (xMin[1] - xMin[3])) * (xMax[1] + xMax[3] - (xMin[1] - xMin[3])) + (xMax[2] + xMax[3] - (xMin[2] - xMin[3])) * (xMax[2] + xMax[3] - (xMin[2] - xMin[3]));
136
+ const ySpan = (yMax[0] + yMax[3] - (yMin[0] - yMin[3])) * (yMax[0] + yMax[3] - (yMin[0] - yMin[3])) + (yMax[1] + yMax[3] - (yMin[1] - yMin[3])) * (yMax[1] + yMax[3] - (yMin[1] - yMin[3])) + (yMax[2] + yMax[3] - (yMin[2] - yMin[3])) * (yMax[2] + yMax[3] - (yMin[2] - yMin[3]));
137
+ const zSpan = (zMax[0] + zMax[3] - (zMin[0] - zMin[3])) * (zMax[0] + zMax[3] - (zMin[0] - zMin[3])) + (zMax[1] + zMax[3] - (zMin[1] - zMin[3])) * (zMax[1] + zMax[3] - (zMin[1] - zMin[3])) + (zMax[2] + zMax[3] - (zMin[2] - zMin[3])) * (zMax[2] + zMax[3] - (zMin[2] - zMin[3]));
138
+ if (xSpan > ySpan) {
139
+ if (xSpan > zSpan) {
140
+ copySphere(s1, xMin);
141
+ copySphere(s2, xMax);
142
+ } else {
143
+ copySphere(s1, zMin);
144
+ copySphere(s2, zMax);
145
+ }
146
+ } else if (ySpan > zSpan) {
147
+ copySphere(s1, yMin);
148
+ copySphere(s2, yMax);
149
+ } else {
150
+ copySphere(s1, zMin);
151
+ copySphere(s2, zMax);
152
+ }
153
+ }
154
+ let r2 = distance2BetweenPoints(s1, s2) / 4;
155
+ sphere[3] = r2 > 0 ? Math.sqrt(r2) : s1[3];
156
+ const t1 = -s1[3] / (2 * sphere[3]);
157
+ const t2 = 1 + s2[3] / (2 * sphere[3]);
158
+ const v = [0, 0, 0];
159
+ for (let i = 0; i < 3; i++) {
160
+ v[i] = s2[i] - s1[i];
161
+ const tmp = s1[i] + t1 * v[i];
162
+ s2[i] = s1[i] + t2 * v[i];
163
+ s1[i] = tmp;
164
+ sphere[i] = (s1[i] + s2[i]) / 2;
165
+ }
166
+ r2 = distance2BetweenPoints(s1, s2) / 4;
167
+ if (r2 > 0) {
168
+ sphere[3] = Math.sqrt(r2);
169
+ } else {
170
+ sphere[3] = s1[3];
171
+ r2 = sphere[3] * sphere[3];
172
+ }
173
+ for (let i = 0; i < actualNumSpheres; i++) {
174
+ const s = spheres[i];
175
+ const sR2 = s[3] * s[3];
176
+ let dist2 = distance2BetweenPoints(s, sphere);
177
+ if (dist2 <= 0) {
178
+ dist2 = s[3];
179
+ }
180
+ const fac = sR2 > dist2 ? 2 * sR2 : 2 * dist2;
181
+ if (dist2 + fac + sR2 > r2) {
182
+ const dist = Math.sqrt(dist2);
183
+ if ((dist + s[3]) * (dist + s[3]) > r2) {
184
+ for (let j = 0; j < 3; j++) {
185
+ v[j] = s[j] - sphere[j];
186
+ s1[j] = sphere[j] - sphere[3] / dist * v[j];
187
+ s2[j] = sphere[j] + (1 + s[3] / dist) * v[j];
188
+ sphere[j] = (s1[j] + s2[j]) / 2;
189
+ }
190
+ r2 = distance2BetweenPoints(s1, s2) / 4;
191
+ if (r2 > 0) {
192
+ sphere[3] = Math.sqrt(r2);
193
+ } else {
194
+ sphere[3] = Math.max(s1[3], sphere[3]);
195
+ r2 = sphere[3] * sphere[3];
196
+ }
197
+ }
198
+ }
199
+ }
200
+ return sphere;
201
+ }
16
202
 
17
203
  // ----------------------------------------------------------------------------
18
204
  // Static API
19
205
  // ----------------------------------------------------------------------------
20
206
 
21
207
  const STATIC = {
22
- evaluate
208
+ evaluate,
209
+ computeBoundingSphere,
210
+ computeBoundingSphereFromSpheres
23
211
  };
24
212
 
25
213
  // ----------------------------------------------------------------------------
@@ -13,7 +13,34 @@ interface ISTLReaderOptions {
13
13
  /**
14
14
  *
15
15
  */
16
- export interface ISTLReaderInitialValues {}
16
+ export interface ISTLReaderInitialValues {
17
+ /**
18
+ * Data access helper used for loading remote resources.
19
+ */
20
+ dataAccessHelper?:
21
+ | HtmlDataAccessHelper
22
+ | HttpDataAccessHelper
23
+ | JSZipDataAccessHelper
24
+ | LiteHttpDataAccessHelper;
25
+
26
+ /**
27
+ * Point locator used for vertex merging.
28
+ */
29
+ locator?: any;
30
+
31
+ /**
32
+ * Enable/disable point merging.
33
+ * Default is true.
34
+ */
35
+ merging?: boolean;
36
+
37
+ /**
38
+ * Merge tolerance power.
39
+ * If >= 0, points within 10^-tolerance are merged.
40
+ * Default is -1 (disabled).
41
+ */
42
+ removeDuplicateVertices?: number;
43
+ }
17
44
 
18
45
  type vtkSTLReaderBase = vtkObject &
19
46
  Omit<
@@ -41,6 +68,16 @@ export interface vtkSTLReader extends vtkSTLReaderBase {
41
68
  | JSZipDataAccessHelper
42
69
  | LiteHttpDataAccessHelper;
43
70
 
71
+ /**
72
+ * Get the point locator used for vertex merging.
73
+ */
74
+ getLocator(): any;
75
+
76
+ /**
77
+ * Get whether point merging is enabled.
78
+ */
79
+ getMerging(): boolean;
80
+
44
81
  /**
45
82
  * Get the url of the object to load.
46
83
  */
@@ -74,6 +111,7 @@ export interface vtkSTLReader extends vtkSTLReaderBase {
74
111
  * @param {String} content The content to parse.
75
112
  */
76
113
  parseAsText(content: string): void;
114
+
77
115
  /**
78
116
  *
79
117
  * @param inData
@@ -93,6 +131,16 @@ export interface vtkSTLReader extends vtkSTLReaderBase {
93
131
  | LiteHttpDataAccessHelper
94
132
  ): boolean;
95
133
 
134
+ /**
135
+ * Set a point locator used for vertex merging.
136
+ */
137
+ setLocator(locator: any): boolean;
138
+
139
+ /**
140
+ * Enable/disable point merging.
141
+ */
142
+ setMerging(merging: boolean): boolean;
143
+
96
144
  /**
97
145
  * Set the url of the object to load.
98
146
  * @param {String} url the url of the object to load.
@@ -1,8 +1,10 @@
1
+ import { m as macro } from '../../macros2.js';
1
2
  import BinaryHelper from '../Core/BinaryHelper.js';
2
3
  import DataAccessHelper from '../Core/DataAccessHelper.js';
3
- import { m as macro } from '../../macros2.js';
4
4
  import vtkDataArray from '../../Common/Core/DataArray.js';
5
5
  import vtkMatrixBuilder from '../../Common/Core/MatrixBuilder.js';
6
+ import vtkPoints from '../../Common/Core/Points.js';
7
+ import vtkMergePoints from '../../Common/DataModel/MergePoints.js';
6
8
  import vtkPolyData from '../../Common/DataModel/PolyData.js';
7
9
  import '../Core/DataAccessHelper/LiteHttpDataAccessHelper.js';
8
10
 
@@ -11,7 +13,8 @@ import '../Core/DataAccessHelper/LiteHttpDataAccessHelper.js';
11
13
  // import 'vtk.js/Sources/IO/Core/DataAccessHelper/JSZipDataAccessHelper'; // zip
12
14
 
13
15
  const {
14
- vtkErrorMacro
16
+ vtkErrorMacro,
17
+ vtkWarningMacro
15
18
  } = macro;
16
19
  function parseHeader(headerString) {
17
20
  const headerSubStr = headerString.split(' ');
@@ -101,54 +104,83 @@ function vtkSTLReader(publicAPI, model) {
101
104
  progressCallback
102
105
  });
103
106
  }
104
- function removeDuplicateVertices(tolerance) {
107
+ function removeDuplicateVertices(tolerancePower) {
105
108
  const polydata = model.output[0];
106
109
  const points = polydata.getPoints().getData();
107
110
  const faces = polydata.getPolys().getData();
108
111
  if (!points || !faces) {
109
- console.warn('No valid polydata.');
112
+ vtkWarningMacro('No valid polydata.');
110
113
  return;
111
114
  }
112
- const vMap = new Map();
113
- const vIndexMap = new Map();
114
- let vInc = 0;
115
- let pointsChanged = false;
116
- for (let i = 0; i < points.length; i += 3) {
117
- const k1 = (points[i] * 10 ** tolerance).toFixed(0);
118
- const k2 = (points[i + 1] * 10 ** tolerance).toFixed(0);
119
- const k3 = (points[i + 2] * 10 ** tolerance).toFixed(0);
120
- const key = `${k1},${k2},${k3}`;
121
- if (vMap.get(key) !== undefined) {
122
- vIndexMap.set(i / 3, vMap.get(key));
123
- pointsChanged = true;
124
- } else {
125
- vIndexMap.set(i / 3, vInc);
126
- vMap.set(key, vInc);
127
- vInc++;
115
+ const inCellNormals = polydata.getCellData().getNormals();
116
+ const inCellScalars = polydata.getCellData().getScalars();
117
+ const mergedPoints = vtkPoints.newInstance({
118
+ dataType: points.constructor
119
+ });
120
+ mergedPoints.allocate(points.length / 6, 3);
121
+ let locator = model.locator;
122
+ if (!locator) {
123
+ locator = vtkMergePoints.newInstance();
124
+ }
125
+ if (tolerancePower >= 0) {
126
+ locator.setTolerance(10 ** -tolerancePower);
127
+ }
128
+ locator.initPointInsertion(mergedPoints, polydata.getBounds(), Math.floor(points.length / 3 / 2));
129
+ const mergedCells = [];
130
+ const keptCellIds = [];
131
+ for (let i = 0, cellId = 0; i < faces.length; i += 4, cellId++) {
132
+ if (faces[i] === 3) {
133
+ const nodeIds = [0, 0, 0];
134
+ for (let j = 0; j < 3; j++) {
135
+ const pid = faces[i + 1 + j];
136
+ const x = [points[pid * 3], points[pid * 3 + 1], points[pid * 3 + 2]];
137
+ nodeIds[j] = locator.insertUniquePoint(x).id;
138
+ }
139
+ if (nodeIds[0] !== nodeIds[1] && nodeIds[0] !== nodeIds[2] && nodeIds[1] !== nodeIds[2]) {
140
+ mergedCells.push(3, nodeIds[0], nodeIds[1], nodeIds[2]);
141
+ keptCellIds.push(cellId);
142
+ }
128
143
  }
129
144
  }
130
- if (pointsChanged) {
131
- const outVerts = new Float32Array(vMap.size * 3);
132
- const keys = Array.from(vMap.keys());
133
- for (let i = 0; i < keys.length; i++) {
134
- const k = keys[i];
135
- const j = vMap.get(k) * 3;
136
- const coords = k.split(',').map(e => +e * 10 ** -tolerance);
137
- outVerts[j] = coords[0];
138
- outVerts[j + 1] = coords[1];
139
- outVerts[j + 2] = coords[2];
145
+ const outCellArray = new faces.constructor(mergedCells);
146
+ polydata.getPoints().setData(mergedPoints.getData(), 3);
147
+ polydata.getPolys().setData(outCellArray);
148
+ if (inCellNormals && inCellNormals.getData()) {
149
+ const inData = inCellNormals.getData();
150
+ const numComp = inCellNormals.getNumberOfComponents();
151
+ const outData = new inData.constructor(keptCellIds.length * numComp);
152
+ for (let i = 0; i < keptCellIds.length; i++) {
153
+ const srcOffset = keptCellIds[i] * numComp;
154
+ const dstOffset = i * numComp;
155
+ for (let c = 0; c < numComp; c++) {
156
+ outData[dstOffset + c] = inData[srcOffset + c];
157
+ }
140
158
  }
141
- const outFaces = new Int32Array(faces.length);
142
- for (let i = 0; i < faces.length; i += 4) {
143
- outFaces[i] = 3;
144
- outFaces[i + 1] = vIndexMap.get(faces[i + 1]);
145
- outFaces[i + 2] = vIndexMap.get(faces[i + 2]);
146
- outFaces[i + 3] = vIndexMap.get(faces[i + 3]);
159
+ polydata.getCellData().setNormals(vtkDataArray.newInstance({
160
+ name: inCellNormals.getName() || 'Normals',
161
+ values: outData,
162
+ numberOfComponents: numComp
163
+ }));
164
+ }
165
+ if (inCellScalars && inCellScalars.getData()) {
166
+ const inData = inCellScalars.getData();
167
+ const numComp = inCellScalars.getNumberOfComponents();
168
+ const outData = new inData.constructor(keptCellIds.length * numComp);
169
+ for (let i = 0; i < keptCellIds.length; i++) {
170
+ const srcOffset = keptCellIds[i] * numComp;
171
+ const dstOffset = i * numComp;
172
+ for (let c = 0; c < numComp; c++) {
173
+ outData[dstOffset + c] = inData[srcOffset + c];
174
+ }
147
175
  }
148
- polydata.getPoints().setData(outVerts);
149
- polydata.getPolys().setData(outFaces);
150
- polydata.modified();
176
+ polydata.getCellData().setScalars(vtkDataArray.newInstance({
177
+ name: inCellScalars.getName() || 'Attribute',
178
+ values: outData,
179
+ numberOfComponents: numComp
180
+ }));
151
181
  }
182
+ locator.initialize();
183
+ polydata.modified();
152
184
  }
153
185
 
154
186
  // Set DataSet url
@@ -296,7 +328,7 @@ function vtkSTLReader(publicAPI, model) {
296
328
 
297
329
  // Add new output
298
330
  model.output[0] = polydata;
299
- if (model.removeDuplicateVertices >= 0) {
331
+ if (model.merging && model.removeDuplicateVertices >= 0) {
300
332
  removeDuplicateVertices(model.removeDuplicateVertices);
301
333
  }
302
334
  };
@@ -329,7 +361,7 @@ function vtkSTLReader(publicAPI, model) {
329
361
 
330
362
  // Add new output
331
363
  model.output[0] = polydata;
332
- if (model.removeDuplicateVertices >= 0) {
364
+ if (model.merging && model.removeDuplicateVertices >= 0) {
333
365
  removeDuplicateVertices(model.removeDuplicateVertices);
334
366
  }
335
367
  };
@@ -345,7 +377,9 @@ function vtkSTLReader(publicAPI, model) {
345
377
  const DEFAULT_VALUES = {
346
378
  // baseURL: null,
347
379
  // dataAccessHelper: null,
380
+ // locator: null,
348
381
  // url: null,
382
+ merging: true,
349
383
  removeDuplicateVertices: -1
350
384
  };
351
385
 
@@ -357,7 +391,7 @@ function extend(publicAPI, model, initialValues = {}) {
357
391
  // Build VTK API
358
392
  macro.obj(publicAPI, model);
359
393
  macro.get(publicAPI, model, ['url', 'baseURL']);
360
- macro.setGet(publicAPI, model, ['dataAccessHelper', 'removeDuplicateVertices']);
394
+ macro.setGet(publicAPI, model, ['dataAccessHelper', 'locator', 'merging', 'removeDuplicateVertices']);
361
395
  macro.algo(publicAPI, model, 0, 1);
362
396
 
363
397
  // vtkSTLReader methods
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitware/vtk.js",
3
- "version": "35.0.0",
3
+ "version": "35.2.0",
4
4
  "description": "Visualization Toolkit for the Web",
5
5
  "keywords": [
6
6
  "3d",