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