]> Creatis software - clitk.git/blob - vv/vvSlicer.cxx
- toolbase + binarize
[clitk.git] / vv / vvSlicer.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 "vvSlicer.h"
25
26 #include "vvImage.h"
27 #include "vvSlicerManagerCommand.h"
28 #include "vvGlyphSource.h"
29 #include "vvGlyph2D.h"
30 #include "vvImageMapToWLColors.h"
31
32 #include <vtkTextProperty.h>
33 #include <vtkTextActor.h>
34 #include <vtkTextSource.h>
35 #include <vtkActor2D.h>
36 #include <vtkCursor2D.h>
37 #include <vtkPolyDataMapper2D.h>
38 #include <vtkProperty2D.h>
39 #include <vtkCornerAnnotation.h>
40 #include <vtkImageMapToWindowLevelColors.h>
41 #include <vtkImageData.h>
42 #include <vtkImageActor.h>
43 #include <vtkToolkits.h>
44 #include <vtkObjectFactory.h>
45 #include <vtkPointData.h>
46 #include <vtkDataArray.h>
47 #include <vtkFloatArray.h>
48 #include <vtkClipPolyData.h>
49 #include <vtkGlyph3D.h>
50 #include <vtkMath.h>
51 #include <vtkCursor3D.h>
52 #include <vtkProperty.h>
53 #include <vtkLight.h>
54 #include <vtkLightCollection.h>
55 #include <vtkScalarBarActor.h>
56 #include <vtkLookupTable.h>
57
58 #include <vtkRenderer.h>
59 #include <vtkRendererCollection.h>
60 #include <vtkRenderWindow.h>
61 #include <vtkRenderWindowInteractor.h>
62 #include <vtkCamera.h>
63 #include <vtkCallbackCommand.h>
64 #include <vtkCommand.h>
65 #include <vtkPolyDataMapper.h>
66 #include <vtkBox.h>
67
68 #include <vtkExtractVOI.h>
69 #include <vtkSphereSource.h>
70 #include <vtkCutter.h>
71 #include <vtkPlane.h>
72 #include <vtkAssignAttribute.h>
73
74 vtkCxxRevisionMacro(vvSlicer, "DummyRevision");
75 vtkStandardNewMacro(vvSlicer);
76
77 vvSlicer::vvSlicer()
78 {
79   mImage = NULL;
80   mCurrentTSlice = 0;
81   mUseReducedExtent = false;
82
83   mCurrent[0] = -VTK_DOUBLE_MAX;
84   mCurrent[1] = -VTK_DOUBLE_MAX;
85   mCurrent[2] = -VTK_DOUBLE_MAX;
86
87   mCursor[0] = -VTK_DOUBLE_MAX;
88   mCursor[1] = -VTK_DOUBLE_MAX;
89   mCursor[2] = -VTK_DOUBLE_MAX;
90   mCursor[3] = -VTK_DOUBLE_MAX;
91
92   mSubSampling = 5;
93   mScale = 1;
94   mVFLog = 0;
95
96   std::string text = "F1 = sagital; F2 = coronal; F3 = axial\n";
97   text += "F5 = horizontal flip; F6 = vertical flip\n\n";
98   text += "0,1,2,3,4,5 : preset windowing\n";
99   text += "6,7,8,9 : preset colormap\n";
100   text += "r : reset view\n";
101   text += "l : reload image\n";
102   text += "f : fly to mouse position\n";
103   text += "g : go to cross hair position\n\n";
104   text += "Up,down : change slice\n";
105   text += "Left,right : change tenporal slice\n\n";
106   text += "Scrollbar (or w/x) : zoom in/out\n";
107   text += "left button : synchronize all views\n";
108   text += "middle button : grab image\n";
109   text += "right button : change windowing\n";
110
111   crossCursor = vtkCursor2D::New();
112   crossCursor->AllOff();
113   crossCursor->AxesOn();
114   crossCursor->SetTranslationMode(1);
115   crossCursor->SetRadius(2);
116
117   pdm = vtkPolyDataMapper2D::New();
118   pdm->SetInput(crossCursor->GetOutput());
119
120   pdmA = vtkActor2D::New();
121   pdmA->SetMapper(pdm);
122   pdmA->GetProperty()->SetColor(255,10,212);
123   pdmA->SetVisibility(0);
124   pdmA->SetPickable(0);
125
126   ca = vtkCornerAnnotation::New();
127   ca->GetTextProperty()->SetColor(255,10,212);
128   ca->SetVisibility(1);
129   mFileName = "";
130
131   mVF = NULL;
132   mOverlay = NULL;
133   mFusion = NULL;
134   mLandmarks = NULL;
135
136   legend = vtkSmartPointer<vtkScalarBarActor>::New();
137   //legend->SetTitle("test!");
138   legend->SetPosition(0.82,0.18);
139   legend->SetWidth(0.1);
140   legend->SetVisibility(0);
141   legend->SetLabelFormat("%.1f");
142   this->GetRenderer()->AddActor(legend);
143
144   this->WindowLevel->Delete();
145   this->WindowLevel = vvImageMapToWLColors::New();
146   this->InstallPipeline();
147 }
148
149 vtkImageMapToWindowLevelColors* vvSlicer::GetOverlayMapper() {
150   return mOverlayMapper.GetPointer();
151 }
152 vtkImageActor* vvSlicer::GetOverlayActor() {
153   return mOverlayActor.GetPointer();
154 }
155 vtkImageMapToWindowLevelColors* vvSlicer::GetFusionMapper() {
156   return mFusionMapper.GetPointer();
157 }
158     
159 vtkImageActor* vvSlicer::GetFusionActor() {
160   return mFusionActor.GetPointer();
161 }
162 vtkActor* vvSlicer::GetVFActor() {
163   return mVFActor.GetPointer();
164 }
165 vtkCornerAnnotation* vvSlicer::GetAnnotation() {
166   return ca.GetPointer();
167 }
168
169 //------------------------------------------------------------------------------
170 void vvSlicer::EnableReducedExtent(bool b) {
171   mUseReducedExtent = b;
172 }
173 //------------------------------------------------------------------------------
174
175
176 //------------------------------------------------------------------------------
177 void vvSlicer::SetReducedExtent(int * ext) {
178   mReducedExtent = ext;
179 }
180 //------------------------------------------------------------------------------
181
182
183 //------------------------------------------------------------------------------
184 void vvSlicer::AddContour(vvMesh::Pointer contour,bool propagate)
185 {
186
187   mSurfaceCutActors.push_back(new vvMeshActor());
188   if (propagate)
189     mSurfaceCutActors.back()->Init(contour,mCurrentTSlice,mVF);
190   else
191     mSurfaceCutActors.back()->Init(contour,mCurrentTSlice);
192   mSurfaceCutActors.back()->SetSlicingOrientation(SliceOrientation);
193   this->GetRenderer()->AddActor(mSurfaceCutActors.back()->GetActor());
194
195   SetContourSlice();
196 }
197
198 void vvSlicer::ToggleContourSuperposition()
199 {
200   for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
201        i!=mSurfaceCutActors.end();i++)
202     (*i)->ToggleSuperposition();
203 }
204
205 void vvSlicer::SetCursorColor(int r,int g, int b)
206 {
207   pdmA->GetProperty()->SetColor(r,g,b);
208 }
209 void vvSlicer::SetCursorVisibility(bool s)
210 {
211   pdmA->SetVisibility(s);
212 }
213 bool vvSlicer::GetCursorVisibility()
214 {
215   return pdmA->GetVisibility();
216 }
217
218 vvSlicer::~vvSlicer()
219 {
220   for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
221        i!=mSurfaceCutActors.end();i++)
222     delete (*i);
223 }
224
225 void vvSlicer::SetCurrentPosition(double x, double y, double z, int t)
226 {
227   mCurrent[0] = x;
228   mCurrent[1] = y;
229   mCurrent[2] = z;
230   mCurrentTSlice = t;
231 }
232
233 void vvSlicer::SetImage(vvImage::Pointer image)
234 {
235   if (image->GetVTKImages().size())
236     {
237       mImage = image;
238       this->Superclass::SetInput(image->GetVTKImages()[0]);
239       this->UpdateDisplayExtent();
240       mCurrentTSlice = 0;
241       ca->SetText(0,mFileName.c_str());
242     }
243 }
244
245 void vvSlicer::SetOverlay(vvImage::Pointer overlay)
246 {
247   if (overlay->GetVTKImages().size())
248     {
249       mOverlay = overlay;
250
251       if (!mOverlayMapper)
252         mOverlayMapper = vtkImageMapToWindowLevelColors::New();
253       mOverlayMapper->SetInput(overlay->GetVTKImages()[0]);
254
255       if (!mOverlayActor)
256         {
257           mOverlayActor = vtkImageActor::New();
258           mOverlayActor->SetInput(mOverlayMapper->GetOutput());
259           mOverlayActor->SetPickable(0);
260           mOverlayActor->SetVisibility(false);
261           mOverlayActor->SetOpacity(0.5);
262           this->UpdateDisplayExtent();
263         }
264
265       //stupid but necessary : the Overlay need to be rendered before fusion
266       if (mFusionActor)
267         {
268           this->GetRenderer()->RemoveActor(mFusionActor);
269           this->GetRenderer()->AddActor(mOverlayActor);
270           this->GetRenderer()->AddActor(mFusionActor);
271         }
272       else
273         this->GetRenderer()->AddActor(mOverlayActor);
274
275       //Synchronize slice
276       SetTSlice(mCurrentTSlice);
277     }
278 }
279
280 void vvSlicer::SetFusion(vvImage::Pointer fusion)
281 {
282   if (fusion->GetVTKImages().size())
283     {
284       mFusion = fusion;
285
286       if (!mFusionMapper)
287         mFusionMapper = vtkImageMapToWindowLevelColors::New();
288       mFusionMapper->SetInput(fusion->GetVTKImages()[0]);
289
290       if (!mFusionActor)
291         {
292           mFusionActor = vtkImageActor::New();
293           mFusionActor->SetInput(mFusionMapper->GetOutput());
294           mFusionActor->SetPickable(0);
295           mFusionActor->SetVisibility(false);
296           mFusionActor->SetOpacity(0.7);
297           this->UpdateDisplayExtent();
298           this->GetRenderer()->AddActor(mFusionActor);
299         }
300
301       //Synchronize slice
302       SetTSlice(mCurrentTSlice);
303     }
304 }
305
306 void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis)
307 {
308   if (actor_type == "vector")
309     {
310       this->mVFActor->SetVisibility(vis);
311     }
312   if (actor_type == "overlay")
313     {
314       this->mOverlayActor->SetVisibility(vis);
315     }
316   if (actor_type == "fusion")
317     {
318       this->mFusionActor->SetVisibility(vis);
319     }
320   if (actor_type == "contour")
321     this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis);
322   UpdateDisplayExtent();
323 }
324
325 void vvSlicer::SetVF(vvImage::Pointer vf)
326 {
327   if (vf->GetVTKImages().size())
328     {
329       mVF = vf;
330
331       if (!mAAFilter)
332         {
333           mAAFilter=vtkAssignAttribute::New();
334           mVOIFilter = vtkExtractVOI::New();
335           mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
336         }
337       mVOIFilter->SetInput(vf->GetVTKImages()[0]);
338       mAAFilter->SetInput(mVOIFilter->GetOutput());
339       ///This tells VTK to use the scalar (pixel) data of the image to draw the little arrows
340       mAAFilter->Assign(vtkDataSetAttributes::SCALARS, vtkDataSetAttributes::VECTORS, vtkAssignAttribute::POINT_DATA);
341
342       if (!mArrow)
343         mArrow = vvGlyphSource::New();
344       mArrow->SetGlyphTypeToSpecificArrow();
345       mArrow->SetScale(mScale);
346       mArrow->FilledOff();
347
348       // Glyph the gradient vector (with arrows)
349       if (!mGlyphFilter)
350         mGlyphFilter = vvGlyph2D::New();
351       mGlyphFilter->SetInput(mAAFilter->GetOutput());
352       mGlyphFilter->SetSource(mArrow->GetOutput());
353       mGlyphFilter->ScalingOn();
354       mGlyphFilter->SetScaleModeToScaleByVector();
355       mGlyphFilter->OrientOn();
356       mGlyphFilter->SetVectorModeToUseVector();
357       mGlyphFilter->SetColorModeToColorByVector();
358
359       if (!mVFMapper)
360         mVFMapper = vtkPolyDataMapper::New();
361       //mVFMapper->SetInputConnection(mGlyphFilter->GetOutputPort());
362       mVFMapper->SetInput(mGlyphFilter->GetOutput());
363       mVFMapper->ImmediateModeRenderingOn();
364
365       if (!mVFActor)
366         mVFActor = vtkActor::New();
367       mVFActor->SetMapper(mVFMapper);
368       mVFActor->SetPickable(0);
369       this->UpdateDisplayExtent();
370       this->GetRenderer()->AddActor(mVFActor);
371
372       //Synchronize slice
373       SetTSlice(mCurrentTSlice);
374     }
375 }
376
377 void vvSlicer::SetLandmarks(vvLandmarks* landmarks)
378 {
379   mLandmarks = landmarks;
380   if (landmarks)
381     {
382
383       if (!mCross)
384         mCross = vtkCursor3D::New();
385       mCross->SetFocalPoint(0.0,0.0,0.0);
386       mCross->SetModelBounds(-10,10,-10,10,-10,10);
387       mCross->AllOff();
388       mCross->AxesOn();
389
390       if (!mLandGlyph)
391         mLandGlyph = vtkGlyph3D::New();
392       mLandGlyph->SetSource(mCross->GetOutput());
393       mLandGlyph->SetInput(landmarks->GetOutput());
394       //mLandGlyph->SetIndexModeToScalar();
395       mLandGlyph->SetRange(0,1);
396       mLandGlyph->ScalingOff();
397
398       mLandGlyph->SetColorModeToColorByScalar();
399
400       if (!mClipBox)
401         mClipBox = vtkBox::New();
402       if (!mLandClipper)
403         mLandClipper = vtkClipPolyData::New();
404       mLandClipper->InsideOutOn();
405       mLandClipper->SetInput(mLandGlyph->GetOutput());
406       mLandClipper->SetClipFunction(mClipBox);
407
408       if (!mLandMapper)
409         mLandMapper = vtkPolyDataMapper::New();
410       mLandMapper->SetInputConnection(mLandClipper->GetOutputPort());
411       //mLandMapper->ScalarVisibilityOff();
412
413       if (!mLandActor)
414         mLandActor = vtkActor::New();
415       mLandActor->SetMapper(mLandMapper);
416       mLandActor->GetProperty()->SetColor(255,10,212);
417       mLandActor->SetPickable(0);
418       mLandActor->SetVisibility(true);
419       this->UpdateDisplayExtent();
420       this->GetRenderer()->AddActor(mLandActor);
421     }
422 }
423
424 //FIXME: this function leaks memory, we should fix it someday :)
425 void vvSlicer::RemoveActor(const std::string& actor_type, int overlay_index)
426 {
427   if (actor_type == "vector")
428     {
429       Renderer->RemoveActor(mVFActor);
430       mGlyphFilter=NULL;
431       mVF = NULL;
432       mArrow = NULL;
433       mAAFilter=NULL;
434       mVOIFilter = NULL;
435       mVFMapper = NULL;
436       mVFActor = NULL;
437     }
438   if (actor_type == "overlay")
439     {
440       Renderer->RemoveActor(mOverlayActor);
441       mOverlay = NULL;
442       mOverlayActor = NULL;
443       mOverlayMapper = NULL;
444     }
445   if (actor_type == "fusion")
446     {
447       Renderer->RemoveActor(mFusionActor);
448       mFusion = NULL;
449       mFusionActor = NULL;
450       mFusionMapper = NULL;
451     }
452   if (actor_type == "contour")
453     {
454       Renderer->RemoveActor(this->mSurfaceCutActors[overlay_index]->GetActor());
455       mSurfaceCutActors.erase(mSurfaceCutActors.begin()+overlay_index);
456     }
457 }
458
459 void vvSlicer::SetVFSubSampling(int sub)
460 {
461   if (mVOIFilter)
462     {
463       mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
464       mSubSampling = sub;
465     }
466   UpdateDisplayExtent();
467   Render();
468 }
469
470 void vvSlicer::SetVFScale(int scale)
471 {
472   mScale = scale;
473   if (mArrow)
474     mArrow->SetScale(mScale);
475   UpdateDisplayExtent();
476   Render();
477 }
478
479 void vvSlicer::SetVFLog(int log)
480 {
481   mVFLog = log;
482   if (mGlyphFilter)
483     {
484       mGlyphFilter->SetUseLog(mVFLog);
485       mGlyphFilter->Modified();
486     }
487   UpdateDisplayExtent();
488   Render();
489 }
490
491 void vvSlicer::SetTSlice(int t)
492 {
493   if (t < 0)
494     t = 0;
495   else if ((unsigned int)t >= mImage->GetVTKImages().size())
496     t = mImage->GetVTKImages().size() -1;
497   mCurrentTSlice = t;
498   this->SetInput(mImage->GetVTKImages()[t]);
499   if (mVF && mVFActor->GetVisibility())
500     {
501       if (mVF->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
502         mVOIFilter->SetInput(mVF->GetVTKImages()[mCurrentTSlice]);
503     }
504   if (mOverlay && mOverlayActor->GetVisibility())
505     {
506       if (mOverlay->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
507         mOverlayMapper->SetInput(mOverlay->GetVTKImages()[mCurrentTSlice]);
508     }
509   if (mFusion && mFusionActor->GetVisibility())
510     {
511       if (mFusion->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
512         mFusionMapper->SetInput(mFusion->GetVTKImages()[mCurrentTSlice]);
513     }
514   if (mSurfaceCutActors.size() > 0)
515     for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
516          i!=mSurfaceCutActors.end();i++)
517       (*i)->SetTimeSlice(mCurrentTSlice);
518   UpdateDisplayExtent();
519 }
520
521 int vvSlicer::GetTSlice()
522 {
523   return mCurrentTSlice;
524 }
525
526 void vvSlicer::SetSliceOrientation(int orientation)
527 {
528   //if 2D image, force to watch in Axial View
529   int extent[6];
530   this->GetInput()->GetWholeExtent(extent);
531   if (extent[5]-extent[4] <= 2)
532     orientation=2;
533
534   if (orientation < vtkImageViewer2::SLICE_ORIENTATION_YZ ||
535       orientation > vtkImageViewer2::SLICE_ORIENTATION_XY)
536     {
537       vtkErrorMacro("Error - invalid slice orientation " << orientation);
538       return;
539     }
540
541   this->SliceOrientation = orientation;
542     
543   // Update the viewer
544   int *range = this->GetSliceRange();
545   if (range)
546     this->Slice = static_cast<int>((range[0] + range[1]) * 0.5);
547
548   this->UpdateOrientation();
549   this->UpdateDisplayExtent();
550
551   if (this->Renderer && this->GetInput())
552     {
553       double scale = this->Renderer->GetActiveCamera()->GetParallelScale();
554       this->Renderer->ResetCamera();
555       this->Renderer->GetActiveCamera()->SetParallelScale(scale);
556     }
557
558   SetContourSlice();
559 }
560
561 //----------------------------------------------------------------------------
562 void vvSlicer::UpdateDisplayExtent()
563 {
564   vtkImageData *input = this->GetInput();
565   if (!input || !this->ImageActor)
566     {
567       return;
568     }
569   input->UpdateInformation();
570   int *w_ext;// = input->GetWholeExtent();
571
572   if (mUseReducedExtent) {
573     w_ext = mReducedExtent;
574   }
575   else w_ext = input->GetWholeExtent();
576
577   DD(w_ext[0]);
578   DD(w_ext[1]);
579   DD(w_ext[2]);
580
581   switch (this->SliceOrientation)
582     {
583     case vtkImageViewer2::SLICE_ORIENTATION_XY:
584       this->ImageActor->SetDisplayExtent(
585                                          w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice);
586       if (mVF && mVFActor->GetVisibility())
587         {
588           int vfExtent[6];
589           ComputeVFDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,vfExtent);
590           mVOIFilter->SetVOI(vfExtent);
591           mGlyphFilter->SetOrientation(1,1,0);
592           mVFMapper->Update();
593           // put the vector field between the image and the camera
594           if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
595             mVFActor->SetPosition(0,0,ImageActor->GetBounds()[5]+2);
596           else
597             mVFActor->SetPosition(0,0,ImageActor->GetBounds()[4]-2);
598         }
599       if (mOverlay && mOverlayActor->GetVisibility())
600         {
601           int overExtent[6];
602           ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,overExtent);
603           mOverlayActor->SetDisplayExtent(overExtent);
604           if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
605             mOverlayActor->SetPosition(0,0,1);
606           else
607             mOverlayActor->SetPosition(0,0,-1);
608         }
609       if (mFusion && mFusionActor->GetVisibility())
610         {
611           int fusExtent[6];
612           ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,fusExtent);
613           mFusionActor->SetDisplayExtent(fusExtent);
614           if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
615             mFusionActor->SetPosition(0,0,1.5);
616           else
617             mFusionActor->SetPosition(0,0,-1.5);
618         }
619       if (mLandActor)
620         {
621           if (mClipBox)
622             {
623               double bounds [6];
624               bounds[0] = ImageActor->GetBounds()[0];
625               bounds[1] = ImageActor->GetBounds()[1];
626               bounds[2] = ImageActor->GetBounds()[2];
627               bounds[3] = ImageActor->GetBounds()[3];
628               bounds[4] = ImageActor->GetBounds()[4]-(0.9/this->GetInput()->GetSpacing()[2]);
629               bounds[5] = ImageActor->GetBounds()[5]+(0.9/this->GetInput()->GetSpacing()[2]);
630               mClipBox->SetBounds(bounds);
631               UpdateLandmarks();
632             }
633           if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
634             mLandActor->SetPosition(0,0,1.5);
635           else
636             mLandActor->SetPosition(0,0,-1.5);
637         }
638       break;
639
640     case vtkImageViewer2::SLICE_ORIENTATION_XZ:
641       this->ImageActor->SetDisplayExtent(
642                                          w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5]);
643       if (mVF && mVFActor->GetVisibility())
644         {
645           int vfExtent[6];
646           ComputeVFDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],vfExtent);
647           mVOIFilter->SetVOI(vfExtent);
648           mGlyphFilter->SetOrientation(1,0,1);
649           mVFMapper->Update();
650           // put the vector field between the image aSpacingnd the camera
651           if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
652             mVFActor->SetPosition(0,ImageActor->GetBounds()[3]+2,0);
653           else
654             mVFActor->SetPosition(0,ImageActor->GetBounds()[2]-2,0);
655         }
656       if (mOverlay && mOverlayActor->GetVisibility())
657         {
658           int overExtent[6];
659           ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],overExtent);
660           mOverlayActor->SetDisplayExtent(overExtent);
661           if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
662             mOverlayActor->SetPosition(0,1,0);
663           else
664             mOverlayActor->SetPosition(0,-1,0);
665         }
666       if (mFusion && mFusionActor->GetVisibility())
667         {
668           int fusExtent[6];
669           ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],fusExtent);
670           mFusionActor->SetDisplayExtent(fusExtent);
671           if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
672             mFusionActor->SetPosition(0,1.5,0);
673           else
674             mFusionActor->SetPosition(0,-1.5,0);
675         }
676       if (mLandActor)
677         {
678           if (mClipBox)
679             {
680               double bounds [6];
681               bounds[0] = ImageActor->GetBounds()[0];
682               bounds[1] = ImageActor->GetBounds()[1];
683               bounds[2] = ImageActor->GetBounds()[2]-(0.5/this->GetInput()->GetSpacing()[1]);
684               bounds[3] = ImageActor->GetBounds()[3]+(0.5/this->GetInput()->GetSpacing()[1]);
685               bounds[4] = ImageActor->GetBounds()[4];
686               bounds[5] = ImageActor->GetBounds()[5];
687               mClipBox->SetBounds(bounds);
688               UpdateLandmarks();
689             }
690           if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
691             mLandActor->SetPosition(0,1.5,0);
692           else
693             mLandActor->SetPosition(0,-1.5,0);
694         }
695       break;
696
697     case vtkImageViewer2::SLICE_ORIENTATION_YZ:
698       this->ImageActor->SetDisplayExtent(
699                                          this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5]);
700       if (mVF && mVFActor->GetVisibility())
701         {
702           int vfExtent[6];
703           ComputeVFDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],vfExtent);
704           mVOIFilter->SetVOI(vfExtent);
705           mGlyphFilter->SetOrientation(0,1,1);
706           mVFMapper->Update();
707           // put the vector field between the image and the camera
708           if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
709             mVFActor->SetPosition(ImageActor->GetBounds()[1]+2,0,0);
710           else
711             mVFActor->SetPosition(ImageActor->GetBounds()[0]-2,0,0);
712         }
713       if (mOverlay && mOverlayActor->GetVisibility())
714         {
715           int overExtent[6];
716           ComputeOverlayDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],overExtent);
717           mOverlayActor->SetDisplayExtent(overExtent);
718           if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
719             mOverlayActor->SetPosition(1,0,0);
720           else
721             mOverlayActor->SetPosition(-1,0,0);
722         }
723       if (mFusion && mFusionActor->GetVisibility())
724         {
725           int fusExtent[6];
726           ComputeFusionDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],fusExtent);
727           mFusionActor->SetDisplayExtent(fusExtent);
728           if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
729             mFusionActor->SetPosition(1.5,0,0);
730           else
731             mFusionActor->SetPosition(-1.5,0,0);
732         }
733       if (mLandActor)
734         {
735           if (mClipBox)
736             {
737               double bounds [6];
738               bounds[0] = ImageActor->GetBounds()[0]-(0.5/this->GetInput()->GetSpacing()[0]);
739               bounds[1] = ImageActor->GetBounds()[1]+(0.5/this->GetInput()->GetSpacing()[0]);
740               bounds[2] = ImageActor->GetBounds()[2];
741               bounds[3] = ImageActor->GetBounds()[3];
742               bounds[4] = ImageActor->GetBounds()[4];
743               bounds[5] = ImageActor->GetBounds()[5];
744               mClipBox->SetBounds(bounds);
745               UpdateLandmarks();
746             }
747           if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
748             mLandActor->SetPosition(1.5,0,0);
749           else
750             mLandActor->SetPosition(-1.5,0,0);
751         }
752       break;
753     }
754
755   // Figure out the correct clipping range
756
757   if (this->Renderer)
758     {
759       if (this->InteractorStyle &&
760           this->InteractorStyle->GetAutoAdjustCameraClippingRange())
761         {
762           this->Renderer->ResetCameraClippingRange();
763         }
764       else
765         {
766           vtkCamera *cam = this->Renderer->GetActiveCamera();
767           if (cam)
768             {
769               double bounds[6];
770               this->ImageActor->GetBounds(bounds);
771               double spos = (double)bounds[this->SliceOrientation * 2];
772               double cpos = (double)cam->GetPosition()[this->SliceOrientation];
773               double range = fabs(spos - cpos);
774               double *spacing = input->GetSpacing();
775               double avg_spacing =
776                 ((double)spacing[0] + (double)spacing[1] + (double)spacing[2]) / 3.0;
777               cam->SetClippingRange(
778                                     range - avg_spacing * 3.0, range + avg_spacing * 3.0);
779             }
780         }
781     }
782 }
783
784 void vvSlicer::ComputeVFDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int vfExtent[6])
785 {
786   vtkImageData* image=this->GetInput();
787   vfExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mVF->GetOrigin()[0]) /
788     mVF->GetSpacing()[0];
789   vfExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mVF->GetOrigin()[0]) /
790     mVF->GetSpacing()[0];
791   vfExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mVF->GetOrigin()[1]) /
792     mVF->GetSpacing()[1];
793   vfExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mVF->GetOrigin()[1]) /
794     mVF->GetSpacing()[1];
795   vfExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mVF->GetOrigin()[2]) /
796     mVF->GetSpacing()[2];
797   vfExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mVF->GetOrigin()[2]) /
798     mVF->GetSpacing()[2];
799
800   ClipDisplayedExtent(vfExtent,mVOIFilter->GetInput()->GetWholeExtent());
801 }
802
803 void vvSlicer::ComputeOverlayDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int overExtent[6])
804 {
805   vtkImageData* image=this->GetInput();
806   overExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mOverlay->GetOrigin()[0]) /
807     mOverlay->GetSpacing()[0];
808   overExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mOverlay->GetOrigin()[0]) /
809     mOverlay->GetSpacing()[0];
810   overExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mOverlay->GetOrigin()[1]) /
811     mOverlay->GetSpacing()[1];
812   overExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mOverlay->GetOrigin()[1]) /
813     mOverlay->GetSpacing()[1];
814   overExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mOverlay->GetOrigin()[2]) /
815     mOverlay->GetSpacing()[2];
816   overExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mOverlay->GetOrigin()[2]) /
817     mOverlay->GetSpacing()[2];
818   ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
819 }
820
821 void vvSlicer::ComputeFusionDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int fusExtent[6])
822 {
823   vtkImageData* image=this->GetInput();
824   fusExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mFusion->GetOrigin()[0]) /
825     mFusion->GetSpacing()[0];
826   fusExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mFusion->GetOrigin()[0]) /
827     mFusion->GetSpacing()[0];
828   fusExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mFusion->GetOrigin()[1]) /
829     mFusion->GetSpacing()[1];
830   fusExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mFusion->GetOrigin()[1]) /
831     mFusion->GetSpacing()[1];
832   fusExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mFusion->GetOrigin()[2]) /
833     mFusion->GetSpacing()[2];
834   fusExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mFusion->GetOrigin()[2]) /
835     mFusion->GetSpacing()[2];
836   ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
837 }
838
839 void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
840 {
841   bool out = false;
842   int maxBound = 6;
843
844   //2D overlay on 3D image specific case
845   if (refExtent[4] == refExtent[5])
846     {
847       maxBound = 4;
848       extent[4] = refExtent[4];
849       extent[5] = refExtent[5];
850     }
851
852   for (int i = 0; i < maxBound; i = i+2)
853     {
854       //if we are totally outside the image
855       if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] )
856         {
857           out = true;
858           break;
859         }
860       //crop to the limit of the image
861       extent[i] = (extent[i] > refExtent[i]) ? extent[i] : refExtent[i];
862       extent[i] = (extent[i] < refExtent[i+1]) ? extent[i] : refExtent[i+1];
863       extent[i+1] = (extent[i+1] > refExtent[i]) ? extent[i+1] : refExtent[i];
864       extent[i+1] = (extent[i+1] < refExtent[i+1]) ? extent[i+1] : refExtent[i+1];
865     }
866   if (out)
867     for (int i = 0; i < maxBound; i = i+2)
868       {
869         extent[i] = refExtent[i];
870         extent[i+1] = refExtent[i];
871       }
872 }
873
874 void vvSlicer::UpdateOrientation()
875 {
876   // Set the camera position
877   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
878   if (cam)
879     {
880       switch (this->SliceOrientation)
881         {
882         case vtkImageViewer2::SLICE_ORIENTATION_XY:
883           cam->SetFocalPoint(0,0,0);
884           cam->SetPosition(0,0,-1); // -1 if medical ?
885           cam->SetViewUp(0,-1,0);
886           break;
887
888         case vtkImageViewer2::SLICE_ORIENTATION_XZ:
889           cam->SetFocalPoint(0,0,0);
890           cam->SetPosition(0,-1,0); // 1 if medical ?
891           cam->SetViewUp(0,0,1);
892           break;
893
894         case vtkImageViewer2::SLICE_ORIENTATION_YZ:
895           cam->SetFocalPoint(0,0,0);
896           cam->SetPosition(-1,0,0); // -1 if medical ?
897           cam->SetViewUp(0,0,1);
898           break;
899         }
900     }
901 }
902
903 void vvSlicer::SetOpacity(double s)
904 {
905   this->GetImageActor()->SetOpacity(s);
906 }
907
908 void vvSlicer::SetRenderWindow(int orientation, vtkRenderWindow * rw)
909 {
910   this->Superclass::SetRenderWindow(rw);
911   this->SetupInteractor(rw->GetInteractor());
912   ca->SetImageActor(this->GetImageActor());
913   ca->SetWindowLevel(this->GetWindowLevel());
914   ca->SetText(2, "<slice>");
915   ca->SetText(3, "<window>\n<level>");
916
917   double bounds[6];
918   double max = 65000;
919
920   bounds[0] = -max;
921   bounds[1] = max;
922   bounds[2] = -max;
923   bounds[3] = max;
924   bounds[4] = -max;
925   bounds[5] = max;
926
927   crossCursor->SetModelBounds(bounds);
928   this->GetRenderer()->AddActor(pdmA);
929   this->GetRenderer()->AddActor(ca);
930   this->GetRenderer()->ResetCamera();
931
932   //this is just a mapping between the labeling of the orientations presented to the user and
933   //the one used by vtk
934   SetSliceOrientation(2-(orientation%3));
935   ResetCamera();
936 }
937
938 void vvSlicer::ResetCamera()
939 {
940   if (this->GetInput())
941     {
942       double* input_bounds=this->GetInput()->GetBounds();
943       double bmax=input_bounds[1]-input_bounds[0];
944       if (bmax < input_bounds[3]-input_bounds[2]) bmax=input_bounds[3]-input_bounds[2];
945       if (bmax < input_bounds[5]-input_bounds[4]) bmax=input_bounds[5]-input_bounds[4];
946       this->GetRenderer()->ResetCamera();
947       this->GetRenderer()->GetActiveCamera()->SetParallelScale(bmax/2);
948     }
949 }
950
951 void vvSlicer::SetDisplayMode(bool i)
952 {
953   this->GetImageActor()->SetVisibility(i);
954   this->GetAnnotation()->SetVisibility(i);
955   this->GetRenderer()->SetDraw(i);
956   if (mLandActor)
957     mLandActor->SetVisibility(i);
958   pdmA->SetVisibility(i);
959   if (i)
960     UpdateDisplayExtent();
961 }
962 //----------------------------------------------------------------------------
963
964
965 //----------------------------------------------------------------------------
966 void vvSlicer::FlipHorizontalView()
967 {
968   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
969   if (cam)
970     {
971       double *position = cam->GetPosition();
972       switch (this->SliceOrientation)
973         {
974         case vtkImageViewer2::SLICE_ORIENTATION_XY:
975           cam->SetPosition(position[0],position[1],-position[2]);
976           break;
977
978         case vtkImageViewer2::SLICE_ORIENTATION_XZ:
979           cam->SetPosition(position[0],-position[1],position[2]);
980           break;
981
982         case vtkImageViewer2::SLICE_ORIENTATION_YZ:
983           cam->SetPosition(-position[0],position[1],position[2]);
984           break;
985         }
986       this->Renderer->ResetCameraClippingRange();
987       this->UpdateDisplayExtent();
988     }
989 }
990 //----------------------------------------------------------------------------
991
992
993 //----------------------------------------------------------------------------
994 void vvSlicer::FlipVerticalView()
995 {
996   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
997   if (cam)
998     {
999       FlipHorizontalView();
1000       double *viewup = cam->GetViewUp();
1001       cam->SetViewUp(-viewup[0],-viewup[1],-viewup[2]);
1002       this->UpdateDisplayExtent();
1003     }
1004 }
1005 //----------------------------------------------------------------------------
1006
1007
1008 //----------------------------------------------------------------------------
1009 void vvSlicer::SetColorWindow(double window)
1010 {
1011   vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1012   if ( LUT )
1013     {
1014       double level = this->GetWindowLevel()->GetLevel();
1015       LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
1016       LUT->Build();
1017     }
1018   this->vtkImageViewer2::SetColorWindow(window);
1019 }
1020 //----------------------------------------------------------------------------
1021
1022
1023 //----------------------------------------------------------------------------
1024 void vvSlicer::SetColorLevel(double level)
1025 {
1026   vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1027   if ( LUT )
1028     {
1029       double window = this->GetWindowLevel()->GetWindow();
1030       LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
1031       LUT->Build();
1032     }
1033   this->vtkImageViewer2::SetColorLevel(level);
1034 }
1035 //----------------------------------------------------------------------------
1036
1037
1038 //----------------------------------------------------------------------------
1039 void vvSlicer::Render()
1040 {
1041   if (this->GetWindowLevel()->GetLookupTable() && !this->mOverlay && !this->mFusion)
1042     {
1043       legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable());
1044       legend->SetVisibility(1);
1045     }
1046   else legend->SetVisibility(0);
1047
1048   if (ca->GetVisibility())
1049     {
1050       std::string worldPos = "";
1051       std::stringstream world1;
1052       std::stringstream world2;
1053       std::stringstream world3;
1054       world1 << (int)mCurrent[0];
1055       world2 << (int)mCurrent[1];
1056       world3 << (int)mCurrent[2];
1057       double X = (mCurrent[0] - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1058       double Y = (mCurrent[1] - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1059       double Z = (mCurrent[2] - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1060
1061       if (pdmA->GetVisibility())
1062         {
1063           double x = mCursor[0];
1064           double y = mCursor[1];
1065           double z = mCursor[2];
1066           double xCursor = (x - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1067           double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1068           double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1069
1070           if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0] &&
1071               xCursor < this->GetImageActor()->GetDisplayExtent()[1]+1 &&
1072               yCursor >= this->GetImageActor()->GetDisplayExtent()[2] &&
1073               yCursor < this->GetImageActor()->GetDisplayExtent()[3]+1 &&
1074               zCursor >= this->GetImageActor()->GetDisplayExtent()[4] &&
1075               zCursor < this->GetImageActor()->GetDisplayExtent()[5]+1 )
1076             {
1077               vtkRenderer * renderer = this->Renderer;
1078
1079               renderer->WorldToView(x,y,z);
1080               renderer->ViewToNormalizedViewport(x,y,z);
1081               renderer->NormalizedViewportToViewport(x,y);
1082               renderer->ViewportToNormalizedDisplay(x,y);
1083               renderer->NormalizedDisplayToDisplay(x,y);
1084               crossCursor->SetFocalPoint(x,y,z);
1085             }
1086           else
1087             crossCursor->SetFocalPoint(-1,-1,z);
1088         }
1089
1090       if (X >= this->GetInput()->GetWholeExtent()[0] &&
1091           X <= this->GetInput()->GetWholeExtent()[1] &&
1092           Y >= this->GetInput()->GetWholeExtent()[2] &&
1093           Y <= this->GetInput()->GetWholeExtent()[3] &&
1094           Z >= this->GetInput()->GetWholeExtent()[4] &&
1095           Z <= this->GetInput()->GetWholeExtent()[5])
1096         {
1097           std::stringstream pixel1;
1098           std::stringstream pixel2;
1099           std::stringstream pixel3;
1100           std::stringstream temps;
1101           pixel1 << (int)X;
1102           pixel2 << (int)Y;
1103           pixel3 << (int)Z;
1104           temps << mCurrentTSlice;
1105           double value = this->GetInput()->GetScalarComponentAsDouble(
1106                                                                       (int)X,
1107                                                                       (int)Y,
1108                                                                       (int)Z,0);
1109
1110           std::stringstream val;
1111           val << value;
1112           worldPos += "data value : " + val.str();
1113           worldPos += "\n mm : " + world1.str() + " " + world2.str() + " " + world3.str() + " " + temps.str();
1114           worldPos += "\n pixel : " + pixel1.str() + " " + pixel2.str() + " " + pixel3.str() + " " + temps.str();
1115         }
1116       ca->SetText(1,worldPos.c_str());
1117     }
1118   if (mOverlay && mOverlayActor->GetVisibility())
1119     {
1120       mOverlayMapper->SetWindow(this->GetColorWindow());
1121       mOverlayMapper->SetLevel(this->GetColorLevel());
1122       mOverlayMapper->Update();
1123     }
1124   if (mLandMapper)
1125     UpdateLandmarks();
1126   //this->Superclass::Render();
1127   this->GetRenderWindow()->Render();
1128 }
1129 //----------------------------------------------------------------------------
1130
1131
1132 //----------------------------------------------------------------------------
1133 void vvSlicer::UpdateCursorPosition()
1134 {
1135   if (this->GetImageActor()->GetVisibility())
1136     {
1137       pdmA->SetVisibility(true);
1138       mCursor[0] = mCurrent[0];
1139       mCursor[1] = mCurrent[1];
1140       mCursor[2] = mCurrent[2];
1141       mCursor[3] = mCurrentTSlice;
1142     }
1143 }
1144 //----------------------------------------------------------------------------
1145
1146 //----------------------------------------------------------------------------
1147 void vvSlicer::UpdateLandmarks()
1148 {
1149   vtkPolyData *pd = static_cast<vtkPolyData*>(mLandClipper->GetInput());
1150   if (pd->GetPoints())
1151     {
1152       mLandGlyph->SetRange(0,1);
1153       mLandGlyph->Modified();
1154       mLandGlyph->Update();
1155
1156       mClipBox->Modified();
1157       mLandClipper->Update();
1158       mLandMapper->Update();
1159     }
1160
1161 }
1162 //----------------------------------------------------------------------------
1163
1164
1165 //----------------------------------------------------------------------------
1166 void vvSlicer::SetSlice(int slice)
1167 {
1168   DD("vvSlicer::SetSlice");
1169   DD(slice);
1170   int *range = this->GetSliceRange();
1171   DD(range[0]);
1172   DD(range[1]);
1173   if (range)
1174     {
1175       if (slice < range[0])
1176         {
1177           slice = range[0];
1178         }
1179       else if (slice > range[1])
1180         {
1181           slice = range[1];
1182         }
1183     }
1184
1185   if (this->Slice == slice)
1186     {
1187       return;
1188     }
1189
1190   this->Slice = slice;
1191   SetContourSlice();
1192   this->Modified();
1193   this->UpdateDisplayExtent();
1194   this->Render();
1195 }
1196 //----------------------------------------------------------------------------
1197
1198
1199 //----------------------------------------------------------------------------
1200 void vvSlicer::SetContourSlice()
1201 {
1202   if (mSurfaceCutActors.size() > 0)
1203     for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
1204          i!=mSurfaceCutActors.end();i++)
1205       (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+
1206                         this->GetImage()->GetOrigin()[this->SliceOrientation]);
1207 }
1208 //----------------------------------------------------------------------------
1209
1210
1211 //----------------------------------------------------------------------------
1212 void vvSlicer::ForceUpdateDisplayExtent()
1213 {
1214   this->UpdateDisplayExtent();
1215 }
1216 //----------------------------------------------------------------------------
1217
1218
1219 //----------------------------------------------------------------------------
1220 int* vvSlicer::GetDisplayExtent()
1221 {
1222   return this->GetImageActor()->GetDisplayExtent();
1223 }
1224 //----------------------------------------------------------------------------
1225
1226
1227 //----------------------------------------------------------------------------
1228 void vvSlicer::PrintSelf(ostream& os, vtkIndent indent)
1229 {
1230   this->Superclass::PrintSelf(os, indent);
1231 }
1232 //----------------------------------------------------------------------------