]> Creatis software - clitk.git/blob - vv/vvSlicer.cxx
Merge branch 'master' of git.creatis.insa-lyon.fr:clitk
[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://www.centreleonberard.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
25 #include <vtkTextProperty.h>
26 #include <vtkTextActor.h>
27 #include <vtkTextSource.h>
28 #include <vtkActor2D.h>
29 #include <vtkCursor2D.h>
30 #include <vtkPolyDataMapper2D.h>
31 #include <vtkProperty2D.h>
32 #include <vtkCornerAnnotation.h>
33 #include <vtkImageMapToWindowLevelColors.h>
34 #include <vtkImageData.h>
35 #include <vtkImageActor.h>
36 #include <vvBlendImageActor.h>
37 #include <vtkToolkits.h>
38 #include <vtkObjectFactory.h>
39 #include <vtkPointData.h>
40 #include <vtkDataArray.h>
41 #include <vtkFloatArray.h>
42 #include <vtkClipPolyData.h>
43 #include <vtkActor2DCollection.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 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
70 #  include <vtkImageMapper3D.h>
71 #endif
72
73 vtkCxxRevisionMacro(vvSlicer, "DummyRevision");
74 vtkStandardNewMacro(vvSlicer);
75 static void copyExtent(int* in, int* to){
76  for(int i=0; i<6; ++i) to[i]=in[i]; 
77 }
78 //------------------------------------------------------------------------------
79 vvSlicer::vvSlicer()
80 {
81   this->UnInstallPipeline();
82   mImage = NULL;
83   mReducedExtent = new int[6];
84   mCurrentTSlice = 0;
85   mCurrentFusionTSlice = 0;
86   mCurrentOverlayTSlice = 0;
87   mUseReducedExtent = false;
88
89   mCurrent[0] = -VTK_DOUBLE_MAX;
90   mCurrent[1] = -VTK_DOUBLE_MAX;
91   mCurrent[2] = -VTK_DOUBLE_MAX;
92
93   mCursor[0] = 0;//-VTK_DOUBLE_MAX;
94   mCursor[1] = 0;//-VTK_DOUBLE_MAX;
95   mCursor[2] = 0;//-VTK_DOUBLE_MAX;
96   mCursor[3] = 0;//-VTK_DOUBLE_MAX;
97
98   mSubSampling = 5;
99   mScale = 1;
100   mVFLog = 0;
101   mVFWidth = 1;
102   mVFColor[0] = 0;
103   mVFColor[1] = 1;
104   mVFColor[2] = 0;
105
106   crossCursor = vtkSmartPointer<vtkCursor2D>::New();
107   crossCursor->AllOff();
108   crossCursor->AxesOn();
109   crossCursor->SetTranslationMode(1);
110   crossCursor->SetRadius(2);
111
112   pdm = vtkSmartPointer<vtkPolyDataMapper2D>::New();
113   pdm->SetInput(crossCursor->GetOutput());
114
115   pdmA = vtkSmartPointer<vtkActor2D>::New();
116   pdmA->SetMapper(pdm);
117   pdmA->GetProperty()->SetColor(255,10,212);
118   pdmA->SetVisibility(0);
119   pdmA->SetPickable(0);
120
121   ca = vtkSmartPointer<vtkCornerAnnotation>::New();
122   ca->GetTextProperty()->SetColor(255,10,212);
123   ca->SetVisibility(1);
124   mFileName = "";
125
126   mVF = NULL;
127   mOverlay = NULL;
128   mFusion = NULL;
129   mLandmarks = NULL;
130
131   legend = vtkSmartPointer<vtkScalarBarActor>::New();
132   //legend->SetTitle("test!");
133   legend->SetPosition(0.82,0.18);
134   legend->SetWidth(0.1);
135   legend->SetVisibility(0);
136   legend->SetLabelFormat("%.1f");
137   this->GetRenderer()->AddActor(legend);
138   showFusionLegend = false;
139
140   this->InstallPipeline();
141
142   mLinkOverlayWindowLevel = true;
143
144 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
145   this->GetImageActor()->GetMapper()->BorderOn();
146 #endif
147
148   mSlicingTransform = vtkSmartPointer<vtkTransform>::New();
149   mConcatenatedTransform = vtkSmartPointer<vtkTransform>::New();
150   mConcatenatedFusionTransform = vtkSmartPointer<vtkTransform>::New();
151   mConcatenatedOverlayTransform = vtkSmartPointer<vtkTransform>::New();
152 }
153 //------------------------------------------------------------------------------
154
155
156 //------------------------------------------------------------------------------
157 vtkImageMapToWindowLevelColors* vvSlicer::GetOverlayMapper()
158 {
159   return mOverlayMapper.GetPointer();
160 }
161 //------------------------------------------------------------------------------
162
163
164 //------------------------------------------------------------------------------
165 vvBlendImageActor* vvSlicer::GetOverlayActor()
166 {
167   return mOverlayActor.GetPointer();
168 }
169 //------------------------------------------------------------------------------
170
171
172 //------------------------------------------------------------------------------
173 vtkImageMapToColors* vvSlicer::GetFusionMapper()
174 {
175   return mFusionMapper.GetPointer();
176 }
177 //------------------------------------------------------------------------------
178
179
180 //------------------------------------------------------------------------------
181 vtkImageActor* vvSlicer::GetFusionActor()
182 {
183   return mFusionActor.GetPointer();
184 }
185 //------------------------------------------------------------------------------
186
187
188 //------------------------------------------------------------------------------
189 vtkActor* vvSlicer::GetVFActor()
190 {
191   return mVFActor.GetPointer();
192 }
193 //------------------------------------------------------------------------------
194
195
196 //------------------------------------------------------------------------------
197 vtkCornerAnnotation* vvSlicer::GetAnnotation()
198 {
199   return ca.GetPointer();
200 }
201 //------------------------------------------------------------------------------
202
203
204 //------------------------------------------------------------------------------
205 void vvSlicer::EnableReducedExtent(bool b)
206 {
207   mUseReducedExtent = b;
208 }
209 //------------------------------------------------------------------------------
210
211
212 //------------------------------------------------------------------------------
213 void vvSlicer::SetReducedExtent(int * ext)
214 {
215   copyExtent(ext, mReducedExtent);
216 }
217 //------------------------------------------------------------------------------
218
219
220 //------------------------------------------------------------------------------
221 void vvSlicer::AddContour(vvMesh::Pointer contour,bool propagate)
222 {
223
224   mSurfaceCutActors.push_back(new vvMeshActor());
225   if (propagate)
226     mSurfaceCutActors.back()->Init(contour,mCurrentTSlice,mVF);
227   else
228     mSurfaceCutActors.back()->Init(contour,mCurrentTSlice);
229   mSurfaceCutActors.back()->SetSlicingOrientation(SliceOrientation);
230   this->GetRenderer()->AddActor(mSurfaceCutActors.back()->GetActor());
231
232   SetContourSlice();
233 }
234 //------------------------------------------------------------------------------
235
236
237 //------------------------------------------------------------------------------
238 void vvSlicer::ToggleContourSuperposition()
239 {
240   for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
241        i!=mSurfaceCutActors.end(); i++)
242     (*i)->ToggleSuperposition();
243 }
244 //------------------------------------------------------------------------------
245
246
247 //------------------------------------------------------------------------------
248 void vvSlicer::SetCursorColor(int r,int g, int b)
249 {
250   pdmA->GetProperty()->SetColor(r,g,b);
251 }
252 //------------------------------------------------------------------------------
253
254
255 //------------------------------------------------------------------------------
256 void vvSlicer::SetCursorVisibility(bool s)
257 {
258   pdmA->SetVisibility(s);
259 }
260 //------------------------------------------------------------------------------
261
262
263 //------------------------------------------------------------------------------
264 bool vvSlicer::GetCursorVisibility()
265 {
266   return pdmA->GetVisibility();
267 }
268 //------------------------------------------------------------------------------
269
270
271 //------------------------------------------------------------------------------
272 void vvSlicer::SetCornerAnnotationVisibility(bool s)
273 {
274   ca->SetVisibility(s);
275 }
276 //------------------------------------------------------------------------------
277
278
279 //------------------------------------------------------------------------------
280 bool vvSlicer::GetCornerAnnotationVisibility()
281 {
282   return ca->GetVisibility();
283 }
284 //------------------------------------------------------------------------------
285
286
287 //------------------------------------------------------------------------------
288 vvSlicer::~vvSlicer()
289 {
290   for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
291        i!=mSurfaceCutActors.end(); i++)
292     delete (*i);
293   delete [] mReducedExtent;
294 }
295 //------------------------------------------------------------------------------
296
297 //------------------------------------------------------------------------------
298 double* vvSlicer::GetCurrentPosition()
299 {
300   return mCurrentBeforeSlicingTransform;
301 }
302 //------------------------------------------------------------------------------
303
304 //------------------------------------------------------------------------------
305 void vvSlicer::SetCurrentPosition(double x, double y, double z, int t)
306 {
307   mCurrentBeforeSlicingTransform[0]=x;
308   mCurrentBeforeSlicingTransform[1]=y;
309   mCurrentBeforeSlicingTransform[2]=z;
310   mSlicingTransform->GetInverse()->TransformPoint(mCurrentBeforeSlicingTransform,mCurrent);
311   SetTSlice(t);
312 }
313 //------------------------------------------------------------------------------
314
315
316 //------------------------------------------------------------------------------
317 void vvSlicer::SetImage(vvImage::Pointer image)
318 {
319   if (image->GetVTKImages().size()) {
320     mImage = image;
321
322     if (!mImageReslice) {
323       mImageReslice = vtkSmartPointer<vtkImageReslice>::New();
324       mImageReslice->SetInterpolationModeToLinear();
325       mImageReslice->AutoCropOutputOn();
326       mImageReslice->SetBackgroundColor(-1000,-1000,-1000,1);
327     }
328
329     mConcatenatedTransform->Identity();
330     mConcatenatedTransform->Concatenate(mImage->GetTransform()[0]);
331     mConcatenatedTransform->Concatenate(mSlicingTransform);
332     mImageReslice->SetResliceTransform(mConcatenatedTransform);
333     mImageReslice->SetInput(0, mImage->GetFirstVTKImageData());
334     mImageReslice->UpdateInformation();
335
336     this->Superclass::SetInput(mImageReslice->GetOutput());
337
338     int extent[6];
339     this->GetInput()->GetWholeExtent(extent);
340
341     // Prevent crash when reload -> change slice if outside extent
342     if (Slice < extent[SliceOrientation*2] || Slice>=extent[SliceOrientation*2+1]) {
343       Slice = (extent[SliceOrientation*2+1]+extent[SliceOrientation*2])/2.0;
344     }
345
346     // Make sure that the required part image has been computed
347     extent[SliceOrientation*2] = Slice;
348     extent[SliceOrientation*2+1] = Slice;
349     mImageReslice->GetOutput()->SetUpdateExtent(extent);
350     mImageReslice->GetOutput()->Update();
351
352     this->UpdateDisplayExtent();
353
354     mCurrentTSlice = 0;
355     ca->SetText(0,mFileName.c_str());
356   }
357 }
358 //------------------------------------------------------------------------------
359
360
361 //------------------------------------------------------------------------------
362 void vvSlicer::SetOverlay(vvImage::Pointer overlay)
363 {
364   if (overlay->GetVTKImages().size()) {
365     mOverlay = overlay;
366     
367     if (!mOverlayReslice) {
368       mOverlayReslice = vtkSmartPointer<vtkImageReslice>::New();
369       mOverlayReslice->SetInterpolationModeToLinear();
370       mOverlayReslice->AutoCropOutputOn();
371       mOverlayReslice->SetBackgroundColor(-1000,-1000,-1000,1);
372     }
373
374     mConcatenatedOverlayTransform->Identity();
375     mConcatenatedOverlayTransform->Concatenate(mOverlay->GetTransform()[0]);
376     mConcatenatedOverlayTransform->Concatenate(mSlicingTransform);
377     mOverlayReslice->SetResliceTransform(mConcatenatedOverlayTransform);
378     mOverlayReslice->SetInput(0, mOverlay->GetFirstVTKImageData());
379     mImageReslice->UpdateInformation();
380
381     if (!mOverlayMapper)
382       mOverlayMapper = vtkSmartPointer<vtkImageMapToWindowLevelColors>::New();
383     mOverlayMapper->SetInput(mOverlayReslice->GetOutput());
384
385     if (!mOverlayActor) {
386       mOverlayActor = vtkSmartPointer<vvBlendImageActor>::New();
387       mOverlayActor->SetInput(mOverlayMapper->GetOutput());
388       mOverlayActor->SetPickable(0);
389       mOverlayActor->SetVisibility(true);
390       mOverlayActor->SetOpacity(0.5);
391 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
392       mOverlayActor->GetMapper()->BorderOn();
393 #endif
394       }
395
396     //stupid but necessary : the Overlay need to be rendered before fusion
397     if (mFusionActor) {
398       this->GetRenderer()->RemoveActor(mFusionActor);
399       this->GetRenderer()->AddActor(mOverlayActor);
400       this->GetRenderer()->AddActor(mFusionActor);
401     } else
402       this->GetRenderer()->AddActor(mOverlayActor);
403
404     //Synchronize orientation and slice
405     AdjustResliceToSliceOrientation(mOverlayReslice);
406     this->UpdateDisplayExtent();
407     this->SetTSlice(mCurrentTSlice);
408   }
409 }
410 //------------------------------------------------------------------------------
411
412
413 //------------------------------------------------------------------------------
414 void vvSlicer::SetFusion(vvImage::Pointer fusion)
415 {
416   if (fusion->GetVTKImages().size()) {
417     mFusion = fusion;
418
419     if (!mFusionReslice) {
420       mFusionReslice = vtkSmartPointer<vtkImageReslice>::New();
421       mFusionReslice->SetInterpolationModeToLinear();
422       mFusionReslice->AutoCropOutputOn();
423       mFusionReslice->SetBackgroundColor(-1000,-1000,-1000,1);
424     }
425
426     mConcatenatedFusionTransform->Identity();
427     mConcatenatedFusionTransform->Concatenate(mFusion->GetTransform()[0]);
428     mConcatenatedFusionTransform->Concatenate(mSlicingTransform);
429     mFusionReslice->SetResliceTransform(mConcatenatedFusionTransform);
430     mFusionReslice->SetInput(0, mFusion->GetFirstVTKImageData());
431     mFusionReslice->UpdateInformation();
432
433     if (!mFusionMapper)
434       mFusionMapper = vtkSmartPointer<vtkImageMapToColors>::New();
435
436     vtkSmartPointer<vtkLookupTable> lut = vtkLookupTable::New();
437     lut->SetRange(0, 1);
438     lut->SetValueRange(0, 1);
439     lut->SetSaturationRange(0, 0);
440     lut->Build();
441     mFusionMapper->SetLookupTable(lut);
442     mFusionMapper->SetInput(mFusionReslice->GetOutput());
443
444     if (!mFusionActor) {
445       mFusionActor = vtkSmartPointer<vtkImageActor>::New();
446       mFusionActor->SetInput(mFusionMapper->GetOutput());
447       mFusionActor->SetPickable(0);
448       mFusionActor->SetVisibility(true);
449       mFusionActor->SetOpacity(0.7);
450 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
451       mFusionActor->GetMapper()->BorderOn();
452 #endif
453       this->GetRenderer()->AddActor(mFusionActor);
454     }
455
456     //Synchronize orientation and slice
457     AdjustResliceToSliceOrientation(mFusionReslice);
458     this->UpdateDisplayExtent();
459     this->SetTSlice(mCurrentTSlice);
460   }
461 }
462 //------------------------------------------------------------------------------
463
464
465 //------------------------------------------------------------------------------
466 bool vvSlicer::GetActorVisibility(const std::string& actor_type, int overlay_index)
467 {
468   bool vis = false;
469   if (actor_type == "image") {
470     vis = this->ImageActor->GetVisibility();
471   }
472   else if (actor_type == "vector") {
473     vis = this->mVFActor->GetVisibility();
474   }
475   else if (actor_type == "overlay") {
476     vis = this->mOverlayActor->GetVisibility();
477   }
478   else if (actor_type == "fusion") {
479     vis = this->mFusionActor->GetVisibility();
480   }
481   else if (actor_type == "contour")
482     vis = this->mSurfaceCutActors[overlay_index]->GetActor()->GetVisibility();
483
484   return vis;
485 }
486 //------------------------------------------------------------------------------
487
488 //------------------------------------------------------------------------------
489 void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis)
490 {
491   if (actor_type == "image") {
492     this->ImageActor->SetVisibility(vis);
493   }
494   else if (actor_type == "vector") {
495     this->mVFActor->SetVisibility(vis);
496   }
497   else if (actor_type == "overlay") {
498     this->mOverlayActor->SetVisibility(vis);
499   }
500   else if (actor_type == "fusion") {
501     this->mFusionActor->SetVisibility(vis);
502   }
503   else if (actor_type == "contour")
504     this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis);
505   UpdateDisplayExtent();
506 }
507 //------------------------------------------------------------------------------
508
509 //------------------------------------------------------------------------------
510 void vvSlicer::SetVF(vvImage::Pointer vf)
511 {
512   if (vf->GetVTKImages().size()) {
513     mVF = vf;
514
515     if (!mAAFilter) {
516       mAAFilter= vtkSmartPointer<vtkAssignAttribute>::New();
517       mVOIFilter = vtkSmartPointer<vtkExtractVOI>::New();
518       mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
519     }
520     mVOIFilter->SetInput(vf->GetFirstVTKImageData());
521     mAAFilter->SetInput(mVOIFilter->GetOutput());
522     ///This tells VTK to use the scalar (pixel) data of the image to draw the little arrows
523     mAAFilter->Assign(vtkDataSetAttributes::SCALARS, vtkDataSetAttributes::VECTORS, vtkAssignAttribute::POINT_DATA);
524
525     if (!mArrow)
526       mArrow = vtkSmartPointer<vvGlyphSource>::New();
527     mArrow->SetGlyphTypeToSpecificArrow();
528     mArrow->SetScale(mScale);
529     mArrow->FilledOff();
530
531     // Glyph the gradient vector (with arrows)
532     if (!mGlyphFilter)
533       mGlyphFilter = vtkSmartPointer<vvGlyph2D>::New();
534     mGlyphFilter->SetInput(mAAFilter->GetOutput());
535     mGlyphFilter->SetSource(mArrow->GetOutput());
536     mGlyphFilter->ScalingOn();
537     mGlyphFilter->SetScaleModeToScaleByVector();
538     mGlyphFilter->OrientOn();
539     mGlyphFilter->SetVectorModeToUseVector();
540     mGlyphFilter->SetColorModeToColorByVector();
541
542     if (!mVFColorLUT)
543       mVFColorLUT = vtkSmartPointer<vtkLookupTable>::New();
544
545     double mVFColorHSV[3];
546     vtkMath::RGBToHSV(mVFColor, mVFColorHSV);
547     mVFColorLUT->SetHueRange(mVFColorHSV[0], mVFColorHSV[0]);
548     mVFColorLUT->SetSaturationRange(mVFColorHSV[1],mVFColorHSV[1]);
549     mVFColorLUT->SetValueRange(mVFColorHSV[2], mVFColorHSV[2]);
550
551     if (!mVFMapper)
552       mVFMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
553     mVFMapper->SetInput(mGlyphFilter->GetOutput());
554     mVFMapper->ImmediateModeRenderingOn();
555     mVFMapper->SetLookupTable(mVFColorLUT);
556
557     if (!mVFActor)
558       mVFActor = vtkSmartPointer<vtkActor>::New();
559     mVFActor->SetMapper(mVFMapper);
560     mVFActor->SetPickable(0);
561     mVFActor->GetProperty()->SetLineWidth(mVFWidth);
562     this->UpdateDisplayExtent();
563     this->GetRenderer()->AddActor(mVFActor);
564
565     //Synchronize slice
566     SetTSlice(mCurrentTSlice);
567   }
568 }
569 //------------------------------------------------------------------------------
570
571
572 //------------------------------------------------------------------------------
573 void vvSlicer::SetLandmarks(vvLandmarks* landmarks)
574 {
575   mLandmarks = landmarks;
576   if (landmarks) {
577
578     if (!mCross)
579       mCross = vtkSmartPointer<vtkCursor3D>::New();
580         if (!mClipBox)
581       mClipBox = vtkSmartPointer<vtkBox>::New();
582     if (!mLandClipper)
583       mLandClipper = vtkSmartPointer<vvClipPolyData>::New();
584     if (!mLandGlyph)
585       mLandGlyph = vtkSmartPointer<vtkGlyph3D>::New();
586     if (!mLandMapper)
587       mLandMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
588     if (!mLandActor)
589       mLandActor = vtkSmartPointer<vtkActor>::New();
590
591     mCross->SetFocalPoint(0.0,0.0,0.0);
592     mCross->SetModelBounds(-10,10,-10,10,-10,10);
593     mCross->AllOff();
594     mCross->AxesOn();
595
596     mLandClipper->SetClipFunction(mClipBox);
597     mLandClipper->InsideOutOn();
598     mLandClipper->SetInput(mLandmarks->GetOutput());
599
600     mLandGlyph->SetSource(mCross->GetOutput());
601     mLandGlyph->SetInput(mLandClipper->GetOutput());
602     //mLandGlyph->SetIndexModeToScalar();
603     //mLandGlyph->SetRange(0,1);
604     //mLandGlyph->ScalingOff();
605
606     //mLandGlyph->SetColorModeToColorByScalar();
607     
608     mLandGlyph->SetScaleModeToDataScalingOff();
609     mLandGlyph->SetIndexModeToOff();
610
611     mLandMapper->SetInputConnection(mLandGlyph->GetOutputPort());
612     //mLandMapper->ScalarVisibilityOff();
613
614     mLandActor->SetMapper(mLandMapper);
615     mLandActor->GetProperty()->SetColor(255,10,212);
616     mLandActor->SetPickable(0);
617     mLandActor->SetVisibility(true);
618     this->UpdateDisplayExtent();
619     this->GetRenderer()->AddActor(mLandActor);
620   }
621 }
622 //------------------------------------------------------------------------------
623
624 //------------------------------------------------------------------------------
625 //FIXME: this function leaks memory, we should fix it someday :)
626 void vvSlicer::RemoveActor(const std::string& actor_type, int overlay_index)
627 {
628   if (actor_type == "vector") {
629     Renderer->RemoveActor(mVFActor);
630     mGlyphFilter=NULL;
631     mVF = NULL;
632     mArrow = NULL;
633     mAAFilter=NULL;
634     mVOIFilter = NULL;
635     mVFMapper = NULL;
636     mVFActor = NULL;
637   }
638   if (actor_type == "overlay") {
639     Renderer->RemoveActor(mOverlayActor);
640     mOverlay = NULL;
641     mOverlayActor = NULL;
642     mOverlayMapper = NULL;
643   }
644   if (actor_type == "fusion") {
645     Renderer->RemoveActor(mFusionActor);
646     mFusion = NULL;
647     mFusionActor = NULL;
648     mFusionMapper = NULL;
649   }
650   if (actor_type == "contour") {
651     Renderer->RemoveActor(this->mSurfaceCutActors[overlay_index]->GetActor());
652     mSurfaceCutActors.erase(mSurfaceCutActors.begin()+overlay_index);
653   }
654 }
655 //------------------------------------------------------------------------------
656
657
658 //------------------------------------------------------------------------------
659 void vvSlicer::SetVFSubSampling(int sub)
660 {
661   if (mVOIFilter) {
662     mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
663     mSubSampling = sub;
664   }
665   UpdateDisplayExtent();
666   Render();
667 }
668 //------------------------------------------------------------------------------
669
670
671 //------------------------------------------------------------------------------
672 void vvSlicer::SetVFScale(int scale)
673 {
674   mScale = scale;
675   if (mArrow)
676     mArrow->SetScale(mScale);
677   UpdateDisplayExtent();
678   Render();
679 }
680 //------------------------------------------------------------------------------
681
682 //------------------------------------------------------------------------------
683 void vvSlicer::SetVFWidth(int width)
684 {
685   mVFWidth = width;
686   if (mVFActor)
687     mVFActor->GetProperty()->SetLineWidth(mVFWidth);
688   UpdateDisplayExtent();
689   Render();
690 }
691 //------------------------------------------------------------------------------
692
693
694 //------------------------------------------------------------------------------
695 void vvSlicer::SetVFLog(int log)
696 {
697   mVFLog = log;
698   if (mGlyphFilter) {
699     mGlyphFilter->SetUseLog(mVFLog);
700     mGlyphFilter->Modified();
701   }
702   UpdateDisplayExtent();
703   Render();
704 }
705 //------------------------------------------------------------------------------
706
707
708 //------------------------------------------------------------------------------
709 void vvSlicer::SetTSlice(int t)
710 {
711   if (t < 0)
712     mCurrentTSlice = 0;
713   else if ((unsigned int)t >= mImage->GetVTKImages().size())
714     mCurrentTSlice = mImage->GetVTKImages().size() -1;
715   else
716     mCurrentTSlice = t;
717
718   // Update transform
719   mConcatenatedTransform->Identity();
720   mConcatenatedTransform->Concatenate(mImage->GetTransform()[mCurrentTSlice]);
721   mConcatenatedTransform->Concatenate(mSlicingTransform);
722
723   // Update image data
724   mImageReslice->SetInput( mImage->GetVTKImages()[mCurrentTSlice] );
725   if (mVF && mVFActor->GetVisibility()) {
726     if (mVF->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
727       mVOIFilter->SetInput(mVF->GetVTKImages()[mCurrentTSlice]);
728   }
729   if (mOverlay && mOverlayActor->GetVisibility()) {
730     if (mOverlay->GetVTKImages().size() > (unsigned int)t) {
731       mCurrentOverlayTSlice = t;
732       mOverlayReslice->SetInput( mOverlay->GetVTKImages()[mCurrentOverlayTSlice] );
733
734       // Update overlay transform
735       mConcatenatedOverlayTransform->Identity();
736       mConcatenatedOverlayTransform->Concatenate(mOverlay->GetTransform()[mCurrentOverlayTSlice]);
737       mConcatenatedOverlayTransform->Concatenate(mSlicingTransform);
738     }
739   }
740   if (mFusion && mFusionActor->GetVisibility()) {
741     if (mFusion->GetVTKImages().size() > (unsigned int)t) {
742       mCurrentFusionTSlice = t;
743       mFusionReslice->SetInput( mFusion->GetVTKImages()[mCurrentFusionTSlice]);
744
745       // Update fusion transform
746       mConcatenatedFusionTransform->Identity();
747       mConcatenatedFusionTransform->Concatenate(mFusion->GetTransform()[mCurrentFusionTSlice]);
748       mConcatenatedFusionTransform->Concatenate(mSlicingTransform);
749     }
750   }
751   if (mSurfaceCutActors.size() > 0)
752     for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
753          i!=mSurfaceCutActors.end(); i++)
754       (*i)->SetTimeSlice(mCurrentTSlice);
755   UpdateDisplayExtent();
756 }
757 //------------------------------------------------------------------------------
758
759
760 //------------------------------------------------------------------------------
761 int vvSlicer::GetTSlice()
762 {
763   return mCurrentTSlice;
764 }
765 //------------------------------------------------------------------------------
766
767 //------------------------------------------------------------------------------
768 int vvSlicer::GetMaxCurrentTSlice()
769 {
770   int t = mCurrentTSlice;
771   if(mOverlay)
772     t = std::max(t, mCurrentOverlayTSlice);
773   if(mFusion)
774     t = std::max(t, mCurrentFusionTSlice);
775   return t;
776 }
777 //------------------------------------------------------------------------------
778
779 //------------------------------------------------------------------------------
780 int vvSlicer::GetFusionTSlice()
781 {
782   return mCurrentFusionTSlice;
783 }
784 //------------------------------------------------------------------------------
785
786 //------------------------------------------------------------------------------
787 int vvSlicer::GetOverlayTSlice()
788 {
789   return mCurrentOverlayTSlice;
790 }
791 //------------------------------------------------------------------------------
792
793 //------------------------------------------------------------------------------
794 void vvSlicer::SetSliceOrientation(int orientation)
795 {
796   //if 2D image, force to watch in Axial View
797   int extent[6];
798   this->GetInput()->GetWholeExtent(extent);
799   if (extent[5]-extent[4] <= 2)
800     orientation = vtkImageViewer2::SLICE_ORIENTATION_XY;
801
802   if (orientation < vtkImageViewer2::SLICE_ORIENTATION_YZ ||
803       orientation > vtkImageViewer2::SLICE_ORIENTATION_XY) {
804     vtkErrorMacro("Error - invalid slice orientation " << orientation);
805     return;
806   }
807   
808   this->SliceOrientation = orientation;
809
810   if(mFusion)
811     AdjustResliceToSliceOrientation(mFusionReslice);
812
813   if(mOverlay)
814     AdjustResliceToSliceOrientation(mOverlayReslice);
815
816   // Update the viewer
817   
818   // Go to current cursor position
819   // double* cursorPos = GetCursorPosition();
820   // DDV(cursorPos, 3);
821   // SetCurrentPosition(cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]);
822
823   if (this->Renderer && this->GetInput()) {
824     double s = mCursor[orientation];
825     double sCursor = (s - this->GetInput()->GetOrigin()[orientation])/this->GetInput()->GetSpacing()[orientation];
826     this->Slice = static_cast<int>(sCursor);
827   }
828   
829 //   int *range = this->GetSliceRange();
830 //   if (range)
831 //     this->Slice = static_cast<int>((range[0] + range[1]) * 0.5);
832
833   this->UpdateOrientation();
834   this->UpdateDisplayExtent();
835
836   if (this->Renderer && this->GetInput()) {
837     double scale = this->Renderer->GetActiveCamera()->GetParallelScale();
838     this->Renderer->ResetCamera();
839     this->Renderer->GetActiveCamera()->SetParallelScale(scale);
840   }
841
842   SetContourSlice();
843 }
844 //----------------------------------------------------------------------------
845
846 //------------------------------------------------------------------------------
847 // This function ensures that we sample the slices of a vtkImageReslice filter
848 // in the direction of the slicer (SliceOrientation) similarly as mImageReslice.
849 // In other words, we change the grid of the reslice in the same way as the grid
850 // of the displayed image in the slicing direction.
851 void vvSlicer::AdjustResliceToSliceOrientation(vtkImageReslice *reslice)
852 {
853   // Reset autocrop and update output information
854   reslice->SetOutputOriginToDefault();
855   reslice->SetOutputSpacingToDefault();
856   reslice->GetOutput()->UpdateInformation();
857
858   // Ge new origin / spacing
859   double origin[3];
860   double spacing[3];
861   reslice->GetOutput()->GetOrigin(origin);
862   reslice->GetOutput()->GetSpacing(spacing);
863
864   // Use similar spacing as the image in the direction SliceOrientation
865   spacing[this->SliceOrientation] = mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation];
866
867   // Modify origin to be on the image grid in the direction SliceOrientation in 3 steps
868   // Step 1: from world coordinates to image coordinates
869   origin[this->SliceOrientation] -= mImageReslice->GetOutput()->GetOrigin()[this->SliceOrientation];
870   origin[this->SliceOrientation] /= mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation];
871   // Step 2: round to superior grid positionInc
872   origin[this->SliceOrientation] = itk::Math::Ceil<double>(origin[this->SliceOrientation]);
873   // Step 3: back to world coordinates
874   origin[this->SliceOrientation] *= mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation];
875   origin[this->SliceOrientation] += mImageReslice->GetOutput()->GetOrigin()[this->SliceOrientation];
876
877   // Set new spacing and origin
878   reslice->SetOutputOrigin(origin);
879   reslice->SetOutputSpacing(spacing);
880   reslice->UpdateInformation();
881   reslice->GetOutput()->UpdateInformation();
882 }
883 //------------------------------------------------------------------------------
884
885 //----------------------------------------------------------------------------
886 int * vvSlicer::GetExtent(){
887   int *w_ext;
888   if (mUseReducedExtent) {
889     w_ext = mReducedExtent;
890   } else w_ext = GetInput()->GetWholeExtent();
891   return w_ext;
892 }
893 //----------------------------------------------------------------------------
894
895
896 //----------------------------------------------------------------------------
897 int vvSlicer::GetOrientation()
898 {
899   return this->SliceOrientation;
900 }
901 //----------------------------------------------------------------------------
902
903
904 //----------------------------------------------------------------------------
905 void vvSlicer::UpdateDisplayExtent()
906 {
907   vtkImageData *input = this->GetInput();
908   if (!input || !this->ImageActor) {
909     return;
910   }
911   input->UpdateInformation();
912   this->SetSlice( this->GetSlice() ); //SR: make sure the update let the slice in extents
913
914   // Local copy of extent
915   int w_ext[6];
916   int* ext = GetExtent();
917   copyExtent(ext, w_ext);
918   // Set slice value
919   w_ext[ this->SliceOrientation*2   ] = this->Slice;
920   w_ext[ this->SliceOrientation*2+1 ] = this->Slice;
921   
922   // Image actor
923   this->ImageActor->SetDisplayExtent(w_ext);
924   
925   // Overlay image actor
926   if (mOverlay && mOverlayActor->GetVisibility()) {
927     AdjustResliceToSliceOrientation(mOverlayReslice);
928     int overExtent[6];
929     this->ConvertImageToImageDisplayExtent(input, w_ext, mOverlayReslice->GetOutput(), overExtent);
930     ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
931     mOverlayActor->SetDisplayExtent( overExtent );
932   }
933
934   // Fusion image actor
935   if (mFusion && mFusionActor->GetVisibility()) {
936     AdjustResliceToSliceOrientation(mFusionReslice);
937     int fusExtent[6];
938     this->ConvertImageToImageDisplayExtent(input, w_ext, mFusionReslice->GetOutput(), fusExtent);
939     ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
940     mFusionActor->SetDisplayExtent(fusExtent);
941   }
942
943   // Vector field actor
944   double* camera = Renderer->GetActiveCamera()->GetPosition();
945   double* image_bounds = ImageActor->GetBounds();
946   double position[3] = {0, 0, 0};
947   position[this->SliceOrientation] = image_bounds[this->SliceOrientation*2]; 
948
949   //print_vector<double, 6>("camera", camera);
950   //print_vector<double, 6>("image_bounds", image_bounds);
951   //print_vector<double, 3>("position", position);
952
953   // find where to place the VF actor. to deal with
954   // z-buffer issues, the VF is placed right in front of the image,
955   // subject to a small offset. the position actually depends on the
956   // the location of the camera relative to the image. 
957   double offset = 1;
958   if (camera[this->SliceOrientation] < image_bounds[this->SliceOrientation*2])
959     offset = -1;
960   
961   if (mVF && mVFActor->GetVisibility()) {
962     int vfExtent[6];
963     mVF->GetVTKImages()[0]->UpdateInformation();
964     this->ConvertImageToImageDisplayExtent(input, w_ext, mVF->GetVTKImages()[0], vfExtent);
965     ClipDisplayedExtent(vfExtent, mVOIFilter->GetInput()->GetWholeExtent());
966     mVOIFilter->SetVOI(vfExtent);
967     int orientation[3] = {1,1,1};
968     orientation[this->SliceOrientation] = 0;
969     mGlyphFilter->SetOrientation(orientation[0], orientation[1], orientation[2]);
970     mVFMapper->Update();
971
972     position[this->SliceOrientation] += offset;
973     mVFActor->SetPosition(position);
974   }
975   
976   // Landmarks actor
977   if (mLandActor) {
978     if (mClipBox) {
979       double bounds [6];
980       for(unsigned int i=0; i<6; i++)
981         bounds[i] = ImageActor->GetBounds()[i];
982       bounds[ this->SliceOrientation*2   ] = ImageActor->GetBounds()[ this->SliceOrientation*2  ]-fabs(this->GetInput()->GetSpacing()[this->SliceOrientation]);
983       bounds[ this->SliceOrientation*2+1 ] = ImageActor->GetBounds()[ this->SliceOrientation*2+1 ]+fabs(this->GetInput()->GetSpacing()[this->SliceOrientation]);
984       mClipBox->SetBounds(bounds);
985       UpdateLandmarks();
986     }
987     
988     position[this->SliceOrientation] = offset;
989     mLandActor->SetPosition(position);
990   }
991
992   // Figure out the correct clipping range
993   if (this->Renderer) {
994     if (this->InteractorStyle &&
995         this->InteractorStyle->GetAutoAdjustCameraClippingRange()) {
996       this->Renderer->ResetCameraClippingRange();
997     } else {
998       vtkCamera *cam = this->Renderer->GetActiveCamera();
999       if (cam) {
1000         double bounds[6];
1001         this->ImageActor->GetBounds(bounds);
1002         double spos = (double)bounds[this->SliceOrientation * 2];
1003         double cpos = (double)cam->GetPosition()[this->SliceOrientation];
1004         double range = fabs(spos - cpos);
1005         double *spacing = input->GetSpacing();
1006         double sumSpacing = spacing[0] + spacing[1] + spacing[2];
1007         cam->SetClippingRange(range - sumSpacing, range + sumSpacing);
1008       }
1009     }
1010   }
1011   
1012 }
1013 //----------------------------------------------------------------------------
1014
1015 //----------------------------------------------------------------------------
1016 void vvSlicer::ConvertImageToImageDisplayExtent(vtkImageData *sourceImage, const int sourceExtent[6],
1017                                                 vtkImageData *targetImage, int targetExtent[6])
1018 {
1019   double dExtents[6];
1020   for(unsigned int i=0; i<6; i++) {
1021     // From source voxel coordinates to world coordinates
1022     dExtents[i] = sourceImage->GetOrigin()[i/2] + sourceImage->GetSpacing()[i/2] * sourceExtent[i];
1023
1024     // From world coordinates to floating point target voxel coordinates
1025     dExtents[i] = (dExtents[i]- targetImage->GetOrigin()[i/2]) / targetImage->GetSpacing()[i/2];
1026     
1027     // Round to nearest
1028     //targetExtent[i] = itk::Math::Round<double>(dExtents[i]);
1029     targetExtent[i] = itk::Math::Floor<double>(dExtents[i]);
1030   }
1031 }
1032 //----------------------------------------------------------------------------
1033
1034 //----------------------------------------------------------------------------
1035 void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
1036 {
1037   bool out = false;
1038   int maxBound = 6;
1039
1040   //2D overlay on 3D image specific case
1041   if (refExtent[4] == refExtent[5]) {
1042     maxBound = 4;
1043     extent[4] = refExtent[4];
1044     extent[5] = refExtent[5];
1045   }
1046
1047   for (int i = 0; i < maxBound; i = i+2) {
1048     //if we are totally outside the image
1049     if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] ) {
1050       out = true;
1051       break;
1052     }
1053     //crop to the limit of the image
1054     extent[i] = (extent[i] > refExtent[i]) ? extent[i] : refExtent[i];
1055     extent[i] = (extent[i] < refExtent[i+1]) ? extent[i] : refExtent[i+1];
1056     extent[i+1] = (extent[i+1] > refExtent[i]) ? extent[i+1] : refExtent[i];
1057     extent[i+1] = (extent[i+1] < refExtent[i+1]) ? extent[i+1] : refExtent[i+1];
1058   }
1059   if (out)
1060     for (int i = 0; i < maxBound; i = i+2) {
1061       extent[i] = refExtent[i];
1062       extent[i+1] = refExtent[i];
1063     }
1064 }
1065 //----------------------------------------------------------------------------
1066
1067
1068 //----------------------------------------------------------------------------
1069 void vvSlicer::UpdateOrientation()
1070 {
1071   // Set the camera position
1072   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1073   if (cam) {
1074     switch (this->SliceOrientation) {
1075     case vtkImageViewer2::SLICE_ORIENTATION_XY:
1076       cam->SetFocalPoint(0,0,0);
1077       cam->SetPosition(0,0,-1); // -1 if medical ?
1078       cam->SetViewUp(0,-1,0);
1079       break;
1080
1081     case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1082       cam->SetFocalPoint(0,0,0);
1083       cam->SetPosition(0,-1,0); // 1 if medical ?
1084       cam->SetViewUp(0,0,1);
1085       break;
1086
1087     case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1088       cam->SetFocalPoint(0,0,0);
1089       cam->SetPosition(-1,0,0); // -1 if medical ?
1090       cam->SetViewUp(0,0,1);
1091       break;
1092     }
1093   }
1094 }
1095 //----------------------------------------------------------------------------
1096
1097
1098 //----------------------------------------------------------------------------
1099 void vvSlicer::SetOpacity(double s)
1100 {
1101   this->GetImageActor()->SetOpacity(s);
1102 }
1103 //----------------------------------------------------------------------------
1104
1105
1106 //----------------------------------------------------------------------------
1107 void vvSlicer::SetRenderWindow(int orientation, vtkRenderWindow * rw)
1108 {
1109   this->Superclass::SetRenderWindow(rw);
1110   this->SetupInteractor(rw->GetInteractor());
1111   ca->SetImageActor(this->GetImageActor());
1112   ca->SetWindowLevel(this->GetWindowLevel());
1113   ca->SetText(2, "<slice>");
1114   ca->SetText(3, "<window>\n<level>");
1115
1116   double bounds[6];
1117   double max = 65000;
1118
1119   bounds[0] = -max;
1120   bounds[1] = max;
1121   bounds[2] = -max;
1122   bounds[3] = max;
1123   bounds[4] = -max;
1124   bounds[5] = max;
1125
1126   crossCursor->SetModelBounds(bounds);
1127   this->GetRenderer()->AddActor(pdmA);
1128   this->GetRenderer()->AddActor(ca);
1129   this->GetRenderer()->ResetCamera();
1130
1131   //this is just a mapping between the labeling of the orientations presented to the user and
1132   //the one used by vtk
1133   SetSliceOrientation(2-(orientation%3));
1134   ResetCamera();
1135 }
1136 //----------------------------------------------------------------------------
1137
1138
1139 //----------------------------------------------------------------------------
1140 void vvSlicer::ResetCamera()
1141 {
1142   this->GetRenderer()->ResetCamera();
1143 }
1144 //----------------------------------------------------------------------------
1145
1146
1147 //----------------------------------------------------------------------------
1148 void vvSlicer::SetDisplayMode(bool i)
1149 {
1150   this->GetRenderer()->SetDraw(i);
1151   if (i)
1152     UpdateDisplayExtent();
1153 }
1154 //----------------------------------------------------------------------------
1155
1156
1157 //----------------------------------------------------------------------------
1158 void vvSlicer::FlipHorizontalView()
1159 {
1160   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1161   if (cam) {
1162     double *position = cam->GetPosition();
1163     double factor[3] = {1, 1, 1};
1164     factor[this->SliceOrientation] = -1;
1165     cam->SetPosition(factor[0]*position[0],factor[1]*position[1],factor[2]*position[2]);
1166     
1167 /*    switch (this->SliceOrientation) {
1168     case vtkImageViewer2::SLICE_ORIENTATION_XY:
1169       cam->SetPosition(position[0],position[1],-position[2]);
1170       break;
1171
1172     case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1173       cam->SetPosition(position[0],-position[1],position[2]);
1174       break;
1175
1176     case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1177       cam->SetPosition(-position[0],position[1],position[2]);
1178       break;
1179     }*/
1180
1181     this->Renderer->ResetCameraClippingRange();
1182     this->UpdateDisplayExtent();
1183   }
1184 }
1185 //----------------------------------------------------------------------------
1186
1187
1188 //----------------------------------------------------------------------------
1189 void vvSlicer::FlipVerticalView()
1190 {
1191   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1192   if (cam) {
1193     FlipHorizontalView();
1194     double *viewup = cam->GetViewUp();
1195     cam->SetViewUp(-viewup[0],-viewup[1],-viewup[2]);
1196     this->UpdateDisplayExtent();
1197   }
1198 }
1199 //----------------------------------------------------------------------------
1200
1201
1202 //----------------------------------------------------------------------------
1203 void vvSlicer::SetColorWindow(double window)
1204 {
1205   vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1206   if ( LUT ) {
1207     double level = this->GetWindowLevel()->GetLevel();
1208     LUT->SetTableRange(level-fabs(window)/2,level+fabs(window)/2);
1209     LUT->Build();
1210   }
1211   this->vtkImageViewer2::SetColorWindow(window);
1212 }
1213 //----------------------------------------------------------------------------
1214
1215 //----------------------------------------------------------------------------
1216 void vvSlicer::SetColorLevel(double level)
1217 {
1218   vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1219   if ( LUT ) {
1220     double window = this->GetWindowLevel()->GetWindow();
1221     LUT->SetTableRange(level-fabs(window)/2,level+fabs(window)/2);
1222     LUT->Build();
1223   }
1224   this->vtkImageViewer2::SetColorLevel(level);
1225 }
1226 //----------------------------------------------------------------------------
1227
1228 //----------------------------------------------------------------------------
1229 double vvSlicer::GetOverlayColorWindow()
1230 {
1231   if(mOverlayMapper)
1232     return mOverlayMapper->GetWindow();
1233   else
1234     return 0.;
1235 }
1236 //----------------------------------------------------------------------------
1237
1238 //----------------------------------------------------------------------------
1239 double vvSlicer::GetOverlayColorLevel()
1240 {
1241   if(mOverlayMapper)
1242     return mOverlayMapper->GetLevel();
1243   else
1244     return 0.;
1245 }
1246 //----------------------------------------------------------------------------
1247
1248 //----------------------------------------------------------------------------
1249 void vvSlicer::SetOverlayColorWindow(double window)
1250 {
1251   mOverlayMapper->SetWindow(window);
1252 }
1253 //----------------------------------------------------------------------------
1254
1255 //----------------------------------------------------------------------------
1256 void vvSlicer::SetOverlayColorLevel(double level)
1257 {
1258   mOverlayMapper->SetLevel(level);
1259 }
1260 //----------------------------------------------------------------------------
1261
1262 //----------------------------------------------------------------------------
1263 // Returns the min an the max value in a 20%x20% region around the mouse pointer
1264 void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image, vtkTransform *transform)
1265 {
1266   //Get mouse pointer position in view coordinates
1267   double corner1[3];
1268   double corner2[3];
1269   for(int i=0; i<3; i++) {
1270     corner1[i] = mCurrent[i];
1271     corner2[i] = mCurrent[i];
1272   }
1273
1274   this->Renderer->WorldToView(corner1[0], corner1[1], corner1[2]);
1275   this->Renderer->WorldToView(corner2[0], corner2[1], corner2[2]);
1276
1277   // In view coordinates, x is the slicer width and y is the slicer height are the in-plane axis
1278   int w, h;
1279   this->Renderer->GetTiledSize(&w, &h);
1280   corner1[0] -= 0.2*h/(double)w;
1281   corner2[0] += 0.2*h/(double)w;
1282   corner1[1] -= 0.2;
1283   corner2[1] += 0.2;
1284   this->Renderer->ViewToWorld(corner1[0], corner1[1], corner1[2]);
1285   this->Renderer->ViewToWorld(corner2[0], corner2[1], corner2[2]);
1286
1287   //Convert to image pixel coordinates (rounded)
1288   transform->TransformPoint(corner1, corner1);
1289   transform->TransformPoint(corner2, corner2);
1290   int iLocalExtents[6];
1291   for(int i=0; i<3; i++) {
1292     corner1[i] = (corner1[i] - image->GetOrigin()[i])/image->GetSpacing()[i];
1293     corner2[i] = (corner2[i] - image->GetOrigin()[i])/image->GetSpacing()[i];
1294
1295     iLocalExtents[i*2  ] = lrint(corner1[i]);
1296     iLocalExtents[i*2+1] = lrint(corner2[i]);
1297
1298     if(iLocalExtents[i*2  ]>iLocalExtents[i*2+1])
1299       std::swap(iLocalExtents[i*2], iLocalExtents[i*2+1]);
1300   }
1301
1302   vtkSmartPointer<vtkExtractVOI> voiFilter = vtkSmartPointer<vtkExtractVOI>::New();
1303   voiFilter->SetInput(image);
1304   voiFilter->SetVOI(iLocalExtents);
1305   voiFilter->Update();
1306   if (!voiFilter->GetOutput()->GetNumberOfPoints()) {
1307     min = 0;
1308     max = 0;
1309     return;
1310   }
1311
1312   vtkSmartPointer<vtkImageAccumulate> accFilter = vtkSmartPointer<vtkImageAccumulate>::New();
1313   accFilter->SetInput(voiFilter->GetOutput());
1314   accFilter->Update();
1315
1316   min = *(accFilter->GetMin());
1317   max = *(accFilter->GetMax());
1318 }
1319 //----------------------------------------------------------------------------
1320
1321 //----------------------------------------------------------------------------
1322 double vvSlicer::GetScalarComponentAsDouble(vtkImageData *image, double X, double Y, double Z, int &ix, int &iy, int &iz, int component)
1323 {
1324   ix = lrint(X);
1325   iy = lrint(Y);
1326   iz = lrint(Z);
1327   if (ix < image->GetWholeExtent()[0] ||
1328       ix > image->GetWholeExtent()[1] ||
1329       iy < image->GetWholeExtent()[2] ||
1330       iy > image->GetWholeExtent()[3] ||
1331       iz < image->GetWholeExtent()[4] ||
1332       iz > image->GetWholeExtent()[5] )
1333     return std::numeric_limits<double>::quiet_NaN();
1334
1335   image->SetUpdateExtent(ix, ix, iy, iy, iz, iz);
1336   image->Update();
1337   return image->GetScalarComponentAsDouble(ix, iy, iz, component);
1338 }
1339 //----------------------------------------------------------------------------
1340
1341 //----------------------------------------------------------------------------
1342 void vvSlicer::Render()
1343 {
1344   if (this->mFusion && mFusionActor->GetVisibility() && showFusionLegend) {
1345     legend->SetLookupTable(this->GetFusionMapper()->GetLookupTable());
1346     legend->UseOpacityOn();
1347     legend->SetVisibility(1);
1348   }
1349   else if (this->GetWindowLevel()->GetLookupTable() && !this->mOverlay)  {
1350     legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable());
1351     legend->UseOpacityOff();
1352     legend->SetVisibility(1);
1353   } else legend->SetVisibility(0);
1354
1355   if (ca->GetVisibility()) {
1356     std::stringstream worldPos;
1357     double pt[3];
1358     mConcatenatedTransform->TransformPoint(mCurrent, pt);
1359     double X = (pt[0] - mImage->GetVTKImages()[mCurrentTSlice]->GetOrigin()[0])/mImage->GetVTKImages()[mCurrentTSlice]->GetSpacing()[0];
1360     double Y = (pt[1] - mImage->GetVTKImages()[mCurrentTSlice]->GetOrigin()[1])/mImage->GetVTKImages()[mCurrentTSlice]->GetSpacing()[1];
1361     double Z = (pt[2] - mImage->GetVTKImages()[mCurrentTSlice]->GetOrigin()[2])/mImage->GetVTKImages()[mCurrentTSlice]->GetSpacing()[2];
1362
1363     if (X >= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[0]-0.5 &&
1364         X <= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[1]+0.5 &&
1365         Y >= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[2]-0.5 &&
1366         Y <= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[3]+0.5 &&
1367         Z >= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[4]-0.5 &&
1368         Z <= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[5]+0.5) {
1369
1370       
1371       int ix, iy, iz;
1372       double value = this->GetScalarComponentAsDouble(mImage->GetVTKImages()[mCurrentTSlice], X, Y, Z, ix, iy, iz);
1373
1374       if(ImageActor->GetVisibility())
1375         worldPos << "data value : " << value << std::endl;
1376
1377       worldPos << "mm : " << lrint(mCurrentBeforeSlicingTransform[0]) << ' '
1378                           << lrint(mCurrentBeforeSlicingTransform[1]) << ' '
1379                           << lrint(mCurrentBeforeSlicingTransform[2]) << ' '
1380                           << mCurrentTSlice
1381                           << std::endl;
1382       worldPos << "pixel : " << ix << ' '
1383                              << iy << ' '
1384                              << iz << ' '
1385                              << mCurrentTSlice
1386                              << std::endl;
1387     }
1388     ca->SetText(1,worldPos.str().c_str());
1389   }
1390
1391   if (pdmA->GetVisibility()) {
1392     double x = mCursor[0];
1393     double y = mCursor[1];
1394     double z = mCursor[2];
1395     double xCursor = (x - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1396     double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1397     double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1398
1399     if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0]-0.5 &&
1400         xCursor < this->GetImageActor()->GetDisplayExtent()[1]+0.5 &&
1401         yCursor >= this->GetImageActor()->GetDisplayExtent()[2]-0.5 &&
1402         yCursor < this->GetImageActor()->GetDisplayExtent()[3]+0.5 &&
1403         zCursor >= this->GetImageActor()->GetDisplayExtent()[4]-0.5 &&
1404         zCursor < this->GetImageActor()->GetDisplayExtent()[5]+0.5 ) {
1405       vtkRenderer * renderer = this->Renderer;
1406
1407       renderer->WorldToView(x,y,z);
1408       renderer->ViewToNormalizedViewport(x,y,z);
1409       renderer->NormalizedViewportToViewport(x,y);
1410       renderer->ViewportToNormalizedDisplay(x,y);
1411       renderer->NormalizedDisplayToDisplay(x,y);
1412       crossCursor->SetFocalPoint(x,y,z);
1413     } else
1414       crossCursor->SetFocalPoint(-1,-1,z);
1415   }
1416
1417
1418   if (mOverlay && mOverlayActor->GetVisibility()) {
1419     if(mLinkOverlayWindowLevel) {
1420       mOverlayMapper->SetWindow(this->GetColorWindow());
1421       mOverlayMapper->SetLevel(this->GetColorLevel());
1422     }
1423     mOverlayMapper->GetOutput()->SetUpdateExtent(mOverlayActor->GetDisplayExtent());
1424     mOverlayMapper->GetOutput()->Update();
1425     mOverlayMapper->Update();
1426   }
1427   if (mLandMapper)
1428     UpdateLandmarks();
1429
1430   this->GetRenderWindow()->Render();
1431 }
1432 //----------------------------------------------------------------------------
1433
1434
1435 //----------------------------------------------------------------------------
1436 void vvSlicer::UpdateCursorPosition()
1437 {
1438   pdmA->SetVisibility(true);
1439   mCursor[0] = mCurrent[0];
1440   mCursor[1] = mCurrent[1];
1441   mCursor[2] = mCurrent[2];
1442   mCursor[3] = mCurrentTSlice;
1443 }
1444 //----------------------------------------------------------------------------
1445
1446
1447 //----------------------------------------------------------------------------
1448 void vvSlicer::UpdateLandmarks()
1449 {
1450   vtkPolyData *pd = static_cast<vtkPolyData*>(mLandClipper->GetInput());
1451   if (pd->GetPoints()) {
1452     //mLandGlyph->SetRange(0,1);
1453     //mLandGlyph->Modified();
1454     //mLandGlyph->Update();
1455
1456     mClipBox->Modified();
1457     mLandClipper->Update();
1458     mLandMapper->Update();
1459     //Let's add the captions
1460     //First remove all captions:
1461     for(unsigned int i=0;i<mLandLabelActors.size();i++) {
1462         this->Renderer->RemoveActor2D(mLandLabelActors[i]);
1463         //allActors2D->Remove (mLandLabelActors[i]);
1464     }
1465     mLandLabelActors.clear();
1466     //Next add the captions to the displayed points
1467     for (vtkIdType id=0; id<mLandClipper->GetOutput()->GetNumberOfPoints(); id++) {
1468           double *position = mLandClipper->GetOutput()->GetPoint(id);
1469       vtkStdString label = static_cast<vtkStringArray*>(mLandClipper->GetOutput()->GetPointData()->GetAbstractArray("labels"))->GetValue(id);
1470       vtkSmartPointer<vtkCaptionActor2D> label_actor = vtkSmartPointer<vtkCaptionActor2D>::New();
1471       label_actor->SetCaption(label);
1472       label_actor->SetAttachmentPoint(position);
1473       label_actor->GetCaptionTextProperty()->SetColor(1,0,0);
1474       label_actor->GetCaptionTextProperty()->SetOrientation(33.333333);
1475       label_actor->GetCaptionTextProperty()->SetFontFamilyToTimes();
1476       label_actor->GetCaptionTextProperty()->SetBold(0);
1477       label_actor->GetCaptionTextProperty()->SetFontSize(6);
1478       label_actor->BorderOff();
1479       label_actor->LeaderOff();
1480       label_actor->ThreeDimensionalLeaderOff();
1481       mLandLabelActors.push_back(label_actor);
1482       this->Renderer->AddActor2D(mLandLabelActors[id]);
1483      }
1484   }
1485
1486 }
1487 //----------------------------------------------------------------------------
1488
1489
1490 //----------------------------------------------------------------------------
1491 void vvSlicer::SetSlice(int slice)
1492 {
1493   int *range = this->GetSliceRange();
1494   if (range) {
1495     if (slice < range[0]) {
1496       slice = range[0];
1497     } else if (slice > range[1]) {
1498       slice = range[1];
1499     }
1500   }
1501
1502   if (this->Slice == slice) {
1503     return;
1504   }
1505
1506   this->Slice = slice;
1507   SetContourSlice();
1508   this->Modified();
1509   this->UpdateDisplayExtent();
1510
1511   // Seems to work without this line
1512   //this->Render();
1513 }
1514 //----------------------------------------------------------------------------
1515
1516 //----------------------------------------------------------------------------
1517 int vvSlicer::GetTMax() {
1518   int tmax = (int)mImage->GetVTKImages().size() - 1;
1519   if(mOverlay)
1520     tmax = std::max(tmax, (int)mOverlay->GetVTKImages().size()-1);
1521   return tmax;
1522 }
1523 //----------------------------------------------------------------------------
1524
1525 //----------------------------------------------------------------------------
1526 void vvSlicer::SetContourSlice()
1527 {
1528   if (mSurfaceCutActors.size() > 0)
1529     for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
1530          i!=mSurfaceCutActors.end(); i++) {
1531          
1532       (*i)->SetSlicingOrientation(this->SliceOrientation);
1533       (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+
1534                         this->GetImage()->GetOrigin()[this->SliceOrientation]);
1535     }
1536 }
1537 //----------------------------------------------------------------------------
1538
1539
1540 //----------------------------------------------------------------------------
1541 void vvSlicer::ForceUpdateDisplayExtent()
1542 {
1543   this->UpdateDisplayExtent();
1544 }
1545 //----------------------------------------------------------------------------
1546
1547
1548 //----------------------------------------------------------------------------
1549 int* vvSlicer::GetDisplayExtent()
1550 {
1551   return this->GetImageActor()->GetDisplayExtent();
1552 }
1553 //----------------------------------------------------------------------------
1554
1555
1556 //----------------------------------------------------------------------------
1557 void vvSlicer::PrintSelf(ostream& os, vtkIndent indent)
1558 {
1559   this->Superclass::PrintSelf(os, indent);
1560 }
1561 //----------------------------------------------------------------------------
1562
1563 //----------------------------------------------------------------------------
1564 void vvSlicer::SetVFColor(double r, double g, double b)
1565 {
1566   double mVFColorHSV[3];
1567   mVFColor[0] = r;
1568   mVFColor[1] = g;
1569   mVFColor[2] = b;
1570
1571   vtkMath::RGBToHSV(mVFColor, mVFColorHSV);
1572   mVFColorLUT->SetHueRange(mVFColorHSV[0], mVFColorHSV[0]);
1573   mVFColorLUT->SetSaturationRange(mVFColorHSV[1],mVFColorHSV[1]);
1574   mVFColorLUT->SetValueRange(mVFColorHSV[2], mVFColorHSV[2]);
1575
1576   this->Render();
1577 }  
1578