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://www.centreleonberard.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 //SR: we don't use the default vtk keys => removed to avoid conflicts
360 //this->Superclass::OnChar();
365 //----------------------------------------------------------------------------
366 void vvInteractorStyleNavigator::OnMouseWheelForward()
368 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
369 this->Interactor->GetEventPosition()[1]);
370 if (this->CurrentRenderer == NULL) {
373 this->GrabFocus(this->EventCallbackCommand);
374 if (this->Interactor->GetControlKey()) {
376 double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
377 this->Dolly(pow((double)1.1, factor));
380 this->ReleaseFocus();
381 this->InvokeEvent(vtkCommand::MouseWheelForwardEvent, this);
384 //----------------------------------------------------------------------------
385 void vvInteractorStyleNavigator::OnMouseWheelBackward()
387 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
388 this->Interactor->GetEventPosition()[1]);
389 if (this->CurrentRenderer == NULL) {
393 this->GrabFocus(this->EventCallbackCommand);
394 if (this->Interactor->GetControlKey()) {
396 double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
397 this->Dolly(pow((double)1.1, factor));
400 this->ReleaseFocus();
401 this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, this);
405 //----------------------------------------------------------------------------
406 void vvInteractorStyleNavigator::WindowLevel()
408 vtkRenderWindowInteractor *rwi = this->Interactor;
410 this->WindowLevelCurrentPosition[0] = rwi->GetEventPosition()[0];
411 this->WindowLevelCurrentPosition[1] = rwi->GetEventPosition()[1];
413 this->InvokeEvent(vtkCommand::WindowLevelEvent, this);
416 //----------------------------------------------------------------------------
417 void vvInteractorStyleNavigator::Pick()
419 this->InvokeEvent(vtkCommand::PickEvent, this);
422 //----------------------------------------------------------------------------
423 void vvInteractorStyleNavigator::Pan()
425 if (this->CurrentRenderer == NULL) {
429 vtkRenderWindowInteractor *rwi = this->Interactor;
431 double viewFocus[4], focalDepth, viewPoint[3];
432 double newPickPoint[4], oldPickPoint[4], motionVector[3];
434 // Calculate the focal depth since we'll be using it a lot
436 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
437 camera->GetFocalPoint(viewFocus);
438 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
440 focalDepth = viewFocus[2];
442 this->ComputeDisplayToWorld((double)rwi->GetEventPosition()[0],
443 (double)rwi->GetEventPosition()[1],
447 // Has to recalc old mouse point since the viewport has moved,
448 // so can't move it outside the loop
450 this->ComputeDisplayToWorld((double)rwi->GetLastEventPosition()[0],
451 (double)rwi->GetLastEventPosition()[1],
455 // Camera motion is reversed
457 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
458 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
459 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
461 camera->GetFocalPoint(viewFocus);
462 camera->GetPosition(viewPoint);
463 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
464 motionVector[1] + viewFocus[1],
465 motionVector[2] + viewFocus[2]);
467 camera->SetPosition(motionVector[0] + viewPoint[0],
468 motionVector[1] + viewPoint[1],
469 motionVector[2] + viewPoint[2]);
471 if (rwi->GetLightFollowCamera()) {
472 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
475 this->InvokeEvent(vtkCommand::EndInteractionEvent, this);
480 //----------------------------------------------------------------------------
481 void vvInteractorStyleNavigator::Dolly()
483 if (this->CurrentRenderer == NULL) {
487 vtkRenderWindowInteractor *rwi = this->Interactor;
488 double *center = this->CurrentRenderer->GetCenter();
489 int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
490 double dyf = this->MotionFactor * (double)(dy) / (double)(center[1]);
491 this->Dolly(pow((double)1.1, dyf));
494 //----------------------------------------------------------------------------
495 void vvInteractorStyleNavigator::Dolly(double factor)
497 if (this->CurrentRenderer == NULL) {
501 double viewFocus[4],viewPoint[4],motionVector[3], focalDepth;
502 double oldPos[3], newPos[3], distance[2];
503 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
504 camera->GetFocalPoint(viewFocus);
505 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
507 focalDepth = viewFocus[2];
509 oldPos[0] = this->CurrentRenderer->GetCenter()[0];
510 oldPos[1] = this->CurrentRenderer->GetCenter()[1];
511 oldPos[2] = focalDepth;
513 distance[0] = 1/factor*
514 (this->Interactor->GetEventPosition()[0]-this->CurrentRenderer->GetCenter()[0]);
515 distance[1] = 1/factor*
516 (this->Interactor->GetEventPosition()[1]-this->CurrentRenderer->GetCenter()[1]);
518 newPos[0] = this->Interactor->GetEventPosition()[0] - distance[0];
519 newPos[1] = this->Interactor->GetEventPosition()[1] - distance[1];
520 newPos[2] = focalDepth;
522 this->CurrentRenderer->DisplayToNormalizedDisplay(oldPos[0],oldPos[1]);
523 this->CurrentRenderer->NormalizedDisplayToViewport(oldPos[0],oldPos[1]);
524 this->CurrentRenderer->ViewportToNormalizedViewport(oldPos[0],oldPos[1]);
525 this->CurrentRenderer->NormalizedViewportToView(oldPos[0],oldPos[1],oldPos[2]);
526 this->CurrentRenderer->ViewToWorld(oldPos[0],oldPos[1],oldPos[2]);
528 this->CurrentRenderer->DisplayToNormalizedDisplay(newPos[0],newPos[1]);
529 this->CurrentRenderer->NormalizedDisplayToViewport(newPos[0],newPos[1]);
530 this->CurrentRenderer->ViewportToNormalizedViewport(newPos[0],newPos[1]);
531 this->CurrentRenderer->NormalizedViewportToView(newPos[0],newPos[1],newPos[2]);
532 this->CurrentRenderer->ViewToWorld(newPos[0],newPos[1],newPos[2]);
534 motionVector[0] = newPos[0] - oldPos[0];
535 motionVector[1] = newPos[1] - oldPos[1];
536 motionVector[2] = newPos[2] - oldPos[2];
538 camera->GetFocalPoint(viewFocus);
539 camera->GetPosition(viewPoint);
540 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
541 motionVector[1] + viewFocus[1],
542 motionVector[2] + viewFocus[2]);
544 camera->SetPosition(motionVector[0] + viewPoint[0],
545 motionVector[1] + viewPoint[1],
546 motionVector[2] + viewPoint[2]);
548 if (camera->GetParallelProjection()) {
549 camera->SetParallelScale(camera->GetParallelScale() / factor);
551 camera->Dolly(factor);
552 if (this->AutoAdjustCameraClippingRange) {
553 this->CurrentRenderer->ResetCameraClippingRange();
557 if (this->Interactor->GetLightFollowCamera()) {
558 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
560 this->CurrentRenderer->ResetCameraClippingRange();
561 //this->Interactor->Render();
563 this->InvokeEvent(vtkCommand::EndInteractionEvent, this);
567 //----------------------------------------------------------------------------
568 void vvInteractorStyleNavigator::PrintSelf(ostream& os, vtkIndent indent)
570 this->Superclass::PrintSelf(os, indent);
572 os << indent << "Window Level Current Position: ("
573 << this->WindowLevelCurrentPosition[0] << ", "
574 << this->WindowLevelCurrentPosition[1] << ")" << endl;
576 os << indent << "Window Level Start Position: ("
577 << this->WindowLevelStartPosition[0] << ", "
578 << this->WindowLevelStartPosition[1] << ")" << endl;