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