]> Creatis software - clitk.git/blob - vv/vvInteractorStyleNavigator.cxx
- comments
[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   //  DD("OnLeftButtonUp");
284     switch (this->State)
285     {
286     case VTKIS_PICK:
287         this->EndPick();
288         if ( this->Interactor )
289         {
290             this->ReleaseFocus();
291         }
292         break;
293     }
294
295     // Call parent to handle all other states and perform additional work
296
297     this->Superclass::OnLeftButtonUp();
298 }
299
300 //----------------------------------------------------------------------------
301 void vvInteractorStyleNavigator::OnMiddleButtonDown()
302 {
303     this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
304                             this->Interactor->GetEventPosition()[1]);
305     if (this->CurrentRenderer == NULL)
306     {
307         return;
308     }
309     this->CurrentRenderer->GetRenderWindow()->SetCurrentCursor(8);
310     this->GrabFocus(this->EventCallbackCommand);
311     this->StartPan();
312 }
313
314 //----------------------------------------------------------------------------
315 void vvInteractorStyleNavigator::OnMiddleButtonUp()
316 {
317     switch (this->State)
318     {
319     case VTKIS_PAN:
320         this->EndPan();
321         if ( this->Interactor )
322         {
323             this->Interactor->GetRenderWindow()->SetCurrentCursor(0);
324             this->ReleaseFocus();
325         }
326         break;
327     }
328 }
329
330 //----------------------------------------------------------------------------
331 void vvInteractorStyleNavigator::OnChar()
332 {
333     vtkRenderWindowInteractor *rwi = this->Interactor;
334
335     switch (rwi->GetKeyCode())
336     {
337     case 'f' :
338     case 'F' :
339     {
340         this->AnimState = VTKIS_ANIM_ON;
341         this->AnimState = VTKIS_ANIM_OFF;
342         break;
343     }
344
345     case 'o'  :
346     case 'O'  :
347     {
348         this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
349                                 this->Interactor->GetEventPosition()[1]);
350         if (this->CurrentRenderer == NULL)
351         {
352             return;
353         }
354         this->GrabFocus(this->EventCallbackCommand);
355         this->StartDolly();
356         double factor = -2;
357         this->Dolly(pow((double)1.1, factor));
358         this->EndDolly();
359         this->ReleaseFocus();
360         break;
361     }
362     case 'i'  :
363     case 'I'  :
364     {
365         this->FindPokedRenderer(rwi->GetEventPosition()[0],
366                                 rwi->GetEventPosition()[1]);
367         if (this->CurrentRenderer == NULL)
368         {
369             return;
370         }
371         this->GrabFocus(this->EventCallbackCommand);
372         this->StartDolly();
373         double factor = 2;
374         this->Dolly(pow((double)1.1, factor));
375         this->EndDolly();
376         this->ReleaseFocus();
377         break;
378     }
379     case '3' :
380         // Disable StereoVision
381         break;
382     case 'r' :
383     case 'R' :
384         //Do nothing, this is handled in vvSlicerManagerCommand
385         break;
386     default:
387         this->Superclass::OnChar();
388         break;
389     }
390 }
391
392 //----------------------------------------------------------------------------
393 void vvInteractorStyleNavigator::OnMouseWheelForward()
394 {
395     this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
396                             this->Interactor->GetEventPosition()[1]);
397     if (this->CurrentRenderer == NULL)
398     {
399         return;
400     }
401     this->GrabFocus(this->EventCallbackCommand);
402     if (this->Interactor->GetControlKey())
403     {
404         this->StartDolly();
405         double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
406         this->Dolly(pow((double)1.1, factor));
407         this->EndDolly();
408     }
409     this->ReleaseFocus();
410     this->InvokeEvent(vtkCommand::MouseWheelForwardEvent, this);
411 }
412
413 //----------------------------------------------------------------------------
414 void vvInteractorStyleNavigator::OnMouseWheelBackward()
415 {
416     this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
417                             this->Interactor->GetEventPosition()[1]);
418     if (this->CurrentRenderer == NULL)
419     {
420         return;
421     }
422
423     this->GrabFocus(this->EventCallbackCommand);
424     if (this->Interactor->GetControlKey())
425     {
426         this->StartDolly();
427         double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
428         this->Dolly(pow((double)1.1, factor));
429         this->EndDolly();
430     }
431     this->ReleaseFocus();
432     this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, this);
433 }
434
435
436 //----------------------------------------------------------------------------
437 void vvInteractorStyleNavigator::WindowLevel()
438 {
439     vtkRenderWindowInteractor *rwi = this->Interactor;
440
441     this->WindowLevelCurrentPosition[0] = rwi->GetEventPosition()[0];
442     this->WindowLevelCurrentPosition[1] = rwi->GetEventPosition()[1];
443
444     this->InvokeEvent(vtkCommand::WindowLevelEvent, this);
445 }
446
447 //----------------------------------------------------------------------------
448 void vvInteractorStyleNavigator::Pick()
449 {
450     this->InvokeEvent(vtkCommand::PickEvent, this);
451 }
452
453 //----------------------------------------------------------------------------
454 void vvInteractorStyleNavigator::Pan()
455 {
456     if (this->CurrentRenderer == NULL)
457     {
458         return;
459     }
460
461     vtkRenderWindowInteractor *rwi = this->Interactor;
462
463     double viewFocus[4], focalDepth, viewPoint[3];
464     double newPickPoint[4], oldPickPoint[4], motionVector[3];
465
466     // Calculate the focal depth since we'll be using it a lot
467
468     vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
469     camera->GetFocalPoint(viewFocus);
470     this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
471                                 viewFocus);
472     focalDepth = viewFocus[2];
473
474     this->ComputeDisplayToWorld((double)rwi->GetEventPosition()[0],
475                                 (double)rwi->GetEventPosition()[1],
476                                 focalDepth,
477                                 newPickPoint);
478
479     // Has to recalc old mouse point since the viewport has moved,
480     // so can't move it outside the loop
481
482     this->ComputeDisplayToWorld((double)rwi->GetLastEventPosition()[0],
483                                 (double)rwi->GetLastEventPosition()[1],
484                                 focalDepth,
485                                 oldPickPoint);
486
487     // Camera motion is reversed
488
489     motionVector[0] = oldPickPoint[0] - newPickPoint[0];
490     motionVector[1] = oldPickPoint[1] - newPickPoint[1];
491     motionVector[2] = oldPickPoint[2] - newPickPoint[2];
492
493     camera->GetFocalPoint(viewFocus);
494     camera->GetPosition(viewPoint);
495     camera->SetFocalPoint(motionVector[0] + viewFocus[0],
496                           motionVector[1] + viewFocus[1],
497                           motionVector[2] + viewFocus[2]);
498
499     camera->SetPosition(motionVector[0] + viewPoint[0],
500                         motionVector[1] + viewPoint[1],
501                         motionVector[2] + viewPoint[2]);
502
503     if (rwi->GetLightFollowCamera())
504     {
505         this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
506     }
507
508     rwi->Render();
509 }
510
511 //----------------------------------------------------------------------------
512 void vvInteractorStyleNavigator::Dolly()
513 {
514     if (this->CurrentRenderer == NULL)
515     {
516         return;
517     }
518
519     vtkRenderWindowInteractor *rwi = this->Interactor;
520     double *center = this->CurrentRenderer->GetCenter();
521     int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
522     double dyf = this->MotionFactor * (double)(dy) / (double)(center[1]);
523     this->Dolly(pow((double)1.1, dyf));
524 }
525
526 //----------------------------------------------------------------------------
527 void vvInteractorStyleNavigator::Dolly(double factor)
528 {
529     if (this->CurrentRenderer == NULL)
530     {
531         return;
532     }
533
534     double viewFocus[4],viewPoint[4],motionVector[3], focalDepth;
535     double oldPos[3], newPos[3], distance[2];
536     vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
537     camera->GetFocalPoint(viewFocus);
538     this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
539                                 viewFocus);
540     focalDepth = viewFocus[2];
541
542     oldPos[0] = this->CurrentRenderer->GetCenter()[0];
543     oldPos[1] = this->CurrentRenderer->GetCenter()[1];
544     oldPos[2] = focalDepth;
545
546     distance[0] = 1/factor*
547                   (this->Interactor->GetEventPosition()[0]-this->CurrentRenderer->GetCenter()[0]);
548     distance[1] = 1/factor*
549                   (this->Interactor->GetEventPosition()[1]-this->CurrentRenderer->GetCenter()[1]);
550
551     newPos[0] = this->Interactor->GetEventPosition()[0] - distance[0];
552     newPos[1] = this->Interactor->GetEventPosition()[1] - distance[1];
553     newPos[2] = focalDepth;
554
555     this->CurrentRenderer->DisplayToNormalizedDisplay(oldPos[0],oldPos[1]);
556     this->CurrentRenderer->NormalizedDisplayToViewport(oldPos[0],oldPos[1]);
557     this->CurrentRenderer->ViewportToNormalizedViewport(oldPos[0],oldPos[1]);
558     this->CurrentRenderer->NormalizedViewportToView(oldPos[0],oldPos[1],oldPos[2]);
559     this->CurrentRenderer->ViewToWorld(oldPos[0],oldPos[1],oldPos[2]);
560
561     this->CurrentRenderer->DisplayToNormalizedDisplay(newPos[0],newPos[1]);
562     this->CurrentRenderer->NormalizedDisplayToViewport(newPos[0],newPos[1]);
563     this->CurrentRenderer->ViewportToNormalizedViewport(newPos[0],newPos[1]);
564     this->CurrentRenderer->NormalizedViewportToView(newPos[0],newPos[1],newPos[2]);
565     this->CurrentRenderer->ViewToWorld(newPos[0],newPos[1],newPos[2]);
566
567     motionVector[0] = newPos[0] - oldPos[0];
568     motionVector[1] = newPos[1] - oldPos[1];
569     motionVector[2] = newPos[2] - oldPos[2];
570
571     camera->GetFocalPoint(viewFocus);
572     camera->GetPosition(viewPoint);
573     camera->SetFocalPoint(motionVector[0] + viewFocus[0],
574                           motionVector[1] + viewFocus[1],
575                           motionVector[2] + viewFocus[2]);
576
577     camera->SetPosition(motionVector[0] + viewPoint[0],
578                         motionVector[1] + viewPoint[1],
579                         motionVector[2] + viewPoint[2]);
580
581     if (camera->GetParallelProjection())
582     {
583         camera->SetParallelScale(camera->GetParallelScale() / factor);
584     }
585     else
586     {
587         camera->Dolly(factor);
588         if (this->AutoAdjustCameraClippingRange)
589         {
590             this->CurrentRenderer->ResetCameraClippingRange();
591         }
592     }
593
594     if (this->Interactor->GetLightFollowCamera())
595     {
596         this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
597     }
598     this->CurrentRenderer->ResetCameraClippingRange();
599     //this->Interactor->Render();
600 }
601
602
603 //----------------------------------------------------------------------------
604 void vvInteractorStyleNavigator::PrintSelf(ostream& os, vtkIndent indent)
605 {
606     this->Superclass::PrintSelf(os, indent);
607
608     os << indent << "Window Level Current Position: ("
609     << this->WindowLevelCurrentPosition[0] << ", "
610     << this->WindowLevelCurrentPosition[1] << ")" << endl;
611
612     os << indent << "Window Level Start Position: ("
613     << this->WindowLevelStartPosition[0] << ", "
614     << this->WindowLevelStartPosition[1] << ")" << endl;
615 }