@kitware/vtk.js 22.5.0 → 22.5.4
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/DataArray.d.ts +32 -21
- package/Common/Core/DataArray.js +51 -17
- package/Rendering/Core/Mapper.js +1 -1
- package/Rendering/Core/Mapper2D.js +1 -1
- package/Rendering/Misc/SynchronizableRenderWindow.d.ts +2 -2
- package/Rendering/OpenGL/HardwareSelector.js +2 -2
- package/Rendering/OpenGL.js +1 -0
- package/Rendering/WebGPU/BufferManager/Constants.js +2 -1
- package/Rendering/WebGPU/BufferManager.js +24 -69
- package/Rendering/WebGPU/Device.js +73 -1
- package/Rendering/WebGPU/ImageMapper.js +1 -1
- package/Rendering/WebGPU/PolyDataMapper.js +25 -26
- package/Rendering/WebGPU/RenderEncoder.js +1 -1
- package/Rendering/WebGPU/SphereMapper.js +6 -6
- package/Rendering/WebGPU/StickMapper.js +8 -8
- package/Rendering/WebGPU/TextureManager.js +19 -47
- package/Rendering/WebGPU/VolumePass.js +6 -7
- package/Rendering/WebGPU/VolumePassFSQ.js +1 -1
- package/Rendering/WebGPU.js +16 -0
- package/package.json +1 -1
|
@@ -31,21 +31,21 @@ export interface vtkDataArray extends vtkObject {
|
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Get the component for a given tupleIdx.
|
|
34
|
-
* @param {Number} tupleIdx
|
|
34
|
+
* @param {Number} tupleIdx
|
|
35
35
|
* @param {Number} [componentIndex] (default: 0)
|
|
36
36
|
*/
|
|
37
37
|
getComponent(tupleIdx: number, componentIndex?: number): number;
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* Set the component value for a given tupleIdx and componentIndex.
|
|
41
|
-
* @param {Number} tupleIdx
|
|
42
|
-
* @param {Number} componentIndex
|
|
43
|
-
* @param {Number} value
|
|
41
|
+
* @param {Number} tupleIdx
|
|
42
|
+
* @param {Number} componentIndex
|
|
43
|
+
* @param {Number} value
|
|
44
44
|
*/
|
|
45
45
|
setComponent(tupleIdx: number, componentIndex: number, value: number): void;
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
48
|
+
*
|
|
49
49
|
*/
|
|
50
50
|
getData(): TypedArray;
|
|
51
51
|
|
|
@@ -57,22 +57,22 @@ export interface vtkDataArray extends vtkObject {
|
|
|
57
57
|
getRange(componentIndex?: number): vtkRange;
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
|
-
*
|
|
61
|
-
* @param {vtkRange} rangeValue
|
|
62
|
-
* @param {Number} componentIndex
|
|
60
|
+
*
|
|
61
|
+
* @param {vtkRange} rangeValue
|
|
62
|
+
* @param {Number} componentIndex
|
|
63
63
|
*/
|
|
64
64
|
setRange(rangeValue: vtkRange, componentIndex: number): [number, number];
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
68
|
-
* @param {Number} idx
|
|
69
|
-
* @param {Number[]} tuple
|
|
67
|
+
*
|
|
68
|
+
* @param {Number} idx
|
|
69
|
+
* @param {Number[]} tuple
|
|
70
70
|
*/
|
|
71
71
|
setTuple(idx: number, tuple: number[]): void;
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
74
|
*
|
|
75
|
-
* @param {Number} idx
|
|
75
|
+
* @param {Number} idx
|
|
76
76
|
* @param {Number[]} [tupleToFill] (default [])
|
|
77
77
|
*/
|
|
78
78
|
getTuple(idx: number, tupleToFill?: number[]): number[];
|
|
@@ -99,42 +99,42 @@ export interface vtkDataArray extends vtkObject {
|
|
|
99
99
|
getNumberOfTuples(): number;
|
|
100
100
|
|
|
101
101
|
/**
|
|
102
|
-
*
|
|
102
|
+
*
|
|
103
103
|
*/
|
|
104
104
|
getDataType(): string;
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
|
-
*
|
|
107
|
+
*
|
|
108
108
|
*/
|
|
109
109
|
newClone(): vtkDataArray;
|
|
110
110
|
|
|
111
111
|
/**
|
|
112
|
-
*
|
|
112
|
+
*
|
|
113
113
|
*/
|
|
114
114
|
getName(): string;
|
|
115
115
|
|
|
116
116
|
/**
|
|
117
|
-
*
|
|
118
|
-
* @param {TypedArray} typedArray
|
|
119
|
-
* @param {Number} [numberOfComponents]
|
|
117
|
+
*
|
|
118
|
+
* @param {TypedArray} typedArray
|
|
119
|
+
* @param {Number} [numberOfComponents]
|
|
120
120
|
*/
|
|
121
121
|
setData(typedArray: TypedArray, numberOfComponents?: number): void;
|
|
122
122
|
|
|
123
123
|
/**
|
|
124
|
-
*
|
|
124
|
+
*
|
|
125
125
|
*/
|
|
126
126
|
getState(): object;
|
|
127
127
|
|
|
128
128
|
// --- via macro --
|
|
129
129
|
|
|
130
130
|
/**
|
|
131
|
-
*
|
|
131
|
+
*
|
|
132
132
|
*/
|
|
133
133
|
setName(name: string): boolean;
|
|
134
134
|
|
|
135
135
|
/**
|
|
136
136
|
* Set the dimension (n) of the components.
|
|
137
|
-
* @param {Number} numberOfComponents
|
|
137
|
+
* @param {Number} numberOfComponents
|
|
138
138
|
*/
|
|
139
139
|
setNumberOfComponents(numberOfComponents: number): boolean;
|
|
140
140
|
}
|
|
@@ -160,6 +160,16 @@ export interface vtkDataArray extends vtkObject {
|
|
|
160
160
|
export function computeRange(values: number[], component?: number, numberOfComponents?: number): vtkRange;
|
|
161
161
|
|
|
162
162
|
/**
|
|
163
|
+
* Compute range of a given array, it only supports 1D arrays.
|
|
164
|
+
*
|
|
165
|
+
* @param {Number[]} values Array to go through to extract the range from
|
|
166
|
+
* @param {Number} offset offset index to select the desired component in the tuple
|
|
167
|
+
* @param {Number} numberOfComponents size of tuple in a multi-channel array
|
|
168
|
+
*/
|
|
169
|
+
export function fastComputeRange(values: number[], offset: number, numberOfComponents: number): vtkRange;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* @deprecated please use `fastComputeRange` instead
|
|
163
173
|
* Create helper object that can be used to gather min, max, count, sum of
|
|
164
174
|
* a set of values.
|
|
165
175
|
*/
|
|
@@ -242,6 +252,7 @@ export declare const vtkDataArray: {
|
|
|
242
252
|
// static
|
|
243
253
|
computeRange: typeof computeRange,
|
|
244
254
|
createRangeHelper: typeof createRangeHelper,
|
|
255
|
+
fastComputeRange: typeof fastComputeRange,
|
|
245
256
|
getDataType: typeof getDataType,
|
|
246
257
|
getMaxNorm: typeof getMaxNorm,
|
|
247
258
|
// constants
|
package/Common/Core/DataArray.js
CHANGED
|
@@ -10,6 +10,45 @@ var DefaultDataType = Constants.DefaultDataType;
|
|
|
10
10
|
var TUPLE_HOLDER = []; // ----------------------------------------------------------------------------
|
|
11
11
|
// Global methods
|
|
12
12
|
// ----------------------------------------------------------------------------
|
|
13
|
+
// Original source from https://www.npmjs.com/package/compute-range
|
|
14
|
+
// Modified to accept type arrays
|
|
15
|
+
|
|
16
|
+
function fastComputeRange(arr, offset, numberOfComponents) {
|
|
17
|
+
var len = arr.length;
|
|
18
|
+
var min;
|
|
19
|
+
var max;
|
|
20
|
+
var x;
|
|
21
|
+
var i;
|
|
22
|
+
|
|
23
|
+
if (len === 0) {
|
|
24
|
+
return {
|
|
25
|
+
min: Number.MAX_VALUE,
|
|
26
|
+
max: -Number.MAX_VALUE
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
min = arr[offset];
|
|
31
|
+
max = min;
|
|
32
|
+
|
|
33
|
+
for (i = offset; i < len; i += numberOfComponents) {
|
|
34
|
+
x = arr[i];
|
|
35
|
+
|
|
36
|
+
if (x < min) {
|
|
37
|
+
min = x;
|
|
38
|
+
} else if (x > max) {
|
|
39
|
+
max = x;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
min: min,
|
|
45
|
+
max: max
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* @deprecated please use fastComputeRange instead
|
|
50
|
+
*/
|
|
51
|
+
|
|
13
52
|
|
|
14
53
|
function createRangeHelper() {
|
|
15
54
|
var min = Number.MAX_VALUE;
|
|
@@ -50,33 +89,27 @@ function createRangeHelper() {
|
|
|
50
89
|
function computeRange(values) {
|
|
51
90
|
var component = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
52
91
|
var numberOfComponents = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
|
|
53
|
-
var helper = createRangeHelper();
|
|
54
|
-
var size = values.length;
|
|
55
|
-
var value = 0;
|
|
56
92
|
|
|
57
93
|
if (component < 0 && numberOfComponents > 1) {
|
|
58
94
|
// Compute magnitude
|
|
59
|
-
|
|
60
|
-
|
|
95
|
+
var size = values.length;
|
|
96
|
+
var numberOfValues = size / numberOfComponents;
|
|
97
|
+
var data = new Float64Array(numberOfValues);
|
|
61
98
|
|
|
62
|
-
|
|
63
|
-
|
|
99
|
+
for (var i = 0, j = 0; i < numberOfValues; ++i) {
|
|
100
|
+
var _i;
|
|
101
|
+
|
|
102
|
+
for (var nextJ = j + numberOfComponents; j < nextJ; ++j) {
|
|
103
|
+
data[i] += values[j] * values[j];
|
|
64
104
|
}
|
|
65
105
|
|
|
66
|
-
|
|
67
|
-
helper.add(value);
|
|
106
|
+
_i = i, data[_i] = Math.pow(data[_i], 0.5);
|
|
68
107
|
}
|
|
69
108
|
|
|
70
|
-
return
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
var offset = component < 0 ? 0 : component;
|
|
74
|
-
|
|
75
|
-
for (var _i = offset; _i < size; _i += numberOfComponents) {
|
|
76
|
-
helper.add(values[_i]);
|
|
109
|
+
return fastComputeRange(data, 0, 1);
|
|
77
110
|
}
|
|
78
111
|
|
|
79
|
-
return
|
|
112
|
+
return fastComputeRange(values, component < 0 ? 0 : component, numberOfComponents);
|
|
80
113
|
}
|
|
81
114
|
|
|
82
115
|
function ensureRangeSize(rangeArray) {
|
|
@@ -116,6 +149,7 @@ function getMaxNorm(normArray) {
|
|
|
116
149
|
var STATIC = {
|
|
117
150
|
computeRange: computeRange,
|
|
118
151
|
createRangeHelper: createRangeHelper,
|
|
152
|
+
fastComputeRange: fastComputeRange,
|
|
119
153
|
getDataType: getDataType,
|
|
120
154
|
getMaxNorm: getMaxNorm
|
|
121
155
|
}; // ----------------------------------------------------------------------------
|
package/Rendering/Core/Mapper.js
CHANGED
|
@@ -189,7 +189,7 @@ function vtkMapper(publicAPI, model) {
|
|
|
189
189
|
if (lut) {
|
|
190
190
|
// Ensure that the lookup table is built
|
|
191
191
|
lut.build();
|
|
192
|
-
model.colorMapColors = lut.mapScalars(scalars, model.colorMode,
|
|
192
|
+
model.colorMapColors = lut.mapScalars(scalars, model.colorMode, model.fieldDataTupleId);
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
195
|
|
|
@@ -158,7 +158,7 @@ function vtkMapper2D(publicAPI, model) {
|
|
|
158
158
|
if (lut) {
|
|
159
159
|
// Ensure that the lookup table is built
|
|
160
160
|
lut.build();
|
|
161
|
-
model.colorMapColors = lut.mapScalars(scalars, model.colorMode,
|
|
161
|
+
model.colorMapColors = lut.mapScalars(scalars, model.colorMode, model.fieldDataTupleId);
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
model.colorBuildString = "".concat(publicAPI.getMTime()).concat(scalars.getMTime()).concat(alpha);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import vtkRenderWindow, { IRenderWindowInitialValues } from '@kitware/vtk.js/Rendering/Core/RenderWindow';
|
|
2
2
|
|
|
3
3
|
// Keeps state for client / server scene synchronization.
|
|
4
4
|
export interface SynchContext {
|
|
@@ -33,7 +33,7 @@ export interface IInitialValues extends IRenderWindowInitialValues {
|
|
|
33
33
|
|
|
34
34
|
// Server-side view state.
|
|
35
35
|
export interface ViewState {
|
|
36
|
-
id:
|
|
36
|
+
id: string;
|
|
37
37
|
// vtk object type.
|
|
38
38
|
type: string;
|
|
39
39
|
// vtk object mtime.
|
|
@@ -57,7 +57,7 @@ function getPixelInformationWithData(buffdata, inDisplayPosition, maxDistance, o
|
|
|
57
57
|
var displayPosition = [inDisplayPosition[0] - buffdata.area[0], inDisplayPosition[1] - buffdata.area[1]];
|
|
58
58
|
var actorid = convert(displayPosition[0], displayPosition[1], buffdata.pixBuffer[PassTypes.ACTOR_PASS], buffdata.area);
|
|
59
59
|
|
|
60
|
-
if (actorid <= 0) {
|
|
60
|
+
if (actorid <= 0 || actorid - idOffset >= buffdata.props.length) {
|
|
61
61
|
// the pixel did not hit any actor.
|
|
62
62
|
return null;
|
|
63
63
|
}
|
|
@@ -520,7 +520,7 @@ function vtkOpenGLHardwareSelector(publicAPI, model) {
|
|
|
520
520
|
var displayPosition = [inDisplayPosition[0] - model.area[0], inDisplayPosition[1] - model.area[1]];
|
|
521
521
|
var actorid = convert(displayPosition[0], displayPosition[1], model.pixBuffer[PassTypes.ACTOR_PASS], model.area);
|
|
522
522
|
|
|
523
|
-
if (actorid <= 0) {
|
|
523
|
+
if (actorid <= 0 || actorid - idOffset >= model.props.length) {
|
|
524
524
|
// the pixel did not hit any actor.
|
|
525
525
|
return null;
|
|
526
526
|
}
|
package/Rendering/OpenGL.js
CHANGED
|
@@ -16,6 +16,7 @@ import vtkOpenGLPolyDataMapper from './OpenGL/PolyDataMapper.js';
|
|
|
16
16
|
import vtkPolyDataMapper2D from './OpenGL/PolyDataMapper2D.js';
|
|
17
17
|
import vtkRenderer from './OpenGL/Renderer.js';
|
|
18
18
|
import vtkRenderWindow from './OpenGL/RenderWindow.js';
|
|
19
|
+
import './OpenGL/ScalarBarActor.js';
|
|
19
20
|
import vtkShader from './OpenGL/Shader.js';
|
|
20
21
|
import vtkShaderCache from './OpenGL/ShaderCache.js';
|
|
21
22
|
import vtkShaderProgram from './OpenGL/ShaderProgram.js';
|
|
@@ -20,15 +20,6 @@ var vtkDebugMacro = vtkDebugMacro$1; // the webgpu constants all show up as unde
|
|
|
20
20
|
// ----------------------------------------------------------------------------
|
|
21
21
|
|
|
22
22
|
var STATIC = {};
|
|
23
|
-
|
|
24
|
-
function requestMatches(req1, req2) {
|
|
25
|
-
if (req1.time !== req2.time) return false;
|
|
26
|
-
if (req1.format !== req2.format) return false;
|
|
27
|
-
if (req1.usage !== req2.usage) return false;
|
|
28
|
-
if (req1.hash !== req2.hash) return false;
|
|
29
|
-
return true;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
23
|
var cellCounters = {
|
|
33
24
|
// easy, every input point becomes an output point
|
|
34
25
|
anythingToPoints: function anythingToPoints(numPoints, cellPts) {
|
|
@@ -363,44 +354,10 @@ function generateNormals(cellArray, primType, representation, inArray) {
|
|
|
363
354
|
|
|
364
355
|
function vtkWebGPUBufferManager(publicAPI, model) {
|
|
365
356
|
// Set our className
|
|
366
|
-
model.classHierarchy.push('vtkWebGPUBufferManager');
|
|
367
|
-
|
|
368
|
-
publicAPI.hasBuffer = function (req) {
|
|
369
|
-
if (req.source) {
|
|
370
|
-
// if a matching buffer already exists then return true
|
|
371
|
-
if (model.buffers.has(req.source)) {
|
|
372
|
-
var dabuffers = model.buffers.get(req.source);
|
|
373
|
-
|
|
374
|
-
for (var i = 0; i < dabuffers.length; i++) {
|
|
375
|
-
if (requestMatches(dabuffers[i].request, req)) {
|
|
376
|
-
return true;
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
return false;
|
|
383
|
-
}; // we cache based on the passed in source, when the source is
|
|
384
|
-
// garbage collected then the cache entry is removed. If a source
|
|
385
|
-
// is not provided then the buffer is NOT cached and you are on your own
|
|
386
|
-
// if you want to share it etc
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
publicAPI.getBuffer = function (req) {
|
|
390
|
-
if (req.source) {
|
|
391
|
-
// if a matching buffer already exists then return it
|
|
392
|
-
if (model.buffers.has(req.source)) {
|
|
393
|
-
var dabuffers = model.buffers.get(req.source);
|
|
394
|
-
|
|
395
|
-
for (var i = 0; i < dabuffers.length; i++) {
|
|
396
|
-
if (requestMatches(dabuffers[i].request, req)) {
|
|
397
|
-
return dabuffers[i].buffer;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
} // if a dataArray is provided set the nativeArray
|
|
402
|
-
|
|
357
|
+
model.classHierarchy.push('vtkWebGPUBufferManager');
|
|
403
358
|
|
|
359
|
+
function _createBuffer(req) {
|
|
360
|
+
// if a dataArray is provided set the nativeArray
|
|
404
361
|
if (req.dataArray && !req.nativeArray) {
|
|
405
362
|
req.nativeArray = req.dataArray.getData();
|
|
406
363
|
} // create one
|
|
@@ -450,8 +407,7 @@ function vtkWebGPUBufferManager(publicAPI, model) {
|
|
|
450
407
|
scale: req.scale,
|
|
451
408
|
cellData: req.cellData,
|
|
452
409
|
cellOffset: req.cellOffset
|
|
453
|
-
});
|
|
454
|
-
|
|
410
|
+
});
|
|
455
411
|
buffer.createAndWrite(result.nativeArray, gpuUsage);
|
|
456
412
|
buffer.setStrideInBytes(vtkWebGPUTypes.getByteStrideFromBufferFormat(req.format));
|
|
457
413
|
buffer.setArrayInformation([{
|
|
@@ -482,29 +438,30 @@ function vtkWebGPUBufferManager(publicAPI, model) {
|
|
|
482
438
|
}]);
|
|
483
439
|
}
|
|
484
440
|
|
|
485
|
-
buffer.setSourceTime(req.time);
|
|
486
|
-
|
|
487
|
-
|
|
441
|
+
buffer.setSourceTime(req.time);
|
|
442
|
+
return buffer;
|
|
443
|
+
} // is the buffer already present?
|
|
488
444
|
|
|
489
|
-
if (req.source) {
|
|
490
|
-
if (!model.buffers.has(req.source)) {
|
|
491
|
-
model.buffers.set(req.source, []);
|
|
492
|
-
}
|
|
493
445
|
|
|
494
|
-
|
|
446
|
+
publicAPI.hasBuffer = function (req) {
|
|
447
|
+
if (req.owner) {
|
|
448
|
+
// if a matching buffer already exists then return true
|
|
449
|
+
var hash = req.time + req.format + req.usage + req.hash;
|
|
450
|
+
return model.device.hasCachedObject(req.owner, hash);
|
|
451
|
+
}
|
|
495
452
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
453
|
+
return false;
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
publicAPI.getBuffer = function (req) {
|
|
457
|
+
// if we have a source the get/create/cache the buffer
|
|
458
|
+
if (req.owner) {
|
|
459
|
+
// if a matching buffer already exists then return it
|
|
460
|
+
var hash = req.time + req.format + req.usage + req.hash;
|
|
461
|
+
return model.device.getCachedObject(req.owner, hash, _createBuffer, req);
|
|
505
462
|
}
|
|
506
463
|
|
|
507
|
-
return
|
|
464
|
+
return _createBuffer(req);
|
|
508
465
|
};
|
|
509
466
|
|
|
510
467
|
publicAPI.getFullScreenQuadBuffer = function () {
|
|
@@ -538,9 +495,7 @@ function extend(publicAPI, model) {
|
|
|
538
495
|
var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
539
496
|
Object.assign(model, DEFAULT_VALUES, initialValues); // Object methods
|
|
540
497
|
|
|
541
|
-
obj(publicAPI, model);
|
|
542
|
-
|
|
543
|
-
model.buffers = new WeakMap();
|
|
498
|
+
obj(publicAPI, model);
|
|
544
499
|
setGet(publicAPI, model, ['device']);
|
|
545
500
|
vtkWebGPUBufferManager(publicAPI, model);
|
|
546
501
|
} // ----------------------------------------------------------------------------
|
|
@@ -89,6 +89,76 @@ function vtkWebGPUDevice(publicAPI, model) {
|
|
|
89
89
|
|
|
90
90
|
publicAPI.onSubmittedWorkDone = function () {
|
|
91
91
|
return model.handle.queue.onSubmittedWorkDone();
|
|
92
|
+
}; // The Device has an object cache that can be used to cache buffers,
|
|
93
|
+
// textures and other objects that can be shared. The basic approach is to
|
|
94
|
+
// call getCachedObject with a request and a create function. The request
|
|
95
|
+
// must have two fields a hash and an owner. The owner is what the weak
|
|
96
|
+
// map uses to hold onto the cached object. When the owner is deleted the
|
|
97
|
+
// cached object will be freed from the cache. The cache lookup just
|
|
98
|
+
// returns any entry that has a matching owner and hash. If a match isn't
|
|
99
|
+
// found then the create function is called with any extra arguments.
|
|
100
|
+
//
|
|
101
|
+
// For best memory management it is important that the owner be as close
|
|
102
|
+
// to the underlying object as possible. For example for a point data buffer
|
|
103
|
+
// you would want the actual vtkDataArray to be the owner, not the polydata
|
|
104
|
+
// or even worse the actor. As the points data array could be freed wihtout
|
|
105
|
+
// the polydata or actor being freed.
|
|
106
|
+
// is the object already cached?
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
publicAPI.hasCachedObject = function (owner, hash) {
|
|
110
|
+
if (!owner) {
|
|
111
|
+
return false;
|
|
112
|
+
} // if a matching request already exists then return true
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
if (model.objectCache.has(owner)) {
|
|
116
|
+
var objects = model.objectCache.get(owner);
|
|
117
|
+
|
|
118
|
+
for (var i = 0; i < objects.length; i++) {
|
|
119
|
+
if (hash === objects[i].hash) {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return false;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
publicAPI.getCachedObject = function (owner, hash, creator) {
|
|
129
|
+
if (!owner || !hash) {
|
|
130
|
+
vtkErrorMacro('attempt to cache an object without an owner or hash');
|
|
131
|
+
return null;
|
|
132
|
+
} // if a matching request already exists then return the cached object
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
if (model.objectCache.has(owner)) {
|
|
136
|
+
var _objects = model.objectCache.get(owner);
|
|
137
|
+
|
|
138
|
+
for (var i = 0; i < _objects.length; i++) {
|
|
139
|
+
if (hash === _objects[i].hash) {
|
|
140
|
+
return _objects[i].object;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
} // otherwise create the object and cache it
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
for (var _len = arguments.length, args = new Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {
|
|
147
|
+
args[_key - 3] = arguments[_key];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
var createdObject = creator.apply(void 0, args);
|
|
151
|
+
|
|
152
|
+
if (!model.objectCache.has(owner)) {
|
|
153
|
+
model.objectCache.set(owner, []);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
var objects = model.objectCache.get(owner);
|
|
157
|
+
objects.push({
|
|
158
|
+
hash: hash,
|
|
159
|
+
object: createdObject
|
|
160
|
+
});
|
|
161
|
+
return createdObject;
|
|
92
162
|
};
|
|
93
163
|
} // ----------------------------------------------------------------------------
|
|
94
164
|
// Object factory
|
|
@@ -110,7 +180,9 @@ function extend(publicAPI, model) {
|
|
|
110
180
|
|
|
111
181
|
obj(publicAPI, model);
|
|
112
182
|
setGet(publicAPI, model, ['handle']);
|
|
113
|
-
get(publicAPI, model, ['bufferManager', 'shaderCache', 'textureManager']);
|
|
183
|
+
get(publicAPI, model, ['bufferManager', 'shaderCache', 'textureManager']); // this is a cache, and a cache with GC pretty much means WeakMap
|
|
184
|
+
|
|
185
|
+
model.objectCache = new WeakMap();
|
|
114
186
|
model.shaderCache = vtkWebGPUShaderCache.newInstance();
|
|
115
187
|
model.shaderCache.setDevice(publicAPI);
|
|
116
188
|
model.bindGroupLayouts = [];
|
|
@@ -269,7 +269,7 @@ function vtkWebGPUImageMapper(publicAPI, model) {
|
|
|
269
269
|
publicAPI.updateBuffers = function (device) {
|
|
270
270
|
var treq = {
|
|
271
271
|
imageData: model.currentInput,
|
|
272
|
-
|
|
272
|
+
owner: model.currentInput.getPointData().getScalars()
|
|
273
273
|
};
|
|
274
274
|
var newTex = device.getTextureManager().getTexture(treq);
|
|
275
275
|
var tViews = model.helper.getTextureViews();
|
|
@@ -262,7 +262,8 @@ function vtkWebGPUPolyDataMapper(publicAPI, model) {
|
|
|
262
262
|
representation = Representation.WIREFRAME;
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
-
var vertexInput = model.primitives[primType].getVertexInput();
|
|
265
|
+
var vertexInput = model.primitives[primType].getVertexInput();
|
|
266
|
+
var hash = "R".concat(representation, "P").concat(primType); // hash = all things that can change the values on the buffer
|
|
266
267
|
// since mtimes are unique we can use
|
|
267
268
|
// - cells mtime - because cells drive how we pack
|
|
268
269
|
// - rep (point/wireframe/surface) - again because of packing
|
|
@@ -273,24 +274,23 @@ function vtkWebGPUPolyDataMapper(publicAPI, model) {
|
|
|
273
274
|
// - usage
|
|
274
275
|
// - packExtra - covered by format
|
|
275
276
|
// - prim type (vert/lines/polys/strips) - covered by cells mtime
|
|
276
|
-
|
|
277
|
-
var hash = cells.getMTime() + representation; // points
|
|
277
|
+
// points
|
|
278
278
|
|
|
279
279
|
var points = pd.getPoints();
|
|
280
280
|
|
|
281
281
|
if (points) {
|
|
282
282
|
var shift = model.WebGPUActor.getBufferShift(model.WebGPURenderer);
|
|
283
283
|
var buffRequest = {
|
|
284
|
-
|
|
284
|
+
owner: points,
|
|
285
|
+
usage: BufferUsage.PointArray,
|
|
286
|
+
format: 'float32x4',
|
|
287
|
+
time: Math.max(points.getMTime(), cells.getMTime(), model.WebGPUActor.getKeyMatricesTime().getMTime()),
|
|
288
|
+
hash: hash,
|
|
285
289
|
dataArray: points,
|
|
286
|
-
source: points,
|
|
287
290
|
cells: cells,
|
|
288
291
|
primitiveType: primType,
|
|
289
292
|
representation: representation,
|
|
290
|
-
time: Math.max(points.getMTime(), cells.getMTime(), model.WebGPUActor.getKeyMatricesTime().getMTime()),
|
|
291
293
|
shift: shift,
|
|
292
|
-
usage: BufferUsage.PointArray,
|
|
293
|
-
format: 'float32x4',
|
|
294
294
|
packExtra: true
|
|
295
295
|
};
|
|
296
296
|
var buff = device.getBufferManager().getBuffer(buffRequest);
|
|
@@ -305,19 +305,19 @@ function vtkWebGPUPolyDataMapper(publicAPI, model) {
|
|
|
305
305
|
if (usage === BufferUsage.Triangles || usage === BufferUsage.Strips) {
|
|
306
306
|
var normals = pd.getPointData().getNormals();
|
|
307
307
|
var _buffRequest = {
|
|
308
|
+
format: 'snorm8x4',
|
|
309
|
+
hash: hash,
|
|
308
310
|
cells: cells,
|
|
309
311
|
representation: representation,
|
|
310
312
|
primitiveType: primType,
|
|
311
|
-
format: 'snorm8x4',
|
|
312
313
|
packExtra: true,
|
|
313
314
|
shift: 0,
|
|
314
315
|
scale: 127
|
|
315
316
|
};
|
|
316
317
|
|
|
317
318
|
if (normals) {
|
|
318
|
-
_buffRequest.
|
|
319
|
+
_buffRequest.owner = normals;
|
|
319
320
|
_buffRequest.dataArray = normals;
|
|
320
|
-
_buffRequest.source = normals;
|
|
321
321
|
_buffRequest.time = Math.max(normals.getMTime(), cells.getMTime());
|
|
322
322
|
_buffRequest.usage = BufferUsage.PointArray;
|
|
323
323
|
|
|
@@ -325,9 +325,8 @@ function vtkWebGPUPolyDataMapper(publicAPI, model) {
|
|
|
325
325
|
|
|
326
326
|
vertexInput.addBuffer(_buff, ['normalMC']);
|
|
327
327
|
} else if (primType === PrimitiveTypes.Triangles) {
|
|
328
|
-
_buffRequest.
|
|
328
|
+
_buffRequest.owner = points;
|
|
329
329
|
_buffRequest.dataArray = points;
|
|
330
|
-
_buffRequest.source = points;
|
|
331
330
|
_buffRequest.time = Math.max(points.getMTime(), cells.getMTime());
|
|
332
331
|
_buffRequest.usage = BufferUsage.NormalsFromPoints;
|
|
333
332
|
|
|
@@ -356,15 +355,15 @@ function vtkWebGPUPolyDataMapper(publicAPI, model) {
|
|
|
356
355
|
}
|
|
357
356
|
|
|
358
357
|
var _buffRequest2 = {
|
|
359
|
-
|
|
358
|
+
owner: c,
|
|
359
|
+
usage: BufferUsage.PointArray,
|
|
360
|
+
format: 'unorm8x4',
|
|
361
|
+
time: Math.max(c.getMTime(), cells.getMTime(), points.getMTime()),
|
|
362
|
+
hash: hash + haveCellScalars,
|
|
360
363
|
dataArray: c,
|
|
361
|
-
source: c,
|
|
362
364
|
cells: cells,
|
|
363
365
|
primitiveType: primType,
|
|
364
366
|
representation: representation,
|
|
365
|
-
time: Math.max(c.getMTime(), cells.getMTime()),
|
|
366
|
-
usage: BufferUsage.PointArray,
|
|
367
|
-
format: 'unorm8x4',
|
|
368
367
|
cellData: haveCellScalars,
|
|
369
368
|
cellOffset: 0
|
|
370
369
|
};
|
|
@@ -390,15 +389,15 @@ function vtkWebGPUPolyDataMapper(publicAPI, model) {
|
|
|
390
389
|
|
|
391
390
|
if (tcoords && !edges) {
|
|
392
391
|
var _buffRequest3 = {
|
|
393
|
-
|
|
392
|
+
owner: tcoords,
|
|
393
|
+
usage: BufferUsage.PointArray,
|
|
394
|
+
format: 'float32x2',
|
|
395
|
+
time: Math.max(tcoords.getMTime(), cells.getMTime()),
|
|
396
|
+
hash: hash,
|
|
394
397
|
dataArray: tcoords,
|
|
395
|
-
source: tcoords,
|
|
396
398
|
cells: cells,
|
|
397
399
|
primitiveType: primType,
|
|
398
|
-
representation: representation
|
|
399
|
-
time: Math.max(tcoords.getMTime(), cells.getMTime()),
|
|
400
|
-
usage: BufferUsage.PointArray,
|
|
401
|
-
format: 'float32x2'
|
|
400
|
+
representation: representation
|
|
402
401
|
};
|
|
403
402
|
|
|
404
403
|
var _buff4 = device.getBufferManager().getBuffer(_buffRequest3);
|
|
@@ -450,10 +449,10 @@ function vtkWebGPUPolyDataMapper(publicAPI, model) {
|
|
|
450
449
|
|
|
451
450
|
if (srcTexture.getInputData()) {
|
|
452
451
|
treq.imageData = srcTexture.getInputData();
|
|
453
|
-
treq.
|
|
452
|
+
treq.owner = treq.imageData.getPointData().getScalars();
|
|
454
453
|
} else if (srcTexture.getImage()) {
|
|
455
454
|
treq.image = srcTexture.getImage();
|
|
456
|
-
treq.
|
|
455
|
+
treq.owner = treq.image;
|
|
457
456
|
}
|
|
458
457
|
|
|
459
458
|
var newTex = model.device.getTextureManager().getTexture(treq);
|
|
@@ -67,8 +67,8 @@ function vtkWebGPUSphereMapper(publicAPI, model) {
|
|
|
67
67
|
primHelper.setNumberOfVertices(3 * numPoints);
|
|
68
68
|
var vertexInput = model.primitives[i].getVertexInput();
|
|
69
69
|
var buffRequest = {
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
owner: points,
|
|
71
|
+
hash: 'spm',
|
|
72
72
|
time: points.getMTime(),
|
|
73
73
|
usage: BufferUsage.RawVertex,
|
|
74
74
|
format: 'float32x3'
|
|
@@ -110,8 +110,8 @@ function vtkWebGPUSphereMapper(publicAPI, model) {
|
|
|
110
110
|
|
|
111
111
|
if (scales || defaultRadius !== model._lastRadius) {
|
|
112
112
|
buffRequest = {
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
owner: scales,
|
|
114
|
+
hash: 'spm',
|
|
115
115
|
time: scales ? pointData.getArray(model.renderable.getScaleArray()).getMTime() : 0,
|
|
116
116
|
usage: BufferUsage.RawVertex,
|
|
117
117
|
format: 'float32x2'
|
|
@@ -157,8 +157,8 @@ function vtkWebGPUSphereMapper(publicAPI, model) {
|
|
|
157
157
|
|
|
158
158
|
if (c) {
|
|
159
159
|
buffRequest = {
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
owner: c,
|
|
161
|
+
hash: 'spm',
|
|
162
162
|
time: c.getMTime(),
|
|
163
163
|
usage: BufferUsage.RawVertex,
|
|
164
164
|
format: 'unorm8x4'
|
|
@@ -89,8 +89,8 @@ function vtkWebGPUStickMapper(publicAPI, model) {
|
|
|
89
89
|
primHelper.setNumberOfVertices(12);
|
|
90
90
|
var vertexInput = model.primitives[i].getVertexInput();
|
|
91
91
|
var buffRequest = {
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
owner: points,
|
|
93
|
+
hash: 'stm',
|
|
94
94
|
time: points.getMTime(),
|
|
95
95
|
usage: BufferUsage.RawVertex,
|
|
96
96
|
format: 'float32x3'
|
|
@@ -125,8 +125,8 @@ function vtkWebGPUStickMapper(publicAPI, model) {
|
|
|
125
125
|
|
|
126
126
|
if (scales || defaultRadius !== model._lastRadius) {
|
|
127
127
|
buffRequest = {
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
owner: scales,
|
|
129
|
+
hash: 'stm',
|
|
130
130
|
time: scales ? pointData.getArray(model.renderable.getScaleArray()).getMTime() : 0,
|
|
131
131
|
usage: BufferUsage.RawVertex,
|
|
132
132
|
format: 'float32'
|
|
@@ -166,8 +166,8 @@ function vtkWebGPUStickMapper(publicAPI, model) {
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
buffRequest = {
|
|
169
|
-
|
|
170
|
-
|
|
169
|
+
owner: orientationArray,
|
|
170
|
+
hash: 'stm',
|
|
171
171
|
time: pointData.getArray(model.renderable.getOrientationArray()).getMTime(),
|
|
172
172
|
usage: BufferUsage.RawVertex,
|
|
173
173
|
format: 'float32x3'
|
|
@@ -209,8 +209,8 @@ function vtkWebGPUStickMapper(publicAPI, model) {
|
|
|
209
209
|
|
|
210
210
|
if (c) {
|
|
211
211
|
buffRequest = {
|
|
212
|
-
|
|
213
|
-
|
|
212
|
+
owner: c,
|
|
213
|
+
hash: 'stm',
|
|
214
214
|
time: c.getMTime(),
|
|
215
215
|
usage: BufferUsage.RawVertex,
|
|
216
216
|
format: 'unorm8x4'
|
|
@@ -5,26 +5,15 @@ import vtkWebGPUTexture from './Texture.js';
|
|
|
5
5
|
var VtkDataTypes = vtkDataArray.VtkDataTypes; // ----------------------------------------------------------------------------
|
|
6
6
|
// Global methods
|
|
7
7
|
// ----------------------------------------------------------------------------
|
|
8
|
-
|
|
9
|
-
function requestMatches(req1, req2) {
|
|
10
|
-
if (req1.time !== req2.time) return false;
|
|
11
|
-
if (req1.nativeArray !== req2.nativeArray) return false;
|
|
12
|
-
if (req1.format !== req2.format) return false;
|
|
13
|
-
return true;
|
|
14
|
-
} // ----------------------------------------------------------------------------
|
|
8
|
+
// ----------------------------------------------------------------------------
|
|
15
9
|
// vtkWebGPUTextureManager methods
|
|
16
10
|
// ----------------------------------------------------------------------------
|
|
17
11
|
|
|
18
|
-
|
|
19
12
|
function vtkWebGPUTextureManager(publicAPI, model) {
|
|
20
13
|
// Set our className
|
|
21
|
-
model.classHierarchy.push('vtkWebGPUTextureManager'); //
|
|
22
|
-
// - source, this is what owns the data and when it does away
|
|
23
|
-
// the data should be freed
|
|
24
|
-
// - imageData - when provided use as the source of the data
|
|
25
|
-
//
|
|
14
|
+
model.classHierarchy.push('vtkWebGPUTextureManager'); // fills in request values based on what is missing/provided
|
|
26
15
|
|
|
27
|
-
|
|
16
|
+
function _fillRequest(req) {
|
|
28
17
|
// fill in values based on imageData if the request has it
|
|
29
18
|
if (req.imageData) {
|
|
30
19
|
req.dataArray = req.imageData.getPointData().getScalars();
|
|
@@ -81,20 +70,10 @@ function vtkWebGPUTextureManager(publicAPI, model) {
|
|
|
81
70
|
req.depth = 1;
|
|
82
71
|
req.format = 'rgba8unorm';
|
|
83
72
|
}
|
|
73
|
+
} // create a texture (used by getTexture)
|
|
84
74
|
|
|
85
|
-
if (req.source) {
|
|
86
|
-
// if a matching texture already exists then return it
|
|
87
|
-
if (model.textures.has(req.source)) {
|
|
88
|
-
var dabuffers = model.textures.get(req.source);
|
|
89
|
-
|
|
90
|
-
for (var i = 0; i < dabuffers.length; i++) {
|
|
91
|
-
if (requestMatches(dabuffers[i].request, req)) {
|
|
92
|
-
return dabuffers[i].texture;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
75
|
|
|
76
|
+
function _createTexture(req) {
|
|
98
77
|
var newTex = vtkWebGPUTexture.newInstance();
|
|
99
78
|
newTex.create(model.device, {
|
|
100
79
|
width: req.width,
|
|
@@ -105,29 +84,25 @@ function vtkWebGPUTextureManager(publicAPI, model) {
|
|
|
105
84
|
|
|
106
85
|
if (req.nativeArray || req.image) {
|
|
107
86
|
newTex.writeImageData(req);
|
|
108
|
-
}
|
|
109
|
-
// We create a new req that only has the fields required for
|
|
110
|
-
// a comparison to avoid GC cycles
|
|
87
|
+
}
|
|
111
88
|
|
|
89
|
+
return newTex;
|
|
90
|
+
} // get a texture or create it if not cached.
|
|
91
|
+
// this is the main entry point
|
|
112
92
|
|
|
113
|
-
if (req.source) {
|
|
114
|
-
if (!model.textures.has(req.source)) {
|
|
115
|
-
model.textures.set(req.source, []);
|
|
116
|
-
}
|
|
117
93
|
|
|
118
|
-
|
|
94
|
+
publicAPI.getTexture = function (req) {
|
|
95
|
+
// if we have a source the get/create/cache the texture
|
|
96
|
+
if (req.owner) {
|
|
97
|
+
// fill out the req time and format based on imageData/image
|
|
98
|
+
_fillRequest(req); // if a matching texture already exists then return it
|
|
119
99
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
nativeArray: req.nativeArray,
|
|
124
|
-
format: req.format
|
|
125
|
-
},
|
|
126
|
-
texture: newTex
|
|
127
|
-
});
|
|
100
|
+
|
|
101
|
+
var hash = req.time + req.format;
|
|
102
|
+
return model.device.getCachedObject(req.owner, hash, _createTexture, req);
|
|
128
103
|
}
|
|
129
104
|
|
|
130
|
-
return
|
|
105
|
+
return _createTexture(req);
|
|
131
106
|
};
|
|
132
107
|
} // ----------------------------------------------------------------------------
|
|
133
108
|
// Object factory
|
|
@@ -135,7 +110,6 @@ function vtkWebGPUTextureManager(publicAPI, model) {
|
|
|
135
110
|
|
|
136
111
|
|
|
137
112
|
var DEFAULT_VALUES = {
|
|
138
|
-
textures: null,
|
|
139
113
|
handle: null,
|
|
140
114
|
device: null
|
|
141
115
|
}; // ----------------------------------------------------------------------------
|
|
@@ -144,9 +118,7 @@ function extend(publicAPI, model) {
|
|
|
144
118
|
var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
145
119
|
Object.assign(model, DEFAULT_VALUES, initialValues); // Object methods
|
|
146
120
|
|
|
147
|
-
macro.obj(publicAPI, model);
|
|
148
|
-
|
|
149
|
-
model.textures = new WeakMap();
|
|
121
|
+
macro.obj(publicAPI, model);
|
|
150
122
|
macro.setGet(publicAPI, model, ['device']);
|
|
151
123
|
vtkWebGPUTextureManager(publicAPI, model);
|
|
152
124
|
} // ----------------------------------------------------------------------------
|
|
@@ -259,20 +259,19 @@ function vtkWebGPUVolumePass(publicAPI, model) {
|
|
|
259
259
|
publicAPI.renderDepthBounds = function (renNode, viewNode) {
|
|
260
260
|
publicAPI.updateDepthPolyData(renNode);
|
|
261
261
|
var pd = model._boundsPoly;
|
|
262
|
-
var cells = pd.getPolys();
|
|
263
|
-
var hash = cells.getMTime(); // points
|
|
262
|
+
var cells = pd.getPolys(); // points
|
|
264
263
|
|
|
265
264
|
var points = pd.getPoints();
|
|
266
265
|
var buffRequest = {
|
|
267
|
-
|
|
266
|
+
owner: points,
|
|
267
|
+
usage: BufferUsage.PointArray,
|
|
268
|
+
format: 'float32x4',
|
|
269
|
+
time: Math.max(points.getMTime(), cells.getMTime()),
|
|
270
|
+
hash: 'vp',
|
|
268
271
|
dataArray: points,
|
|
269
|
-
source: points,
|
|
270
272
|
cells: cells,
|
|
271
273
|
primitiveType: PrimitiveTypes.Triangles,
|
|
272
274
|
representation: Representation.SURFACE,
|
|
273
|
-
time: Math.max(points.getMTime(), cells.getMTime()),
|
|
274
|
-
usage: BufferUsage.PointArray,
|
|
275
|
-
format: 'float32x4',
|
|
276
275
|
packExtra: true
|
|
277
276
|
};
|
|
278
277
|
var buff = viewNode.getDevice().getBufferManager().getBuffer(buffRequest);
|
package/Rendering/WebGPU.js
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
import vtkRenderWindow from './WebGPU/RenderWindow.js';
|
|
2
|
+
import './WebGPU/Actor.js';
|
|
3
|
+
import './WebGPU/Camera.js';
|
|
4
|
+
import './WebGPU/ForwardPass.js';
|
|
5
|
+
import './WebGPU/Glyph3DMapper.js';
|
|
6
|
+
import './WebGPU/HardwareSelector.js';
|
|
7
|
+
import './WebGPU/ImageMapper.js';
|
|
8
|
+
import './WebGPU/ImageSlice.js';
|
|
9
|
+
import './WebGPU/PixelSpaceCallbackMapper.js';
|
|
10
|
+
import './WebGPU/PolyDataMapper.js';
|
|
11
|
+
import './WebGPU/Renderer.js';
|
|
12
|
+
import './WebGPU/ScalarBarActor.js';
|
|
13
|
+
import './WebGPU/SphereMapper.js';
|
|
14
|
+
import './WebGPU/StickMapper.js';
|
|
15
|
+
import './WebGPU/Texture.js';
|
|
16
|
+
import './WebGPU/ViewNodeFactory.js';
|
|
17
|
+
import './WebGPU/Volume.js';
|
|
2
18
|
|
|
3
19
|
var WebGPU = {
|
|
4
20
|
vtkRenderWindow: vtkRenderWindow
|