@kitware/vtk.js 33.3.2 → 34.0.0-beta.2
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/BREAKING_CHANGES.md +10 -0
- package/IO/Geometry/GLTFImporter/Decoder.js +21 -35
- package/IO/Geometry/GLTFImporter/ORMTexture.worker.js +42 -0
- package/IO/Geometry/GLTFImporter/Parser.js +6 -15
- package/IO/Geometry/GLTFImporter/Reader.js +10 -7
- package/IO/Geometry/GLTFImporter/Utils.js +27 -9
- package/Interaction/Manipulators/KeyboardCameraManipulator.d.ts +113 -0
- package/Rendering/Core/Actor.d.ts +5 -20
- package/Rendering/Core/Actor.js +5 -68
- package/Rendering/Core/ImageCPRMapper.d.ts +1 -20
- package/Rendering/Core/ImageCPRMapper.js +1 -2
- package/Rendering/Core/ImageProperty.d.ts +20 -1
- package/Rendering/Core/ImageProperty.js +7 -5
- package/Rendering/Core/ImageResliceMapper.d.ts +1 -20
- package/Rendering/Core/ImageResliceMapper.js +1 -2
- package/Rendering/Core/ImageSlice.d.ts +7 -23
- package/Rendering/Core/ImageSlice.js +9 -68
- package/Rendering/Core/Prop3D.d.ts +39 -2
- package/Rendering/Core/Prop3D.js +81 -2
- package/Rendering/Core/RenderWindowInteractor.d.ts +6 -0
- package/Rendering/Core/RenderWindowInteractor.js +7 -5
- package/Rendering/Core/Volume.d.ts +5 -20
- package/Rendering/Core/Volume.js +2 -70
- package/Rendering/Core/VolumeMapper/Constants.d.ts +0 -7
- package/Rendering/Core/VolumeMapper/Constants.js +2 -8
- package/Rendering/Core/VolumeMapper.d.ts +16 -173
- package/Rendering/Core/VolumeMapper.js +16 -51
- package/Rendering/Core/VolumeProperty/Constants.d.ts +12 -3
- package/Rendering/Core/VolumeProperty/Constants.js +11 -4
- package/Rendering/Core/VolumeProperty.d.ts +140 -5
- package/Rendering/Core/VolumeProperty.js +54 -7
- package/Rendering/OpenGL/Framebuffer.js +7 -1
- package/Rendering/OpenGL/ImageCPRMapper.js +72 -27
- package/Rendering/OpenGL/ImageMapper.js +71 -33
- package/Rendering/OpenGL/ImageResliceMapper.js +306 -183
- package/Rendering/OpenGL/OrderIndependentTranslucentPass.js +20 -3
- package/Rendering/OpenGL/PolyDataMapper.js +8 -9
- package/Rendering/OpenGL/RenderWindow/resourceSharingHelper.d.ts +3 -3
- package/Rendering/OpenGL/RenderWindow/resourceSharingHelper.js +8 -5
- package/Rendering/OpenGL/SurfaceLIC/LineIntegralConvolution2D/pingpong.js +7 -1
- package/Rendering/OpenGL/SurfaceLIC/SurfaceLICInterface.js +20 -3
- package/Rendering/OpenGL/Texture.d.ts +110 -62
- package/Rendering/OpenGL/Texture.js +145 -37
- package/Rendering/OpenGL/VolumeMapper.js +763 -783
- package/Rendering/OpenGL/glsl/vtkVolumeFS.glsl.js +1 -1
- package/Rendering/WebGPU/CellArrayMapper.js +17 -17
- package/Rendering/WebGPU/PolyDataMapper.js +15 -35
- package/Rendering/WebGPU/Renderer.js +1 -1
- package/Rendering/WebGPU/Texture.js +12 -13
- package/Rendering/WebGPU/TextureManager.js +7 -12
- package/Rendering/WebGPU/VolumePassFSQ.js +2 -2
- package/_virtual/rollup-plugin-worker-loader__module_Sources/IO/Geometry/GLTFImporter/ORMTexture.worker.js +296 -0
- package/index.d.ts +1 -0
- package/macros.js +1 -1
- package/macros2.js +8 -3
- package/package.json +1 -1
package/BREAKING_CHANGES.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## From 33.x to 34
|
|
2
|
+
|
|
3
|
+
- **vtkMapper**: many properties have moved to `vtkVolumeProperty`. The full list of changed methods is: `getAnisotropy`, `getComputeNormalFromOpacity`, `getFilterMode`, `getFilterModeAsString`, `getGlobalIlluminationReach`, `getIpScalarRange`, `getIpScalarRangeByReference`, `getLAOKernelRadius`, `getLAOKernelSize`, `getLocalAmbientOcclusion`, `getPreferSizeOverAccuracy`, `getVolumetricScatteringBlending`, `setAnisotropy`, `setAverageIPScalarRange`, `setComputeNormalFromOpacity`, `setFilterMode`, `setFilterModeToNormalized`, `setFilterModeToOff`, `setFilterModeToRaw`, `setGlobalIlluminationReach`, `setIpScalarRange`, `setIpScalarRangeFrom`, `setLAOKernelRadius`, `setLAOKernelSize`, `setLocalAmbientOcclusion`, `setPreferSizeOverAccuracy`, `setVolumetricScatteringBlending`.
|
|
4
|
+
- **vtkRenderWindowInteractor**: KeyPress, KeyDown and KeyUp events are now observed on the container and no longer on the document. "tabIndex=0" is now automatically added on RWI containers to give focus on your render windows and catch key events. Check the KeyPressEvents example for usage.
|
|
5
|
+
- **vtkOpenGLTexture**: The public `create2D*` and `create3D*` methods used to have positional parameters. These methods now use named parameters via passing in an object record.
|
|
6
|
+
|
|
7
|
+
## From 32.x to 33
|
|
8
|
+
|
|
9
|
+
- **vtkColorTransferFunction**, **vtkMapper**: Previous log scaling was disabled but functionality is now quite different from what it maybe was before it was disabled. ColorTransfer function now maps the model.nodes in logarithmic scales so there's an even spacing between powers of ten.
|
|
10
|
+
|
|
1
11
|
## From 31.x to 32
|
|
2
12
|
|
|
3
13
|
- **vtkMapper**: remove `mapScalarsToTexture` from the public API. The function becomes protected and its API changes. This shouldn't cause any issue in most cases.
|
|
@@ -1,79 +1,65 @@
|
|
|
1
1
|
import BinaryHelper from '../../Core/BinaryHelper.js';
|
|
2
|
-
import {
|
|
2
|
+
import { BINARY_HEADER_MAGIC, BINARY_CHUNK_TYPES, BINARY_CHUNK_HEADER_INTS, BINARY_HEADER_LENGTH, BINARY_HEADER_INTS } from './Constants.js';
|
|
3
3
|
|
|
4
4
|
function getChunkInfo(headerStart, data) {
|
|
5
|
-
// Cache array view
|
|
6
5
|
const header = new Uint32Array(data, headerStart, BINARY_CHUNK_HEADER_INTS);
|
|
7
6
|
const chunkStart = headerStart + BINARY_CHUNK_HEADER_INTS * 4;
|
|
7
|
+
const chunkLength = header[0];
|
|
8
|
+
const chunkType = header[1];
|
|
8
9
|
return {
|
|
9
10
|
start: chunkStart,
|
|
10
|
-
length:
|
|
11
|
-
type:
|
|
11
|
+
length: chunkLength,
|
|
12
|
+
type: chunkType
|
|
12
13
|
};
|
|
13
14
|
}
|
|
14
15
|
function getAllChunkInfos(data) {
|
|
15
|
-
|
|
16
|
-
const maxChunks = Math.floor((data.byteLength - BINARY_HEADER_LENGTH) / 8);
|
|
17
|
-
const infos = new Array(maxChunks);
|
|
16
|
+
const infos = [];
|
|
18
17
|
let chunkStart = BINARY_HEADER_INTS * 4;
|
|
19
|
-
let chunkCount = 0;
|
|
20
18
|
while (chunkStart < data.byteLength) {
|
|
21
19
|
const chunkInfo = getChunkInfo(chunkStart, data);
|
|
22
|
-
infos
|
|
20
|
+
infos.push(chunkInfo);
|
|
23
21
|
chunkStart += chunkInfo.length + BINARY_CHUNK_HEADER_INTS * 4;
|
|
24
22
|
}
|
|
25
|
-
|
|
26
|
-
// Trim array to actual size
|
|
27
|
-
return infos.slice(0, chunkCount);
|
|
23
|
+
return infos;
|
|
28
24
|
}
|
|
29
25
|
function getJsonFromChunk(chunkInfo, data) {
|
|
26
|
+
const chunkLength = chunkInfo.length;
|
|
30
27
|
const jsonStart = (BINARY_HEADER_INTS + BINARY_CHUNK_HEADER_INTS) * 4;
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
return JSON.parse(jsonString);
|
|
28
|
+
const jsonSlice = new Uint8Array(data, jsonStart, chunkLength);
|
|
29
|
+
const stringBuffer = BinaryHelper.arrayBufferToString(jsonSlice);
|
|
30
|
+
return JSON.parse(stringBuffer);
|
|
35
31
|
}
|
|
36
32
|
function getBufferFromChunk(chunkInfo, data) {
|
|
37
33
|
return data.slice(chunkInfo.start, chunkInfo.start + chunkInfo.length);
|
|
38
34
|
}
|
|
39
35
|
function parseGLB(data) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Cache DataView
|
|
36
|
+
let json;
|
|
37
|
+
const buffers = [];
|
|
45
38
|
const headerView = new DataView(data, 0, BINARY_HEADER_LENGTH);
|
|
46
|
-
const magic = new Uint8Array(data, 0, 4);
|
|
47
39
|
const header = {
|
|
48
|
-
magic: BinaryHelper.arrayBufferToString(
|
|
40
|
+
magic: BinaryHelper.arrayBufferToString(new Uint8Array(data, 0, 4)),
|
|
49
41
|
version: headerView.getUint32(4, true),
|
|
50
42
|
length: headerView.getUint32(8, true)
|
|
51
43
|
};
|
|
52
44
|
if (header.magic !== BINARY_HEADER_MAGIC) {
|
|
53
45
|
throw new Error('Unsupported glTF-Binary header.');
|
|
54
|
-
}
|
|
55
|
-
if (header.version < 2.0) {
|
|
46
|
+
} else if (header.version < 2.0) {
|
|
56
47
|
throw new Error('Unsupported legacy binary file detected.');
|
|
57
48
|
}
|
|
58
|
-
if (header.length > data.byteLength) {
|
|
59
|
-
throw new Error('Invalid GLB: Declared length exceeds file size');
|
|
60
|
-
}
|
|
61
49
|
const chunkInfos = getAllChunkInfos(data);
|
|
62
|
-
|
|
63
|
-
const buffers = [];
|
|
64
|
-
|
|
65
|
-
// Process chunks sequentially
|
|
66
|
-
for (let i = 0; i < chunkInfos.length; i++) {
|
|
67
|
-
const chunkInfo = chunkInfos[i];
|
|
50
|
+
chunkInfos.forEach(chunkInfo => {
|
|
68
51
|
if (chunkInfo.type === BINARY_CHUNK_TYPES.JSON && !json) {
|
|
69
52
|
json = getJsonFromChunk(chunkInfo, data);
|
|
70
53
|
} else if (chunkInfo.type === BINARY_CHUNK_TYPES.BIN) {
|
|
71
54
|
buffers.push(getBufferFromChunk(chunkInfo, data));
|
|
72
55
|
}
|
|
73
|
-
}
|
|
56
|
+
});
|
|
74
57
|
if (!json) {
|
|
75
58
|
throw new Error('glTF-Binary: JSON content not found.');
|
|
76
59
|
}
|
|
60
|
+
if (!buffers) {
|
|
61
|
+
throw new Error('glTF-Binary: Binary chunk not found.');
|
|
62
|
+
}
|
|
77
63
|
return {
|
|
78
64
|
json,
|
|
79
65
|
buffers
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import registerWebworker from 'webworker-promise/lib/register';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {ArrayBuffer} imageBuffer
|
|
6
|
+
* @param {string} mimeType
|
|
7
|
+
* @param {string} channel
|
|
8
|
+
* @returns {Promise<ImageData>}
|
|
9
|
+
*/
|
|
10
|
+
registerWebworker(async _ref => {
|
|
11
|
+
let {
|
|
12
|
+
imageBuffer,
|
|
13
|
+
mimeType,
|
|
14
|
+
channel
|
|
15
|
+
} = _ref;
|
|
16
|
+
const channelsMap = {
|
|
17
|
+
r: 0,
|
|
18
|
+
g: 1,
|
|
19
|
+
b: 2
|
|
20
|
+
};
|
|
21
|
+
const blob = new Blob([imageBuffer], {
|
|
22
|
+
type: mimeType
|
|
23
|
+
});
|
|
24
|
+
const img = await createImageBitmap(blob);
|
|
25
|
+
const canvas = new OffscreenCanvas(img.width, img.height);
|
|
26
|
+
const ctx = canvas.getContext('2d');
|
|
27
|
+
ctx.drawImage(img, 0, 0, img.width, img.height);
|
|
28
|
+
const bitmap = ctx.getImageData(0, 0, img.width, img.height);
|
|
29
|
+
if (channel) {
|
|
30
|
+
const idx = channelsMap[channel];
|
|
31
|
+
for (let i = 0; i < bitmap.data.length; i += 4) {
|
|
32
|
+
const channelValue = bitmap.data[i + idx];
|
|
33
|
+
bitmap.data[i] = channelValue; // red channel
|
|
34
|
+
bitmap.data[i + 1] = channelValue; // green channel
|
|
35
|
+
bitmap.data[i + 2] = channelValue; // blue channel
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
bitmap
|
|
41
|
+
};
|
|
42
|
+
});
|
|
@@ -210,24 +210,15 @@ class GLTFParser {
|
|
|
210
210
|
if (accessor.bufferView) {
|
|
211
211
|
const buffer = accessor.bufferView.buffer;
|
|
212
212
|
const {
|
|
213
|
-
ArrayType
|
|
213
|
+
ArrayType,
|
|
214
|
+
byteLength
|
|
214
215
|
} = getAccessorArrayTypeAndLength(accessor, accessor.bufferView);
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
let arrayBufferView;
|
|
216
|
+
const byteOffset = (accessor.bufferView.byteOffset || 0) + (accessor.byteOffset || 0) + buffer.byteOffset;
|
|
217
|
+
let slicedBufffer = buffer.arrayBuffer.slice(byteOffset, byteOffset + byteLength);
|
|
218
218
|
if (accessor.bufferView.byteStride) {
|
|
219
|
-
|
|
220
|
-
if (accessor.bufferView.byteStride === accessor.bytesPerElement) {
|
|
221
|
-
arrayBufferView = new ArrayType(buffer.arrayBuffer, byteOffset, accessor.count * accessor.components);
|
|
222
|
-
} else {
|
|
223
|
-
// Interleaved buffer, extract only needed bytes
|
|
224
|
-
const interleavedBuffer = this.getValueFromInterleavedBuffer(buffer, byteOffset, accessor.bufferView.byteStride, accessor.bytesPerElement, accessor.count);
|
|
225
|
-
arrayBufferView = new ArrayType(interleavedBuffer);
|
|
226
|
-
}
|
|
227
|
-
} else {
|
|
228
|
-
arrayBufferView = new ArrayType(buffer.arrayBuffer, byteOffset, accessor.count * accessor.components);
|
|
219
|
+
slicedBufffer = this.getValueFromInterleavedBuffer(buffer, byteOffset, accessor.bufferView.byteStride, accessor.bytesPerElement, accessor.count);
|
|
229
220
|
}
|
|
230
|
-
accessor.value =
|
|
221
|
+
accessor.value = new ArrayType(slicedBufffer);
|
|
231
222
|
}
|
|
232
223
|
return accessor;
|
|
233
224
|
}
|
|
@@ -149,7 +149,6 @@ async function createPolyDataFromGLTFMesh(primitive) {
|
|
|
149
149
|
polyData.setStrips(cells);
|
|
150
150
|
break;
|
|
151
151
|
default:
|
|
152
|
-
cells.delete();
|
|
153
152
|
vtkWarningMacro('Invalid primitive draw mode. Ignoring connectivity.');
|
|
154
153
|
}
|
|
155
154
|
return polyData;
|
|
@@ -199,7 +198,15 @@ async function createPropertyFromGLTFMaterial(model, material, actor) {
|
|
|
199
198
|
const sampler = tex.sampler;
|
|
200
199
|
const image = await loadImage(tex.source);
|
|
201
200
|
const diffuseTex = createVTKTextureFromGLTFTexture(image, sampler);
|
|
202
|
-
|
|
201
|
+
|
|
202
|
+
// FIXME: Workaround for textures not showing up in WebGL
|
|
203
|
+
const viewAPI = model.renderer.getRenderWindow();
|
|
204
|
+
const isWebGL = viewAPI.getViews()[0].isA('vtkOpenGLRenderWindow');
|
|
205
|
+
if (isWebGL) {
|
|
206
|
+
actor.addTexture(diffuseTex);
|
|
207
|
+
} else {
|
|
208
|
+
property.setDiffuseTexture(diffuseTex);
|
|
209
|
+
}
|
|
203
210
|
}
|
|
204
211
|
|
|
205
212
|
// Handle metallic-roughness texture (metallicRoughnessTexture)
|
|
@@ -217,7 +224,7 @@ async function createPropertyFromGLTFMaterial(model, material, actor) {
|
|
|
217
224
|
material.occlusionTexture.extensions;
|
|
218
225
|
const tex = material.occlusionTexture.texture;
|
|
219
226
|
const sampler = tex.sampler;
|
|
220
|
-
const aoImage = await loadImage(tex.source);
|
|
227
|
+
const aoImage = await loadImage(tex.source, 'r');
|
|
221
228
|
const aoTex = createVTKTextureFromGLTFTexture(aoImage, sampler);
|
|
222
229
|
property.setAmbientOcclusionTexture(aoTex);
|
|
223
230
|
}
|
|
@@ -292,8 +299,6 @@ function handlePrimitiveExtensions(nodeId, extensions, model) {
|
|
|
292
299
|
case 'KHR_materials_variants':
|
|
293
300
|
model.variantMappings.set(nodeId, extension.mappings);
|
|
294
301
|
break;
|
|
295
|
-
case 'KHR_draco_mesh_compression':
|
|
296
|
-
break;
|
|
297
302
|
default:
|
|
298
303
|
vtkWarningMacro(`Unhandled extension: ${extensionName}`);
|
|
299
304
|
}
|
|
@@ -309,7 +314,6 @@ async function createActorFromGTLFNode(worldMatrix) {
|
|
|
309
314
|
const actor = vtkActor.newInstance();
|
|
310
315
|
const mapper = vtkMapper.newInstance();
|
|
311
316
|
mapper.setColorModeToDirectScalars();
|
|
312
|
-
mapper.setInterpolateScalarsBeforeMapping(true);
|
|
313
317
|
actor.setMapper(mapper);
|
|
314
318
|
actor.setUserMatrix(worldMatrix);
|
|
315
319
|
const polydata = vtkPolyData.newInstance();
|
|
@@ -326,7 +330,6 @@ async function createActorFromGTLFPrimitive(model, primitive, worldMatrix) {
|
|
|
326
330
|
const actor = vtkActor.newInstance();
|
|
327
331
|
const mapper = vtkMapper.newInstance();
|
|
328
332
|
mapper.setColorModeToDirectScalars();
|
|
329
|
-
mapper.setInterpolateScalarsBeforeMapping(true);
|
|
330
333
|
actor.setMapper(mapper);
|
|
331
334
|
actor.setUserMatrix(worldMatrix);
|
|
332
335
|
const polydata = await createPolyDataFromGLTFMesh(primitive);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import WebworkerPromise from 'webworker-promise';
|
|
1
2
|
import { m as macro } from '../../../macros2.js';
|
|
2
3
|
import vtkTexture from '../../../Rendering/Core/Texture.js';
|
|
4
|
+
import { W as WorkerFactory } from '../../../_virtual/rollup-plugin-worker-loader__module_Sources/IO/Geometry/GLTFImporter/ORMTexture.worker.js';
|
|
3
5
|
import { ARRAY_TYPES, COMPONENTS, BYTES, GL_SAMPLER } from './Constants.js';
|
|
4
6
|
|
|
5
7
|
const {
|
|
@@ -81,18 +83,33 @@ function resolveUrl(url, originalPath) {
|
|
|
81
83
|
/**
|
|
82
84
|
* Loads image from buffer or URI
|
|
83
85
|
* @param {*} image
|
|
86
|
+
* @param {*} channel
|
|
84
87
|
* @returns
|
|
85
88
|
*/
|
|
86
|
-
async function loadImage(image) {
|
|
89
|
+
async function loadImage(image, channel) {
|
|
90
|
+
let forceReLoad = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
91
|
+
// Initialize cache if it doesn't exist
|
|
92
|
+
if (!image.cache) {
|
|
93
|
+
image.cache = {};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Return cached result for the channel if available and not forced to reload
|
|
97
|
+
if (!forceReLoad && image.cache[channel]) {
|
|
98
|
+
return image.cache[channel];
|
|
99
|
+
}
|
|
100
|
+
const worker = new WebworkerPromise(new WorkerFactory());
|
|
87
101
|
if (image.bufferView) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
102
|
+
return worker.postMessage({
|
|
103
|
+
imageBuffer: image.bufferView.data,
|
|
104
|
+
mimeType: image.mimeType,
|
|
105
|
+
channel
|
|
106
|
+
}).then(result => {
|
|
107
|
+
// Cache the bitmap based on the channel
|
|
108
|
+
image.cache[channel] = result.bitmap;
|
|
109
|
+
return result.bitmap;
|
|
110
|
+
}).finally(() => {
|
|
111
|
+
worker.terminate();
|
|
94
112
|
});
|
|
95
|
-
return bitmap;
|
|
96
113
|
}
|
|
97
114
|
if (image.uri) {
|
|
98
115
|
vtkWarningMacro('Falling back to image uri', image.uri);
|
|
@@ -100,6 +117,7 @@ async function loadImage(image) {
|
|
|
100
117
|
const img = new Image();
|
|
101
118
|
img.crossOrigin = 'Anonymous';
|
|
102
119
|
img.onload = () => {
|
|
120
|
+
image.cache[channel] = img; // Cache the loaded image based on the channel
|
|
103
121
|
resolve(img);
|
|
104
122
|
};
|
|
105
123
|
img.onerror = reject;
|
|
@@ -140,7 +158,7 @@ function createVTKTextureFromGLTFTexture(image, sampler, extensions) {
|
|
|
140
158
|
texture.setEdgeClamp(true);
|
|
141
159
|
}
|
|
142
160
|
}
|
|
143
|
-
texture.
|
|
161
|
+
texture.setJsImageData(image);
|
|
144
162
|
return texture;
|
|
145
163
|
}
|
|
146
164
|
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Vector3 } from './../../types';
|
|
2
|
+
import { vtkObject } from './../../interfaces';
|
|
3
|
+
import vtkCompositeKeyboardManipulator from './CompositeKeyboardManipulator';
|
|
4
|
+
import vtkRenderWindowInteractor from './../../Rendering/Core/RenderWindowInteractor';
|
|
5
|
+
import vtkCamera from './../../Rendering/Core/Camera';
|
|
6
|
+
import vtkRenderer from './../../Rendering/Core/Renderer';
|
|
7
|
+
|
|
8
|
+
export interface vtkKeyboardCameraManipulator
|
|
9
|
+
extends vtkObject,
|
|
10
|
+
vtkCompositeKeyboardManipulator {
|
|
11
|
+
/**
|
|
12
|
+
* Returns whether a movement is ongoing.
|
|
13
|
+
*/
|
|
14
|
+
inMotion(): boolean;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Reset the movement speed to be proportional to the longest length of the renderer's bounds.
|
|
18
|
+
*/
|
|
19
|
+
resetMovementSpeed(): void;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Initialize a movement of the current camera.
|
|
23
|
+
*/
|
|
24
|
+
startMovement(): void;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Cancel any ongoing camera movement.
|
|
28
|
+
*/
|
|
29
|
+
endMovement(): void;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Update active camera direction, depending on currently pressed keys.
|
|
33
|
+
*/
|
|
34
|
+
calculateCurrentDirection(): void;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Returns the direction vector of the given camera for the given key.
|
|
38
|
+
* @param key the movedkey
|
|
39
|
+
* @param camera the camera
|
|
40
|
+
*/
|
|
41
|
+
getDirectionFromKey(key: KeyboardEvent['key'], camera: vtkCamera): Vector3;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Moves the given camera, in the given direction, at the given speed.
|
|
45
|
+
* @param camera the moved camera
|
|
46
|
+
* @param direction the direction of the movemnt
|
|
47
|
+
* @param speed the speed
|
|
48
|
+
*/
|
|
49
|
+
moveCamera(camera: vtkCamera, direction: Vector3, speed: number): void;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Handles a keypress event.
|
|
53
|
+
* @param interactor the interactor
|
|
54
|
+
* @param renderer the renderer
|
|
55
|
+
* @param key the key
|
|
56
|
+
*/
|
|
57
|
+
onKeyPress(
|
|
58
|
+
interactor: vtkRenderWindowInteractor,
|
|
59
|
+
renderer: vtkRenderer,
|
|
60
|
+
key: KeyboardEvent['key']
|
|
61
|
+
): void;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Handles a keydown event.
|
|
65
|
+
* @param interactor the interactor
|
|
66
|
+
* @param renderer the renderer
|
|
67
|
+
* @param key the key
|
|
68
|
+
*/
|
|
69
|
+
onKeyDown(
|
|
70
|
+
interactor: vtkRenderWindowInteractor,
|
|
71
|
+
renderer: vtkRenderer,
|
|
72
|
+
key: KeyboardEvent['key']
|
|
73
|
+
): void;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Handles a keyup event.
|
|
77
|
+
* @param interactor the interactor
|
|
78
|
+
* @param renderer the renderer
|
|
79
|
+
* @param key the key
|
|
80
|
+
*/
|
|
81
|
+
onKeyUp(
|
|
82
|
+
interactor: vtkRenderWindowInteractor,
|
|
83
|
+
renderer: vtkRenderer,
|
|
84
|
+
key: KeyboardEvent['key']
|
|
85
|
+
): void;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface IKeyboardCameraManipulatorInitialValues {
|
|
89
|
+
movementSpeed?: number;
|
|
90
|
+
moveForwardKeys?: KeyboardEvent['key'][];
|
|
91
|
+
moveLeftKeys?: KeyboardEvent['key'][];
|
|
92
|
+
moveBackwardKeys?: KeyboardEvent['key'][];
|
|
93
|
+
moveRightKeys?: KeyboardEvent['key'][];
|
|
94
|
+
moveUpKeys?: KeyboardEvent['key'][];
|
|
95
|
+
moveDownKeys?: KeyboardEvent['key'][];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function newInstance(
|
|
99
|
+
initialValues?: IKeyboardCameraManipulatorInitialValues
|
|
100
|
+
): vtkKeyboardCameraManipulator;
|
|
101
|
+
|
|
102
|
+
export function extend(
|
|
103
|
+
publicAPI: object,
|
|
104
|
+
model: object,
|
|
105
|
+
initialValues?: IKeyboardCameraManipulatorInitialValues
|
|
106
|
+
): void;
|
|
107
|
+
|
|
108
|
+
export const vtkKeyboardCameraManipulator: {
|
|
109
|
+
newInstance: typeof newInstance;
|
|
110
|
+
extend: typeof extend;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export default vtkKeyboardCameraManipulator;
|
|
@@ -36,12 +36,6 @@ export interface vtkActor extends vtkProp3D {
|
|
|
36
36
|
*/
|
|
37
37
|
getBackfaceProperty(): vtkProperty;
|
|
38
38
|
|
|
39
|
-
/**
|
|
40
|
-
* Get the bounds for this mapper as [xmin, xmax, ymin, ymax,zmin, zmax].
|
|
41
|
-
* @return {Bounds} The bounds for the mapper.
|
|
42
|
-
*/
|
|
43
|
-
getBounds(): Bounds;
|
|
44
|
-
|
|
45
39
|
/**
|
|
46
40
|
* Check whether the opaque is forced or not.
|
|
47
41
|
*/
|
|
@@ -63,16 +57,6 @@ export interface vtkActor extends vtkProp3D {
|
|
|
63
57
|
*/
|
|
64
58
|
getMapper(): Nullable<vtkMapper>;
|
|
65
59
|
|
|
66
|
-
/**
|
|
67
|
-
* Get the property object that controls this actors surface
|
|
68
|
-
* properties. This should be an instance of a vtkProperty object. Every
|
|
69
|
-
* actor must have a property associated with it. If one isn’t specified,
|
|
70
|
-
* then one will be generated automatically. Multiple actors can share one
|
|
71
|
-
* property object.
|
|
72
|
-
* @return {vtkProperty} The property object
|
|
73
|
-
*/
|
|
74
|
-
getProperty(): vtkProperty;
|
|
75
|
-
|
|
76
60
|
/**
|
|
77
61
|
* Check whether if the actor supports selection
|
|
78
62
|
* @return {Boolean} true if the actor support selection.
|
|
@@ -111,11 +95,12 @@ export interface vtkActor extends vtkProp3D {
|
|
|
111
95
|
*/
|
|
112
96
|
setMapper(mapper: vtkMapper): boolean;
|
|
113
97
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
98
|
+
// Inherited from vtkProp3D, but takes a vtkProperty instead of a generic vtkObject
|
|
99
|
+
getProperty(mapperInputPort?: number): vtkProperty;
|
|
100
|
+
getProperties(): vtkProperty[];
|
|
101
|
+
setProperty(mapperInputPort: number, property: vtkProperty): boolean;
|
|
118
102
|
setProperty(property: vtkProperty): boolean;
|
|
103
|
+
setProperties(properties: vtkProperty[]): boolean;
|
|
119
104
|
}
|
|
120
105
|
|
|
121
106
|
/**
|
package/Rendering/Core/Actor.js
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import { mat4, vec3 } from 'gl-matrix';
|
|
2
1
|
import { m as macro } from '../../macros2.js';
|
|
3
|
-
import vtkBoundingBox from '../../Common/DataModel/BoundingBox.js';
|
|
4
2
|
import vtkProp3D from './Prop3D.js';
|
|
5
3
|
import vtkProperty from './Property.js';
|
|
6
4
|
|
|
7
|
-
const {
|
|
8
|
-
vtkDebugMacro
|
|
9
|
-
} = macro;
|
|
10
|
-
|
|
11
5
|
// ----------------------------------------------------------------------------
|
|
12
6
|
// vtkActor methods
|
|
13
7
|
// ----------------------------------------------------------------------------
|
|
@@ -29,11 +23,11 @@ function vtkActor(publicAPI, model) {
|
|
|
29
23
|
return false;
|
|
30
24
|
}
|
|
31
25
|
// make sure we have a property
|
|
32
|
-
if (!model.
|
|
26
|
+
if (!model.properties[0]) {
|
|
33
27
|
// force creation of a property
|
|
34
28
|
publicAPI.getProperty();
|
|
35
29
|
}
|
|
36
|
-
let isOpaque = model.
|
|
30
|
+
let isOpaque = model.properties[0].getOpacity() >= 1.0;
|
|
37
31
|
|
|
38
32
|
// are we using an opaque texture, if any?
|
|
39
33
|
isOpaque = isOpaque && (!model.texture || !model.texture.isTranslucent());
|
|
@@ -47,71 +41,17 @@ function vtkActor(publicAPI, model) {
|
|
|
47
41
|
return false;
|
|
48
42
|
}
|
|
49
43
|
// make sure we have a property
|
|
50
|
-
if (model.
|
|
44
|
+
if (!model.properties[0]) {
|
|
51
45
|
// force creation of a property
|
|
52
|
-
publicAPI.
|
|
46
|
+
publicAPI.getProperty();
|
|
53
47
|
}
|
|
54
48
|
|
|
55
49
|
// is this actor opaque ?
|
|
56
50
|
return !publicAPI.getIsOpaque();
|
|
57
51
|
};
|
|
58
52
|
publicAPI.makeProperty = vtkProperty.newInstance;
|
|
59
|
-
publicAPI.getProperty = () => {
|
|
60
|
-
if (model.property === null) {
|
|
61
|
-
model.property = publicAPI.makeProperty();
|
|
62
|
-
}
|
|
63
|
-
return model.property;
|
|
64
|
-
};
|
|
65
|
-
publicAPI.getBounds = () => {
|
|
66
|
-
if (model.mapper === null) {
|
|
67
|
-
return model.bounds;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Check for the special case when the mapper's bounds are unknown
|
|
71
|
-
const bds = model.mapper.getBounds();
|
|
72
|
-
if (!bds || bds.length !== 6) {
|
|
73
|
-
return bds;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Check for the special case when the actor is empty.
|
|
77
|
-
if (bds[0] > bds[1]) {
|
|
78
|
-
model.mapperBounds = bds.concat(); // copy the mapper's bounds
|
|
79
|
-
model.bounds = [1, -1, 1, -1, 1, -1];
|
|
80
|
-
model.boundsMTime.modified();
|
|
81
|
-
return bds;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Check if we have cached values for these bounds - we cache the
|
|
85
|
-
// values returned by model.mapper.getBounds() and we store the time
|
|
86
|
-
// of caching. If the values returned this time are different, or
|
|
87
|
-
// the modified time of this class is newer than the cached time,
|
|
88
|
-
// then we need to rebuild.
|
|
89
|
-
if (!model.mapperBounds || bds[0] !== model.mapperBounds[0] || bds[1] !== model.mapperBounds[1] || bds[2] !== model.mapperBounds[2] || bds[3] !== model.mapperBounds[3] || bds[4] !== model.mapperBounds[4] || bds[5] !== model.mapperBounds[5] || publicAPI.getMTime() > model.boundsMTime.getMTime()) {
|
|
90
|
-
vtkDebugMacro('Recomputing bounds...');
|
|
91
|
-
model.mapperBounds = bds.concat(); // copy the mapper's bounds
|
|
92
|
-
const bbox = [];
|
|
93
|
-
vtkBoundingBox.getCorners(bds, bbox);
|
|
94
|
-
publicAPI.computeMatrix();
|
|
95
|
-
const tmp4 = new Float64Array(16);
|
|
96
|
-
mat4.transpose(tmp4, model.matrix);
|
|
97
|
-
bbox.forEach(pt => vec3.transformMat4(pt, pt, tmp4));
|
|
98
|
-
|
|
99
|
-
/* eslint-disable no-multi-assign */
|
|
100
|
-
model.bounds[0] = model.bounds[2] = model.bounds[4] = Number.MAX_VALUE;
|
|
101
|
-
model.bounds[1] = model.bounds[3] = model.bounds[5] = -Number.MAX_VALUE;
|
|
102
|
-
/* eslint-enable no-multi-assign */
|
|
103
|
-
|
|
104
|
-
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));
|
|
105
|
-
model.boundsMTime.modified();
|
|
106
|
-
}
|
|
107
|
-
return model.bounds;
|
|
108
|
-
};
|
|
109
53
|
publicAPI.getMTime = () => {
|
|
110
54
|
let mt = superClass.getMTime();
|
|
111
|
-
if (model.property !== null) {
|
|
112
|
-
const time = model.property.getMTime();
|
|
113
|
-
mt = time > mt ? time : mt;
|
|
114
|
-
}
|
|
115
55
|
if (model.backfaceProperty !== null) {
|
|
116
56
|
const time = model.backfaceProperty.getMTime();
|
|
117
57
|
mt = time > mt ? time : mt;
|
|
@@ -146,11 +86,9 @@ function vtkActor(publicAPI, model) {
|
|
|
146
86
|
|
|
147
87
|
const DEFAULT_VALUES = {
|
|
148
88
|
mapper: null,
|
|
149
|
-
property: null,
|
|
150
89
|
backfaceProperty: null,
|
|
151
90
|
forceOpaque: false,
|
|
152
|
-
forceTranslucent: false
|
|
153
|
-
bounds: [1, -1, 1, -1, 1, -1]
|
|
91
|
+
forceTranslucent: false
|
|
154
92
|
};
|
|
155
93
|
|
|
156
94
|
// ----------------------------------------------------------------------------
|
|
@@ -167,7 +105,6 @@ function extend(publicAPI, model) {
|
|
|
167
105
|
macro.obj(model.boundsMTime);
|
|
168
106
|
|
|
169
107
|
// Build VTK API
|
|
170
|
-
macro.set(publicAPI, model, ['property']);
|
|
171
108
|
macro.setGet(publicAPI, model, ['backfaceProperty', 'forceOpaque', 'forceTranslucent', 'mapper']);
|
|
172
109
|
|
|
173
110
|
// Object methods
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { mat3, mat4, quat, vec3 } from 'gl-matrix';
|
|
2
|
-
import {
|
|
2
|
+
import { Nullable } from './../../types';
|
|
3
3
|
import { vtkOutputPort } from './../../interfaces';
|
|
4
4
|
import {
|
|
5
5
|
vtkAbstractMapper3D,
|
|
@@ -309,25 +309,6 @@ export interface vtkImageCPRMapper
|
|
|
309
309
|
* @param imageData
|
|
310
310
|
*/
|
|
311
311
|
setImageConnection(imageData: vtkOutputPort): void;
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Tells the mapper to only update the specified extents.
|
|
315
|
-
*
|
|
316
|
-
* If there are zero extents, the mapper updates the entire volume texture.
|
|
317
|
-
* Otherwise, the mapper will only update the texture by the specified extents
|
|
318
|
-
* during the next render call.
|
|
319
|
-
*
|
|
320
|
-
* This array is cleared after a successful render.
|
|
321
|
-
* @param extents
|
|
322
|
-
*/
|
|
323
|
-
setUpdatedExtents(extents: Extent[]): boolean;
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Retrieves the updated extents.
|
|
327
|
-
*
|
|
328
|
-
* This array is cleared after every successful render.
|
|
329
|
-
*/
|
|
330
|
-
getUpdatedExtents(): Extent[];
|
|
331
312
|
}
|
|
332
313
|
|
|
333
314
|
/**
|
|
@@ -283,7 +283,6 @@ const defaultValues = initialValues => ({
|
|
|
283
283
|
projectionSlabThickness: 1,
|
|
284
284
|
projectionSlabNumberOfSamples: 1,
|
|
285
285
|
projectionMode: ProjectionMode.MAX,
|
|
286
|
-
updatedExtents: [],
|
|
287
286
|
...initialValues
|
|
288
287
|
});
|
|
289
288
|
|
|
@@ -304,7 +303,7 @@ function extend(publicAPI, model) {
|
|
|
304
303
|
});
|
|
305
304
|
|
|
306
305
|
// Setters and getters
|
|
307
|
-
macro.setGet(publicAPI, model, ['width', 'uniformOrientation', 'useUniformOrientation', 'centerPoint', 'preferSizeOverAccuracy', 'orientationArrayName', 'tangentDirection', 'bitangentDirection', 'normalDirection', 'projectionSlabThickness', 'projectionSlabNumberOfSamples', 'projectionMode'
|
|
306
|
+
macro.setGet(publicAPI, model, ['width', 'uniformOrientation', 'useUniformOrientation', 'centerPoint', 'preferSizeOverAccuracy', 'orientationArrayName', 'tangentDirection', 'bitangentDirection', 'normalDirection', 'projectionSlabThickness', 'projectionSlabNumberOfSamples', 'projectionMode']);
|
|
308
307
|
CoincidentTopologyHelper.implementCoincidentTopologyMethods(publicAPI, model);
|
|
309
308
|
|
|
310
309
|
// Object methods
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { vtkObject } from './../../interfaces';
|
|
2
|
-
import { Nullable } from './../../types';
|
|
2
|
+
import { Extent, Nullable } from './../../types';
|
|
3
3
|
import vtkColorTransferFunction from './ColorTransferFunction';
|
|
4
4
|
import vtkPiecewiseFunction from './../../Common/DataModel/PiecewiseFunction';
|
|
5
5
|
import { InterpolationType } from './ImageProperty/Constants';
|
|
@@ -231,6 +231,25 @@ export interface vtkImageProperty extends vtkObject {
|
|
|
231
231
|
* @param {Boolean} useLookupTableScalarRange
|
|
232
232
|
*/
|
|
233
233
|
setUseLookupTableScalarRange(useLookupTableScalarRange: boolean): boolean;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Informs the mapper to only update the specified extents at the next render.
|
|
237
|
+
*
|
|
238
|
+
* If there are zero extents, the mapper updates the entire volume texture.
|
|
239
|
+
* Otherwise, the mapper will only update the texture by the specified extents
|
|
240
|
+
* during the next render call.
|
|
241
|
+
*
|
|
242
|
+
* This array is cleared after a successful render.
|
|
243
|
+
* @param extents
|
|
244
|
+
*/
|
|
245
|
+
setUpdatedExtents(extents: Extent[]): boolean;
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Retrieves the updated extents.
|
|
249
|
+
*
|
|
250
|
+
* This array is cleared after every successful render.
|
|
251
|
+
*/
|
|
252
|
+
getUpdatedExtents(): Extent[];
|
|
234
253
|
}
|
|
235
254
|
|
|
236
255
|
/**
|