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()
283 // DD("OnLeftButtonUp");
288 if ( this->Interactor )
290 this->ReleaseFocus();
295 // Call parent to handle all other states and perform additional work
297 this->Superclass::OnLeftButtonUp();
300 //----------------------------------------------------------------------------
301 void vvInteractorStyleNavigator::OnMiddleButtonDown()
303 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
304 this->Interactor->GetEventPosition()[1]);
305 if (this->CurrentRenderer == NULL)
309 this->CurrentRenderer->GetRenderWindow()->SetCurrentCursor(8);
310 this->GrabFocus(this->EventCallbackCommand);
314 //----------------------------------------------------------------------------
315 void vvInteractorStyleNavigator::OnMiddleButtonUp()
321 if ( this->Interactor )
323 this->Interactor->GetRenderWindow()->SetCurrentCursor(0);
324 this->ReleaseFocus();
330 //----------------------------------------------------------------------------
331 void vvInteractorStyleNavigator::OnChar()
333 vtkRenderWindowInteractor *rwi = this->Interactor;
335 switch (rwi->GetKeyCode())
340 this->AnimState = VTKIS_ANIM_ON;
341 this->AnimState = VTKIS_ANIM_OFF;
348 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
349 this->Interactor->GetEventPosition()[1]);
350 if (this->CurrentRenderer == NULL)
354 this->GrabFocus(this->EventCallbackCommand);
357 this->Dolly(pow((double)1.1, factor));
359 this->ReleaseFocus();
365 this->FindPokedRenderer(rwi->GetEventPosition()[0],
366 rwi->GetEventPosition()[1]);
367 if (this->CurrentRenderer == NULL)
371 this->GrabFocus(this->EventCallbackCommand);
374 this->Dolly(pow((double)1.1, factor));
376 this->ReleaseFocus();
380 // Disable StereoVision
384 //Do nothing, this is handled in vvSlicerManagerCommand
387 this->Superclass::OnChar();
392 //----------------------------------------------------------------------------
393 void vvInteractorStyleNavigator::OnMouseWheelForward()
395 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
396 this->Interactor->GetEventPosition()[1]);
397 if (this->CurrentRenderer == NULL)
401 this->GrabFocus(this->EventCallbackCommand);
402 if (this->Interactor->GetControlKey())
405 double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
406 this->Dolly(pow((double)1.1, factor));
409 this->ReleaseFocus();
410 this->InvokeEvent(vtkCommand::MouseWheelForwardEvent, this);
413 //----------------------------------------------------------------------------
414 void vvInteractorStyleNavigator::OnMouseWheelBackward()
416 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
417 this->Interactor->GetEventPosition()[1]);
418 if (this->CurrentRenderer == NULL)
423 this->GrabFocus(this->EventCallbackCommand);
424 if (this->Interactor->GetControlKey())
427 double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
428 this->Dolly(pow((double)1.1, factor));
431 this->ReleaseFocus();
432 this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, this);
436 //----------------------------------------------------------------------------
437 void vvInteractorStyleNavigator::WindowLevel()
439 vtkRenderWindowInteractor *rwi = this->Interactor;
441 this->WindowLevelCurrentPosition[0] = rwi->GetEventPosition()[0];
442 this->WindowLevelCurrentPosition[1] = rwi->GetEventPosition()[1];
444 this->InvokeEvent(vtkCommand::WindowLevelEvent, this);
447 //----------------------------------------------------------------------------
448 void vvInteractorStyleNavigator::Pick()
450 this->InvokeEvent(vtkCommand::PickEvent, this);
453 //----------------------------------------------------------------------------
454 void vvInteractorStyleNavigator::Pan()
456 if (this->CurrentRenderer == NULL)
461 vtkRenderWindowInteractor *rwi = this->Interactor;
463 double viewFocus[4], focalDepth, viewPoint[3];
464 double newPickPoint[4], oldPickPoint[4], motionVector[3];
466 // Calculate the focal depth since we'll be using it a lot
468 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
469 camera->GetFocalPoint(viewFocus);
470 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
472 focalDepth = viewFocus[2];
474 this->ComputeDisplayToWorld((double)rwi->GetEventPosition()[0],
475 (double)rwi->GetEventPosition()[1],
479 // Has to recalc old mouse point since the viewport has moved,
480 // so can't move it outside the loop
482 this->ComputeDisplayToWorld((double)rwi->GetLastEventPosition()[0],
483 (double)rwi->GetLastEventPosition()[1],
487 // Camera motion is reversed
489 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
490 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
491 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
493 camera->GetFocalPoint(viewFocus);
494 camera->GetPosition(viewPoint);
495 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
496 motionVector[1] + viewFocus[1],
497 motionVector[2] + viewFocus[2]);
499 camera->SetPosition(motionVector[0] + viewPoint[0],
500 motionVector[1] + viewPoint[1],
501 motionVector[2] + viewPoint[2]);
503 if (rwi->GetLightFollowCamera())
505 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
511 //----------------------------------------------------------------------------
512 void vvInteractorStyleNavigator::Dolly()
514 if (this->CurrentRenderer == NULL)
519 vtkRenderWindowInteractor *rwi = this->Interactor;
520 double *center = this->CurrentRenderer->GetCenter();
521 int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
522 double dyf = this->MotionFactor * (double)(dy) / (double)(center[1]);
523 this->Dolly(pow((double)1.1, dyf));
526 //----------------------------------------------------------------------------
527 void vvInteractorStyleNavigator::Dolly(double factor)
529 if (this->CurrentRenderer == NULL)
534 double viewFocus[4],viewPoint[4],motionVector[3], focalDepth;
535 double oldPos[3], newPos[3], distance[2];
536 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
537 camera->GetFocalPoint(viewFocus);
538 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
540 focalDepth = viewFocus[2];
542 oldPos[0] = this->CurrentRenderer->GetCenter()[0];
543 oldPos[1] = this->CurrentRenderer->GetCenter()[1];
544 oldPos[2] = focalDepth;
546 distance[0] = 1/factor*
547 (this->Interactor->GetEventPosition()[0]-this->CurrentRenderer->GetCenter()[0]);
548 distance[1] = 1/factor*
549 (this->Interactor->GetEventPosition()[1]-this->CurrentRenderer->GetCenter()[1]);
551 newPos[0] = this->Interactor->GetEventPosition()[0] - distance[0];
552 newPos[1] = this->Interactor->GetEventPosition()[1] - distance[1];
553 newPos[2] = focalDepth;
555 this->CurrentRenderer->DisplayToNormalizedDisplay(oldPos[0],oldPos[1]);
556 this->CurrentRenderer->NormalizedDisplayToViewport(oldPos[0],oldPos[1]);
557 this->CurrentRenderer->ViewportToNormalizedViewport(oldPos[0],oldPos[1]);
558 this->CurrentRenderer->NormalizedViewportToView(oldPos[0],oldPos[1],oldPos[2]);
559 this->CurrentRenderer->ViewToWorld(oldPos[0],oldPos[1],oldPos[2]);
561 this->CurrentRenderer->DisplayToNormalizedDisplay(newPos[0],newPos[1]);
562 this->CurrentRenderer->NormalizedDisplayToViewport(newPos[0],newPos[1]);
563 this->CurrentRenderer->ViewportToNormalizedViewport(newPos[0],newPos[1]);
564 this->CurrentRenderer->NormalizedViewportToView(newPos[0],newPos[1],newPos[2]);
565 this->CurrentRenderer->ViewToWorld(newPos[0],newPos[1],newPos[2]);
567 motionVector[0] = newPos[0] - oldPos[0];
568 motionVector[1] = newPos[1] - oldPos[1];
569 motionVector[2] = newPos[2] - oldPos[2];
571 camera->GetFocalPoint(viewFocus);
572 camera->GetPosition(viewPoint);
573 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
574 motionVector[1] + viewFocus[1],
575 motionVector[2] + viewFocus[2]);
577 camera->SetPosition(motionVector[0] + viewPoint[0],
578 motionVector[1] + viewPoint[1],
579 motionVector[2] + viewPoint[2]);
581 if (camera->GetParallelProjection())
583 camera->SetParallelScale(camera->GetParallelScale() / factor);
587 camera->Dolly(factor);
588 if (this->AutoAdjustCameraClippingRange)
590 this->CurrentRenderer->ResetCameraClippingRange();
594 if (this->Interactor->GetLightFollowCamera())
596 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
598 this->CurrentRenderer->ResetCameraClippingRange();
599 //this->Interactor->Render();
603 //----------------------------------------------------------------------------
604 void vvInteractorStyleNavigator::PrintSelf(ostream& os, vtkIndent indent)
606 this->Superclass::PrintSelf(os, indent);
608 os << indent << "Window Level Current Position: ("
609 << this->WindowLevelCurrentPosition[0] << ", "
610 << this->WindowLevelCurrentPosition[1] << ")" << endl;
612 os << indent << "Window Level Start Position: ("
613 << this->WindowLevelStartPosition[0] << ", "
614 << this->WindowLevelStartPosition[1] << ")" << endl;