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();
59 vtkRenderer* current = renwin->GetRenderers()->GetNextItem();
60 if (current==NULL || current->GetDraw()) {
61 CurrentRenderer=current;
67 //----------------------------------------------------------------------------
68 void vvInteractorStyleNavigator::StartWindowLevel()
70 if (this->State != VTKIS_NONE) {
73 this->StartState(VTKIS_WINDOW_LEVEL);
74 this->InvokeEvent(vtkCommand::StartWindowLevelEvent,this);
77 //----------------------------------------------------------------------------
78 void vvInteractorStyleNavigator::EndWindowLevel()
80 if (this->State != VTKIS_WINDOW_LEVEL) {
83 this->InvokeEvent(vtkCommand::EndWindowLevelEvent, this);
87 //----------------------------------------------------------------------------
88 void vvInteractorStyleNavigator::StartPick()
90 if (this->State != VTKIS_NONE) {
93 this->StartState(VTKIS_PICK);
94 this->InvokeEvent(vtkCommand::StartPickEvent, this);
97 //----------------------------------------------------------------------------
98 void vvInteractorStyleNavigator::EndPick()
100 if (this->State != VTKIS_PICK) {
103 this->InvokeEvent(vtkCommand::EndPickEvent, this);
107 //----------------------------------------------------------------------------
108 void vvInteractorStyleNavigator::OnMouseMove()
110 int x = this->Interactor->GetEventPosition()[0];
111 int y = this->Interactor->GetEventPosition()[1];
113 switch (this->State) {
114 case VTKIS_WINDOW_LEVEL:
115 this->FindPokedRenderer(x, y);
117 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
121 this->FindPokedRenderer(x, y);
123 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
127 this->FindPokedRenderer(x, y);
129 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
133 this->FindPokedRenderer(x, y);
135 this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
139 this->InvokeEvent(vtkCommand::UserEvent, NULL);
143 // Call parent to handle all other states and perform additional work
147 void vvInteractorStyleNavigator::OnEnter()
149 // int x = this->Interactor->GetEventPosition()[0];
150 //int y = this->Interactor->GetEventPosition()[1];
152 switch (this->State) {
153 case VTKIS_WINDOW_LEVEL:
163 this->InvokeEvent(vtkCommand::EnterEvent, NULL);
167 // Call parent to handle all other states and perform additional work
171 //----------------------------------------------------------------------------
172 void vvInteractorStyleNavigator::OnLeave()
174 // int x = this->Interactor->GetEventPosition()[0];
175 //int y = this->Interactor->GetEventPosition()[1];
177 switch (this->State) {
178 case VTKIS_WINDOW_LEVEL:
188 this->InvokeEvent(vtkCommand::LeaveEvent, NULL);
192 // Call parent to handle all other states and perform additional work
196 //----------------------------------------------------------------------------
197 void vvInteractorStyleNavigator::OnRightButtonDown()
199 int x = this->Interactor->GetEventPosition()[0];
200 int y = this->Interactor->GetEventPosition()[1];
202 this->FindPokedRenderer(x, y);
203 if (this->CurrentRenderer == NULL) {
207 // Redefine this button to handle window/level
208 this->GrabFocus(this->EventCallbackCommand);
209 if (!this->Interactor->GetShiftKey() && !this->Interactor->GetControlKey()) {
210 this->WindowLevelStartPosition[0] = x;
211 this->WindowLevelStartPosition[1] = y;
212 this->StartWindowLevel();
215 // The rest of the button + key combinations remain the same
218 this->Superclass::OnRightButtonDown();
222 //----------------------------------------------------------------------------
223 void vvInteractorStyleNavigator::OnRightButtonUp()
225 switch (this->State) {
226 case VTKIS_WINDOW_LEVEL:
227 this->EndWindowLevel();
228 if ( this->Interactor ) {
229 this->ReleaseFocus();
234 // Call parent to handle all other states and perform additional work
236 this->Superclass::OnRightButtonUp();
239 //----------------------------------------------------------------------------
240 void vvInteractorStyleNavigator::OnLeftButtonDown()
242 int x = this->Interactor->GetEventPosition()[0];
243 int y = this->Interactor->GetEventPosition()[1];
245 this->FindPokedRenderer(x, y);
246 if (this->CurrentRenderer == NULL) {
250 // Redefine this button to handle pick
251 this->GrabFocus(this->EventCallbackCommand);
252 if (!this->Interactor->GetShiftKey() && !this->Interactor->GetControlKey()) {
256 // The rest of the button + key combinations remain the same
259 this->Superclass::OnLeftButtonDown();
263 //----------------------------------------------------------------------------
264 void vvInteractorStyleNavigator::OnLeftButtonUp()
266 // DD("OnLeftButtonUp");
267 switch (this->State) {
270 if ( this->Interactor ) {
271 this->ReleaseFocus();
276 // Call parent to handle all other states and perform additional work
278 this->Superclass::OnLeftButtonUp();
281 //----------------------------------------------------------------------------
282 void vvInteractorStyleNavigator::OnMiddleButtonDown()
284 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
285 this->Interactor->GetEventPosition()[1]);
286 if (this->CurrentRenderer == NULL) {
289 this->CurrentRenderer->GetRenderWindow()->SetCurrentCursor(8);
290 this->GrabFocus(this->EventCallbackCommand);
294 //----------------------------------------------------------------------------
295 void vvInteractorStyleNavigator::OnMiddleButtonUp()
297 switch (this->State) {
300 if ( this->Interactor ) {
301 this->Interactor->GetRenderWindow()->SetCurrentCursor(0);
302 this->ReleaseFocus();
308 //----------------------------------------------------------------------------
309 void vvInteractorStyleNavigator::OnChar()
311 vtkRenderWindowInteractor *rwi = this->Interactor;
313 switch (rwi->GetKeyCode()) {
316 this->AnimState = VTKIS_ANIM_ON;
317 this->AnimState = VTKIS_ANIM_OFF;
323 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
324 this->Interactor->GetEventPosition()[1]);
325 if (this->CurrentRenderer == NULL) {
328 this->GrabFocus(this->EventCallbackCommand);
331 this->Dolly(pow((double)1.1, factor));
333 this->ReleaseFocus();
338 this->FindPokedRenderer(rwi->GetEventPosition()[0],
339 rwi->GetEventPosition()[1]);
340 if (this->CurrentRenderer == NULL) {
343 this->GrabFocus(this->EventCallbackCommand);
346 this->Dolly(pow((double)1.1, factor));
348 this->ReleaseFocus();
352 // Disable StereoVision
356 //Do nothing, this is handled in vvSlicerManagerCommand
359 this->Superclass::OnChar();
364 //----------------------------------------------------------------------------
365 void vvInteractorStyleNavigator::OnMouseWheelForward()
367 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
368 this->Interactor->GetEventPosition()[1]);
369 if (this->CurrentRenderer == NULL) {
372 this->GrabFocus(this->EventCallbackCommand);
373 if (this->Interactor->GetControlKey()) {
375 double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
376 this->Dolly(pow((double)1.1, factor));
379 this->ReleaseFocus();
380 this->InvokeEvent(vtkCommand::MouseWheelForwardEvent, this);
383 //----------------------------------------------------------------------------
384 void vvInteractorStyleNavigator::OnMouseWheelBackward()
386 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
387 this->Interactor->GetEventPosition()[1]);
388 if (this->CurrentRenderer == NULL) {
392 this->GrabFocus(this->EventCallbackCommand);
393 if (this->Interactor->GetControlKey()) {
395 double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
396 this->Dolly(pow((double)1.1, factor));
399 this->ReleaseFocus();
400 this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, this);
404 //----------------------------------------------------------------------------
405 void vvInteractorStyleNavigator::WindowLevel()
407 vtkRenderWindowInteractor *rwi = this->Interactor;
409 this->WindowLevelCurrentPosition[0] = rwi->GetEventPosition()[0];
410 this->WindowLevelCurrentPosition[1] = rwi->GetEventPosition()[1];
412 this->InvokeEvent(vtkCommand::WindowLevelEvent, this);
415 //----------------------------------------------------------------------------
416 void vvInteractorStyleNavigator::Pick()
418 this->InvokeEvent(vtkCommand::PickEvent, this);
421 //----------------------------------------------------------------------------
422 void vvInteractorStyleNavigator::Pan()
424 if (this->CurrentRenderer == NULL) {
428 vtkRenderWindowInteractor *rwi = this->Interactor;
430 double viewFocus[4], focalDepth, viewPoint[3];
431 double newPickPoint[4], oldPickPoint[4], motionVector[3];
433 // Calculate the focal depth since we'll be using it a lot
435 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
436 camera->GetFocalPoint(viewFocus);
437 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
439 focalDepth = viewFocus[2];
441 this->ComputeDisplayToWorld((double)rwi->GetEventPosition()[0],
442 (double)rwi->GetEventPosition()[1],
446 // Has to recalc old mouse point since the viewport has moved,
447 // so can't move it outside the loop
449 this->ComputeDisplayToWorld((double)rwi->GetLastEventPosition()[0],
450 (double)rwi->GetLastEventPosition()[1],
454 // Camera motion is reversed
456 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
457 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
458 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
460 camera->GetFocalPoint(viewFocus);
461 camera->GetPosition(viewPoint);
462 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
463 motionVector[1] + viewFocus[1],
464 motionVector[2] + viewFocus[2]);
466 camera->SetPosition(motionVector[0] + viewPoint[0],
467 motionVector[1] + viewPoint[1],
468 motionVector[2] + viewPoint[2]);
470 if (rwi->GetLightFollowCamera()) {
471 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
477 //----------------------------------------------------------------------------
478 void vvInteractorStyleNavigator::Dolly()
480 if (this->CurrentRenderer == NULL) {
484 vtkRenderWindowInteractor *rwi = this->Interactor;
485 double *center = this->CurrentRenderer->GetCenter();
486 int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
487 double dyf = this->MotionFactor * (double)(dy) / (double)(center[1]);
488 this->Dolly(pow((double)1.1, dyf));
491 //----------------------------------------------------------------------------
492 void vvInteractorStyleNavigator::Dolly(double factor)
494 if (this->CurrentRenderer == NULL) {
498 double viewFocus[4],viewPoint[4],motionVector[3], focalDepth;
499 double oldPos[3], newPos[3], distance[2];
500 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
501 camera->GetFocalPoint(viewFocus);
502 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
504 focalDepth = viewFocus[2];
506 oldPos[0] = this->CurrentRenderer->GetCenter()[0];
507 oldPos[1] = this->CurrentRenderer->GetCenter()[1];
508 oldPos[2] = focalDepth;
510 distance[0] = 1/factor*
511 (this->Interactor->GetEventPosition()[0]-this->CurrentRenderer->GetCenter()[0]);
512 distance[1] = 1/factor*
513 (this->Interactor->GetEventPosition()[1]-this->CurrentRenderer->GetCenter()[1]);
515 newPos[0] = this->Interactor->GetEventPosition()[0] - distance[0];
516 newPos[1] = this->Interactor->GetEventPosition()[1] - distance[1];
517 newPos[2] = focalDepth;
519 this->CurrentRenderer->DisplayToNormalizedDisplay(oldPos[0],oldPos[1]);
520 this->CurrentRenderer->NormalizedDisplayToViewport(oldPos[0],oldPos[1]);
521 this->CurrentRenderer->ViewportToNormalizedViewport(oldPos[0],oldPos[1]);
522 this->CurrentRenderer->NormalizedViewportToView(oldPos[0],oldPos[1],oldPos[2]);
523 this->CurrentRenderer->ViewToWorld(oldPos[0],oldPos[1],oldPos[2]);
525 this->CurrentRenderer->DisplayToNormalizedDisplay(newPos[0],newPos[1]);
526 this->CurrentRenderer->NormalizedDisplayToViewport(newPos[0],newPos[1]);
527 this->CurrentRenderer->ViewportToNormalizedViewport(newPos[0],newPos[1]);
528 this->CurrentRenderer->NormalizedViewportToView(newPos[0],newPos[1],newPos[2]);
529 this->CurrentRenderer->ViewToWorld(newPos[0],newPos[1],newPos[2]);
531 motionVector[0] = newPos[0] - oldPos[0];
532 motionVector[1] = newPos[1] - oldPos[1];
533 motionVector[2] = newPos[2] - oldPos[2];
535 camera->GetFocalPoint(viewFocus);
536 camera->GetPosition(viewPoint);
537 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
538 motionVector[1] + viewFocus[1],
539 motionVector[2] + viewFocus[2]);
541 camera->SetPosition(motionVector[0] + viewPoint[0],
542 motionVector[1] + viewPoint[1],
543 motionVector[2] + viewPoint[2]);
545 if (camera->GetParallelProjection()) {
546 camera->SetParallelScale(camera->GetParallelScale() / factor);
548 camera->Dolly(factor);
549 if (this->AutoAdjustCameraClippingRange) {
550 this->CurrentRenderer->ResetCameraClippingRange();
554 if (this->Interactor->GetLightFollowCamera()) {
555 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
557 this->CurrentRenderer->ResetCameraClippingRange();
558 //this->Interactor->Render();
562 //----------------------------------------------------------------------------
563 void vvInteractorStyleNavigator::PrintSelf(ostream& os, vtkIndent indent)
565 this->Superclass::PrintSelf(os, indent);
567 os << indent << "Window Level Current Position: ("
568 << this->WindowLevelCurrentPosition[0] << ", "
569 << this->WindowLevelCurrentPosition[1] << ")" << endl;
571 os << indent << "Window Level Start Position: ("
572 << this->WindowLevelStartPosition[0] << ", "
573 << this->WindowLevelStartPosition[1] << ")" << endl;