]> Creatis software - clitk.git/blob - vv/vvSlicer.cxx
Use smart pointers for vvSlicers
[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 void vvSlicer::SetCornerAnnotationVisibility(bool s)
272 {
273   ca->SetVisibility(s);
274 }
275 //------------------------------------------------------------------------------
276
277
278 //------------------------------------------------------------------------------
279 bool vvSlicer::GetCornerAnnotationVisibility()
280 {
281   return ca->GetVisibility();
282 }
283 //------------------------------------------------------------------------------
284
285
286 //------------------------------------------------------------------------------
287 vvSlicer::~vvSlicer()
288 {
289   for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
290        i!=mSurfaceCutActors.end(); i++)
291     delete (*i);
292 }
293 //------------------------------------------------------------------------------
294
295
296 //------------------------------------------------------------------------------
297 void vvSlicer::SetCurrentPosition(double x, double y, double z, int t)
298 {
299   mCurrent[0] = x;
300   mCurrent[1] = y;
301   mCurrent[2] = z;
302   mCurrentTSlice = t;
303 }
304 //------------------------------------------------------------------------------
305
306
307 //------------------------------------------------------------------------------
308 void vvSlicer::SetImage(vvImage::Pointer image)
309 {
310   if (image->GetVTKImages().size()) {
311     mImage = image;
312     this->Superclass::SetInput(image->GetTransformedVTKImages()[0]);
313
314     int extent[6];
315     this->GetInput()->GetWholeExtent(extent);
316
317     // Prevent crash when reload -> change slice if outside extent
318     if (Slice < extent[SliceOrientation*2] || Slice>=extent[SliceOrientation*2+1]) {
319       Slice = (extent[SliceOrientation*2+1]-extent[SliceOrientation*2])/2.0;
320     }
321
322     // Make sure that the required part image has been computed
323     extent[SliceOrientation*2] = Slice;
324     extent[SliceOrientation*2+1] = Slice;
325     image->GetTransformedVTKImages()[0]->SetUpdateExtent(extent);
326     image->GetTransformedVTKImages()[0]->Update();
327
328     this->UpdateDisplayExtent();
329
330     mCurrentTSlice = 0;
331     ca->SetText(0,mFileName.c_str());
332   }
333 }
334 //------------------------------------------------------------------------------
335
336
337 //------------------------------------------------------------------------------
338 void vvSlicer::SetOverlay(vvImage::Pointer overlay)
339 {
340   if (overlay->GetVTKImages().size()) {
341     mOverlay = overlay;
342
343     if (!mOverlayMapper)
344       mOverlayMapper = vtkSmartPointer<vtkImageMapToWindowLevelColors>::New();
345     mOverlayMapper->SetInput(overlay->GetTransformedVTKImages()[0]);
346
347     if (!mOverlayActor) {
348       mOverlayActor = vtkSmartPointer<vvBlendImageActor>::New();
349       mOverlayActor->SetInput(mOverlayMapper->GetOutput());
350       mOverlayActor->SetPickable(0);
351       mOverlayActor->SetVisibility(false);
352       mOverlayActor->SetOpacity(0.5);
353       this->UpdateDisplayExtent();
354     }
355
356     //stupid but necessary : the Overlay need to be rendered before fusion
357     if (mFusionActor) {
358       this->GetRenderer()->RemoveActor(mFusionActor);
359       this->GetRenderer()->AddActor(mOverlayActor);
360       this->GetRenderer()->AddActor(mFusionActor);
361     } else
362       this->GetRenderer()->AddActor(mOverlayActor);
363
364     //Synchronize slice
365     SetTSlice(mCurrentTSlice);
366   }
367 }
368 //------------------------------------------------------------------------------
369
370
371 //------------------------------------------------------------------------------
372 void vvSlicer::SetFusion(vvImage::Pointer fusion)
373 {
374   if (fusion->GetVTKImages().size()) {
375     mFusion = fusion;
376
377     if (!mFusionMapper)
378       mFusionMapper = vtkSmartPointer<vtkImageMapToWindowLevelColors>::New();
379     mFusionMapper->SetInput(fusion->GetTransformedVTKImages()[0]);
380
381     if (!mFusionActor) {
382       mFusionActor = vtkSmartPointer<vtkImageActor>::New();
383       mFusionActor->SetInput(mFusionMapper->GetOutput());
384       mFusionActor->SetPickable(0);
385       mFusionActor->SetVisibility(false);
386       mFusionActor->SetOpacity(0.7);
387       this->UpdateDisplayExtent();
388       this->GetRenderer()->AddActor(mFusionActor);
389     }
390
391     //Synchronize slice
392     SetTSlice(mCurrentTSlice);
393   }
394 }
395 //------------------------------------------------------------------------------
396
397
398 //------------------------------------------------------------------------------
399 void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis)
400 {
401   if (actor_type == "vector") {
402     this->mVFActor->SetVisibility(vis);
403   }
404   if (actor_type == "overlay") {
405     this->mOverlayActor->SetVisibility(vis);
406   }
407   if (actor_type == "fusion") {
408     this->mFusionActor->SetVisibility(vis);
409   }
410   if (actor_type == "contour")
411     this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis);
412   UpdateDisplayExtent();
413 }
414 //------------------------------------------------------------------------------
415
416
417 //------------------------------------------------------------------------------
418 void vvSlicer::SetVF(vvImage::Pointer vf)
419 {
420   if (vf->GetVTKImages().size()) {
421     mVF = vf;
422
423     if (!mAAFilter) {
424       mAAFilter= vtkSmartPointer<vtkAssignAttribute>::New();
425       mVOIFilter = vtkSmartPointer<vtkExtractVOI>::New();
426       mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
427     }
428     mVOIFilter->SetInput(vf->GetTransformedVTKImages()[0]);
429     mAAFilter->SetInput(mVOIFilter->GetOutput());
430     ///This tells VTK to use the scalar (pixel) data of the image to draw the little arrows
431     mAAFilter->Assign(vtkDataSetAttributes::SCALARS, vtkDataSetAttributes::VECTORS, vtkAssignAttribute::POINT_DATA);
432
433     if (!mArrow)
434       mArrow = vtkSmartPointer<vvGlyphSource>::New();
435     mArrow->SetGlyphTypeToSpecificArrow();
436     mArrow->SetScale(mScale);
437     mArrow->FilledOff();
438
439     // Glyph the gradient vector (with arrows)
440     if (!mGlyphFilter)
441       mGlyphFilter = vtkSmartPointer<vvGlyph2D>::New();
442     mGlyphFilter->SetInput(mAAFilter->GetOutput());
443     mGlyphFilter->SetSource(mArrow->GetOutput());
444     mGlyphFilter->ScalingOn();
445     mGlyphFilter->SetScaleModeToScaleByVector();
446     mGlyphFilter->OrientOn();
447     mGlyphFilter->SetVectorModeToUseVector();
448     mGlyphFilter->SetColorModeToColorByVector();
449
450     if (!mVFColorLUT)
451       mVFColorLUT = vtkSmartPointer<vtkLookupTable>::New();
452
453     double mVFColorHSV[3];
454     vtkMath::RGBToHSV(mVFColor, mVFColorHSV);
455     mVFColorLUT->SetHueRange(mVFColorHSV[0], mVFColorHSV[0]);
456     mVFColorLUT->SetSaturationRange(mVFColorHSV[1],mVFColorHSV[1]);
457     mVFColorLUT->SetValueRange(mVFColorHSV[2], mVFColorHSV[2]);
458
459     if (!mVFMapper)
460       mVFMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
461     mVFMapper->SetInput(mGlyphFilter->GetOutput());
462     mVFMapper->ImmediateModeRenderingOn();
463     mVFMapper->SetLookupTable(mVFColorLUT);
464
465     if (!mVFActor)
466       mVFActor = vtkSmartPointer<vtkActor>::New();
467     mVFActor->SetMapper(mVFMapper);
468     mVFActor->SetPickable(0);
469     mVFActor->GetProperty()->SetLineWidth(mVFWidth);
470     this->UpdateDisplayExtent();
471     this->GetRenderer()->AddActor(mVFActor);
472
473     //Synchronize slice
474     SetTSlice(mCurrentTSlice);
475   }
476 }
477 //------------------------------------------------------------------------------
478
479
480 //------------------------------------------------------------------------------
481 void vvSlicer::SetLandmarks(vvLandmarks* landmarks)
482 {
483   mLandmarks = landmarks;
484   if (landmarks) {
485
486     if (!mCross)
487       mCross = vtkSmartPointer<vtkCursor3D>::New();
488     mCross->SetFocalPoint(0.0,0.0,0.0);
489     mCross->SetModelBounds(-10,10,-10,10,-10,10);
490     mCross->AllOff();
491     mCross->AxesOn();
492
493     if (!mLandGlyph)
494       mLandGlyph = vtkSmartPointer<vtkGlyph3D>::New();
495     mLandGlyph->SetSource(mCross->GetOutput());
496     mLandGlyph->SetInput(landmarks->GetOutput());
497     //mLandGlyph->SetIndexModeToScalar();
498     mLandGlyph->SetRange(0,1);
499     mLandGlyph->ScalingOff();
500
501     mLandGlyph->SetColorModeToColorByScalar();
502
503     if (!mClipBox)
504       mClipBox = vtkSmartPointer<vtkBox>::New();
505     if (!mLandClipper)
506       mLandClipper = vtkSmartPointer<vtkClipPolyData>::New();
507     mLandClipper->InsideOutOn();
508     mLandClipper->SetInput(mLandGlyph->GetOutput());
509     mLandClipper->SetClipFunction(mClipBox);
510
511     if (!mLandMapper)
512       mLandMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
513     mLandMapper->SetInputConnection(mLandClipper->GetOutputPort());
514     //mLandMapper->ScalarVisibilityOff();
515
516     if (!mLandActor)
517       mLandActor = vtkSmartPointer<vtkActor>::New();
518     mLandActor->SetMapper(mLandMapper);
519     mLandActor->GetProperty()->SetColor(255,10,212);
520     mLandActor->SetPickable(0);
521     mLandActor->SetVisibility(true);
522     this->UpdateDisplayExtent();
523     this->GetRenderer()->AddActor(mLandActor);
524   }
525 }
526 //------------------------------------------------------------------------------
527
528 //------------------------------------------------------------------------------
529 //FIXME: this function leaks memory, we should fix it someday :)
530 void vvSlicer::RemoveActor(const std::string& actor_type, int overlay_index)
531 {
532   if (actor_type == "vector") {
533     Renderer->RemoveActor(mVFActor);
534     mGlyphFilter=NULL;
535     mVF = NULL;
536     mArrow = NULL;
537     mAAFilter=NULL;
538     mVOIFilter = NULL;
539     mVFMapper = NULL;
540     mVFActor = NULL;
541   }
542   if (actor_type == "overlay") {
543     Renderer->RemoveActor(mOverlayActor);
544     mOverlay = NULL;
545     mOverlayActor = NULL;
546     mOverlayMapper = NULL;
547   }
548   if (actor_type == "fusion") {
549     Renderer->RemoveActor(mFusionActor);
550     mFusion = NULL;
551     mFusionActor = NULL;
552     mFusionMapper = NULL;
553   }
554   if (actor_type == "contour") {
555     Renderer->RemoveActor(this->mSurfaceCutActors[overlay_index]->GetActor());
556     mSurfaceCutActors.erase(mSurfaceCutActors.begin()+overlay_index);
557   }
558 }
559 //------------------------------------------------------------------------------
560
561
562 //------------------------------------------------------------------------------
563 void vvSlicer::SetVFSubSampling(int sub)
564 {
565   if (mVOIFilter) {
566     mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
567     mSubSampling = sub;
568   }
569   UpdateDisplayExtent();
570   Render();
571 }
572 //------------------------------------------------------------------------------
573
574
575 //------------------------------------------------------------------------------
576 void vvSlicer::SetVFScale(int scale)
577 {
578   mScale = scale;
579   if (mArrow)
580     mArrow->SetScale(mScale);
581   UpdateDisplayExtent();
582   Render();
583 }
584 //------------------------------------------------------------------------------
585
586 //------------------------------------------------------------------------------
587 void vvSlicer::SetVFWidth(int width)
588 {
589   mVFWidth = width;
590   if (mVFActor)
591     mVFActor->GetProperty()->SetLineWidth(mVFWidth);
592   UpdateDisplayExtent();
593   Render();
594 }
595 //------------------------------------------------------------------------------
596
597
598 //------------------------------------------------------------------------------
599 void vvSlicer::SetVFLog(int log)
600 {
601   mVFLog = log;
602   if (mGlyphFilter) {
603     mGlyphFilter->SetUseLog(mVFLog);
604     mGlyphFilter->Modified();
605   }
606   UpdateDisplayExtent();
607   Render();
608 }
609 //------------------------------------------------------------------------------
610
611
612 //------------------------------------------------------------------------------
613 void vvSlicer::SetTSlice(int t)
614 {
615   if (t < 0)
616     t = 0;
617   else if ((unsigned int)t >= mImage->GetVTKImages().size())
618     t = mImage->GetVTKImages().size() -1;
619
620   if (mCurrentTSlice == t) return;
621
622   mCurrentTSlice = t;
623   this->SetInput(mImage->GetTransformedVTKImages()[t]);
624   if (mVF && mVFActor->GetVisibility()) {
625     if (mVF->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
626       mVOIFilter->SetInput(mVF->GetTransformedVTKImages()[mCurrentTSlice]);
627   }
628   if (mOverlay && mOverlayActor->GetVisibility()) {
629     if (mOverlay->GetTransformedVTKImages().size() > (unsigned int)mCurrentTSlice)
630       mOverlayMapper->SetInput(mOverlay->GetTransformedVTKImages()[mCurrentTSlice]);
631   }
632   if (mFusion && mFusionActor->GetVisibility()) {
633     if (mFusion->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
634       mFusionMapper->SetInput(mFusion->GetTransformedVTKImages()[mCurrentTSlice]);
635   }
636   if (mSurfaceCutActors.size() > 0)
637     for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
638          i!=mSurfaceCutActors.end(); i++)
639       (*i)->SetTimeSlice(mCurrentTSlice);
640   UpdateDisplayExtent();
641 }
642 //------------------------------------------------------------------------------
643
644
645 //------------------------------------------------------------------------------
646 int vvSlicer::GetTSlice()
647 {
648   return mCurrentTSlice;
649 }
650 //------------------------------------------------------------------------------
651
652
653 //------------------------------------------------------------------------------
654 void vvSlicer::SetSliceOrientation(int orientation)
655 {
656   //if 2D image, force to watch in Axial View
657   int extent[6];
658   this->GetInput()->GetWholeExtent(extent);
659   if (extent[5]-extent[4] <= 2)
660     orientation=2;
661
662   if (orientation < vtkImageViewer2::SLICE_ORIENTATION_YZ ||
663       orientation > vtkImageViewer2::SLICE_ORIENTATION_XY) {
664     vtkErrorMacro("Error - invalid slice orientation " << orientation);
665     return;
666   }
667
668   this->SliceOrientation = orientation;
669
670   // Update the viewer
671   int *range = this->GetSliceRange();
672   if (range)
673     this->Slice = static_cast<int>((range[0] + range[1]) * 0.5);
674
675   // Go to current cursor position
676   // double* cursorPos = GetCursorPosition();
677   // DDV(cursorPos, 3);
678   // SetCurrentPosition(cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]);
679
680   this->UpdateOrientation();
681   this->UpdateDisplayExtent();
682
683   if (this->Renderer && this->GetInput()) {
684     double scale = this->Renderer->GetActiveCamera()->GetParallelScale();
685     this->Renderer->ResetCamera();
686     this->Renderer->GetActiveCamera()->SetParallelScale(scale);
687   }
688
689   SetContourSlice();
690 }
691 //----------------------------------------------------------------------------
692
693
694 //----------------------------------------------------------------------------
695 int * vvSlicer::GetExtent()
696 {
697   int *w_ext;
698   if (mUseReducedExtent) {
699     w_ext = mReducedExtent;
700   } else w_ext = GetInput()->GetWholeExtent();
701   return w_ext;
702 }
703 //----------------------------------------------------------------------------
704
705
706 //----------------------------------------------------------------------------
707 int vvSlicer::GetOrientation()
708 {
709   return this->SliceOrientation;
710 }
711 //----------------------------------------------------------------------------
712
713
714 //----------------------------------------------------------------------------
715 void vvSlicer::UpdateDisplayExtent()
716 {
717   vtkImageData *input = this->GetInput();
718   if (!input || !this->ImageActor) {
719     return;
720   }
721   input->UpdateInformation();
722   int *w_ext;// = input->GetWholeExtent();
723
724   if (mUseReducedExtent) {
725     w_ext = mReducedExtent;
726   } else w_ext = input->GetWholeExtent();
727
728   switch (this->SliceOrientation) {
729   case vtkImageViewer2::SLICE_ORIENTATION_XY:
730     this->ImageActor->SetDisplayExtent(
731                                        w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice);
732     if (mVF && mVFActor->GetVisibility()) {
733       int vfExtent[6];
734       ComputeVFDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,vfExtent);
735       mVOIFilter->SetVOI(vfExtent);
736       mGlyphFilter->SetOrientation(1,1,0);
737       mVFMapper->Update();
738       // put the vector field between the image and the camera
739       if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
740         mVFActor->SetPosition(0,0,ImageActor->GetBounds()[5]+2);
741       else
742         mVFActor->SetPosition(0,0,ImageActor->GetBounds()[4]-2);
743     }
744     if (mOverlay && mOverlayActor->GetVisibility()) {
745       int overExtent[6];
746       ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,overExtent);
747       mOverlayActor->SetDisplayExtent(overExtent);
748       if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
749         mOverlayActor->SetPosition(0,0,1);
750       else
751         mOverlayActor->SetPosition(0,0,-1);
752     }
753     if (mFusion && mFusionActor->GetVisibility()) {
754       int fusExtent[6];
755       ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,fusExtent);
756       mFusionActor->SetDisplayExtent(fusExtent);
757       if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
758         mFusionActor->SetPosition(0,0,1.5);
759       else
760         mFusionActor->SetPosition(0,0,-1.5);
761     }
762     if (mLandActor) {
763       if (mClipBox) {
764         double bounds [6];
765         bounds[0] = ImageActor->GetBounds()[0];
766         bounds[1] = ImageActor->GetBounds()[1];
767         bounds[2] = ImageActor->GetBounds()[2];
768         bounds[3] = ImageActor->GetBounds()[3];
769         bounds[4] = ImageActor->GetBounds()[4]-fabs(0.5/this->GetInput()->GetSpacing()[2]);
770         bounds[5] = ImageActor->GetBounds()[5]+fabs(0.5/this->GetInput()->GetSpacing()[2]);
771         mClipBox->SetBounds(bounds);
772         UpdateLandmarks();
773       }
774       mLandActor->SetPosition(0,0,-1.5);
775       /*
776       if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
777         mLandActor->SetPosition(0,0,1.5);
778       else
779         mLandActor->SetPosition(0,0,-1.5);
780       */
781     }
782     break;
783
784   case vtkImageViewer2::SLICE_ORIENTATION_XZ:
785     this->ImageActor->SetDisplayExtent(
786                                        w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5]);
787     if (mVF && mVFActor->GetVisibility()) {
788       int vfExtent[6];
789       ComputeVFDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],vfExtent);
790       mVOIFilter->SetVOI(vfExtent);
791       mGlyphFilter->SetOrientation(1,0,1);
792       mVFMapper->Update();
793       // put the vector field between the image aSpacingnd the camera
794       if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
795         mVFActor->SetPosition(0,ImageActor->GetBounds()[3]+2,0);
796       else
797         mVFActor->SetPosition(0,ImageActor->GetBounds()[2]-2,0);
798     }
799     if (mOverlay && mOverlayActor->GetVisibility()) {
800       int overExtent[6];
801       ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],overExtent);
802       mOverlayActor->SetDisplayExtent(overExtent);
803       if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
804         mOverlayActor->SetPosition(0,1,0);
805       else
806         mOverlayActor->SetPosition(0,-1,0);
807     }
808     if (mFusion && mFusionActor->GetVisibility()) {
809       int fusExtent[6];
810       ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],fusExtent);
811       mFusionActor->SetDisplayExtent(fusExtent);
812       if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
813         mFusionActor->SetPosition(0,1.5,0);
814       else
815         mFusionActor->SetPosition(0,-1.5,0);
816     }
817     if (mLandActor) {
818       if (mClipBox) {
819         double bounds [6];
820         bounds[0] = ImageActor->GetBounds()[0];
821         bounds[1] = ImageActor->GetBounds()[1];
822         bounds[2] = ImageActor->GetBounds()[2]-fabs(0.5/this->GetInput()->GetSpacing()[1]);
823         bounds[3] = ImageActor->GetBounds()[3]+fabs(0.5/this->GetInput()->GetSpacing()[1]);
824         bounds[4] = ImageActor->GetBounds()[4];
825         bounds[5] = ImageActor->GetBounds()[5];
826         mClipBox->SetBounds(bounds);
827         UpdateLandmarks();
828       }
829       if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
830         mLandActor->SetPosition(0,1.5,0);
831       else
832         mLandActor->SetPosition(0,-1.5,0);
833     }
834     break;
835
836   case vtkImageViewer2::SLICE_ORIENTATION_YZ:
837     this->ImageActor->SetDisplayExtent(
838                                        this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5]);
839     if (mVF && mVFActor->GetVisibility()) {
840       int vfExtent[6];
841       ComputeVFDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],vfExtent);
842       mVOIFilter->SetVOI(vfExtent);
843       mGlyphFilter->SetOrientation(0,1,1);
844       mVFMapper->Update();
845       // put the vector field between the image and the camera
846       if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
847         mVFActor->SetPosition(ImageActor->GetBounds()[1]+2,0,0);
848       else
849         mVFActor->SetPosition(ImageActor->GetBounds()[0]-2,0,0);
850     }
851     if (mOverlay && mOverlayActor->GetVisibility()) {
852       int overExtent[6];
853       ComputeOverlayDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],overExtent);
854       mOverlayActor->SetDisplayExtent(overExtent);
855       if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
856         mOverlayActor->SetPosition(1,0,0);
857       else
858         mOverlayActor->SetPosition(-1,0,0);
859     }
860     if (mFusion && mFusionActor->GetVisibility()) {
861       int fusExtent[6];
862       ComputeFusionDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],fusExtent);
863       mFusionActor->SetDisplayExtent(fusExtent);
864       if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
865         mFusionActor->SetPosition(1.5,0,0);
866       else
867         mFusionActor->SetPosition(-1.5,0,0);
868     }
869     if (mLandActor) {
870       if (mClipBox) {
871         double bounds [6];
872         bounds[0] = ImageActor->GetBounds()[0]-fabs(0.5/this->GetInput()->GetSpacing()[0]);
873         bounds[1] = ImageActor->GetBounds()[1]+fabs(0.5/this->GetInput()->GetSpacing()[0]);
874         bounds[2] = ImageActor->GetBounds()[2];
875         bounds[3] = ImageActor->GetBounds()[3];
876         bounds[4] = ImageActor->GetBounds()[4];
877         bounds[5] = ImageActor->GetBounds()[5];
878         mClipBox->SetBounds(bounds);
879         UpdateLandmarks();
880       }
881       if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
882         mLandActor->SetPosition(1.5,0,0);
883       else
884         mLandActor->SetPosition(-1.5,0,0);
885     }
886     break;
887   }
888
889   // Figure out the correct clipping range
890
891   if (this->Renderer) {
892     if (this->InteractorStyle &&
893         this->InteractorStyle->GetAutoAdjustCameraClippingRange()) {
894       this->Renderer->ResetCameraClippingRange();
895     } else {
896       vtkCamera *cam = this->Renderer->GetActiveCamera();
897       if (cam) {
898         double bounds[6];
899         this->ImageActor->GetBounds(bounds);
900         double spos = (double)bounds[this->SliceOrientation * 2];
901         double cpos = (double)cam->GetPosition()[this->SliceOrientation];
902         double range = fabs(spos - cpos);
903         double *spacing = input->GetSpacing();
904         double avg_spacing =
905           ((double)spacing[0] + (double)spacing[1] + (double)spacing[2]) / 3.0;
906         cam->SetClippingRange(
907                               range - avg_spacing * 3.0, range + avg_spacing * 3.0);
908       }
909     }
910   }
911 }
912 //----------------------------------------------------------------------------
913
914
915 //----------------------------------------------------------------------------
916 void vvSlicer::ComputeVFDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int vfExtent[6])
917 {
918   vtkImageData* image = this->GetInput();
919   vfExtent[0] = image->GetOrigin()[0] + x1*image->GetSpacing()[0];
920   vfExtent[1] = image->GetOrigin()[0] + x2*image->GetSpacing()[0];
921   vfExtent[2] = image->GetOrigin()[1] + y1*image->GetSpacing()[1];
922   vfExtent[3] = image->GetOrigin()[1] + y2*image->GetSpacing()[1];
923   vfExtent[4] = image->GetOrigin()[2] + z1*image->GetSpacing()[2];
924   vfExtent[5] = image->GetOrigin()[2] + z2*image->GetSpacing()[2];
925   
926   vtkImageData* vf = mVF->GetTransformedVTKImages()[0];
927   vf->UpdateInformation();
928   for(unsigned int i=0; i<6; i++)
929     vfExtent[i] = (vfExtent[i]- vf->GetOrigin()[i/2]) / vf->GetSpacing()[i/2];  
930
931   ClipDisplayedExtent(vfExtent,mVOIFilter->GetInput()->GetWholeExtent());
932 }
933 //----------------------------------------------------------------------------
934
935
936 //----------------------------------------------------------------------------
937 void vvSlicer::ComputeOverlayDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int overExtent[6])
938 {
939   vtkImageData* image = this->GetInput();
940   overExtent[0] = image->GetOrigin()[0] + x1*image->GetSpacing()[0];
941   overExtent[1] = image->GetOrigin()[0] + x2*image->GetSpacing()[0];
942   overExtent[2] = image->GetOrigin()[1] + y1*image->GetSpacing()[1];
943   overExtent[3] = image->GetOrigin()[1] + y2*image->GetSpacing()[1];
944   overExtent[4] = image->GetOrigin()[2] + z1*image->GetSpacing()[2];
945   overExtent[5] = image->GetOrigin()[2] + z2*image->GetSpacing()[2];
946   
947   vtkImageData* overlay = mOverlay->GetTransformedVTKImages()[0];
948   overlay->UpdateInformation();
949   for(unsigned int i=0; i<6; i++)
950     overExtent[i] = (overExtent[i]- overlay->GetOrigin()[i/2]) / overlay->GetSpacing()[i/2];  
951
952   ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
953 }
954 //----------------------------------------------------------------------------
955
956
957 //----------------------------------------------------------------------------
958 void vvSlicer::ComputeFusionDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int fusExtent[6])
959 {
960   vtkImageData* image = this->GetInput();
961   fusExtent[0] = image->GetOrigin()[0] + x1*image->GetSpacing()[0];
962   fusExtent[1] = image->GetOrigin()[0] + x2*image->GetSpacing()[0];
963   fusExtent[2] = image->GetOrigin()[1] + y1*image->GetSpacing()[1];
964   fusExtent[3] = image->GetOrigin()[1] + y2*image->GetSpacing()[1];
965   fusExtent[4] = image->GetOrigin()[2] + z1*image->GetSpacing()[2];
966   fusExtent[5] = image->GetOrigin()[2] + z2*image->GetSpacing()[2];
967   
968   vtkImageData* fusion = mFusion->GetTransformedVTKImages()[0];
969   fusion->UpdateInformation();
970   for(unsigned int i=0; i<6; i++)
971     fusExtent[i] = (fusExtent[i]- fusion->GetOrigin()[i/2]) / fusion->GetSpacing()[i/2];  
972
973   ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
974 }
975 //----------------------------------------------------------------------------
976
977
978 //----------------------------------------------------------------------------
979 void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
980 {
981   bool out = false;
982   int maxBound = 6;
983
984   //2D overlay on 3D image specific case
985   if (refExtent[4] == refExtent[5]) {
986     maxBound = 4;
987     extent[4] = refExtent[4];
988     extent[5] = refExtent[5];
989   }
990
991   for (int i = 0; i < maxBound; i = i+2) {
992     //if we are totally outside the image
993     if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] ) {
994       out = true;
995       break;
996     }
997     //crop to the limit of the image
998     extent[i] = (extent[i] > refExtent[i]) ? extent[i] : refExtent[i];
999     extent[i] = (extent[i] < refExtent[i+1]) ? extent[i] : refExtent[i+1];
1000     extent[i+1] = (extent[i+1] > refExtent[i]) ? extent[i+1] : refExtent[i];
1001     extent[i+1] = (extent[i+1] < refExtent[i+1]) ? extent[i+1] : refExtent[i+1];
1002   }
1003   if (out)
1004     for (int i = 0; i < maxBound; i = i+2) {
1005       extent[i] = refExtent[i];
1006       extent[i+1] = refExtent[i];
1007     }
1008 }
1009 //----------------------------------------------------------------------------
1010
1011
1012 //----------------------------------------------------------------------------
1013 void vvSlicer::UpdateOrientation()
1014 {
1015   // Set the camera position
1016   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1017   if (cam) {
1018     switch (this->SliceOrientation) {
1019     case vtkImageViewer2::SLICE_ORIENTATION_XY:
1020       cam->SetFocalPoint(0,0,0);
1021       cam->SetPosition(0,0,-1); // -1 if medical ?
1022       cam->SetViewUp(0,-1,0);
1023       break;
1024
1025     case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1026       cam->SetFocalPoint(0,0,0);
1027       cam->SetPosition(0,-1,0); // 1 if medical ?
1028       cam->SetViewUp(0,0,1);
1029       break;
1030
1031     case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1032       cam->SetFocalPoint(0,0,0);
1033       cam->SetPosition(-1,0,0); // -1 if medical ?
1034       cam->SetViewUp(0,0,1);
1035       break;
1036     }
1037   }
1038 }
1039 //----------------------------------------------------------------------------
1040
1041
1042 //----------------------------------------------------------------------------
1043 void vvSlicer::SetOpacity(double s)
1044 {
1045   this->GetImageActor()->SetOpacity(s);
1046 }
1047 //----------------------------------------------------------------------------
1048
1049
1050 //----------------------------------------------------------------------------
1051 void vvSlicer::SetRenderWindow(int orientation, vtkRenderWindow * rw)
1052 {
1053   this->Superclass::SetRenderWindow(rw);
1054   this->SetupInteractor(rw->GetInteractor());
1055   ca->SetImageActor(this->GetImageActor());
1056   ca->SetWindowLevel(this->GetWindowLevel());
1057   ca->SetText(2, "<slice>");
1058   ca->SetText(3, "<window>\n<level>");
1059
1060   double bounds[6];
1061   double max = 65000;
1062
1063   bounds[0] = -max;
1064   bounds[1] = max;
1065   bounds[2] = -max;
1066   bounds[3] = max;
1067   bounds[4] = -max;
1068   bounds[5] = max;
1069
1070   crossCursor->SetModelBounds(bounds);
1071   this->GetRenderer()->AddActor(pdmA);
1072   this->GetRenderer()->AddActor(ca);
1073   this->GetRenderer()->ResetCamera();
1074
1075   //this is just a mapping between the labeling of the orientations presented to the user and
1076   //the one used by vtk
1077   SetSliceOrientation(2-(orientation%3));
1078   ResetCamera();
1079 }
1080 //----------------------------------------------------------------------------
1081
1082
1083 //----------------------------------------------------------------------------
1084 void vvSlicer::ResetCamera()
1085 {
1086   this->GetRenderer()->ResetCamera();
1087 }
1088 //----------------------------------------------------------------------------
1089
1090
1091 //----------------------------------------------------------------------------
1092 void vvSlicer::SetDisplayMode(bool i)
1093 {
1094   this->GetImageActor()->SetVisibility(i);
1095   this->GetAnnotation()->SetVisibility(i);
1096   this->GetRenderer()->SetDraw(i);
1097   if (mLandActor)
1098     mLandActor->SetVisibility(i);
1099   pdmA->SetVisibility(i);
1100   if (i)
1101     UpdateDisplayExtent();
1102 }
1103 //----------------------------------------------------------------------------
1104
1105
1106 //----------------------------------------------------------------------------
1107 void vvSlicer::FlipHorizontalView()
1108 {
1109   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1110   if (cam) {
1111     double *position = cam->GetPosition();
1112     switch (this->SliceOrientation) {
1113     case vtkImageViewer2::SLICE_ORIENTATION_XY:
1114       cam->SetPosition(position[0],position[1],-position[2]);
1115       break;
1116
1117     case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1118       cam->SetPosition(position[0],-position[1],position[2]);
1119       break;
1120
1121     case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1122       cam->SetPosition(-position[0],position[1],position[2]);
1123       break;
1124     }
1125     this->Renderer->ResetCameraClippingRange();
1126     this->UpdateDisplayExtent();
1127   }
1128 }
1129 //----------------------------------------------------------------------------
1130
1131
1132 //----------------------------------------------------------------------------
1133 void vvSlicer::FlipVerticalView()
1134 {
1135   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1136   if (cam) {
1137     FlipHorizontalView();
1138     double *viewup = cam->GetViewUp();
1139     cam->SetViewUp(-viewup[0],-viewup[1],-viewup[2]);
1140     this->UpdateDisplayExtent();
1141   }
1142 }
1143 //----------------------------------------------------------------------------
1144
1145
1146 //----------------------------------------------------------------------------
1147 void vvSlicer::SetColorWindow(double window)
1148 {
1149   vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1150   if ( LUT ) {
1151     double level = this->GetWindowLevel()->GetLevel();
1152     LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
1153     LUT->Build();
1154   }
1155   this->vtkImageViewer2::SetColorWindow(window);
1156 }
1157 //----------------------------------------------------------------------------
1158
1159
1160 //----------------------------------------------------------------------------
1161 void vvSlicer::SetColorLevel(double level)
1162 {
1163   vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1164   if ( LUT ) {
1165     double window = this->GetWindowLevel()->GetWindow();
1166     LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
1167     LUT->Build();
1168   }
1169   this->vtkImageViewer2::SetColorLevel(level);
1170 }
1171 //----------------------------------------------------------------------------
1172
1173 //----------------------------------------------------------------------------
1174 // Returns the min an the max value in a 41x41 region around the mouse pointer
1175 void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max)
1176 {
1177   //Get mouse pointer position in view coordinates
1178   double fLocalExtents[6];
1179   for(int i=0; i<3; i++) {
1180     fLocalExtents[i*2  ] = mCurrent[i];
1181     fLocalExtents[i*2+1] = mCurrent[i];
1182   }
1183   this->Renderer->WorldToView(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
1184   this->Renderer->WorldToView(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
1185   for(int i=0; i<3; i++) {
1186     if (i!=SliceOrientation) { //SR: assumes that SliceOrientation is valid in ViewCoordinates (???)
1187       fLocalExtents[i*2  ] -= 0.2;
1188       fLocalExtents[i*2+1] += 0.2;
1189     }
1190   }
1191   this->Renderer->ViewToWorld(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
1192   this->Renderer->ViewToWorld(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
1193
1194   //Convert to image pixel coordinates (rounded)
1195   int iLocalExtents[6];
1196   for(int i=0; i<3; i++) {
1197     fLocalExtents[i*2  ] = (fLocalExtents[i*2  ] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
1198     fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
1199
1200     iLocalExtents[i*2  ] = lrint(fLocalExtents[i*2  ]);
1201     iLocalExtents[i*2+1] = lrint(fLocalExtents[i*2+1]);
1202
1203     if(iLocalExtents[i*2  ]>iLocalExtents[i*2+1])
1204       std::swap(iLocalExtents[i*2], iLocalExtents[i*2+1]);
1205   }
1206
1207   vtkSmartPointer<vtkExtractVOI> voiFilter = vtkSmartPointer<vtkExtractVOI>::New();
1208   voiFilter->SetInput(this->GetInput());
1209   voiFilter->SetVOI(iLocalExtents);
1210   voiFilter->Update();
1211   if (!voiFilter->GetOutput()->GetNumberOfPoints()) {
1212     min = 0;
1213     max = 0;
1214     return;
1215   }
1216
1217   vtkSmartPointer<vtkImageAccumulate> accFilter = vtkSmartPointer<vtkImageAccumulate>::New();
1218   accFilter->SetInput(voiFilter->GetOutput());
1219   accFilter->Update();
1220
1221   min = *(accFilter->GetMin());
1222   max = *(accFilter->GetMax());
1223 }
1224 //----------------------------------------------------------------------------
1225
1226 //----------------------------------------------------------------------------
1227 double vvSlicer::GetScalarComponentAsDouble(vtkImageData *image, int X, double Y, double Z, int &ix, int &iy, int &iz, int component)
1228 {
1229   ix = lrint(X);
1230   iy = lrint(Y);
1231   iz = lrint(Z);
1232   if (ix < image->GetWholeExtent()[0] ||
1233       ix > image->GetWholeExtent()[1] ||
1234       iy < image->GetWholeExtent()[2] ||
1235       iy > image->GetWholeExtent()[3] ||
1236       iz < image->GetWholeExtent()[4] ||
1237       iz > image->GetWholeExtent()[5] )
1238     return sqrt(-1.);
1239
1240   image->SetUpdateExtent(ix, ix, iy, iy, iz, iz);
1241   image->Update();
1242   return image->GetScalarComponentAsDouble(ix, iy, iz, component);
1243 }
1244 //----------------------------------------------------------------------------
1245
1246 //----------------------------------------------------------------------------
1247 void vvSlicer::Render()
1248 {
1249   if (this->GetWindowLevel()->GetLookupTable() && !this->mOverlay && !this->mFusion) {
1250     legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable());
1251     legend->SetVisibility(1);
1252   } else legend->SetVisibility(0);
1253
1254   if (ca->GetVisibility()) {
1255     std::string worldPos = "";
1256     std::stringstream world1;
1257     std::stringstream world2;
1258     std::stringstream world3;
1259     world1 << (int)mCurrent[0];
1260     world2 << (int)mCurrent[1];
1261     world3 << (int)mCurrent[2];
1262     double X = (mCurrent[0] - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1263     double Y = (mCurrent[1] - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1264     double Z = (mCurrent[2] - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1265
1266     if (pdmA->GetVisibility()) {
1267       double x = mCursor[0];
1268       double y = mCursor[1];
1269       double z = mCursor[2];
1270       double xCursor = (x - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1271       double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1272       double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1273
1274       if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0] &&
1275           xCursor < this->GetImageActor()->GetDisplayExtent()[1]+1 &&
1276           yCursor >= this->GetImageActor()->GetDisplayExtent()[2] &&
1277           yCursor < this->GetImageActor()->GetDisplayExtent()[3]+1 &&
1278           zCursor >= this->GetImageActor()->GetDisplayExtent()[4] &&
1279           zCursor < this->GetImageActor()->GetDisplayExtent()[5]+1 ) {
1280         vtkRenderer * renderer = this->Renderer;
1281
1282         renderer->WorldToView(x,y,z);
1283         renderer->ViewToNormalizedViewport(x,y,z);
1284         renderer->NormalizedViewportToViewport(x,y);
1285         renderer->ViewportToNormalizedDisplay(x,y);
1286         renderer->NormalizedDisplayToDisplay(x,y);
1287         crossCursor->SetFocalPoint(x,y,z);
1288       } else
1289         crossCursor->SetFocalPoint(-1,-1,z);
1290     }
1291
1292     if (X >= this->GetInput()->GetWholeExtent()[0] &&
1293         X <= this->GetInput()->GetWholeExtent()[1] &&
1294         Y >= this->GetInput()->GetWholeExtent()[2] &&
1295         Y <= this->GetInput()->GetWholeExtent()[3] &&
1296         Z >= this->GetInput()->GetWholeExtent()[4] &&
1297         Z <= this->GetInput()->GetWholeExtent()[5]) {
1298       int ix, iy, iz;
1299       double value = this->GetScalarComponentAsDouble(this->GetInput(), X, Y, Z, ix, iy, iz);
1300
1301       std::stringstream pixel1;
1302       std::stringstream pixel2;
1303       std::stringstream pixel3;
1304       std::stringstream temps;
1305       pixel1 << ix;
1306       pixel2 << iy;
1307       pixel3 << iz;
1308       temps << mCurrentTSlice;
1309
1310       std::stringstream val;
1311       val << value;
1312       worldPos += "data value : " + val.str();
1313       worldPos += "\n mm : " + world1.str() + " " + world2.str() + " " +
1314         world3.str() + " " + temps.str();
1315       worldPos += "\n pixel : " + pixel1.str() + " " + pixel2.str() + " " +
1316         pixel3.str() + " " + temps.str();
1317     }
1318     ca->SetText(1,worldPos.c_str());
1319   }
1320   if (mOverlay && mOverlayActor->GetVisibility()) {
1321     mOverlayMapper->SetWindow(this->GetColorWindow());
1322     mOverlayMapper->SetLevel(this->GetColorLevel());
1323     mOverlayMapper->GetOutput()->SetUpdateExtent(mOverlayActor->GetDisplayExtent());
1324     mOverlayMapper->GetOutput()->Update();
1325     mOverlayMapper->Update();
1326   }
1327   if (mLandMapper)
1328     UpdateLandmarks();
1329   //this->Superclass::Render();
1330   this->GetRenderWindow()->Render();
1331 }
1332 //----------------------------------------------------------------------------
1333
1334
1335 //----------------------------------------------------------------------------
1336 void vvSlicer::UpdateCursorPosition()
1337 {
1338   if (this->GetImageActor()->GetVisibility()) {
1339     pdmA->SetVisibility(true);
1340     mCursor[0] = mCurrent[0];
1341     mCursor[1] = mCurrent[1];
1342     mCursor[2] = mCurrent[2];
1343     mCursor[3] = mCurrentTSlice;
1344   }
1345 }
1346 //----------------------------------------------------------------------------
1347
1348
1349 //----------------------------------------------------------------------------
1350 void vvSlicer::UpdateLandmarks()
1351 {
1352   vtkPolyData *pd = static_cast<vtkPolyData*>(mLandClipper->GetInput());
1353   if (pd->GetPoints()) {
1354     mLandGlyph->SetRange(0,1);
1355     mLandGlyph->Modified();
1356     mLandGlyph->Update();
1357
1358     mClipBox->Modified();
1359     mLandClipper->Update();
1360     mLandMapper->Update();
1361   }
1362
1363 }
1364 //----------------------------------------------------------------------------
1365
1366
1367 //----------------------------------------------------------------------------
1368 void vvSlicer::SetSlice(int slice)
1369 {
1370   int *range = this->GetSliceRange();
1371   if (range) {
1372     if (slice < range[0]) {
1373       slice = range[0];
1374     } else if (slice > range[1]) {
1375       slice = range[1];
1376     }
1377   }
1378
1379   if (this->Slice == slice) {
1380     return;
1381   }
1382
1383   this->Slice = slice;
1384   SetContourSlice();
1385   this->Modified();
1386   this->UpdateDisplayExtent();
1387
1388   // Seems to work without this line
1389   //  this->Render();
1390 }
1391 //----------------------------------------------------------------------------
1392
1393
1394 //----------------------------------------------------------------------------
1395 void vvSlicer::SetContourSlice()
1396 {
1397   if (mSurfaceCutActors.size() > 0)
1398     for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
1399          i!=mSurfaceCutActors.end(); i++)
1400       (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+
1401                         this->GetImage()->GetOrigin()[this->SliceOrientation]);
1402 }
1403 //----------------------------------------------------------------------------
1404
1405
1406 //----------------------------------------------------------------------------
1407 void vvSlicer::ForceUpdateDisplayExtent()
1408 {
1409   this->UpdateDisplayExtent();
1410 }
1411 //----------------------------------------------------------------------------
1412
1413
1414 //----------------------------------------------------------------------------
1415 int* vvSlicer::GetDisplayExtent()
1416 {
1417   return this->GetImageActor()->GetDisplayExtent();
1418 }
1419 //----------------------------------------------------------------------------
1420
1421
1422 //----------------------------------------------------------------------------
1423 void vvSlicer::PrintSelf(ostream& os, vtkIndent indent)
1424 {
1425   this->Superclass::PrintSelf(os, indent);
1426 }
1427 //----------------------------------------------------------------------------
1428
1429 //----------------------------------------------------------------------------
1430 void vvSlicer::SetVFColor(double r, double g, double b)
1431 {
1432   double mVFColorHSV[3];
1433   mVFColor[0] = r;
1434   mVFColor[1] = g;
1435   mVFColor[2] = b;
1436
1437   vtkMath::RGBToHSV(mVFColor, mVFColorHSV);
1438   mVFColorLUT->SetHueRange(mVFColorHSV[0], mVFColorHSV[0]);
1439   mVFColorLUT->SetSaturationRange(mVFColorHSV[1],mVFColorHSV[1]);
1440   mVFColorLUT->SetValueRange(mVFColorHSV[2], mVFColorHSV[2]);
1441
1442   this->Render();
1443 }  
1444