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