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