@kitware/vtk.js 30.8.0 → 30.9.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.
@@ -3,6 +3,7 @@ import vtkAbstractMapper3D, {
3
3
  IAbstractMapper3DInitialValues,
4
4
  } from './AbstractMapper3D';
5
5
  import { ColorMode, GetArray, ScalarMode } from './Mapper/Constants';
6
+ import vtkDataArray from './../../Common/Core/DataArray';
6
7
 
7
8
  interface IPrimitiveCount {
8
9
  points: number;
@@ -13,6 +14,7 @@ interface IPrimitiveCount {
13
14
 
14
15
  interface IAbstractScalars {
15
16
  cellFlag: boolean;
17
+ scalars: Nullable<vtkDataArray>;
16
18
  }
17
19
 
18
20
  interface ICoincidentTopology {
@@ -54,9 +56,13 @@ export interface vtkMapper extends vtkAbstractMapper3D {
54
56
  * When rendering multiblock datasets, if any 2 blocks provide different
55
57
  * lookup tables for the scalars, then also we cannot use textures. This case
56
58
  * can be handled if required.
57
- * @param input
59
+ * @param scalars
60
+ * @param cellFlag True when the scalars are per cell instead of per point
58
61
  */
59
- canUseTextureMapForColoring(input: any): boolean;
62
+ canUseTextureMapForColoring(
63
+ scalars: vtkDataArray,
64
+ cellFlag: boolean
65
+ ): boolean;
60
66
 
61
67
  /**
62
68
  * Call to force a rebuild of color result arrays on next MapScalars.
@@ -77,26 +83,18 @@ export interface vtkMapper extends vtkAbstractMapper3D {
77
83
  /**
78
84
  *
79
85
  * @param input
80
- * @param output
81
- * @param numScalars
82
- * @param numComps
83
86
  * @param component
84
87
  * @param range
85
- * @param tableRange
86
88
  * @param tableNumberOfColors
87
89
  * @param useLogScale
88
90
  */
89
91
  createColorTextureCoordinates(
90
- input: any,
91
- output: any,
92
- numScalars: number,
93
- numComps: number,
92
+ input: vtkDataArray,
94
93
  component: number,
95
94
  range: any,
96
- tableRange: any,
97
95
  tableNumberOfColors: number,
98
96
  useLogScale: boolean
99
- ): void;
97
+ ): vtkDataArray;
100
98
 
101
99
  /**
102
100
  * Create default lookup table. Generally used to create one when
@@ -120,6 +118,17 @@ export interface vtkMapper extends vtkAbstractMapper3D {
120
118
  arrayName: any
121
119
  ): IAbstractScalars;
122
120
 
121
+ /**
122
+ * When scalars are mapped from cells,
123
+ * there is one color coordinate per cell instead of one per point
124
+ * in the vtkDataArray getColorCoordinates().
125
+ * It means that when getAreScalarsMappedFromCells() is true,
126
+ * the number of tuples in getColorCoordinates() is the number of points,
127
+ * and when getAreScalarsMappedFromCells() is false,
128
+ * the number of tuples in getColorCoordinates() is the number of cells.
129
+ */
130
+ getAreScalarsMappedFromCells(): boolean;
131
+
123
132
  /**
124
133
  *
125
134
  */
@@ -132,7 +132,11 @@ function vtkMapper(publicAPI, model) {
132
132
  };
133
133
  };
134
134
  publicAPI.mapScalars = (input, alpha) => {
135
- const scalars = publicAPI.getAbstractScalars(input, model.scalarMode, model.arrayAccessMode, model.arrayId, model.colorByArrayName).scalars;
135
+ const {
136
+ scalars,
137
+ cellFlag
138
+ } = publicAPI.getAbstractScalars(input, model.scalarMode, model.arrayAccessMode, model.arrayId, model.colorByArrayName);
139
+ model.areScalarsMappedFromCells = cellFlag;
136
140
  if (!scalars) {
137
141
  model.colorCoordinates = null;
138
142
  model.colorTextureMap = null;
@@ -150,7 +154,7 @@ function vtkMapper(publicAPI, model) {
150
154
  // Decide between texture color or vertex color.
151
155
  // Cell data always uses vertex color.
152
156
  // Only point data can use both texture and vertex coloring.
153
- if (publicAPI.canUseTextureMapForColoring(input)) {
157
+ if (publicAPI.canUseTextureMapForColoring(scalars, cellFlag)) {
154
158
  publicAPI.mapScalarsToTexture(scalars, alpha);
155
159
  } else {
156
160
  model.colorCoordinates = null;
@@ -205,50 +209,56 @@ function vtkMapper(publicAPI, model) {
205
209
  };
206
210
 
207
211
  //-----------------------------------------------------------------------------
208
- publicAPI.createColorTextureCoordinates = (input, output, numScalars, numComps, component, range, tableRange, tableNumberOfColors, useLogScale) => {
212
+ publicAPI.createColorTextureCoordinates = (input, component, range, tableNumberOfColors, useLogScale) => {
209
213
  // We have to change the range used for computing texture
210
214
  // coordinates slightly to accommodate the special above- and
211
215
  // below-range colors that are the first and last texels,
212
216
  // respectively.
213
217
  const scalarTexelWidth = (range[1] - range[0]) / tableNumberOfColors;
214
- const paddedRange = [];
215
- paddedRange[0] = range[0] - scalarTexelWidth;
216
- paddedRange[1] = range[1] + scalarTexelWidth;
218
+ const paddedRange = [range[0] - scalarTexelWidth, range[1] + scalarTexelWidth];
217
219
  const invRangeWidth = 1.0 / (paddedRange[1] - paddedRange[0]);
218
- const outputV = output.getData();
219
220
  const inputV = input.getData();
220
- let count = 0;
221
- let outputCount = 0;
221
+ const numScalars = input.getNumberOfTuples();
222
+ const numComps = input.getNumberOfComponents();
223
+ const output = vtkDataArray.newInstance({
224
+ numberOfComponents: 2,
225
+ values: new Float32Array(numScalars * 2)
226
+ });
227
+ const outputV = output.getData();
222
228
  if (component < 0 || component >= numComps) {
229
+ // Convert the magnitude of all components to texture coordinates
230
+ let inputIdx = 0;
231
+ let outputIdx = 0;
223
232
  for (let scalarIdx = 0; scalarIdx < numScalars; ++scalarIdx) {
224
233
  let sum = 0;
225
234
  for (let compIdx = 0; compIdx < numComps; ++compIdx) {
226
- sum += inputV[count] * inputV[count];
227
- count++;
235
+ sum += inputV[inputIdx] * inputV[inputIdx];
236
+ inputIdx++;
228
237
  }
229
238
  let magnitude = Math.sqrt(sum);
230
239
  if (useLogScale) {
231
- magnitude = vtkLookupTable.applyLogScale(magnitude, tableRange, range);
240
+ magnitude = vtkLookupTable.applyLogScale(magnitude, range, range);
232
241
  }
233
242
  const outputs = publicAPI.scalarToTextureCoordinate(magnitude, paddedRange[0], invRangeWidth);
234
- outputV[outputCount] = outputs.texCoordS;
235
- outputV[outputCount + 1] = outputs.texCoordT;
236
- outputCount += 2;
243
+ outputV[outputIdx++] = outputs.texCoordS;
244
+ outputV[outputIdx++] = outputs.texCoordT;
237
245
  }
238
246
  } else {
239
- count += component;
247
+ // Convert one of the components to texture coordinates
248
+ let inputIdx = component;
249
+ let outputIdx = 0;
240
250
  for (let scalarIdx = 0; scalarIdx < numScalars; ++scalarIdx) {
241
- let inputValue = inputV[count];
251
+ let inputValue = inputV[inputIdx];
242
252
  if (useLogScale) {
243
- inputValue = vtkLookupTable.applyLogScale(inputValue, tableRange, range);
253
+ inputValue = vtkLookupTable.applyLogScale(inputValue, range, range);
244
254
  }
245
255
  const outputs = publicAPI.scalarToTextureCoordinate(inputValue, paddedRange[0], invRangeWidth);
246
- outputV[outputCount] = outputs.texCoordS;
247
- outputV[outputCount + 1] = outputs.texCoordT;
248
- outputCount += 2;
249
- count += numComps;
256
+ outputV[outputIdx++] = outputs.texCoordS;
257
+ outputV[outputIdx++] = outputs.texCoordT;
258
+ inputIdx += numComps;
250
259
  }
251
260
  }
261
+ return output;
252
262
  };
253
263
  publicAPI.mapScalarsToTexture = (scalars, alpha) => {
254
264
  const range = model.lookupTable.getRange();
@@ -274,28 +284,23 @@ function vtkMapper(publicAPI, model) {
274
284
  // Create a dummy ramp of scalars.
275
285
  // In the future, we could extend vtkScalarsToColors.
276
286
  model.lookupTable.build();
277
- let numberOfColors = model.lookupTable.getNumberOfAvailableColors();
278
- if (numberOfColors > 4094) {
279
- numberOfColors = 4094;
280
- }
281
- if (numberOfColors < 64) {
282
- numberOfColors = 64;
283
- }
284
- numberOfColors += 2;
285
- const k = (range[1] - range[0]) / (numberOfColors - 2);
286
- const newArray = new Float64Array(numberOfColors * 2);
287
- for (let i = 0; i < numberOfColors; ++i) {
288
- newArray[i] = range[0] + i * k - k / 2.0; // minus k / 2 to start at below range color
287
+ const numberOfColorsInRange = Math.min(Math.max(model.lookupTable.getNumberOfAvailableColors(), 64), 4094);
288
+ // Texel width is computed before min and max colors that are out of range
289
+ const scalarTexelWidth = (range[1] - range[0]) / numberOfColorsInRange;
290
+ // Add two colors for special min and max colors
291
+ const totalNumberOfColors = numberOfColorsInRange + 2;
292
+ const newArray = new Float64Array(totalNumberOfColors * 2);
293
+ for (let i = 0; i < totalNumberOfColors; ++i) {
294
+ // minus 0.5 to start at below range color
295
+ newArray[i] = range[0] + (i - 0.5) * scalarTexelWidth;
289
296
  if (useLogScale) {
290
297
  newArray[i] = 10.0 ** newArray[i];
291
298
  }
292
299
  }
293
300
  // Dimension on NaN.
294
- for (let i = 0; i < numberOfColors; ++i) {
295
- newArray[i + numberOfColors] = NaN;
296
- }
301
+ newArray.fill(NaN, totalNumberOfColors);
297
302
  model.colorTextureMap = vtkImageData.newInstance();
298
- model.colorTextureMap.setExtent(0, numberOfColors - 1, 0, 1, 0, 0);
303
+ model.colorTextureMap.setExtent(0, totalNumberOfColors - 1, 0, 1, 0, 0);
299
304
  const tmp = vtkDataArray.newInstance({
300
305
  numberOfComponents: 1,
301
306
  values: newArray
@@ -304,28 +309,20 @@ function vtkMapper(publicAPI, model) {
304
309
  model.lookupTable.setAlpha(origAlpha);
305
310
  }
306
311
 
307
- // Create new coordinates if necessary.
308
- // Need to compare lookup table in case the range has changed.
309
- if (!model.colorCoordinates || publicAPI.getMTime() > model.colorCoordinates.getMTime() || publicAPI.getInputData(0).getMTime() > model.colorCoordinates.getMTime() || model.lookupTable.getMTime() > model.colorCoordinates.getMTime()) {
310
- // Get rid of old colors
311
- model.colorCoordinates = null;
312
+ // Although I like the feature of applying magnitude to single component
313
+ // scalars, it is not how the old MapScalars for vertex coloring works.
314
+ const scalarComponent = model.lookupTable.getVectorMode() === VectorMode.MAGNITUDE && scalars.getNumberOfComponents() > 1 ? -1 : model.lookupTable.getVectorComponent();
312
315
 
313
- // Now create the color texture coordinates.
314
- const numComps = scalars.getNumberOfComponents();
315
- const num = scalars.getNumberOfTuples();
316
+ // Reverse the computation of numberOfColorsInRange that is used to compute model.colorTextureMap
317
+ const textureMapTuples = model.colorTextureMap.getPointData().getScalars().getNumberOfTuples();
318
+ const totalNumberOfColors = textureMapTuples / 2;
319
+ const numberOfColorsInRange = totalNumberOfColors - 2;
316
320
 
317
- // const fArray = new FloatArray(num * 2);
318
- model.colorCoordinates = vtkDataArray.newInstance({
319
- numberOfComponents: 2,
320
- values: new Float32Array(num * 2)
321
- });
322
- let scalarComponent = model.lookupTable.getVectorComponent();
323
- // Although I like the feature of applying magnitude to single component
324
- // scalars, it is not how the old MapScalars for vertex coloring works.
325
- if (model.lookupTable.getVectorMode() === VectorMode.MAGNITUDE && scalars.getNumberOfComponents() > 1) {
326
- scalarComponent = -1;
327
- }
328
- publicAPI.createColorTextureCoordinates(scalars, model.colorCoordinates, num, numComps, scalarComponent, range, model.lookupTable.getRange(), model.colorTextureMap.getPointData().getScalars().getNumberOfTuples() / 2 - 2, useLogScale);
321
+ // Create new coordinates if necessary.
322
+ const colorCoordinatesString = `${scalars.getMTime()}/${scalarComponent}/${range}/${numberOfColorsInRange}/${useLogScale}`;
323
+ if (colorCoordinatesString !== model.colorCoordinatesString) {
324
+ model.colorCoordinates = publicAPI.createColorTextureCoordinates(scalars, scalarComponent, range, numberOfColorsInRange, useLogScale);
325
+ model.colorCoordinatesString = colorCoordinatesString;
329
326
  }
330
327
  };
331
328
  publicAPI.getIsOpaque = () => {
@@ -344,7 +341,11 @@ function vtkMapper(publicAPI, model) {
344
341
  }
345
342
  return true;
346
343
  };
347
- publicAPI.canUseTextureMapForColoring = input => {
344
+ publicAPI.canUseTextureMapForColoring = (scalars, cellFlag) => {
345
+ if (cellFlag) {
346
+ return true; // cell data always use textures.
347
+ }
348
+
348
349
  if (!model.interpolateScalarsBeforeMapping) {
349
350
  return false; // user doesn't want us to use texture maps at all.
350
351
  }
@@ -353,16 +354,10 @@ function vtkMapper(publicAPI, model) {
353
354
  if (model.lookupTable && model.lookupTable.getIndexedLookup()) {
354
355
  return false;
355
356
  }
356
- const gasResult = publicAPI.getAbstractScalars(input, model.scalarMode, model.arrayAccessMode, model.arrayId, model.colorByArrayName);
357
- const scalars = gasResult.scalars;
358
357
  if (!scalars) {
359
358
  // no scalars on this dataset, we don't care if texture is used at all.
360
359
  return false;
361
360
  }
362
- if (gasResult.cellFlag) {
363
- return false; // cell data colors, don't use textures.
364
- }
365
-
366
361
  if (model.colorMode === ColorMode.DEFAULT && scalars.getDataType() === VtkDataTypes.UNSIGNED_CHAR || model.colorMode === ColorMode.DIRECT_SCALARS) {
367
362
  // Don't use texture is direct coloring using RGB unsigned chars is
368
363
  // requested.
@@ -464,7 +459,7 @@ function vtkMapper(publicAPI, model) {
464
459
  const DEFAULT_VALUES = {
465
460
  colorMapColors: null,
466
461
  // Same as this->Colors
467
-
462
+ areScalarsMappedFromCells: false,
468
463
  static: false,
469
464
  lookupTable: null,
470
465
  scalarVisibility: true,
@@ -497,7 +492,7 @@ function extend(publicAPI, model) {
497
492
 
498
493
  // Inheritance
499
494
  vtkAbstractMapper3D.extend(publicAPI, model, initialValues);
500
- macro.get(publicAPI, model, ['colorCoordinates', 'colorMapColors', 'colorTextureMap', 'selectionWebGLIdsToVTKIds']);
495
+ macro.get(publicAPI, model, ['areScalarsMappedFromCells', 'colorCoordinates', 'colorMapColors', 'colorTextureMap', 'selectionWebGLIdsToVTKIds']);
501
496
  macro.setGet(publicAPI, model, ['colorByArrayName', 'arrayAccessMode', 'colorMode', 'fieldDataTupleId', 'interpolateScalarsBeforeMapping', 'lookupTable', 'populateSelectionSettings', 'renderTime', 'scalarMode', 'scalarVisibility', 'static', 'useLookupTableScalarRange', 'customShaderAttributes' // point data array names that will be transferred to the VBO
502
497
  ]);
503
498
 
@@ -104,52 +104,52 @@ function vtkOpenGLCellArrayBufferObject(publicAPI, model) {
104
104
  let addAPoint;
105
105
  const cellBuilders = {
106
106
  // easy, every input point becomes an output point
107
- anythingToPoints(numPoints, cellPts, offset) {
107
+ anythingToPoints(numPoints, cellPts, offset, cellId) {
108
108
  for (let i = 0; i < numPoints; ++i) {
109
- addAPoint(cellPts[offset + i]);
109
+ addAPoint(cellPts[offset + i], cellId);
110
110
  }
111
111
  },
112
- linesToWireframe(numPoints, cellPts, offset) {
112
+ linesToWireframe(numPoints, cellPts, offset, cellIdx) {
113
113
  // for lines we add a bunch of segments
114
114
  for (let i = 0; i < numPoints - 1; ++i) {
115
- addAPoint(cellPts[offset + i]);
116
- addAPoint(cellPts[offset + i + 1]);
115
+ addAPoint(cellPts[offset + i], cellIdx);
116
+ addAPoint(cellPts[offset + i + 1], cellIdx);
117
117
  }
118
118
  },
119
- polysToWireframe(numPoints, cellPts, offset) {
119
+ polysToWireframe(numPoints, cellPts, offset, cellIdx) {
120
120
  // for polys we add a bunch of segments and close it
121
121
  if (numPoints > 2) {
122
122
  for (let i = 0; i < numPoints; ++i) {
123
- addAPoint(cellPts[offset + i]);
124
- addAPoint(cellPts[offset + (i + 1) % numPoints]);
123
+ addAPoint(cellPts[offset + i], cellIdx);
124
+ addAPoint(cellPts[offset + (i + 1) % numPoints], cellIdx);
125
125
  }
126
126
  }
127
127
  },
128
- stripsToWireframe(numPoints, cellPts, offset) {
128
+ stripsToWireframe(numPoints, cellPts, offset, cellIdx) {
129
129
  if (numPoints > 2) {
130
130
  // for strips we add a bunch of segments and close it
131
131
  for (let i = 0; i < numPoints - 1; ++i) {
132
- addAPoint(cellPts[offset + i]);
133
- addAPoint(cellPts[offset + i + 1]);
132
+ addAPoint(cellPts[offset + i], cellIdx);
133
+ addAPoint(cellPts[offset + i + 1], cellIdx);
134
134
  }
135
135
  for (let i = 0; i < numPoints - 2; i++) {
136
- addAPoint(cellPts[offset + i]);
137
- addAPoint(cellPts[offset + i + 2]);
136
+ addAPoint(cellPts[offset + i], cellIdx);
137
+ addAPoint(cellPts[offset + i + 2], cellIdx);
138
138
  }
139
139
  }
140
140
  },
141
- polysToSurface(npts, cellPts, offset) {
141
+ polysToSurface(npts, cellPts, offset, cellIdx) {
142
142
  for (let i = 0; i < npts - 2; i++) {
143
- addAPoint(cellPts[offset + 0]);
144
- addAPoint(cellPts[offset + i + 1]);
145
- addAPoint(cellPts[offset + i + 2]);
143
+ addAPoint(cellPts[offset + 0], cellIdx);
144
+ addAPoint(cellPts[offset + i + 1], cellIdx);
145
+ addAPoint(cellPts[offset + i + 2], cellIdx);
146
146
  }
147
147
  },
148
- stripsToSurface(npts, cellPts, offset) {
148
+ stripsToSurface(npts, cellPts, offset, cellIdx) {
149
149
  for (let i = 0; i < npts - 2; i++) {
150
- addAPoint(cellPts[offset + i]);
151
- addAPoint(cellPts[offset + i + 1 + i % 2]);
152
- addAPoint(cellPts[offset + i + 1 + (i + 1) % 2]);
150
+ addAPoint(cellPts[offset + i], cellIdx);
151
+ addAPoint(cellPts[offset + i + 1 + i % 2], cellIdx);
152
+ addAPoint(cellPts[offset + i + 1 + (i + 1) % 2], cellIdx);
153
153
  }
154
154
  }
155
155
  };
@@ -264,16 +264,16 @@ function vtkOpenGLCellArrayBufferObject(publicAPI, model) {
264
264
  }
265
265
  }
266
266
  let pointCount = options.vertexOffset;
267
- addAPoint = function addAPointFunc(i) {
267
+ addAPoint = function addAPointFunc(pointId, cellId) {
268
268
  // Keep track of original point and cell ids, for selection
269
269
  if (selectionMaps) {
270
- selectionMaps.points[pointCount] = i;
270
+ selectionMaps.points[pointCount] = pointId;
271
271
  selectionMaps.cells[pointCount] = cellCount + options.cellOffset;
272
272
  }
273
273
  ++pointCount;
274
274
 
275
275
  // Vertices
276
- pointIdx = i * 3;
276
+ pointIdx = pointId * 3;
277
277
  if (!model.coordShiftAndScaleEnabled) {
278
278
  packedVBO[vboidx++] = pointData[pointIdx++];
279
279
  packedVBO[vboidx++] = pointData[pointIdx++];
@@ -288,20 +288,24 @@ function vtkOpenGLCellArrayBufferObject(publicAPI, model) {
288
288
  if (options.haveCellNormals) {
289
289
  normalIdx = (cellCount + options.cellOffset) * 3;
290
290
  } else {
291
- normalIdx = i * 3;
291
+ normalIdx = pointId * 3;
292
292
  }
293
293
  packedVBO[vboidx++] = normalData[normalIdx++];
294
294
  packedVBO[vboidx++] = normalData[normalIdx++];
295
295
  packedVBO[vboidx++] = normalData[normalIdx++];
296
296
  }
297
297
  model.customData.forEach(attr => {
298
- custIdx = i * attr.components;
298
+ custIdx = pointId * attr.components;
299
299
  for (let j = 0; j < attr.components; ++j) {
300
300
  packedVBO[vboidx++] = attr.data[custIdx++];
301
301
  }
302
302
  });
303
303
  if (tcoordData !== null) {
304
- tcoordIdx = i * textureComponents;
304
+ if (options.useTCoordsPerCell) {
305
+ tcoordIdx = cellId * textureComponents;
306
+ } else {
307
+ tcoordIdx = pointId * textureComponents;
308
+ }
305
309
  for (let j = 0; j < textureComponents; ++j) {
306
310
  packedVBO[vboidx++] = tcoordData[tcoordIdx++];
307
311
  }
@@ -310,7 +314,7 @@ function vtkOpenGLCellArrayBufferObject(publicAPI, model) {
310
314
  if (options.haveCellScalars) {
311
315
  colorIdx = (cellCount + options.cellOffset) * colorComponents;
312
316
  } else {
313
- colorIdx = i * colorComponents;
317
+ colorIdx = pointId * colorComponents;
314
318
  }
315
319
  packedUCVBO[ucidx++] = colorData[colorIdx++];
316
320
  packedUCVBO[ucidx++] = colorData[colorIdx++];
@@ -318,10 +322,11 @@ function vtkOpenGLCellArrayBufferObject(publicAPI, model) {
318
322
  packedUCVBO[ucidx++] = colorComponents === 4 ? colorData[colorIdx++] : 255;
319
323
  }
320
324
  };
321
- for (let index = 0; index < size;) {
322
- func(array[index], array, index + 1);
323
- index += array[index] + 1;
324
- cellCount++;
325
+
326
+ // Browse the cell array: the index is at the beginning of a cell
327
+ // The value of 'array' at the position 'index' is the number of points in the cell
328
+ for (let index = 0; index < size; index += array[index] + 1, cellCount++) {
329
+ func(array[index], array, index + 1, cellCount);
325
330
  }
326
331
  model.elementCount = caboCount;
327
332
  publicAPI.upload(packedVBO, ObjectType.ARRAY_BUFFER);
@@ -147,7 +147,7 @@ function vtkOpenGLPolyDataMapper(publicAPI, model) {
147
147
  if (model.lastBoundBO.getCABO().getColorComponents() !== 0 && !model.drawingEdges) {
148
148
  FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Color::Impl', colorImpl.concat([' diffuseColor = vertexColorVSOutput.rgb;', ' ambientColor = vertexColorVSOutput.rgb;', ' opacity = opacity*vertexColorVSOutput.a;'])).result;
149
149
  } else {
150
- if (model.renderable.getInterpolateScalarsBeforeMapping() && model.renderable.getColorCoordinates() && !model.drawingEdges) {
150
+ if ((model.renderable.getAreScalarsMappedFromCells() || model.renderable.getInterpolateScalarsBeforeMapping()) && model.renderable.getColorCoordinates() && !model.drawingEdges) {
151
151
  FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::Color::Impl', colorImpl.concat([' vec4 texColor = texture2D(texture1, tcoordVCVSOutput.st);', ' diffuseColor = texColor.rgb;', ' ambientColor = texColor.rgb;', ' opacity = opacity*texColor.a;'])).result;
152
152
  } else {
153
153
  if (actor.getBackfaceProperty() && !model.drawingEdges) {
@@ -993,9 +993,12 @@ function vtkOpenGLPolyDataMapper(publicAPI, model) {
993
993
  tcoords = null;
994
994
  }
995
995
 
996
+ // Flag to check if tcoords are per cell instead of per point
997
+ let useTCoordsPerCell = false;
996
998
  // handle color mapping via texture
997
999
  if (model.renderable.getColorCoordinates()) {
998
1000
  tcoords = model.renderable.getColorCoordinates();
1001
+ useTCoordsPerCell = model.renderable.getAreScalarsMappedFromCells();
999
1002
  if (!model.internalColorTexture) {
1000
1003
  model.internalColorTexture = vtkOpenGLTexture.newInstance({
1001
1004
  resizable: true
@@ -1028,6 +1031,7 @@ function vtkOpenGLPolyDataMapper(publicAPI, model) {
1028
1031
  cellOffset: 0,
1029
1032
  vertexOffset: 0,
1030
1033
  // Used to keep track of vertex ids across primitives for selection
1034
+ useTCoordsPerCell,
1031
1035
  haveCellScalars: model.haveCellScalars,
1032
1036
  haveCellNormals: model.haveCellNormals,
1033
1037
  customAttributes: model.renderable.getCustomShaderAttributes().map(arrayName => poly.getPointData().getArrayByName(arrayName))
@@ -1085,9 +1089,9 @@ function vtkOpenGLPolyDataMapper(publicAPI, model) {
1085
1089
  model.renderable.setSelectionWebGLIdsToVTKIds(model.selectionWebGLIdsToVTKIds);
1086
1090
  publicAPI.updateMaximumPointCellIds();
1087
1091
  }
1088
- model.VBOBuildTime.modified();
1089
1092
  model.VBOBuildString = toString;
1090
1093
  }
1094
+ model.VBOBuildTime.modified();
1091
1095
  };
1092
1096
  publicAPI.getAllocatedGPUMemoryInBytes = () => {
1093
1097
  let memUsed = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitware/vtk.js",
3
- "version": "30.8.0",
3
+ "version": "30.9.0",
4
4
  "description": "Visualization Toolkit for the Web",
5
5
  "keywords": [
6
6
  "3d",