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