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