@kitware/vtk.js 34.4.0 → 34.6.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.
Files changed (66) hide show
  1. package/Common/Core/CellArray.d.ts +3 -0
  2. package/Common/Core/CellArray.js +12 -1
  3. package/Common/Core/DataArray.d.ts +15 -0
  4. package/Common/Core/DataArray.js +8 -4
  5. package/Common/Core/Math/index.js +1 -1
  6. package/Common/Core/Math.js +1 -1
  7. package/Common/DataModel/Triangle.d.ts +68 -19
  8. package/Common/DataModel/Triangle.js +140 -1
  9. package/Common/DataModel/TriangleStrip.d.ts +180 -0
  10. package/Common/DataModel/TriangleStrip.js +396 -0
  11. package/Common/DataModel.js +3 -1
  12. package/Common/Transform/LandmarkTransform.js +1 -1
  13. package/Common/Transform/Transform.d.ts +112 -1
  14. package/Common/Transform/Transform.js +301 -2
  15. package/Filters/Core/Cutter.js +41 -0
  16. package/Filters/General/OBBTree.js +1 -1
  17. package/Filters/General/TransformPolyDataFilter.d.ts +75 -0
  18. package/Filters/General/TransformPolyDataFilter.js +194 -0
  19. package/Filters/General.js +2 -0
  20. package/Filters/Sources/CircleSource.js +1 -1
  21. package/Filters/Sources/PointSource.js +1 -1
  22. package/Filters/Texture/TextureMapToPlane.js +1 -1
  23. package/IO/Geometry/DracoReader.js +1 -1
  24. package/IO/Geometry/GLTFImporter/Animations.js +1 -1
  25. package/IO/Geometry/GLTFImporter/Reader.js +2 -2
  26. package/IO/Image/HDRReader/Utils.js +1 -1
  27. package/IO/Image/HDRReader.js +1 -1
  28. package/Interaction/Manipulators/MouseCameraTrackballRollManipulator.js +1 -1
  29. package/Interaction/Manipulators/MouseCameraTrackballRotateManipulator.js +1 -1
  30. package/Interaction/Manipulators/MouseCameraUnicamManipulator.js +1 -1
  31. package/Interaction/Manipulators/MouseCameraUnicamRotateManipulator.js +1 -1
  32. package/Interaction/Style/InteractorStyleTrackballCamera.js +1 -1
  33. package/Interaction/Widgets/PiecewiseGaussianWidget.js +1 -1
  34. package/Proxy/Core/View2DProxy.js +1 -1
  35. package/Rendering/Core/AbstractImageMapper.js +1 -1
  36. package/Rendering/Core/AbstractMapper3D.js +1 -1
  37. package/Rendering/Core/ColorTransferFunction/CssFilters.js +1 -1
  38. package/Rendering/Core/ColorTransferFunction.js +1 -1
  39. package/Rendering/Core/Coordinate.js +1 -1
  40. package/Rendering/Core/CubeAxesActor.js +1 -1
  41. package/Rendering/Core/Glyph3DMapper.js +1 -1
  42. package/Rendering/Core/ImageArrayMapper.js +1 -1
  43. package/Rendering/Core/ImageMapper.js +1 -1
  44. package/Rendering/Core/ImageProperty.d.ts +10 -4
  45. package/Rendering/Core/Mapper.js +1 -1
  46. package/Rendering/Core/Mapper2D.js +362 -8
  47. package/Rendering/Core/Prop3D.js +1 -1
  48. package/Rendering/Core/RenderWindowInteractor.js +3 -3
  49. package/Rendering/Core/Renderer.js +1 -1
  50. package/Rendering/Core/ScalarBarActor.js +1 -1
  51. package/Rendering/Core/TextActor.js +1 -1
  52. package/Rendering/Core/VectorText/Utils.js +1 -1
  53. package/Rendering/Core/VolumeProperty.js +1 -1
  54. package/Rendering/OpenGL/ImageMapper.js +90 -20
  55. package/Rendering/OpenGL/PolyDataMapper2D.js +89 -30
  56. package/Rendering/OpenGL/Texture.js +1 -1
  57. package/Rendering/OpenGL/VolumeMapper.js +21 -19
  58. package/Widgets/Manipulators/LineManipulator.js +1 -1
  59. package/Widgets/Representations/PolyLineRepresentation.js +1 -1
  60. package/Widgets/Widgets3D/AngleWidget.js +1 -1
  61. package/Widgets/Widgets3D/LineWidget/helpers.js +1 -1
  62. package/Widgets/Widgets3D/ResliceCursorWidget/behavior.js +1 -1
  63. package/Widgets/Widgets3D/ResliceCursorWidget/helpers.js +1 -1
  64. package/Widgets/Widgets3D/ResliceCursorWidget.js +1 -1
  65. package/index.d.ts +2 -0
  66. package/package.json +1 -1
@@ -1,6 +1,10 @@
1
1
  import { m as macro } from '../../macros2.js';
2
2
  import vtkAbstractMapper from './AbstractMapper.js';
3
+ import vtkDataArray from '../../Common/Core/DataArray.js';
4
+ import vtkImageData from '../../Common/DataModel/ImageData.js';
3
5
  import vtkLookupTable from '../../Common/Core/LookupTable.js';
6
+ import vtkScalarsToColors from '../../Common/Core/ScalarsToColors/Constants.js';
7
+ import { i as isNan } from '../../Common/Core/Math/index.js';
4
8
  import Constants from './Mapper/Constants.js';
5
9
 
6
10
  const {
@@ -8,6 +12,237 @@ const {
8
12
  ScalarMode,
9
13
  GetArray
10
14
  } = Constants;
15
+ const {
16
+ VectorMode
17
+ } = vtkScalarsToColors;
18
+ const {
19
+ VtkDataTypes
20
+ } = vtkDataArray;
21
+
22
+ /**
23
+ * Increase by one the 3D coordinates
24
+ * It will follow a zigzag pattern so that each coordinate is the neighbor of the next coordinate
25
+ * This enables interpolation between two texels without issues
26
+ * Note: texture coordinates can't be interpolated using this pattern
27
+ * @param {vec3} coordinates The 3D coordinates using integers for each coordinate
28
+ * @param {vec3} dimensions The 3D dimensions of the volume
29
+ */
30
+ function updateZigzaggingCoordinates(coordinates, dimensions) {
31
+ const directionX = coordinates[1] % 2 === 0 ? 1 : -1;
32
+ coordinates[0] += directionX;
33
+ if (coordinates[0] >= dimensions[0] || coordinates[0] < 0) {
34
+ const directionY = coordinates[2] % 2 === 0 ? 1 : -1;
35
+ coordinates[0] -= directionX;
36
+ coordinates[1] += directionY;
37
+ if (coordinates[1] >= dimensions[1] || coordinates[1] < 0) {
38
+ coordinates[1] -= directionY;
39
+ coordinates[2]++;
40
+ }
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Returns the index in the array representing the volume from a 3D coordinate
46
+ * @param {vec3} coordinates The 3D integer coordinates
47
+ * @param {vec3} dimensions The 3D dimensions of the volume
48
+ * @returns The index in a flat array representing the volume
49
+ */
50
+ function getIndexFromCoordinates(coordinates, dimensions) {
51
+ return coordinates[0] + dimensions[0] * (coordinates[1] + dimensions[1] * coordinates[2]);
52
+ }
53
+
54
+ /**
55
+ * Write texture coordinates for the given `texelIndexPosition` in `textureCoordinate`.
56
+ * The `texelIndexPosition` is a floating point number that represents the distance in index space
57
+ * from the center of the first texel to the final output position.
58
+ * The output is given in texture coordinates and not in index coordinates (this is done at the very end of the function)
59
+ * @param {vec3} textureCoordinate The output texture coordinates (to avoid allocating a new Array)
60
+ * @param {Number} texelIndexPosition The floating point distance from the center of the first texel, following a zigzag pattern
61
+ * @param {vec3} dimensions The 3D dimensions of the volume
62
+ */
63
+ function getZigZagTextureCoordinatesFromTexelPosition(textureCoordinate, texelIndexPosition, dimensions) {
64
+ // First compute the integer textureCoordinate
65
+ const intTexelIndex = Math.floor(texelIndexPosition);
66
+ const xCoordBeforeWrap = intTexelIndex % (2 * dimensions[0]);
67
+ let xDirection;
68
+ let xEndFlag;
69
+ if (xCoordBeforeWrap < dimensions[0]) {
70
+ textureCoordinate[0] = xCoordBeforeWrap;
71
+ xDirection = 1;
72
+ xEndFlag = textureCoordinate[0] === dimensions[0] - 1;
73
+ } else {
74
+ textureCoordinate[0] = 2 * dimensions[0] - 1 - xCoordBeforeWrap;
75
+ xDirection = -1;
76
+ xEndFlag = textureCoordinate[0] === 0;
77
+ }
78
+ const intRowIndex = Math.floor(intTexelIndex / dimensions[0]);
79
+ const yCoordBeforeWrap = intRowIndex % (2 * dimensions[1]);
80
+ let yDirection;
81
+ let yEndFlag;
82
+ if (yCoordBeforeWrap < dimensions[1]) {
83
+ textureCoordinate[1] = yCoordBeforeWrap;
84
+ yDirection = 1;
85
+ yEndFlag = textureCoordinate[1] === dimensions[1] - 1;
86
+ } else {
87
+ textureCoordinate[1] = 2 * dimensions[1] - 1 - yCoordBeforeWrap;
88
+ yDirection = -1;
89
+ yEndFlag = textureCoordinate[1] === 0;
90
+ }
91
+ textureCoordinate[2] = Math.floor(intRowIndex / dimensions[1]);
92
+
93
+ // Now add the remainder either in x, y or z
94
+ const remainder = texelIndexPosition - intTexelIndex;
95
+ if (xEndFlag) {
96
+ if (yEndFlag) {
97
+ textureCoordinate[2] += remainder;
98
+ } else {
99
+ textureCoordinate[1] += yDirection * remainder;
100
+ }
101
+ } else {
102
+ textureCoordinate[0] += xDirection * remainder;
103
+ }
104
+
105
+ // textureCoordinates are in index space, convert to texture space
106
+ textureCoordinate[0] = (textureCoordinate[0] + 0.5) / dimensions[0];
107
+ textureCoordinate[1] = (textureCoordinate[1] + 0.5) / dimensions[1];
108
+ textureCoordinate[2] = (textureCoordinate[2] + 0.5) / dimensions[2];
109
+ }
110
+ // Associate an input vtkDataArray to an object { stringHash, textureCoordinates }
111
+ // A single dataArray only caches one array of texture coordinates, so this cache is useless when
112
+ // the input data array is used with two different lookup tables (which is very unlikely)
113
+ const colorTextureCoordinatesCache = new WeakMap();
114
+ /**
115
+ * The minimum of the range is mapped to the center of the first texel excluding min texel (texel at index distance 1)
116
+ * The maximum of the range is mapped to the center of the last texel excluding max and NaN texels (texel at index distance numberOfColorsInRange)
117
+ * The result is cached, and is reused if the arguments are the same and the input doesn't change
118
+ * @param {vtkDataArray} input The input data array used for coloring
119
+ * @param {Number} component The component of the input data array that is used for coloring (-1 for magnitude of the vectors)
120
+ * @param {Range} range The range of the scalars
121
+ * @param {boolean} useLogScale Should the values be transformed to logarithmic scale. When true, the range must already be in logarithmic scale.
122
+ * @param {Number} numberOfColorsInRange The number of colors that are used in the range
123
+ * @param {vec3} dimensions The dimensions of the texture
124
+ * @param {boolean} useZigzagPattern If a zigzag pattern should be used. Otherwise 1 row for colors (including min and max) and 1 row for NaN are used.
125
+ * @returns A vtkDataArray containing the texture coordinates (2D or 3D)
126
+ */
127
+ function getOrCreateColorTextureCoordinates(input, component, range, useLogScale, numberOfColorsInRange, dimensions, useZigzagPattern) {
128
+ // Caching using the "arguments" special object (because it is a pure function)
129
+ const argStrings = new Array(arguments.length);
130
+ for (let argIndex = 0; argIndex < arguments.length; ++argIndex) {
131
+ // eslint-disable-next-line prefer-rest-params
132
+ const arg = arguments[argIndex];
133
+ argStrings[argIndex] = arg.getMTime?.() ?? arg;
134
+ }
135
+ const stringHash = argStrings.join('/');
136
+ const cachedResult = colorTextureCoordinatesCache.get(input);
137
+ if (cachedResult && cachedResult.stringHash === stringHash) {
138
+ return cachedResult.textureCoordinates;
139
+ }
140
+
141
+ // The range used for computing coordinates have to change
142
+ // slightly to accommodate the special above- and below-range
143
+ // colors that are the first and last texels, respectively.
144
+ const scalarTexelWidth = (range[1] - range[0]) / (numberOfColorsInRange - 1);
145
+ const [paddedRangeMin, paddedRangeMax] = [range[0] - scalarTexelWidth, range[1] + scalarTexelWidth];
146
+
147
+ // Use the center of the voxel
148
+ const textureSOrigin = paddedRangeMin - 0.5 * scalarTexelWidth;
149
+ const textureSCoeff = 1.0 / (paddedRangeMax - paddedRangeMin + scalarTexelWidth);
150
+
151
+ // Compute in index space first
152
+ const texelIndexOrigin = paddedRangeMin;
153
+ const texelIndexCoeff = (numberOfColorsInRange + 1) / (paddedRangeMax - paddedRangeMin);
154
+ const inputV = input.getData();
155
+ const numScalars = input.getNumberOfTuples();
156
+ const numComps = input.getNumberOfComponents();
157
+ const useMagnitude = component < 0 || component >= numComps;
158
+ const numberOfOutputComponents = dimensions[2] <= 1 ? 2 : 3;
159
+ const output = vtkDataArray.newInstance({
160
+ numberOfComponents: numberOfOutputComponents,
161
+ values: new Float32Array(numScalars * numberOfOutputComponents)
162
+ });
163
+ const outputV = output.getData();
164
+ const nanTextureCoordinate = [0, 0, 0];
165
+ // Distance of NaN from the beginning:
166
+ // min: 0, ...colorsInRange, max: numberOfColorsInRange + 1, NaN = numberOfColorsInRange + 2
167
+ getZigZagTextureCoordinatesFromTexelPosition(nanTextureCoordinate, numberOfColorsInRange + 2, dimensions);
168
+
169
+ // Set a texture coordinate in the output for each tuple in the input
170
+ let inputIdx = 0;
171
+ let outputIdx = 0;
172
+ const textureCoordinate = [0.5, 0.5, 0.5];
173
+ for (let scalarIdx = 0; scalarIdx < numScalars; ++scalarIdx) {
174
+ // Get scalar value from magnitude or a single component
175
+ let scalarValue;
176
+ if (useMagnitude) {
177
+ let sum = 0;
178
+ for (let compIdx = 0; compIdx < numComps; ++compIdx) {
179
+ const compValue = inputV[inputIdx + compIdx];
180
+ sum += compValue * compValue;
181
+ }
182
+ scalarValue = Math.sqrt(sum);
183
+ } else {
184
+ scalarValue = inputV[inputIdx + component];
185
+ }
186
+ if (useLogScale) {
187
+ scalarValue = Math.log10(scalarValue);
188
+ }
189
+ inputIdx += numComps;
190
+
191
+ // Convert to texture coordinates and update output
192
+ if (isNan(scalarValue)) {
193
+ // Last texels are NaN colors (there is at least one NaN color)
194
+ textureCoordinate[0] = nanTextureCoordinate[0];
195
+ textureCoordinate[1] = nanTextureCoordinate[1];
196
+ textureCoordinate[2] = nanTextureCoordinate[2];
197
+ } else if (useZigzagPattern) {
198
+ // Texel position is in [0, numberOfColorsInRange + 1]
199
+ let texelIndexPosition = (scalarValue - texelIndexOrigin) * texelIndexCoeff;
200
+ if (texelIndexPosition < 1) {
201
+ // Use min color when smaller than range
202
+ texelIndexPosition = 0;
203
+ } else if (texelIndexPosition > numberOfColorsInRange) {
204
+ // Use max color when greater than range
205
+ texelIndexPosition = numberOfColorsInRange + 1;
206
+ }
207
+
208
+ // Convert the texel position into texture coordinate following a zigzag pattern
209
+ getZigZagTextureCoordinatesFromTexelPosition(textureCoordinate, texelIndexPosition, dimensions);
210
+ } else {
211
+ // 0.0 in t coordinate means not NaN. So why am I setting it to 0.49?
212
+ // Because when you are mapping scalars and you have a NaN adjacent to
213
+ // anything else, the interpolation everywhere should be NaN. Thus, I
214
+ // want the NaN color everywhere except right on the non-NaN neighbors.
215
+ // To simulate this, I set the t coord for the real numbers close to
216
+ // the threshold so that the interpolation almost immediately looks up
217
+ // the NaN value.
218
+ textureCoordinate[1] = 0.49;
219
+
220
+ // Some implementations apparently don't handle relatively large
221
+ // numbers (compared to the range [0.0, 1.0]) very well. In fact,
222
+ // values above 1122.0f appear to cause texture wrap-around on
223
+ // some systems even when edge clamping is enabled. Why 1122.0f? I
224
+ // don't know. For safety, we'll clamp at +/- 1000. This will
225
+ // result in incorrect images when the texture value should be
226
+ // above or below 1000, but I don't have a better solution.
227
+ const textureS = (scalarValue - textureSOrigin) * textureSCoeff;
228
+ if (textureS > 1000.0) {
229
+ textureCoordinate[0] = 1000.0;
230
+ } else if (textureS < -1000.0) {
231
+ textureCoordinate[0] = -1000.0;
232
+ } else {
233
+ textureCoordinate[0] = textureS;
234
+ }
235
+ }
236
+ for (let i = 0; i < numberOfOutputComponents; ++i) {
237
+ outputV[outputIdx++] = textureCoordinate[i];
238
+ }
239
+ }
240
+ colorTextureCoordinatesCache.set(input, {
241
+ stringHash,
242
+ textureCoordinates: output
243
+ });
244
+ return output;
245
+ }
11
246
 
12
247
  // ---------------------------------------------------------------------------
13
248
  // vtkMapper2D methods
@@ -35,7 +270,7 @@ function vtkMapper2D(publicAPI, model) {
35
270
  if (!input || !model.scalarVisibility) {
36
271
  return {
37
272
  scalars: null,
38
- cellFLag: false
273
+ cellFlag: false
39
274
  };
40
275
  }
41
276
  let scalars = null;
@@ -96,8 +331,14 @@ function vtkMapper2D(publicAPI, model) {
96
331
  return mt;
97
332
  };
98
333
  publicAPI.mapScalars = (input, alpha) => {
99
- const scalars = publicAPI.getAbstractScalars(input, model.scalarMode, model.arrayAccessMode, model.arrayId, model.colorByArrayName).scalars;
334
+ const {
335
+ scalars,
336
+ cellFlag
337
+ } = publicAPI.getAbstractScalars(input, model.scalarMode, model.arrayAccessMode, model.arrayId, model.colorByArrayName);
338
+ model.areScalarsMappedFromCells = cellFlag;
100
339
  if (!scalars) {
340
+ model.colorCoordinates = null;
341
+ model.colorTextureMap = null;
101
342
  model.colorMapColors = null;
102
343
  return;
103
344
  }
@@ -108,14 +349,124 @@ function vtkMapper2D(publicAPI, model) {
108
349
  if (!model.useLookupTableScalarRange) {
109
350
  publicAPI.getLookupTable().setRange(model.scalarRange[0], model.scalarRange[1]);
110
351
  }
111
- const lut = publicAPI.getLookupTable();
112
- if (lut) {
113
- // Ensure that the lookup table is built
114
- lut.build();
115
- model.colorMapColors = lut.mapScalars(scalars, model.colorMode, model.fieldDataTupleId);
352
+ if (publicAPI.canUseTextureMapForColoring(scalars, cellFlag)) {
353
+ model.mapScalarsToTexture(scalars, cellFlag, alpha);
354
+ } else {
355
+ model.colorCoordinates = null;
356
+ model.colorTextureMap = null;
357
+ const lut = publicAPI.getLookupTable();
358
+ if (lut) {
359
+ // Ensure that the lookup table is built
360
+ lut.build();
361
+ model.colorMapColors = lut.mapScalars(scalars, model.colorMode, model.fieldDataTupleId);
362
+ }
116
363
  }
117
364
  model.colorBuildString = `${publicAPI.getMTime()}${scalars.getMTime()}${alpha}`;
118
365
  };
366
+ publicAPI.canUseTextureMapForColoring = (scalars, cellFlag) => {
367
+ if (cellFlag && !(model.colorMode === ColorMode.DIRECT_SCALARS)) {
368
+ return true; // cell data always use textures.
369
+ }
370
+
371
+ // index color does not use textures
372
+ if (model.lookupTable && model.lookupTable.getIndexedLookup()) {
373
+ return false;
374
+ }
375
+ if (!scalars) {
376
+ // no scalars on this dataset, we don't care if texture is used at all.
377
+ return false;
378
+ }
379
+ if (model.colorMode === ColorMode.DEFAULT && scalars.getDataType() === VtkDataTypes.UNSIGNED_CHAR || model.colorMode === ColorMode.DIRECT_SCALARS) {
380
+ // Don't use texture if direct coloring using RGB unsigned chars is
381
+ // requested.
382
+ return false;
383
+ }
384
+ return true;
385
+ };
386
+
387
+ // Protected method
388
+ model.mapScalarsToTexture = (scalars, cellFlag, alpha) => {
389
+ const range = model.lookupTable.getRange();
390
+ const useLogScale = model.lookupTable.usingLogScale();
391
+ const origAlpha = model.lookupTable.getAlpha();
392
+ const scaledRange = useLogScale ? [Math.log10(range[0]), Math.log10(range[1])] : range;
393
+
394
+ // Get rid of vertex color array. Only texture or vertex coloring
395
+ // can be active at one time. The existence of the array is the
396
+ // signal to use that technique.
397
+ model.colorMapColors = null;
398
+
399
+ // If the lookup table has changed, then recreate the color texture map.
400
+ // Set a new lookup table changes this->MTime.
401
+ if (model.colorTextureMap == null || publicAPI.getMTime() > model.colorTextureMap.getMTime() || model.lookupTable.getMTime() > model.colorTextureMap.getMTime() || model.lookupTable.getAlpha() !== alpha) {
402
+ model.lookupTable.setAlpha(alpha);
403
+ model.colorTextureMap = null;
404
+
405
+ // Get the texture map from the lookup table.
406
+ // Create a dummy ramp of scalars.
407
+ // In the future, we could extend vtkScalarsToColors.
408
+ model.lookupTable.build();
409
+ const numberOfAvailableColors = model.lookupTable.getNumberOfAvailableColors();
410
+
411
+ // Maximum dimensions and number of colors in range
412
+ const maxTextureWidthForCells = 2048;
413
+ const maxColorsInRangeForCells = maxTextureWidthForCells ** 3 - 3; // 3D but keep a color for min, max and NaN
414
+ const maxTextureWidthForPoints = 4096;
415
+ const maxColorsInRangeForPoints = maxTextureWidthForPoints - 2; // 1D but keep a color for min and max (NaN is in a different row)
416
+ // Minimum number of colors in range (excluding special colors like minColor, maxColor and NaNColor)
417
+ const minColorsInRange = 2;
418
+ // Maximum number of colors, limited by the maximum possible texture size
419
+ const maxColorsInRange = cellFlag ? maxColorsInRangeForCells : maxColorsInRangeForPoints;
420
+ model.numberOfColorsInRange = Math.min(Math.max(numberOfAvailableColors, minColorsInRange), maxColorsInRange);
421
+ const numberOfColorsForCells = model.numberOfColorsInRange + 3; // Add min, max and NaN
422
+ const numberOfColorsInUpperRowForPoints = model.numberOfColorsInRange + 2; // Add min and max ; the lower row will be used for NaN color
423
+ const textureDimensions = cellFlag ? [Math.min(Math.ceil(numberOfColorsForCells / maxTextureWidthForCells ** 0), maxTextureWidthForCells), Math.min(Math.ceil(numberOfColorsForCells / maxTextureWidthForCells ** 1), maxTextureWidthForCells), Math.min(Math.ceil(numberOfColorsForCells / maxTextureWidthForCells ** 2), maxTextureWidthForCells)] : [numberOfColorsInUpperRowForPoints, 2, 1];
424
+ const textureSize = textureDimensions[0] * textureDimensions[1] * textureDimensions[2];
425
+ const scalarsArray = new Float64Array(textureSize);
426
+
427
+ // Colors for NaN by default
428
+ scalarsArray.fill(NaN);
429
+
430
+ // Colors in range
431
+ // Add 2 to also get color for min and max
432
+ const numberOfNonSpecialColors = model.numberOfColorsInRange;
433
+ const numberOfNonNaNColors = numberOfNonSpecialColors + 2;
434
+ const textureCoordinates = [0, 0, 0];
435
+ const rangeMin = scaledRange[0];
436
+ const rangeDifference = scaledRange[1] - scaledRange[0];
437
+ for (let i = 0; i < numberOfNonNaNColors; ++i) {
438
+ const scalarsArrayIndex = getIndexFromCoordinates(textureCoordinates, textureDimensions);
439
+
440
+ // Minus 1 start at min color
441
+ const intermediateValue = rangeMin + rangeDifference * (i - 1) / (numberOfNonSpecialColors - 1);
442
+ const scalarValue = useLogScale ? 10.0 ** intermediateValue : intermediateValue;
443
+ scalarsArray[scalarsArrayIndex] = scalarValue;
444
+
445
+ // Colors are zigzagging to allow interpolation between two neighbor colors when coloring cells
446
+ updateZigzaggingCoordinates(textureCoordinates, textureDimensions);
447
+ }
448
+ const scalarsDataArray = vtkDataArray.newInstance({
449
+ numberOfComponents: 1,
450
+ values: scalarsArray
451
+ });
452
+ const colorsDataArray = model.lookupTable.mapScalars(scalarsDataArray, model.colorMode, 0);
453
+ model.colorTextureMap = vtkImageData.newInstance();
454
+ model.colorTextureMap.setDimensions(textureDimensions);
455
+ model.colorTextureMap.getPointData().setScalars(colorsDataArray);
456
+ model.lookupTable.setAlpha(origAlpha);
457
+ }
458
+
459
+ // Although I like the feature of applying magnitude to single component
460
+ // scalars, it is not how the old MapScalars for vertex coloring works.
461
+ const scalarComponent = model.lookupTable.getVectorMode() === VectorMode.MAGNITUDE && scalars.getNumberOfComponents() > 1 ? -1 : model.lookupTable.getVectorComponent();
462
+
463
+ // Create new coordinates if necessary, this function uses cache if possible.
464
+ // A zigzag pattern can't be used with point data, as interpolation of texture coordinates will be wrong
465
+ // A zigzag pattern can be used with cell data, as there will be no texture coordinates interpolation
466
+ // The texture generated using a zigzag pattern in one dimension is the same as without zigzag
467
+ // Therefore, the same code can be used for texture generation of point/cell data but not for texture coordinates
468
+ model.colorCoordinates = getOrCreateColorTextureCoordinates(scalars, scalarComponent, scaledRange, useLogScale, model.numberOfColorsInRange, model.colorTextureMap.getDimensions(), cellFlag);
469
+ };
119
470
  publicAPI.getPrimitiveCount = () => {
120
471
  const input = publicAPI.getInputData();
121
472
  const pcount = {
@@ -143,6 +494,9 @@ const DEFAULT_VALUES = {
143
494
  arrayAccessMode: 1,
144
495
  // By_NAME
145
496
 
497
+ colorMapColors: null,
498
+ // Same as this->Colors
499
+ areScalarsMappedFromCells: false,
146
500
  renderTime: 0,
147
501
  colorByArrayName: null,
148
502
  transformCoordinate: null,
@@ -157,7 +511,7 @@ function extend(publicAPI, model) {
157
511
 
158
512
  // Inheritance
159
513
  vtkAbstractMapper.extend(publicAPI, model, initialValues);
160
- macro.get(publicAPI, model, ['colorMapColors']);
514
+ macro.get(publicAPI, model, ['areScalarsMappedFromCells', 'colorCoordinates', 'colorTextureMap', 'colorMapColors']);
161
515
  macro.setGet(publicAPI, model, ['arrayAccessMode', 'colorByArrayName', 'colorMode', 'lookupTable', 'renderTime', 'scalarMode', 'scalarVisibility', 'static', 'transformCoordinate', 'useLookupTableScalarRange', 'viewSpecificProperties', 'customShaderAttributes' // point data array names that will be transferred to the VBO
162
516
  ]);
163
517
 
@@ -1,7 +1,7 @@
1
1
  import { mat4, quat } from 'gl-matrix';
2
2
  import { m as macro } from '../../macros2.js';
3
3
  import vtkBoundingBox from '../../Common/DataModel/BoundingBox.js';
4
- import { A as degreesFromRadians, r as radiansFromDegrees, a as areMatricesEqual } from '../../Common/Core/Math/index.js';
4
+ import { B as degreesFromRadians, r as radiansFromDegrees, a as areMatricesEqual } from '../../Common/Core/Math/index.js';
5
5
  import vtkProp from './Prop.js';
6
6
 
7
7
  const VTK_EPSILON = 1e-6;
@@ -1,5 +1,5 @@
1
1
  import { m as macro } from '../../macros2.js';
2
- import { A as degreesFromRadians } from '../../Common/Core/Math/index.js';
2
+ import { B as degreesFromRadians } from '../../Common/Core/Math/index.js';
3
3
  import Constants from './RenderWindowInteractor/Constants.js';
4
4
 
5
5
  const {
@@ -238,9 +238,9 @@ function vtkRenderWindowInteractor(publicAPI, model) {
238
238
  });
239
239
  container.removeEventListener('pointerup', publicAPI.handlePointerUp);
240
240
  container.removeEventListener('pointercancel', publicAPI.handlePointerCancel);
241
+ container.removeEventListener('keypress', publicAPI.handleKeyPress);
242
+ container.removeEventListener('keydown', publicAPI.handleKeyDown);
241
243
  }
242
- container.removeEventListener('keypress', publicAPI.handleKeyPress);
243
- container.removeEventListener('keydown', publicAPI.handleKeyDown);
244
244
  document.removeEventListener('keyup', publicAPI.handleKeyUp);
245
245
  document.removeEventListener('pointerlockchange', publicAPI.handlePointerLockChange);
246
246
  pointerCache.clear();
@@ -2,7 +2,7 @@ import { mat4, vec3 } from 'gl-matrix';
2
2
  import { n as newInstance$1, g as get, e as setGet, k as getArray, l as setGetArray, i as moveToProtected, c as macro } from '../../macros2.js';
3
3
  import vtkCamera from './Camera.js';
4
4
  import vtkLight from './Light.js';
5
- import { U as areBoundsInitialized, u as uninitializeBounds, r as radiansFromDegrees, d as dot, H as createUninitializedBounds } from '../../Common/Core/Math/index.js';
5
+ import { V as areBoundsInitialized, u as uninitializeBounds, r as radiansFromDegrees, d as dot, I as createUninitializedBounds } from '../../Common/Core/Math/index.js';
6
6
  import vtkViewport from './Viewport.js';
7
7
  import vtkBoundingBox from '../../Common/DataModel/BoundingBox.js';
8
8
 
@@ -1,5 +1,5 @@
1
1
  import * as d3 from 'd3-scale';
2
- import { R as nearestPowerOfTwo } from '../../Common/Core/Math/index.js';
2
+ import { S as nearestPowerOfTwo } from '../../Common/Core/Math/index.js';
3
3
  import { m as macro } from '../../macros2.js';
4
4
  import vtkActor from './Actor.js';
5
5
  import vtkDataArray from '../../Common/Core/DataArray.js';
@@ -5,7 +5,7 @@ import vtkActor2D from './Actor2D.js';
5
5
  import vtkMapper2D from './Mapper2D.js';
6
6
  import vtkTextProperty from './TextProperty.js';
7
7
  import ImageHelper from '../../Common/Core/ImageHelper.js';
8
- import { V as floatRGB2HexCode } from '../../Common/Core/Math/index.js';
8
+ import { W as floatRGB2HexCode } from '../../Common/Core/Math/index.js';
9
9
 
10
10
  // ----------------------------------------------------------------------------
11
11
  // vtkTextActor methods
@@ -1,4 +1,4 @@
1
- import { D as areEquals } from '../../../Common/Core/Math/index.js';
1
+ import { E as areEquals } from '../../../Common/Core/Math/index.js';
2
2
 
3
3
  /**
4
4
  * Computes UV coordinates for top/bottom faces
@@ -1,5 +1,5 @@
1
1
  import { m as macro } from '../../macros2.js';
2
- import { E as clampValue, K as floor } from '../../Common/Core/Math/index.js';
2
+ import { F as clampValue, L as floor } from '../../Common/Core/Math/index.js';
3
3
  import vtkColorTransferFunction from './ColorTransferFunction.js';
4
4
  import vtkPiecewiseFunction from '../../Common/DataModel/PiecewiseFunction.js';
5
5
  import Constants from './VolumeProperty/Constants.js';