]> Creatis software - bbtk.git/blob - packages/wxvtk/src/wxvtkImageViewer2.cxx
* Viewer2D now works !!!
[bbtk.git] / packages / wxvtk / src / wxvtkImageViewer2.cxx
1 /*=========================================================================
2
3   Program:   Visualization Toolkit
4   Module:    $RCSfile: wxvtkImageViewer2.cxx,v $
5
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "wxvtkImageViewer2.h"
16
17 #include "vtkCamera.h"
18 #include "vtkCommand.h"
19 #include "vtkImageActor.h"
20 #include "vtkImageData.h"
21 #include "vtkImageData.h"
22 #include "vtkImageMapToWindowLevelColors.h"
23 #include "vtkInteractorStyleImage.h"
24 #include "vtkObjectFactory.h"
25 #include "vtkRenderWindow.h"
26 #include "vtkRenderWindowInteractor.h"
27 #include "vtkRenderer.h"
28
29 vtkCxxRevisionMacro(wxvtkImageViewer2, "$Revision: 1.2 $");
30 vtkStandardNewMacro(wxvtkImageViewer2);
31
32 //----------------------------------------------------------------------------
33 wxvtkImageViewer2::wxvtkImageViewer2()
34 {
35   this->RenderWindow    = NULL;
36   this->Renderer        = NULL;
37   this->ImageActor      = vtkImageActor::New();
38   this->WindowLevel     = vtkImageMapToWindowLevelColors::New();
39   this->Interactor      = NULL;
40   this->InteractorStyle = NULL;
41
42   this->Slice = 0;
43   this->FirstRender = 1;
44   this->SliceOrientation = wxvtkImageViewer2::SLICE_ORIENTATION_XY;
45
46   // Setup the pipeline
47
48   vtkRenderWindow *renwin = vtkRenderWindow::New();
49   this->SetRenderWindow(renwin);
50   renwin->Delete();
51
52   vtkRenderer *ren = vtkRenderer::New();
53   this->SetRenderer(ren);
54   ren->Delete();
55
56   this->InstallPipeline();
57 }
58
59 //----------------------------------------------------------------------------
60 wxvtkImageViewer2::~wxvtkImageViewer2()
61 {
62   if (this->WindowLevel)
63     {
64     this->WindowLevel->Delete();
65     this->WindowLevel = NULL;
66     }
67
68   if (this->ImageActor)
69     {
70     this->ImageActor->Delete();
71     this->ImageActor = NULL;
72     }
73
74   if (this->Renderer)
75     {
76     this->Renderer->Delete();
77     this->Renderer = NULL;
78     }
79
80   if (this->RenderWindow)
81     {
82     this->RenderWindow->Delete();
83     this->RenderWindow = NULL;
84     }
85
86   if (this->Interactor)
87     {
88     this->Interactor->Delete();
89     this->Interactor = NULL;
90     }
91
92   if (this->InteractorStyle)
93     {
94     this->InteractorStyle->Delete();
95     this->InteractorStyle = NULL;
96     }
97 }
98
99 //----------------------------------------------------------------------------
100 void wxvtkImageViewer2::SetupInteractor(vtkRenderWindowInteractor *arg)
101 {
102   if (this->Interactor == arg)
103     {
104     return;
105     }
106
107   this->UnInstallPipeline();
108
109   if (this->Interactor)
110     {
111     this->Interactor->UnRegister(this);
112     }
113     
114   this->Interactor = arg;
115   
116   if (this->Interactor)
117     {
118     this->Interactor->Register(this);
119     }
120
121   this->InstallPipeline();
122
123   if (this->Renderer)
124     {
125     this->Renderer->GetActiveCamera()->ParallelProjectionOn();
126     }
127 }
128
129 //----------------------------------------------------------------------------
130 void wxvtkImageViewer2::SetRenderWindow(vtkRenderWindow *arg)
131 {
132   if (this->RenderWindow == arg)
133     {
134     return;
135     }
136
137   this->UnInstallPipeline();
138
139   if (this->RenderWindow)
140     {
141     this->RenderWindow->UnRegister(this);
142     }
143     
144   this->RenderWindow = arg;
145   
146   if (this->RenderWindow)
147     {
148     this->RenderWindow->Register(this);
149     }
150
151   this->InstallPipeline();
152 }
153
154 //----------------------------------------------------------------------------
155 void wxvtkImageViewer2::SetRenderer(vtkRenderer *arg)
156 {
157   if (this->Renderer == arg)
158     {
159     return;
160     }
161
162   this->UnInstallPipeline();
163
164   if (this->Renderer)
165     {
166     this->Renderer->UnRegister(this);
167     }
168     
169   this->Renderer = arg;
170   
171   if (this->Renderer)
172     {
173     this->Renderer->Register(this);
174     }
175
176   this->InstallPipeline();
177   this->UpdateOrientation();
178 }
179
180 //----------------------------------------------------------------------------
181 void wxvtkImageViewer2::SetSize(int a,int b) 
182 {
183   this->RenderWindow->SetSize(a, b);
184 }
185
186 //----------------------------------------------------------------------------
187 int* wxvtkImageViewer2::GetSize() 
188 {
189   return this->RenderWindow->GetSize();
190 }
191
192 //----------------------------------------------------------------------------
193 void wxvtkImageViewer2::GetSliceRange(int &min, int &max)
194 {
195   vtkImageData *input = this->GetInput();
196   if (input)
197     {
198     input->UpdateInformation();
199     int *w_ext = input->GetWholeExtent();
200     min = w_ext[this->SliceOrientation * 2];
201     max = w_ext[this->SliceOrientation * 2 + 1];
202     }
203 }
204
205 //----------------------------------------------------------------------------
206 int* wxvtkImageViewer2::GetSliceRange()
207 {
208   vtkImageData *input = this->GetInput();
209   if (input)
210     {
211     input->UpdateInformation();
212     return input->GetWholeExtent() + this->SliceOrientation * 2;
213     }
214   return NULL;
215 }
216
217 //----------------------------------------------------------------------------
218 int wxvtkImageViewer2::GetSliceMin() 
219 {
220   int *range = this->GetSliceRange();
221   if (range)
222     {
223     return range[0];
224     }
225   return 0;
226 }
227
228 //----------------------------------------------------------------------------
229 int wxvtkImageViewer2::GetSliceMax() 
230 {
231   int *range = this->GetSliceRange();
232   if (range)
233     {
234     return range[1];
235     }
236   return 0;
237 }
238
239 //----------------------------------------------------------------------------
240 void wxvtkImageViewer2::SetSlice(int slice)
241 {
242   int *range = this->GetSliceRange();
243   if (range)
244     {
245     if (slice < range[0])
246       {
247       slice = range[0];
248       }
249     else if (slice > range[1])
250       {
251       slice = range[1];
252       }
253     }
254
255   if (this->Slice == slice)
256     {
257     return;
258     }
259
260   this->Slice = slice;
261   this->Modified();
262
263   this->UpdateDisplayExtent();
264   this->Render();
265 }
266
267 //----------------------------------------------------------------------------
268 void wxvtkImageViewer2::SetSliceOrientation(int orientation)
269 {
270   if (orientation < wxvtkImageViewer2::SLICE_ORIENTATION_YZ ||
271       orientation > wxvtkImageViewer2::SLICE_ORIENTATION_XY)
272     {
273     vtkErrorMacro("Error - invalid slice orientation " << orientation);
274     return;
275     }
276   
277   if (this->SliceOrientation == orientation)
278     {
279     return;
280     }
281
282   this->SliceOrientation = orientation;
283
284   // Update the viewer 
285
286   int *range = this->GetSliceRange();
287   if (range)
288     {
289     this->Slice = static_cast<int>((range[0] + range[1]) * 0.5);
290     }
291
292   this->UpdateOrientation();
293   this->UpdateDisplayExtent();
294
295   if (this->Renderer && this->GetInput())
296     {
297     double scale = this->Renderer->GetActiveCamera()->GetParallelScale();
298     this->Renderer->ResetCamera();
299     this->Renderer->GetActiveCamera()->SetParallelScale(scale);
300     }
301
302   this->Render();
303 }
304
305 //----------------------------------------------------------------------------
306 void wxvtkImageViewer2::UpdateOrientation()
307 {
308   // Set the camera position
309
310   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
311   if (cam)
312     {
313     switch (this->SliceOrientation)
314       {
315       case wxvtkImageViewer2::SLICE_ORIENTATION_XY:
316         cam->SetFocalPoint(0,0,0);
317         cam->SetPosition(0,0,1); // -1 if medical ?
318         cam->SetViewUp(0,1,0);
319         break;
320         
321       case wxvtkImageViewer2::SLICE_ORIENTATION_XZ:
322         cam->SetFocalPoint(0,0,0);
323         cam->SetPosition(0,-1,0); // 1 if medical ?
324         cam->SetViewUp(0,0,1);
325         break;
326         
327       case wxvtkImageViewer2::SLICE_ORIENTATION_YZ:
328         cam->SetFocalPoint(0,0,0);
329         cam->SetPosition(1,0,0); // -1 if medical ?
330         cam->SetViewUp(0,0,1);
331         break;
332       }
333     }
334 }
335
336 //----------------------------------------------------------------------------
337 void wxvtkImageViewer2::UpdateDisplayExtent()
338 {
339   vtkImageData *input = this->GetInput();
340   if (!input || !this->ImageActor)
341     {
342     return;
343     }
344
345   //  std::cout << "--- wxvtkImageViewer2::UpdateDisplayExtent()"<<std::endl;
346   input->UpdateInformation();
347   int *w_ext = input->GetWholeExtent();
348
349   //    std::cout << "ext = "
350   //    <<w_ext[0]<<" - "<<w_ext[1]<<" ; "
351   //            <<w_ext[2]<<" - "<<w_ext[3]<<" ; "
352   //            <<w_ext[4]<<" - "<<w_ext[5]
353   //            <<std::endl;
354       // Is the slice in range ? If not, fix it
355
356   int slice_min = w_ext[this->SliceOrientation * 2];
357   int slice_max = w_ext[this->SliceOrientation * 2 + 1];
358   if (this->Slice < slice_min || this->Slice > slice_max)
359     {
360     this->Slice = static_cast<int>((slice_min + slice_max) * 0.5);
361     }
362
363   // Set the image actor
364
365   switch (this->SliceOrientation)
366     {
367     case wxvtkImageViewer2::SLICE_ORIENTATION_XY:
368       this->ImageActor->SetDisplayExtent(
369         w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice);
370       break;
371
372     case wxvtkImageViewer2::SLICE_ORIENTATION_XZ:
373       this->ImageActor->SetDisplayExtent(
374         w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5]);
375       break;
376
377     case wxvtkImageViewer2::SLICE_ORIENTATION_YZ:
378       this->ImageActor->SetDisplayExtent(
379         this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5]);
380       break;
381     }
382
383   // Figure out the correct clipping range
384
385   if (this->Renderer)
386     {
387     if (this->InteractorStyle && 
388         this->InteractorStyle->GetAutoAdjustCameraClippingRange())
389       {
390       this->Renderer->ResetCameraClippingRange();
391       }
392     else
393       {
394       vtkCamera *cam = this->Renderer->GetActiveCamera();
395       if (cam)
396         {
397         double bounds[6];
398         this->ImageActor->GetBounds(bounds);
399         double spos = bounds[this->SliceOrientation * 2];
400         double cpos = cam->GetPosition()[this->SliceOrientation];
401         double range = fabs(spos - cpos);
402         double *spacing = input->GetSpacing();
403         double avg_spacing = 
404           (spacing[0] + spacing[1] + spacing[2]) / 3.0;
405         cam->SetClippingRange(
406           range - avg_spacing * 3.0, range + avg_spacing * 3.0);
407         }
408       }
409     }
410 }
411
412 //----------------------------------------------------------------------------
413 void wxvtkImageViewer2::SetPosition(int a,int b) 
414 {
415   this->RenderWindow->SetPosition(a, b);
416 }
417
418 //----------------------------------------------------------------------------
419 int* wxvtkImageViewer2::GetPosition() 
420 {
421   return this->RenderWindow->GetPosition();
422 }
423
424 //----------------------------------------------------------------------------
425 void wxvtkImageViewer2::SetDisplayId(void *a) 
426 {
427   this->RenderWindow->SetDisplayId(a);
428 }
429
430 //----------------------------------------------------------------------------
431 void wxvtkImageViewer2::SetWindowId(void *a) 
432 {
433   this->RenderWindow->SetWindowId(a);
434 }
435
436 //----------------------------------------------------------------------------
437 void wxvtkImageViewer2::SetParentId(void *a) 
438 {
439   this->RenderWindow->SetParentId(a);
440 }
441
442 //----------------------------------------------------------------------------
443 double wxvtkImageViewer2::GetColorWindow() 
444 {
445   return this->WindowLevel->GetWindow();
446 }
447
448 //----------------------------------------------------------------------------
449 double wxvtkImageViewer2::GetColorLevel() 
450 {
451   return this->WindowLevel->GetLevel();
452 }
453
454 //----------------------------------------------------------------------------
455 void wxvtkImageViewer2::SetColorWindow(double s) 
456 {
457   this->WindowLevel->SetWindow(s);
458 }
459
460 //----------------------------------------------------------------------------
461 void wxvtkImageViewer2::SetColorLevel(double s) 
462 {
463   this->WindowLevel->SetLevel(s);
464 }
465
466 //----------------------------------------------------------------------------
467 class wxvtkImageViewer2Callback : public vtkCommand
468 {
469 public:
470   static wxvtkImageViewer2Callback *New() { return new wxvtkImageViewer2Callback; }
471   
472   void Execute(vtkObject *caller, 
473                unsigned long event, 
474                void *vtkNotUsed(callData))
475     {
476       if (this->IV->GetInput() == NULL)
477         {
478         return;
479         }
480
481       // Reset
482
483       if (event == vtkCommand::ResetWindowLevelEvent)
484         {
485         this->IV->GetInput()->UpdateInformation();
486         this->IV->GetInput()->SetUpdateExtent
487           (this->IV->GetInput()->GetWholeExtent());
488         this->IV->GetInput()->Update();
489         double *range = this->IV->GetInput()->GetScalarRange();
490         this->IV->SetColorWindow(range[1] - range[0]);
491         this->IV->SetColorLevel(0.5 * (range[1] + range[0]));
492         this->IV->Render();
493         return;
494         }
495
496       // Start
497
498       if (event == vtkCommand::StartWindowLevelEvent)
499         {
500         this->InitialWindow = this->IV->GetColorWindow();
501         this->InitialLevel = this->IV->GetColorLevel();
502         return;
503         }
504       
505       // Adjust the window level here
506
507       vtkInteractorStyleImage *isi = 
508         static_cast<vtkInteractorStyleImage *>(caller);
509
510       int *size = this->IV->GetRenderWindow()->GetSize();
511       double window = this->InitialWindow;
512       double level = this->InitialLevel;
513       
514       // Compute normalized delta
515
516       double dx = 4.0 * 
517         (isi->GetWindowLevelCurrentPosition()[0] - 
518          isi->GetWindowLevelStartPosition()[0]) / size[0];
519       double dy = 4.0 * 
520         (isi->GetWindowLevelStartPosition()[1] - 
521          isi->GetWindowLevelCurrentPosition()[1]) / size[1];
522       
523       // Scale by current values
524
525       if (fabs(window) > 0.01)
526         {
527         dx = dx * window;
528         }
529       else
530         {
531         dx = dx * (window < 0 ? -0.01 : 0.01);
532         }
533       if (fabs(level) > 0.01)
534         {
535         dy = dy * level;
536         }
537       else
538         {
539         dy = dy * (level < 0 ? -0.01 : 0.01);
540         }
541       
542       // Abs so that direction does not flip
543
544       if (window < 0.0) 
545         {
546         dx = -1*dx;
547         }
548       if (level < 0.0) 
549         {
550         dy = -1*dy;
551         }
552       
553       // Compute new window level
554
555       double newWindow = dx + window;
556       double newLevel;
557       newLevel = level - dy;
558       
559       // Stay away from zero and really
560
561       if (fabs(newWindow) < 0.01)
562         {
563         newWindow = 0.01*(newWindow < 0 ? -1 : 1);
564         }
565       if (fabs(newLevel) < 0.01)
566         {
567         newLevel = 0.01*(newLevel < 0 ? -1 : 1);
568         }
569       
570       this->IV->SetColorWindow(newWindow);
571       this->IV->SetColorLevel(newLevel);
572       this->IV->Render();
573     }
574   
575   wxvtkImageViewer2 *IV;
576   double InitialWindow;
577   double InitialLevel;
578 };
579
580 //----------------------------------------------------------------------------
581 void wxvtkImageViewer2::InstallPipeline()
582 {
583   if (this->RenderWindow && this->Renderer)
584     {
585     this->RenderWindow->AddRenderer(this->Renderer);
586     }
587
588   if (this->Interactor)
589     {
590     if (!this->InteractorStyle)
591       {
592       this->InteractorStyle = vtkInteractorStyleImage::New();
593       wxvtkImageViewer2Callback *cbk = wxvtkImageViewer2Callback::New();
594       cbk->IV = this;
595       this->InteractorStyle->AddObserver(
596         vtkCommand::WindowLevelEvent, cbk);
597       this->InteractorStyle->AddObserver(
598         vtkCommand::StartWindowLevelEvent, cbk);
599       this->InteractorStyle->AddObserver(
600         vtkCommand::ResetWindowLevelEvent, cbk);
601       cbk->Delete();
602       }
603     
604     this->Interactor->SetInteractorStyle(this->InteractorStyle);
605     this->Interactor->SetRenderWindow(this->RenderWindow);
606     }
607
608   if (this->Renderer && this->ImageActor)
609     {
610     this->Renderer->AddViewProp(this->ImageActor);
611     }
612
613   if (this->ImageActor && this->WindowLevel)
614     {
615     this->ImageActor->SetInput(this->WindowLevel->GetOutput());
616     }
617 }
618
619 //----------------------------------------------------------------------------
620 void wxvtkImageViewer2::UnInstallPipeline()
621 {
622   if (this->ImageActor)
623     {
624     this->ImageActor->SetInput(NULL);
625     }
626
627   if (this->Renderer && this->ImageActor)
628     {
629     this->Renderer->RemoveViewProp(this->ImageActor);
630     }
631
632   if (this->RenderWindow && this->Renderer)
633     {
634     this->RenderWindow->RemoveRenderer(this->Renderer);
635     }
636
637   if (this->Interactor)
638     {
639     this->Interactor->SetInteractorStyle(NULL);
640     this->Interactor->SetRenderWindow(NULL);
641     }
642 }
643
644 //----------------------------------------------------------------------------
645 void wxvtkImageViewer2::Render()
646 {
647   if (this->FirstRender)
648     {
649     // Initialize the size if not set yet
650
651     vtkImageData *input = this->GetInput();
652     if (this->RenderWindow->GetSize()[0] == 0 && 
653         input)
654       {
655         
656       input->UpdateInformation();
657       int *w_ext = input->GetWholeExtent();
658       int xs = 0, ys = 0;
659       
660       //        std::cout << "wxvtkImageViewer2::Render ext = "
661       //        <<w_ext[0]<<" - "<<w_ext[1]<<" ; "
662       //                <<w_ext[2]<<" - "<<w_ext[3]<<" ; "
663       //                <<w_ext[4]<<" - "<<w_ext[5]
664       //                <<std::endl;
665       
666       switch (this->SliceOrientation)
667         {
668         case wxvtkImageViewer2::SLICE_ORIENTATION_XY:
669         default:
670           xs = w_ext[1] - w_ext[0] + 1;
671           ys = w_ext[3] - w_ext[2] + 1;
672           //      std::cout << "SLICE_ORIENTATION_XY" << std::endl;
673           break;
674
675         case wxvtkImageViewer2::SLICE_ORIENTATION_XZ:
676           xs = w_ext[1] - w_ext[0] + 1;
677           ys = w_ext[5] - w_ext[4] + 1;
678           //      std::cout << "SLICE_ORIENTATION_XZ" << std::endl;
679           break;
680
681         case wxvtkImageViewer2::SLICE_ORIENTATION_YZ:
682           xs = w_ext[3] - w_ext[2] + 1;
683           ys = w_ext[5] - w_ext[4] + 1;
684           //      std::cout << "SLICE_ORIENTATION_YZ" << std::endl;
685           break;
686         }
687
688       // if it would be smaller than 150 by 100 then limit to 150 by 100
689       this->RenderWindow->SetSize(
690         xs < 150 ? 150 : xs, ys < 100 ? 100 : ys);
691
692       //      std::cout << "wxvtkImageViewer2::Render() : "<<xs<<"-"<<ys<<std::endl;
693       if (this->Renderer)
694         {
695         this->Renderer->ResetCamera();
696         this->Renderer->GetActiveCamera()->SetParallelScale(
697           xs < 150 ? 75 : (xs - 1 ) / 2.0);
698         }
699       this->FirstRender = 0;  
700
701       }
702     }
703   if (this->GetInput())
704     {
705     this->RenderWindow->Render();
706     }
707 }
708
709 //----------------------------------------------------------------------------
710 const char* wxvtkImageViewer2::GetWindowName() 
711 {
712   return this->RenderWindow->GetWindowName();
713 }
714
715 //----------------------------------------------------------------------------
716 void wxvtkImageViewer2::SetOffScreenRendering(int i)
717 {
718   this->RenderWindow->SetOffScreenRendering(i);
719 }
720
721 //----------------------------------------------------------------------------
722 int wxvtkImageViewer2::GetOffScreenRendering()
723 {
724   return this->RenderWindow->GetOffScreenRendering();
725 }
726
727 //----------------------------------------------------------------------------
728 void wxvtkImageViewer2::SetInput(vtkImageData *in) 
729 {
730   //  std::cout << "### wxvtkImageViewer2::SetInput"<<std::endl;
731   this->WindowLevel->SetInput(in);
732   this->UpdateDisplayExtent();
733   // LG 03/12/08
734   //  FirstRender = 1;
735 }
736 //----------------------------------------------------------------------------
737 vtkImageData* wxvtkImageViewer2::GetInput()
738
739   return vtkImageData::SafeDownCast(this->WindowLevel->GetInput());
740 }
741
742 //----------------------------------------------------------------------------
743 void wxvtkImageViewer2::SetInputConnection(vtkAlgorithmOutput* input) 
744 {
745   this->WindowLevel->SetInputConnection(input);
746   this->UpdateDisplayExtent();
747 }
748
749 //----------------------------------------------------------------------------
750 #ifndef VTK_LEGACY_REMOVE
751 int wxvtkImageViewer2::GetWholeZMin()
752 {
753   VTK_LEGACY_REPLACED_BODY(wxvtkImageViewer2::GetWholeZMin, "VTK 5.0",
754                            wxvtkImageViewer2::GetSliceMin);
755   return this->GetSliceMin();
756 }
757 int wxvtkImageViewer2::GetWholeZMax()
758 {
759   VTK_LEGACY_REPLACED_BODY(wxvtkImageViewer2::GetWholeZMax, "VTK 5.0",
760                            wxvtkImageViewer2::GetSliceMax);
761   return this->GetSliceMax();
762 }
763 int wxvtkImageViewer2::GetZSlice()
764 {
765   VTK_LEGACY_REPLACED_BODY(wxvtkImageViewer2::GetZSlice, "VTK 5.0",
766                            wxvtkImageViewer2::GetSlice);
767   return this->GetSlice();
768 }
769 void wxvtkImageViewer2::SetZSlice(int s)
770 {
771   VTK_LEGACY_REPLACED_BODY(wxvtkImageViewer2::SetZSlice, "VTK 5.0",
772                            wxvtkImageViewer2::SetSlice);
773   this->SetSlice(s);
774 }
775 #endif
776
777 //----------------------------------------------------------------------------
778 void wxvtkImageViewer2::PrintSelf(ostream& os, vtkIndent indent)
779 {
780   this->Superclass::PrintSelf(os, indent);
781
782   os << indent << "RenderWindow:\n";
783   this->RenderWindow->PrintSelf(os,indent.GetNextIndent());
784   os << indent << "Renderer:\n";
785   this->Renderer->PrintSelf(os,indent.GetNextIndent());
786   os << indent << "ImageActor:\n";
787   this->ImageActor->PrintSelf(os,indent.GetNextIndent());
788   os << indent << "WindowLevel:\n" << endl;
789   this->WindowLevel->PrintSelf(os,indent.GetNextIndent());
790   os << indent << "Slice: " << this->Slice << endl;
791   os << indent << "SliceOrientation: " << this->SliceOrientation << endl;
792   os << indent << "InteractorStyle: " << endl;
793   if (this->InteractorStyle)
794     {
795     os << "\n";
796     this->InteractorStyle->PrintSelf(os,indent.GetNextIndent());
797     }
798   else
799     {
800     os << "None";
801     }
802 }