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