]> Creatis software - clitk.git/blob - vv/vvSlicer.cxx
Changes rounding to nearest slice with a comment to explain that the
[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 nearest grid positionInc. This has been validated as the only
905   // way to have something consistent with the thickness of a 2D slice visible on the
906   // other slices. The thickness is accounted for so if the 2D slice is to thin and
907   // between two slices, one will never be able to see this 2D slice (bug #1883).
908   origin[this->SliceOrientation] = itk::Math::Round<double>(origin[this->SliceOrientation]);
909   // Step 3: back to world coordinates
910   origin[this->SliceOrientation] *= mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation];
911   origin[this->SliceOrientation] += mImageReslice->GetOutput()->GetOrigin()[this->SliceOrientation];
912
913   // Set new spacing and origin
914   reslice->SetOutputOrigin(origin);
915   reslice->SetOutputSpacing(spacing);
916   reslice->UpdateInformation();
917   reslice->GetOutput()->UpdateInformation();
918 }
919 //------------------------------------------------------------------------------
920
921 //----------------------------------------------------------------------------
922 int * vvSlicer::GetExtent(){
923   int *w_ext;
924   if (mUseReducedExtent) {
925     w_ext = mReducedExtent;
926   } else w_ext = GetInput()->GetWholeExtent();
927   return w_ext;
928 }
929 //----------------------------------------------------------------------------
930
931
932 //----------------------------------------------------------------------------
933 int vvSlicer::GetOrientation()
934 {
935   return this->SliceOrientation;
936 }
937 //----------------------------------------------------------------------------
938
939
940 //----------------------------------------------------------------------------
941 void vvSlicer::UpdateDisplayExtent()
942 {
943   vtkImageData *input = this->GetInput();
944   if (!input || !this->ImageActor) {
945     return;
946   }
947   input->UpdateInformation();
948   this->SetSlice( this->GetSlice() ); //SR: make sure the update let the slice in extents
949
950   // Local copy of extent
951   int w_ext[6];
952   int* ext = GetExtent();
953   copyExtent(ext, w_ext);
954   // Set slice value
955   w_ext[ this->SliceOrientation*2   ] = this->Slice;
956   w_ext[ this->SliceOrientation*2+1 ] = this->Slice;
957   
958   // Image actor
959   this->ImageActor->SetVisibility(mImageVisibility);
960   this->ImageActor->SetDisplayExtent(w_ext);
961 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
962   // Fix for bug #1882
963   dynamic_cast<vtkImageSliceMapper *>(this->ImageActor->GetMapper())->SetOrientation(this->GetOrientation());
964 #endif
965
966   // Overlay image actor
967   if (mOverlay && mOverlayVisibility) {
968     AdjustResliceToSliceOrientation(mOverlayReslice);
969     int overExtent[6];
970     this->ConvertImageToImageDisplayExtent(input, w_ext, mOverlayReslice->GetOutput(), overExtent);
971     bool out = ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
972     mOverlayActor->SetVisibility(!out);
973     mOverlayActor->SetDisplayExtent( overExtent );
974 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
975     // Fix for bug #1882
976     dynamic_cast<vtkImageSliceMapper *>(mOverlayActor->GetMapper())->SetOrientation(this->GetOrientation());
977 #endif
978   }
979   else if(mOverlay)
980     mOverlayActor->SetVisibility(false);
981
982   // Fusion image actor
983   if (mFusion && mFusionVisibility) {
984     AdjustResliceToSliceOrientation(mFusionReslice);
985     int fusExtent[6];
986     this->ConvertImageToImageDisplayExtent(input, w_ext, mFusionReslice->GetOutput(), fusExtent);
987     bool out = ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
988     mFusionActor->SetVisibility(!out);
989     mFusionActor->SetDisplayExtent( fusExtent );
990 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
991     // Fix for bug #1882
992     dynamic_cast<vtkImageSliceMapper *>(mFusionActor->GetMapper())->SetOrientation(this->GetOrientation());
993 #endif
994   }
995   else if(mFusion)
996     mFusionActor->SetVisibility(false);
997
998   // Vector field actor
999   double* camera = Renderer->GetActiveCamera()->GetPosition();
1000   double* image_bounds = ImageActor->GetBounds();
1001   double position[3] = {0, 0, 0};
1002   position[this->SliceOrientation] = image_bounds[this->SliceOrientation*2]; 
1003
1004   //print_vector<double, 6>("camera", camera);
1005   //print_vector<double, 6>("image_bounds", image_bounds);
1006   //print_vector<double, 3>("position", position);
1007
1008   // find where to place the VF actor. to deal with
1009   // z-buffer issues, the VF is placed right in front of the image,
1010   // subject to a small offset. the position actually depends on the
1011   // the location of the camera relative to the image. 
1012   double offset = 1;
1013   if (camera[this->SliceOrientation] < image_bounds[this->SliceOrientation*2])
1014     offset = -1;
1015   
1016   if (mVF && mVFVisibility) {
1017     int vfExtent[6];
1018     mVF->GetVTKImages()[0]->UpdateInformation();
1019     this->ConvertImageToImageDisplayExtent(input, w_ext, mVF->GetVTKImages()[0], vfExtent);
1020     bool out = ClipDisplayedExtent(vfExtent, mVOIFilter->GetInput()->GetWholeExtent());
1021     mVFActor->SetVisibility(!out);
1022     mVOIFilter->SetVOI(vfExtent);
1023     int orientation[3] = {1,1,1};
1024     orientation[this->SliceOrientation] = 0;
1025     mGlyphFilter->SetOrientation(orientation[0], orientation[1], orientation[2]);
1026     mVFMapper->Update();
1027
1028     position[this->SliceOrientation] += offset;
1029     mVFActor->SetPosition(position);
1030   }
1031   else if(mVF)
1032     mVFActor->SetVisibility(false);
1033
1034   // Landmarks actor
1035   if (mLandActor) {
1036     if (mClipBox) {
1037       double bounds [6];
1038       for(unsigned int i=0; i<6; i++)
1039         bounds[i] = ImageActor->GetBounds()[i];
1040       bounds[ this->SliceOrientation*2   ] = ImageActor->GetBounds()[ this->SliceOrientation*2  ]-fabs(this->GetInput()->GetSpacing()[this->SliceOrientation]);
1041       bounds[ this->SliceOrientation*2+1 ] = ImageActor->GetBounds()[ this->SliceOrientation*2+1 ]+fabs(this->GetInput()->GetSpacing()[this->SliceOrientation]);
1042       mClipBox->SetBounds(bounds);
1043       UpdateLandmarks();
1044     }
1045     
1046     position[this->SliceOrientation] = offset;
1047     mLandActor->SetPosition(position);
1048   }
1049
1050   // Figure out the correct clipping range
1051   if (this->Renderer) {
1052     if (this->InteractorStyle &&
1053         this->InteractorStyle->GetAutoAdjustCameraClippingRange()) {
1054       this->Renderer->ResetCameraClippingRange();
1055     } else {
1056       vtkCamera *cam = this->Renderer->GetActiveCamera();
1057       if (cam) {
1058         double bounds[6];
1059         this->ImageActor->GetBounds(bounds);
1060         double spos = (double)bounds[this->SliceOrientation * 2];
1061         double cpos = (double)cam->GetPosition()[this->SliceOrientation];
1062         double range = fabs(spos - cpos);
1063         double *spacing = input->GetSpacing();
1064         double sumSpacing = spacing[0] + spacing[1] + spacing[2];
1065         cam->SetClippingRange(range - sumSpacing, range + sumSpacing);
1066       }
1067     }
1068   }
1069 }
1070 //----------------------------------------------------------------------------
1071
1072 //----------------------------------------------------------------------------
1073 void vvSlicer::ConvertImageToImageDisplayExtent(vtkImageData *sourceImage, const int sourceExtent[6],
1074                                                 vtkImageData *targetImage, int targetExtent[6])
1075 {
1076   double dExtents[6];
1077   for(unsigned int i=0; i<6; i++) {
1078     // From source voxel coordinates to world coordinates
1079     dExtents[i] = sourceImage->GetOrigin()[i/2] + sourceImage->GetSpacing()[i/2] * sourceExtent[i];
1080
1081     // From world coordinates to floating point target voxel coordinates
1082     dExtents[i] = (dExtents[i]- targetImage->GetOrigin()[i/2]) / targetImage->GetSpacing()[i/2];
1083     
1084     // Round to current slice or larger extent
1085     if(i/2==this->GetOrientation())
1086       targetExtent[i] = itk::Math::Round<double>(dExtents[i]);
1087     else if(i%2==1)
1088       targetExtent[i] = itk::Math::Ceil<double>(dExtents[i]);
1089     else
1090       targetExtent[i] = itk::Math::Floor<double>(dExtents[i]);
1091   }
1092 }
1093 //----------------------------------------------------------------------------
1094
1095 //----------------------------------------------------------------------------
1096 bool vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
1097 {
1098   bool out = false;
1099   int maxBound = 6;
1100
1101   for (int i = 0; i < maxBound; i = i+2) {
1102     //if we are totally outside the image
1103     if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] ) {
1104       out = true;
1105       break;
1106     }
1107     //crop to the limit of the image
1108     extent[i] = std::max(extent[i], refExtent[i]);
1109     extent[i] = std::min(extent[i], refExtent[i+1]);;
1110     extent[i+1] = std::max(extent[i+1], refExtent[i]);
1111     extent[i+1] = std::min(extent[i+1], refExtent[i+1]);;
1112   }
1113   if (out)
1114     for (int i = 0; i < maxBound; i = i+2) {
1115       extent[i] = refExtent[i];
1116       extent[i+1] = refExtent[i];
1117     }
1118   return out;
1119 }
1120 //----------------------------------------------------------------------------
1121
1122
1123 //----------------------------------------------------------------------------
1124 void vvSlicer::UpdateOrientation()
1125 {
1126   // Set the camera position
1127   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1128   if (cam) {
1129     switch (this->SliceOrientation) {
1130     case vtkImageViewer2::SLICE_ORIENTATION_XY:
1131       cam->SetFocalPoint(0,0,0);
1132       cam->SetPosition(0,0,-1); // -1 if medical ?
1133       cam->SetViewUp(0,-1,0);
1134       break;
1135
1136     case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1137       cam->SetFocalPoint(0,0,0);
1138       cam->SetPosition(0,-1,0); // 1 if medical ?
1139       cam->SetViewUp(0,0,1);
1140       break;
1141
1142     case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1143       cam->SetFocalPoint(0,0,0);
1144       cam->SetPosition(-1,0,0); // -1 if medical ?
1145       cam->SetViewUp(0,0,1);
1146       break;
1147     }
1148   }
1149 }
1150 //----------------------------------------------------------------------------
1151
1152
1153 //----------------------------------------------------------------------------
1154 void vvSlicer::SetOpacity(double s)
1155 {
1156   this->GetImageActor()->SetOpacity(s);
1157 }
1158 //----------------------------------------------------------------------------
1159
1160
1161 //----------------------------------------------------------------------------
1162 void vvSlicer::SetRenderWindow(int orientation, vtkRenderWindow * rw)
1163 {
1164   this->Superclass::SetRenderWindow(rw);
1165   this->SetupInteractor(rw->GetInteractor());
1166   ca->SetImageActor(this->GetImageActor());
1167   ca->SetWindowLevel(this->GetWindowLevel());
1168   ca->SetText(2, "<slice>");
1169   ca->SetText(3, "<window>\n<level>");
1170
1171   double bounds[6];
1172   double max = 65000;
1173
1174   bounds[0] = -max;
1175   bounds[1] = max;
1176   bounds[2] = -max;
1177   bounds[3] = max;
1178   bounds[4] = -max;
1179   bounds[5] = max;
1180
1181   crossCursor->SetModelBounds(bounds);
1182   this->GetRenderer()->AddActor(pdmA);
1183   this->GetRenderer()->AddActor(ca);
1184   this->GetRenderer()->ResetCamera();
1185
1186   //this is just a mapping between the labeling of the orientations presented to the user and
1187   //the one used by vtk
1188   SetSliceOrientation(2-(orientation%3));
1189   ResetCamera();
1190 }
1191 //----------------------------------------------------------------------------
1192
1193
1194 //----------------------------------------------------------------------------
1195 void vvSlicer::ResetCamera()
1196 {
1197   this->GetRenderer()->ResetCamera();
1198 }
1199 //----------------------------------------------------------------------------
1200
1201
1202 //----------------------------------------------------------------------------
1203 void vvSlicer::SetDisplayMode(bool i)
1204 {
1205         this->GetRenderer()->SetDraw(i);
1206         if (i) UpdateDisplayExtent();
1207 }
1208 //----------------------------------------------------------------------------
1209
1210
1211 //----------------------------------------------------------------------------
1212 void vvSlicer::FlipHorizontalView()
1213 {
1214   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1215   if (cam) {
1216     double *position = cam->GetPosition();
1217     double factor[3] = {1, 1, 1};
1218     factor[this->SliceOrientation] = -1;
1219     cam->SetPosition(factor[0]*position[0],factor[1]*position[1],factor[2]*position[2]);
1220     
1221 /*    switch (this->SliceOrientation) {
1222     case vtkImageViewer2::SLICE_ORIENTATION_XY:
1223       cam->SetPosition(position[0],position[1],-position[2]);
1224       break;
1225
1226     case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1227       cam->SetPosition(position[0],-position[1],position[2]);
1228       break;
1229
1230     case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1231       cam->SetPosition(-position[0],position[1],position[2]);
1232       break;
1233     }*/
1234
1235     this->Renderer->ResetCameraClippingRange();
1236     this->UpdateDisplayExtent();
1237   }
1238 }
1239 //----------------------------------------------------------------------------
1240
1241
1242 //----------------------------------------------------------------------------
1243 void vvSlicer::FlipVerticalView()
1244 {
1245   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1246   if (cam) {
1247     FlipHorizontalView();
1248     double *viewup = cam->GetViewUp();
1249     cam->SetViewUp(-viewup[0],-viewup[1],-viewup[2]);
1250     this->UpdateDisplayExtent();
1251   }
1252 }
1253 //----------------------------------------------------------------------------
1254
1255
1256 //----------------------------------------------------------------------------
1257 void vvSlicer::SetColorWindow(double window)
1258 {
1259   vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1260   if ( LUT ) {
1261     double level = this->GetWindowLevel()->GetLevel();
1262     LUT->SetTableRange(level-fabs(window)/2,level+fabs(window)/2);
1263     LUT->Build();
1264   }
1265   this->vtkImageViewer2::SetColorWindow(window);
1266 }
1267 //----------------------------------------------------------------------------
1268
1269 //----------------------------------------------------------------------------
1270 void vvSlicer::SetColorLevel(double level)
1271 {
1272   vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1273   if ( LUT ) {
1274     double window = this->GetWindowLevel()->GetWindow();
1275     LUT->SetTableRange(level-fabs(window)/2,level+fabs(window)/2);
1276     LUT->Build();
1277   }
1278   this->vtkImageViewer2::SetColorLevel(level);
1279 }
1280 //----------------------------------------------------------------------------
1281
1282 //----------------------------------------------------------------------------
1283 double vvSlicer::GetOverlayColorWindow()
1284 {
1285   if(mOverlayMapper)
1286     return mOverlayMapper->GetWindow();
1287   else
1288     return 0.;
1289 }
1290 //----------------------------------------------------------------------------
1291
1292 //----------------------------------------------------------------------------
1293 double vvSlicer::GetOverlayColorLevel()
1294 {
1295   if(mOverlayMapper)
1296     return mOverlayMapper->GetLevel();
1297   else
1298     return 0.;
1299 }
1300 //----------------------------------------------------------------------------
1301
1302 //----------------------------------------------------------------------------
1303 void vvSlicer::SetOverlayColorWindow(double window)
1304 {
1305   mOverlayMapper->SetWindow(window);
1306 }
1307 //----------------------------------------------------------------------------
1308
1309 //----------------------------------------------------------------------------
1310 void vvSlicer::SetOverlayColorLevel(double level)
1311 {
1312   mOverlayMapper->SetLevel(level);
1313 }
1314 //----------------------------------------------------------------------------
1315
1316 //----------------------------------------------------------------------------
1317 // Returns the min an the max value in a 20%x20% region around the mouse pointer
1318 void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image, vtkTransform *transform)
1319 {
1320   //Get mouse pointer position in view coordinates
1321   double corner1[3];
1322   double corner2[3];
1323   for(int i=0; i<3; i++) {
1324     corner1[i] = mCurrent[i];
1325     corner2[i] = mCurrent[i];
1326   }
1327
1328   this->Renderer->WorldToView(corner1[0], corner1[1], corner1[2]);
1329   this->Renderer->WorldToView(corner2[0], corner2[1], corner2[2]);
1330
1331   // In view coordinates, x is the slicer width and y is the slicer height are the in-plane axis
1332   int w, h;
1333   this->Renderer->GetTiledSize(&w, &h);
1334   corner1[0] -= 0.2*h/(double)w;
1335   corner2[0] += 0.2*h/(double)w;
1336   corner1[1] -= 0.2;
1337   corner2[1] += 0.2;
1338   this->Renderer->ViewToWorld(corner1[0], corner1[1], corner1[2]);
1339   this->Renderer->ViewToWorld(corner2[0], corner2[1], corner2[2]);
1340
1341   //Convert to image pixel coordinates (rounded)
1342   transform->TransformPoint(corner1, corner1);
1343   transform->TransformPoint(corner2, corner2);
1344   int iLocalExtents[6];
1345   for(int i=0; i<3; i++) {
1346     corner1[i] = (corner1[i] - image->GetOrigin()[i])/image->GetSpacing()[i];
1347     corner2[i] = (corner2[i] - image->GetOrigin()[i])/image->GetSpacing()[i];
1348
1349     iLocalExtents[i*2  ] = lrint(corner1[i]);
1350     iLocalExtents[i*2+1] = lrint(corner2[i]);
1351
1352     if(iLocalExtents[i*2  ]>iLocalExtents[i*2+1])
1353       std::swap(iLocalExtents[i*2], iLocalExtents[i*2+1]);
1354   }
1355
1356   vtkSmartPointer<vtkExtractVOI> voiFilter = vtkSmartPointer<vtkExtractVOI>::New();
1357   voiFilter->SetInput(image);
1358   voiFilter->SetVOI(iLocalExtents);
1359   voiFilter->Update();
1360   if (!voiFilter->GetOutput()->GetNumberOfPoints()) {
1361     min = 0;
1362     max = 0;
1363     return;
1364   }
1365
1366   vtkSmartPointer<vtkImageAccumulate> accFilter = vtkSmartPointer<vtkImageAccumulate>::New();
1367   accFilter->SetInput(voiFilter->GetOutput());
1368   accFilter->Update();
1369
1370   min = *(accFilter->GetMin());
1371   max = *(accFilter->GetMax());
1372 }
1373 //----------------------------------------------------------------------------
1374
1375 //----------------------------------------------------------------------------
1376 double vvSlicer::GetScalarComponentAsDouble(vtkImageData *image, double X, double Y, double Z, int &ix, int &iy, int &iz, int component)
1377 {
1378   ix = lrint(X);
1379   iy = lrint(Y);
1380   iz = lrint(Z);
1381
1382   if (ix < image->GetWholeExtent()[0] ||
1383       ix > image->GetWholeExtent()[1] ||
1384       iy < image->GetWholeExtent()[2] ||
1385       iy > image->GetWholeExtent()[3] ||
1386       iz < image->GetWholeExtent()[4] ||
1387       iz > image->GetWholeExtent()[5] )
1388     return std::numeric_limits<double>::quiet_NaN();
1389
1390   image->SetUpdateExtent(ix, ix, iy, iy, iz, iz);
1391   image->Update();
1392   return image->GetScalarComponentAsDouble(ix, iy, iz, component);
1393 }
1394 //----------------------------------------------------------------------------
1395
1396 //----------------------------------------------------------------------------
1397 void vvSlicer::Render()
1398 {
1399   if (this->mFusion && mFusionActor->GetVisibility() && showFusionLegend) {
1400     legend->SetLookupTable(this->GetFusionMapper()->GetLookupTable());
1401     legend->UseOpacityOn();
1402     legend->SetVisibility(1);
1403   }
1404   else if (this->GetWindowLevel()->GetLookupTable() && !this->mOverlay)  {
1405     legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable());
1406     legend->UseOpacityOff();
1407     legend->SetVisibility(1);
1408   } else legend->SetVisibility(0);
1409
1410   if (ca->GetVisibility()) {
1411     std::stringstream worldPos;
1412     double pt[3];
1413     mConcatenatedTransform->TransformPoint(mCurrent, pt);
1414     double X = (pt[0] - mImage->GetVTKImages()[mCurrentTSlice]->GetOrigin()[0])/mImage->GetVTKImages()[mCurrentTSlice]->GetSpacing()[0];
1415     double Y = (pt[1] - mImage->GetVTKImages()[mCurrentTSlice]->GetOrigin()[1])/mImage->GetVTKImages()[mCurrentTSlice]->GetSpacing()[1];
1416     double Z = (pt[2] - mImage->GetVTKImages()[mCurrentTSlice]->GetOrigin()[2])/mImage->GetVTKImages()[mCurrentTSlice]->GetSpacing()[2];
1417
1418     if (X >= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[0]-0.5 &&
1419         X <= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[1]+0.5 &&
1420         Y >= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[2]-0.5 &&
1421         Y <= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[3]+0.5 &&
1422         Z >= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[4]-0.5 &&
1423         Z <= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[5]+0.5) {
1424
1425       
1426       int ix, iy, iz;
1427       double value = this->GetScalarComponentAsDouble(mImage->GetVTKImages()[mCurrentTSlice], X, Y, Z, ix, iy, iz);
1428
1429       if(ImageActor->GetVisibility())
1430         worldPos << "data value : " << value << std::endl;
1431
1432       worldPos << "mm : " << lrint(mCurrentBeforeSlicingTransform[0]) << ' '
1433                           << lrint(mCurrentBeforeSlicingTransform[1]) << ' '
1434                           << lrint(mCurrentBeforeSlicingTransform[2]) << ' '
1435                           << mCurrentTSlice
1436                           << std::endl;
1437       worldPos << "pixel : " << ix << ' '
1438                              << iy << ' '
1439                              << iz << ' '
1440                              << mCurrentTSlice
1441                              << std::endl;
1442     }
1443     ca->SetText(1,worldPos.str().c_str());
1444   }
1445
1446   if (pdmA->GetVisibility()) {
1447     double x = mCursor[0];
1448     double y = mCursor[1];
1449     double z = mCursor[2];
1450     double xCursor = (x - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1451     double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1452     double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1453
1454     if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0]-0.5 &&
1455         xCursor < this->GetImageActor()->GetDisplayExtent()[1]+0.5 &&
1456         yCursor >= this->GetImageActor()->GetDisplayExtent()[2]-0.5 &&
1457         yCursor < this->GetImageActor()->GetDisplayExtent()[3]+0.5 &&
1458         zCursor >= this->GetImageActor()->GetDisplayExtent()[4]-0.5 &&
1459         zCursor < this->GetImageActor()->GetDisplayExtent()[5]+0.5 ) {
1460       vtkRenderer * renderer = this->Renderer;
1461
1462       renderer->WorldToView(x,y,z);
1463       renderer->ViewToNormalizedViewport(x,y,z);
1464       renderer->NormalizedViewportToViewport(x,y);
1465       renderer->ViewportToNormalizedDisplay(x,y);
1466       renderer->NormalizedDisplayToDisplay(x,y);
1467       crossCursor->SetFocalPoint(x,y,z);
1468     } else
1469       crossCursor->SetFocalPoint(-1,-1,z);
1470   }
1471
1472
1473   if (mOverlay && mOverlayActor->GetVisibility()) {
1474     if(mLinkOverlayWindowLevel) {
1475       mOverlayMapper->SetWindow(this->GetColorWindow());
1476       mOverlayMapper->SetLevel(this->GetColorLevel());
1477     }
1478     mOverlayMapper->GetOutput()->SetUpdateExtent(mOverlayActor->GetDisplayExtent());
1479     mOverlayMapper->GetOutput()->Update();
1480     mOverlayMapper->Update();
1481   }
1482   if (mLandMapper)
1483     UpdateLandmarks();
1484
1485   this->GetRenderWindow()->Render();
1486 }
1487 //----------------------------------------------------------------------------
1488
1489
1490 //----------------------------------------------------------------------------
1491 void vvSlicer::UpdateCursorPosition()
1492 {
1493   pdmA->SetVisibility(true);
1494   mCursor[0] = mCurrent[0];
1495   mCursor[1] = mCurrent[1];
1496   mCursor[2] = mCurrent[2];
1497   mCursor[3] = mCurrentTSlice;
1498 }
1499 //----------------------------------------------------------------------------
1500
1501
1502 //----------------------------------------------------------------------------
1503 void vvSlicer::UpdateLandmarks()
1504 {
1505   vtkPolyData *pd = static_cast<vtkPolyData*>(mLandClipper->GetInput());
1506   if (pd->GetPoints()) {
1507     //mLandGlyph->SetRange(0,1);
1508     //mLandGlyph->Modified();
1509     //mLandGlyph->Update();
1510
1511     mClipBox->Modified();
1512     mLandClipper->Update();
1513     mLandMapper->Update();
1514     //Let's add the captions
1515     //First remove all captions:
1516     for(unsigned int i=0;i<mLandLabelActors.size();i++) {
1517         this->Renderer->RemoveActor2D(mLandLabelActors[i]);
1518         //allActors2D->Remove (mLandLabelActors[i]);
1519     }
1520     mLandLabelActors.clear();
1521     //Next add the captions to the displayed points
1522     for (vtkIdType id=0; id<mLandClipper->GetOutput()->GetNumberOfPoints(); id++) {
1523           double *position = mLandClipper->GetOutput()->GetPoint(id);
1524       vtkStdString label = static_cast<vtkStringArray*>(mLandClipper->GetOutput()->GetPointData()->GetAbstractArray("labels"))->GetValue(id);
1525       vtkSmartPointer<vtkCaptionActor2D> label_actor = vtkSmartPointer<vtkCaptionActor2D>::New();
1526       label_actor->SetCaption(label);
1527       label_actor->SetAttachmentPoint(position);
1528       label_actor->GetCaptionTextProperty()->SetColor(1,0,0);
1529       label_actor->GetCaptionTextProperty()->SetOrientation(33.333333);
1530       label_actor->GetCaptionTextProperty()->SetFontFamilyToTimes();
1531       label_actor->GetCaptionTextProperty()->SetBold(0);
1532       label_actor->GetCaptionTextProperty()->SetFontSize(6);
1533       label_actor->BorderOff();
1534       label_actor->LeaderOff();
1535       label_actor->ThreeDimensionalLeaderOff();
1536       mLandLabelActors.push_back(label_actor);
1537       this->Renderer->AddActor2D(mLandLabelActors[id]);
1538      }
1539   }
1540
1541 }
1542 //----------------------------------------------------------------------------
1543
1544
1545 //----------------------------------------------------------------------------
1546 void vvSlicer::SetSlice(int slice)
1547 {
1548   int *range = this->GetSliceRange();
1549   if (range) {
1550     if (slice < range[0]) {
1551       slice = range[0];
1552     } else if (slice > range[1]) {
1553       slice = range[1];
1554     }
1555   }
1556
1557   if (this->Slice == slice) {
1558     return;
1559   }
1560
1561   this->Slice = slice;
1562   SetContourSlice();
1563   this->Modified();
1564   this->UpdateDisplayExtent();
1565
1566   // Seems to work without this line
1567   //this->Render();
1568 }
1569 //----------------------------------------------------------------------------
1570
1571 //----------------------------------------------------------------------------
1572 int vvSlicer::GetTMax() {
1573   int tmax = (int)mImage->GetVTKImages().size() - 1;
1574   if(mOverlay)
1575     tmax = std::max(tmax, (int)mOverlay->GetVTKImages().size()-1);
1576   return tmax;
1577 }
1578 //----------------------------------------------------------------------------
1579
1580 //----------------------------------------------------------------------------
1581 void vvSlicer::SetContourSlice()
1582 {
1583   if (mSurfaceCutActors.size() > 0)
1584     for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
1585          i!=mSurfaceCutActors.end(); i++) {
1586          
1587       (*i)->SetSlicingOrientation(this->SliceOrientation);
1588       (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+
1589                         this->GetImage()->GetOrigin()[this->SliceOrientation]);
1590     }
1591 }
1592 //----------------------------------------------------------------------------
1593
1594
1595 //----------------------------------------------------------------------------
1596 void vvSlicer::ForceUpdateDisplayExtent()
1597 {
1598   this->UpdateDisplayExtent();
1599 }
1600 //----------------------------------------------------------------------------
1601
1602
1603 //----------------------------------------------------------------------------
1604 int* vvSlicer::GetDisplayExtent()
1605 {
1606   return this->GetImageActor()->GetDisplayExtent();
1607 }
1608 //----------------------------------------------------------------------------
1609
1610
1611 //----------------------------------------------------------------------------
1612 void vvSlicer::PrintSelf(ostream& os, vtkIndent indent)
1613 {
1614   this->Superclass::PrintSelf(os, indent);
1615 }
1616 //----------------------------------------------------------------------------
1617
1618 //----------------------------------------------------------------------------
1619 void vvSlicer::SetVFColor(double r, double g, double b)
1620 {
1621   double mVFColorHSV[3];
1622   mVFColor[0] = r;
1623   mVFColor[1] = g;
1624   mVFColor[2] = b;
1625
1626   vtkMath::RGBToHSV(mVFColor, mVFColorHSV);
1627   mVFColorLUT->SetHueRange(mVFColorHSV[0], mVFColorHSV[0]);
1628   mVFColorLUT->SetSaturationRange(mVFColorHSV[1],mVFColorHSV[1]);
1629   mVFColorLUT->SetValueRange(mVFColorHSV[2], mVFColorHSV[2]);
1630
1631   this->Render();
1632 }  
1633