]> Creatis software - clitk.git/blob - vv/vvInteractorStyleNavigator.cxx
Initial revision
[clitk.git] / vv / vvInteractorStyleNavigator.cxx
1 /*=========================================================================
2
3  Program:   vv
4  Module:    $RCSfile: vvInteractorStyleNavigator.cxx,v $
5  Language:  C++
6  Date:      $Date: 2010/01/06 13:31:57 $
7  Version:   $Revision: 1.1 $
8  Author :   Pierre Seroul (pierre.seroul@gmail.com)
9
10 Copyright (C) 2008
11 Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
12 CREATIS-LRMN http://www.creatis.insa-lyon.fr
13
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.
17
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.
22
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/>.
25
26 =========================================================================*/
27 #include "vvInteractorStyleNavigator.h"
28
29 #include "vtkAbstractPropPicker.h"
30 #include "vtkAssemblyPath.h"
31 #include "vtkCallbackCommand.h"
32 #include "vtkMath.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"
40
41
42 vtkCxxRevisionMacro(vvInteractorStyleNavigator, "$Revision: 1.1 $");
43 vtkStandardNewMacro(vvInteractorStyleNavigator);
44
45 //----------------------------------------------------------------------------
46 vvInteractorStyleNavigator::vvInteractorStyleNavigator()
47 {
48     this->WindowLevelStartPosition[0]   = 0;
49     this->WindowLevelStartPosition[1]   = 0;
50
51     this->WindowLevelCurrentPosition[0] = 0;
52     this->WindowLevelCurrentPosition[1] = 0;
53
54     this->MotionFactor   = 10.0;
55 }
56
57 //----------------------------------------------------------------------------
58 vvInteractorStyleNavigator::~vvInteractorStyleNavigator()
59 {
60     CurrentRenderer=NULL;
61 }
62
63 void vvInteractorStyleNavigator::FindPokedRenderer(int dummy1,int dummy2)
64 {
65     vtkRenderWindow * renwin=this->GetInteractor()->GetRenderWindow();
66     renwin->GetRenderers()->InitTraversal();
67     while (true)
68     {
69         vtkRenderer* current = renwin->GetRenderers()->GetNextItem();
70         if (current==NULL || current->GetDraw())
71         {
72             CurrentRenderer=current;
73             return;
74         }
75     }
76 }
77
78 //----------------------------------------------------------------------------
79 void vvInteractorStyleNavigator::StartWindowLevel()
80 {
81     if (this->State != VTKIS_NONE)
82     {
83         return;
84     }
85     this->StartState(VTKIS_WINDOW_LEVEL);
86     this->InvokeEvent(vtkCommand::StartWindowLevelEvent,this);
87 }
88
89 //----------------------------------------------------------------------------
90 void vvInteractorStyleNavigator::EndWindowLevel()
91 {
92     if (this->State != VTKIS_WINDOW_LEVEL)
93     {
94         return;
95     }
96     this->InvokeEvent(vtkCommand::EndWindowLevelEvent, this);
97     this->StopState();
98 }
99
100 //----------------------------------------------------------------------------
101 void vvInteractorStyleNavigator::StartPick()
102 {
103     if (this->State != VTKIS_NONE)
104     {
105         return;
106     }
107     this->StartState(VTKIS_PICK);
108     this->InvokeEvent(vtkCommand::StartPickEvent, this);
109 }
110
111 //----------------------------------------------------------------------------
112 void vvInteractorStyleNavigator::EndPick()
113 {
114     if (this->State != VTKIS_PICK)
115     {
116         return;
117     }
118     this->InvokeEvent(vtkCommand::EndPickEvent, this);
119     this->StopState();
120 }
121
122 //----------------------------------------------------------------------------
123 void vvInteractorStyleNavigator::OnMouseMove()
124 {
125     int x = this->Interactor->GetEventPosition()[0];
126     int y = this->Interactor->GetEventPosition()[1];
127
128     switch (this->State)
129     {
130     case VTKIS_WINDOW_LEVEL:
131         this->FindPokedRenderer(x, y);
132         this->WindowLevel();
133         this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
134         break;
135
136     case VTKIS_PICK:
137         this->FindPokedRenderer(x, y);
138         this->Pick();
139         this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
140         break;
141
142     case VTKIS_PAN:
143         this->FindPokedRenderer(x, y);
144         this->Pan();
145         this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
146         break;
147
148     case VTKIS_DOLLY:
149         this->FindPokedRenderer(x, y);
150         this->Dolly();
151         this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
152         break;
153
154     default:
155         this->InvokeEvent(vtkCommand::UserEvent, NULL);
156         break;
157     }
158
159     // Call parent to handle all other states and perform additional work
160
161 }
162
163 void vvInteractorStyleNavigator::OnEnter()
164 {
165     //  int x = this->Interactor->GetEventPosition()[0];
166     //int y = this->Interactor->GetEventPosition()[1];
167
168     switch (this->State)
169     {
170     case VTKIS_WINDOW_LEVEL:
171         break;
172
173     case VTKIS_PICK:
174         break;
175
176     case VTKIS_PAN:
177         break;
178
179     default:
180         this->InvokeEvent(vtkCommand::EnterEvent, NULL);
181         break;
182     }
183
184     // Call parent to handle all other states and perform additional work
185
186 }
187
188 //----------------------------------------------------------------------------
189 void vvInteractorStyleNavigator::OnLeave()
190 {
191     //  int x = this->Interactor->GetEventPosition()[0];
192     //int y = this->Interactor->GetEventPosition()[1];
193
194     switch (this->State)
195     {
196     case VTKIS_WINDOW_LEVEL:
197         break;
198
199     case VTKIS_PICK:
200         break;
201
202     case VTKIS_PAN:
203         break;
204
205     default:
206         this->InvokeEvent(vtkCommand::LeaveEvent, NULL);
207         break;
208     }
209
210     // Call parent to handle all other states and perform additional work
211
212 }
213
214 //----------------------------------------------------------------------------
215 void vvInteractorStyleNavigator::OnRightButtonDown()
216 {
217     int x = this->Interactor->GetEventPosition()[0];
218     int y = this->Interactor->GetEventPosition()[1];
219
220     this->FindPokedRenderer(x, y);
221     if (this->CurrentRenderer == NULL)
222     {
223         return;
224     }
225
226     // Redefine this button to handle window/level
227     this->GrabFocus(this->EventCallbackCommand);
228     if (!this->Interactor->GetShiftKey() && !this->Interactor->GetControlKey())
229     {
230         this->WindowLevelStartPosition[0] = x;
231         this->WindowLevelStartPosition[1] = y;
232         this->StartWindowLevel();
233     }
234
235     // The rest of the button + key combinations remain the same
236
237     else
238     {
239         this->Superclass::OnRightButtonDown();
240     }
241 }
242
243 //----------------------------------------------------------------------------
244 void vvInteractorStyleNavigator::OnRightButtonUp()
245 {
246     switch (this->State)
247     {
248     case VTKIS_WINDOW_LEVEL:
249         this->EndWindowLevel();
250         if ( this->Interactor )
251         {
252             this->ReleaseFocus();
253         }
254         break;
255     }
256
257     // Call parent to handle all other states and perform additional work
258
259     this->Superclass::OnRightButtonUp();
260 }
261
262 //----------------------------------------------------------------------------
263 void vvInteractorStyleNavigator::OnLeftButtonDown()
264 {
265     int x = this->Interactor->GetEventPosition()[0];
266     int y = this->Interactor->GetEventPosition()[1];
267
268     this->FindPokedRenderer(x, y);
269     if (this->CurrentRenderer == NULL)
270     {
271         return;
272     }
273
274     // Redefine this button to handle pick
275     this->GrabFocus(this->EventCallbackCommand);
276     if (!this->Interactor->GetShiftKey() && !this->Interactor->GetControlKey())
277     {
278         this->StartPick();
279     }
280
281     // The rest of the button + key combinations remain the same
282
283     else
284     {
285         this->Superclass::OnLeftButtonDown();
286     }
287 }
288
289 //----------------------------------------------------------------------------
290 void vvInteractorStyleNavigator::OnLeftButtonUp()
291 {
292     switch (this->State)
293     {
294     case VTKIS_PICK:
295         this->EndPick();
296         if ( this->Interactor )
297         {
298             this->ReleaseFocus();
299         }
300         break;
301     }
302
303     // Call parent to handle all other states and perform additional work
304
305     this->Superclass::OnLeftButtonUp();
306 }
307
308 //----------------------------------------------------------------------------
309 void vvInteractorStyleNavigator::OnMiddleButtonDown()
310 {
311     this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
312                             this->Interactor->GetEventPosition()[1]);
313     if (this->CurrentRenderer == NULL)
314     {
315         return;
316     }
317     this->CurrentRenderer->GetRenderWindow()->SetCurrentCursor(8);
318     this->GrabFocus(this->EventCallbackCommand);
319     this->StartPan();
320 }
321
322 //----------------------------------------------------------------------------
323 void vvInteractorStyleNavigator::OnMiddleButtonUp()
324 {
325     switch (this->State)
326     {
327     case VTKIS_PAN:
328         this->EndPan();
329         if ( this->Interactor )
330         {
331             this->Interactor->GetRenderWindow()->SetCurrentCursor(0);
332             this->ReleaseFocus();
333         }
334         break;
335     }
336 }
337
338 //----------------------------------------------------------------------------
339 void vvInteractorStyleNavigator::OnChar()
340 {
341     vtkRenderWindowInteractor *rwi = this->Interactor;
342
343     switch (rwi->GetKeyCode())
344     {
345     case 'f' :
346     case 'F' :
347     {
348         this->AnimState = VTKIS_ANIM_ON;
349         this->AnimState = VTKIS_ANIM_OFF;
350         break;
351     }
352
353     case 'w'  :
354     case 'W'  :
355     {
356         this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
357                                 this->Interactor->GetEventPosition()[1]);
358         if (this->CurrentRenderer == NULL)
359         {
360             return;
361         }
362         this->GrabFocus(this->EventCallbackCommand);
363         this->StartDolly();
364         double factor = -2;
365         this->Dolly(pow((double)1.1, factor));
366         this->EndDolly();
367         this->ReleaseFocus();
368         break;
369     }
370     case 'x'  :
371     case 'X'  :
372     {
373         this->FindPokedRenderer(rwi->GetEventPosition()[0],
374                                 rwi->GetEventPosition()[1]);
375         if (this->CurrentRenderer == NULL)
376         {
377             return;
378         }
379         this->GrabFocus(this->EventCallbackCommand);
380         this->StartDolly();
381         double factor = 2;
382         this->Dolly(pow((double)1.1, factor));
383         this->EndDolly();
384         this->ReleaseFocus();
385         break;
386     }
387     case '3' :
388         // Disable StereoVision
389         break;
390     case 'r' :
391     case 'R' :
392         //Do nothing, this is handled in vvSlicerManagerCommand
393         break;
394     default:
395         this->Superclass::OnChar();
396         break;
397     }
398 }
399
400 //----------------------------------------------------------------------------
401 void vvInteractorStyleNavigator::OnMouseWheelForward()
402 {
403     this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
404                             this->Interactor->GetEventPosition()[1]);
405     if (this->CurrentRenderer == NULL)
406     {
407         return;
408     }
409     this->GrabFocus(this->EventCallbackCommand);
410     if (this->Interactor->GetControlKey())
411     {
412         this->StartDolly();
413         double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
414         this->Dolly(pow((double)1.1, factor));
415         this->EndDolly();
416     }
417     this->ReleaseFocus();
418     this->InvokeEvent(vtkCommand::MouseWheelForwardEvent, this);
419 }
420
421 //----------------------------------------------------------------------------
422 void vvInteractorStyleNavigator::OnMouseWheelBackward()
423 {
424     this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
425                             this->Interactor->GetEventPosition()[1]);
426     if (this->CurrentRenderer == NULL)
427     {
428         return;
429     }
430
431     this->GrabFocus(this->EventCallbackCommand);
432     if (this->Interactor->GetControlKey())
433     {
434         this->StartDolly();
435         double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
436         this->Dolly(pow((double)1.1, factor));
437         this->EndDolly();
438     }
439     this->ReleaseFocus();
440     this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, this);
441 }
442
443
444 //----------------------------------------------------------------------------
445 void vvInteractorStyleNavigator::WindowLevel()
446 {
447     vtkRenderWindowInteractor *rwi = this->Interactor;
448
449     this->WindowLevelCurrentPosition[0] = rwi->GetEventPosition()[0];
450     this->WindowLevelCurrentPosition[1] = rwi->GetEventPosition()[1];
451
452     this->InvokeEvent(vtkCommand::WindowLevelEvent, this);
453 }
454
455 //----------------------------------------------------------------------------
456 void vvInteractorStyleNavigator::Pick()
457 {
458     this->InvokeEvent(vtkCommand::PickEvent, this);
459 }
460
461 //----------------------------------------------------------------------------
462 void vvInteractorStyleNavigator::Pan()
463 {
464     if (this->CurrentRenderer == NULL)
465     {
466         return;
467     }
468
469     vtkRenderWindowInteractor *rwi = this->Interactor;
470
471     double viewFocus[4], focalDepth, viewPoint[3];
472     double newPickPoint[4], oldPickPoint[4], motionVector[3];
473
474     // Calculate the focal depth since we'll be using it a lot
475
476     vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
477     camera->GetFocalPoint(viewFocus);
478     this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
479                                 viewFocus);
480     focalDepth = viewFocus[2];
481
482     this->ComputeDisplayToWorld((double)rwi->GetEventPosition()[0],
483                                 (double)rwi->GetEventPosition()[1],
484                                 focalDepth,
485                                 newPickPoint);
486
487     // Has to recalc old mouse point since the viewport has moved,
488     // so can't move it outside the loop
489
490     this->ComputeDisplayToWorld((double)rwi->GetLastEventPosition()[0],
491                                 (double)rwi->GetLastEventPosition()[1],
492                                 focalDepth,
493                                 oldPickPoint);
494
495     // Camera motion is reversed
496
497     motionVector[0] = oldPickPoint[0] - newPickPoint[0];
498     motionVector[1] = oldPickPoint[1] - newPickPoint[1];
499     motionVector[2] = oldPickPoint[2] - newPickPoint[2];
500
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]);
506
507     camera->SetPosition(motionVector[0] + viewPoint[0],
508                         motionVector[1] + viewPoint[1],
509                         motionVector[2] + viewPoint[2]);
510
511     if (rwi->GetLightFollowCamera())
512     {
513         this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
514     }
515
516     rwi->Render();
517 }
518
519 //----------------------------------------------------------------------------
520 void vvInteractorStyleNavigator::Dolly()
521 {
522     if (this->CurrentRenderer == NULL)
523     {
524         return;
525     }
526
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));
532 }
533
534 //----------------------------------------------------------------------------
535 void vvInteractorStyleNavigator::Dolly(double factor)
536 {
537     if (this->CurrentRenderer == NULL)
538     {
539         return;
540     }
541
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],
547                                 viewFocus);
548     focalDepth = viewFocus[2];
549
550     oldPos[0] = this->CurrentRenderer->GetCenter()[0];
551     oldPos[1] = this->CurrentRenderer->GetCenter()[1];
552     oldPos[2] = focalDepth;
553
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]);
558
559     newPos[0] = this->Interactor->GetEventPosition()[0] - distance[0];
560     newPos[1] = this->Interactor->GetEventPosition()[1] - distance[1];
561     newPos[2] = focalDepth;
562
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]);
568
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]);
574
575     motionVector[0] = newPos[0] - oldPos[0];
576     motionVector[1] = newPos[1] - oldPos[1];
577     motionVector[2] = newPos[2] - oldPos[2];
578
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]);
584
585     camera->SetPosition(motionVector[0] + viewPoint[0],
586                         motionVector[1] + viewPoint[1],
587                         motionVector[2] + viewPoint[2]);
588
589     if (camera->GetParallelProjection())
590     {
591         camera->SetParallelScale(camera->GetParallelScale() / factor);
592     }
593     else
594     {
595         camera->Dolly(factor);
596         if (this->AutoAdjustCameraClippingRange)
597         {
598             this->CurrentRenderer->ResetCameraClippingRange();
599         }
600     }
601
602     if (this->Interactor->GetLightFollowCamera())
603     {
604         this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
605     }
606     this->CurrentRenderer->ResetCameraClippingRange();
607     //this->Interactor->Render();
608 }
609
610
611 //----------------------------------------------------------------------------
612 void vvInteractorStyleNavigator::PrintSelf(ostream& os, vtkIndent indent)
613 {
614     this->Superclass::PrintSelf(os, indent);
615
616     os << indent << "Window Level Current Position: ("
617     << this->WindowLevelCurrentPosition[0] << ", "
618     << this->WindowLevelCurrentPosition[1] << ")" << endl;
619
620     os << indent << "Window Level Start Position: ("
621     << this->WindowLevelStartPosition[0] << ", "
622     << this->WindowLevelStartPosition[1] << ")" << endl;
623 }