]> Creatis software - clitk.git/blob - vv/vvInteractorStyleNavigator.cxx
Reformatted using new coding style
[clitk.git] / vv / vvInteractorStyleNavigator.cxx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to:
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
8
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.
12
13   It is distributed under dual licence
14
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"
19
20 #include "vtkAbstractPropPicker.h"
21 #include "vtkAssemblyPath.h"
22 #include "vtkCallbackCommand.h"
23 #include "vtkMath.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"
31
32
33 vtkCxxRevisionMacro(vvInteractorStyleNavigator, "DummyRevision");
34 vtkStandardNewMacro(vvInteractorStyleNavigator);
35
36 //----------------------------------------------------------------------------
37 vvInteractorStyleNavigator::vvInteractorStyleNavigator()
38 {
39   this->WindowLevelStartPosition[0]   = 0;
40   this->WindowLevelStartPosition[1]   = 0;
41
42   this->WindowLevelCurrentPosition[0] = 0;
43   this->WindowLevelCurrentPosition[1] = 0;
44
45   this->MotionFactor   = 10.0;
46 }
47
48 //----------------------------------------------------------------------------
49 vvInteractorStyleNavigator::~vvInteractorStyleNavigator()
50 {
51   CurrentRenderer=NULL;
52 }
53
54 void vvInteractorStyleNavigator::FindPokedRenderer(int dummy1,int dummy2)
55 {
56   vtkRenderWindow * renwin=this->GetInteractor()->GetRenderWindow();
57   renwin->GetRenderers()->InitTraversal();
58   while (true) {
59     vtkRenderer* current = renwin->GetRenderers()->GetNextItem();
60     if (current==NULL || current->GetDraw()) {
61       CurrentRenderer=current;
62       return;
63     }
64   }
65 }
66
67 //----------------------------------------------------------------------------
68 void vvInteractorStyleNavigator::StartWindowLevel()
69 {
70   if (this->State != VTKIS_NONE) {
71     return;
72   }
73   this->StartState(VTKIS_WINDOW_LEVEL);
74   this->InvokeEvent(vtkCommand::StartWindowLevelEvent,this);
75 }
76
77 //----------------------------------------------------------------------------
78 void vvInteractorStyleNavigator::EndWindowLevel()
79 {
80   if (this->State != VTKIS_WINDOW_LEVEL) {
81     return;
82   }
83   this->InvokeEvent(vtkCommand::EndWindowLevelEvent, this);
84   this->StopState();
85 }
86
87 //----------------------------------------------------------------------------
88 void vvInteractorStyleNavigator::StartPick()
89 {
90   if (this->State != VTKIS_NONE) {
91     return;
92   }
93   this->StartState(VTKIS_PICK);
94   this->InvokeEvent(vtkCommand::StartPickEvent, this);
95 }
96
97 //----------------------------------------------------------------------------
98 void vvInteractorStyleNavigator::EndPick()
99 {
100   if (this->State != VTKIS_PICK) {
101     return;
102   }
103   this->InvokeEvent(vtkCommand::EndPickEvent, this);
104   this->StopState();
105 }
106
107 //----------------------------------------------------------------------------
108 void vvInteractorStyleNavigator::OnMouseMove()
109 {
110   int x = this->Interactor->GetEventPosition()[0];
111   int y = this->Interactor->GetEventPosition()[1];
112
113   switch (this->State) {
114   case VTKIS_WINDOW_LEVEL:
115     this->FindPokedRenderer(x, y);
116     this->WindowLevel();
117     this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
118     break;
119
120   case VTKIS_PICK:
121     this->FindPokedRenderer(x, y);
122     this->Pick();
123     this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
124     break;
125
126   case VTKIS_PAN:
127     this->FindPokedRenderer(x, y);
128     this->Pan();
129     this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
130     break;
131
132   case VTKIS_DOLLY:
133     this->FindPokedRenderer(x, y);
134     this->Dolly();
135     this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
136     break;
137
138   default:
139     this->InvokeEvent(vtkCommand::UserEvent, NULL);
140     break;
141   }
142
143   // Call parent to handle all other states and perform additional work
144
145 }
146
147 void vvInteractorStyleNavigator::OnEnter()
148 {
149   //  int x = this->Interactor->GetEventPosition()[0];
150   //int y = this->Interactor->GetEventPosition()[1];
151
152   switch (this->State) {
153   case VTKIS_WINDOW_LEVEL:
154     break;
155
156   case VTKIS_PICK:
157     break;
158
159   case VTKIS_PAN:
160     break;
161
162   default:
163     this->InvokeEvent(vtkCommand::EnterEvent, NULL);
164     break;
165   }
166
167   // Call parent to handle all other states and perform additional work
168
169 }
170
171 //----------------------------------------------------------------------------
172 void vvInteractorStyleNavigator::OnLeave()
173 {
174   //  int x = this->Interactor->GetEventPosition()[0];
175   //int y = this->Interactor->GetEventPosition()[1];
176
177   switch (this->State) {
178   case VTKIS_WINDOW_LEVEL:
179     break;
180
181   case VTKIS_PICK:
182     break;
183
184   case VTKIS_PAN:
185     break;
186
187   default:
188     this->InvokeEvent(vtkCommand::LeaveEvent, NULL);
189     break;
190   }
191
192   // Call parent to handle all other states and perform additional work
193
194 }
195
196 //----------------------------------------------------------------------------
197 void vvInteractorStyleNavigator::OnRightButtonDown()
198 {
199   int x = this->Interactor->GetEventPosition()[0];
200   int y = this->Interactor->GetEventPosition()[1];
201
202   this->FindPokedRenderer(x, y);
203   if (this->CurrentRenderer == NULL) {
204     return;
205   }
206
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();
213   }
214
215   // The rest of the button + key combinations remain the same
216
217   else {
218     this->Superclass::OnRightButtonDown();
219   }
220 }
221
222 //----------------------------------------------------------------------------
223 void vvInteractorStyleNavigator::OnRightButtonUp()
224 {
225   switch (this->State) {
226   case VTKIS_WINDOW_LEVEL:
227     this->EndWindowLevel();
228     if ( this->Interactor ) {
229       this->ReleaseFocus();
230     }
231     break;
232   }
233
234   // Call parent to handle all other states and perform additional work
235
236   this->Superclass::OnRightButtonUp();
237 }
238
239 //----------------------------------------------------------------------------
240 void vvInteractorStyleNavigator::OnLeftButtonDown()
241 {
242   int x = this->Interactor->GetEventPosition()[0];
243   int y = this->Interactor->GetEventPosition()[1];
244
245   this->FindPokedRenderer(x, y);
246   if (this->CurrentRenderer == NULL) {
247     return;
248   }
249
250   // Redefine this button to handle pick
251   this->GrabFocus(this->EventCallbackCommand);
252   if (!this->Interactor->GetShiftKey() && !this->Interactor->GetControlKey()) {
253     this->StartPick();
254   }
255
256   // The rest of the button + key combinations remain the same
257
258   else {
259     this->Superclass::OnLeftButtonDown();
260   }
261 }
262
263 //----------------------------------------------------------------------------
264 void vvInteractorStyleNavigator::OnLeftButtonUp()
265 {
266   //  DD("OnLeftButtonUp");
267   switch (this->State) {
268   case VTKIS_PICK:
269     this->EndPick();
270     if ( this->Interactor ) {
271       this->ReleaseFocus();
272     }
273     break;
274   }
275
276   // Call parent to handle all other states and perform additional work
277
278   this->Superclass::OnLeftButtonUp();
279 }
280
281 //----------------------------------------------------------------------------
282 void vvInteractorStyleNavigator::OnMiddleButtonDown()
283 {
284   this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
285                           this->Interactor->GetEventPosition()[1]);
286   if (this->CurrentRenderer == NULL) {
287     return;
288   }
289   this->CurrentRenderer->GetRenderWindow()->SetCurrentCursor(8);
290   this->GrabFocus(this->EventCallbackCommand);
291   this->StartPan();
292 }
293
294 //----------------------------------------------------------------------------
295 void vvInteractorStyleNavigator::OnMiddleButtonUp()
296 {
297   switch (this->State) {
298   case VTKIS_PAN:
299     this->EndPan();
300     if ( this->Interactor ) {
301       this->Interactor->GetRenderWindow()->SetCurrentCursor(0);
302       this->ReleaseFocus();
303     }
304     break;
305   }
306 }
307
308 //----------------------------------------------------------------------------
309 void vvInteractorStyleNavigator::OnChar()
310 {
311   vtkRenderWindowInteractor *rwi = this->Interactor;
312
313   switch (rwi->GetKeyCode()) {
314   case 'f' :
315   case 'F' : {
316     this->AnimState = VTKIS_ANIM_ON;
317     this->AnimState = VTKIS_ANIM_OFF;
318     break;
319   }
320
321   case 'o'  :
322   case 'O'  : {
323     this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
324                             this->Interactor->GetEventPosition()[1]);
325     if (this->CurrentRenderer == NULL) {
326       return;
327     }
328     this->GrabFocus(this->EventCallbackCommand);
329     this->StartDolly();
330     double factor = -2;
331     this->Dolly(pow((double)1.1, factor));
332     this->EndDolly();
333     this->ReleaseFocus();
334     break;
335   }
336   case 'i'  :
337   case 'I'  : {
338     this->FindPokedRenderer(rwi->GetEventPosition()[0],
339                             rwi->GetEventPosition()[1]);
340     if (this->CurrentRenderer == NULL) {
341       return;
342     }
343     this->GrabFocus(this->EventCallbackCommand);
344     this->StartDolly();
345     double factor = 2;
346     this->Dolly(pow((double)1.1, factor));
347     this->EndDolly();
348     this->ReleaseFocus();
349     break;
350   }
351   case '3' :
352     // Disable StereoVision
353     break;
354   case 'r' :
355   case 'R' :
356     //Do nothing, this is handled in vvSlicerManagerCommand
357     break;
358   default:
359     this->Superclass::OnChar();
360     break;
361   }
362 }
363
364 //----------------------------------------------------------------------------
365 void vvInteractorStyleNavigator::OnMouseWheelForward()
366 {
367   this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
368                           this->Interactor->GetEventPosition()[1]);
369   if (this->CurrentRenderer == NULL) {
370     return;
371   }
372   this->GrabFocus(this->EventCallbackCommand);
373   if (this->Interactor->GetControlKey()) {
374     this->StartDolly();
375     double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
376     this->Dolly(pow((double)1.1, factor));
377     this->EndDolly();
378   }
379   this->ReleaseFocus();
380   this->InvokeEvent(vtkCommand::MouseWheelForwardEvent, this);
381 }
382
383 //----------------------------------------------------------------------------
384 void vvInteractorStyleNavigator::OnMouseWheelBackward()
385 {
386   this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
387                           this->Interactor->GetEventPosition()[1]);
388   if (this->CurrentRenderer == NULL) {
389     return;
390   }
391
392   this->GrabFocus(this->EventCallbackCommand);
393   if (this->Interactor->GetControlKey()) {
394     this->StartDolly();
395     double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
396     this->Dolly(pow((double)1.1, factor));
397     this->EndDolly();
398   }
399   this->ReleaseFocus();
400   this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, this);
401 }
402
403
404 //----------------------------------------------------------------------------
405 void vvInteractorStyleNavigator::WindowLevel()
406 {
407   vtkRenderWindowInteractor *rwi = this->Interactor;
408
409   this->WindowLevelCurrentPosition[0] = rwi->GetEventPosition()[0];
410   this->WindowLevelCurrentPosition[1] = rwi->GetEventPosition()[1];
411
412   this->InvokeEvent(vtkCommand::WindowLevelEvent, this);
413 }
414
415 //----------------------------------------------------------------------------
416 void vvInteractorStyleNavigator::Pick()
417 {
418   this->InvokeEvent(vtkCommand::PickEvent, this);
419 }
420
421 //----------------------------------------------------------------------------
422 void vvInteractorStyleNavigator::Pan()
423 {
424   if (this->CurrentRenderer == NULL) {
425     return;
426   }
427
428   vtkRenderWindowInteractor *rwi = this->Interactor;
429
430   double viewFocus[4], focalDepth, viewPoint[3];
431   double newPickPoint[4], oldPickPoint[4], motionVector[3];
432
433   // Calculate the focal depth since we'll be using it a lot
434
435   vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
436   camera->GetFocalPoint(viewFocus);
437   this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
438                               viewFocus);
439   focalDepth = viewFocus[2];
440
441   this->ComputeDisplayToWorld((double)rwi->GetEventPosition()[0],
442                               (double)rwi->GetEventPosition()[1],
443                               focalDepth,
444                               newPickPoint);
445
446   // Has to recalc old mouse point since the viewport has moved,
447   // so can't move it outside the loop
448
449   this->ComputeDisplayToWorld((double)rwi->GetLastEventPosition()[0],
450                               (double)rwi->GetLastEventPosition()[1],
451                               focalDepth,
452                               oldPickPoint);
453
454   // Camera motion is reversed
455
456   motionVector[0] = oldPickPoint[0] - newPickPoint[0];
457   motionVector[1] = oldPickPoint[1] - newPickPoint[1];
458   motionVector[2] = oldPickPoint[2] - newPickPoint[2];
459
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]);
465
466   camera->SetPosition(motionVector[0] + viewPoint[0],
467                       motionVector[1] + viewPoint[1],
468                       motionVector[2] + viewPoint[2]);
469
470   if (rwi->GetLightFollowCamera()) {
471     this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
472   }
473
474   rwi->Render();
475 }
476
477 //----------------------------------------------------------------------------
478 void vvInteractorStyleNavigator::Dolly()
479 {
480   if (this->CurrentRenderer == NULL) {
481     return;
482   }
483
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));
489 }
490
491 //----------------------------------------------------------------------------
492 void vvInteractorStyleNavigator::Dolly(double factor)
493 {
494   if (this->CurrentRenderer == NULL) {
495     return;
496   }
497
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],
503                               viewFocus);
504   focalDepth = viewFocus[2];
505
506   oldPos[0] = this->CurrentRenderer->GetCenter()[0];
507   oldPos[1] = this->CurrentRenderer->GetCenter()[1];
508   oldPos[2] = focalDepth;
509
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]);
514
515   newPos[0] = this->Interactor->GetEventPosition()[0] - distance[0];
516   newPos[1] = this->Interactor->GetEventPosition()[1] - distance[1];
517   newPos[2] = focalDepth;
518
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]);
524
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]);
530
531   motionVector[0] = newPos[0] - oldPos[0];
532   motionVector[1] = newPos[1] - oldPos[1];
533   motionVector[2] = newPos[2] - oldPos[2];
534
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]);
540
541   camera->SetPosition(motionVector[0] + viewPoint[0],
542                       motionVector[1] + viewPoint[1],
543                       motionVector[2] + viewPoint[2]);
544
545   if (camera->GetParallelProjection()) {
546     camera->SetParallelScale(camera->GetParallelScale() / factor);
547   } else {
548     camera->Dolly(factor);
549     if (this->AutoAdjustCameraClippingRange) {
550       this->CurrentRenderer->ResetCameraClippingRange();
551     }
552   }
553
554   if (this->Interactor->GetLightFollowCamera()) {
555     this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
556   }
557   this->CurrentRenderer->ResetCameraClippingRange();
558   //this->Interactor->Render();
559 }
560
561
562 //----------------------------------------------------------------------------
563 void vvInteractorStyleNavigator::PrintSelf(ostream& os, vtkIndent indent)
564 {
565   this->Superclass::PrintSelf(os, indent);
566
567   os << indent << "Window Level Current Position: ("
568      << this->WindowLevelCurrentPosition[0] << ", "
569      << this->WindowLevelCurrentPosition[1] << ")" << endl;
570
571   os << indent << "Window Level Start Position: ("
572      << this->WindowLevelStartPosition[0] << ", "
573      << this->WindowLevelStartPosition[1] << ")" << endl;
574 }