1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://www.centreleonberard.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18 #include "vvInteractorStyleNavigator.h"
20 #include "vtkAbstractPropPicker.h"
21 #include "vtkAssemblyPath.h"
22 #include "vtkCallbackCommand.h"
24 #include "vtkObjectFactory.h"
25 #include "vtkCamera.h"
26 #include "vtkRenderWindow.h"
27 #include "vtkRenderWindowInteractor.h"
28 #include "vtkRenderer.h"
29 #include <vtkRendererCollection.h>
30 #include "clitkCommon.h"
32 vtkStandardNewMacro(vvInteractorStyleNavigator);
34 //----------------------------------------------------------------------------
35 vvInteractorStyleNavigator::vvInteractorStyleNavigator()
37 this->WindowLevelStartPosition[0] = 0;
38 this->WindowLevelStartPosition[1] = 0;
40 this->WindowLevelCurrentPosition[0] = 0;
41 this->WindowLevelCurrentPosition[1] = 0;
43 this->MotionFactor = 10.0;
46 //----------------------------------------------------------------------------
47 vvInteractorStyleNavigator::~vvInteractorStyleNavigator()
52 void vvInteractorStyleNavigator::FindPokedRenderer(int dummy1,int dummy2)
54 vtkRenderWindow * renwin=this->GetInteractor()->GetRenderWindow();
55 renwin->GetRenderers()->InitTraversal();
57 vtkRenderer* current = renwin->GetRenderers()->GetNextItem();
58 if (current==NULL || current->GetDraw()) {
59 CurrentRenderer=current;
65 //----------------------------------------------------------------------------
66 void vvInteractorStyleNavigator::StartWindowLevel()
68 if (this->State != VTKIS_NONE) {
71 this->StartState(VTKIS_WINDOW_LEVEL);
72 this->InvokeEvent(vtkCommand::StartWindowLevelEvent,this);
75 //----------------------------------------------------------------------------
76 void vvInteractorStyleNavigator::EndWindowLevel()
78 if (this->State != VTKIS_WINDOW_LEVEL) {
81 this->InvokeEvent(vtkCommand::EndWindowLevelEvent, this);
85 //----------------------------------------------------------------------------
86 void vvInteractorStyleNavigator::StartPick()
88 if (this->State != VTKIS_NONE) {
91 this->StartState(VTKIS_PICK_NEW);
92 this->InvokeEvent(vtkCommand::StartPickEvent, this);
95 //----------------------------------------------------------------------------
96 void vvInteractorStyleNavigator::EndPick()
98 if (this->State != VTKIS_PICK_NEW) {
101 this->InvokeEvent(vtkCommand::EndPickEvent, this);
105 //----------------------------------------------------------------------------
106 void vvInteractorStyleNavigator::OnMouseMove()
108 int x = this->Interactor->GetEventPosition()[0];
109 int y = this->Interactor->GetEventPosition()[1];
111 switch (this->State) {
112 case VTKIS_WINDOW_LEVEL:
113 this->FindPokedRenderer(x, y);
115 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
119 this->FindPokedRenderer(x, y);
121 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
125 this->FindPokedRenderer(x, y);
127 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
131 this->FindPokedRenderer(x, y);
133 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
137 this->InvokeEvent(vtkCommand::UserEvent, NULL);
141 // Call parent to handle all other states and perform additional work
145 void vvInteractorStyleNavigator::OnEnter()
147 // int x = this->Interactor->GetEventPosition()[0];
148 //int y = this->Interactor->GetEventPosition()[1];
150 switch (this->State) {
151 case VTKIS_WINDOW_LEVEL:
161 this->InvokeEvent(vtkCommand::EnterEvent, NULL);
165 // Call parent to handle all other states and perform additional work
169 //----------------------------------------------------------------------------
170 void vvInteractorStyleNavigator::OnLeave()
172 // int x = this->Interactor->GetEventPosition()[0];
173 //int y = this->Interactor->GetEventPosition()[1];
175 switch (this->State) {
176 case VTKIS_WINDOW_LEVEL:
186 this->InvokeEvent(vtkCommand::LeaveEvent, NULL);
190 // Call parent to handle all other states and perform additional work
194 //----------------------------------------------------------------------------
195 void vvInteractorStyleNavigator::OnRightButtonDown()
197 int x = this->Interactor->GetEventPosition()[0];
198 int y = this->Interactor->GetEventPosition()[1];
200 this->FindPokedRenderer(x, y);
201 if (this->CurrentRenderer == NULL) {
205 // Redefine this button to handle window/level
206 this->GrabFocus(this->EventCallbackCommand);
207 if (!this->Interactor->GetShiftKey() && !this->Interactor->GetControlKey()) {
208 this->WindowLevelStartPosition[0] = x;
209 this->WindowLevelStartPosition[1] = y;
210 this->StartWindowLevel();
213 // The rest of the button + key combinations remain the same
216 this->Superclass::OnRightButtonDown();
220 //----------------------------------------------------------------------------
221 void vvInteractorStyleNavigator::OnRightButtonUp()
223 switch (this->State) {
224 case VTKIS_WINDOW_LEVEL:
225 this->EndWindowLevel();
226 if ( this->Interactor ) {
227 this->ReleaseFocus();
232 // Call parent to handle all other states and perform additional work
234 this->Superclass::OnRightButtonUp();
237 //----------------------------------------------------------------------------
238 void vvInteractorStyleNavigator::OnLeftButtonDown()
240 int x = this->Interactor->GetEventPosition()[0];
241 int y = this->Interactor->GetEventPosition()[1];
243 this->FindPokedRenderer(x, y);
244 if (this->CurrentRenderer == NULL) {
248 // Redefine this button to handle pick
249 this->GrabFocus(this->EventCallbackCommand);
250 if (this->Interactor->GetShiftKey()) {
251 this->OnMiddleButtonDown();
253 else if (!this->Interactor->GetControlKey()) {
257 // The rest of the button + key combinations remain the same
260 this->Superclass::OnLeftButtonDown();
264 //----------------------------------------------------------------------------
265 void vvInteractorStyleNavigator::OnLeftButtonUp()
267 // DD("OnLeftButtonUp");
268 switch (this->State) {
271 if ( this->Interactor ) {
272 this->ReleaseFocus();
276 this->OnMiddleButtonUp();
280 // Call parent to handle all other states and perform additional work
282 this->Superclass::OnLeftButtonUp();
285 //----------------------------------------------------------------------------
286 void vvInteractorStyleNavigator::OnMiddleButtonDown()
288 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
289 this->Interactor->GetEventPosition()[1]);
290 if (this->CurrentRenderer == NULL) {
293 this->CurrentRenderer->GetRenderWindow()->SetCurrentCursor(8);
294 this->GrabFocus(this->EventCallbackCommand);
298 //----------------------------------------------------------------------------
299 void vvInteractorStyleNavigator::OnMiddleButtonUp()
301 switch (this->State) {
304 if ( this->Interactor ) {
305 this->Interactor->GetRenderWindow()->SetCurrentCursor(0);
306 this->ReleaseFocus();
312 //----------------------------------------------------------------------------
313 void vvInteractorStyleNavigator::OnChar()
315 vtkRenderWindowInteractor *rwi = this->Interactor;
317 switch (rwi->GetKeyCode()) {
320 this->AnimState = VTKIS_ANIM_ON;
321 this->AnimState = VTKIS_ANIM_OFF;
327 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
328 this->Interactor->GetEventPosition()[1]);
329 if (this->CurrentRenderer == NULL) {
332 this->GrabFocus(this->EventCallbackCommand);
335 this->Dolly(pow((double)1.1, factor));
337 this->ReleaseFocus();
342 this->FindPokedRenderer(rwi->GetEventPosition()[0],
343 rwi->GetEventPosition()[1]);
344 if (this->CurrentRenderer == NULL) {
347 this->GrabFocus(this->EventCallbackCommand);
350 this->Dolly(pow((double)1.1, factor));
352 this->ReleaseFocus();
356 // Disable StereoVision
360 //Do nothing, this is handled in vvSlicerManagerCommand
363 //SR: we don't use the default vtk keys => removed to avoid conflicts
364 //this->Superclass::OnChar();
369 //----------------------------------------------------------------------------
370 void vvInteractorStyleNavigator::OnMouseWheelForward()
372 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
373 this->Interactor->GetEventPosition()[1]);
374 if (this->CurrentRenderer == NULL) {
377 this->GrabFocus(this->EventCallbackCommand);
378 if (this->Interactor->GetControlKey()) {
380 double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
381 this->Dolly(pow((double)1.1, factor));
384 this->ReleaseFocus();
385 this->InvokeEvent(vtkCommand::MouseWheelForwardEvent, this);
388 //----------------------------------------------------------------------------
389 void vvInteractorStyleNavigator::OnMouseWheelBackward()
391 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
392 this->Interactor->GetEventPosition()[1]);
393 if (this->CurrentRenderer == NULL) {
397 this->GrabFocus(this->EventCallbackCommand);
398 if (this->Interactor->GetControlKey()) {
400 double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
401 this->Dolly(pow((double)1.1, factor));
404 this->ReleaseFocus();
405 this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, this);
409 //----------------------------------------------------------------------------
410 void vvInteractorStyleNavigator::WindowLevel()
412 vtkRenderWindowInteractor *rwi = this->Interactor;
414 this->WindowLevelCurrentPosition[0] = rwi->GetEventPosition()[0];
415 this->WindowLevelCurrentPosition[1] = rwi->GetEventPosition()[1];
417 this->InvokeEvent(vtkCommand::WindowLevelEvent, this);
420 //----------------------------------------------------------------------------
421 void vvInteractorStyleNavigator::Pick()
423 this->InvokeEvent(vtkCommand::PickEvent, this);
426 //----------------------------------------------------------------------------
427 void vvInteractorStyleNavigator::Pan()
429 if (this->CurrentRenderer == NULL) {
433 vtkRenderWindowInteractor *rwi = this->Interactor;
435 double viewFocus[4], focalDepth, viewPoint[3];
436 double newPickPoint[4], oldPickPoint[4], motionVector[3];
438 // Calculate the focal depth since we'll be using it a lot
440 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
441 camera->GetFocalPoint(viewFocus);
442 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
444 focalDepth = viewFocus[2];
446 this->ComputeDisplayToWorld((double)rwi->GetEventPosition()[0],
447 (double)rwi->GetEventPosition()[1],
451 // Has to recalc old mouse point since the viewport has moved,
452 // so can't move it outside the loop
454 this->ComputeDisplayToWorld((double)rwi->GetLastEventPosition()[0],
455 (double)rwi->GetLastEventPosition()[1],
459 // Camera motion is reversed
461 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
462 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
463 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
465 camera->GetFocalPoint(viewFocus);
466 camera->GetPosition(viewPoint);
467 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
468 motionVector[1] + viewFocus[1],
469 motionVector[2] + viewFocus[2]);
471 camera->SetPosition(motionVector[0] + viewPoint[0],
472 motionVector[1] + viewPoint[1],
473 motionVector[2] + viewPoint[2]);
475 if (rwi->GetLightFollowCamera()) {
476 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
479 this->InvokeEvent(vtkCommand::EndInteractionEvent, this);
484 //----------------------------------------------------------------------------
485 void vvInteractorStyleNavigator::Dolly()
487 if (this->CurrentRenderer == NULL) {
491 vtkRenderWindowInteractor *rwi = this->Interactor;
492 double *center = this->CurrentRenderer->GetCenter();
493 int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
494 double dyf = this->MotionFactor * (double)(dy) / (double)(center[1]);
495 this->Dolly(pow((double)1.1, dyf));
498 //----------------------------------------------------------------------------
499 void vvInteractorStyleNavigator::Dolly(double factor)
501 if (this->CurrentRenderer == NULL) {
505 double viewFocus[4],viewPoint[4],motionVector[3], focalDepth;
506 double oldPos[3], newPos[3], distance[2];
507 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
508 camera->GetFocalPoint(viewFocus);
509 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
511 focalDepth = viewFocus[2];
513 oldPos[0] = this->CurrentRenderer->GetCenter()[0];
514 oldPos[1] = this->CurrentRenderer->GetCenter()[1];
515 oldPos[2] = focalDepth;
517 distance[0] = 1/factor*
518 (this->Interactor->GetEventPosition()[0]-this->CurrentRenderer->GetCenter()[0]);
519 distance[1] = 1/factor*
520 (this->Interactor->GetEventPosition()[1]-this->CurrentRenderer->GetCenter()[1]);
522 newPos[0] = this->Interactor->GetEventPosition()[0] - distance[0];
523 newPos[1] = this->Interactor->GetEventPosition()[1] - distance[1];
524 newPos[2] = focalDepth;
526 this->CurrentRenderer->DisplayToNormalizedDisplay(oldPos[0],oldPos[1]);
527 this->CurrentRenderer->NormalizedDisplayToViewport(oldPos[0],oldPos[1]);
528 this->CurrentRenderer->ViewportToNormalizedViewport(oldPos[0],oldPos[1]);
529 this->CurrentRenderer->NormalizedViewportToView(oldPos[0],oldPos[1],oldPos[2]);
530 this->CurrentRenderer->ViewToWorld(oldPos[0],oldPos[1],oldPos[2]);
532 this->CurrentRenderer->DisplayToNormalizedDisplay(newPos[0],newPos[1]);
533 this->CurrentRenderer->NormalizedDisplayToViewport(newPos[0],newPos[1]);
534 this->CurrentRenderer->ViewportToNormalizedViewport(newPos[0],newPos[1]);
535 this->CurrentRenderer->NormalizedViewportToView(newPos[0],newPos[1],newPos[2]);
536 this->CurrentRenderer->ViewToWorld(newPos[0],newPos[1],newPos[2]);
538 motionVector[0] = newPos[0] - oldPos[0];
539 motionVector[1] = newPos[1] - oldPos[1];
540 motionVector[2] = newPos[2] - oldPos[2];
542 camera->GetFocalPoint(viewFocus);
543 camera->GetPosition(viewPoint);
544 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
545 motionVector[1] + viewFocus[1],
546 motionVector[2] + viewFocus[2]);
548 camera->SetPosition(motionVector[0] + viewPoint[0],
549 motionVector[1] + viewPoint[1],
550 motionVector[2] + viewPoint[2]);
552 if (camera->GetParallelProjection()) {
553 camera->SetParallelScale(camera->GetParallelScale() / factor);
555 camera->Dolly(factor);
556 if (this->AutoAdjustCameraClippingRange) {
557 this->CurrentRenderer->ResetCameraClippingRange();
561 if (this->Interactor->GetLightFollowCamera()) {
562 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
564 this->CurrentRenderer->ResetCameraClippingRange();
565 //this->Interactor->Render();
567 this->InvokeEvent(vtkCommand::EndInteractionEvent, this);
571 //----------------------------------------------------------------------------
572 void vvInteractorStyleNavigator::PrintSelf(ostream& os, vtkIndent indent)
574 this->Superclass::PrintSelf(os, indent);
576 os << indent << "Window Level Current Position: ("
577 << this->WindowLevelCurrentPosition[0] << ", "
578 << this->WindowLevelCurrentPosition[1] << ")" << endl;
580 os << indent << "Window Level Start Position: ("
581 << this->WindowLevelStartPosition[0] << ", "
582 << this->WindowLevelStartPosition[1] << ")" << endl;