@kitware/vtk.js 33.0.0 → 33.0.2

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.
@@ -13,7 +13,19 @@ interface IPLYReaderOptions {
13
13
  /**
14
14
  *
15
15
  */
16
- export interface IPLYReaderInitialValues {}
16
+ export interface IPLYReaderInitialValues {
17
+ /**
18
+ * Controls whether points are duplicated for face-texture mapping.
19
+ * Default is true.
20
+ */
21
+ duplicatePointsForFaceTexture?: boolean;
22
+
23
+ /**
24
+ * The tolerance used to determine if two points are the same.
25
+ * Default is 0.000001.
26
+ */
27
+ faceTextureTolerance?: number;
28
+ }
17
29
 
18
30
  type vtkPLYReaderBase = vtkObject &
19
31
  Omit<
@@ -41,6 +53,16 @@ export interface vtkPLYReader extends vtkPLYReaderBase {
41
53
  | JSZipDataAccessHelper
42
54
  | LiteHttpDataAccessHelper;
43
55
 
56
+ /**
57
+ * Controls whether points are duplicated for face-texture mapping.
58
+ */
59
+ getDuplicatePointsForFaceTexture(): boolean;
60
+
61
+ /**
62
+ * Get the tolerance used to determine if two points are the same.
63
+ */
64
+ getFaceTextureTolerance(): number;
65
+
44
66
  /**
45
67
  * Get the url of the object to load.
46
68
  */
@@ -95,7 +95,7 @@ function parseHeader(data) {
95
95
  }
96
96
  return header;
97
97
  }
98
- function postProcess(buffer, elements) {
98
+ function postProcess(buffer, elements, faceTextureTolerance, duplicatePointsForFaceTexture) {
99
99
  const vertElement = elements.find(element => element.name === 'vertex');
100
100
  const faceElement = elements.find(element => element.name === 'face');
101
101
  let nbVerts = 0;
@@ -106,14 +106,20 @@ function postProcess(buffer, elements) {
106
106
  if (faceElement) {
107
107
  nbFaces = faceElement.count;
108
108
  }
109
- const pointValues = new Float32Array(nbVerts * 3);
110
- const colorArray = new Uint8Array(nbVerts * 3);
111
- const tcoordsArray = new Float32Array(nbVerts * 2);
112
- const normalsArray = new Float32Array(nbVerts * 3);
109
+ let pointValues = new Float32Array(nbVerts * 3);
110
+ let colorArray = new Uint8Array(nbVerts * 3);
111
+ let tcoordsArray = new Float32Array(nbVerts * 2);
112
+ let normalsArray = new Float32Array(nbVerts * 3);
113
113
  const hasColor = buffer.colors.length > 0;
114
114
  const hasVertTCoords = buffer.uvs.length > 0;
115
115
  const hasNorms = buffer.normals.length > 0;
116
116
  const hasFaceTCoords = buffer.faceVertexUvs.length > 0;
117
+
118
+ // For duplicate point handling
119
+ const pointIds = new Map(); // Maps texture coords to arrays of point IDs
120
+ let nextPointId = nbVerts;
121
+
122
+ // Initialize base points
117
123
  for (let vertIdx = 0; vertIdx < nbVerts; vertIdx++) {
118
124
  let a = vertIdx * 3 + 0;
119
125
  let b = vertIdx * 3 + 1;
@@ -131,6 +137,10 @@ function postProcess(buffer, elements) {
131
137
  b = vertIdx * 2 + 1;
132
138
  tcoordsArray[a] = buffer.uvs[a];
133
139
  tcoordsArray[b] = buffer.uvs[b];
140
+ } else {
141
+ // Initialize with sentinel value
142
+ tcoordsArray[vertIdx * 2] = -1;
143
+ tcoordsArray[vertIdx * 2 + 1] = -1;
134
144
  }
135
145
  if (hasNorms) {
136
146
  normalsArray[a] = buffer.normals[a];
@@ -138,33 +148,153 @@ function postProcess(buffer, elements) {
138
148
  normalsArray[c] = buffer.normals[c];
139
149
  }
140
150
  }
141
- if (!hasVertTCoords && hasFaceTCoords) {
151
+
152
+ // Process face texture coordinates
153
+ if (hasFaceTCoords && !hasVertTCoords && nbFaces > 0) {
142
154
  // don't use array.shift, because buffer.indices will be used later
143
155
  let idxVerts = 0;
144
156
  let idxCoord = 0;
145
- for (let faceIdx = 0; faceIdx < nbFaces; ++faceIdx) {
146
- const nbFaceVerts = buffer.indices[idxVerts++];
147
- const texcoords = buffer.faceVertexUvs[idxCoord++];
148
- if (texcoords && nbFaceVerts * 2 === texcoords.length) {
149
- // grab the vertex index
150
- for (let vertIdx = 0; vertIdx < nbFaceVerts; ++vertIdx) {
151
- const vert = buffer.indices[idxVerts++];
152
- // new texture stored at the current face
153
- tcoordsArray[vert * 2 + 0] = texcoords[vertIdx * 2 + 0];
154
- tcoordsArray[vert * 2 + 1] = texcoords[vertIdx * 2 + 1];
157
+ if (duplicatePointsForFaceTexture) {
158
+ // Arrays to store duplicated point data
159
+ const extraPoints = [];
160
+ const extraColors = [];
161
+ const extraNormals = [];
162
+ const extraTCoords = [];
163
+ for (let faceIdx = 0; faceIdx < nbFaces; ++faceIdx) {
164
+ const nbFaceVerts = buffer.indices[idxVerts++];
165
+ const texcoords = buffer.faceVertexUvs[idxCoord++];
166
+ if (texcoords && nbFaceVerts * 2 === texcoords.length) {
167
+ for (let vertIdx = 0; vertIdx < nbFaceVerts; ++vertIdx) {
168
+ const vertId = buffer.indices[idxVerts + vertIdx];
169
+ const newTex = [texcoords[vertIdx * 2], texcoords[vertIdx * 2 + 1]];
170
+ const currentTex = [tcoordsArray[vertId * 2], tcoordsArray[vertId * 2 + 1]];
171
+ if (currentTex[0] === -1) {
172
+ // First time seeing texture coordinates for this vertex
173
+ tcoordsArray[vertId * 2] = newTex[0];
174
+ tcoordsArray[vertId * 2 + 1] = newTex[1];
175
+ const key = `${newTex[0]},${newTex[1]}`;
176
+ if (!pointIds.has(key)) {
177
+ pointIds.set(key, []);
178
+ }
179
+ pointIds.get(key).push(vertId);
180
+ } else {
181
+ // Check if we need to duplicate the vertex
182
+ const needsDuplication = Math.abs(currentTex[0] - newTex[0]) > faceTextureTolerance || Math.abs(currentTex[1] - newTex[1]) > faceTextureTolerance;
183
+ if (needsDuplication) {
184
+ const key = `${newTex[0]},${newTex[1]}`;
185
+ let existingPointId = -1;
186
+
187
+ // Check if we already have a point with these texture coordinates
188
+ if (pointIds.has(key)) {
189
+ const candidates = pointIds.get(key);
190
+ for (let i = 0, len = candidates.length; i < len; i++) {
191
+ const candidateId = candidates[i];
192
+ const samePosition = Math.abs(pointValues[candidateId * 3] - pointValues[vertId * 3]) <= faceTextureTolerance && Math.abs(pointValues[candidateId * 3 + 1] - pointValues[vertId * 3 + 1]) <= faceTextureTolerance && Math.abs(pointValues[candidateId * 3 + 2] - pointValues[vertId * 3 + 2]) <= faceTextureTolerance;
193
+ if (samePosition) {
194
+ existingPointId = candidateId;
195
+ break;
196
+ }
197
+ }
198
+ }
199
+ if (existingPointId === -1) {
200
+ // Create new point
201
+ extraPoints.push(pointValues[vertId * 3], pointValues[vertId * 3 + 1], pointValues[vertId * 3 + 2]);
202
+ if (hasColor) {
203
+ extraColors.push(colorArray[vertId * 3], colorArray[vertId * 3 + 1], colorArray[vertId * 3 + 2]);
204
+ }
205
+ if (hasNorms) {
206
+ extraNormals.push(normalsArray[vertId * 3], normalsArray[vertId * 3 + 1], normalsArray[vertId * 3 + 2]);
207
+ }
208
+ extraTCoords.push(newTex[0], newTex[1]);
209
+ if (!pointIds.has(key)) {
210
+ pointIds.set(key, []);
211
+ }
212
+ pointIds.get(key).push(nextPointId);
213
+ buffer.indices[idxVerts + vertIdx] = nextPointId;
214
+ nextPointId++;
215
+ } else {
216
+ buffer.indices[idxVerts + vertIdx] = existingPointId;
217
+ }
218
+ }
219
+ }
220
+ }
155
221
  }
156
- } else {
157
222
  idxVerts += nbFaceVerts;
158
223
  }
224
+
225
+ // Extend arrays with duplicated points if needed
226
+ if (extraPoints.length > 0) {
227
+ const newPointCount = nbVerts + extraPoints.length / 3;
228
+ const newPointValues = new Float32Array(newPointCount * 3);
229
+ const newTcoordsArray = new Float32Array(newPointCount * 2);
230
+ const newColorArray = hasColor ? new Uint8Array(newPointCount * 3) : null;
231
+ const newNormalsArray = hasNorms ? new Float32Array(newPointCount * 3) : null;
232
+
233
+ // Copy existing data
234
+ newPointValues.set(pointValues);
235
+ newTcoordsArray.set(tcoordsArray);
236
+ if (hasColor && newColorArray) {
237
+ newColorArray.set(colorArray);
238
+ }
239
+ if (hasNorms && newNormalsArray) {
240
+ newNormalsArray.set(normalsArray);
241
+ }
242
+
243
+ // Add new data
244
+ newPointValues.set(extraPoints, nbVerts * 3);
245
+ newTcoordsArray.set(extraTCoords, nbVerts * 2);
246
+ if (hasColor && newColorArray) {
247
+ newColorArray.set(extraColors, nbVerts * 3);
248
+ }
249
+ if (hasNorms && newNormalsArray) {
250
+ newNormalsArray.set(extraNormals, nbVerts * 3);
251
+ }
252
+ pointValues = newPointValues;
253
+ tcoordsArray = newTcoordsArray;
254
+ if (hasColor) {
255
+ colorArray = newColorArray;
256
+ }
257
+ if (hasNorms) {
258
+ normalsArray = newNormalsArray;
259
+ }
260
+ }
261
+ } else {
262
+ for (let faceIdx = 0; faceIdx < nbFaces; ++faceIdx) {
263
+ const nbFaceVerts = buffer.indices[idxVerts++];
264
+ const texcoords = buffer.faceVertexUvs[idxCoord++];
265
+ if (texcoords && nbFaceVerts * 2 === texcoords.length) {
266
+ for (let vertIdx = 0; vertIdx < nbFaceVerts; ++vertIdx) {
267
+ const vert = buffer.indices[idxVerts++];
268
+ tcoordsArray[vert * 2] = texcoords[vertIdx * 2];
269
+ tcoordsArray[vert * 2 + 1] = texcoords[vertIdx * 2 + 1];
270
+ }
271
+ } else {
272
+ idxVerts += nbFaceVerts;
273
+ }
274
+ }
159
275
  }
160
276
  }
161
277
  const polydata = vtkPolyData.newInstance();
162
278
  polydata.getPoints().setData(pointValues, 3);
279
+
280
+ // If we have faces, add them as polys
281
+ if (nbFaces > 0) {
282
+ polydata.getPolys().setData(Uint32Array.from(buffer.indices));
283
+ } else {
284
+ // Point cloud - create a vertex list containing all points
285
+ const verts = new Uint32Array(nbVerts * 2);
286
+ for (let i = 0; i < nbVerts; i++) {
287
+ verts[i * 2] = 1; // number of points in vertex cell (always 1)
288
+ verts[i * 2 + 1] = i; // point index
289
+ }
290
+
291
+ polydata.getVerts().setData(verts);
292
+ }
163
293
  if (hasColor) {
164
294
  polydata.getPointData().setScalars(vtkDataArray.newInstance({
165
295
  numberOfComponents: 3,
166
296
  values: colorArray,
167
- name: 'Scalars'
297
+ name: 'RGB'
168
298
  }));
169
299
  }
170
300
  if (hasVertTCoords || hasFaceTCoords) {
@@ -184,7 +314,6 @@ function postProcess(buffer, elements) {
184
314
  values: normalsArray
185
315
  }));
186
316
  }
187
- polydata.getPolys().setData(Uint32Array.from(buffer.indices));
188
317
  return polydata;
189
318
  }
190
319
  function parseNumber(n, type) {
@@ -410,7 +539,10 @@ function vtkPLYReader(publicAPI, model) {
410
539
  }
411
540
 
412
541
  // Header
413
- const text = BinaryHelper.arrayBufferToString(content);
542
+ let text = content;
543
+ if (content instanceof ArrayBuffer) {
544
+ text = BinaryHelper.arrayBufferToString(content);
545
+ }
414
546
  const header = parseHeader(text);
415
547
 
416
548
  // ascii/binary detection
@@ -418,7 +550,7 @@ function vtkPLYReader(publicAPI, model) {
418
550
 
419
551
  // Check if ascii format
420
552
  if (!isBinary) {
421
- publicAPI.parseAsText(content);
553
+ publicAPI.parseAsText(text);
422
554
  return;
423
555
  }
424
556
  model.parseData = content;
@@ -445,7 +577,7 @@ function vtkPLYReader(publicAPI, model) {
445
577
  handleElement(buffer, header.elements[elem].name, element);
446
578
  }
447
579
  }
448
- const polydata = postProcess(buffer, header.elements);
580
+ const polydata = postProcess(buffer, header.elements, model.faceTextureTolerance, model.duplicatePointsForFaceTexture);
449
581
 
450
582
  // Add new output
451
583
  model.output[0] = polydata;
@@ -462,7 +594,10 @@ function vtkPLYReader(publicAPI, model) {
462
594
  model.parseData = content;
463
595
 
464
596
  // Header
465
- const text = BinaryHelper.arrayBufferToString(content);
597
+ let text = content;
598
+ if (content instanceof ArrayBuffer) {
599
+ text = BinaryHelper.arrayBufferToString(content);
600
+ }
466
601
  const header = parseHeader(text);
467
602
 
468
603
  // ascii/binary detection
@@ -504,7 +639,7 @@ function vtkPLYReader(publicAPI, model) {
504
639
  idx++;
505
640
  }
506
641
  }
507
- const polydata = postProcess(buffer, header.elements);
642
+ const polydata = postProcess(buffer, header.elements, model.faceTextureTolerance, model.duplicatePointsForFaceTexture);
508
643
 
509
644
  // Add new output
510
645
  model.output[0] = polydata;
@@ -522,6 +657,8 @@ const DEFAULT_VALUES = {
522
657
  // baseURL: null,
523
658
  // dataAccessHelper: null,
524
659
  // url: null,
660
+ faceTextureTolerance: 1e-6,
661
+ duplicatePointsForFaceTexture: true
525
662
  };
526
663
 
527
664
  // ----------------------------------------------------------------------------
@@ -532,7 +669,7 @@ function extend(publicAPI, model) {
532
669
 
533
670
  // Build VTK API
534
671
  macro.obj(publicAPI, model);
535
- macro.get(publicAPI, model, ['url', 'baseURL']);
672
+ macro.get(publicAPI, model, ['url', 'baseURL', 'duplicatePointsForFaceTexture', 'faceTextureTolerance']);
536
673
  macro.setGet(publicAPI, model, ['dataAccessHelper']);
537
674
  macro.algo(publicAPI, model, 0, 1);
538
675
 
@@ -0,0 +1,45 @@
1
+ function computeCoordShiftAndScale(points) {
2
+ // Find out if shift scale should be used
3
+ // Compute squares of diagonal size and distance from the origin
4
+ let diagSq = 0.0;
5
+ let distSq = 0.0;
6
+ for (let i = 0; i < 3; ++i) {
7
+ const range = points.getRange(i);
8
+ const delta = range[1] - range[0];
9
+ diagSq += delta * delta;
10
+ const distShift = 0.5 * (range[1] + range[0]);
11
+ distSq += distShift * distShift;
12
+ }
13
+ const useShiftAndScale = diagSq > 0 && (Math.abs(distSq) / diagSq > 1.0e6 ||
14
+ // If data is far from the origin relative to its size
15
+ Math.abs(Math.log10(diagSq)) > 3.0 ||
16
+ // If the size is huge when not far from the origin
17
+ diagSq === 0 && distSq > 1.0e6); // If data is a point, but far from the origin
18
+
19
+ if (useShiftAndScale) {
20
+ // Compute shift and scale vectors
21
+ const coordShift = new Float64Array(3);
22
+ const coordScale = new Float64Array(3);
23
+ for (let i = 0; i < 3; ++i) {
24
+ const range = points.getRange(i);
25
+ const delta = range[1] - range[0];
26
+ coordShift[i] = 0.5 * (range[1] + range[0]);
27
+ coordScale[i] = delta > 0 ? 1.0 / delta : 1.0;
28
+ }
29
+ return {
30
+ useShiftAndScale,
31
+ coordShift,
32
+ coordScale
33
+ };
34
+ }
35
+ return {
36
+ useShiftAndScale,
37
+ coordShift: new Float32Array([0, 0, 0]),
38
+ coordScale: new Float32Array([1, 1, 1])
39
+ };
40
+ }
41
+ var helpers = {
42
+ computeCoordShiftAndScale
43
+ };
44
+
45
+ export { computeCoordShiftAndScale, helpers as default };
@@ -3,6 +3,7 @@ import { m as macro } from '../../macros2.js';
3
3
  import vtkBufferObject from './BufferObject.js';
4
4
  import { ObjectType } from './BufferObject/Constants.js';
5
5
  import { Representation } from '../Core/Property/Constants.js';
6
+ import { computeCoordShiftAndScale } from './CellArrayBufferObject/helpers.js';
6
7
 
7
8
  const {
8
9
  vtkErrorMacro
@@ -217,32 +218,12 @@ function vtkOpenGLCellArrayBufferObject(publicAPI, model) {
217
218
  let ucidx = 0;
218
219
 
219
220
  // Find out if shift scale should be used
220
- // Compute squares of diagonal size and distance from the origin
221
- let diagSq = 0.0;
222
- let distSq = 0.0;
223
- for (let i = 0; i < 3; ++i) {
224
- const range = options.points.getRange(i);
225
- const delta = range[1] - range[0];
226
- diagSq += delta * delta;
227
- const distShift = 0.5 * (range[1] + range[0]);
228
- distSq += distShift * distShift;
229
- }
230
- const useShiftAndScale = diagSq > 0 && (Math.abs(distSq) / diagSq > 1.0e6 ||
231
- // If data is far from the origin relative to its size
232
- Math.abs(Math.log10(diagSq)) > 3.0 ||
233
- // If the size is huge when not far from the origin
234
- diagSq === 0 && distSq > 1.0e6); // If data is a point, but far from the origin
235
-
221
+ const {
222
+ useShiftAndScale,
223
+ coordShift,
224
+ coordScale
225
+ } = computeCoordShiftAndScale(options.points);
236
226
  if (useShiftAndScale) {
237
- // Compute shift and scale vectors
238
- const coordShift = new Float64Array(3);
239
- const coordScale = new Float64Array(3);
240
- for (let i = 0; i < 3; ++i) {
241
- const range = options.points.getRange(i);
242
- const delta = range[1] - range[0];
243
- coordShift[i] = 0.5 * (range[1] + range[0]);
244
- coordScale[i] = delta > 0 ? 1.0 / delta : 1.0;
245
- }
246
227
  publicAPI.setCoordShiftAndScale(coordShift, coordScale);
247
228
  } else if (model.coordShiftAndScaleEnabled === true) {
248
229
  // Make sure to reset
@@ -8,6 +8,7 @@ import vtkOpenGLPolyDataMapper from './PolyDataMapper.js';
8
8
  import { v as vtkSphereMapperVS } from './glsl/vtkSphereMapperVS.glsl.js';
9
9
  import { v as vtkPolyDataFS } from './glsl/vtkPolyDataFS.glsl.js';
10
10
  import { registerOverride } from './ViewNodeFactory.js';
11
+ import { computeCoordShiftAndScale } from './CellArrayBufferObject/helpers.js';
11
12
 
12
13
  const {
13
14
  vtkErrorMacro
@@ -112,14 +113,24 @@ function vtkOpenGLSphereMapper(publicAPI, model) {
112
113
  if (program.isUniformUsed('VCPCMatrix')) {
113
114
  program.setUniformMatrix('VCPCMatrix', keyMats.vcpc);
114
115
  }
116
+
117
+ // mat4.create() defaults to Float32Array b/c of gl-matrix's settings.
118
+ // We need Float64Array to avoid loss of precision with large coordinates.
119
+ const tmp4 = new Float64Array(16);
115
120
  if (program.isUniformUsed('MCVCMatrix')) {
116
121
  if (!actor.getIsIdentity()) {
117
122
  const actMats = model.openGLActor.getKeyMatrices();
118
- const tmp4 = new Float64Array(16);
119
123
  mat4.multiply(tmp4, keyMats.wcvc, actMats.mcwc);
124
+ if (cellBO.getCABO().getCoordShiftAndScaleEnabled()) {
125
+ mat4.multiply(tmp4, tmp4, cellBO.getCABO().getInverseShiftAndScaleMatrix());
126
+ }
120
127
  program.setUniformMatrix('MCVCMatrix', tmp4);
121
128
  } else {
122
- program.setUniformMatrix('MCVCMatrix', keyMats.wcvc);
129
+ mat4.copy(tmp4, keyMats.wcvc);
130
+ if (cellBO.getCABO().getCoordShiftAndScaleEnabled()) {
131
+ mat4.multiply(tmp4, tmp4, cellBO.getCABO().getInverseShiftAndScaleMatrix());
132
+ }
133
+ program.setUniformMatrix('MCVCMatrix', tmp4);
123
134
  }
124
135
  }
125
136
  if (program.isUniformUsed('cameraParallel')) {
@@ -166,6 +177,14 @@ function vtkOpenGLSphereMapper(publicAPI, model) {
166
177
  const cos30 = Math.cos(radiansFromDegrees(30.0));
167
178
  let pointIdx = 0;
168
179
  let colorIdx = 0;
180
+ const {
181
+ useShiftAndScale,
182
+ coordShift,
183
+ coordScale
184
+ } = computeCoordShiftAndScale(points);
185
+ if (useShiftAndScale) {
186
+ vbo.setCoordShiftAndScale(coordShift, coordScale);
187
+ }
169
188
 
170
189
  //
171
190
  // Generate points and point data for sides
@@ -178,9 +197,12 @@ function vtkOpenGLSphereMapper(publicAPI, model) {
178
197
  radius = scales[i];
179
198
  }
180
199
  pointIdx = i * 3;
181
- packedVBO[vboIdx++] = pointArray[pointIdx++];
182
- packedVBO[vboIdx++] = pointArray[pointIdx++];
183
- packedVBO[vboIdx++] = pointArray[pointIdx++];
200
+ const ptX = (pointArray[pointIdx++] - coordShift[0]) * coordScale[0];
201
+ const ptY = (pointArray[pointIdx++] - coordShift[1]) * coordScale[1];
202
+ const ptZ = (pointArray[pointIdx++] - coordShift[2]) * coordScale[2];
203
+ packedVBO[vboIdx++] = ptX;
204
+ packedVBO[vboIdx++] = ptY;
205
+ packedVBO[vboIdx++] = ptZ;
184
206
  packedVBO[vboIdx++] = -2.0 * radius * cos30;
185
207
  packedVBO[vboIdx++] = -radius;
186
208
  if (colorData) {
@@ -190,10 +212,9 @@ function vtkOpenGLSphereMapper(publicAPI, model) {
190
212
  packedUCVBO[ucIdx++] = colorData[colorIdx + 2];
191
213
  packedUCVBO[ucIdx++] = colorData[colorIdx + 3];
192
214
  }
193
- pointIdx = i * 3;
194
- packedVBO[vboIdx++] = pointArray[pointIdx++];
195
- packedVBO[vboIdx++] = pointArray[pointIdx++];
196
- packedVBO[vboIdx++] = pointArray[pointIdx++];
215
+ packedVBO[vboIdx++] = ptX;
216
+ packedVBO[vboIdx++] = ptY;
217
+ packedVBO[vboIdx++] = ptZ;
197
218
  packedVBO[vboIdx++] = 2.0 * radius * cos30;
198
219
  packedVBO[vboIdx++] = -radius;
199
220
  if (colorData) {
@@ -202,10 +223,9 @@ function vtkOpenGLSphereMapper(publicAPI, model) {
202
223
  packedUCVBO[ucIdx++] = colorData[colorIdx + 2];
203
224
  packedUCVBO[ucIdx++] = colorData[colorIdx + 3];
204
225
  }
205
- pointIdx = i * 3;
206
- packedVBO[vboIdx++] = pointArray[pointIdx++];
207
- packedVBO[vboIdx++] = pointArray[pointIdx++];
208
- packedVBO[vboIdx++] = pointArray[pointIdx++];
226
+ packedVBO[vboIdx++] = ptX;
227
+ packedVBO[vboIdx++] = ptY;
228
+ packedVBO[vboIdx++] = ptZ;
209
229
  packedVBO[vboIdx++] = 0.0;
210
230
  packedVBO[vboIdx++] = 2.0 * radius;
211
231
  if (colorData) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitware/vtk.js",
3
- "version": "33.0.0",
3
+ "version": "33.0.2",
4
4
  "description": "Visualization Toolkit for the Web",
5
5
  "keywords": [
6
6
  "3d",