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