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