]> Creatis software - clitk.git/blob - vv/vvSlicerManagerCommand.cxx
Use Tab key for next and previous image
[clitk.git] / vv / vvSlicerManagerCommand.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 "vvSlicerManagerCommand.h"
19 #include "vvSlicerManager.h"
20
21 #include <vtkTextProperty.h>
22 #include <vtkRenderer.h>
23 #include <vtkImageActor.h>
24 #include <vtkRenderWindowInteractor.h>
25 #include <vtkPropPicker.h>
26 #include <vtkCamera.h>
27 #include <vtkImageMapToWindowLevelColors.h>
28 #include <vtkLookupTable.h>
29 #include <vtkMath.h>
30 #include <vtkAbstractPropPicker.h>
31 #include <vtkAssemblyPath.h>
32 #include <vtkCornerAnnotation.h>
33 #include <vtkRenderWindow.h>
34
35 #include "vvSlicer.h"
36 #include "vvInteractorStyleNavigator.h"
37
38 #include <cmath>
39
40 //------------------------------------------------------------------------------
41 vvSlicerManagerCommand::vvSlicerManagerCommand()
42 {
43     mStartSlicer = -1;
44     mSlicerNumber=-1;
45 }
46 //------------------------------------------------------------------------------
47
48
49 //------------------------------------------------------------------------------
50 //return the num of the current slicer if visible (-1 else)
51 int vvSlicerManagerCommand::FindSlicerNumber(vtkRenderWindow* renwin)
52 {
53     int rvalue;
54     if (renwin != SM->GetSlicer(mSlicerNumber)->GetRenderWindow() ||
55             !SM->GetSlicer(mSlicerNumber)->GetRenderer()->GetDraw())
56         rvalue = -1;
57     else rvalue = mSlicerNumber;
58     //std::cerr << this << ":" << mSlicerNumber << ": " << rvalue << endl;
59     return rvalue;
60 }
61 //------------------------------------------------------------------------------
62
63
64 //------------------------------------------------------------------------------
65 void vvSlicerManagerCommand::Execute(vtkObject *caller,
66                                      unsigned long event,
67                                      void *vtkNotUsed(callData))
68 {
69     //KeyPress event
70     vvInteractorStyleNavigator *isi =
71         dynamic_cast<vvInteractorStyleNavigator *>(caller);
72     if (isi)
73     {
74         double x = isi->GetInteractor()->GetEventPosition()[0];
75         double y = isi->GetInteractor()->GetEventPosition()[1];
76         double z;
77
78         int VisibleInWindow = this->FindSlicerNumber(isi->GetInteractor()->GetRenderWindow());
79         vtkRenderer* renderer=NULL;
80         if (VisibleInWindow>-1)
81             renderer=this->SM->GetSlicer(VisibleInWindow)->GetRenderer();
82         newLandmark = false;
83
84         if (event == vtkCommand::StartPickEvent && VisibleInWindow == -1)
85         {
86             for (int i = 0; i < this->SM->NumberOfSlicers(); i++)
87             {
88                 if (this->SM->GetSlicer(i)->GetCursorVisibility())
89                 {
90                     this->SM->GetSlicer(i)->SetCursorVisibility(0);
91                     this->SM->GetSlicer(i)->Render();
92                 }
93             }
94         }
95         if ( VisibleInWindow > -1 )
96         {
97             if (event == vtkCommand::KeyPressEvent)
98             {
99                 std::string KeyPress = isi->GetInteractor()->GetKeySym();
100                 if (KeyPress == "Tab")
101                 {
102                     if(isi->GetInteractor()->GetShiftKey())
103                         this->SM->PrevImage(VisibleInWindow);
104                     else
105                         this->SM->NextImage(VisibleInWindow);
106                     return;
107                 }
108                 if (KeyPress == "f" || KeyPress == "F")
109                 {
110                     FlyToPosition(isi->GetInteractor(),this->SM->GetSlicer(VisibleInWindow));
111                   return;
112                 }
113                 if (KeyPress == "z")
114                 {
115                    this->SM->SetLocalColorWindowing(VisibleInWindow);
116                    return;
117                 }
118                 if (KeyPress == "0")
119                 {
120                     this->SM->SetPreset(0);
121                     this->SM->UpdateWindowLevel();
122                     return;
123                 }
124                 if (KeyPress == "1")
125                 {
126                     this->SM->SetPreset(1);
127                     this->SM->UpdateWindowLevel();
128                     return;
129                 }
130                 if (KeyPress == "2")
131                 {
132                     this->SM->SetPreset(2);
133                     this->SM->UpdateWindowLevel();
134
135                     return;
136                 }
137                 if (KeyPress == "3")
138                 {
139                     this->SM->SetPreset(3);
140                     this->SM->UpdateWindowLevel();
141                     return;
142                 }
143                 if (KeyPress == "4")
144                 {
145                     this->SM->SetPreset(4);
146                     this->SM->UpdateWindowLevel();
147                     return;
148                 }
149                 if (KeyPress == "5")
150                 {
151                     this->SM->SetPreset(5);
152                     this->SM->UpdateWindowLevel();
153                     return;
154                 }
155                 if (KeyPress == "6")
156                 {
157                     this->SM->SetColorMap(0);
158                     this->SM->UpdateWindowLevel();
159                     return;
160                 }
161                 if (KeyPress == "7")
162                 {
163                     this->SM->SetColorMap(1);
164                     this->SM->UpdateWindowLevel();
165                     return;
166                 }
167                 if (KeyPress == "8")
168                 {
169                     this->SM->SetColorMap(2);
170                     this->SM->UpdateWindowLevel();
171                     return;
172                 }
173                 if (KeyPress == "9")
174                 {
175                     this->SM->SetColorMap(3);
176                     this->SM->UpdateWindowLevel();
177                     return;
178                 }
179                 if (KeyPress == "equal") //keycodes are in vtkWin32RenderWindowInteractor
180                 {
181                     this->SM->SetPreset(7);
182                     //this->SM->SetColorMap(1);
183                     this->SM->UpdateWindowLevel();
184                     return;
185                 }
186                 if (KeyPress == "minus")
187                 {
188                     this->SM->SetColorWindow(-this->SM->GetColorWindow());
189                     this->SM->SetColorMap(-1);
190                     this->SM->UpdateWindowLevel();
191                     return;
192                 }
193                 if (KeyPress == "u")
194                 {
195                     this->SM->ToggleContourSuperposition();
196                     this->SM->Render();
197                     return;
198                 }
199                 if (KeyPress == "i")
200                 {
201                     this->SM->ToggleInterpolation();
202                     this->SM->Render();
203                     return;
204                 }
205                 if (KeyPress == "h")
206                 {
207                     this->SM->SetCursorVisibility(0);
208                     this->SM->Render();
209                     return;
210                 }
211                 if (KeyPress == "l")
212                 {
213                     this->SM->Reload();
214                     this->SM->Render();
215                     return;
216                 }
217                 if (KeyPress == "r" || KeyPress=="R")
218                 {
219                     this->SM->GetSlicer(VisibleInWindow)->ResetCamera();
220                     this->SM->GetSlicer(VisibleInWindow)->Render();
221                     return;
222                 }
223                 if (KeyPress == "g")
224                 {
225                     double* cursorPos = this->SM->GetSlicer(VisibleInWindow)->GetCursorPosition();
226                     this->SM->GetSlicer(VisibleInWindow)->SetCurrentPosition(
227                             cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]);
228                     this->SM->UpdateViews(1,VisibleInWindow);
229                     this->SM->UpdateLinked(VisibleInWindow);
230                     return;
231                 }
232                 if (KeyPress == "F5")
233                 {
234                     this->SM->GetSlicer(VisibleInWindow)->FlipHorizontalView();
235                     this->SM->GetSlicer(VisibleInWindow)->Render();
236                     return;
237                 }
238                 if (KeyPress == "F6")
239                 {
240                     this->SM->GetSlicer(VisibleInWindow)->FlipVerticalView();
241                     this->SM->GetSlicer(VisibleInWindow)->Render();
242                     return;
243                 }
244                 if (KeyPress == "Up")
245                 {
246                     this->SM->GetSlicer(VisibleInWindow)->SetSlice(this->SM->GetSlicer(VisibleInWindow)->GetSlice()+1);
247                     this->SM->UpdateSlice(VisibleInWindow);
248                     this->SM->UpdateInfoOnCursorPosition(VisibleInWindow);
249                 }
250                 if (KeyPress == "Down")
251                 {
252                     this->SM->GetSlicer(VisibleInWindow)->SetSlice(this->SM->GetSlicer(VisibleInWindow)->GetSlice()-1);
253                     this->SM->UpdateSlice(VisibleInWindow);
254                     this->SM->UpdateInfoOnCursorPosition(VisibleInWindow);
255                 }
256                 if (KeyPress == "space")
257                 {
258                     newLandmark = true;
259                 }
260                 if (KeyPress == "Left")
261                     this->SM->SetPreviousTSlice(VisibleInWindow);
262                 if (KeyPress == "Right")
263                     this->SM->SetNextTSlice(VisibleInWindow);
264
265                 if (KeyPress == "F1")
266                 {
267                     this->SM->GetSlicer(VisibleInWindow)->GetAnnotation()->SetText(2,"Sagital\n<slice>");
268                     this->SM->GetSlicer(VisibleInWindow)->SetSliceOrientation(0);
269                     this->SM->UpdateSliceRange(VisibleInWindow);
270                     this->SM->UpdateInfoOnCursorPosition(VisibleInWindow);
271                 }
272                 if (KeyPress == "F2")
273                 {
274                     this->SM->GetSlicer(VisibleInWindow)->GetAnnotation()->SetText(2,"Coronal\n<slice>");
275                     this->SM->GetSlicer(VisibleInWindow)->SetSliceOrientation(1);
276                     this->SM->UpdateSliceRange(VisibleInWindow);
277                     this->SM->UpdateInfoOnCursorPosition(VisibleInWindow);
278                 }
279                 if (KeyPress == "F3")
280                 {
281                     this->SM->GetSlicer(VisibleInWindow)->GetAnnotation()->SetText(2,"Axial\n<slice>");
282                     this->SM->GetSlicer(VisibleInWindow)->SetSliceOrientation(2);
283                     this->SM->UpdateSliceRange(VisibleInWindow);
284                     this->SM->UpdateInfoOnCursorPosition(VisibleInWindow);
285                 }
286             }
287
288             //All type of mouse events
289             if (event == vtkCommand::LeaveEvent)
290             {
291                 this->SM->GetSlicer(VisibleInWindow)->SetCurrentPosition(-VTK_DOUBLE_MAX,-VTK_DOUBLE_MAX,
292                         -VTK_DOUBLE_MAX,this->SM->GetSlicer(VisibleInWindow)->GetTSlice());
293                 this->SM->GetSlicer(VisibleInWindow)->Render();
294                 return;
295             }
296
297             if (event == vtkCommand::StartWindowLevelEvent)
298             {
299                 mStartSlicer = -1;
300                 this->InitialWindow = this->SM->GetColorWindow();
301                 this->InitialLevel = this->SM->GetColorLevel();
302
303                 if (VisibleInWindow > -1)
304                 {
305                     mStartSlicer = VisibleInWindow;
306                 }
307                 return;
308             }
309
310             if (event == vtkCommand::EndWindowLevelEvent)
311             {
312                 mStartSlicer = -1;
313             }
314
315         }
316         if (VisibleInWindow > -1)
317         {
318             this->SM->Activated();
319             //if(!this->SM->GetSlicer(VisibleInWindow)->GetAnnotation()->GetVisibility())
320             this->SM->GetSlicer(VisibleInWindow)->GetAnnotation()->SetVisibility(1);
321
322             if (event == vtkCommand::MouseWheelForwardEvent && !isi->GetInteractor()->GetControlKey())
323             {
324                 this->SM->GetSlicer(VisibleInWindow)->SetSlice(this->SM->GetSlicer(VisibleInWindow)->GetSlice()+1);
325                 this->SM->UpdateSlice(VisibleInWindow);
326                 this->SM->UpdateInfoOnCursorPosition(VisibleInWindow);
327             }
328             else if (event == vtkCommand::MouseWheelForwardEvent && isi->GetInteractor()->GetControlKey())
329             {
330                 double factor = 2;
331                 this->Dolly(pow((double)1.1, factor),isi->GetInteractor());
332             }
333             else if (event == vtkCommand::MouseWheelBackwardEvent && !isi->GetInteractor()->GetControlKey())
334             {
335                 this->SM->GetSlicer(VisibleInWindow)->SetSlice(this->SM->GetSlicer(VisibleInWindow)->GetSlice()-1);
336                 this->SM->UpdateSlice(VisibleInWindow);
337                 this->SM->UpdateInfoOnCursorPosition(VisibleInWindow);
338             }
339             else if (event == vtkCommand::MouseWheelBackwardEvent && isi->GetInteractor()->GetControlKey())
340             {
341                 double factor = -2;
342                 this->Dolly(pow((double)1.1, factor),isi->GetInteractor());
343             }
344             double xWorld=0; double yWorld=0; double zWorld=0;
345
346             //Move into World Coordinate
347             renderer->DisplayToNormalizedDisplay(x,y);
348             renderer->NormalizedDisplayToViewport(x,y);
349             renderer->ViewportToNormalizedViewport(x,y);
350             renderer->NormalizedViewportToView(x,y,z);
351             renderer->ViewToWorld(x,y,z);
352             switch (this->SM->GetSlicer(VisibleInWindow)->GetSliceOrientation())
353             {
354                 case vtkImageViewer2::SLICE_ORIENTATION_XY:
355                     xWorld = x;
356                     yWorld = y;
357                     zWorld = this->SM->GetSlicer(VisibleInWindow)->GetSlice()*
358                         this->SM->GetSlicer(VisibleInWindow)->GetInput()->GetSpacing()[2] +
359                         this->SM->GetSlicer(VisibleInWindow)->GetInput()->GetOrigin()[2];
360                     break;
361
362                 case vtkImageViewer2::SLICE_ORIENTATION_XZ:
363                     xWorld = x;
364                     yWorld = this->SM->GetSlicer(VisibleInWindow)->GetSlice()*
365                         this->SM->GetSlicer(VisibleInWindow)->GetInput()->GetSpacing()[1] +
366                         this->SM->GetSlicer(VisibleInWindow)->GetInput()->GetOrigin()[1];
367                     zWorld = z;
368                     break;
369
370                 case vtkImageViewer2::SLICE_ORIENTATION_YZ:
371                     xWorld = this->SM->GetSlicer(VisibleInWindow)->GetSlice()*
372                         this->SM->GetSlicer(VisibleInWindow)->GetInput()->GetSpacing()[0] +
373                         this->SM->GetSlicer(VisibleInWindow)->GetInput()->GetOrigin()[0];
374                     yWorld = y;
375                     zWorld = z;
376                     break;
377             }
378             this->SM->GetSlicer(VisibleInWindow)->SetCurrentPosition(xWorld,yWorld,zWorld,
379                     this->SM->GetSlicer(VisibleInWindow)->GetTSlice());
380             if (newLandmark)
381             {
382                 this->SM->AddLandmark(xWorld,yWorld,zWorld,
383                                       this->SM->GetSlicer(VisibleInWindow)->GetTSlice());
384                 this->SM->GetSlicer(VisibleInWindow)->UpdateLandmarks();
385                 this->SM->Render();
386             }
387             if (event == vtkCommand::PickEvent || event == vtkCommand::StartPickEvent)
388             {
389                 this->SM->UpdateViews(1,VisibleInWindow);
390                 this->SM->UpdateLinked(VisibleInWindow);
391                 this->SM->UpdateInfoOnCursorPosition(VisibleInWindow);
392             }
393             else
394             {
395                 this->SM->GetSlicer(VisibleInWindow)->Render();
396             }
397             //this->SM->GetSlicer(VisibleInWindow)->SetCurrentPosition(-VTK_DOUBLE_MAX,-VTK_DOUBLE_MAX,
398             //-VTK_DOUBLE_MAX,this->SM->GetSlicer(VisibleInWindow)->GetTSlice());
399             //this->SM->GetSlicer(VisibleInWindow)->Render();
400         }
401
402         if (event == vtkCommand::WindowLevelEvent && mStartSlicer > -1)
403         {
404             this->SM->GetSlicer(mStartSlicer)->GetAnnotation()->SetVisibility(1);
405             // Adjust the window level here
406             int *size = isi->GetInteractor()->GetRenderWindow()->GetSize();
407             double window = this->InitialWindow;
408             double level = this->InitialLevel;
409             double range[2];
410             this->SM->GetImage()->GetScalarRange(range);
411
412             // Compute normalized delta
413             double dx = static_cast<double>(isi->GetWindowLevelCurrentPosition()[0] -
414                                             isi->GetWindowLevelStartPosition()[0]) / size[0];
415             double dy = static_cast<double>(isi->GetWindowLevelStartPosition()[1] -
416                                             isi->GetWindowLevelCurrentPosition()[1]) / size[1];
417             //Window is exponential in nature, use exponential to avoid falling into negative numbers
418             dx = std::exp(1.0 * (dx*fabs(dx) + dx)) ; //Quadratic behavior for more reactive interface
419             dy = 0.15 * (dy*fabs(dy) + dy) * (range[1]-range[0]);//Quadratic behavior for more reactive interface
420
421             this->SM->SetColorWindow(window*dx);
422             this->SM->SetColorLevel(level-dy);
423             this->SM->SetPreset(6);
424             this->SM->UpdateWindowLevel();
425             this->SM->Render();
426             return;
427         }
428     }
429 }
430 //------------------------------------------------------------------------------
431
432
433 //------------------------------------------------------------------------------
434 void vvSlicerManagerCommand::Dolly(double factor, vtkRenderWindowInteractor *interactor)
435 {
436     int VisibleInWindow = this->FindSlicerNumber(interactor->GetRenderWindow());
437     vtkRenderer* renderer;
438     if (VisibleInWindow>-1)
439         renderer=this->SM->GetSlicer(VisibleInWindow)->GetRenderer();
440     else
441     {
442         return;
443     }
444
445     double viewFocus[4],viewPoint[4],motionVector[3], focalDepth;
446     double oldPos[3], newPos[3], distance[2];
447     vtkCamera *camera = renderer->GetActiveCamera();
448     camera->GetFocalPoint(viewFocus);
449
450     renderer->SetWorldPoint(viewFocus[0], viewFocus[0], viewFocus[0], 1.0);
451     renderer->WorldToDisplay();
452     renderer->GetDisplayPoint(viewFocus);
453
454     focalDepth = viewFocus[2];
455
456     oldPos[0] = renderer->GetCenter()[0];
457     oldPos[1] = renderer->GetCenter()[1];
458     oldPos[2] = focalDepth;
459
460     distance[0] = 1/factor*
461         (interactor->GetEventPosition()[0]-renderer->GetCenter()[0]);
462     distance[1] = 1/factor*
463         (interactor->GetEventPosition()[1]-renderer->GetCenter()[1]);
464
465     newPos[0] = interactor->GetEventPosition()[0] - distance[0];
466     newPos[1] = interactor->GetEventPosition()[1] - distance[1];
467     newPos[2] = focalDepth;
468
469     renderer->DisplayToNormalizedDisplay(oldPos[0],oldPos[1]);
470     renderer->NormalizedDisplayToViewport(oldPos[0],oldPos[1]);
471     renderer->ViewportToNormalizedViewport(oldPos[0],oldPos[1]);
472     renderer->NormalizedViewportToView(oldPos[0],oldPos[1],oldPos[2]);
473     renderer->ViewToWorld(oldPos[0],oldPos[1],oldPos[2]);
474
475     renderer->DisplayToNormalizedDisplay(newPos[0],newPos[1]);
476     renderer->NormalizedDisplayToViewport(newPos[0],newPos[1]);
477     renderer->ViewportToNormalizedViewport(newPos[0],newPos[1]);
478     renderer->NormalizedViewportToView(newPos[0],newPos[1],newPos[2]);
479     renderer->ViewToWorld(newPos[0],newPos[1],newPos[2]);
480
481     motionVector[0] = newPos[0] - oldPos[0];
482     motionVector[1] = newPos[1] - oldPos[1];
483     motionVector[2] = newPos[2] - oldPos[2];
484
485     camera->GetFocalPoint(viewFocus);
486     camera->GetPosition(viewPoint);
487     camera->SetFocalPoint(motionVector[0] + viewFocus[0],
488                           motionVector[1] + viewFocus[1],
489                           motionVector[2] + viewFocus[2]);
490
491     camera->SetPosition(motionVector[0] + viewPoint[0],
492                         motionVector[1] + viewPoint[1],
493                         motionVector[2] + viewPoint[2]);
494
495     if (camera->GetParallelProjection())
496     {
497         camera->SetParallelScale(camera->GetParallelScale() / factor);
498     }
499     else
500     {
501         camera->Dolly(factor);
502     }
503
504     if (interactor->GetLightFollowCamera())
505     {
506         renderer->UpdateLightsGeometryToFollowCamera();
507     }
508     renderer->ResetCameraClippingRange();
509     //interactor->Render();
510 }
511
512 void vvSlicerManagerCommand::FlyToPosition(vtkRenderWindowInteractor *interactor,vvSlicer* slicer)
513 {
514     double flyFrom[3], flyTo[3];
515     double d[3], focalPt[3], position[3], positionFrom[3];
516     int i, j;
517     int VisibleInWindow = this->FindSlicerNumber(interactor->GetRenderWindow());
518     vtkRenderer* renderer=NULL;
519     if (VisibleInWindow>-1)
520         renderer=this->SM->GetSlicer(VisibleInWindow)->GetRenderer();
521     else
522         return;
523
524     interactor->GetPicker()->Pick(interactor->GetEventPosition()[0],
525                                   interactor->GetEventPosition()[1], 0.0,
526                                   renderer);
527
528     vtkAssemblyPath *path=NULL;
529     vtkAbstractPropPicker *picker;
530     if ( (picker=vtkAbstractPropPicker::SafeDownCast(interactor->GetPicker())))
531     {
532         path = picker->GetPath();
533     }
534     if ( path != NULL )
535     {
536         flyTo[0] = picker->GetPickPosition()[0];
537         flyTo[1] = picker->GetPickPosition()[1];
538         flyTo[2] = picker->GetPickPosition()[2];
539         renderer->GetActiveCamera()->GetFocalPoint(flyFrom);
540         renderer->GetActiveCamera()->GetPosition(positionFrom);
541
542         switch (slicer->GetSliceOrientation())
543         {
544         case vtkImageViewer2::SLICE_ORIENTATION_XY:
545             flyTo[2] = flyFrom[2];
546             break;
547
548         case vtkImageViewer2::SLICE_ORIENTATION_XZ:
549             flyTo[1] = flyFrom[1];
550             break;
551
552         case vtkImageViewer2::SLICE_ORIENTATION_YZ:
553             flyTo[0] = flyFrom[0];
554             break;
555         }
556
557
558         for (i=0; i<3; i++)
559         {
560             d[i] = flyTo[i] - flyFrom[i];
561         }
562         double distance = vtkMath::Normalize(d);
563         double delta = distance/15;
564
565         for (i=1; i<=15; i++)
566         {
567             for (j=0; j<3; j++)
568             {
569                 focalPt[j] = flyFrom[j] + d[j]*i*delta;
570                 position[j] = positionFrom[j] + d[j]*i*delta;
571             }
572             renderer->GetActiveCamera()->SetFocalPoint(focalPt);
573             renderer->GetActiveCamera()->SetPosition(position);
574             renderer->GetActiveCamera()->Dolly(0.3/15 + 1.0);
575             renderer->ResetCameraClippingRange();
576             interactor->Render();
577         }
578     }
579 }