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://oncora1.lyon.fnclcc.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"
33 vtkCxxRevisionMacro(vvInteractorStyleNavigator, "DummyRevision");
34 vtkStandardNewMacro(vvInteractorStyleNavigator);
36 //----------------------------------------------------------------------------
37 vvInteractorStyleNavigator::vvInteractorStyleNavigator()
39 this->WindowLevelStartPosition[0] = 0;
40 this->WindowLevelStartPosition[1] = 0;
42 this->WindowLevelCurrentPosition[0] = 0;
43 this->WindowLevelCurrentPosition[1] = 0;
45 this->MotionFactor = 10.0;
48 //----------------------------------------------------------------------------
49 vvInteractorStyleNavigator::~vvInteractorStyleNavigator()
54 void vvInteractorStyleNavigator::FindPokedRenderer(int dummy1,int dummy2)
56 vtkRenderWindow * renwin=this->GetInteractor()->GetRenderWindow();
57 renwin->GetRenderers()->InitTraversal();
60 vtkRenderer* current = renwin->GetRenderers()->GetNextItem();
61 if (current==NULL || current->GetDraw())
63 CurrentRenderer=current;
69 //----------------------------------------------------------------------------
70 void vvInteractorStyleNavigator::StartWindowLevel()
72 if (this->State != VTKIS_NONE)
76 this->StartState(VTKIS_WINDOW_LEVEL);
77 this->InvokeEvent(vtkCommand::StartWindowLevelEvent,this);
80 //----------------------------------------------------------------------------
81 void vvInteractorStyleNavigator::EndWindowLevel()
83 if (this->State != VTKIS_WINDOW_LEVEL)
87 this->InvokeEvent(vtkCommand::EndWindowLevelEvent, this);
91 //----------------------------------------------------------------------------
92 void vvInteractorStyleNavigator::StartPick()
94 if (this->State != VTKIS_NONE)
98 this->StartState(VTKIS_PICK);
99 this->InvokeEvent(vtkCommand::StartPickEvent, this);
102 //----------------------------------------------------------------------------
103 void vvInteractorStyleNavigator::EndPick()
105 if (this->State != VTKIS_PICK)
109 this->InvokeEvent(vtkCommand::EndPickEvent, this);
113 //----------------------------------------------------------------------------
114 void vvInteractorStyleNavigator::OnMouseMove()
116 int x = this->Interactor->GetEventPosition()[0];
117 int y = this->Interactor->GetEventPosition()[1];
121 case VTKIS_WINDOW_LEVEL:
122 this->FindPokedRenderer(x, y);
124 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
128 this->FindPokedRenderer(x, y);
130 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
134 this->FindPokedRenderer(x, y);
136 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
140 this->FindPokedRenderer(x, y);
142 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
146 this->InvokeEvent(vtkCommand::UserEvent, NULL);
150 // Call parent to handle all other states and perform additional work
154 void vvInteractorStyleNavigator::OnEnter()
156 // int x = this->Interactor->GetEventPosition()[0];
157 //int y = this->Interactor->GetEventPosition()[1];
161 case VTKIS_WINDOW_LEVEL:
171 this->InvokeEvent(vtkCommand::EnterEvent, NULL);
175 // Call parent to handle all other states and perform additional work
179 //----------------------------------------------------------------------------
180 void vvInteractorStyleNavigator::OnLeave()
182 // int x = this->Interactor->GetEventPosition()[0];
183 //int y = this->Interactor->GetEventPosition()[1];
187 case VTKIS_WINDOW_LEVEL:
197 this->InvokeEvent(vtkCommand::LeaveEvent, NULL);
201 // Call parent to handle all other states and perform additional work
205 //----------------------------------------------------------------------------
206 void vvInteractorStyleNavigator::OnRightButtonDown()
208 int x = this->Interactor->GetEventPosition()[0];
209 int y = this->Interactor->GetEventPosition()[1];
211 this->FindPokedRenderer(x, y);
212 if (this->CurrentRenderer == NULL)
217 // Redefine this button to handle window/level
218 this->GrabFocus(this->EventCallbackCommand);
219 if (!this->Interactor->GetShiftKey() && !this->Interactor->GetControlKey())
221 this->WindowLevelStartPosition[0] = x;
222 this->WindowLevelStartPosition[1] = y;
223 this->StartWindowLevel();
226 // The rest of the button + key combinations remain the same
230 this->Superclass::OnRightButtonDown();
234 //----------------------------------------------------------------------------
235 void vvInteractorStyleNavigator::OnRightButtonUp()
239 case VTKIS_WINDOW_LEVEL:
240 this->EndWindowLevel();
241 if ( this->Interactor )
243 this->ReleaseFocus();
248 // Call parent to handle all other states and perform additional work
250 this->Superclass::OnRightButtonUp();
253 //----------------------------------------------------------------------------
254 void vvInteractorStyleNavigator::OnLeftButtonDown()
256 int x = this->Interactor->GetEventPosition()[0];
257 int y = this->Interactor->GetEventPosition()[1];
259 this->FindPokedRenderer(x, y);
260 if (this->CurrentRenderer == NULL)
265 // Redefine this button to handle pick
266 this->GrabFocus(this->EventCallbackCommand);
267 if (!this->Interactor->GetShiftKey() && !this->Interactor->GetControlKey())
272 // The rest of the button + key combinations remain the same
276 this->Superclass::OnLeftButtonDown();
280 //----------------------------------------------------------------------------
281 void vvInteractorStyleNavigator::OnLeftButtonUp()
287 if ( this->Interactor )
289 this->ReleaseFocus();
294 // Call parent to handle all other states and perform additional work
296 this->Superclass::OnLeftButtonUp();
299 //----------------------------------------------------------------------------
300 void vvInteractorStyleNavigator::OnMiddleButtonDown()
302 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
303 this->Interactor->GetEventPosition()[1]);
304 if (this->CurrentRenderer == NULL)
308 this->CurrentRenderer->GetRenderWindow()->SetCurrentCursor(8);
309 this->GrabFocus(this->EventCallbackCommand);
313 //----------------------------------------------------------------------------
314 void vvInteractorStyleNavigator::OnMiddleButtonUp()
320 if ( this->Interactor )
322 this->Interactor->GetRenderWindow()->SetCurrentCursor(0);
323 this->ReleaseFocus();
329 //----------------------------------------------------------------------------
330 void vvInteractorStyleNavigator::OnChar()
332 vtkRenderWindowInteractor *rwi = this->Interactor;
334 switch (rwi->GetKeyCode())
339 this->AnimState = VTKIS_ANIM_ON;
340 this->AnimState = VTKIS_ANIM_OFF;
347 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
348 this->Interactor->GetEventPosition()[1]);
349 if (this->CurrentRenderer == NULL)
353 this->GrabFocus(this->EventCallbackCommand);
356 this->Dolly(pow((double)1.1, factor));
358 this->ReleaseFocus();
364 this->FindPokedRenderer(rwi->GetEventPosition()[0],
365 rwi->GetEventPosition()[1]);
366 if (this->CurrentRenderer == NULL)
370 this->GrabFocus(this->EventCallbackCommand);
373 this->Dolly(pow((double)1.1, factor));
375 this->ReleaseFocus();
379 // Disable StereoVision
383 //Do nothing, this is handled in vvSlicerManagerCommand
386 this->Superclass::OnChar();
391 //----------------------------------------------------------------------------
392 void vvInteractorStyleNavigator::OnMouseWheelForward()
394 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
395 this->Interactor->GetEventPosition()[1]);
396 if (this->CurrentRenderer == NULL)
400 this->GrabFocus(this->EventCallbackCommand);
401 if (this->Interactor->GetControlKey())
404 double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
405 this->Dolly(pow((double)1.1, factor));
408 this->ReleaseFocus();
409 this->InvokeEvent(vtkCommand::MouseWheelForwardEvent, this);
412 //----------------------------------------------------------------------------
413 void vvInteractorStyleNavigator::OnMouseWheelBackward()
415 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
416 this->Interactor->GetEventPosition()[1]);
417 if (this->CurrentRenderer == NULL)
422 this->GrabFocus(this->EventCallbackCommand);
423 if (this->Interactor->GetControlKey())
426 double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
427 this->Dolly(pow((double)1.1, factor));
430 this->ReleaseFocus();
431 this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, this);
435 //----------------------------------------------------------------------------
436 void vvInteractorStyleNavigator::WindowLevel()
438 vtkRenderWindowInteractor *rwi = this->Interactor;
440 this->WindowLevelCurrentPosition[0] = rwi->GetEventPosition()[0];
441 this->WindowLevelCurrentPosition[1] = rwi->GetEventPosition()[1];
443 this->InvokeEvent(vtkCommand::WindowLevelEvent, this);
446 //----------------------------------------------------------------------------
447 void vvInteractorStyleNavigator::Pick()
449 this->InvokeEvent(vtkCommand::PickEvent, this);
452 //----------------------------------------------------------------------------
453 void vvInteractorStyleNavigator::Pan()
455 if (this->CurrentRenderer == NULL)
460 vtkRenderWindowInteractor *rwi = this->Interactor;
462 double viewFocus[4], focalDepth, viewPoint[3];
463 double newPickPoint[4], oldPickPoint[4], motionVector[3];
465 // Calculate the focal depth since we'll be using it a lot
467 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
468 camera->GetFocalPoint(viewFocus);
469 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
471 focalDepth = viewFocus[2];
473 this->ComputeDisplayToWorld((double)rwi->GetEventPosition()[0],
474 (double)rwi->GetEventPosition()[1],
478 // Has to recalc old mouse point since the viewport has moved,
479 // so can't move it outside the loop
481 this->ComputeDisplayToWorld((double)rwi->GetLastEventPosition()[0],
482 (double)rwi->GetLastEventPosition()[1],
486 // Camera motion is reversed
488 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
489 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
490 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
492 camera->GetFocalPoint(viewFocus);
493 camera->GetPosition(viewPoint);
494 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
495 motionVector[1] + viewFocus[1],
496 motionVector[2] + viewFocus[2]);
498 camera->SetPosition(motionVector[0] + viewPoint[0],
499 motionVector[1] + viewPoint[1],
500 motionVector[2] + viewPoint[2]);
502 if (rwi->GetLightFollowCamera())
504 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
510 //----------------------------------------------------------------------------
511 void vvInteractorStyleNavigator::Dolly()
513 if (this->CurrentRenderer == NULL)
518 vtkRenderWindowInteractor *rwi = this->Interactor;
519 double *center = this->CurrentRenderer->GetCenter();
520 int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
521 double dyf = this->MotionFactor * (double)(dy) / (double)(center[1]);
522 this->Dolly(pow((double)1.1, dyf));
525 //----------------------------------------------------------------------------
526 void vvInteractorStyleNavigator::Dolly(double factor)
528 if (this->CurrentRenderer == NULL)
533 double viewFocus[4],viewPoint[4],motionVector[3], focalDepth;
534 double oldPos[3], newPos[3], distance[2];
535 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
536 camera->GetFocalPoint(viewFocus);
537 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
539 focalDepth = viewFocus[2];
541 oldPos[0] = this->CurrentRenderer->GetCenter()[0];
542 oldPos[1] = this->CurrentRenderer->GetCenter()[1];
543 oldPos[2] = focalDepth;
545 distance[0] = 1/factor*
546 (this->Interactor->GetEventPosition()[0]-this->CurrentRenderer->GetCenter()[0]);
547 distance[1] = 1/factor*
548 (this->Interactor->GetEventPosition()[1]-this->CurrentRenderer->GetCenter()[1]);
550 newPos[0] = this->Interactor->GetEventPosition()[0] - distance[0];
551 newPos[1] = this->Interactor->GetEventPosition()[1] - distance[1];
552 newPos[2] = focalDepth;
554 this->CurrentRenderer->DisplayToNormalizedDisplay(oldPos[0],oldPos[1]);
555 this->CurrentRenderer->NormalizedDisplayToViewport(oldPos[0],oldPos[1]);
556 this->CurrentRenderer->ViewportToNormalizedViewport(oldPos[0],oldPos[1]);
557 this->CurrentRenderer->NormalizedViewportToView(oldPos[0],oldPos[1],oldPos[2]);
558 this->CurrentRenderer->ViewToWorld(oldPos[0],oldPos[1],oldPos[2]);
560 this->CurrentRenderer->DisplayToNormalizedDisplay(newPos[0],newPos[1]);
561 this->CurrentRenderer->NormalizedDisplayToViewport(newPos[0],newPos[1]);
562 this->CurrentRenderer->ViewportToNormalizedViewport(newPos[0],newPos[1]);
563 this->CurrentRenderer->NormalizedViewportToView(newPos[0],newPos[1],newPos[2]);
564 this->CurrentRenderer->ViewToWorld(newPos[0],newPos[1],newPos[2]);
566 motionVector[0] = newPos[0] - oldPos[0];
567 motionVector[1] = newPos[1] - oldPos[1];
568 motionVector[2] = newPos[2] - oldPos[2];
570 camera->GetFocalPoint(viewFocus);
571 camera->GetPosition(viewPoint);
572 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
573 motionVector[1] + viewFocus[1],
574 motionVector[2] + viewFocus[2]);
576 camera->SetPosition(motionVector[0] + viewPoint[0],
577 motionVector[1] + viewPoint[1],
578 motionVector[2] + viewPoint[2]);
580 if (camera->GetParallelProjection())
582 camera->SetParallelScale(camera->GetParallelScale() / factor);
586 camera->Dolly(factor);
587 if (this->AutoAdjustCameraClippingRange)
589 this->CurrentRenderer->ResetCameraClippingRange();
593 if (this->Interactor->GetLightFollowCamera())
595 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
597 this->CurrentRenderer->ResetCameraClippingRange();
598 //this->Interactor->Render();
602 //----------------------------------------------------------------------------
603 void vvInteractorStyleNavigator::PrintSelf(ostream& os, vtkIndent indent)
605 this->Superclass::PrintSelf(os, indent);
607 os << indent << "Window Level Current Position: ("
608 << this->WindowLevelCurrentPosition[0] << ", "
609 << this->WindowLevelCurrentPosition[1] << ")" << endl;
611 os << indent << "Window Level Start Position: ("
612 << this->WindowLevelStartPosition[0] << ", "
613 << this->WindowLevelStartPosition[1] << ")" << endl;