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