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()) {
253 this->OnMiddleButtonDown();
255 else if (!this->Interactor->GetControlKey()) {
259 // The rest of the button + key combinations remain the same
262 this->Superclass::OnLeftButtonDown();
266 //----------------------------------------------------------------------------
267 void vvInteractorStyleNavigator::OnLeftButtonUp()
269 // DD("OnLeftButtonUp");
270 switch (this->State) {
273 if ( this->Interactor ) {
274 this->ReleaseFocus();
278 this->OnMiddleButtonUp();
282 // Call parent to handle all other states and perform additional work
284 this->Superclass::OnLeftButtonUp();
287 //----------------------------------------------------------------------------
288 void vvInteractorStyleNavigator::OnMiddleButtonDown()
290 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
291 this->Interactor->GetEventPosition()[1]);
292 if (this->CurrentRenderer == NULL) {
295 this->CurrentRenderer->GetRenderWindow()->SetCurrentCursor(8);
296 this->GrabFocus(this->EventCallbackCommand);
300 //----------------------------------------------------------------------------
301 void vvInteractorStyleNavigator::OnMiddleButtonUp()
303 switch (this->State) {
306 if ( this->Interactor ) {
307 this->Interactor->GetRenderWindow()->SetCurrentCursor(0);
308 this->ReleaseFocus();
314 //----------------------------------------------------------------------------
315 void vvInteractorStyleNavigator::OnChar()
317 vtkRenderWindowInteractor *rwi = this->Interactor;
319 switch (rwi->GetKeyCode()) {
322 this->AnimState = VTKIS_ANIM_ON;
323 this->AnimState = VTKIS_ANIM_OFF;
329 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
330 this->Interactor->GetEventPosition()[1]);
331 if (this->CurrentRenderer == NULL) {
334 this->GrabFocus(this->EventCallbackCommand);
337 this->Dolly(pow((double)1.1, factor));
339 this->ReleaseFocus();
344 this->FindPokedRenderer(rwi->GetEventPosition()[0],
345 rwi->GetEventPosition()[1]);
346 if (this->CurrentRenderer == NULL) {
349 this->GrabFocus(this->EventCallbackCommand);
352 this->Dolly(pow((double)1.1, factor));
354 this->ReleaseFocus();
358 // Disable StereoVision
362 //Do nothing, this is handled in vvSlicerManagerCommand
365 //SR: we don't use the default vtk keys => removed to avoid conflicts
366 //this->Superclass::OnChar();
371 //----------------------------------------------------------------------------
372 void vvInteractorStyleNavigator::OnMouseWheelForward()
374 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
375 this->Interactor->GetEventPosition()[1]);
376 if (this->CurrentRenderer == NULL) {
379 this->GrabFocus(this->EventCallbackCommand);
380 if (this->Interactor->GetControlKey()) {
382 double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
383 this->Dolly(pow((double)1.1, factor));
386 this->ReleaseFocus();
387 this->InvokeEvent(vtkCommand::MouseWheelForwardEvent, this);
390 //----------------------------------------------------------------------------
391 void vvInteractorStyleNavigator::OnMouseWheelBackward()
393 this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
394 this->Interactor->GetEventPosition()[1]);
395 if (this->CurrentRenderer == NULL) {
399 this->GrabFocus(this->EventCallbackCommand);
400 if (this->Interactor->GetControlKey()) {
402 double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
403 this->Dolly(pow((double)1.1, factor));
406 this->ReleaseFocus();
407 this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, this);
411 //----------------------------------------------------------------------------
412 void vvInteractorStyleNavigator::WindowLevel()
414 vtkRenderWindowInteractor *rwi = this->Interactor;
416 this->WindowLevelCurrentPosition[0] = rwi->GetEventPosition()[0];
417 this->WindowLevelCurrentPosition[1] = rwi->GetEventPosition()[1];
419 this->InvokeEvent(vtkCommand::WindowLevelEvent, this);
422 //----------------------------------------------------------------------------
423 void vvInteractorStyleNavigator::Pick()
425 this->InvokeEvent(vtkCommand::PickEvent, this);
428 //----------------------------------------------------------------------------
429 void vvInteractorStyleNavigator::Pan()
431 if (this->CurrentRenderer == NULL) {
435 vtkRenderWindowInteractor *rwi = this->Interactor;
437 double viewFocus[4], focalDepth, viewPoint[3];
438 double newPickPoint[4], oldPickPoint[4], motionVector[3];
440 // Calculate the focal depth since we'll be using it a lot
442 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
443 camera->GetFocalPoint(viewFocus);
444 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
446 focalDepth = viewFocus[2];
448 this->ComputeDisplayToWorld((double)rwi->GetEventPosition()[0],
449 (double)rwi->GetEventPosition()[1],
453 // Has to recalc old mouse point since the viewport has moved,
454 // so can't move it outside the loop
456 this->ComputeDisplayToWorld((double)rwi->GetLastEventPosition()[0],
457 (double)rwi->GetLastEventPosition()[1],
461 // Camera motion is reversed
463 motionVector[0] = oldPickPoint[0] - newPickPoint[0];
464 motionVector[1] = oldPickPoint[1] - newPickPoint[1];
465 motionVector[2] = oldPickPoint[2] - newPickPoint[2];
467 camera->GetFocalPoint(viewFocus);
468 camera->GetPosition(viewPoint);
469 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
470 motionVector[1] + viewFocus[1],
471 motionVector[2] + viewFocus[2]);
473 camera->SetPosition(motionVector[0] + viewPoint[0],
474 motionVector[1] + viewPoint[1],
475 motionVector[2] + viewPoint[2]);
477 if (rwi->GetLightFollowCamera()) {
478 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
481 this->InvokeEvent(vtkCommand::EndInteractionEvent, this);
486 //----------------------------------------------------------------------------
487 void vvInteractorStyleNavigator::Dolly()
489 if (this->CurrentRenderer == NULL) {
493 vtkRenderWindowInteractor *rwi = this->Interactor;
494 double *center = this->CurrentRenderer->GetCenter();
495 int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
496 double dyf = this->MotionFactor * (double)(dy) / (double)(center[1]);
497 this->Dolly(pow((double)1.1, dyf));
500 //----------------------------------------------------------------------------
501 void vvInteractorStyleNavigator::Dolly(double factor)
503 if (this->CurrentRenderer == NULL) {
507 double viewFocus[4],viewPoint[4],motionVector[3], focalDepth;
508 double oldPos[3], newPos[3], distance[2];
509 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
510 camera->GetFocalPoint(viewFocus);
511 this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
513 focalDepth = viewFocus[2];
515 oldPos[0] = this->CurrentRenderer->GetCenter()[0];
516 oldPos[1] = this->CurrentRenderer->GetCenter()[1];
517 oldPos[2] = focalDepth;
519 distance[0] = 1/factor*
520 (this->Interactor->GetEventPosition()[0]-this->CurrentRenderer->GetCenter()[0]);
521 distance[1] = 1/factor*
522 (this->Interactor->GetEventPosition()[1]-this->CurrentRenderer->GetCenter()[1]);
524 newPos[0] = this->Interactor->GetEventPosition()[0] - distance[0];
525 newPos[1] = this->Interactor->GetEventPosition()[1] - distance[1];
526 newPos[2] = focalDepth;
528 this->CurrentRenderer->DisplayToNormalizedDisplay(oldPos[0],oldPos[1]);
529 this->CurrentRenderer->NormalizedDisplayToViewport(oldPos[0],oldPos[1]);
530 this->CurrentRenderer->ViewportToNormalizedViewport(oldPos[0],oldPos[1]);
531 this->CurrentRenderer->NormalizedViewportToView(oldPos[0],oldPos[1],oldPos[2]);
532 this->CurrentRenderer->ViewToWorld(oldPos[0],oldPos[1],oldPos[2]);
534 this->CurrentRenderer->DisplayToNormalizedDisplay(newPos[0],newPos[1]);
535 this->CurrentRenderer->NormalizedDisplayToViewport(newPos[0],newPos[1]);
536 this->CurrentRenderer->ViewportToNormalizedViewport(newPos[0],newPos[1]);
537 this->CurrentRenderer->NormalizedViewportToView(newPos[0],newPos[1],newPos[2]);
538 this->CurrentRenderer->ViewToWorld(newPos[0],newPos[1],newPos[2]);
540 motionVector[0] = newPos[0] - oldPos[0];
541 motionVector[1] = newPos[1] - oldPos[1];
542 motionVector[2] = newPos[2] - oldPos[2];
544 camera->GetFocalPoint(viewFocus);
545 camera->GetPosition(viewPoint);
546 camera->SetFocalPoint(motionVector[0] + viewFocus[0],
547 motionVector[1] + viewFocus[1],
548 motionVector[2] + viewFocus[2]);
550 camera->SetPosition(motionVector[0] + viewPoint[0],
551 motionVector[1] + viewPoint[1],
552 motionVector[2] + viewPoint[2]);
554 if (camera->GetParallelProjection()) {
555 camera->SetParallelScale(camera->GetParallelScale() / factor);
557 camera->Dolly(factor);
558 if (this->AutoAdjustCameraClippingRange) {
559 this->CurrentRenderer->ResetCameraClippingRange();
563 if (this->Interactor->GetLightFollowCamera()) {
564 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
566 this->CurrentRenderer->ResetCameraClippingRange();
567 //this->Interactor->Render();
569 this->InvokeEvent(vtkCommand::EndInteractionEvent, this);
573 //----------------------------------------------------------------------------
574 void vvInteractorStyleNavigator::PrintSelf(ostream& os, vtkIndent indent)
576 this->Superclass::PrintSelf(os, indent);
578 os << indent << "Window Level Current Position: ("
579 << this->WindowLevelCurrentPosition[0] << ", "
580 << this->WindowLevelCurrentPosition[1] << ")" << endl;
582 os << indent << "Window Level Start Position: ("
583 << this->WindowLevelStartPosition[0] << ", "
584 << this->WindowLevelStartPosition[1] << ")" << endl;