1 /*=========================================================================
4 Module: $RCSfile: vvInteractorStyleNavigator.cxx,v $
6 Date: $Date: 2010/01/06 13:31:57 $
7 Version: $Revision: 1.1 $
8 Author : Pierre Seroul (pierre.seroul@gmail.com)
11 Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
12 CREATIS-LRMN http://www.creatis.insa-lyon.fr
14 This program is free software: you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation, version 3 of the License.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 =========================================================================*/
27 #include "vvInteractorStyleNavigator.h"
29 #include "vtkAbstractPropPicker.h"
30 #include "vtkAssemblyPath.h"
31 #include "vtkCallbackCommand.h"
33 #include "vtkObjectFactory.h"
34 #include "vtkCamera.h"
35 #include "vtkRenderWindow.h"
36 #include "vtkRenderWindowInteractor.h"
37 #include "vtkRenderer.h"
38 #include <vtkRendererCollection.h>
39 #include "clitkCommon.h"
42 vtkCxxRevisionMacro(vvInteractorStyleNavigator, "$Revision: 1.1 $");
43 vtkStandardNewMacro(vvInteractorStyleNavigator);
45 //----------------------------------------------------------------------------
46 vvInteractorStyleNavigator::vvInteractorStyleNavigator()
48 this->WindowLevelStartPosition[0] = 0;
49 this->WindowLevelStartPosition[1] = 0;
51 this->WindowLevelCurrentPosition[0] = 0;
52 this->WindowLevelCurrentPosition[1] = 0;
54 this->MotionFactor = 10.0;
57 //----------------------------------------------------------------------------
58 vvInteractorStyleNavigator::~vvInteractorStyleNavigator()
63 void vvInteractorStyleNavigator::FindPokedRenderer(int dummy1,int dummy2)
65 vtkRenderWindow * renwin=this->GetInteractor()->GetRenderWindow();
66 renwin->GetRenderers()->InitTraversal();
69 vtkRenderer* current = renwin->GetRenderers()->GetNextItem();
70 if (current==NULL || current->GetDraw())
72 CurrentRenderer=current;
78 //----------------------------------------------------------------------------
79 void vvInteractorStyleNavigator::StartWindowLevel()
81 if (this->State != VTKIS_NONE)
85 this->StartState(VTKIS_WINDOW_LEVEL);
86 this->InvokeEvent(vtkCommand::StartWindowLevelEvent,this);
89 //----------------------------------------------------------------------------
90 void vvInteractorStyleNavigator::EndWindowLevel()
92 if (this->State != VTKIS_WINDOW_LEVEL)
96 this->InvokeEvent(vtkCommand::EndWindowLevelEvent, this);
100 //----------------------------------------------------------------------------
101 void vvInteractorStyleNavigator::StartPick()
103 if (this->State != VTKIS_NONE)
107 this->StartState(VTKIS_PICK);
108 this->InvokeEvent(vtkCommand::StartPickEvent, this);
111 //----------------------------------------------------------------------------
112 void vvInteractorStyleNavigator::EndPick()
114 if (this->State != VTKIS_PICK)
118 this->InvokeEvent(vtkCommand::EndPickEvent, this);
122 //----------------------------------------------------------------------------
123 void vvInteractorStyleNavigator::OnMouseMove()
125 int x = this->Interactor->GetEventPosition()[0];
126 int y = this->Interactor->GetEventPosition()[1];
130 case VTKIS_WINDOW_LEVEL:
131 this->FindPokedRenderer(x, y);
133 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
137 this->FindPokedRenderer(x, y);
139 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
143 this->FindPokedRenderer(x, y);
145 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
149 this->FindPokedRenderer(x, y);
151 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
155 this->InvokeEvent(vtkCommand::UserEvent, NULL);
159 // Call parent to handle all other states and perform additional work
163 void vvInteractorStyleNavigator::OnEnter()
165 // int x = this->Interactor->GetEventPosition()[0];
166 //int y = this->Interactor->GetEventPosition()[1];
170 case VTKIS_WINDOW_LEVEL:
180 this->InvokeEvent(vtkCommand::EnterEvent, NULL);
184 // Call parent to handle all other states and perform additional work
188 //----------------------------------------------------------------------------
189 void vvInteractorStyleNavigator::OnLeave()
191 // int x = this->Interactor->GetEventPosition()[0];
192 //int y = this->Interactor->GetEventPosition()[1];
196 case VTKIS_WINDOW_LEVEL:
206 this->InvokeEvent(vtkCommand::LeaveEvent, NULL);
210 // Call parent to handle all other states and perform additional work
214 //----------------------------------------------------------------------------
215 void vvInteractorStyleNavigator::OnRightButtonDown()
217 int x = this->Interactor->GetEventPosition()[0];
218 int y = this->Interactor->GetEventPosition()[1];
220 this->FindPokedRenderer(x, y);
221 if (this->CurrentRenderer == NULL)
226 // Redefine this button to handle window/level
227 this->GrabFocus(this->EventCallbackCommand);
228 if (!this->Interactor->GetShiftKey() && !this->Interactor->GetControlKey())
230 this->WindowLevelStartPosition[0] = x;
231 this->WindowLevelStartPosition[1] = y;
232 this->StartWindowLevel();
235 // The rest of the button + key combinations remain the same
239 this->Superclass::OnRightButtonDown();
243 //----------------------------------------------------------------------------
244 void vvInteractorStyleNavigator::OnRightButtonUp()
248 case VTKIS_WINDOW_LEVEL:
249 this->EndWindowLevel();
250 if ( this->Interactor )
252 this->ReleaseFocus();
257 // Call parent to handle all other states and perform additional work
259 this->Superclass::OnRightButtonUp();
262 //----------------------------------------------------------------------------
263 void vvInteractorStyleNavigator::OnLeftButtonDown()
265 int x = this->Interactor->GetEventPosition()[0];
266 int y = this->Interactor->GetEventPosition()[1];
268 this->FindPokedRenderer(x, y);
269 if (this->CurrentRenderer == NULL)
274 // Redefine this button to handle pick
275 this->GrabFocus(this->EventCallbackCommand);
276 if (!this->Interactor->GetShiftKey() && !this->Interactor->GetControlKey())
281 // The rest of the button + key combinations remain the same
285 this->Superclass::OnLeftButtonDown();
289 //----------------------------------------------------------------------------
290 void vvInteractorStyleNavigator::OnLeftButtonUp()
296 if ( this->Interactor )
298 this->ReleaseFocus();
303 // Call parent to handle all other states and perform additional work
305 this->Superclass::OnLeftButtonUp();
308 //----------------------------------------------------------------------------
309 void vvInteractorStyleNavigator::OnMiddleButtonDown()
311 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
312 this->Interactor->GetEventPosition()[1]);
313 if (this->CurrentRenderer == NULL)
317 this->CurrentRenderer->GetRenderWindow()->SetCurrentCursor(8);
318 this->GrabFocus(this->EventCallbackCommand);
322 //----------------------------------------------------------------------------
323 void vvInteractorStyleNavigator::OnMiddleButtonUp()
329 if ( this->Interactor )
331 this->Interactor->GetRenderWindow()->SetCurrentCursor(0);
332 this->ReleaseFocus();
338 //----------------------------------------------------------------------------
339 void vvInteractorStyleNavigator::OnChar()
341 vtkRenderWindowInteractor *rwi = this->Interactor;
343 switch (rwi->GetKeyCode())
348 this->AnimState = VTKIS_ANIM_ON;
349 this->AnimState = VTKIS_ANIM_OFF;
356 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
357 this->Interactor->GetEventPosition()[1]);
358 if (this->CurrentRenderer == NULL)
362 this->GrabFocus(this->EventCallbackCommand);
365 this->Dolly(pow((double)1.1, factor));
367 this->ReleaseFocus();
373 this->FindPokedRenderer(rwi->GetEventPosition()[0],
374 rwi->GetEventPosition()[1]);
375 if (this->CurrentRenderer == NULL)
379 this->GrabFocus(this->EventCallbackCommand);
382 this->Dolly(pow((double)1.1, factor));
384 this->ReleaseFocus();
388 // Disable StereoVision
392 //Do nothing, this is handled in vvSlicerManagerCommand
395 this->Superclass::OnChar();
400 //----------------------------------------------------------------------------
401 void vvInteractorStyleNavigator::OnMouseWheelForward()
403 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
404 this->Interactor->GetEventPosition()[1]);
405 if (this->CurrentRenderer == NULL)
409 this->GrabFocus(this->EventCallbackCommand);
410 if (this->Interactor->GetControlKey())
413 double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
414 this->Dolly(pow((double)1.1, factor));
417 this->ReleaseFocus();
418 this->InvokeEvent(vtkCommand::MouseWheelForwardEvent, this);
421 //----------------------------------------------------------------------------
422 void vvInteractorStyleNavigator::OnMouseWheelBackward()
424 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
425 this->Interactor->GetEventPosition()[1]);
426 if (this->CurrentRenderer == NULL)
431 this->GrabFocus(this->EventCallbackCommand);
432 if (this->Interactor->GetControlKey())
435 double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
436 this->Dolly(pow((double)1.1, factor));
439 this->ReleaseFocus();
440 this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, this);
444 //----------------------------------------------------------------------------
445 void vvInteractorStyleNavigator::WindowLevel()
447 vtkRenderWindowInteractor *rwi = this->Interactor;
449 this->WindowLevelCurrentPosition[0] = rwi->GetEventPosition()[0];
450 this->WindowLevelCurrentPosition[1] = rwi->GetEventPosition()[1];
452 this->InvokeEvent(vtkCommand::WindowLevelEvent, this);
455 //----------------------------------------------------------------------------
456 void vvInteractorStyleNavigator::Pick()
458 this->InvokeEvent(vtkCommand::PickEvent, this);
461 //----------------------------------------------------------------------------
462 void vvInteractorStyleNavigator::Pan()
464 if (this->CurrentRenderer == NULL)
469 vtkRenderWindowInteractor *rwi = this->Interactor;
471 double viewFocus[4], focalDepth, viewPoint[3];
472 double newPickPoint[4], oldPickPoint[4], motionVector[3];
474 // Calculate the focal depth since we'll be using it a lot
476 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
477 camera->GetFocalPoint(viewFocus);
478 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
480 focalDepth = viewFocus[2];
482 this->ComputeDisplayToWorld((double)rwi->GetEventPosition()[0],
483 (double)rwi->GetEventPosition()[1],
487 // Has to recalc old mouse point since the viewport has moved,
488 // so can't move it outside the loop
490 this->ComputeDisplayToWorld((double)rwi->GetLastEventPosition()[0],
491 (double)rwi->GetLastEventPosition()[1],
495 // Camera motion is reversed
497 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
498 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
499 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
501 camera->GetFocalPoint(viewFocus);
502 camera->GetPosition(viewPoint);
503 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
504 motionVector[1] + viewFocus[1],
505 motionVector[2] + viewFocus[2]);
507 camera->SetPosition(motionVector[0] + viewPoint[0],
508 motionVector[1] + viewPoint[1],
509 motionVector[2] + viewPoint[2]);
511 if (rwi->GetLightFollowCamera())
513 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
519 //----------------------------------------------------------------------------
520 void vvInteractorStyleNavigator::Dolly()
522 if (this->CurrentRenderer == NULL)
527 vtkRenderWindowInteractor *rwi = this->Interactor;
528 double *center = this->CurrentRenderer->GetCenter();
529 int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
530 double dyf = this->MotionFactor * (double)(dy) / (double)(center[1]);
531 this->Dolly(pow((double)1.1, dyf));
534 //----------------------------------------------------------------------------
535 void vvInteractorStyleNavigator::Dolly(double factor)
537 if (this->CurrentRenderer == NULL)
542 double viewFocus[4],viewPoint[4],motionVector[3], focalDepth;
543 double oldPos[3], newPos[3], distance[2];
544 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
545 camera->GetFocalPoint(viewFocus);
546 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
548 focalDepth = viewFocus[2];
550 oldPos[0] = this->CurrentRenderer->GetCenter()[0];
551 oldPos[1] = this->CurrentRenderer->GetCenter()[1];
552 oldPos[2] = focalDepth;
554 distance[0] = 1/factor*
555 (this->Interactor->GetEventPosition()[0]-this->CurrentRenderer->GetCenter()[0]);
556 distance[1] = 1/factor*
557 (this->Interactor->GetEventPosition()[1]-this->CurrentRenderer->GetCenter()[1]);
559 newPos[0] = this->Interactor->GetEventPosition()[0] - distance[0];
560 newPos[1] = this->Interactor->GetEventPosition()[1] - distance[1];
561 newPos[2] = focalDepth;
563 this->CurrentRenderer->DisplayToNormalizedDisplay(oldPos[0],oldPos[1]);
564 this->CurrentRenderer->NormalizedDisplayToViewport(oldPos[0],oldPos[1]);
565 this->CurrentRenderer->ViewportToNormalizedViewport(oldPos[0],oldPos[1]);
566 this->CurrentRenderer->NormalizedViewportToView(oldPos[0],oldPos[1],oldPos[2]);
567 this->CurrentRenderer->ViewToWorld(oldPos[0],oldPos[1],oldPos[2]);
569 this->CurrentRenderer->DisplayToNormalizedDisplay(newPos[0],newPos[1]);
570 this->CurrentRenderer->NormalizedDisplayToViewport(newPos[0],newPos[1]);
571 this->CurrentRenderer->ViewportToNormalizedViewport(newPos[0],newPos[1]);
572 this->CurrentRenderer->NormalizedViewportToView(newPos[0],newPos[1],newPos[2]);
573 this->CurrentRenderer->ViewToWorld(newPos[0],newPos[1],newPos[2]);
575 motionVector[0] = newPos[0] - oldPos[0];
576 motionVector[1] = newPos[1] - oldPos[1];
577 motionVector[2] = newPos[2] - oldPos[2];
579 camera->GetFocalPoint(viewFocus);
580 camera->GetPosition(viewPoint);
581 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
582 motionVector[1] + viewFocus[1],
583 motionVector[2] + viewFocus[2]);
585 camera->SetPosition(motionVector[0] + viewPoint[0],
586 motionVector[1] + viewPoint[1],
587 motionVector[2] + viewPoint[2]);
589 if (camera->GetParallelProjection())
591 camera->SetParallelScale(camera->GetParallelScale() / factor);
595 camera->Dolly(factor);
596 if (this->AutoAdjustCameraClippingRange)
598 this->CurrentRenderer->ResetCameraClippingRange();
602 if (this->Interactor->GetLightFollowCamera())
604 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
606 this->CurrentRenderer->ResetCameraClippingRange();
607 //this->Interactor->Render();
611 //----------------------------------------------------------------------------
612 void vvInteractorStyleNavigator::PrintSelf(ostream& os, vtkIndent indent)
614 this->Superclass::PrintSelf(os, indent);
616 os << indent << "Window Level Current Position: ("
617 << this->WindowLevelCurrentPosition[0] << ", "
618 << this->WindowLevelCurrentPosition[1] << ")" << endl;
620 os << indent << "Window Level Start Position: ("
621 << this->WindowLevelStartPosition[0] << ", "
622 << this->WindowLevelStartPosition[1] << ")" << endl;