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