@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.
- package/Common/Core/CellArray.d.ts +3 -0
- package/Common/Core/CellArray.js +12 -1
- package/Common/Core/DataArray.d.ts +15 -0
- package/Common/Core/DataArray.js +8 -4
- package/Common/Core/Math/index.js +1 -1
- package/Common/Core/Math.js +1 -1
- package/Common/DataModel/Triangle.d.ts +68 -19
- package/Common/DataModel/Triangle.js +140 -1
- package/Common/DataModel/TriangleStrip.d.ts +180 -0
- package/Common/DataModel/TriangleStrip.js +396 -0
- package/Common/DataModel.js +3 -1
- package/Common/Transform/LandmarkTransform.js +1 -1
- package/Common/Transform/Transform.d.ts +112 -1
- package/Common/Transform/Transform.js +301 -2
- package/Filters/Core/Cutter.js +41 -0
- package/Filters/General/OBBTree.js +1 -1
- package/Filters/General/TransformPolyDataFilter.d.ts +75 -0
- package/Filters/General/TransformPolyDataFilter.js +194 -0
- package/Filters/General.js +2 -0
- package/Filters/Sources/CircleSource.js +1 -1
- package/Filters/Sources/PointSource.js +1 -1
- package/Filters/Texture/TextureMapToPlane.js +1 -1
- package/IO/Geometry/DracoReader.js +1 -1
- package/IO/Geometry/GLTFImporter/Animations.js +1 -1
- package/IO/Geometry/GLTFImporter/Reader.js +2 -2
- package/IO/Image/HDRReader/Utils.js +1 -1
- package/IO/Image/HDRReader.js +1 -1
- package/Interaction/Manipulators/MouseCameraTrackballRollManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraTrackballRotateManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraUnicamManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraUnicamRotateManipulator.js +1 -1
- package/Interaction/Style/InteractorStyleTrackballCamera.js +1 -1
- package/Interaction/Widgets/PiecewiseGaussianWidget.js +1 -1
- package/Proxy/Core/View2DProxy.js +1 -1
- package/Rendering/Core/AbstractImageMapper.js +1 -1
- package/Rendering/Core/AbstractMapper3D.js +1 -1
- package/Rendering/Core/ColorTransferFunction/CssFilters.js +1 -1
- package/Rendering/Core/ColorTransferFunction.js +1 -1
- package/Rendering/Core/Coordinate.js +1 -1
- package/Rendering/Core/CubeAxesActor.js +1 -1
- package/Rendering/Core/Glyph3DMapper.js +1 -1
- package/Rendering/Core/ImageArrayMapper.js +1 -1
- package/Rendering/Core/ImageMapper.js +1 -1
- package/Rendering/Core/ImageProperty.d.ts +10 -4
- package/Rendering/Core/Mapper.js +1 -1
- package/Rendering/Core/Mapper2D.js +362 -8
- package/Rendering/Core/Prop3D.js +1 -1
- package/Rendering/Core/RenderWindowInteractor.js +3 -3
- package/Rendering/Core/Renderer.js +1 -1
- package/Rendering/Core/ScalarBarActor.js +1 -1
- package/Rendering/Core/TextActor.js +1 -1
- package/Rendering/Core/VectorText/Utils.js +1 -1
- package/Rendering/Core/VolumeProperty.js +1 -1
- package/Rendering/OpenGL/ImageMapper.js +90 -20
- package/Rendering/OpenGL/PolyDataMapper2D.js +89 -30
- package/Rendering/OpenGL/Texture.js +1 -1
- package/Rendering/OpenGL/VolumeMapper.js +21 -19
- package/Widgets/Manipulators/LineManipulator.js +1 -1
- package/Widgets/Representations/PolyLineRepresentation.js +1 -1
- package/Widgets/Widgets3D/AngleWidget.js +1 -1
- package/Widgets/Widgets3D/LineWidget/helpers.js +1 -1
- package/Widgets/Widgets3D/ResliceCursorWidget/behavior.js +1 -1
- package/Widgets/Widgets3D/ResliceCursorWidget/helpers.js +1 -1
- package/Widgets/Widgets3D/ResliceCursorWidget.js +1 -1
- package/index.d.ts +2 -0
- 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
|
-
|
|
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
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
model.
|
|
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
|
|
package/Rendering/Core/Prop3D.js
CHANGED
|
@@ -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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
8
|
+
import { W as floatRGB2HexCode } from '../../Common/Core/Math/index.js';
|
|
9
9
|
|
|
10
10
|
// ----------------------------------------------------------------------------
|
|
11
11
|
// vtkTextActor methods
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { m as macro } from '../../macros2.js';
|
|
2
|
-
import {
|
|
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';
|