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