1 /*=========================================================================
5 Author : Pierre Seroul (pierre.seroul@gmail.com)
8 Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
9 CREATIS-LRMN http://www.creatis.insa-lyon.fr
11 This program is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, version 3 of the License.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 =========================================================================*/
24 #include "vvInteractorStyleNavigator.h"
26 #include "vtkAbstractPropPicker.h"
27 #include "vtkAssemblyPath.h"
28 #include "vtkCallbackCommand.h"
30 #include "vtkObjectFactory.h"
31 #include "vtkCamera.h"
32 #include "vtkRenderWindow.h"
33 #include "vtkRenderWindowInteractor.h"
34 #include "vtkRenderer.h"
35 #include <vtkRendererCollection.h>
36 #include "clitkCommon.h"
39 vtkCxxRevisionMacro(vvInteractorStyleNavigator, "DummyRevision");
40 vtkStandardNewMacro(vvInteractorStyleNavigator);
42 //----------------------------------------------------------------------------
43 vvInteractorStyleNavigator::vvInteractorStyleNavigator()
45 this->WindowLevelStartPosition[0] = 0;
46 this->WindowLevelStartPosition[1] = 0;
48 this->WindowLevelCurrentPosition[0] = 0;
49 this->WindowLevelCurrentPosition[1] = 0;
51 this->MotionFactor = 10.0;
54 //----------------------------------------------------------------------------
55 vvInteractorStyleNavigator::~vvInteractorStyleNavigator()
60 void vvInteractorStyleNavigator::FindPokedRenderer(int dummy1,int dummy2)
62 vtkRenderWindow * renwin=this->GetInteractor()->GetRenderWindow();
63 renwin->GetRenderers()->InitTraversal();
66 vtkRenderer* current = renwin->GetRenderers()->GetNextItem();
67 if (current==NULL || current->GetDraw())
69 CurrentRenderer=current;
75 //----------------------------------------------------------------------------
76 void vvInteractorStyleNavigator::StartWindowLevel()
78 if (this->State != VTKIS_NONE)
82 this->StartState(VTKIS_WINDOW_LEVEL);
83 this->InvokeEvent(vtkCommand::StartWindowLevelEvent,this);
86 //----------------------------------------------------------------------------
87 void vvInteractorStyleNavigator::EndWindowLevel()
89 if (this->State != VTKIS_WINDOW_LEVEL)
93 this->InvokeEvent(vtkCommand::EndWindowLevelEvent, this);
97 //----------------------------------------------------------------------------
98 void vvInteractorStyleNavigator::StartPick()
100 if (this->State != VTKIS_NONE)
104 this->StartState(VTKIS_PICK);
105 this->InvokeEvent(vtkCommand::StartPickEvent, this);
108 //----------------------------------------------------------------------------
109 void vvInteractorStyleNavigator::EndPick()
111 if (this->State != VTKIS_PICK)
115 this->InvokeEvent(vtkCommand::EndPickEvent, this);
119 //----------------------------------------------------------------------------
120 void vvInteractorStyleNavigator::OnMouseMove()
122 int x = this->Interactor->GetEventPosition()[0];
123 int y = this->Interactor->GetEventPosition()[1];
127 case VTKIS_WINDOW_LEVEL:
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->FindPokedRenderer(x, y);
148 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
152 this->InvokeEvent(vtkCommand::UserEvent, NULL);
156 // Call parent to handle all other states and perform additional work
160 void vvInteractorStyleNavigator::OnEnter()
162 // int x = this->Interactor->GetEventPosition()[0];
163 //int y = this->Interactor->GetEventPosition()[1];
167 case VTKIS_WINDOW_LEVEL:
177 this->InvokeEvent(vtkCommand::EnterEvent, NULL);
181 // Call parent to handle all other states and perform additional work
185 //----------------------------------------------------------------------------
186 void vvInteractorStyleNavigator::OnLeave()
188 // int x = this->Interactor->GetEventPosition()[0];
189 //int y = this->Interactor->GetEventPosition()[1];
193 case VTKIS_WINDOW_LEVEL:
203 this->InvokeEvent(vtkCommand::LeaveEvent, NULL);
207 // Call parent to handle all other states and perform additional work
211 //----------------------------------------------------------------------------
212 void vvInteractorStyleNavigator::OnRightButtonDown()
214 int x = this->Interactor->GetEventPosition()[0];
215 int y = this->Interactor->GetEventPosition()[1];
217 this->FindPokedRenderer(x, y);
218 if (this->CurrentRenderer == NULL)
223 // Redefine this button to handle window/level
224 this->GrabFocus(this->EventCallbackCommand);
225 if (!this->Interactor->GetShiftKey() && !this->Interactor->GetControlKey())
227 this->WindowLevelStartPosition[0] = x;
228 this->WindowLevelStartPosition[1] = y;
229 this->StartWindowLevel();
232 // The rest of the button + key combinations remain the same
236 this->Superclass::OnRightButtonDown();
240 //----------------------------------------------------------------------------
241 void vvInteractorStyleNavigator::OnRightButtonUp()
245 case VTKIS_WINDOW_LEVEL:
246 this->EndWindowLevel();
247 if ( this->Interactor )
249 this->ReleaseFocus();
254 // Call parent to handle all other states and perform additional work
256 this->Superclass::OnRightButtonUp();
259 //----------------------------------------------------------------------------
260 void vvInteractorStyleNavigator::OnLeftButtonDown()
262 int x = this->Interactor->GetEventPosition()[0];
263 int y = this->Interactor->GetEventPosition()[1];
265 this->FindPokedRenderer(x, y);
266 if (this->CurrentRenderer == NULL)
271 // Redefine this button to handle pick
272 this->GrabFocus(this->EventCallbackCommand);
273 if (!this->Interactor->GetShiftKey() && !this->Interactor->GetControlKey())
278 // The rest of the button + key combinations remain the same
282 this->Superclass::OnLeftButtonDown();
286 //----------------------------------------------------------------------------
287 void vvInteractorStyleNavigator::OnLeftButtonUp()
293 if ( this->Interactor )
295 this->ReleaseFocus();
300 // Call parent to handle all other states and perform additional work
302 this->Superclass::OnLeftButtonUp();
305 //----------------------------------------------------------------------------
306 void vvInteractorStyleNavigator::OnMiddleButtonDown()
308 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
309 this->Interactor->GetEventPosition()[1]);
310 if (this->CurrentRenderer == NULL)
314 this->CurrentRenderer->GetRenderWindow()->SetCurrentCursor(8);
315 this->GrabFocus(this->EventCallbackCommand);
319 //----------------------------------------------------------------------------
320 void vvInteractorStyleNavigator::OnMiddleButtonUp()
326 if ( this->Interactor )
328 this->Interactor->GetRenderWindow()->SetCurrentCursor(0);
329 this->ReleaseFocus();
335 //----------------------------------------------------------------------------
336 void vvInteractorStyleNavigator::OnChar()
338 vtkRenderWindowInteractor *rwi = this->Interactor;
340 switch (rwi->GetKeyCode())
345 this->AnimState = VTKIS_ANIM_ON;
346 this->AnimState = VTKIS_ANIM_OFF;
353 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
354 this->Interactor->GetEventPosition()[1]);
355 if (this->CurrentRenderer == NULL)
359 this->GrabFocus(this->EventCallbackCommand);
362 this->Dolly(pow((double)1.1, factor));
364 this->ReleaseFocus();
370 this->FindPokedRenderer(rwi->GetEventPosition()[0],
371 rwi->GetEventPosition()[1]);
372 if (this->CurrentRenderer == NULL)
376 this->GrabFocus(this->EventCallbackCommand);
379 this->Dolly(pow((double)1.1, factor));
381 this->ReleaseFocus();
385 // Disable StereoVision
389 //Do nothing, this is handled in vvSlicerManagerCommand
392 this->Superclass::OnChar();
397 //----------------------------------------------------------------------------
398 void vvInteractorStyleNavigator::OnMouseWheelForward()
400 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
401 this->Interactor->GetEventPosition()[1]);
402 if (this->CurrentRenderer == NULL)
406 this->GrabFocus(this->EventCallbackCommand);
407 if (this->Interactor->GetControlKey())
410 double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
411 this->Dolly(pow((double)1.1, factor));
414 this->ReleaseFocus();
415 this->InvokeEvent(vtkCommand::MouseWheelForwardEvent, this);
418 //----------------------------------------------------------------------------
419 void vvInteractorStyleNavigator::OnMouseWheelBackward()
421 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
422 this->Interactor->GetEventPosition()[1]);
423 if (this->CurrentRenderer == NULL)
428 this->GrabFocus(this->EventCallbackCommand);
429 if (this->Interactor->GetControlKey())
432 double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
433 this->Dolly(pow((double)1.1, factor));
436 this->ReleaseFocus();
437 this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, this);
441 //----------------------------------------------------------------------------
442 void vvInteractorStyleNavigator::WindowLevel()
444 vtkRenderWindowInteractor *rwi = this->Interactor;
446 this->WindowLevelCurrentPosition[0] = rwi->GetEventPosition()[0];
447 this->WindowLevelCurrentPosition[1] = rwi->GetEventPosition()[1];
449 this->InvokeEvent(vtkCommand::WindowLevelEvent, this);
452 //----------------------------------------------------------------------------
453 void vvInteractorStyleNavigator::Pick()
455 this->InvokeEvent(vtkCommand::PickEvent, this);
458 //----------------------------------------------------------------------------
459 void vvInteractorStyleNavigator::Pan()
461 if (this->CurrentRenderer == NULL)
466 vtkRenderWindowInteractor *rwi = this->Interactor;
468 double viewFocus[4], focalDepth, viewPoint[3];
469 double newPickPoint[4], oldPickPoint[4], motionVector[3];
471 // Calculate the focal depth since we'll be using it a lot
473 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
474 camera->GetFocalPoint(viewFocus);
475 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
477 focalDepth = viewFocus[2];
479 this->ComputeDisplayToWorld((double)rwi->GetEventPosition()[0],
480 (double)rwi->GetEventPosition()[1],
484 // Has to recalc old mouse point since the viewport has moved,
485 // so can't move it outside the loop
487 this->ComputeDisplayToWorld((double)rwi->GetLastEventPosition()[0],
488 (double)rwi->GetLastEventPosition()[1],
492 // Camera motion is reversed
494 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
495 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
496 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
498 camera->GetFocalPoint(viewFocus);
499 camera->GetPosition(viewPoint);
500 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
501 motionVector[1] + viewFocus[1],
502 motionVector[2] + viewFocus[2]);
504 camera->SetPosition(motionVector[0] + viewPoint[0],
505 motionVector[1] + viewPoint[1],
506 motionVector[2] + viewPoint[2]);
508 if (rwi->GetLightFollowCamera())
510 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
516 //----------------------------------------------------------------------------
517 void vvInteractorStyleNavigator::Dolly()
519 if (this->CurrentRenderer == NULL)
524 vtkRenderWindowInteractor *rwi = this->Interactor;
525 double *center = this->CurrentRenderer->GetCenter();
526 int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
527 double dyf = this->MotionFactor * (double)(dy) / (double)(center[1]);
528 this->Dolly(pow((double)1.1, dyf));
531 //----------------------------------------------------------------------------
532 void vvInteractorStyleNavigator::Dolly(double factor)
534 if (this->CurrentRenderer == NULL)
539 double viewFocus[4],viewPoint[4],motionVector[3], focalDepth;
540 double oldPos[3], newPos[3], distance[2];
541 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
542 camera->GetFocalPoint(viewFocus);
543 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
545 focalDepth = viewFocus[2];
547 oldPos[0] = this->CurrentRenderer->GetCenter()[0];
548 oldPos[1] = this->CurrentRenderer->GetCenter()[1];
549 oldPos[2] = focalDepth;
551 distance[0] = 1/factor*
552 (this->Interactor->GetEventPosition()[0]-this->CurrentRenderer->GetCenter()[0]);
553 distance[1] = 1/factor*
554 (this->Interactor->GetEventPosition()[1]-this->CurrentRenderer->GetCenter()[1]);
556 newPos[0] = this->Interactor->GetEventPosition()[0] - distance[0];
557 newPos[1] = this->Interactor->GetEventPosition()[1] - distance[1];
558 newPos[2] = focalDepth;
560 this->CurrentRenderer->DisplayToNormalizedDisplay(oldPos[0],oldPos[1]);
561 this->CurrentRenderer->NormalizedDisplayToViewport(oldPos[0],oldPos[1]);
562 this->CurrentRenderer->ViewportToNormalizedViewport(oldPos[0],oldPos[1]);
563 this->CurrentRenderer->NormalizedViewportToView(oldPos[0],oldPos[1],oldPos[2]);
564 this->CurrentRenderer->ViewToWorld(oldPos[0],oldPos[1],oldPos[2]);
566 this->CurrentRenderer->DisplayToNormalizedDisplay(newPos[0],newPos[1]);
567 this->CurrentRenderer->NormalizedDisplayToViewport(newPos[0],newPos[1]);
568 this->CurrentRenderer->ViewportToNormalizedViewport(newPos[0],newPos[1]);
569 this->CurrentRenderer->NormalizedViewportToView(newPos[0],newPos[1],newPos[2]);
570 this->CurrentRenderer->ViewToWorld(newPos[0],newPos[1],newPos[2]);
572 motionVector[0] = newPos[0] - oldPos[0];
573 motionVector[1] = newPos[1] - oldPos[1];
574 motionVector[2] = newPos[2] - oldPos[2];
576 camera->GetFocalPoint(viewFocus);
577 camera->GetPosition(viewPoint);
578 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
579 motionVector[1] + viewFocus[1],
580 motionVector[2] + viewFocus[2]);
582 camera->SetPosition(motionVector[0] + viewPoint[0],
583 motionVector[1] + viewPoint[1],
584 motionVector[2] + viewPoint[2]);
586 if (camera->GetParallelProjection())
588 camera->SetParallelScale(camera->GetParallelScale() / factor);
592 camera->Dolly(factor);
593 if (this->AutoAdjustCameraClippingRange)
595 this->CurrentRenderer->ResetCameraClippingRange();
599 if (this->Interactor->GetLightFollowCamera())
601 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
603 this->CurrentRenderer->ResetCameraClippingRange();
604 //this->Interactor->Render();
608 //----------------------------------------------------------------------------
609 void vvInteractorStyleNavigator::PrintSelf(ostream& os, vtkIndent indent)
611 this->Superclass::PrintSelf(os, indent);
613 os << indent << "Window Level Current Position: ("
614 << this->WindowLevelCurrentPosition[0] << ", "
615 << this->WindowLevelCurrentPosition[1] << ")" << endl;
617 os << indent << "Window Level Start Position: ("
618 << this->WindowLevelStartPosition[0] << ", "
619 << this->WindowLevelStartPosition[1] << ")" << endl;