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