@kitware/vtk.js 22.1.1 → 22.1.5
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/DataModel/ITKHelper.js +1 -1
- package/Filters/Sources/Arrow2DSource.js +1 -1
- package/Filters/Sources/ArrowSource.js +1 -1
- package/Filters/Sources/CircleSource.js +1 -1
- package/Filters/Sources/ConcentricCylinderSource.js +1 -1
- package/Filters/Sources/ConeSource.js +1 -1
- package/Filters/Sources/CubeSource.js +2 -2
- package/Filters/Sources/CylinderSource.js +1 -1
- package/Filters/Sources/LineSource.js +3 -3
- package/Filters/Sources/PlaneSource.js +4 -4
- package/Filters/Sources/PointSource.js +2 -2
- package/Filters/Sources/SLICSource.js +3 -3
- package/Filters/Sources/SphereSource.js +2 -2
- package/Filters/Sources/ViewFinderSource.js +1 -1
- package/Rendering/WebGPU/VolumePass.js +65 -75
- package/Widgets/Widgets3D/ResliceCursorWidget/helpers.js +15 -5
- package/package.json +1 -1
|
@@ -92,7 +92,7 @@ function convertItkToVtkImage(itkImage) {
|
|
|
92
92
|
imageData.getPointData().setScalars(pointData); // Associate the point data that are 3D vectors / tensors
|
|
93
93
|
// Refer to itk-js/src/PixelTypes.js for numerical values
|
|
94
94
|
|
|
95
|
-
switch (ITKPixelTypes[itkImage.imageType.pixelType]) {
|
|
95
|
+
switch (isITKWasm ? ITKPixelTypes[itkImage.imageType.pixelType] : itkImage.imageType.pixelType) {
|
|
96
96
|
case ITKPixelTypes.Scalar:
|
|
97
97
|
break;
|
|
98
98
|
|
|
@@ -72,7 +72,7 @@ var DEFAULT_VALUES = {
|
|
|
72
72
|
shaftRadius: 0.03,
|
|
73
73
|
invert: false,
|
|
74
74
|
direction: [1.0, 0.0, 0.0],
|
|
75
|
-
pointType: '
|
|
75
|
+
pointType: 'Float64Array'
|
|
76
76
|
}; // ----------------------------------------------------------------------------
|
|
77
77
|
|
|
78
78
|
function extend(publicAPI, model) {
|
|
@@ -386,7 +386,7 @@ var DEFAULT_VALUES = {
|
|
|
386
386
|
skipInnerFaces: true,
|
|
387
387
|
mask: null,
|
|
388
388
|
// If present, array to know if a layer should be skipped(=true)
|
|
389
|
-
pointType: '
|
|
389
|
+
pointType: 'Float64Array'
|
|
390
390
|
}; // ----------------------------------------------------------------------------
|
|
391
391
|
|
|
392
392
|
function extend(publicAPI, model) {
|
|
@@ -81,7 +81,7 @@ var DEFAULT_VALUES = {
|
|
|
81
81
|
center: [0, 0, 0],
|
|
82
82
|
direction: [1.0, 0.0, 0.0],
|
|
83
83
|
capping: true,
|
|
84
|
-
pointType: '
|
|
84
|
+
pointType: 'Float64Array'
|
|
85
85
|
}; // ----------------------------------------------------------------------------
|
|
86
86
|
|
|
87
87
|
function extend(publicAPI, model) {
|
|
@@ -178,7 +178,7 @@ function vtkCubeSource(publicAPI, model) {
|
|
|
178
178
|
(_vtkMatrixBuilder$bui = vtkMatrixBuilder.buildFromRadian()).translate.apply(_vtkMatrixBuilder$bui, _toConsumableArray(model.center)).apply(points); // Define quads
|
|
179
179
|
|
|
180
180
|
|
|
181
|
-
var polys =
|
|
181
|
+
var polys = new Uint16Array(numberOfPolys * 5);
|
|
182
182
|
polyData.getPolys().setData(polys, 1);
|
|
183
183
|
var polyIndex = 0;
|
|
184
184
|
polys[polyIndex++] = 4;
|
|
@@ -247,7 +247,7 @@ var DEFAULT_VALUES = {
|
|
|
247
247
|
zLength: 1.0,
|
|
248
248
|
center: [0.0, 0.0, 0.0],
|
|
249
249
|
rotations: [0.0, 0.0, 0.0],
|
|
250
|
-
pointType: '
|
|
250
|
+
pointType: 'Float64Array',
|
|
251
251
|
generate3DTextureCoordinates: false
|
|
252
252
|
}; // ----------------------------------------------------------------------------
|
|
253
253
|
|
|
@@ -180,7 +180,7 @@ var DEFAULT_VALUES = {
|
|
|
180
180
|
center: [0, 0, 0],
|
|
181
181
|
direction: [0.0, 1.0, 0.0],
|
|
182
182
|
capping: true,
|
|
183
|
-
pointType: '
|
|
183
|
+
pointType: 'Float64Array'
|
|
184
184
|
}; // ----------------------------------------------------------------------------
|
|
185
185
|
|
|
186
186
|
function extend(publicAPI, model) {
|
|
@@ -17,9 +17,9 @@ function vtkLineSource(publicAPI, model) {
|
|
|
17
17
|
|
|
18
18
|
var dataset = outData[0]; // Check input
|
|
19
19
|
|
|
20
|
-
var pointDataType = dataset ? dataset.getPoints().getDataType() :
|
|
20
|
+
var pointDataType = dataset ? dataset.getPoints().getDataType() : model.pointType;
|
|
21
21
|
var pd = vtkPolyData.newInstance();
|
|
22
|
-
var v21 =
|
|
22
|
+
var v21 = [];
|
|
23
23
|
subtract(model.point2, model.point1, v21);
|
|
24
24
|
|
|
25
25
|
if (norm(v21) <= 0.0) {
|
|
@@ -68,7 +68,7 @@ var DEFAULT_VALUES = {
|
|
|
68
68
|
resolution: 10,
|
|
69
69
|
point1: [-1, 0, 0],
|
|
70
70
|
point2: [1, 0, 0],
|
|
71
|
-
pointType: '
|
|
71
|
+
pointType: 'Float64Array'
|
|
72
72
|
}; // ----------------------------------------------------------------------------
|
|
73
73
|
|
|
74
74
|
function extend(publicAPI, model) {
|
|
@@ -22,10 +22,10 @@ function vtkPlaneSource(publicAPI, model) {
|
|
|
22
22
|
|
|
23
23
|
var dataset = outData[0]; // Check input
|
|
24
24
|
|
|
25
|
-
var pointDataType = dataset ? dataset.getPoints().getDataType() :
|
|
25
|
+
var pointDataType = dataset ? dataset.getPoints().getDataType() : model.pointType;
|
|
26
26
|
var pd = vtkPolyData.newInstance();
|
|
27
|
-
var v10 =
|
|
28
|
-
var v20 =
|
|
27
|
+
var v10 = [];
|
|
28
|
+
var v20 = [];
|
|
29
29
|
subtract(model.point1, model.origin, v10);
|
|
30
30
|
subtract(model.point2, model.origin, v20);
|
|
31
31
|
|
|
@@ -242,7 +242,7 @@ var DEFAULT_VALUES = {
|
|
|
242
242
|
origin: [0, 0, 0],
|
|
243
243
|
point1: [1, 0, 0],
|
|
244
244
|
point2: [0, 1, 0],
|
|
245
|
-
pointType: '
|
|
245
|
+
pointType: 'Float64Array'
|
|
246
246
|
}; // ----------------------------------------------------------------------------
|
|
247
247
|
|
|
248
248
|
function extend(publicAPI, model) {
|
|
@@ -16,7 +16,7 @@ function vtkPointSource(publicAPI, model) {
|
|
|
16
16
|
|
|
17
17
|
var dataset = outData[0]; // Check input
|
|
18
18
|
|
|
19
|
-
var pointDataType = dataset ? dataset.getPoints().getDataType() :
|
|
19
|
+
var pointDataType = dataset ? dataset.getPoints().getDataType() : model.pointType;
|
|
20
20
|
var pd = vtkPolyData.newInstance(); // hand create a point cloud
|
|
21
21
|
|
|
22
22
|
var numPts = model.numberOfPoints; // Points
|
|
@@ -63,7 +63,7 @@ var DEFAULT_VALUES = {
|
|
|
63
63
|
numberOfPoints: 10,
|
|
64
64
|
center: [0, 0, 0],
|
|
65
65
|
radius: 0.5,
|
|
66
|
-
pointType: '
|
|
66
|
+
pointType: 'Float64Array'
|
|
67
67
|
}; // ----------------------------------------------------------------------------
|
|
68
68
|
|
|
69
69
|
function extend(publicAPI, model) {
|
|
@@ -7,7 +7,7 @@ import vtkDataArray from '../../Common/Core/DataArray.js';
|
|
|
7
7
|
// ----------------------------------------------------------------------------
|
|
8
8
|
|
|
9
9
|
function generateCoordinates(origin, dimensions, spacing) {
|
|
10
|
-
var coordinates = new
|
|
10
|
+
var coordinates = new Float64Array(dimensions[0] * dimensions[1] * dimensions[2] * 3);
|
|
11
11
|
var offset = 0;
|
|
12
12
|
|
|
13
13
|
for (var k = 0; k < dimensions[2]; k++) {
|
|
@@ -37,7 +37,7 @@ function vtkSLICSource(publicAPI, model) {
|
|
|
37
37
|
|
|
38
38
|
publicAPI.addCluster = function (centerX, centerY, centerZ, fnConst, fnDfDx, fnDfDy, fnDfDz) {
|
|
39
39
|
var id = model.clusters.length;
|
|
40
|
-
model.clusters.push(new
|
|
40
|
+
model.clusters.push(new Float64Array([centerX, centerY, centerZ, fnConst, fnDfDx, fnDfDy, fnDfDz]));
|
|
41
41
|
publicAPI.modified();
|
|
42
42
|
return id;
|
|
43
43
|
};
|
|
@@ -54,7 +54,7 @@ function vtkSLICSource(publicAPI, model) {
|
|
|
54
54
|
|
|
55
55
|
publicAPI.updateCluster = function (id, centerX, centerY, centerZ, fnConst, fnDfDx, fnDfDy, fnDfDz) {
|
|
56
56
|
if (!model.clusters[id]) {
|
|
57
|
-
model.clusters[id] = new
|
|
57
|
+
model.clusters[id] = new Float64Array(7);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
model.clusters[id][0] = centerX;
|
|
@@ -15,7 +15,7 @@ function vtkSphereSource(publicAPI, model) {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
var dataset = outData[0];
|
|
18
|
-
var pointDataType = dataset ? dataset.getPoints().getDataType() :
|
|
18
|
+
var pointDataType = dataset ? dataset.getPoints().getDataType() : model.pointType;
|
|
19
19
|
dataset = vtkPolyData.newInstance(); // ----------------------------------------------------------------------
|
|
20
20
|
|
|
21
21
|
var numPoles = 0; // Check data, determine increments, and convert to radians
|
|
@@ -180,7 +180,7 @@ var DEFAULT_VALUES = {
|
|
|
180
180
|
startPhi: 0.0,
|
|
181
181
|
endPhi: 180.0,
|
|
182
182
|
center: [0, 0, 0],
|
|
183
|
-
pointType: '
|
|
183
|
+
pointType: 'Float64Array'
|
|
184
184
|
}; // ----------------------------------------------------------------------------
|
|
185
185
|
|
|
186
186
|
function extend(publicAPI, model) {
|
|
@@ -8,6 +8,7 @@ import vtkWebGPUMapperHelper from './MapperHelper.js';
|
|
|
8
8
|
import vtkWebGPURenderEncoder from './RenderEncoder.js';
|
|
9
9
|
import vtkWebGPUShaderCache from './ShaderCache.js';
|
|
10
10
|
import vtkWebGPUTexture from './Texture.js';
|
|
11
|
+
import vtkWebGPUUniformBuffer from './UniformBuffer.js';
|
|
11
12
|
import vtkWebGPUFullScreenQuad from './FullScreenQuad.js';
|
|
12
13
|
import vtkWebGPUVolumePassFSQ from './VolumePassFSQ.js';
|
|
13
14
|
import { f as distance2BetweenPoints } from '../../Common/Core/Math/index.js';
|
|
@@ -33,7 +34,7 @@ var BufferUsage = vtkWebGPUBufferManager.BufferUsage,
|
|
|
33
34
|
|
|
34
35
|
var cubeFaceTriangles = [[0, 4, 6], [0, 6, 2], [1, 3, 7], [1, 7, 5], [0, 5, 4], [0, 1, 5], [2, 6, 7], [2, 7, 3], [0, 3, 1], [0, 2, 3], [4, 5, 7], [4, 7, 6]];
|
|
35
36
|
var DepthBoundsFS = "\n//VTK::Renderer::Dec\n\n//VTK::Select::Dec\n\n//VTK::VolumePass::Dec\n\n//VTK::TCoord::Dec\n\n//VTK::RenderEncoder::Dec\n\n//VTK::Mapper::Dec\n\n//VTK::IOStructs::Dec\n\n[[stage(fragment)]]\nfn main(\n//VTK::IOStructs::Input\n)\n//VTK::IOStructs::Output\n{\n var output : fragmentOutput;\n\n //VTK::Select::Impl\n\n //VTK::TCoord::Impl\n\n //VTK::VolumePass::Impl\n\n // use the maximum (closest) of the current value and the zbuffer\n // the blend func will then take the min to find the farthest stop value\n var stopval: f32 = max(input.fragPos.z, textureLoad(opaquePassDepthTexture, vec2<i32>(i32(input.fragPos.x), i32(input.fragPos.y)), 0));\n\n //VTK::RenderEncoder::Impl\n return output;\n}\n";
|
|
36
|
-
var volumeCopyFragTemplate = "\n//VTK::Renderer::Dec\n\n//VTK::Mapper::Dec\n\n//VTK::TCoord::Dec\n\n//VTK::RenderEncoder::Dec\n\n//VTK::IOStructs::Dec\n\n[[stage(fragment)]]\nfn main(\n//VTK::IOStructs::Input\n)\n//VTK::IOStructs::Output\n{\n var output: fragmentOutput;\n\n var computedColor: vec4<f32> = textureSample(volumePassSmallColorTexture,\n volumePassSmallColorTextureSampler, input.tcoordVS);\n\n //VTK::RenderEncoder::Impl\n return output;\n}\n";
|
|
37
|
+
var volumeCopyFragTemplate = "\n//VTK::Renderer::Dec\n\n//VTK::Mapper::Dec\n\n//VTK::TCoord::Dec\n\n//VTK::RenderEncoder::Dec\n\n//VTK::IOStructs::Dec\n\n[[stage(fragment)]]\nfn main(\n//VTK::IOStructs::Input\n)\n//VTK::IOStructs::Output\n{\n var output: fragmentOutput;\n\n var computedColor: vec4<f32> = textureSample(volumePassSmallColorTexture,\n volumePassSmallColorTextureSampler, mapperUBO.tscale*input.tcoordVS);\n\n //VTK::RenderEncoder::Impl\n return output;\n}\n";
|
|
37
38
|
/* eslint-disable no-undef */
|
|
38
39
|
|
|
39
40
|
/* eslint-disable no-bitwise */
|
|
@@ -44,14 +45,14 @@ function vtkWebGPUVolumePass(publicAPI, model) {
|
|
|
44
45
|
model.classHierarchy.push('vtkWebGPUVolumePass'); // create the required textures, encoders, FSQ etc
|
|
45
46
|
|
|
46
47
|
publicAPI.initialize = function (viewNode) {
|
|
47
|
-
if (!model._mergeEncoder) {
|
|
48
|
-
publicAPI.createMergeEncoder(viewNode);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
48
|
if (!model._clearEncoder) {
|
|
52
49
|
publicAPI.createClearEncoder(viewNode);
|
|
53
50
|
}
|
|
54
51
|
|
|
52
|
+
if (!model._mergeEncoder) {
|
|
53
|
+
publicAPI.createMergeEncoder(viewNode);
|
|
54
|
+
}
|
|
55
|
+
|
|
55
56
|
if (!model._copyEncoder) {
|
|
56
57
|
publicAPI.createCopyEncoder(viewNode);
|
|
57
58
|
}
|
|
@@ -74,6 +75,16 @@ function vtkWebGPUVolumePass(publicAPI, model) {
|
|
|
74
75
|
model._volumeCopyQuad.setDevice(viewNode.getDevice());
|
|
75
76
|
|
|
76
77
|
model._volumeCopyQuad.setFragmentShaderTemplate(volumeCopyFragTemplate);
|
|
78
|
+
|
|
79
|
+
model._copyUBO = vtkWebGPUUniformBuffer.newInstance();
|
|
80
|
+
|
|
81
|
+
model._copyUBO.setName('mapperUBO');
|
|
82
|
+
|
|
83
|
+
model._copyUBO.addEntry('tscale', 'vec2<f32>');
|
|
84
|
+
|
|
85
|
+
model._volumeCopyQuad.setUBO(model._copyUBO);
|
|
86
|
+
|
|
87
|
+
model._volumeCopyQuad.setTextureViews([model._colorTextureView]);
|
|
77
88
|
}
|
|
78
89
|
};
|
|
79
90
|
|
|
@@ -136,13 +147,7 @@ function vtkWebGPUVolumePass(publicAPI, model) {
|
|
|
136
147
|
// if not rendering in chunks then just draw all of them at once
|
|
137
148
|
publicAPI.rayCastPass(viewNode, renNode, model.volumes);
|
|
138
149
|
} // copy back to the original color buffer
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (model.small) {
|
|
142
|
-
model._volumeCopyQuad.setTextureViews([model._smallColorTextureView]);
|
|
143
|
-
} else {
|
|
144
|
-
model._volumeCopyQuad.setTextureViews([model._largeColorTextureView]);
|
|
145
|
-
} // final composite
|
|
150
|
+
// final composite
|
|
146
151
|
|
|
147
152
|
|
|
148
153
|
model._copyEncoder.setColorTextureView(0, model.colorTextureView);
|
|
@@ -157,6 +162,18 @@ function vtkWebGPUVolumePass(publicAPI, model) {
|
|
|
157
162
|
|
|
158
163
|
model._volumeCopyQuad.setWebGPURenderer(renNode);
|
|
159
164
|
|
|
165
|
+
if (model._useSmallViewport) {
|
|
166
|
+
var width = model._colorTextureView.getTexture().getWidth();
|
|
167
|
+
|
|
168
|
+
var height = model._colorTextureView.getTexture().getHeight();
|
|
169
|
+
|
|
170
|
+
model._copyUBO.setArray('tscale', [model._smallViewportWidth / width, model._smallViewportHeight / height]);
|
|
171
|
+
} else {
|
|
172
|
+
model._copyUBO.setArray('tscale', [1.0, 1.0]);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
model._copyUBO.sendIfNeeded(device);
|
|
176
|
+
|
|
160
177
|
model._volumeCopyQuad.render(model._copyEncoder, viewNode.getDevice());
|
|
161
178
|
|
|
162
179
|
model._copyEncoder.end();
|
|
@@ -172,47 +189,38 @@ function vtkWebGPUVolumePass(publicAPI, model) {
|
|
|
172
189
|
}, publicAPI.delete);
|
|
173
190
|
|
|
174
191
|
publicAPI.computeTiming = function (viewNode) {
|
|
175
|
-
model.
|
|
192
|
+
model._useSmallViewport = false;
|
|
176
193
|
var rwi = viewNode.getRenderable().getInteractor();
|
|
177
194
|
|
|
178
195
|
if (rwi.isAnimating() && model._lastScale > 1.5) {
|
|
179
|
-
model.
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
model._activeColorTextureView = model._smallColorTextureView;
|
|
184
|
-
} else {
|
|
185
|
-
model._largeColorTexture.resize(viewNode.getCanvas().width, viewNode.getCanvas().height);
|
|
196
|
+
if (!model._smallViewportHeight) {
|
|
197
|
+
model._smallViewportWidth = Math.ceil(viewNode.getCanvas().width / Math.sqrt(model._lastScale));
|
|
198
|
+
model._smallViewportHeight = Math.ceil(viewNode.getCanvas().height / Math.sqrt(model._lastScale));
|
|
199
|
+
}
|
|
186
200
|
|
|
187
|
-
model.
|
|
201
|
+
model._useSmallViewport = true;
|
|
188
202
|
}
|
|
189
203
|
|
|
204
|
+
model._colorTexture.resize(viewNode.getCanvas().width, viewNode.getCanvas().height);
|
|
205
|
+
|
|
190
206
|
if (!model._animationRateSubscription) {
|
|
191
207
|
// when the animation frame rate changes recompute the scale factor
|
|
192
208
|
model._animationRateSubscription = rwi.onAnimationFrameRateUpdate(function () {
|
|
193
209
|
var frate = rwi.getRecentAnimationFrameRate();
|
|
194
|
-
var targetScale = model._lastScale * rwi.getDesiredUpdateRate() / frate;
|
|
195
|
-
|
|
196
|
-
//
|
|
197
|
-
//
|
|
198
|
-
|
|
199
|
-
if (targetScale > 1.4 * model._lastScale || targetScale < 0.7 * model._lastScale) {
|
|
200
|
-
model._lastScale = targetScale; // clamp scale to some reasonable values.
|
|
201
|
-
// Below 1.5 we will just be using full resolution as that is close enough
|
|
202
|
-
// Above 400 seems like a lot so we limit to that 1/20th per axis
|
|
203
|
-
|
|
204
|
-
if (model._lastScale > 400) {
|
|
205
|
-
model._lastScale = 400;
|
|
206
|
-
}
|
|
210
|
+
var targetScale = model._lastScale * rwi.getDesiredUpdateRate() / frate;
|
|
211
|
+
model._lastScale = targetScale; // clamp scale to some reasonable values.
|
|
212
|
+
// Below 1.5 we will just be using full resolution as that is close enough
|
|
213
|
+
// Above 400 seems like a lot so we limit to that 1/20th per axis
|
|
207
214
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
var targetSmallWidth = 64 * Math.ceil(viewNode.getCanvas().width / (Math.sqrt(model._lastScale) * 64));
|
|
212
|
-
var targetSmallHeight = Math.ceil(targetSmallWidth * viewNode.getCanvas().height / viewNode.getCanvas().width);
|
|
215
|
+
if (model._lastScale > 400) {
|
|
216
|
+
model._lastScale = 400;
|
|
217
|
+
}
|
|
213
218
|
|
|
214
|
-
|
|
215
|
-
|
|
219
|
+
if (model._lastScale < 1.5) {
|
|
220
|
+
model._lastScale = 1.5;
|
|
221
|
+
} else {
|
|
222
|
+
model._smallViewportWidth = Math.ceil(viewNode.getCanvas().width / Math.sqrt(model._lastScale));
|
|
223
|
+
model._smallViewportHeight = Math.ceil(viewNode.getCanvas().height / Math.sqrt(model._lastScale));
|
|
216
224
|
}
|
|
217
225
|
});
|
|
218
226
|
}
|
|
@@ -220,14 +228,18 @@ function vtkWebGPUVolumePass(publicAPI, model) {
|
|
|
220
228
|
|
|
221
229
|
publicAPI.rayCastPass = function (viewNode, renNode, volumes) {
|
|
222
230
|
var encoder = model._firstGroup ? model._clearEncoder : model._mergeEncoder;
|
|
223
|
-
encoder.setColorTextureView(0, model._activeColorTextureView);
|
|
224
231
|
encoder.attachTextureViews();
|
|
225
232
|
renNode.setRenderEncoder(encoder);
|
|
226
233
|
encoder.begin(viewNode.getCommandEncoder());
|
|
227
234
|
|
|
228
|
-
var width = model.
|
|
235
|
+
var width = model._colorTextureView.getTexture().getWidth();
|
|
236
|
+
|
|
237
|
+
var height = model._colorTextureView.getTexture().getHeight();
|
|
229
238
|
|
|
230
|
-
|
|
239
|
+
if (model._useSmallViewport) {
|
|
240
|
+
width = model._smallViewportWidth;
|
|
241
|
+
height = model._smallViewportHeight;
|
|
242
|
+
}
|
|
231
243
|
|
|
232
244
|
encoder.getHandle().setViewport(0, 0, width, height, 0.0, 1.0); // set scissor
|
|
233
245
|
|
|
@@ -453,35 +465,9 @@ function vtkWebGPUVolumePass(publicAPI, model) {
|
|
|
453
465
|
};
|
|
454
466
|
|
|
455
467
|
publicAPI.createClearEncoder = function (viewNode) {
|
|
456
|
-
model.
|
|
457
|
-
// as webgpu textures have to be multiples of 256 bytes wide
|
|
458
|
-
// for data transfers (just in case)
|
|
468
|
+
model._colorTexture = vtkWebGPUTexture.newInstance();
|
|
459
469
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
model._smallColorTexture.create(viewNode.getDevice(), {
|
|
463
|
-
width: targetSmallWidth,
|
|
464
|
-
height: Math.ceil(targetSmallWidth * viewNode.getCanvas().height / viewNode.getCanvas().width),
|
|
465
|
-
format: 'bgra8unorm',
|
|
466
|
-
|
|
467
|
-
/* eslint-disable no-undef */
|
|
468
|
-
|
|
469
|
-
/* eslint-disable no-bitwise */
|
|
470
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC
|
|
471
|
-
});
|
|
472
|
-
|
|
473
|
-
model._smallColorTextureView = model._smallColorTexture.createView();
|
|
474
|
-
|
|
475
|
-
model._smallColorTextureView.setName('volumePassSmallColorTexture');
|
|
476
|
-
|
|
477
|
-
model._smallColorTextureView.addSampler(viewNode.getDevice(), {
|
|
478
|
-
minFilter: 'linear',
|
|
479
|
-
magFilter: 'linear'
|
|
480
|
-
});
|
|
481
|
-
|
|
482
|
-
model._largeColorTexture = vtkWebGPUTexture.newInstance();
|
|
483
|
-
|
|
484
|
-
model._largeColorTexture.create(viewNode.getDevice(), {
|
|
470
|
+
model._colorTexture.create(viewNode.getDevice(), {
|
|
485
471
|
width: viewNode.getCanvas().width,
|
|
486
472
|
height: viewNode.getCanvas().height,
|
|
487
473
|
format: 'bgra8unorm',
|
|
@@ -492,17 +478,19 @@ function vtkWebGPUVolumePass(publicAPI, model) {
|
|
|
492
478
|
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC
|
|
493
479
|
});
|
|
494
480
|
|
|
495
|
-
model.
|
|
481
|
+
model._colorTextureView = model._colorTexture.createView();
|
|
496
482
|
|
|
497
|
-
model.
|
|
483
|
+
model._colorTextureView.setName('volumePassSmallColorTexture');
|
|
498
484
|
|
|
499
|
-
model.
|
|
485
|
+
model._colorTextureView.addSampler(viewNode.getDevice(), {
|
|
500
486
|
minFilter: 'linear',
|
|
501
487
|
magFilter: 'linear'
|
|
502
488
|
});
|
|
503
489
|
|
|
504
490
|
model._clearEncoder = vtkWebGPURenderEncoder.newInstance();
|
|
505
491
|
|
|
492
|
+
model._clearEncoder.setColorTextureView(0, model._colorTextureView);
|
|
493
|
+
|
|
506
494
|
model._clearEncoder.setDescription({
|
|
507
495
|
colorAttachments: [{
|
|
508
496
|
view: null,
|
|
@@ -573,6 +561,8 @@ function vtkWebGPUVolumePass(publicAPI, model) {
|
|
|
573
561
|
publicAPI.createMergeEncoder = function (viewNode) {
|
|
574
562
|
model._mergeEncoder = vtkWebGPURenderEncoder.newInstance();
|
|
575
563
|
|
|
564
|
+
model._mergeEncoder.setColorTextureView(0, model._colorTextureView);
|
|
565
|
+
|
|
576
566
|
model._mergeEncoder.setDescription({
|
|
577
567
|
colorAttachments: [{
|
|
578
568
|
view: null,
|
|
@@ -3,11 +3,11 @@ import vtkBoundingBox, { STATIC } from '../../../Common/DataModel/BoundingBox.js
|
|
|
3
3
|
import vtkCubeSource from '../../../Filters/Sources/CubeSource.js';
|
|
4
4
|
import vtkCutter from '../../../Filters/Core/Cutter.js';
|
|
5
5
|
import vtkPlane from '../../../Common/DataModel/Plane.js';
|
|
6
|
-
import { g as subtract, l as normalize, j as cross, Q as multiplyAccumulate, S as signedAngleBetweenVectors } from '../../../Common/Core/Math/index.js';
|
|
6
|
+
import { g as subtract, l as normalize, j as cross, t as multiplyScalar, Q as multiplyAccumulate, S as signedAngleBetweenVectors } from '../../../Common/Core/Math/index.js';
|
|
7
7
|
import vtkMatrixBuilder from '../../../Common/Core/MatrixBuilder.js';
|
|
8
8
|
import { ViewTypes } from '../../Core/WidgetManager/Constants.js';
|
|
9
9
|
|
|
10
|
-
var EPSILON =
|
|
10
|
+
var EPSILON = 10e-7;
|
|
11
11
|
/**
|
|
12
12
|
* Fit the plane defined by origin, p1, p2 onto the bounds.
|
|
13
13
|
* Plane is untouched if does not intersect bounds.
|
|
@@ -15,6 +15,7 @@ var EPSILON = 0.00001;
|
|
|
15
15
|
* @param {Array} origin
|
|
16
16
|
* @param {Array} p1
|
|
17
17
|
* @param {Array} p2
|
|
18
|
+
* @return {Boolean} false if no bounds have been found, else true
|
|
18
19
|
*/
|
|
19
20
|
|
|
20
21
|
function boundPlane(bounds, origin, p1, p2) {
|
|
@@ -26,19 +27,26 @@ function boundPlane(bounds, origin, p1, p2) {
|
|
|
26
27
|
normalize(v2);
|
|
27
28
|
var n = [0, 0, 1];
|
|
28
29
|
cross(v1, v2, n);
|
|
29
|
-
normalize(n);
|
|
30
|
+
normalize(n); // Inflate bounds in order to avoid precision error when cutting cubesource
|
|
31
|
+
|
|
32
|
+
var inflatedBounds = _toConsumableArray(bounds);
|
|
33
|
+
|
|
34
|
+
var eps = [].concat(n);
|
|
35
|
+
multiplyScalar(eps, EPSILON);
|
|
36
|
+
vtkBoundingBox.addBounds(inflatedBounds, bounds[0] + eps[0], bounds[1] + eps[0], bounds[2] + eps[1], bounds[3] + eps[1], bounds[4] + eps[2], bounds[5] + eps[2]);
|
|
37
|
+
vtkBoundingBox.addBounds(inflatedBounds, bounds[0] - eps[0], bounds[1] - eps[0], bounds[2] - eps[1], bounds[3] - eps[1], bounds[4] - eps[2], bounds[5] - eps[2]);
|
|
30
38
|
var plane = vtkPlane.newInstance();
|
|
31
39
|
plane.setOrigin.apply(plane, _toConsumableArray(origin));
|
|
32
40
|
plane.setNormal.apply(plane, n);
|
|
33
41
|
var cubeSource = vtkCubeSource.newInstance();
|
|
34
|
-
cubeSource.setBounds(
|
|
42
|
+
cubeSource.setBounds(inflatedBounds);
|
|
35
43
|
var cutter = vtkCutter.newInstance();
|
|
36
44
|
cutter.setCutFunction(plane);
|
|
37
45
|
cutter.setInputConnection(cubeSource.getOutputPort());
|
|
38
46
|
var cutBounds = cutter.getOutputData();
|
|
39
47
|
|
|
40
48
|
if (cutBounds.getNumberOfPoints() === 0) {
|
|
41
|
-
return;
|
|
49
|
+
return false;
|
|
42
50
|
}
|
|
43
51
|
|
|
44
52
|
var localBounds = STATIC.computeLocalBounds(cutBounds.getPoints(), v1, v2, n);
|
|
@@ -48,6 +56,8 @@ function boundPlane(bounds, origin, p1, p2) {
|
|
|
48
56
|
p1[i] = localBounds[1] * v1[i] + localBounds[2] * v2[i] + localBounds[4] * n[i];
|
|
49
57
|
p2[i] = localBounds[0] * v1[i] + localBounds[3] * v2[i] + localBounds[4] * n[i];
|
|
50
58
|
}
|
|
59
|
+
|
|
60
|
+
return true;
|
|
51
61
|
} // Project point (inPoint) to the bounds of the image according to a plane
|
|
52
62
|
// defined by two vectors (v1, v2)
|
|
53
63
|
|