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