@kitware/vtk.js 33.0.0-beta.4 → 33.0.1

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 (44) hide show
  1. package/BREAKING_CHANGES.md +0 -3
  2. package/Common/Core/ScalarsToColors/Constants.js +7 -2
  3. package/Common/Core/ScalarsToColors.js +3 -1
  4. package/Rendering/Core/Actor.d.ts +20 -5
  5. package/Rendering/Core/Actor.js +68 -5
  6. package/Rendering/Core/ColorTransferFunction.js +26 -35
  7. package/Rendering/Core/ImageCPRMapper.d.ts +20 -1
  8. package/Rendering/Core/ImageCPRMapper.js +2 -1
  9. package/Rendering/Core/ImageProperty.d.ts +1 -20
  10. package/Rendering/Core/ImageProperty.js +5 -7
  11. package/Rendering/Core/ImageResliceMapper.d.ts +20 -1
  12. package/Rendering/Core/ImageResliceMapper.js +2 -1
  13. package/Rendering/Core/ImageSlice.d.ts +23 -7
  14. package/Rendering/Core/ImageSlice.js +68 -9
  15. package/Rendering/Core/Mapper.js +8 -16
  16. package/Rendering/Core/Prop3D.d.ts +2 -39
  17. package/Rendering/Core/Prop3D.js +2 -81
  18. package/Rendering/Core/ScalarBarActor.js +4 -2
  19. package/Rendering/Core/Volume.d.ts +20 -5
  20. package/Rendering/Core/Volume.js +70 -2
  21. package/Rendering/Core/VolumeMapper/Constants.d.ts +7 -0
  22. package/Rendering/Core/VolumeMapper/Constants.js +8 -2
  23. package/Rendering/Core/VolumeMapper.d.ts +173 -16
  24. package/Rendering/Core/VolumeMapper.js +51 -16
  25. package/Rendering/Core/VolumeProperty/Constants.d.ts +3 -12
  26. package/Rendering/Core/VolumeProperty/Constants.js +4 -11
  27. package/Rendering/Core/VolumeProperty.d.ts +5 -140
  28. package/Rendering/Core/VolumeProperty.js +7 -54
  29. package/Rendering/OpenGL/CellArrayBufferObject/helpers.js +45 -0
  30. package/Rendering/OpenGL/CellArrayBufferObject.js +6 -25
  31. package/Rendering/OpenGL/ImageCPRMapper.js +21 -30
  32. package/Rendering/OpenGL/ImageMapper.js +27 -27
  33. package/Rendering/OpenGL/ImageResliceMapper.js +183 -271
  34. package/Rendering/OpenGL/PolyDataMapper.js +8 -1
  35. package/Rendering/OpenGL/RenderWindow/resourceSharingHelper.d.ts +3 -3
  36. package/Rendering/OpenGL/RenderWindow/resourceSharingHelper.js +5 -8
  37. package/Rendering/OpenGL/SphereMapper.js +33 -13
  38. package/Rendering/OpenGL/VolumeMapper.js +784 -722
  39. package/Rendering/OpenGL/glsl/vtkVolumeFS.glsl.js +1 -1
  40. package/Rendering/WebGPU/VolumePassFSQ.js +2 -2
  41. package/index.d.ts +0 -1
  42. package/macros2.js +1 -1
  43. package/package.json +1 -1
  44. package/Interaction/Manipulators/KeyboardCameraManipulator.d.ts +0 -113
@@ -4,6 +4,10 @@ import vtkBoundingBox from '../../Common/DataModel/BoundingBox.js';
4
4
  import vtkProp3D from './Prop3D.js';
5
5
  import vtkImageProperty from './ImageProperty.js';
6
6
 
7
+ const {
8
+ vtkDebugMacro
9
+ } = macro;
10
+
7
11
  // ----------------------------------------------------------------------------
8
12
  // vtkImageSlice methods
9
13
  // ----------------------------------------------------------------------------
@@ -21,11 +25,11 @@ function vtkImageSlice(publicAPI, model) {
21
25
  return false;
22
26
  }
23
27
  // make sure we have a property
24
- if (!model.properties[0]) {
28
+ if (!model.property) {
25
29
  // force creation of a property
26
30
  publicAPI.getProperty();
27
31
  }
28
- let isOpaque = model.properties[0].getOpacity() >= 1.0;
32
+ let isOpaque = model.property.getOpacity() >= 1.0;
29
33
 
30
34
  // are we using an opaque scalar array, if any?
31
35
  isOpaque = isOpaque && (!model.mapper || model.mapper.getIsOpaque());
@@ -39,6 +43,48 @@ function vtkImageSlice(publicAPI, model) {
39
43
  // and the Renderer will do the images in their own pass.
40
44
  publicAPI.hasTranslucentPolygonalGeometry = () => false;
41
45
  publicAPI.makeProperty = vtkImageProperty.newInstance;
46
+ publicAPI.getProperty = () => {
47
+ if (model.property === null) {
48
+ model.property = publicAPI.makeProperty();
49
+ }
50
+ return model.property;
51
+ };
52
+ publicAPI.getBounds = () => {
53
+ if (model.mapper === null) {
54
+ return model.bounds;
55
+ }
56
+
57
+ // Check for the special case when the mapper's bounds are unknown
58
+ const bds = model.mapper.getBounds();
59
+ if (!bds || bds.length !== 6) {
60
+ return bds;
61
+ }
62
+
63
+ // Check for the special case when the actor is empty.
64
+ if (bds[0] > bds[1]) {
65
+ model.mapperBounds = bds.concat(); // copy the mapper's bounds
66
+ model.bounds = [1, -1, 1, -1, 1, -1];
67
+ model.boundsMTime.modified();
68
+ return bds;
69
+ }
70
+
71
+ // Check if we have cached values for these bounds - we cache the
72
+ // values returned by model.mapper.getBounds() and we store the time
73
+ // of caching. If the values returned this time are different, or
74
+ // the modified time of this class is newer than the cached time,
75
+ // then we need to rebuild.
76
+ const zip = rows => rows[0].map((_, c) => rows.map(row => row[c]));
77
+ if (!model.mapperBounds || !zip([bds, model.mapperBounds]).reduce((a, b) => a && b[0] === b[1], true) || publicAPI.getMTime() > model.boundsMTime.getMTime()) {
78
+ vtkDebugMacro('Recomputing bounds...');
79
+ model.mapperBounds = bds.map(x => x);
80
+ publicAPI.computeMatrix();
81
+ const tmp4 = new Float64Array(16);
82
+ mat4.transpose(tmp4, model.matrix);
83
+ vtkBoundingBox.transformBounds(bds, tmp4, model.bounds);
84
+ model.boundsMTime.modified();
85
+ }
86
+ return model.bounds;
87
+ };
42
88
  publicAPI.getBoundsForSlice = (slice, thickness) => {
43
89
  // Check for the special case when the mapper's bounds are unknown
44
90
  const bds = model.mapper.getBoundsForSlice(slice, thickness);
@@ -71,6 +117,14 @@ function vtkImageSlice(publicAPI, model) {
71
117
 
72
118
  // Get the maximum Z bound
73
119
  publicAPI.getMaxZBound = () => publicAPI.getBounds()[5];
120
+ publicAPI.getMTime = () => {
121
+ let mt = model.mtime;
122
+ if (model.property !== null) {
123
+ const time = model.property.getMTime();
124
+ mt = time > mt ? time : mt;
125
+ }
126
+ return mt;
127
+ };
74
128
  publicAPI.getRedrawMTime = () => {
75
129
  let mt = model.mtime;
76
130
  if (model.mapper !== null) {
@@ -83,13 +137,14 @@ function vtkImageSlice(publicAPI, model) {
83
137
  mt = time > mt ? time : mt;
84
138
  }
85
139
  }
86
- model.properties.forEach(property => {
87
- mt = Math.max(mt, property.getMTime());
88
- const rgbFunc = property.getRGBTransferFunction();
89
- if (rgbFunc !== null) {
90
- mt = Math.max(mt, rgbFunc.getMTime());
140
+ if (model.property !== null) {
141
+ let time = model.property.getMTime();
142
+ mt = time > mt ? time : mt;
143
+ if (model.property.getRGBTransferFunction() !== null) {
144
+ time = model.property.getRGBTransferFunction().getMTime();
145
+ mt = time > mt ? time : mt;
91
146
  }
92
- });
147
+ }
93
148
  return mt;
94
149
  };
95
150
  publicAPI.getSupportsSelection = () => model.mapper ? model.mapper.getSupportsSelection() : false;
@@ -101,8 +156,10 @@ function vtkImageSlice(publicAPI, model) {
101
156
 
102
157
  const DEFAULT_VALUES = {
103
158
  mapper: null,
159
+ property: null,
104
160
  forceOpaque: false,
105
- forceTranslucent: false
161
+ forceTranslucent: false,
162
+ bounds: [...vtkBoundingBox.INIT_BOUNDS]
106
163
  };
107
164
 
108
165
  // ----------------------------------------------------------------------------
@@ -119,7 +176,9 @@ function extend(publicAPI, model) {
119
176
  macro.obj(model.boundsMTime);
120
177
 
121
178
  // Build VTK API
179
+ macro.set(publicAPI, model, ['property']);
122
180
  macro.setGet(publicAPI, model, ['mapper', 'forceOpaque', 'forceTranslucent']);
181
+ macro.getArray(publicAPI, model, ['bounds'], 6);
123
182
 
124
183
  // Object methods
125
184
  vtkImageSlice(publicAPI, model);
@@ -137,11 +137,10 @@ const colorTextureCoordinatesCache = new WeakMap();
137
137
  * @param {Range} range The range of the scalars
138
138
  * @param {Number} numberOfColorsInRange The number of colors that are used in the range
139
139
  * @param {vec3} dimensions The dimensions of the texture
140
- * @param {boolean} useLogScale If log scale should be used to transform input scalars
141
140
  * @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.
142
141
  * @returns A vtkDataArray containing the texture coordinates (2D or 3D)
143
142
  */
144
- function getOrCreateColorTextureCoordinates(input, component, range, numberOfColorsInRange, dimensions, useLogScale, useZigzagPattern) {
143
+ function getOrCreateColorTextureCoordinates(input, component, range, numberOfColorsInRange, dimensions, useZigzagPattern) {
145
144
  // Caching using the "arguments" special object (because it is a pure function)
146
145
  const argStrings = new Array(arguments.length);
147
146
  for (let argIndex = 0; argIndex < arguments.length; ++argIndex) {
@@ -202,11 +201,6 @@ function getOrCreateColorTextureCoordinates(input, component, range, numberOfCol
202
201
  }
203
202
  inputIdx += numComps;
204
203
 
205
- // Apply log scale if necessary
206
- if (useLogScale) {
207
- scalarValue = vtkLookupTable.applyLogScale(scalarValue, range, range);
208
- }
209
-
210
204
  // Convert to texture coordinates and update output
211
205
  if (isNan(scalarValue)) {
212
206
  // Last texels are NaN colors (there is at least one NaN color)
@@ -401,10 +395,6 @@ function vtkMapper(publicAPI, model) {
401
395
  model.mapScalarsToTexture = (scalars, cellFlag, alpha) => {
402
396
  const range = model.lookupTable.getRange();
403
397
  const useLogScale = model.lookupTable.usingLogScale();
404
- if (useLogScale) {
405
- // convert range to log.
406
- vtkLookupTable.getLogRange(range, range);
407
- }
408
398
  const origAlpha = model.lookupTable.getAlpha();
409
399
 
410
400
  // Get rid of vertex color array. Only texture or vertex coloring
@@ -448,14 +438,16 @@ function vtkMapper(publicAPI, model) {
448
438
  const numberOfNonSpecialColors = model.numberOfColorsInRange;
449
439
  const numberOfNonNaNColors = numberOfNonSpecialColors + 2;
450
440
  const textureCoordinates = [0, 0, 0];
451
- const rangeMin = range[0];
452
- const rangeDifference = range[1] - range[0];
441
+ const scaledRange = useLogScale ? [Math.log10(range[0]), Math.log10(range[1])] : range;
442
+ const rangeMin = scaledRange[0];
443
+ const rangeDifference = scaledRange[1] - scaledRange[0];
453
444
  for (let i = 0; i < numberOfNonNaNColors; ++i) {
454
445
  const scalarsArrayIndex = getIndexFromCoordinates(textureCoordinates, textureDimensions);
455
446
 
456
447
  // Minus 1 start at min color
457
- const scalarValue = rangeMin + rangeDifference * (i - 1) / (numberOfNonSpecialColors - 1);
458
- scalarsArray[scalarsArrayIndex] = useLogScale ? 10.0 ** scalarValue : scalarValue;
448
+ const intermediateValue = rangeMin + rangeDifference * (i - 1) / (numberOfNonSpecialColors - 1);
449
+ const scalarValue = useLogScale ? 10.0 ** intermediateValue : intermediateValue;
450
+ scalarsArray[scalarsArrayIndex] = scalarValue;
459
451
 
460
452
  // Colors are zigzagging to allow interpolation between two neighbor colors when coloring cells
461
453
  updateZigzaggingCoordinates(textureCoordinates, textureDimensions);
@@ -480,7 +472,7 @@ function vtkMapper(publicAPI, model) {
480
472
  // A zigzag pattern can be used with cell data, as there will be no texture coordinates interpolation
481
473
  // The texture generated using a zigzag pattern in one dimension is the same as without zigzag
482
474
  // Therefore, the same code can be used for texture generation of point/cell data but not for texture coordinates
483
- model.colorCoordinates = getOrCreateColorTextureCoordinates(scalars, scalarComponent, range, model.numberOfColorsInRange, model.colorTextureMap.getDimensions(), useLogScale, cellFlag);
475
+ model.colorCoordinates = getOrCreateColorTextureCoordinates(scalars, scalarComponent, range, model.numberOfColorsInRange, model.colorTextureMap.getDimensions(), cellFlag);
484
476
  };
485
477
  publicAPI.getIsOpaque = () => {
486
478
  const input = publicAPI.getInputData();
@@ -1,7 +1,6 @@
1
1
  import { mat4, quat } from 'gl-matrix';
2
2
  import { Bounds, Vector3, Range } from './../../types';
3
3
  import vtkProp, { IPropInitialValues } from './Prop';
4
- import { vtkObject } from './../../interfaces';
5
4
 
6
5
  export interface IProp3DInitialValues extends IPropInitialValues {
7
6
  origin?: number[];
@@ -20,17 +19,11 @@ export interface vtkProp3D extends vtkProp {
20
19
  addPosition(deltaXYZ: number[]): void;
21
20
 
22
21
  /**
23
- * Get the bounds of this actor as [xmin, xmax, ymin, ymax, zmin, zmax].
24
- * They are the bounds of the underlying mapper, transformed using the actor's matrix.
25
- * @return {Bounds} The bounds for the actor.
22
+ * Get the bounds as [xmin, xmax, ymin, ymax, zmin, zmax].
23
+ * @return {Bounds} The bounds for the mapper.
26
24
  */
27
25
  getBounds(): Bounds;
28
26
 
29
- /**
30
- * Same as getBounds() but the returned array is not copied, so it should not be written to.
31
- */
32
- getBoundsByReference(): Bounds;
33
-
34
27
  /**
35
28
  * Check if there was a modification or transformation.
36
29
  * @default null
@@ -138,21 +131,6 @@ export interface vtkProp3D extends vtkProp {
138
131
  */
139
132
  getUserMatrix(): mat4;
140
133
 
141
- /**
142
- * Get the actor property for the specified mapper input port, which defaults to 0
143
- * It controls this actors rendering properties. If one isn’t specified,
144
- * then one will be generated automatically. Multiple actors can share one
145
- * property object.
146
- * @param {number} mapperInputPort Defaults to 0
147
- */
148
- getProperty(mapperInputPort?: number): vtkObject;
149
-
150
- /**
151
- * Get the actor properties array
152
- * Each element of the array corresponds to a mapper input port
153
- */
154
- getProperties(): vtkObject[];
155
-
156
134
  /**
157
135
  * Rotate the Prop3D in degrees about the X axis using the right hand
158
136
  * rule. The axis is the Prop3D’s X axis, which can change as other
@@ -278,21 +256,6 @@ export interface vtkProp3D extends vtkProp {
278
256
  * Generate the matrix based on internal model.
279
257
  */
280
258
  computeMatrix(): void;
281
-
282
- /**
283
- * Set the actor property for the specified mapper input port, which defaults to 0
284
- * @param {vtkObject} property
285
- * @param {number} mapperInputPort Is 0 when not given
286
- */
287
- setProperty(mapperInputPort: number, property: vtkObject): boolean;
288
- setProperty(property: vtkObject): boolean;
289
-
290
- /**
291
- * Set the actor properties array
292
- * Each element of the array corresponds to a mapper input port
293
- * @param {vtkObject[]} properties
294
- */
295
- setProperties(properties: vtkObject[]): boolean;
296
259
  }
297
260
 
298
261
  /**
@@ -121,54 +121,6 @@ function vtkProp3D(publicAPI, model) {
121
121
  model.matrixMTime.modified();
122
122
  }
123
123
  };
124
- publicAPI.getBoundsByReference = () => {
125
- if (model.mapper === null) {
126
- return model.bounds;
127
- }
128
-
129
- // Check for the special case when the mapper's bounds are unknown
130
- const bds = model.mapper.getBounds();
131
- if (!bds || bds.length !== 6) {
132
- return bds;
133
- }
134
-
135
- // Check for the special case when the actor is empty.
136
- if (bds[0] > bds[1]) {
137
- // No need to copy bds, a new array is created when calling getBounds()
138
- model.mapperBounds = bds;
139
- model.bounds = [...vtkBoundingBox.INIT_BOUNDS];
140
- model.boundsMTime.modified();
141
- return bds;
142
- }
143
-
144
- // Check if we have cached values for these bounds - we cache the
145
- // values returned by model.mapper.getBounds() and we store the time
146
- // of caching. If the values returned this time are different, or
147
- // the modified time of this class is newer than the cached time,
148
- // then we need to rebuild.
149
- if (!model.mapperBounds || !bds.every((_, i) => bds[i] === model.mapperBounds[i]) || publicAPI.getMTime() > model.boundsMTime.getMTime()) {
150
- macro.vtkDebugMacro('Recomputing bounds...');
151
- // No need to copy bds, a new array is created when calling getBounds()
152
- model.mapperBounds = bds;
153
-
154
- // Compute actor bounds from matrix and mapper bounds
155
- publicAPI.computeMatrix();
156
- const transposedMatrix = new Float64Array(16);
157
- mat4.transpose(transposedMatrix, model.matrix);
158
- vtkBoundingBox.transformBounds(bds, transposedMatrix, model.bounds);
159
- model.boundsMTime.modified();
160
- }
161
- return model.bounds;
162
- };
163
- publicAPI.getBounds = () => {
164
- const bounds = publicAPI.getBoundsByReference();
165
- // Handle case when bounds are not iterable (for example null or undefined)
166
- try {
167
- return [...bounds];
168
- } catch {
169
- return bounds;
170
- }
171
- };
172
124
  publicAPI.getCenter = () => vtkBoundingBox.getCenter(model.bounds);
173
125
  publicAPI.getLength = () => vtkBoundingBox.getLength(model.bounds);
174
126
  publicAPI.getXRange = () => vtkBoundingBox.getXRange(model.bounds);
@@ -179,35 +131,6 @@ function vtkProp3D(publicAPI, model) {
179
131
  publicAPI.computeMatrix();
180
132
  }
181
133
  publicAPI.onModified(updateIdentityFlag);
182
- publicAPI.getProperty = function () {
183
- let mapperInputPort = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
184
- if (model.properties[mapperInputPort] == null) {
185
- model.properties[mapperInputPort] = publicAPI.makeProperty?.();
186
- }
187
- return model.properties[mapperInputPort];
188
- };
189
- publicAPI.setProperty = (firstArg, secondArg) => {
190
- // Two options for argument layout:
191
- // - (mapperInputPort, property)
192
- // - (property)
193
- const useInputPortArgument = Number.isInteger(firstArg);
194
- const [mapperInputPort, property] = useInputPortArgument ? [firstArg, secondArg] : [0, firstArg];
195
- if (model.properties[mapperInputPort] === property) {
196
- return false;
197
- }
198
- model.properties[mapperInputPort] = property;
199
- return true;
200
- };
201
- publicAPI.getMTime = () => {
202
- let mt = model.mtime;
203
- model.properties.forEach(property => {
204
- if (property !== null) {
205
- const time = property.getMTime();
206
- mt = time > mt ? time : mt;
207
- }
208
- });
209
- return mt;
210
- };
211
134
  }
212
135
 
213
136
  // ----------------------------------------------------------------------------
@@ -220,8 +143,7 @@ const DEFAULT_VALUES = {
220
143
  orientation: [0, 0, 0],
221
144
  rotation: null,
222
145
  scale: [1, 1, 1],
223
- bounds: [...vtkBoundingBox.INIT_BOUNDS],
224
- properties: [],
146
+ bounds: [1, -1, 1, -1, 1, -1],
225
147
  userMatrix: null,
226
148
  userMatrixMTime: null,
227
149
  cachedProp3D: null,
@@ -241,10 +163,9 @@ function extend(publicAPI, model) {
241
163
  macro.obj(model.matrixMTime);
242
164
 
243
165
  // Build VTK API
244
- macro.get(publicAPI, model, ['isIdentity']);
166
+ macro.get(publicAPI, model, ['bounds', 'isIdentity']);
245
167
  macro.getArray(publicAPI, model, ['orientation']);
246
168
  macro.setGetArray(publicAPI, model, ['origin', 'position', 'scale'], 3);
247
- macro.setGet(publicAPI, model, ['properties']);
248
169
 
249
170
  // Object internal instance
250
171
  model.matrix = mat4.identity(new Float64Array(16));
@@ -566,8 +566,10 @@ function vtkScalarBarActorHelper(publicAPI, model) {
566
566
  const tickSegmentSize = model.barSize[spacedAxis] * (tickSeg.corners[2][spacedAxis] - tickSeg.corners[0][spacedAxis]);
567
567
  const ticks = publicAPI.getTicks();
568
568
  const tickStrings = publicAPI.getTickStrings();
569
+ const tickPositions = publicAPI.getTickPositions();
569
570
  for (let t = 0; t < ticks.length; t++) {
570
- const tickPos = (ticks[t] - model.lastTickBounds[0]) / (model.lastTickBounds[1] - model.lastTickBounds[0]);
571
+ // If tickPositions is not set, use a normalized position
572
+ const tickPos = tickPositions ? tickPositions[t] : (ticks[t] - model.lastTickBounds[0]) / (model.lastTickBounds[1] - model.lastTickBounds[0]);
571
573
  tmpv3[spacedAxis] = tickSegmentStart + tickSegmentSize * tickPos;
572
574
  publicAPI.createPolyDataForOneLabel(tickStrings[t], tmpv3, alignment, 'horizontal', tickOffsets, results);
573
575
  }
@@ -651,7 +653,7 @@ const newScalarBarActorHelper = macro.newInstance(function (publicAPI, model) {
651
653
 
652
654
  // Inheritance
653
655
  macro.obj(publicAPI, model);
654
- macro.setGet(publicAPI, model, ['axisTitlePixelOffset', 'tickLabelPixelOffset', 'renderable', 'topTitle', 'ticks', 'tickStrings']);
656
+ macro.setGet(publicAPI, model, ['axisTitlePixelOffset', 'tickLabelPixelOffset', 'renderable', 'topTitle', 'ticks', 'tickStrings', 'tickPositions']);
655
657
  macro.get(publicAPI, model, ['lastSize', 'lastAspectRatio', 'lastTickBounds', 'axisTextStyle', 'tickTextStyle', 'barActor', 'tmActor']);
656
658
  macro.getArray(publicAPI, model, ['boxPosition', 'boxSize']);
657
659
  macro.setArray(publicAPI, model, ['boxPosition', 'boxSize'], 2);
@@ -29,6 +29,22 @@ export interface vtkVolume extends vtkProp3D {
29
29
  */
30
30
  getVolumes(): vtkVolume[];
31
31
 
32
+ /**
33
+ * Get the volume property
34
+ */
35
+ getProperty(): vtkVolumeProperty;
36
+
37
+ /**
38
+ * Get the bounds for this mapper as [xmin, xmax, ymin, ymax,zmin, zmax].
39
+ * @return {Bounds} The bounds for the mapper.
40
+ */
41
+ getBounds(): Bounds;
42
+
43
+ /**
44
+ * Get the bounds as [xmin, xmax, ymin, ymax, zmin, zmax].
45
+ */
46
+ getBoundsByReference(): Bounds;
47
+
32
48
  /**
33
49
  * Get the `Modified Time` which is a monotonic increasing integer
34
50
  * global for all vtkObjects.
@@ -59,12 +75,11 @@ export interface vtkVolume extends vtkProp3D {
59
75
  */
60
76
  setMapper(mapper: vtkVolumeMapper): boolean;
61
77
 
62
- // Inherited from vtkProp3D, but takes a vtkVolumeProperty instead of a generic vtkObject
63
- getProperty(mapperInputPort?: number): vtkVolumeProperty;
64
- getProperties(): vtkVolumeProperty[];
65
- setProperty(mapperInputPort: number, property: vtkVolumeProperty): boolean;
78
+ /**
79
+ * Set the volume property
80
+ * @param {vtkVolumeProperty} property
81
+ */
66
82
  setProperty(property: vtkVolumeProperty): boolean;
67
- setProperties(properties: vtkVolumeProperty[]): boolean;
68
83
  }
69
84
 
70
85
  /**
@@ -1,7 +1,13 @@
1
+ import { mat4, vec3 } from 'gl-matrix';
1
2
  import { m as macro } from '../../macros2.js';
3
+ import vtkBoundingBox from '../../Common/DataModel/BoundingBox.js';
2
4
  import vtkProp3D from './Prop3D.js';
3
5
  import vtkVolumeProperty from './VolumeProperty.js';
4
6
 
7
+ const {
8
+ vtkDebugMacro
9
+ } = macro;
10
+
5
11
  // ----------------------------------------------------------------------------
6
12
  // vtkVolume methods
7
13
  // ----------------------------------------------------------------------------
@@ -9,8 +15,66 @@ import vtkVolumeProperty from './VolumeProperty.js';
9
15
  function vtkVolume(publicAPI, model) {
10
16
  // Set our className
11
17
  model.classHierarchy.push('vtkVolume');
12
- publicAPI.getVolumes = () => [publicAPI];
18
+ publicAPI.getVolumes = () => publicAPI;
13
19
  publicAPI.makeProperty = vtkVolumeProperty.newInstance;
20
+ publicAPI.getProperty = () => {
21
+ if (model.property === null) {
22
+ model.property = publicAPI.makeProperty();
23
+ }
24
+ return model.property;
25
+ };
26
+ publicAPI.getBounds = () => {
27
+ if (model.mapper === null) {
28
+ return model.bounds;
29
+ }
30
+
31
+ // Check for the special case when the mapper's bounds are unknown
32
+ const bds = model.mapper.getBounds();
33
+ if (!bds || bds.length !== 6) {
34
+ return bds;
35
+ }
36
+
37
+ // Check for the special case when the actor is empty.
38
+ if (bds[0] > bds[1]) {
39
+ model.mapperBounds = bds.concat(); // copy the mapper's bounds
40
+ model.bounds = [1, -1, 1, -1, 1, -1];
41
+ model.boundsMTime.modified();
42
+ return bds;
43
+ }
44
+
45
+ // Check if we have cached values for these bounds - we cache the
46
+ // values returned by model.mapper.getBounds() and we store the time
47
+ // of caching. If the values returned this time are different, or
48
+ // the modified time of this class is newer than the cached time,
49
+ // then we need to rebuild.
50
+ const zip = rows => rows[0].map((_, c) => rows.map(row => row[c]));
51
+ if (!model.mapperBounds || !zip([bds, model.mapperBounds]).reduce((a, b) => a && b[0] === b[1], true) || publicAPI.getMTime() > model.boundsMTime.getMTime()) {
52
+ vtkDebugMacro('Recomputing bounds...');
53
+ model.mapperBounds = bds.map(x => x);
54
+ const bbox = [];
55
+ vtkBoundingBox.getCorners(bds, bbox);
56
+ publicAPI.computeMatrix();
57
+ const tmp4 = new Float64Array(16);
58
+ mat4.transpose(tmp4, model.matrix);
59
+ bbox.forEach(pt => vec3.transformMat4(pt, pt, tmp4));
60
+
61
+ /* eslint-disable no-multi-assign */
62
+ model.bounds[0] = model.bounds[2] = model.bounds[4] = Number.MAX_VALUE;
63
+ model.bounds[1] = model.bounds[3] = model.bounds[5] = -Number.MAX_VALUE;
64
+ /* eslint-enable no-multi-assign */
65
+ model.bounds = model.bounds.map((d, i) => i % 2 === 0 ? bbox.reduce((a, b) => a > b[i / 2] ? b[i / 2] : a, d) : bbox.reduce((a, b) => a < b[(i - 1) / 2] ? b[(i - 1) / 2] : a, d));
66
+ model.boundsMTime.modified();
67
+ }
68
+ return model.bounds;
69
+ };
70
+ publicAPI.getMTime = () => {
71
+ let mt = model.mtime;
72
+ if (model.property !== null) {
73
+ const time = model.property.getMTime();
74
+ mt = time > mt ? time : mt;
75
+ }
76
+ return mt;
77
+ };
14
78
  publicAPI.getRedrawMTime = () => {
15
79
  let mt = model.mtime;
16
80
  if (model.mapper !== null) {
@@ -32,7 +96,9 @@ function vtkVolume(publicAPI, model) {
32
96
  // ----------------------------------------------------------------------------
33
97
 
34
98
  const DEFAULT_VALUES = {
35
- mapper: null
99
+ mapper: null,
100
+ property: null,
101
+ bounds: [1, -1, 1, -1, 1, -1]
36
102
  };
37
103
 
38
104
  // ----------------------------------------------------------------------------
@@ -49,7 +115,9 @@ function extend(publicAPI, model) {
49
115
  macro.obj(model.boundsMTime);
50
116
 
51
117
  // Build VTK API
118
+ macro.set(publicAPI, model, ['property']);
52
119
  macro.setGet(publicAPI, model, ['mapper']);
120
+ macro.getArray(publicAPI, model, ['bounds'], 6);
53
121
 
54
122
  // Object methods
55
123
  vtkVolume(publicAPI, model);
@@ -8,7 +8,14 @@ export declare enum BlendMode {
8
8
  LABELMAP_EDGE_PROJECTION_BLEND = 6,
9
9
  }
10
10
 
11
+ export declare enum FilterMode {
12
+ OFF = 0,
13
+ NORMALIZED = 1,
14
+ RAW = 2,
15
+ }
16
+
11
17
  declare const _default: {
12
18
  BlendMode: typeof BlendMode;
19
+ FilterMode: typeof FilterMode;
13
20
  };
14
21
  export default _default;
@@ -7,8 +7,14 @@ const BlendMode = {
7
7
  RADON_TRANSFORM_BLEND: 5,
8
8
  LABELMAP_EDGE_PROJECTION_BLEND: 6
9
9
  };
10
+ const FilterMode = {
11
+ OFF: 0,
12
+ NORMALIZED: 1,
13
+ RAW: 2
14
+ };
10
15
  var Constants = {
11
- BlendMode
16
+ BlendMode,
17
+ FilterMode
12
18
  };
13
19
 
14
- export { BlendMode, Constants as default };
20
+ export { BlendMode, FilterMode, Constants as default };