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