@kitware/vtk.js 30.7.0 → 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.
@@ -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.pokedRenderer;
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.pokedRenderer.getActiveCamera();
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.pokedRenderer.getViewProps().filter(prop => prop.isA('vtkImageSlice'));
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.pokedRenderer, model.state, 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.pokedRenderer, model.state, 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.pokedRenderer, callData.position);
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.pokedRenderer, callData.spinY);
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.pokedRenderer, callData.spinY, model.cachedMousePosition);
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.pokedRenderer, callData.position);
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.pokedRenderer, callData.key);
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.pokedRenderer, callData.key);
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.pokedRenderer, callData.key);
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.pokedRenderer, callData.scale);
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.pokedRenderer, callData.translation);
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.pokedRenderer, callData.rotation);
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.pokedRenderer;
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.pokedRenderer.getActiveCamera();
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.pokedRenderer, callData.scale / model.previousScale);
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.pokedRenderer.getActiveCamera();
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.pokedRenderer, viewFocus[0], viewFocus[1], viewFocus[2]);
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.pokedRenderer, viewFocus[0] + trans[0] - lastTrans[0], viewFocus[1] + trans[1] - lastTrans[1], focalDepth);
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.pokedRenderer, viewFocus[0], viewFocus[1], focalDepth);
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.pokedRenderer.updateLightsGeometryToFollowCamera();
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.pokedRenderer.getActiveCamera();
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.pokedRenderer, dyf);
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(false);
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.pokedRenderer.resetCamera();
76
+ model.getRenderer(callData).resetCamera();
76
77
  rwi.render();
77
78
  break;
78
79
  case 'w':
79
80
  case 'W':
80
- ac = callData.pokedRenderer.getActors();
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.pokedRenderer.getActors();
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.pokedRenderer.getActors();
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);
@@ -44,7 +44,7 @@ function vtkOpenGLImageCPRMapper(publicAPI, model) {
44
44
  model.currentRenderPass = null;
45
45
  model.openGLImageSlice = publicAPI.getFirstAncestorOfType('vtkOpenGLImageSlice');
46
46
  model._openGLRenderer = publicAPI.getFirstAncestorOfType('vtkOpenGLRenderer');
47
- model._openGLRenderWindow = model._openGLRenderer.getParent();
47
+ model._openGLRenderWindow = model._openGLRenderer.getLastAncestorOfType('vtkOpenGLRenderWindow');
48
48
  model.context = model._openGLRenderWindow.getContext();
49
49
  model.openGLCamera = model._openGLRenderer.getViewNodeFor(model._openGLRenderer.getRenderable().getActiveCamera());
50
50
  model.tris.setOpenGLRenderWindow(model._openGLRenderWindow);
@@ -60,7 +60,7 @@ function vtkOpenGLImageMapper(publicAPI, model) {
60
60
  model.currentRenderPass = null;
61
61
  model.openGLImageSlice = publicAPI.getFirstAncestorOfType('vtkOpenGLImageSlice');
62
62
  model._openGLRenderer = publicAPI.getFirstAncestorOfType('vtkOpenGLRenderer');
63
- model._openGLRenderWindow = model._openGLRenderer.getParent();
63
+ model._openGLRenderWindow = model._openGLRenderer.getLastAncestorOfType('vtkOpenGLRenderWindow');
64
64
  model.context = model._openGLRenderWindow.getContext();
65
65
  model.tris.setOpenGLRenderWindow(model._openGLRenderWindow);
66
66
  const ren = model._openGLRenderer.getRenderable();
@@ -60,7 +60,7 @@ function vtkOpenGLImageResliceMapper(publicAPI, model) {
60
60
  model._openGLRenderer = publicAPI.getFirstAncestorOfType('vtkOpenGLRenderer');
61
61
  const ren = model._openGLRenderer.getRenderable();
62
62
  model._openGLCamera = model._openGLRenderer.getViewNodeFor(ren.getActiveCamera());
63
- model._openGLRenderWindow = model._openGLRenderer.getParent();
63
+ model._openGLRenderWindow = model._openGLRenderer.getLastAncestorOfType('vtkOpenGLRenderWindow');
64
64
  model.context = model._openGLRenderWindow.getContext();
65
65
  model.tris.setOpenGLRenderWindow(model._openGLRenderWindow);
66
66
  }
@@ -15,7 +15,7 @@ function vtkOpenGLPixelSpaceCallbackMapper(publicAPI, model) {
15
15
  model.classHierarchy.push('vtkOpenGLPixelSpaceCallbackMapper');
16
16
  publicAPI.opaquePass = (prepass, renderPass) => {
17
17
  model._openGLRenderer = publicAPI.getFirstAncestorOfType('vtkOpenGLRenderer');
18
- model._openGLRenderWindow = model._openGLRenderer.getParent();
18
+ model._openGLRenderWindow = model._openGLRenderer.getLastAncestorOfType('vtkOpenGLRenderWindow');
19
19
  const aspectRatio = model._openGLRenderer.getAspectRatio();
20
20
  const camera = model._openGLRenderer ? model._openGLRenderer.getRenderable().getActiveCamera() : null;
21
21
  const tsize = model._openGLRenderer.getTiledSizeAndOrigin();
@@ -67,7 +67,7 @@ function vtkOpenGLPolyDataMapper(publicAPI, model) {
67
67
  model.currentRenderPass = null;
68
68
  model.openGLActor = publicAPI.getFirstAncestorOfType('vtkOpenGLActor');
69
69
  model._openGLRenderer = model.openGLActor.getFirstAncestorOfType('vtkOpenGLRenderer');
70
- model._openGLRenderWindow = model._openGLRenderer.getParent();
70
+ model._openGLRenderWindow = model._openGLRenderer.getLastAncestorOfType('vtkOpenGLRenderWindow');
71
71
  model.openGLCamera = model._openGLRenderer.getViewNodeFor(model._openGLRenderer.getRenderable().getActiveCamera());
72
72
  }
73
73
  };
@@ -40,7 +40,7 @@ function vtkOpenGLPolyDataMapper2D(publicAPI, model) {
40
40
  if (prepass) {
41
41
  model.openGLActor2D = publicAPI.getFirstAncestorOfType('vtkOpenGLActor2D');
42
42
  model._openGLRenderer = model.openGLActor2D.getFirstAncestorOfType('vtkOpenGLRenderer');
43
- model._openGLRenderWindow = model._openGLRenderer.getParent();
43
+ model._openGLRenderWindow = model._openGLRenderer.getLastAncestorOfType('vtkOpenGLRenderWindow');
44
44
  model.openGLCamera = model._openGLRenderer.getViewNodeFor(model._openGLRenderer.getRenderable().getActiveCamera());
45
45
  }
46
46
  };
@@ -37,7 +37,7 @@ function vtkOpenGLTexture(publicAPI, model) {
37
37
  } else {
38
38
  model._openGLRenderer = publicAPI.getFirstAncestorOfType('vtkOpenGLRenderer');
39
39
  // sync renderable properties
40
- model._openGLRenderWindow = model._openGLRenderer.getParent();
40
+ model._openGLRenderWindow = model._openGLRenderer.getLastAncestorOfType('vtkOpenGLRenderWindow');
41
41
  }
42
42
  model.context = model._openGLRenderWindow.getContext();
43
43
  if (model.renderable.getInterpolate()) {
@@ -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" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitware/vtk.js",
3
- "version": "30.7.0",
3
+ "version": "30.8.0",
4
4
  "description": "Visualization Toolkit for the Web",
5
5
  "keywords": [
6
6
  "3d",