@kitware/vtk.js 30.7.1 → 30.8.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/Interaction/Style/InteractorStyleImage.js +3 -3
- package/Interaction/Style/InteractorStyleManipulator.js +12 -12
- package/Interaction/Style/InteractorStyleTrackballCamera.js +10 -10
- package/Interaction/Widgets/OrientationMarkerWidget.d.ts +7 -0
- package/Interaction/Widgets/OrientationMarkerWidget.js +4 -3
- package/Rendering/Core/InteractorStyle.d.ts +15 -0
- package/Rendering/Core/InteractorStyle.js +6 -4
- package/Widgets/Widgets3D/InteractiveOrientationWidget/helpers.d.ts +73 -0
- package/Widgets/Widgets3D/InteractiveOrientationWidget/helpers.js +71 -0
- package/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -15,7 +15,7 @@ function vtkInteractorStyleImage(publicAPI, model) {
|
|
|
15
15
|
publicAPI.superHandleMouseMove = publicAPI.handleMouseMove;
|
|
16
16
|
publicAPI.handleMouseMove = callData => {
|
|
17
17
|
const pos = callData.position;
|
|
18
|
-
const renderer = callData
|
|
18
|
+
const renderer = model.getRenderer(callData);
|
|
19
19
|
switch (model.state) {
|
|
20
20
|
case States.IS_WINDOW_LEVEL:
|
|
21
21
|
publicAPI.windowLevel(renderer, pos);
|
|
@@ -94,7 +94,7 @@ function vtkInteractorStyleImage(publicAPI, model) {
|
|
|
94
94
|
|
|
95
95
|
//--------------------------------------------------------------------------
|
|
96
96
|
publicAPI.handleMouseWheel = callData => {
|
|
97
|
-
const camera = callData.
|
|
97
|
+
const camera = model.getRenderer(callData).getActiveCamera();
|
|
98
98
|
let distance = camera.getDistance();
|
|
99
99
|
distance += callData.spinY;
|
|
100
100
|
|
|
@@ -107,7 +107,7 @@ function vtkInteractorStyleImage(publicAPI, model) {
|
|
|
107
107
|
distance = range[1];
|
|
108
108
|
}
|
|
109
109
|
camera.setDistance(distance);
|
|
110
|
-
const props = callData.
|
|
110
|
+
const props = model.getRenderer(callData).getViewProps().filter(prop => prop.isA('vtkImageSlice'));
|
|
111
111
|
props.forEach(prop => {
|
|
112
112
|
if (prop.getMapper().isA('vtkImageResliceMapper')) {
|
|
113
113
|
const p = prop.getMapper().getSlicePlane();
|
|
@@ -251,7 +251,7 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
251
251
|
if (manipulator) {
|
|
252
252
|
// register the manipulator for this device
|
|
253
253
|
model.currentVRManipulators.set(ed.device, manipulator);
|
|
254
|
-
manipulator.onButton3D(publicAPI, ed
|
|
254
|
+
manipulator.onButton3D(publicAPI, model.getRenderer(ed), model.state, ed);
|
|
255
255
|
if (ed.pressed) {
|
|
256
256
|
publicAPI.startCameraPose();
|
|
257
257
|
} else {
|
|
@@ -271,7 +271,7 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
271
271
|
publicAPI.handleMove3D = ed => {
|
|
272
272
|
const manipulator = model.currentVRManipulators.get(ed.device);
|
|
273
273
|
if (manipulator && model.state === States.IS_CAMERA_POSE) {
|
|
274
|
-
manipulator.onMove3D(publicAPI, ed
|
|
274
|
+
manipulator.onMove3D(publicAPI, model.getRenderer(ed), model.state, ed);
|
|
275
275
|
}
|
|
276
276
|
};
|
|
277
277
|
|
|
@@ -292,7 +292,7 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
292
292
|
model.currentManipulator.setRotationFactor(model.rotationFactor);
|
|
293
293
|
}
|
|
294
294
|
model.currentManipulator.startInteraction();
|
|
295
|
-
model.currentManipulator.onButtonDown(model._interactor, callData
|
|
295
|
+
model.currentManipulator.onButtonDown(model._interactor, model.getRenderer(callData), callData.position);
|
|
296
296
|
model._interactor.requestAnimation(publicAPI.onButtonDown);
|
|
297
297
|
publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
|
|
298
298
|
} else {
|
|
@@ -373,7 +373,7 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
373
373
|
}
|
|
374
374
|
if (manipulator) {
|
|
375
375
|
model.currentWheelManipulator = manipulator;
|
|
376
|
-
model.currentWheelManipulator.onStartScroll(model._interactor, callData
|
|
376
|
+
model.currentWheelManipulator.onStartScroll(model._interactor, model.getRenderer(callData), callData.spinY);
|
|
377
377
|
model.currentWheelManipulator.startInteraction();
|
|
378
378
|
model._interactor.requestAnimation(publicAPI.handleStartMouseWheel);
|
|
379
379
|
publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
|
|
@@ -399,7 +399,7 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
399
399
|
//-------------------------------------------------------------------------
|
|
400
400
|
publicAPI.handleMouseWheel = callData => {
|
|
401
401
|
if (model.currentWheelManipulator && model.currentWheelManipulator.onScroll) {
|
|
402
|
-
model.currentWheelManipulator.onScroll(model._interactor, callData
|
|
402
|
+
model.currentWheelManipulator.onScroll(model._interactor, model.getRenderer(callData), callData.spinY, model.cachedMousePosition);
|
|
403
403
|
publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
|
|
404
404
|
}
|
|
405
405
|
};
|
|
@@ -408,7 +408,7 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
408
408
|
publicAPI.handleMouseMove = callData => {
|
|
409
409
|
model.cachedMousePosition = callData.position;
|
|
410
410
|
if (model.currentManipulator && model.currentManipulator.onMouseMove) {
|
|
411
|
-
model.currentManipulator.onMouseMove(model._interactor, callData
|
|
411
|
+
model.currentManipulator.onMouseMove(model._interactor, model.getRenderer(callData), callData.position);
|
|
412
412
|
publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
|
|
413
413
|
}
|
|
414
414
|
};
|
|
@@ -418,7 +418,7 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
418
418
|
//-------------------------------------------------------------------------
|
|
419
419
|
publicAPI.handleKeyPress = callData => {
|
|
420
420
|
model.keyboardManipulators.filter(m => m.onKeyPress).forEach(manipulator => {
|
|
421
|
-
manipulator.onKeyPress(model._interactor, callData
|
|
421
|
+
manipulator.onKeyPress(model._interactor, model.getRenderer(callData), callData.key);
|
|
422
422
|
publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
|
|
423
423
|
});
|
|
424
424
|
};
|
|
@@ -426,7 +426,7 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
426
426
|
//-------------------------------------------------------------------------
|
|
427
427
|
publicAPI.handleKeyDown = callData => {
|
|
428
428
|
model.keyboardManipulators.filter(m => m.onKeyDown).forEach(manipulator => {
|
|
429
|
-
manipulator.onKeyDown(model._interactor, callData
|
|
429
|
+
manipulator.onKeyDown(model._interactor, model.getRenderer(callData), callData.key);
|
|
430
430
|
publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
|
|
431
431
|
});
|
|
432
432
|
};
|
|
@@ -434,7 +434,7 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
434
434
|
//-------------------------------------------------------------------------
|
|
435
435
|
publicAPI.handleKeyUp = callData => {
|
|
436
436
|
model.keyboardManipulators.filter(m => m.onKeyUp).forEach(manipulator => {
|
|
437
|
-
manipulator.onKeyUp(model._interactor, callData
|
|
437
|
+
manipulator.onKeyUp(model._interactor, model.getRenderer(callData), callData.key);
|
|
438
438
|
publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
|
|
439
439
|
});
|
|
440
440
|
};
|
|
@@ -539,7 +539,7 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
539
539
|
while (count--) {
|
|
540
540
|
const manipulator = model.gestureManipulators[count];
|
|
541
541
|
if (manipulator && manipulator.isPinchEnabled()) {
|
|
542
|
-
manipulator.onPinch(model._interactor, callData
|
|
542
|
+
manipulator.onPinch(model._interactor, model.getRenderer(callData), callData.scale);
|
|
543
543
|
actionCount++;
|
|
544
544
|
}
|
|
545
545
|
}
|
|
@@ -555,7 +555,7 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
555
555
|
while (count--) {
|
|
556
556
|
const manipulator = model.gestureManipulators[count];
|
|
557
557
|
if (manipulator && manipulator.isPanEnabled()) {
|
|
558
|
-
manipulator.onPan(model._interactor, callData
|
|
558
|
+
manipulator.onPan(model._interactor, model.getRenderer(callData), callData.translation);
|
|
559
559
|
actionCount++;
|
|
560
560
|
}
|
|
561
561
|
}
|
|
@@ -571,7 +571,7 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
571
571
|
while (count--) {
|
|
572
572
|
const manipulator = model.gestureManipulators[count];
|
|
573
573
|
if (manipulator && manipulator.isRotateEnabled()) {
|
|
574
|
-
manipulator.onRotate(model._interactor, callData
|
|
574
|
+
manipulator.onRotate(model._interactor, model.getRenderer(callData), callData.rotation);
|
|
575
575
|
actionCount++;
|
|
576
576
|
}
|
|
577
577
|
}
|
|
@@ -21,7 +21,7 @@ function vtkInteractorStyleTrackballCamera(publicAPI, model) {
|
|
|
21
21
|
// Public API methods
|
|
22
22
|
publicAPI.handleMouseMove = callData => {
|
|
23
23
|
const pos = callData.position;
|
|
24
|
-
const renderer = callData
|
|
24
|
+
const renderer = model.getRenderer(callData);
|
|
25
25
|
switch (model.state) {
|
|
26
26
|
case States.IS_ROTATE:
|
|
27
27
|
publicAPI.handleMouseRotate(renderer, pos);
|
|
@@ -73,7 +73,7 @@ function vtkInteractorStyleTrackballCamera(publicAPI, model) {
|
|
|
73
73
|
publicAPI.updateCameraPose = ed => {
|
|
74
74
|
// move the world in the direction of the
|
|
75
75
|
// controller
|
|
76
|
-
const camera = ed.
|
|
76
|
+
const camera = model.getRenderer(ed).getActiveCamera();
|
|
77
77
|
const oldTrans = camera.getPhysicalTranslation();
|
|
78
78
|
|
|
79
79
|
// look at the y axis to determine how fast / what direction to move
|
|
@@ -169,25 +169,25 @@ function vtkInteractorStyleTrackballCamera(publicAPI, model) {
|
|
|
169
169
|
|
|
170
170
|
//----------------------------------------------------------------------------
|
|
171
171
|
publicAPI.handlePinch = callData => {
|
|
172
|
-
publicAPI.dollyByFactor(callData
|
|
172
|
+
publicAPI.dollyByFactor(model.getRenderer(callData), callData.scale / model.previousScale);
|
|
173
173
|
model.previousScale = callData.scale;
|
|
174
174
|
};
|
|
175
175
|
|
|
176
176
|
//----------------------------------------------------------------------------
|
|
177
177
|
publicAPI.handlePan = callData => {
|
|
178
|
-
const camera = callData.
|
|
178
|
+
const camera = model.getRenderer(callData).getActiveCamera();
|
|
179
179
|
|
|
180
180
|
// Calculate the focal depth since we'll be using it a lot
|
|
181
181
|
let viewFocus = camera.getFocalPoint();
|
|
182
|
-
viewFocus = publicAPI.computeWorldToDisplay(callData
|
|
182
|
+
viewFocus = publicAPI.computeWorldToDisplay(model.getRenderer(callData), viewFocus[0], viewFocus[1], viewFocus[2]);
|
|
183
183
|
const focalDepth = viewFocus[2];
|
|
184
184
|
const trans = callData.translation;
|
|
185
185
|
const lastTrans = model.previousTranslation;
|
|
186
|
-
const newPickPoint = publicAPI.computeDisplayToWorld(callData
|
|
186
|
+
const newPickPoint = publicAPI.computeDisplayToWorld(model.getRenderer(callData), viewFocus[0] + trans[0] - lastTrans[0], viewFocus[1] + trans[1] - lastTrans[1], focalDepth);
|
|
187
187
|
|
|
188
188
|
// Has to recalc old mouse point since the viewport has moved,
|
|
189
189
|
// so can't move it outside the loop
|
|
190
|
-
const oldPickPoint = publicAPI.computeDisplayToWorld(callData
|
|
190
|
+
const oldPickPoint = publicAPI.computeDisplayToWorld(model.getRenderer(callData), viewFocus[0], viewFocus[1], focalDepth);
|
|
191
191
|
|
|
192
192
|
// Camera motion is reversed
|
|
193
193
|
const motionVector = [];
|
|
@@ -199,7 +199,7 @@ function vtkInteractorStyleTrackballCamera(publicAPI, model) {
|
|
|
199
199
|
camera.setFocalPoint(motionVector[0] + viewFocus[0], motionVector[1] + viewFocus[1], motionVector[2] + viewFocus[2]);
|
|
200
200
|
camera.setPosition(motionVector[0] + viewPoint[0], motionVector[1] + viewPoint[1], motionVector[2] + viewPoint[2]);
|
|
201
201
|
if (model._interactor.getLightFollowCamera()) {
|
|
202
|
-
callData.
|
|
202
|
+
model.getRenderer(callData).updateLightsGeometryToFollowCamera();
|
|
203
203
|
}
|
|
204
204
|
camera.orthogonalizeViewUp();
|
|
205
205
|
model.previousTranslation = callData.translation;
|
|
@@ -207,7 +207,7 @@ function vtkInteractorStyleTrackballCamera(publicAPI, model) {
|
|
|
207
207
|
|
|
208
208
|
//----------------------------------------------------------------------------
|
|
209
209
|
publicAPI.handleRotate = callData => {
|
|
210
|
-
const camera = callData.
|
|
210
|
+
const camera = model.getRenderer(callData).getActiveCamera();
|
|
211
211
|
camera.roll(callData.rotation - model.previousRotation);
|
|
212
212
|
camera.orthogonalizeViewUp();
|
|
213
213
|
model.previousRotation = callData.rotation;
|
|
@@ -306,7 +306,7 @@ function vtkInteractorStyleTrackballCamera(publicAPI, model) {
|
|
|
306
306
|
//----------------------------------------------------------------------------
|
|
307
307
|
publicAPI.handleMouseWheel = callData => {
|
|
308
308
|
const dyf = 1 - callData.spinY / model.zoomFactor;
|
|
309
|
-
publicAPI.dollyByFactor(callData
|
|
309
|
+
publicAPI.dollyByFactor(model.getRenderer(callData), dyf);
|
|
310
310
|
};
|
|
311
311
|
|
|
312
312
|
//----------------------------------------------------------------------------
|
|
@@ -145,6 +145,13 @@ export interface vtkOrientationMarkerWidget extends vtkObject {
|
|
|
145
145
|
* Updates the orientation widget viewport size.
|
|
146
146
|
*/
|
|
147
147
|
updateViewport(): void;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* An instance of this class will spawn its own renderer, by default non interactive.
|
|
151
|
+
* This behavior is configurable through the interactiveRenderer property when initializing the instance.
|
|
152
|
+
* @returns true if the renderer was created as interactive, false otherwise.
|
|
153
|
+
*/
|
|
154
|
+
getInteractiveRenderer(): boolean;
|
|
148
155
|
}
|
|
149
156
|
|
|
150
157
|
/**
|
|
@@ -123,7 +123,7 @@ function vtkOrientationMarkerWidget(publicAPI, model) {
|
|
|
123
123
|
}
|
|
124
124
|
// Highest number is foreground
|
|
125
125
|
selfRenderer.setLayer(renderWindow.getNumberOfLayers() - 1);
|
|
126
|
-
selfRenderer.setInteractive(
|
|
126
|
+
selfRenderer.setInteractive(model.interactiveRenderer);
|
|
127
127
|
selfRenderer.addViewProp(model.actor);
|
|
128
128
|
model.actor.setVisibility(true);
|
|
129
129
|
onCameraChangedSub = ren.onEvent(event => {
|
|
@@ -236,7 +236,8 @@ const DEFAULT_VALUES = {
|
|
|
236
236
|
viewportSize: 0.2,
|
|
237
237
|
minPixelSize: 50,
|
|
238
238
|
maxPixelSize: 200,
|
|
239
|
-
parentRenderer: null
|
|
239
|
+
parentRenderer: null,
|
|
240
|
+
interactiveRenderer: false
|
|
240
241
|
};
|
|
241
242
|
|
|
242
243
|
// ----------------------------------------------------------------------------
|
|
@@ -247,7 +248,7 @@ function extend(publicAPI, model) {
|
|
|
247
248
|
|
|
248
249
|
// Build VTK API
|
|
249
250
|
macro.obj(publicAPI, model);
|
|
250
|
-
macro.get(publicAPI, model, ['enabled', 'viewportCorner', 'viewportSize']);
|
|
251
|
+
macro.get(publicAPI, model, ['enabled', 'viewportCorner', 'viewportSize', 'interactiveRenderer']);
|
|
251
252
|
|
|
252
253
|
// NOTE: setting these while the widget is enabled will
|
|
253
254
|
// not update the widget.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { EventHandler, vtkSubscription } from './../../interfaces';
|
|
2
|
+
import { Nullable } from './../../types';
|
|
2
3
|
import vtkInteractorObserver from './InteractorObserver';
|
|
4
|
+
import vtkRenderer from './Renderer';
|
|
3
5
|
|
|
4
6
|
export interface vtkInteractorStyle extends vtkInteractorObserver {
|
|
5
7
|
/**
|
|
@@ -210,6 +212,19 @@ export interface vtkInteractorStyle extends vtkInteractorObserver {
|
|
|
210
212
|
* Handles a keypress.
|
|
211
213
|
*/
|
|
212
214
|
handleKeyPress(callData: unknown): void;
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Explicitly defines a renderer to be used for event handling.
|
|
218
|
+
* If never called or called with null, the pokedRenderer of the event will be used.
|
|
219
|
+
*
|
|
220
|
+
* @param {Nullable<vtkRenderer>} renderer
|
|
221
|
+
*/
|
|
222
|
+
setFocusedRenderer(renderer: Nullable<vtkRenderer>): boolean;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Get the renderer used for event handling, returns null if not set.
|
|
226
|
+
*/
|
|
227
|
+
getFocusedRenderer(): Nullable<vtkRenderer>;
|
|
213
228
|
}
|
|
214
229
|
|
|
215
230
|
export interface IInteractorStyleInitialValues {
|
|
@@ -64,6 +64,7 @@ function vtkInteractorStyle(publicAPI, model) {
|
|
|
64
64
|
model._interactor.render();
|
|
65
65
|
};
|
|
66
66
|
});
|
|
67
|
+
model.getRenderer = callData => model.focusedRenderer || callData.pokedRenderer;
|
|
67
68
|
|
|
68
69
|
//----------------------------------------------------------------------------
|
|
69
70
|
publicAPI.handleKeyPress = callData => {
|
|
@@ -72,12 +73,12 @@ function vtkInteractorStyle(publicAPI, model) {
|
|
|
72
73
|
switch (callData.key) {
|
|
73
74
|
case 'r':
|
|
74
75
|
case 'R':
|
|
75
|
-
callData.
|
|
76
|
+
model.getRenderer(callData).resetCamera();
|
|
76
77
|
rwi.render();
|
|
77
78
|
break;
|
|
78
79
|
case 'w':
|
|
79
80
|
case 'W':
|
|
80
|
-
ac = callData.
|
|
81
|
+
ac = model.getRenderer(callData).getActors();
|
|
81
82
|
ac.forEach(anActor => {
|
|
82
83
|
const prop = anActor.getProperty();
|
|
83
84
|
if (prop.setRepresentationToWireframe) {
|
|
@@ -88,7 +89,7 @@ function vtkInteractorStyle(publicAPI, model) {
|
|
|
88
89
|
break;
|
|
89
90
|
case 's':
|
|
90
91
|
case 'S':
|
|
91
|
-
ac = callData.
|
|
92
|
+
ac = model.getRenderer(callData).getActors();
|
|
92
93
|
ac.forEach(anActor => {
|
|
93
94
|
const prop = anActor.getProperty();
|
|
94
95
|
if (prop.setRepresentationToSurface) {
|
|
@@ -99,7 +100,7 @@ function vtkInteractorStyle(publicAPI, model) {
|
|
|
99
100
|
break;
|
|
100
101
|
case 'v':
|
|
101
102
|
case 'V':
|
|
102
|
-
ac = callData.
|
|
103
|
+
ac = model.getRenderer(callData).getActors();
|
|
103
104
|
ac.forEach(anActor => {
|
|
104
105
|
const prop = anActor.getProperty();
|
|
105
106
|
if (prop.setRepresentationToPoints) {
|
|
@@ -130,6 +131,7 @@ function extend(publicAPI, model) {
|
|
|
130
131
|
|
|
131
132
|
// Inheritance
|
|
132
133
|
vtkInteractorObserver.extend(publicAPI, model, initialValues);
|
|
134
|
+
macro.setGet(publicAPI, model, ['focusedRenderer']);
|
|
133
135
|
|
|
134
136
|
// Object specific methods
|
|
135
137
|
vtkInteractorStyle(publicAPI, model);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import vtkAbstractWidget from '../../../Widgets/Core/AbstractWidget';
|
|
2
|
+
import vtkCamera from '../../../Rendering/Core/Camera';
|
|
3
|
+
import vtkInteractiveOrientationWidget from '../InteractiveOrientationWidget';
|
|
4
|
+
import vtkOrientationMarkerWidget from '../../../Interaction/Widgets/OrientationMarkerWidget';
|
|
5
|
+
import vtkRenderer from '../../../Rendering/Core/Renderer';
|
|
6
|
+
import vtkRenderWindowInteractor from '../../../Rendering/Core/RenderWindowInteractor';
|
|
7
|
+
import vtkWidgetManager from '../../../Widgets/Core/WidgetManager';
|
|
8
|
+
import { vtkSubscription } from '../../../interfaces';
|
|
9
|
+
import { Bounds, Vector3 } from '../../../types';
|
|
10
|
+
|
|
11
|
+
export function majorAxis(
|
|
12
|
+
vec3: Vector3,
|
|
13
|
+
idxA: number,
|
|
14
|
+
idxB: number
|
|
15
|
+
): [number, number, number];
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create a new vtkOrientationMarkerWidget instance from the provided interactor and parentRenderer and sensible defaults.
|
|
19
|
+
*
|
|
20
|
+
* @param {vtkRenderWindowInteractor} interactor
|
|
21
|
+
* @param {vtkRenderer} parentRenderer
|
|
22
|
+
* @returns {vtkOrientationMarkerWidget}
|
|
23
|
+
*/
|
|
24
|
+
export function createOrientationMarkerWidget(
|
|
25
|
+
interactor: vtkRenderWindowInteractor,
|
|
26
|
+
parentRenderer: vtkRenderer
|
|
27
|
+
): vtkOrientationMarkerWidget;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Create a new vtkInteractiveOrientationWidget instance and place it at the given bounds.
|
|
31
|
+
*
|
|
32
|
+
* @param {Bounds} bounds
|
|
33
|
+
* @returns {vtkInteractiveOrientationWidget}
|
|
34
|
+
*/
|
|
35
|
+
export function createInteractiveOrientationWidget(
|
|
36
|
+
bounds: Bounds
|
|
37
|
+
): vtkInteractiveOrientationWidget;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Create a new vtkOrientationMarkerWidget alongside with a new vtkInteractiveOrientationWidget with sensible defaults.
|
|
41
|
+
*
|
|
42
|
+
* @param {vtkWidgetManager} widgetManager
|
|
43
|
+
* @param {vtkRenderWindowInteractor} interactor
|
|
44
|
+
* @param {vtkRenderer} mainRenderer
|
|
45
|
+
* @returns {Object} the constructed widget instances
|
|
46
|
+
*/
|
|
47
|
+
export function createInteractiveOrientationMarkerWidget(
|
|
48
|
+
widgetManager: vtkWidgetManager,
|
|
49
|
+
interactor: vtkRenderWindowInteractor,
|
|
50
|
+
mainRenderer: vtkRenderer
|
|
51
|
+
): {
|
|
52
|
+
interactiveOrientationWidget: vtkInteractiveOrientationWidget;
|
|
53
|
+
orientationMarkerWidget: vtkOrientationMarkerWidget;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Listen to OrientationChange events on the given view widget.
|
|
58
|
+
* The event handler will align the provided camera and update the provided vtkOrientationMarkerWidget instance.
|
|
59
|
+
*
|
|
60
|
+
* @param {vtkAbstractWidget} viewWidget Must be a vtkInteractiveOrientationWidget view widget
|
|
61
|
+
* @param {vtkCamera} camera The camera instance to upate when orientation changes
|
|
62
|
+
* @param {vtkOrientationMarkerWidget} orientationMarkerWidget The instance to update when orientation changes
|
|
63
|
+
* @param {vtkWidgetManager} widgetManager
|
|
64
|
+
* @param {Function} render A callback that should render the view
|
|
65
|
+
* @returns {vtkSubscription} the corresponding event subscription, can be used to unsubscribe from the event
|
|
66
|
+
*/
|
|
67
|
+
export function alignCameraOnViewWidgetOrientationChange(
|
|
68
|
+
viewWidget: vtkAbstractWidget,
|
|
69
|
+
camera: vtkCamera,
|
|
70
|
+
orientationMarkerWidget: vtkOrientationMarkerWidget,
|
|
71
|
+
widgetManager: vtkWidgetManager,
|
|
72
|
+
render: () => void
|
|
73
|
+
): vtkSubscription;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as vtkMath from '@kitware/vtk.js/Common/Core/Math';
|
|
2
|
+
import vtkOrientationMarkerWidget from '@kitware/vtk.js/Interaction/Widgets/OrientationMarkerWidget';
|
|
3
|
+
import vtkAxesActor from '@kitware/vtk.js/Rendering/Core/AxesActor';
|
|
4
|
+
import vtkInteractiveOrientationWidget from '@kitware/vtk.js/Widgets/Widgets3D/InteractiveOrientationWidget';
|
|
5
|
+
|
|
6
|
+
function majorAxis(vec3, idxA, idxB) {
|
|
7
|
+
const axis = [0, 0, 0];
|
|
8
|
+
const idx = Math.abs(vec3[idxA]) > Math.abs(vec3[idxB]) ? idxA : idxB;
|
|
9
|
+
const value = vec3[idx] > 0 ? 1 : -1;
|
|
10
|
+
axis[idx] = value;
|
|
11
|
+
return axis;
|
|
12
|
+
}
|
|
13
|
+
function createOrientationMarkerWidget(interactor, parentRenderer) {
|
|
14
|
+
const axes = vtkAxesActor.newInstance();
|
|
15
|
+
const orientationWidget = vtkOrientationMarkerWidget.newInstance({
|
|
16
|
+
actor: axes,
|
|
17
|
+
interactor,
|
|
18
|
+
interactiveRenderer: true,
|
|
19
|
+
viewportSize: 0.1,
|
|
20
|
+
minPixelSize: 100,
|
|
21
|
+
maxPixelSize: 300,
|
|
22
|
+
parentRenderer
|
|
23
|
+
});
|
|
24
|
+
orientationWidget.setEnabled(true);
|
|
25
|
+
orientationWidget.setViewportCorner(vtkOrientationMarkerWidget.Corners.BOTTOM_LEFT);
|
|
26
|
+
return orientationWidget;
|
|
27
|
+
}
|
|
28
|
+
function createInteractiveOrientationWidget(bounds) {
|
|
29
|
+
const widget = vtkInteractiveOrientationWidget.newInstance();
|
|
30
|
+
widget.placeWidget(bounds);
|
|
31
|
+
widget.setBounds(bounds.map(v => v * 0.45));
|
|
32
|
+
return widget;
|
|
33
|
+
}
|
|
34
|
+
function createInteractiveOrientationMarkerWidget(widgetManager, interactor, mainRenderer) {
|
|
35
|
+
const orientationMarkerWidget = createOrientationMarkerWidget(interactor, mainRenderer);
|
|
36
|
+
interactor.getInteractorStyle().setFocusedRenderer(mainRenderer);
|
|
37
|
+
widgetManager.setRenderer(orientationMarkerWidget.getRenderer());
|
|
38
|
+
const widget = createInteractiveOrientationWidget(orientationMarkerWidget.getActor().getBounds());
|
|
39
|
+
return {
|
|
40
|
+
interactiveOrientationWidget: widget,
|
|
41
|
+
orientationMarkerWidget
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function alignCameraOnViewWidgetOrientationChange(viewWidget, camera, orientationMarkerWidget, widgetManager, render) {
|
|
45
|
+
return viewWidget.onOrientationChange(_ref => {
|
|
46
|
+
let {
|
|
47
|
+
up,
|
|
48
|
+
direction,
|
|
49
|
+
action,
|
|
50
|
+
event
|
|
51
|
+
} = _ref;
|
|
52
|
+
const focalPoint = camera.getFocalPoint();
|
|
53
|
+
const position = camera.getPosition();
|
|
54
|
+
const viewUp = camera.getViewUp();
|
|
55
|
+
const distance = Math.sqrt(vtkMath.distance2BetweenPoints(position, focalPoint));
|
|
56
|
+
camera.setPosition(focalPoint[0] + direction[0] * distance, focalPoint[1] + direction[1] * distance, focalPoint[2] + direction[2] * distance);
|
|
57
|
+
if (direction[0]) {
|
|
58
|
+
camera.setViewUp(majorAxis(viewUp, 1, 2));
|
|
59
|
+
}
|
|
60
|
+
if (direction[1]) {
|
|
61
|
+
camera.setViewUp(majorAxis(viewUp, 0, 2));
|
|
62
|
+
}
|
|
63
|
+
if (direction[2]) {
|
|
64
|
+
camera.setViewUp(majorAxis(viewUp, 0, 1));
|
|
65
|
+
}
|
|
66
|
+
orientationMarkerWidget.updateMarkerOrientation();
|
|
67
|
+
render();
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { alignCameraOnViewWidgetOrientationChange, createInteractiveOrientationMarkerWidget, createInteractiveOrientationWidget, createOrientationMarkerWidget, majorAxis };
|
package/index.d.ts
CHANGED
|
@@ -234,6 +234,7 @@
|
|
|
234
234
|
/// <reference path="./Widgets/Manipulators/PlaneManipulator.d.ts" />
|
|
235
235
|
/// <reference path="./Widgets/Manipulators/TrackballManipulator.d.ts" />
|
|
236
236
|
/// <reference path="./Widgets/Representations/WidgetRepresentation.d.ts" />
|
|
237
|
+
/// <reference path="./Widgets/Widgets3D/InteractiveOrientationWidget/helpers.d.ts" />
|
|
237
238
|
/// <reference path="./Widgets/Widgets3D/InteractiveOrientationWidget.d.ts" />
|
|
238
239
|
/// <reference path="./Widgets/Widgets3D/ResliceCursorWidget/Constants.d.ts" />
|
|
239
240
|
/// <reference path="./Widgets/Widgets3D/ResliceCursorWidget/behavior.d.ts" />
|