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