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