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