@kitware/vtk.js 33.0.1 → 33.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/IO/Geometry/PLYReader.d.ts +23 -1
- package/IO/Geometry/PLYReader.js +162 -25
- package/Interaction/Manipulators/MouseCameraTrackballFirstPersonManipulator.js +3 -45
- package/Interaction/Style/InteractorStyleManipulator.d.ts +4 -3
- package/Interaction/Style/InteractorStyleManipulator.js +15 -8
- package/Rendering/Core/ColorTransferFunction.d.ts +24 -0
- package/Rendering/Core/Mapper.js +7 -3
- package/Rendering/Core/RenderWindowInteractor/Constants.d.ts +7 -0
- package/Rendering/Core/RenderWindowInteractor/Constants.js +8 -2
- package/Rendering/Core/RenderWindowInteractor.d.ts +2 -1
- package/Rendering/Core/RenderWindowInteractor.js +3 -1
- package/package.json +1 -1
|
@@ -13,7 +13,19 @@ interface IPLYReaderOptions {
|
|
|
13
13
|
/**
|
|
14
14
|
*
|
|
15
15
|
*/
|
|
16
|
-
export interface IPLYReaderInitialValues {
|
|
16
|
+
export interface IPLYReaderInitialValues {
|
|
17
|
+
/**
|
|
18
|
+
* Controls whether points are duplicated for face-texture mapping.
|
|
19
|
+
* Default is true.
|
|
20
|
+
*/
|
|
21
|
+
duplicatePointsForFaceTexture?: boolean;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The tolerance used to determine if two points are the same.
|
|
25
|
+
* Default is 0.000001.
|
|
26
|
+
*/
|
|
27
|
+
faceTextureTolerance?: number;
|
|
28
|
+
}
|
|
17
29
|
|
|
18
30
|
type vtkPLYReaderBase = vtkObject &
|
|
19
31
|
Omit<
|
|
@@ -41,6 +53,16 @@ export interface vtkPLYReader extends vtkPLYReaderBase {
|
|
|
41
53
|
| JSZipDataAccessHelper
|
|
42
54
|
| LiteHttpDataAccessHelper;
|
|
43
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Controls whether points are duplicated for face-texture mapping.
|
|
58
|
+
*/
|
|
59
|
+
getDuplicatePointsForFaceTexture(): boolean;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Get the tolerance used to determine if two points are the same.
|
|
63
|
+
*/
|
|
64
|
+
getFaceTextureTolerance(): number;
|
|
65
|
+
|
|
44
66
|
/**
|
|
45
67
|
* Get the url of the object to load.
|
|
46
68
|
*/
|
package/IO/Geometry/PLYReader.js
CHANGED
|
@@ -95,7 +95,7 @@ function parseHeader(data) {
|
|
|
95
95
|
}
|
|
96
96
|
return header;
|
|
97
97
|
}
|
|
98
|
-
function postProcess(buffer, elements) {
|
|
98
|
+
function postProcess(buffer, elements, faceTextureTolerance, duplicatePointsForFaceTexture) {
|
|
99
99
|
const vertElement = elements.find(element => element.name === 'vertex');
|
|
100
100
|
const faceElement = elements.find(element => element.name === 'face');
|
|
101
101
|
let nbVerts = 0;
|
|
@@ -106,14 +106,20 @@ function postProcess(buffer, elements) {
|
|
|
106
106
|
if (faceElement) {
|
|
107
107
|
nbFaces = faceElement.count;
|
|
108
108
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
let pointValues = new Float32Array(nbVerts * 3);
|
|
110
|
+
let colorArray = new Uint8Array(nbVerts * 3);
|
|
111
|
+
let tcoordsArray = new Float32Array(nbVerts * 2);
|
|
112
|
+
let normalsArray = new Float32Array(nbVerts * 3);
|
|
113
113
|
const hasColor = buffer.colors.length > 0;
|
|
114
114
|
const hasVertTCoords = buffer.uvs.length > 0;
|
|
115
115
|
const hasNorms = buffer.normals.length > 0;
|
|
116
116
|
const hasFaceTCoords = buffer.faceVertexUvs.length > 0;
|
|
117
|
+
|
|
118
|
+
// For duplicate point handling
|
|
119
|
+
const pointIds = new Map(); // Maps texture coords to arrays of point IDs
|
|
120
|
+
let nextPointId = nbVerts;
|
|
121
|
+
|
|
122
|
+
// Initialize base points
|
|
117
123
|
for (let vertIdx = 0; vertIdx < nbVerts; vertIdx++) {
|
|
118
124
|
let a = vertIdx * 3 + 0;
|
|
119
125
|
let b = vertIdx * 3 + 1;
|
|
@@ -131,6 +137,10 @@ function postProcess(buffer, elements) {
|
|
|
131
137
|
b = vertIdx * 2 + 1;
|
|
132
138
|
tcoordsArray[a] = buffer.uvs[a];
|
|
133
139
|
tcoordsArray[b] = buffer.uvs[b];
|
|
140
|
+
} else {
|
|
141
|
+
// Initialize with sentinel value
|
|
142
|
+
tcoordsArray[vertIdx * 2] = -1;
|
|
143
|
+
tcoordsArray[vertIdx * 2 + 1] = -1;
|
|
134
144
|
}
|
|
135
145
|
if (hasNorms) {
|
|
136
146
|
normalsArray[a] = buffer.normals[a];
|
|
@@ -138,33 +148,153 @@ function postProcess(buffer, elements) {
|
|
|
138
148
|
normalsArray[c] = buffer.normals[c];
|
|
139
149
|
}
|
|
140
150
|
}
|
|
141
|
-
|
|
151
|
+
|
|
152
|
+
// Process face texture coordinates
|
|
153
|
+
if (hasFaceTCoords && !hasVertTCoords && nbFaces > 0) {
|
|
142
154
|
// don't use array.shift, because buffer.indices will be used later
|
|
143
155
|
let idxVerts = 0;
|
|
144
156
|
let idxCoord = 0;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
157
|
+
if (duplicatePointsForFaceTexture) {
|
|
158
|
+
// Arrays to store duplicated point data
|
|
159
|
+
const extraPoints = [];
|
|
160
|
+
const extraColors = [];
|
|
161
|
+
const extraNormals = [];
|
|
162
|
+
const extraTCoords = [];
|
|
163
|
+
for (let faceIdx = 0; faceIdx < nbFaces; ++faceIdx) {
|
|
164
|
+
const nbFaceVerts = buffer.indices[idxVerts++];
|
|
165
|
+
const texcoords = buffer.faceVertexUvs[idxCoord++];
|
|
166
|
+
if (texcoords && nbFaceVerts * 2 === texcoords.length) {
|
|
167
|
+
for (let vertIdx = 0; vertIdx < nbFaceVerts; ++vertIdx) {
|
|
168
|
+
const vertId = buffer.indices[idxVerts + vertIdx];
|
|
169
|
+
const newTex = [texcoords[vertIdx * 2], texcoords[vertIdx * 2 + 1]];
|
|
170
|
+
const currentTex = [tcoordsArray[vertId * 2], tcoordsArray[vertId * 2 + 1]];
|
|
171
|
+
if (currentTex[0] === -1) {
|
|
172
|
+
// First time seeing texture coordinates for this vertex
|
|
173
|
+
tcoordsArray[vertId * 2] = newTex[0];
|
|
174
|
+
tcoordsArray[vertId * 2 + 1] = newTex[1];
|
|
175
|
+
const key = `${newTex[0]},${newTex[1]}`;
|
|
176
|
+
if (!pointIds.has(key)) {
|
|
177
|
+
pointIds.set(key, []);
|
|
178
|
+
}
|
|
179
|
+
pointIds.get(key).push(vertId);
|
|
180
|
+
} else {
|
|
181
|
+
// Check if we need to duplicate the vertex
|
|
182
|
+
const needsDuplication = Math.abs(currentTex[0] - newTex[0]) > faceTextureTolerance || Math.abs(currentTex[1] - newTex[1]) > faceTextureTolerance;
|
|
183
|
+
if (needsDuplication) {
|
|
184
|
+
const key = `${newTex[0]},${newTex[1]}`;
|
|
185
|
+
let existingPointId = -1;
|
|
186
|
+
|
|
187
|
+
// Check if we already have a point with these texture coordinates
|
|
188
|
+
if (pointIds.has(key)) {
|
|
189
|
+
const candidates = pointIds.get(key);
|
|
190
|
+
for (let i = 0, len = candidates.length; i < len; i++) {
|
|
191
|
+
const candidateId = candidates[i];
|
|
192
|
+
const samePosition = Math.abs(pointValues[candidateId * 3] - pointValues[vertId * 3]) <= faceTextureTolerance && Math.abs(pointValues[candidateId * 3 + 1] - pointValues[vertId * 3 + 1]) <= faceTextureTolerance && Math.abs(pointValues[candidateId * 3 + 2] - pointValues[vertId * 3 + 2]) <= faceTextureTolerance;
|
|
193
|
+
if (samePosition) {
|
|
194
|
+
existingPointId = candidateId;
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (existingPointId === -1) {
|
|
200
|
+
// Create new point
|
|
201
|
+
extraPoints.push(pointValues[vertId * 3], pointValues[vertId * 3 + 1], pointValues[vertId * 3 + 2]);
|
|
202
|
+
if (hasColor) {
|
|
203
|
+
extraColors.push(colorArray[vertId * 3], colorArray[vertId * 3 + 1], colorArray[vertId * 3 + 2]);
|
|
204
|
+
}
|
|
205
|
+
if (hasNorms) {
|
|
206
|
+
extraNormals.push(normalsArray[vertId * 3], normalsArray[vertId * 3 + 1], normalsArray[vertId * 3 + 2]);
|
|
207
|
+
}
|
|
208
|
+
extraTCoords.push(newTex[0], newTex[1]);
|
|
209
|
+
if (!pointIds.has(key)) {
|
|
210
|
+
pointIds.set(key, []);
|
|
211
|
+
}
|
|
212
|
+
pointIds.get(key).push(nextPointId);
|
|
213
|
+
buffer.indices[idxVerts + vertIdx] = nextPointId;
|
|
214
|
+
nextPointId++;
|
|
215
|
+
} else {
|
|
216
|
+
buffer.indices[idxVerts + vertIdx] = existingPointId;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
155
221
|
}
|
|
156
|
-
} else {
|
|
157
222
|
idxVerts += nbFaceVerts;
|
|
158
223
|
}
|
|
224
|
+
|
|
225
|
+
// Extend arrays with duplicated points if needed
|
|
226
|
+
if (extraPoints.length > 0) {
|
|
227
|
+
const newPointCount = nbVerts + extraPoints.length / 3;
|
|
228
|
+
const newPointValues = new Float32Array(newPointCount * 3);
|
|
229
|
+
const newTcoordsArray = new Float32Array(newPointCount * 2);
|
|
230
|
+
const newColorArray = hasColor ? new Uint8Array(newPointCount * 3) : null;
|
|
231
|
+
const newNormalsArray = hasNorms ? new Float32Array(newPointCount * 3) : null;
|
|
232
|
+
|
|
233
|
+
// Copy existing data
|
|
234
|
+
newPointValues.set(pointValues);
|
|
235
|
+
newTcoordsArray.set(tcoordsArray);
|
|
236
|
+
if (hasColor && newColorArray) {
|
|
237
|
+
newColorArray.set(colorArray);
|
|
238
|
+
}
|
|
239
|
+
if (hasNorms && newNormalsArray) {
|
|
240
|
+
newNormalsArray.set(normalsArray);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Add new data
|
|
244
|
+
newPointValues.set(extraPoints, nbVerts * 3);
|
|
245
|
+
newTcoordsArray.set(extraTCoords, nbVerts * 2);
|
|
246
|
+
if (hasColor && newColorArray) {
|
|
247
|
+
newColorArray.set(extraColors, nbVerts * 3);
|
|
248
|
+
}
|
|
249
|
+
if (hasNorms && newNormalsArray) {
|
|
250
|
+
newNormalsArray.set(extraNormals, nbVerts * 3);
|
|
251
|
+
}
|
|
252
|
+
pointValues = newPointValues;
|
|
253
|
+
tcoordsArray = newTcoordsArray;
|
|
254
|
+
if (hasColor) {
|
|
255
|
+
colorArray = newColorArray;
|
|
256
|
+
}
|
|
257
|
+
if (hasNorms) {
|
|
258
|
+
normalsArray = newNormalsArray;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
} else {
|
|
262
|
+
for (let faceIdx = 0; faceIdx < nbFaces; ++faceIdx) {
|
|
263
|
+
const nbFaceVerts = buffer.indices[idxVerts++];
|
|
264
|
+
const texcoords = buffer.faceVertexUvs[idxCoord++];
|
|
265
|
+
if (texcoords && nbFaceVerts * 2 === texcoords.length) {
|
|
266
|
+
for (let vertIdx = 0; vertIdx < nbFaceVerts; ++vertIdx) {
|
|
267
|
+
const vert = buffer.indices[idxVerts++];
|
|
268
|
+
tcoordsArray[vert * 2] = texcoords[vertIdx * 2];
|
|
269
|
+
tcoordsArray[vert * 2 + 1] = texcoords[vertIdx * 2 + 1];
|
|
270
|
+
}
|
|
271
|
+
} else {
|
|
272
|
+
idxVerts += nbFaceVerts;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
159
275
|
}
|
|
160
276
|
}
|
|
161
277
|
const polydata = vtkPolyData.newInstance();
|
|
162
278
|
polydata.getPoints().setData(pointValues, 3);
|
|
279
|
+
|
|
280
|
+
// If we have faces, add them as polys
|
|
281
|
+
if (nbFaces > 0) {
|
|
282
|
+
polydata.getPolys().setData(Uint32Array.from(buffer.indices));
|
|
283
|
+
} else {
|
|
284
|
+
// Point cloud - create a vertex list containing all points
|
|
285
|
+
const verts = new Uint32Array(nbVerts * 2);
|
|
286
|
+
for (let i = 0; i < nbVerts; i++) {
|
|
287
|
+
verts[i * 2] = 1; // number of points in vertex cell (always 1)
|
|
288
|
+
verts[i * 2 + 1] = i; // point index
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
polydata.getVerts().setData(verts);
|
|
292
|
+
}
|
|
163
293
|
if (hasColor) {
|
|
164
294
|
polydata.getPointData().setScalars(vtkDataArray.newInstance({
|
|
165
295
|
numberOfComponents: 3,
|
|
166
296
|
values: colorArray,
|
|
167
|
-
name: '
|
|
297
|
+
name: 'RGB'
|
|
168
298
|
}));
|
|
169
299
|
}
|
|
170
300
|
if (hasVertTCoords || hasFaceTCoords) {
|
|
@@ -184,7 +314,6 @@ function postProcess(buffer, elements) {
|
|
|
184
314
|
values: normalsArray
|
|
185
315
|
}));
|
|
186
316
|
}
|
|
187
|
-
polydata.getPolys().setData(Uint32Array.from(buffer.indices));
|
|
188
317
|
return polydata;
|
|
189
318
|
}
|
|
190
319
|
function parseNumber(n, type) {
|
|
@@ -410,7 +539,10 @@ function vtkPLYReader(publicAPI, model) {
|
|
|
410
539
|
}
|
|
411
540
|
|
|
412
541
|
// Header
|
|
413
|
-
|
|
542
|
+
let text = content;
|
|
543
|
+
if (content instanceof ArrayBuffer) {
|
|
544
|
+
text = BinaryHelper.arrayBufferToString(content);
|
|
545
|
+
}
|
|
414
546
|
const header = parseHeader(text);
|
|
415
547
|
|
|
416
548
|
// ascii/binary detection
|
|
@@ -418,7 +550,7 @@ function vtkPLYReader(publicAPI, model) {
|
|
|
418
550
|
|
|
419
551
|
// Check if ascii format
|
|
420
552
|
if (!isBinary) {
|
|
421
|
-
publicAPI.parseAsText(
|
|
553
|
+
publicAPI.parseAsText(text);
|
|
422
554
|
return;
|
|
423
555
|
}
|
|
424
556
|
model.parseData = content;
|
|
@@ -445,7 +577,7 @@ function vtkPLYReader(publicAPI, model) {
|
|
|
445
577
|
handleElement(buffer, header.elements[elem].name, element);
|
|
446
578
|
}
|
|
447
579
|
}
|
|
448
|
-
const polydata = postProcess(buffer, header.elements);
|
|
580
|
+
const polydata = postProcess(buffer, header.elements, model.faceTextureTolerance, model.duplicatePointsForFaceTexture);
|
|
449
581
|
|
|
450
582
|
// Add new output
|
|
451
583
|
model.output[0] = polydata;
|
|
@@ -462,7 +594,10 @@ function vtkPLYReader(publicAPI, model) {
|
|
|
462
594
|
model.parseData = content;
|
|
463
595
|
|
|
464
596
|
// Header
|
|
465
|
-
|
|
597
|
+
let text = content;
|
|
598
|
+
if (content instanceof ArrayBuffer) {
|
|
599
|
+
text = BinaryHelper.arrayBufferToString(content);
|
|
600
|
+
}
|
|
466
601
|
const header = parseHeader(text);
|
|
467
602
|
|
|
468
603
|
// ascii/binary detection
|
|
@@ -504,7 +639,7 @@ function vtkPLYReader(publicAPI, model) {
|
|
|
504
639
|
idx++;
|
|
505
640
|
}
|
|
506
641
|
}
|
|
507
|
-
const polydata = postProcess(buffer, header.elements);
|
|
642
|
+
const polydata = postProcess(buffer, header.elements, model.faceTextureTolerance, model.duplicatePointsForFaceTexture);
|
|
508
643
|
|
|
509
644
|
// Add new output
|
|
510
645
|
model.output[0] = polydata;
|
|
@@ -522,6 +657,8 @@ const DEFAULT_VALUES = {
|
|
|
522
657
|
// baseURL: null,
|
|
523
658
|
// dataAccessHelper: null,
|
|
524
659
|
// url: null,
|
|
660
|
+
faceTextureTolerance: 1e-6,
|
|
661
|
+
duplicatePointsForFaceTexture: true
|
|
525
662
|
};
|
|
526
663
|
|
|
527
664
|
// ----------------------------------------------------------------------------
|
|
@@ -532,7 +669,7 @@ function extend(publicAPI, model) {
|
|
|
532
669
|
|
|
533
670
|
// Build VTK API
|
|
534
671
|
macro.obj(publicAPI, model);
|
|
535
|
-
macro.get(publicAPI, model, ['url', 'baseURL']);
|
|
672
|
+
macro.get(publicAPI, model, ['url', 'baseURL', 'duplicatePointsForFaceTexture', 'faceTextureTolerance']);
|
|
536
673
|
macro.setGet(publicAPI, model, ['dataAccessHelper']);
|
|
537
674
|
macro.algo(publicAPI, model, 0, 1);
|
|
538
675
|
|
|
@@ -13,77 +13,35 @@ function vtkMouseCameraTrackballFirstPersonManipulator(publicAPI, model) {
|
|
|
13
13
|
model.classHierarchy.push('vtkMouseCameraTrackballFirstPersonManipulator');
|
|
14
14
|
const internal = {
|
|
15
15
|
interactor: null,
|
|
16
|
-
renderer: null
|
|
17
|
-
previousPosition: null
|
|
16
|
+
renderer: null
|
|
18
17
|
};
|
|
19
18
|
|
|
20
19
|
//--------------------------------------------------------------------------
|
|
21
20
|
|
|
22
21
|
publicAPI.onButtonDown = (interactor, renderer, position) => {
|
|
23
|
-
internal.previousPosition = position;
|
|
24
22
|
if (model.usePointerLock && !interactor.isPointerLocked()) {
|
|
25
23
|
Object.assign(internal, {
|
|
26
24
|
interactor,
|
|
27
25
|
renderer
|
|
28
26
|
});
|
|
29
27
|
interactor.requestPointerLock();
|
|
30
|
-
publicAPI.startPointerLockInteraction();
|
|
31
28
|
}
|
|
32
29
|
};
|
|
33
30
|
|
|
34
31
|
//--------------------------------------------------------------------------
|
|
35
32
|
|
|
36
|
-
publicAPI.startPointerLockInteraction = () => {
|
|
37
|
-
const {
|
|
38
|
-
interactor
|
|
39
|
-
} = internal;
|
|
40
|
-
|
|
41
|
-
// TODO: at some point, this should perhaps be done in
|
|
42
|
-
// RenderWindowInteractor instead of here.
|
|
43
|
-
// We need to hook into mousemove directly for two reasons:
|
|
44
|
-
// 1. We need to keep receiving mouse move events after the mouse button
|
|
45
|
-
// is released. This is currently not possible with
|
|
46
|
-
// vtkInteractorStyleManipulator.
|
|
47
|
-
// 2. Since the mouse is stationary in pointer lock mode, we need the
|
|
48
|
-
// event.movementX and event.movementY info, which are not currently
|
|
49
|
-
// passed via interactor.onMouseMove.
|
|
50
|
-
document.addEventListener('mousemove', publicAPI.onPointerLockMove);
|
|
51
|
-
let subscription = null;
|
|
52
|
-
const endInteraction = () => {
|
|
53
|
-
document.removeEventListener('mousemove', publicAPI.onPointerLockMove);
|
|
54
|
-
subscription.unsubscribe();
|
|
55
|
-
};
|
|
56
|
-
subscription = interactor.onEndPointerLock(endInteraction);
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
//--------------------------------------------------------------------------
|
|
60
|
-
|
|
61
|
-
publicAPI.onPointerLockMove = e => {
|
|
62
|
-
const sensitivity = model.sensitivity;
|
|
63
|
-
const yaw = -1 * e.movementX * sensitivity;
|
|
64
|
-
const pitch = -1 * e.movementY * sensitivity;
|
|
65
|
-
publicAPI.moveCamera(yaw, pitch);
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
//--------------------------------------------------------------------------
|
|
69
|
-
|
|
70
33
|
publicAPI.onMouseMove = (interactor, renderer, position) => {
|
|
71
|
-
// This is currently only being called for non pointer lock mode
|
|
72
34
|
if (!position) {
|
|
73
35
|
return;
|
|
74
36
|
}
|
|
75
|
-
const {
|
|
76
|
-
previousPosition
|
|
77
|
-
} = internal;
|
|
78
37
|
const sensitivity = model.sensitivity;
|
|
79
|
-
const yaw =
|
|
80
|
-
const pitch =
|
|
38
|
+
const yaw = -position.movementX * sensitivity;
|
|
39
|
+
const pitch = -position.movementY * sensitivity;
|
|
81
40
|
Object.assign(internal, {
|
|
82
41
|
interactor,
|
|
83
42
|
renderer
|
|
84
43
|
});
|
|
85
44
|
publicAPI.moveCamera(yaw, pitch);
|
|
86
|
-
internal.previousPosition = position;
|
|
87
45
|
};
|
|
88
46
|
|
|
89
47
|
//--------------------------------------------------------------------------
|
|
@@ -6,6 +6,7 @@ import vtkInteractorStyle from './../../Rendering/Core/InteractorStyle';
|
|
|
6
6
|
import {
|
|
7
7
|
Device,
|
|
8
8
|
Input,
|
|
9
|
+
MouseButton,
|
|
9
10
|
} from './../../Rendering/Core/RenderWindowInteractor/Constants';
|
|
10
11
|
import { Nullable, Vector3 } from './../../types';
|
|
11
12
|
|
|
@@ -120,7 +121,7 @@ export interface vtkInteractorStyleManipulator extends vtkInteractorStyle {
|
|
|
120
121
|
* @param alt alt enabled
|
|
121
122
|
*/
|
|
122
123
|
findMouseManipulator(
|
|
123
|
-
button:
|
|
124
|
+
button: MouseButton,
|
|
124
125
|
shift: boolean,
|
|
125
126
|
scroll: boolean,
|
|
126
127
|
alt: boolean
|
|
@@ -285,13 +286,13 @@ export interface vtkInteractorStyleManipulator extends vtkInteractorStyle {
|
|
|
285
286
|
* @param button which button
|
|
286
287
|
* @param callData event data
|
|
287
288
|
*/
|
|
288
|
-
onButtonDown(button:
|
|
289
|
+
onButtonDown(button: MouseButton, callData: unknown): void;
|
|
289
290
|
|
|
290
291
|
/**
|
|
291
292
|
* Handles a button up event.
|
|
292
293
|
* @param button which button
|
|
293
294
|
*/
|
|
294
|
-
onButtonUp(button:
|
|
295
|
+
onButtonUp(button: MouseButton): void;
|
|
295
296
|
|
|
296
297
|
/**
|
|
297
298
|
* Sets the rotation factor.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { m as macro } from '../../macros2.js';
|
|
2
|
+
import { MouseButton } from '../../Rendering/Core/RenderWindowInteractor/Constants.js';
|
|
2
3
|
import vtkInteractorStyle from '../../Rendering/Core/InteractorStyle.js';
|
|
3
4
|
|
|
4
5
|
const {
|
|
@@ -225,19 +226,19 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
225
226
|
//-------------------------------------------------------------------------
|
|
226
227
|
publicAPI.handleLeftButtonPress = callData => {
|
|
227
228
|
model.previousPosition = callData.position;
|
|
228
|
-
publicAPI.onButtonDown(
|
|
229
|
+
publicAPI.onButtonDown(MouseButton.LeftButton, callData);
|
|
229
230
|
};
|
|
230
231
|
|
|
231
232
|
//-------------------------------------------------------------------------
|
|
232
233
|
publicAPI.handleMiddleButtonPress = callData => {
|
|
233
234
|
model.previousPosition = callData.position;
|
|
234
|
-
publicAPI.onButtonDown(
|
|
235
|
+
publicAPI.onButtonDown(MouseButton.MiddleButton, callData);
|
|
235
236
|
};
|
|
236
237
|
|
|
237
238
|
//-------------------------------------------------------------------------
|
|
238
239
|
publicAPI.handleRightButtonPress = callData => {
|
|
239
240
|
model.previousPosition = callData.position;
|
|
240
|
-
publicAPI.onButtonDown(
|
|
241
|
+
publicAPI.onButtonDown(MouseButton.RightButton, callData);
|
|
241
242
|
};
|
|
242
243
|
|
|
243
244
|
//-------------------------------------------------------------------------
|
|
@@ -330,17 +331,17 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
330
331
|
|
|
331
332
|
//-------------------------------------------------------------------------
|
|
332
333
|
publicAPI.handleLeftButtonRelease = () => {
|
|
333
|
-
publicAPI.onButtonUp(
|
|
334
|
+
publicAPI.onButtonUp(MouseButton.LeftButton);
|
|
334
335
|
};
|
|
335
336
|
|
|
336
337
|
//-------------------------------------------------------------------------
|
|
337
338
|
publicAPI.handleMiddleButtonRelease = () => {
|
|
338
|
-
publicAPI.onButtonUp(
|
|
339
|
+
publicAPI.onButtonUp(MouseButton.MiddleButton);
|
|
339
340
|
};
|
|
340
341
|
|
|
341
342
|
//-------------------------------------------------------------------------
|
|
342
343
|
publicAPI.handleRightButtonRelease = () => {
|
|
343
|
-
publicAPI.onButtonUp(
|
|
344
|
+
publicAPI.onButtonUp(MouseButton.RightButton);
|
|
344
345
|
};
|
|
345
346
|
|
|
346
347
|
//-------------------------------------------------------------------------
|
|
@@ -351,12 +352,18 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
351
352
|
if (model.currentManipulator.getButton && model.currentManipulator.getButton() === button) {
|
|
352
353
|
model.currentManipulator.onButtonUp(model._interactor);
|
|
353
354
|
model.currentManipulator.endInteraction();
|
|
354
|
-
model.
|
|
355
|
-
|
|
355
|
+
if (!model._interactor.isPointerLocked()) {
|
|
356
|
+
model.currentManipulator = null;
|
|
357
|
+
}
|
|
356
358
|
publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
|
|
357
359
|
}
|
|
358
360
|
};
|
|
359
361
|
|
|
362
|
+
//-------------------------------------------------------------------------
|
|
363
|
+
publicAPI.handleEndPointerLock = () => {
|
|
364
|
+
model.currentManipulator = null;
|
|
365
|
+
};
|
|
366
|
+
|
|
360
367
|
//-------------------------------------------------------------------------
|
|
361
368
|
publicAPI.handleStartMouseWheel = callData => {
|
|
362
369
|
// Must not be processing a wheel interaction to start another.
|
|
@@ -312,6 +312,30 @@ export interface vtkColorTransferFunction extends vtkScalarsToColors {
|
|
|
312
312
|
* @param colorMap
|
|
313
313
|
*/
|
|
314
314
|
applyColorMap(colorMap: any): void;
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Get the color space of the color transfer function.
|
|
318
|
+
* @returns {ColorSpace}
|
|
319
|
+
*/
|
|
320
|
+
getColorSpace(): ColorSpace;
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Set the color space of the color transfer function.
|
|
324
|
+
* @param {ColorSpace} colorSpace
|
|
325
|
+
*/
|
|
326
|
+
setColorSpace(colorSpace: ColorSpace): void;
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Get the scale of the color transfer function.
|
|
330
|
+
* @returns {Scale}
|
|
331
|
+
*/
|
|
332
|
+
getScale(): Scale;
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Set the scale of the color transfer function.
|
|
336
|
+
* @param {Scale} scale
|
|
337
|
+
*/
|
|
338
|
+
setScale(scale: Scale): void;
|
|
315
339
|
}
|
|
316
340
|
|
|
317
341
|
/**
|
package/Rendering/Core/Mapper.js
CHANGED
|
@@ -135,12 +135,13 @@ const colorTextureCoordinatesCache = new WeakMap();
|
|
|
135
135
|
* @param {vtkDataArray} input The input data array used for coloring
|
|
136
136
|
* @param {Number} component The component of the input data array that is used for coloring (-1 for magnitude of the vectors)
|
|
137
137
|
* @param {Range} range The range of the scalars
|
|
138
|
+
* @param {boolean} useLogScale Should the values be transformed to logarithmic scale. When true, the range must already be in logarithmic scale.
|
|
138
139
|
* @param {Number} numberOfColorsInRange The number of colors that are used in the range
|
|
139
140
|
* @param {vec3} dimensions The dimensions of the texture
|
|
140
141
|
* @param {boolean} useZigzagPattern If a zigzag pattern should be used. Otherwise 1 row for colors (including min and max) and 1 row for NaN are used.
|
|
141
142
|
* @returns A vtkDataArray containing the texture coordinates (2D or 3D)
|
|
142
143
|
*/
|
|
143
|
-
function getOrCreateColorTextureCoordinates(input, component, range, numberOfColorsInRange, dimensions, useZigzagPattern) {
|
|
144
|
+
function getOrCreateColorTextureCoordinates(input, component, range, useLogScale, numberOfColorsInRange, dimensions, useZigzagPattern) {
|
|
144
145
|
// Caching using the "arguments" special object (because it is a pure function)
|
|
145
146
|
const argStrings = new Array(arguments.length);
|
|
146
147
|
for (let argIndex = 0; argIndex < arguments.length; ++argIndex) {
|
|
@@ -199,6 +200,9 @@ function getOrCreateColorTextureCoordinates(input, component, range, numberOfCol
|
|
|
199
200
|
} else {
|
|
200
201
|
scalarValue = inputV[inputIdx + component];
|
|
201
202
|
}
|
|
203
|
+
if (useLogScale) {
|
|
204
|
+
scalarValue = Math.log10(scalarValue);
|
|
205
|
+
}
|
|
202
206
|
inputIdx += numComps;
|
|
203
207
|
|
|
204
208
|
// Convert to texture coordinates and update output
|
|
@@ -396,6 +400,7 @@ function vtkMapper(publicAPI, model) {
|
|
|
396
400
|
const range = model.lookupTable.getRange();
|
|
397
401
|
const useLogScale = model.lookupTable.usingLogScale();
|
|
398
402
|
const origAlpha = model.lookupTable.getAlpha();
|
|
403
|
+
const scaledRange = useLogScale ? [Math.log10(range[0]), Math.log10(range[1])] : range;
|
|
399
404
|
|
|
400
405
|
// Get rid of vertex color array. Only texture or vertex coloring
|
|
401
406
|
// can be active at one time. The existence of the array is the
|
|
@@ -438,7 +443,6 @@ function vtkMapper(publicAPI, model) {
|
|
|
438
443
|
const numberOfNonSpecialColors = model.numberOfColorsInRange;
|
|
439
444
|
const numberOfNonNaNColors = numberOfNonSpecialColors + 2;
|
|
440
445
|
const textureCoordinates = [0, 0, 0];
|
|
441
|
-
const scaledRange = useLogScale ? [Math.log10(range[0]), Math.log10(range[1])] : range;
|
|
442
446
|
const rangeMin = scaledRange[0];
|
|
443
447
|
const rangeDifference = scaledRange[1] - scaledRange[0];
|
|
444
448
|
for (let i = 0; i < numberOfNonNaNColors; ++i) {
|
|
@@ -472,7 +476,7 @@ function vtkMapper(publicAPI, model) {
|
|
|
472
476
|
// A zigzag pattern can be used with cell data, as there will be no texture coordinates interpolation
|
|
473
477
|
// The texture generated using a zigzag pattern in one dimension is the same as without zigzag
|
|
474
478
|
// Therefore, the same code can be used for texture generation of point/cell data but not for texture coordinates
|
|
475
|
-
model.colorCoordinates = getOrCreateColorTextureCoordinates(scalars, scalarComponent,
|
|
479
|
+
model.colorCoordinates = getOrCreateColorTextureCoordinates(scalars, scalarComponent, scaledRange, useLogScale, model.numberOfColorsInRange, model.colorTextureMap.getDimensions(), cellFlag);
|
|
476
480
|
};
|
|
477
481
|
publicAPI.getIsOpaque = () => {
|
|
478
482
|
const input = publicAPI.getInputData();
|
|
@@ -23,9 +23,16 @@ export declare enum Axis {
|
|
|
23
23
|
ThumbstickY = 4,
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
export declare enum MouseButton {
|
|
27
|
+
LeftButton = 1,
|
|
28
|
+
MiddleButton = 2,
|
|
29
|
+
RightButton = 3,
|
|
30
|
+
}
|
|
31
|
+
|
|
26
32
|
declare const _default: {
|
|
27
33
|
Device: typeof Device;
|
|
28
34
|
Input: typeof Input;
|
|
29
35
|
Axis: typeof Axis;
|
|
36
|
+
MouseButton: typeof MouseButton;
|
|
30
37
|
};
|
|
31
38
|
export default _default;
|
|
@@ -21,10 +21,16 @@ const Axis = {
|
|
|
21
21
|
ThumbstickX: 3,
|
|
22
22
|
ThumbstickY: 4
|
|
23
23
|
};
|
|
24
|
+
const MouseButton = {
|
|
25
|
+
LeftButton: 1,
|
|
26
|
+
MiddleButton: 2,
|
|
27
|
+
RightButton: 3
|
|
28
|
+
};
|
|
24
29
|
var Constants = {
|
|
25
30
|
Device,
|
|
26
31
|
Input,
|
|
27
|
-
Axis
|
|
32
|
+
Axis,
|
|
33
|
+
MouseButton
|
|
28
34
|
};
|
|
29
35
|
|
|
30
|
-
export { Axis, Device, Input, Constants as default };
|
|
36
|
+
export { Axis, Device, Input, MouseButton, Constants as default };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { vtkObject, vtkSubscription } from './../../interfaces';
|
|
2
2
|
import { Nullable } from './../../types';
|
|
3
3
|
import vtkRenderer from './Renderer';
|
|
4
|
-
import { Axis, Device, Input } from './RenderWindowInteractor/Constants';
|
|
4
|
+
import { Axis, Device, Input, MouseButton } from './RenderWindowInteractor/Constants';
|
|
5
5
|
|
|
6
6
|
declare enum handledEvents {
|
|
7
7
|
'StartAnimation',
|
|
@@ -1397,5 +1397,6 @@ export declare const vtkRenderWindowInteractor: {
|
|
|
1397
1397
|
Device: typeof Device;
|
|
1398
1398
|
Input: typeof Input;
|
|
1399
1399
|
Axis: typeof Axis;
|
|
1400
|
+
MouseButton: typeof MouseButton;
|
|
1400
1401
|
};
|
|
1401
1402
|
export default vtkRenderWindowInteractor;
|
|
@@ -136,7 +136,9 @@ function vtkRenderWindowInteractor(publicAPI, model) {
|
|
|
136
136
|
const position = {
|
|
137
137
|
x: scaleX * (source.clientX - bounds.left),
|
|
138
138
|
y: scaleY * (bounds.height - source.clientY + bounds.top),
|
|
139
|
-
z: 0
|
|
139
|
+
z: 0,
|
|
140
|
+
movementX: scaleX * source.movementX,
|
|
141
|
+
movementY: scaleY * source.movementY
|
|
140
142
|
};
|
|
141
143
|
|
|
142
144
|
// if multitouch, do not update the current renderer
|