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