]> Creatis software - clitk.git/blob - vv/vvSlicer.cxx
1c486bc786213e22bc1e7d82342dbf2a04ed8644
[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   double dVfExtent[6];
919   vtkImageData* image = this->GetInput();
920   dVfExtent[0] = image->GetOrigin()[0] + x1*image->GetSpacing()[0];
921   dVfExtent[1] = image->GetOrigin()[0] + x2*image->GetSpacing()[0];
922   dVfExtent[2] = image->GetOrigin()[1] + y1*image->GetSpacing()[1];
923   dVfExtent[3] = image->GetOrigin()[1] + y2*image->GetSpacing()[1];
924   dVfExtent[4] = image->GetOrigin()[2] + z1*image->GetSpacing()[2];
925   dVfExtent[5] = image->GetOrigin()[2] + z2*image->GetSpacing()[2];
926   
927   vtkImageData* vf = mVF->GetTransformedVTKImages()[0];
928   vf->UpdateInformation();
929   for(unsigned int i=0; i<6; i++)
930     vfExtent[i] = itk::Math::Round((dVfExtent[i]- vf->GetOrigin()[i/2]) / vf->GetSpacing()[i/2]);
931
932   ClipDisplayedExtent(vfExtent,mVOIFilter->GetInput()->GetWholeExtent());
933 }
934 //----------------------------------------------------------------------------
935
936
937 //----------------------------------------------------------------------------
938 void vvSlicer::ComputeOverlayDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int overExtent[6])
939 {
940   double dOverExtent[6];
941   vtkImageData* image = this->GetInput();
942   dOverExtent[0] = image->GetOrigin()[0] + x1*image->GetSpacing()[0];
943   dOverExtent[1] = image->GetOrigin()[0] + x2*image->GetSpacing()[0];
944   dOverExtent[2] = image->GetOrigin()[1] + y1*image->GetSpacing()[1];
945   dOverExtent[3] = image->GetOrigin()[1] + y2*image->GetSpacing()[1];
946   dOverExtent[4] = image->GetOrigin()[2] + z1*image->GetSpacing()[2];
947   dOverExtent[5] = image->GetOrigin()[2] + z2*image->GetSpacing()[2];
948   
949   vtkImageData* overlay = mOverlay->GetTransformedVTKImages()[0];
950   overlay->UpdateInformation();
951   for(unsigned int i=0; i<6; i++)
952     overExtent[i] = itk::Math::Round((dOverExtent[i]- overlay->GetOrigin()[i/2]) / overlay->GetSpacing()[i/2]);
953
954   ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
955 }
956 //----------------------------------------------------------------------------
957
958
959 //----------------------------------------------------------------------------
960 void vvSlicer::ComputeFusionDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int fusExtent[6])
961 {
962   double dFusExtent[6];
963   vtkImageData* image = this->GetInput();
964   dFusExtent[0] = image->GetOrigin()[0] + x1*image->GetSpacing()[0];
965   dFusExtent[1] = image->GetOrigin()[0] + x2*image->GetSpacing()[0];
966   dFusExtent[2] = image->GetOrigin()[1] + y1*image->GetSpacing()[1];
967   dFusExtent[3] = image->GetOrigin()[1] + y2*image->GetSpacing()[1];
968   dFusExtent[4] = image->GetOrigin()[2] + z1*image->GetSpacing()[2];
969   dFusExtent[5] = image->GetOrigin()[2] + z2*image->GetSpacing()[2];
970   
971   vtkImageData* fusion = mFusion->GetTransformedVTKImages()[0];
972   fusion->UpdateInformation();
973   for(unsigned int i=0; i<6; i++)
974     fusExtent[i] = itk::Math::Round((dFusExtent[i]- fusion->GetOrigin()[i/2]) / fusion->GetSpacing()[i/2]);
975
976   ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
977 }
978 //----------------------------------------------------------------------------
979
980
981 //----------------------------------------------------------------------------
982 void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
983 {
984   bool out = false;
985   int maxBound = 6;
986
987   //2D overlay on 3D image specific case
988   if (refExtent[4] == refExtent[5]) {
989     maxBound = 4;
990     extent[4] = refExtent[4];
991     extent[5] = refExtent[5];
992   }
993
994   for (int i = 0; i < maxBound; i = i+2) {
995     //if we are totally outside the image
996     if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] ) {
997       out = true;
998       break;
999     }
1000     //crop to the limit of the image
1001     extent[i] = (extent[i] > refExtent[i]) ? extent[i] : refExtent[i];
1002     extent[i] = (extent[i] < refExtent[i+1]) ? extent[i] : refExtent[i+1];
1003     extent[i+1] = (extent[i+1] > refExtent[i]) ? extent[i+1] : refExtent[i];
1004     extent[i+1] = (extent[i+1] < refExtent[i+1]) ? extent[i+1] : refExtent[i+1];
1005   }
1006   if (out)
1007     for (int i = 0; i < maxBound; i = i+2) {
1008       extent[i] = refExtent[i];
1009       extent[i+1] = refExtent[i];
1010     }
1011 }
1012 //----------------------------------------------------------------------------
1013
1014
1015 //----------------------------------------------------------------------------
1016 void vvSlicer::UpdateOrientation()
1017 {
1018   // Set the camera position
1019   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1020   if (cam) {
1021     switch (this->SliceOrientation) {
1022     case vtkImageViewer2::SLICE_ORIENTATION_XY:
1023       cam->SetFocalPoint(0,0,0);
1024       cam->SetPosition(0,0,-1); // -1 if medical ?
1025       cam->SetViewUp(0,-1,0);
1026       break;
1027
1028     case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1029       cam->SetFocalPoint(0,0,0);
1030       cam->SetPosition(0,-1,0); // 1 if medical ?
1031       cam->SetViewUp(0,0,1);
1032       break;
1033
1034     case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1035       cam->SetFocalPoint(0,0,0);
1036       cam->SetPosition(-1,0,0); // -1 if medical ?
1037       cam->SetViewUp(0,0,1);
1038       break;
1039     }
1040   }
1041 }
1042 //----------------------------------------------------------------------------
1043
1044
1045 //----------------------------------------------------------------------------
1046 void vvSlicer::SetOpacity(double s)
1047 {
1048   this->GetImageActor()->SetOpacity(s);
1049 }
1050 //----------------------------------------------------------------------------
1051
1052
1053 //----------------------------------------------------------------------------
1054 void vvSlicer::SetRenderWindow(int orientation, vtkRenderWindow * rw)
1055 {
1056   this->Superclass::SetRenderWindow(rw);
1057   this->SetupInteractor(rw->GetInteractor());
1058   ca->SetImageActor(this->GetImageActor());
1059   ca->SetWindowLevel(this->GetWindowLevel());
1060   ca->SetText(2, "<slice>");
1061   ca->SetText(3, "<window>\n<level>");
1062
1063   double bounds[6];
1064   double max = 65000;
1065
1066   bounds[0] = -max;
1067   bounds[1] = max;
1068   bounds[2] = -max;
1069   bounds[3] = max;
1070   bounds[4] = -max;
1071   bounds[5] = max;
1072
1073   crossCursor->SetModelBounds(bounds);
1074   this->GetRenderer()->AddActor(pdmA);
1075   this->GetRenderer()->AddActor(ca);
1076   this->GetRenderer()->ResetCamera();
1077
1078   //this is just a mapping between the labeling of the orientations presented to the user and
1079   //the one used by vtk
1080   SetSliceOrientation(2-(orientation%3));
1081   ResetCamera();
1082 }
1083 //----------------------------------------------------------------------------
1084
1085
1086 //----------------------------------------------------------------------------
1087 void vvSlicer::ResetCamera()
1088 {
1089   this->GetRenderer()->ResetCamera();
1090 }
1091 //----------------------------------------------------------------------------
1092
1093
1094 //----------------------------------------------------------------------------
1095 void vvSlicer::SetDisplayMode(bool i)
1096 {
1097   this->GetImageActor()->SetVisibility(i);
1098   this->GetAnnotation()->SetVisibility(i);
1099   this->GetRenderer()->SetDraw(i);
1100   if (mLandActor)
1101     mLandActor->SetVisibility(i);
1102   pdmA->SetVisibility(i);
1103   if (i)
1104     UpdateDisplayExtent();
1105 }
1106 //----------------------------------------------------------------------------
1107
1108
1109 //----------------------------------------------------------------------------
1110 void vvSlicer::FlipHorizontalView()
1111 {
1112   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1113   if (cam) {
1114     double *position = cam->GetPosition();
1115     switch (this->SliceOrientation) {
1116     case vtkImageViewer2::SLICE_ORIENTATION_XY:
1117       cam->SetPosition(position[0],position[1],-position[2]);
1118       break;
1119
1120     case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1121       cam->SetPosition(position[0],-position[1],position[2]);
1122       break;
1123
1124     case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1125       cam->SetPosition(-position[0],position[1],position[2]);
1126       break;
1127     }
1128     this->Renderer->ResetCameraClippingRange();
1129     this->UpdateDisplayExtent();
1130   }
1131 }
1132 //----------------------------------------------------------------------------
1133
1134
1135 //----------------------------------------------------------------------------
1136 void vvSlicer::FlipVerticalView()
1137 {
1138   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1139   if (cam) {
1140     FlipHorizontalView();
1141     double *viewup = cam->GetViewUp();
1142     cam->SetViewUp(-viewup[0],-viewup[1],-viewup[2]);
1143     this->UpdateDisplayExtent();
1144   }
1145 }
1146 //----------------------------------------------------------------------------
1147
1148
1149 //----------------------------------------------------------------------------
1150 void vvSlicer::SetColorWindow(double window)
1151 {
1152   vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1153   if ( LUT ) {
1154     double level = this->GetWindowLevel()->GetLevel();
1155     LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
1156     LUT->Build();
1157   }
1158   this->vtkImageViewer2::SetColorWindow(window);
1159 }
1160 //----------------------------------------------------------------------------
1161
1162
1163 //----------------------------------------------------------------------------
1164 void vvSlicer::SetColorLevel(double level)
1165 {
1166   vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1167   if ( LUT ) {
1168     double window = this->GetWindowLevel()->GetWindow();
1169     LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
1170     LUT->Build();
1171   }
1172   this->vtkImageViewer2::SetColorLevel(level);
1173 }
1174 //----------------------------------------------------------------------------
1175
1176 //----------------------------------------------------------------------------
1177 // Returns the min an the max value in a 41x41 region around the mouse pointer
1178 void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max)
1179 {
1180   //Get mouse pointer position in view coordinates
1181   double fLocalExtents[6];
1182   for(int i=0; i<3; i++) {
1183     fLocalExtents[i*2  ] = mCurrent[i];
1184     fLocalExtents[i*2+1] = mCurrent[i];
1185   }
1186   this->Renderer->WorldToView(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
1187   this->Renderer->WorldToView(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
1188   for(int i=0; i<3; i++) {
1189     if (i!=SliceOrientation) { //SR: assumes that SliceOrientation is valid in ViewCoordinates (???)
1190       fLocalExtents[i*2  ] -= 0.2;
1191       fLocalExtents[i*2+1] += 0.2;
1192     }
1193   }
1194   this->Renderer->ViewToWorld(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
1195   this->Renderer->ViewToWorld(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
1196
1197   //Convert to image pixel coordinates (rounded)
1198   int iLocalExtents[6];
1199   for(int i=0; i<3; i++) {
1200     fLocalExtents[i*2  ] = (fLocalExtents[i*2  ] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
1201     fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
1202
1203     iLocalExtents[i*2  ] = lrint(fLocalExtents[i*2  ]);
1204     iLocalExtents[i*2+1] = lrint(fLocalExtents[i*2+1]);
1205
1206     if(iLocalExtents[i*2  ]>iLocalExtents[i*2+1])
1207       std::swap(iLocalExtents[i*2], iLocalExtents[i*2+1]);
1208   }
1209
1210   vtkSmartPointer<vtkExtractVOI> voiFilter = vtkSmartPointer<vtkExtractVOI>::New();
1211   voiFilter->SetInput(this->GetInput());
1212   voiFilter->SetVOI(iLocalExtents);
1213   voiFilter->Update();
1214   if (!voiFilter->GetOutput()->GetNumberOfPoints()) {
1215     min = 0;
1216     max = 0;
1217     return;
1218   }
1219
1220   vtkSmartPointer<vtkImageAccumulate> accFilter = vtkSmartPointer<vtkImageAccumulate>::New();
1221   accFilter->SetInput(voiFilter->GetOutput());
1222   accFilter->Update();
1223
1224   min = *(accFilter->GetMin());
1225   max = *(accFilter->GetMax());
1226 }
1227 //----------------------------------------------------------------------------
1228
1229 //----------------------------------------------------------------------------
1230 double vvSlicer::GetScalarComponentAsDouble(vtkImageData *image, int X, double Y, double Z, int &ix, int &iy, int &iz, int component)
1231 {
1232   ix = lrint(X);
1233   iy = lrint(Y);
1234   iz = lrint(Z);
1235   if (ix < image->GetWholeExtent()[0] ||
1236       ix > image->GetWholeExtent()[1] ||
1237       iy < image->GetWholeExtent()[2] ||
1238       iy > image->GetWholeExtent()[3] ||
1239       iz < image->GetWholeExtent()[4] ||
1240       iz > image->GetWholeExtent()[5] )
1241     return sqrt(-1.);
1242
1243   image->SetUpdateExtent(ix, ix, iy, iy, iz, iz);
1244   image->Update();
1245   return image->GetScalarComponentAsDouble(ix, iy, iz, component);
1246 }
1247 //----------------------------------------------------------------------------
1248
1249 //----------------------------------------------------------------------------
1250 void vvSlicer::Render()
1251 {
1252   if (this->GetWindowLevel()->GetLookupTable() && !this->mOverlay && !this->mFusion) {
1253     legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable());
1254     legend->SetVisibility(1);
1255   } else legend->SetVisibility(0);
1256
1257   if (ca->GetVisibility()) {
1258     std::string worldPos = "";
1259     std::stringstream world1;
1260     std::stringstream world2;
1261     std::stringstream world3;
1262     world1 << (int)mCurrent[0];
1263     world2 << (int)mCurrent[1];
1264     world3 << (int)mCurrent[2];
1265     double X = (mCurrent[0] - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1266     double Y = (mCurrent[1] - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1267     double Z = (mCurrent[2] - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1268     
1269 //     if (X < this->GetInput()->GetWholeExtent()[0]) X = this->GetInput()->GetWholeExtent()[0];
1270 //     else if (X > this->GetInput()->GetWholeExtent()[1]) X = this->GetInput()->GetWholeExtent()[1]; 
1271 //     if (Y < this->GetInput()->GetWholeExtent()[2]) Y = this->GetInput()->GetWholeExtent()[2];
1272 //     else if (Y > this->GetInput()->GetWholeExtent()[3]) Y = this->GetInput()->GetWholeExtent()[3]; 
1273 //     if (Z < this->GetInput()->GetWholeExtent()[4]) Z = this->GetInput()->GetWholeExtent()[4];
1274 //     else if (Z > this->GetInput()->GetWholeExtent()[5]) Z = this->GetInput()->GetWholeExtent()[5]; 
1275
1276     if (X >= this->GetInput()->GetWholeExtent()[0] &&
1277         X <= this->GetInput()->GetWholeExtent()[1] &&
1278         Y >= this->GetInput()->GetWholeExtent()[2] &&
1279         Y <= this->GetInput()->GetWholeExtent()[3] &&
1280         Z >= this->GetInput()->GetWholeExtent()[4] &&
1281         Z <= this->GetInput()->GetWholeExtent()[5]) {
1282
1283       
1284       int ix, iy, iz;
1285       double value = this->GetScalarComponentAsDouble(this->GetInput(), X, Y, Z, ix, iy, iz);
1286
1287       std::stringstream pixel1;
1288       std::stringstream pixel2;
1289       std::stringstream pixel3;
1290       std::stringstream temps;
1291       pixel1 << ix;
1292       pixel2 << iy;
1293       pixel3 << iz;
1294       temps << mCurrentTSlice;
1295
1296       std::stringstream val;
1297       val << value;
1298       worldPos += "data value : " + val.str();
1299       worldPos += "\n mm : " + world1.str() + " " + world2.str() + " " +
1300         world3.str() + " " + temps.str();
1301       worldPos += "\n pixel : " + pixel1.str() + " " + pixel2.str() + " " +
1302         pixel3.str() + " " + temps.str();
1303     }
1304     ca->SetText(1,worldPos.c_str());
1305   }
1306
1307   if (pdmA->GetVisibility()) {
1308     double x = mCursor[0];
1309     double y = mCursor[1];
1310     double z = mCursor[2];
1311     double xCursor = (x - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1312     double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1313     double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1314
1315     if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0] &&
1316         xCursor < this->GetImageActor()->GetDisplayExtent()[1]+1 &&
1317         yCursor >= this->GetImageActor()->GetDisplayExtent()[2] &&
1318         yCursor < this->GetImageActor()->GetDisplayExtent()[3]+1 &&
1319         zCursor >= this->GetImageActor()->GetDisplayExtent()[4] &&
1320         zCursor < this->GetImageActor()->GetDisplayExtent()[5]+1 ) {
1321       vtkRenderer * renderer = this->Renderer;
1322
1323       renderer->WorldToView(x,y,z);
1324       renderer->ViewToNormalizedViewport(x,y,z);
1325       renderer->NormalizedViewportToViewport(x,y);
1326       renderer->ViewportToNormalizedDisplay(x,y);
1327       renderer->NormalizedDisplayToDisplay(x,y);
1328       crossCursor->SetFocalPoint(x,y,z);
1329     } else
1330       crossCursor->SetFocalPoint(-1,-1,z);
1331   }
1332
1333
1334   if (mOverlay && mOverlayActor->GetVisibility()) {
1335     mOverlayMapper->SetWindow(this->GetColorWindow());
1336     mOverlayMapper->SetLevel(this->GetColorLevel());
1337     mOverlayMapper->GetOutput()->SetUpdateExtent(mOverlayActor->GetDisplayExtent());
1338     mOverlayMapper->GetOutput()->Update();
1339     mOverlayMapper->Update();
1340   }
1341   if (mLandMapper)
1342     UpdateLandmarks();
1343
1344   this->GetRenderWindow()->Render();
1345 }
1346 //----------------------------------------------------------------------------
1347
1348
1349 //----------------------------------------------------------------------------
1350 void vvSlicer::UpdateCursorPosition()
1351 {
1352   if (this->GetImageActor()->GetVisibility()) {
1353     pdmA->SetVisibility(true);
1354     mCursor[0] = mCurrent[0];
1355     mCursor[1] = mCurrent[1];
1356     mCursor[2] = mCurrent[2];
1357     mCursor[3] = mCurrentTSlice;
1358   }
1359 }
1360 //----------------------------------------------------------------------------
1361
1362
1363 //----------------------------------------------------------------------------
1364 void vvSlicer::UpdateLandmarks()
1365 {
1366   vtkPolyData *pd = static_cast<vtkPolyData*>(mLandClipper->GetInput());
1367   if (pd->GetPoints()) {
1368     mLandGlyph->SetRange(0,1);
1369     mLandGlyph->Modified();
1370     mLandGlyph->Update();
1371
1372     mClipBox->Modified();
1373     mLandClipper->Update();
1374     mLandMapper->Update();
1375   }
1376
1377 }
1378 //----------------------------------------------------------------------------
1379
1380
1381 //----------------------------------------------------------------------------
1382 void vvSlicer::SetSlice(int slice)
1383 {
1384   int *range = this->GetSliceRange();
1385   if (range) {
1386     if (slice < range[0]) {
1387       slice = range[0];
1388     } else if (slice > range[1]) {
1389       slice = range[1];
1390     }
1391   }
1392
1393   if (this->Slice == slice) {
1394     return;
1395   }
1396
1397   this->Slice = slice;
1398   SetContourSlice();
1399   this->Modified();
1400   this->UpdateDisplayExtent();
1401
1402   // Seems to work without this line
1403   //this->Render();
1404 }
1405 //----------------------------------------------------------------------------
1406
1407
1408 //----------------------------------------------------------------------------
1409 void vvSlicer::SetContourSlice()
1410 {
1411   if (mSurfaceCutActors.size() > 0)
1412     for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
1413          i!=mSurfaceCutActors.end(); i++)
1414       (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+
1415                         this->GetImage()->GetOrigin()[this->SliceOrientation]);
1416 }
1417 //----------------------------------------------------------------------------
1418
1419
1420 //----------------------------------------------------------------------------
1421 void vvSlicer::ForceUpdateDisplayExtent()
1422 {
1423   this->UpdateDisplayExtent();
1424 }
1425 //----------------------------------------------------------------------------
1426
1427
1428 //----------------------------------------------------------------------------
1429 int* vvSlicer::GetDisplayExtent()
1430 {
1431   return this->GetImageActor()->GetDisplayExtent();
1432 }
1433 //----------------------------------------------------------------------------
1434
1435
1436 //----------------------------------------------------------------------------
1437 void vvSlicer::PrintSelf(ostream& os, vtkIndent indent)
1438 {
1439   this->Superclass::PrintSelf(os, indent);
1440 }
1441 //----------------------------------------------------------------------------
1442
1443 //----------------------------------------------------------------------------
1444 void vvSlicer::SetVFColor(double r, double g, double b)
1445 {
1446   double mVFColorHSV[3];
1447   mVFColor[0] = r;
1448   mVFColor[1] = g;
1449   mVFColor[2] = b;
1450
1451   vtkMath::RGBToHSV(mVFColor, mVFColorHSV);
1452   mVFColorLUT->SetHueRange(mVFColorHSV[0], mVFColorHSV[0]);
1453   mVFColorLUT->SetSaturationRange(mVFColorHSV[1],mVFColorHSV[1]);
1454   mVFColorLUT->SetValueRange(mVFColorHSV[2], mVFColorHSV[2]);
1455
1456   this->Render();
1457 }  
1458