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