@kitware/vtk.js 29.4.3 → 29.4.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/Rendering/Core/Picker.js
CHANGED
|
@@ -33,6 +33,35 @@ function vtkPicker(publicAPI, model) {
|
|
|
33
33
|
model.globalTMin = Number.MAX_VALUE;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Compute the tolerance in world coordinates.
|
|
38
|
+
* Do this by determining the world coordinates of the diagonal points of the
|
|
39
|
+
* window, computing the width of the window in world coordinates, and
|
|
40
|
+
* multiplying by the tolerance.
|
|
41
|
+
* @param {Number} selectionZ
|
|
42
|
+
* @param {Number} aspect
|
|
43
|
+
* @param {vtkRenderer} renderer
|
|
44
|
+
* @returns {Number} the computed tolerance
|
|
45
|
+
*/
|
|
46
|
+
function computeTolerance(selectionZ, aspect, renderer) {
|
|
47
|
+
let tolerance = 0.0;
|
|
48
|
+
const view = renderer.getRenderWindow().getViews()[0];
|
|
49
|
+
const viewport = renderer.getViewport();
|
|
50
|
+
const winSize = view.getSize();
|
|
51
|
+
let x = winSize[0] * viewport[0];
|
|
52
|
+
let y = winSize[1] * viewport[1];
|
|
53
|
+
const normalizedLeftDisplay = view.displayToNormalizedDisplay(x, y, selectionZ);
|
|
54
|
+
const windowLowerLeft = renderer.normalizedDisplayToWorld(normalizedLeftDisplay[0], normalizedLeftDisplay[1], normalizedLeftDisplay[2], aspect);
|
|
55
|
+
x = winSize[0] * viewport[2];
|
|
56
|
+
y = winSize[1] * viewport[3];
|
|
57
|
+
const normalizedRightDisplay = view.displayToNormalizedDisplay(x, y, selectionZ);
|
|
58
|
+
const windowUpperRight = renderer.normalizedDisplayToWorld(normalizedRightDisplay[0], normalizedRightDisplay[1], normalizedRightDisplay[2], aspect);
|
|
59
|
+
for (let i = 0; i < 3; i++) {
|
|
60
|
+
tolerance += (windowUpperRight[i] - windowLowerLeft[i]) * (windowUpperRight[i] - windowLowerLeft[i]);
|
|
61
|
+
}
|
|
62
|
+
return Math.sqrt(tolerance);
|
|
63
|
+
}
|
|
64
|
+
|
|
36
65
|
// Intersect data with specified ray.
|
|
37
66
|
// Project the center point of the mapper onto the ray and determine its parametric value
|
|
38
67
|
publicAPI.intersectWithLine = (p1, p2, tol, mapper) => {
|
|
@@ -73,13 +102,6 @@ function vtkPicker(publicAPI, model) {
|
|
|
73
102
|
let tB;
|
|
74
103
|
const p1World = [];
|
|
75
104
|
const p2World = [];
|
|
76
|
-
let viewport = [];
|
|
77
|
-
let winSize = [];
|
|
78
|
-
let x;
|
|
79
|
-
let y;
|
|
80
|
-
let windowLowerLeft = [];
|
|
81
|
-
let windowUpperRight = [];
|
|
82
|
-
let tol = 0.0;
|
|
83
105
|
let props = [];
|
|
84
106
|
let pickable = false;
|
|
85
107
|
const p1Mapper = new Float64Array(4);
|
|
@@ -108,6 +130,7 @@ function vtkPicker(publicAPI, model) {
|
|
|
108
130
|
displayCoords = renderer.worldToNormalizedDisplay(cameraFP[0], cameraFP[1], cameraFP[2], aspect);
|
|
109
131
|
displayCoords = view.normalizedDisplayToDisplay(displayCoords[0], displayCoords[1], displayCoords[2]);
|
|
110
132
|
selectionZ = displayCoords[2];
|
|
133
|
+
const tolerance = computeTolerance(selectionZ, aspect, renderer) * model.tolerance;
|
|
111
134
|
|
|
112
135
|
// Convert the selection point into world coordinates.
|
|
113
136
|
const normalizedDisplay = view.displayToNormalizedDisplay(selectionX, selectionY, selectionZ);
|
|
@@ -150,27 +173,6 @@ function vtkPicker(publicAPI, model) {
|
|
|
150
173
|
}
|
|
151
174
|
p1World[3] = 1.0;
|
|
152
175
|
p2World[3] = 1.0;
|
|
153
|
-
|
|
154
|
-
// Compute the tolerance in world coordinates. Do this by
|
|
155
|
-
// determining the world coordinates of the diagonal points of the
|
|
156
|
-
// window, computing the width of the window in world coordinates, and
|
|
157
|
-
// multiplying by the tolerance.
|
|
158
|
-
viewport = renderer.getViewport();
|
|
159
|
-
if (renderer.getRenderWindow()) {
|
|
160
|
-
winSize = renderer.getRenderWindow().getViews()[0].getSize();
|
|
161
|
-
}
|
|
162
|
-
x = winSize[0] * viewport[0];
|
|
163
|
-
y = winSize[1] * viewport[1];
|
|
164
|
-
const normalizedLeftDisplay = view.displayToNormalizedDisplay(x, y, selectionZ);
|
|
165
|
-
windowLowerLeft = renderer.normalizedDisplayToWorld(normalizedLeftDisplay[0], normalizedLeftDisplay[1], normalizedLeftDisplay[2], aspect);
|
|
166
|
-
x = winSize[0] * viewport[2];
|
|
167
|
-
y = winSize[1] * viewport[3];
|
|
168
|
-
const normalizedRightDisplay = view.displayToNormalizedDisplay(x, y, selectionZ);
|
|
169
|
-
windowUpperRight = renderer.normalizedDisplayToWorld(normalizedRightDisplay[0], normalizedRightDisplay[1], normalizedRightDisplay[2], aspect);
|
|
170
|
-
for (let i = 0; i < 3; i++) {
|
|
171
|
-
tol += (windowUpperRight[i] - windowLowerLeft[i]) * (windowUpperRight[i] - windowLowerLeft[i]);
|
|
172
|
-
}
|
|
173
|
-
tol = Math.sqrt(tol) * model.tolerance;
|
|
174
176
|
if (model.pickFromList) {
|
|
175
177
|
props = model.pickList;
|
|
176
178
|
} else {
|
|
@@ -209,12 +211,12 @@ function vtkPicker(publicAPI, model) {
|
|
|
209
211
|
}
|
|
210
212
|
if (mapper) {
|
|
211
213
|
bbox.setBounds(mapper.getBounds());
|
|
212
|
-
bbox.inflate(
|
|
214
|
+
bbox.inflate(tolerance);
|
|
213
215
|
} else {
|
|
214
216
|
bbox.reset();
|
|
215
217
|
}
|
|
216
218
|
if (bbox.intersectBox(p1Mapper, ray, hitPosition, t)) {
|
|
217
|
-
t[0] = publicAPI.intersectWithLine(p1Mapper, p2Mapper,
|
|
219
|
+
t[0] = publicAPI.intersectWithLine(p1Mapper, p2Mapper, tolerance * 0.333 * (scale[0] + scale[1] + scale[2]), prop, mapper);
|
|
218
220
|
if (t[0] < Number.MAX_VALUE) {
|
|
219
221
|
const p = [];
|
|
220
222
|
p[0] = (1.0 - t[0]) * p1World[0] + t[0] * p2World[0];
|
|
@@ -93,7 +93,7 @@ export interface vtkRenderWindowInteractor extends vtkObject {
|
|
|
93
93
|
*
|
|
94
94
|
* @default null
|
|
95
95
|
*/
|
|
96
|
-
getContainer(): HTMLElement
|
|
96
|
+
getContainer(): Nullable<HTMLElement>;
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
99
|
*
|
|
@@ -827,6 +827,13 @@ export interface vtkRenderWindowInteractor extends vtkObject {
|
|
|
827
827
|
*/
|
|
828
828
|
rotateEvent(args: any): any;
|
|
829
829
|
|
|
830
|
+
/**
|
|
831
|
+
* Add an HTMLElement as the new container for the interactor.
|
|
832
|
+
* All events will be bound to this new container.
|
|
833
|
+
* Any old container will be removed along with its listeners.
|
|
834
|
+
*/
|
|
835
|
+
setContainer(container: Nullable<HTMLElement>): boolean;
|
|
836
|
+
|
|
830
837
|
/**
|
|
831
838
|
* Turn on/off the automatic repositioning of lights as the camera moves.
|
|
832
839
|
* @param lightFollowCamera
|
|
@@ -992,12 +999,15 @@ export interface vtkRenderWindowInteractor extends vtkObject {
|
|
|
992
999
|
|
|
993
1000
|
/**
|
|
994
1001
|
*
|
|
995
|
-
* @param container
|
|
1002
|
+
* @param container kept for backward compatibility.
|
|
1003
|
+
* @deprecated please use vtkRenderWindowInteractor.setContainer(container: HTMLElement)
|
|
1004
|
+
* which will also bind events.
|
|
996
1005
|
*/
|
|
997
1006
|
bindEvents(container: any): void;
|
|
998
1007
|
|
|
999
1008
|
/**
|
|
1000
1009
|
*
|
|
1010
|
+
* @deprecated please use vtkRenderWindowInteractor.setContainer(null) instead.
|
|
1001
1011
|
*/
|
|
1002
1012
|
unbindEvents(): void;
|
|
1003
1013
|
|
|
@@ -51,6 +51,11 @@ function vtkRenderWindowInteractor(publicAPI, model) {
|
|
|
51
51
|
// Set our className
|
|
52
52
|
model.classHierarchy.push('vtkRenderWindowInteractor');
|
|
53
53
|
|
|
54
|
+
// Capture "parentClass" api for internal use
|
|
55
|
+
const superClass = {
|
|
56
|
+
...publicAPI
|
|
57
|
+
};
|
|
58
|
+
|
|
54
59
|
// Initialize list of requesters
|
|
55
60
|
const animationRequesters = new Set();
|
|
56
61
|
|
|
@@ -161,8 +166,13 @@ function vtkRenderWindowInteractor(publicAPI, model) {
|
|
|
161
166
|
function getDeviceTypeFor(event) {
|
|
162
167
|
return event.pointerType || '';
|
|
163
168
|
}
|
|
164
|
-
|
|
165
|
-
model.container
|
|
169
|
+
const _bindEvents = () => {
|
|
170
|
+
if (model.container === null) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const {
|
|
174
|
+
container
|
|
175
|
+
} = model;
|
|
166
176
|
container.addEventListener('contextmenu', preventDefault);
|
|
167
177
|
container.addEventListener('wheel', publicAPI.handleWheel);
|
|
168
178
|
container.addEventListener('DOMMouseScroll', publicAPI.handleWheel);
|
|
@@ -188,30 +198,53 @@ function vtkRenderWindowInteractor(publicAPI, model) {
|
|
|
188
198
|
// disables tap highlight for when cursor is pointer
|
|
189
199
|
container.style.webkitTapHighlightColor = 'rgba(0,0,0,0)';
|
|
190
200
|
};
|
|
191
|
-
|
|
201
|
+
|
|
202
|
+
// For backward compatibility.
|
|
203
|
+
// Necessary for using unbind/bindEvent without calling setContainer.
|
|
204
|
+
publicAPI.bindEvents = container => {
|
|
205
|
+
if (container === null) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const res = superClass.setContainer(container);
|
|
209
|
+
if (res) {
|
|
210
|
+
_bindEvents();
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
const _unbindEvents = () => {
|
|
214
|
+
// Clear any previous timeouts and state variables that control mouse / touchpad behavior.
|
|
215
|
+
clearTimeout(model.moveTimeoutID);
|
|
216
|
+
clearTimeout(model.wheelTimeoutID);
|
|
217
|
+
model.moveTimeoutID = 0;
|
|
218
|
+
model.wheelTimeoutID = 0;
|
|
219
|
+
wheelCoefficient = 1.0;
|
|
192
220
|
const {
|
|
193
221
|
container
|
|
194
222
|
} = model;
|
|
195
|
-
container
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
223
|
+
if (container) {
|
|
224
|
+
container.removeEventListener('contextmenu', preventDefault);
|
|
225
|
+
container.removeEventListener('wheel', publicAPI.handleWheel);
|
|
226
|
+
container.removeEventListener('DOMMouseScroll', publicAPI.handleWheel);
|
|
227
|
+
container.removeEventListener('pointerenter', publicAPI.handlePointerEnter);
|
|
228
|
+
container.removeEventListener('pointerleave', publicAPI.handlePointerLeave);
|
|
229
|
+
container.removeEventListener('pointermove', publicAPI.handlePointerMove, {
|
|
230
|
+
passive: false
|
|
231
|
+
});
|
|
232
|
+
container.removeEventListener('pointerdown', publicAPI.handlePointerDown, {
|
|
233
|
+
passive: false
|
|
234
|
+
});
|
|
235
|
+
container.removeEventListener('pointerup', publicAPI.handlePointerUp);
|
|
236
|
+
container.removeEventListener('pointercancel', publicAPI.handlePointerCancel);
|
|
237
|
+
}
|
|
208
238
|
document.removeEventListener('keypress', publicAPI.handleKeyPress);
|
|
209
239
|
document.removeEventListener('keydown', publicAPI.handleKeyDown);
|
|
210
240
|
document.removeEventListener('keyup', publicAPI.handleKeyUp);
|
|
211
241
|
document.removeEventListener('pointerlockchange', publicAPI.handlePointerLockChange);
|
|
212
|
-
model.container = null;
|
|
213
242
|
pointerCache.clear();
|
|
214
243
|
};
|
|
244
|
+
publicAPI.unbindEvents = () => {
|
|
245
|
+
_unbindEvents();
|
|
246
|
+
superClass.setContainer(null);
|
|
247
|
+
};
|
|
215
248
|
publicAPI.handleKeyPress = event => {
|
|
216
249
|
const data = getKeysFor(event);
|
|
217
250
|
publicAPI.keyPressEvent(data);
|
|
@@ -947,9 +980,16 @@ function vtkRenderWindowInteractor(publicAPI, model) {
|
|
|
947
980
|
model._forcedRenderer = !!r;
|
|
948
981
|
model.currentRenderer = r;
|
|
949
982
|
};
|
|
983
|
+
publicAPI.setContainer = container => {
|
|
984
|
+
_unbindEvents();
|
|
985
|
+
const res = superClass.setContainer(container ?? null);
|
|
986
|
+
if (res) {
|
|
987
|
+
_bindEvents();
|
|
988
|
+
}
|
|
989
|
+
return res;
|
|
990
|
+
};
|
|
950
991
|
|
|
951
992
|
// Stop animating if the renderWindowInteractor is deleted.
|
|
952
|
-
const superDelete = publicAPI.delete;
|
|
953
993
|
publicAPI.delete = () => {
|
|
954
994
|
while (animationRequesters.size) {
|
|
955
995
|
publicAPI.cancelAnimation(animationRequesters.values().next().value);
|
|
@@ -958,9 +998,9 @@ function vtkRenderWindowInteractor(publicAPI, model) {
|
|
|
958
998
|
document.removeEventListener('visibilitychange', publicAPI.handleVisibilityChange);
|
|
959
999
|
}
|
|
960
1000
|
if (model.container) {
|
|
961
|
-
publicAPI.
|
|
1001
|
+
publicAPI.setContainer(null);
|
|
962
1002
|
}
|
|
963
|
-
|
|
1003
|
+
superClass.delete();
|
|
964
1004
|
};
|
|
965
1005
|
|
|
966
1006
|
// Use the Page Visibility API to detect when we switch away from or back to
|
|
@@ -1017,10 +1057,10 @@ function extend(publicAPI, model) {
|
|
|
1017
1057
|
handledEvents.forEach(eventName => macro.event(publicAPI, model, eventName));
|
|
1018
1058
|
|
|
1019
1059
|
// Create get-only macros
|
|
1020
|
-
macro.get(publicAPI, model, ['initialized', '
|
|
1060
|
+
macro.get(publicAPI, model, ['initialized', 'interactorStyle', 'lastFrameTime', 'recentAnimationFrameRate', '_view']);
|
|
1021
1061
|
|
|
1022
1062
|
// Create get-set macros
|
|
1023
|
-
macro.setGet(publicAPI, model, ['lightFollowCamera', 'enabled', 'enableRender', 'recognizeGestures', 'desiredUpdateRate', 'stillUpdateRate', 'picker', 'preventDefaultOnPointerDown', 'preventDefaultOnPointerUp', 'mouseScrollDebounceByPass']);
|
|
1063
|
+
macro.setGet(publicAPI, model, ['container', 'lightFollowCamera', 'enabled', 'enableRender', 'recognizeGestures', 'desiredUpdateRate', 'stillUpdateRate', 'picker', 'preventDefaultOnPointerDown', 'preventDefaultOnPointerUp', 'mouseScrollDebounceByPass']);
|
|
1024
1064
|
macro.moveToProtected(publicAPI, model, ['view']);
|
|
1025
1065
|
|
|
1026
1066
|
// For more macro methods, see "Sources/macros.js"
|
|
@@ -24,29 +24,30 @@ function widgetBehavior(publicAPI, model) {
|
|
|
24
24
|
};
|
|
25
25
|
publicAPI.handleEvent = callData => {
|
|
26
26
|
const manipulator = model.activeState?.getManipulator?.() ?? model.manipulator;
|
|
27
|
-
if (manipulator && model.activeState && model.activeState.getActive()) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const trailCircle = model.widgetState.addTrail();
|
|
43
|
-
trailCircle.set(model.activeState.get('origin', 'up', 'right', 'direction', 'scale1'));
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
publicAPI.invokeInteractionEvent();
|
|
47
|
-
return macro.EVENT_ABORT;
|
|
27
|
+
if (!(manipulator && model.activeState && model.activeState.getActive())) {
|
|
28
|
+
return macro.VOID;
|
|
29
|
+
}
|
|
30
|
+
const normal = model._camera.getDirectionOfProjection();
|
|
31
|
+
const up = model._camera.getViewUp();
|
|
32
|
+
const right = [];
|
|
33
|
+
vec3.cross(right, up, normal);
|
|
34
|
+
model.activeState.setUp(...up);
|
|
35
|
+
model.activeState.setRight(...right);
|
|
36
|
+
model.activeState.setDirection(...normal);
|
|
37
|
+
const {
|
|
38
|
+
worldCoords
|
|
39
|
+
} = manipulator.handleEvent(callData, model._apiSpecificRenderWindow);
|
|
40
|
+
if (!worldCoords?.length) {
|
|
41
|
+
return macro.VOID;
|
|
48
42
|
}
|
|
49
|
-
|
|
43
|
+
model.widgetState.setTrueOrigin(...worldCoords);
|
|
44
|
+
model.activeState.setOrigin(...worldCoords);
|
|
45
|
+
if (model.painting) {
|
|
46
|
+
const trailCircle = model.widgetState.addTrail();
|
|
47
|
+
trailCircle.set(model.activeState.get('origin', 'up', 'right', 'direction', 'scale1'));
|
|
48
|
+
}
|
|
49
|
+
publicAPI.invokeInteractionEvent();
|
|
50
|
+
return macro.EVENT_ABORT;
|
|
50
51
|
};
|
|
51
52
|
publicAPI.grabFocus = () => {
|
|
52
53
|
if (!model.hasFocus) {
|
|
@@ -75,7 +75,7 @@ export interface vtkResliceCursorWidget extends vtkAbstractWidgetFactory {
|
|
|
75
75
|
* Return an array of the first and the last possible points of the plane
|
|
76
76
|
* along its normal.
|
|
77
77
|
* @param {ViewTypes} viewType
|
|
78
|
-
* @returns {
|
|
78
|
+
* @returns {Array<Vector3>} two Vector3 arrays (first and last points)
|
|
79
79
|
*/
|
|
80
80
|
getPlaneExtremities(viewType: ViewTypes): Array<Vector3>;
|
|
81
81
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kitware/vtk.js",
|
|
3
|
-
"version": "29.4.
|
|
3
|
+
"version": "29.4.5",
|
|
4
4
|
"description": "Visualization Toolkit for the Web",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"3d",
|
|
@@ -118,7 +118,6 @@
|
|
|
118
118
|
"string-replace-loader": "3.1.0",
|
|
119
119
|
"style-loader": "3.3.1",
|
|
120
120
|
"tape": "5.5.3",
|
|
121
|
-
"tape-catch": "1.0.6",
|
|
122
121
|
"webpack": "5.76.0",
|
|
123
122
|
"webpack-bundle-analyzer": "4.5.0",
|
|
124
123
|
"webpack-cli": "4.9.2",
|