]> Creatis software - clitk.git/blob - vv/vvSlicer.cxx
Fixed compilation with VC++ 9
[clitk.git] / vv / vvSlicer.cxx
1 /*=========================================================================
2
3 Program:   vv
4 Language:  C++
5 Author :   Pierre Seroul (pierre.seroul@gmail.com)
6
7 Copyright (C) 2008
8 Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
9 CREATIS-LRMN http://www.creatis.insa-lyon.fr
10
11 This program is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, version 3 of the License.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
23 =========================================================================*/
24 #include "vvSlicer.h"
25
26 #include "vvImage.h"
27 #include "vvImage.h"
28 #include "vvSlicerManagerCommand.h"
29 #include "vvGlyphSource.h"
30 #include "vvGlyph2D.h"
31 #include "vvImageMapToWLColors.h"
32
33 #include <vtkTextProperty.h>
34 #include <vtkTextActor.h>
35 #include <vtkTextSource.h>
36 #include <vtkActor2D.h>
37 #include <vtkCursor2D.h>
38 #include <vtkPolyDataMapper2D.h>
39 #include <vtkProperty2D.h>
40 #include <vtkCornerAnnotation.h>
41 #include <vtkImageMapToWindowLevelColors.h>
42 #include <vtkImageData.h>
43 #include <vtkImageActor.h>
44 #include <vtkToolkits.h>
45 #include <vtkObjectFactory.h>
46 #include <vtkPointData.h>
47 #include <vtkDataArray.h>
48 #include <vtkFloatArray.h>
49 #include <vtkClipPolyData.h>
50 #include <vtkGlyph3D.h>
51 #include <vtkMath.h>
52 #include <vtkCursor3D.h>
53 #include <vtkProperty.h>
54 #include <vtkLight.h>
55 #include <vtkLightCollection.h>
56 #include <vtkScalarBarActor.h>
57 #include <vtkLookupTable.h>
58
59 #include <vtkRenderer.h>
60 #include <vtkRendererCollection.h>
61 #include <vtkRenderWindow.h>
62 #include <vtkRenderWindowInteractor.h>
63 #include <vtkCamera.h>
64 #include <vtkCallbackCommand.h>
65 #include <vtkCommand.h>
66 #include <vtkPolyDataMapper.h>
67 #include <vtkBox.h>
68
69 #include <vtkExtractVOI.h>
70 #include <vtkSphereSource.h>
71 #include <vtkCutter.h>
72 #include <vtkPlane.h>
73 #include <vtkAssignAttribute.h>
74
75 vtkCxxRevisionMacro(vvSlicer, "DummyRevision");
76 vtkStandardNewMacro(vvSlicer);
77
78 vvSlicer::vvSlicer()
79 {
80     mImage = NULL;
81     mCurrentTSlice = 0;
82
83     mCurrent[0] = -VTK_DOUBLE_MAX;
84     mCurrent[1] = -VTK_DOUBLE_MAX;
85     mCurrent[2] = -VTK_DOUBLE_MAX;
86
87     mCursor[0] = -VTK_DOUBLE_MAX;
88     mCursor[1] = -VTK_DOUBLE_MAX;
89     mCursor[2] = -VTK_DOUBLE_MAX;
90     mCursor[3] = -VTK_DOUBLE_MAX;
91
92     mSubSampling = 5;
93     mScale = 1;
94     mVFLog = 0;
95
96     std::string text = "F1 = sagital; F2 = coronal; F3 = axial\n";
97     text += "F5 = horizontal flip; F6 = vertical flip\n\n";
98     text += "0,1,2,3,4,5 : preset windowing\n";
99     text += "6,7,8,9 : preset colormap\n";
100     text += "r : reset view\n";
101     text += "l : reload image\n";
102     text += "f : fly to mouse position\n";
103     text += "g : go to cross hair position\n\n";
104     text += "Up,down : change slice\n";
105     text += "Left,right : change tenporal slice\n\n";
106     text += "Scrollbar (or w/x) : zoom in/out\n";
107     text += "left button : synchronize all views\n";
108     text += "middle button : grab image\n";
109     text += "right button : change windowing\n";
110
111     crossCursor = vtkCursor2D::New();
112     crossCursor->AllOff();
113     crossCursor->AxesOn();
114     crossCursor->SetTranslationMode(1);
115     crossCursor->SetRadius(2);
116
117     pdm = vtkPolyDataMapper2D::New();
118     pdm->SetInput(crossCursor->GetOutput());
119
120     pdmA = vtkActor2D::New();
121     pdmA->SetMapper(pdm);
122     pdmA->GetProperty()->SetColor(255,10,212);
123     pdmA->SetVisibility(0);
124     pdmA->SetPickable(0);
125
126     ca = 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
144     this->WindowLevel->Delete();
145     this->WindowLevel = vvImageMapToWLColors::New();
146     this->InstallPipeline();
147 }
148
149 vtkImageMapToWindowLevelColors* vvSlicer::GetOverlayMapper() {
150     return mOverlayMapper.GetPointer();
151 }
152 vtkImageActor* vvSlicer::GetOverlayActor() {
153     return mOverlayActor.GetPointer();
154 }
155 vtkImageMapToWindowLevelColors* vvSlicer::GetFusionMapper() {
156     return mFusionMapper.GetPointer();
157 }
158     
159 vtkImageActor* vvSlicer::GetFusionActor() {
160     return mFusionActor.GetPointer();
161 }
162 vtkActor* vvSlicer::GetVFActor() {
163     return mVFActor.GetPointer();
164 }
165 vtkCornerAnnotation* vvSlicer::GetAnnotation() {
166     return ca.GetPointer();
167 }
168
169 void vvSlicer::AddContour(vvMesh::Pointer contour,bool propagate)
170 {
171
172     mSurfaceCutActors.push_back(new vvMeshActor());
173     if (propagate)
174         mSurfaceCutActors.back()->Init(contour,mCurrentTSlice,mVF);
175     else
176         mSurfaceCutActors.back()->Init(contour,mCurrentTSlice);
177     mSurfaceCutActors.back()->SetSlicingOrientation(SliceOrientation);
178     this->GetRenderer()->AddActor(mSurfaceCutActors.back()->GetActor());
179
180     SetContourSlice();
181 }
182
183 void vvSlicer::ToggleContourSuperposition()
184 {
185     for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
186             i!=mSurfaceCutActors.end();i++)
187         (*i)->ToggleSuperposition();
188 }
189
190 void vvSlicer::SetCursorColor(int r,int g, int b)
191 {
192     pdmA->GetProperty()->SetColor(r,g,b);
193 }
194 void vvSlicer::SetCursorVisibility(bool s)
195 {
196     pdmA->SetVisibility(s);
197 }
198 bool vvSlicer::GetCursorVisibility()
199 {
200     return pdmA->GetVisibility();
201 }
202
203 vvSlicer::~vvSlicer()
204 {
205     for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
206             i!=mSurfaceCutActors.end();i++)
207         delete (*i);
208 }
209
210 void vvSlicer::SetCurrentPosition(double x, double y, double z, int t)
211 {
212     mCurrent[0] = x;
213     mCurrent[1] = y;
214     mCurrent[2] = z;
215     mCurrentTSlice = t;
216 }
217
218 void vvSlicer::SetImage(vvImage::Pointer image)
219 {
220     if (image->GetVTKImages().size())
221     {
222         mImage = image;
223         this->Superclass::SetInput(image->GetVTKImages()[0]);
224         this->UpdateDisplayExtent();
225         mCurrentTSlice = 0;
226         ca->SetText(0,mFileName.c_str());
227     }
228 }
229
230 void vvSlicer::SetOverlay(vvImage::Pointer overlay)
231 {
232     if (overlay->GetVTKImages().size())
233     {
234         mOverlay = overlay;
235
236         if (!mOverlayMapper)
237             mOverlayMapper = vtkImageMapToWindowLevelColors::New();
238         mOverlayMapper->SetInput(overlay->GetVTKImages()[0]);
239
240         if (!mOverlayActor)
241         {
242             mOverlayActor = vtkImageActor::New();
243             mOverlayActor->SetInput(mOverlayMapper->GetOutput());
244             mOverlayActor->SetPickable(0);
245             mOverlayActor->SetVisibility(false);
246             mOverlayActor->SetOpacity(0.5);
247             this->UpdateDisplayExtent();
248         }
249
250         //stupid but necessary : the Overlay need to be rendered before fusion
251         if (mFusionActor)
252         {
253             this->GetRenderer()->RemoveActor(mFusionActor);
254             this->GetRenderer()->AddActor(mOverlayActor);
255             this->GetRenderer()->AddActor(mFusionActor);
256         }
257         else
258             this->GetRenderer()->AddActor(mOverlayActor);
259
260         //Synchronize slice
261         SetTSlice(mCurrentTSlice);
262     }
263 }
264
265 void vvSlicer::SetFusion(vvImage::Pointer fusion)
266 {
267     if (fusion->GetVTKImages().size())
268     {
269         mFusion = fusion;
270
271         if (!mFusionMapper)
272             mFusionMapper = vtkImageMapToWindowLevelColors::New();
273         mFusionMapper->SetInput(fusion->GetVTKImages()[0]);
274
275         if (!mFusionActor)
276         {
277             mFusionActor = vtkImageActor::New();
278             mFusionActor->SetInput(mFusionMapper->GetOutput());
279             mFusionActor->SetPickable(0);
280             mFusionActor->SetVisibility(false);
281             mFusionActor->SetOpacity(0.7);
282             this->UpdateDisplayExtent();
283             this->GetRenderer()->AddActor(mFusionActor);
284         }
285
286         //Synchronize slice
287         SetTSlice(mCurrentTSlice);
288     }
289 }
290
291 void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis)
292 {
293     if (actor_type == "vector")
294     {
295         this->mVFActor->SetVisibility(vis);
296     }
297     if (actor_type == "overlay")
298     {
299         this->mOverlayActor->SetVisibility(vis);
300     }
301     if (actor_type == "fusion")
302     {
303         this->mFusionActor->SetVisibility(vis);
304     }
305     if (actor_type == "contour")
306         this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis);
307     UpdateDisplayExtent();
308 }
309
310 void vvSlicer::SetVF(vvImage::Pointer vf)
311 {
312     if (vf->GetVTKImages().size())
313     {
314         mVF = vf;
315
316         if (!mAAFilter)
317         {
318             mAAFilter=vtkAssignAttribute::New();
319             mVOIFilter = vtkExtractVOI::New();
320             mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
321         }
322         mVOIFilter->SetInput(vf->GetVTKImages()[0]);
323         mAAFilter->SetInput(mVOIFilter->GetOutput());
324         ///This tells VTK to use the scalar (pixel) data of the image to draw the little arrows
325         mAAFilter->Assign(vtkDataSetAttributes::SCALARS, vtkDataSetAttributes::VECTORS, vtkAssignAttribute::POINT_DATA);
326
327         if (!mArrow)
328             mArrow = vvGlyphSource::New();
329         mArrow->SetGlyphTypeToSpecificArrow();
330         mArrow->SetScale(mScale);
331         mArrow->FilledOff();
332
333         // Glyph the gradient vector (with arrows)
334         if (!mGlyphFilter)
335             mGlyphFilter = vvGlyph2D::New();
336         mGlyphFilter->SetInput(mAAFilter->GetOutput());
337         mGlyphFilter->SetSource(mArrow->GetOutput());
338         mGlyphFilter->ScalingOn();
339         mGlyphFilter->SetScaleModeToScaleByVector();
340         mGlyphFilter->OrientOn();
341         mGlyphFilter->SetVectorModeToUseVector();
342         mGlyphFilter->SetColorModeToColorByVector();
343
344         if (!mVFMapper)
345             mVFMapper = vtkPolyDataMapper::New();
346         //mVFMapper->SetInputConnection(mGlyphFilter->GetOutputPort());
347         mVFMapper->SetInput(mGlyphFilter->GetOutput());
348         mVFMapper->ImmediateModeRenderingOn();
349
350         if (!mVFActor)
351             mVFActor = vtkActor::New();
352         mVFActor->SetMapper(mVFMapper);
353         mVFActor->SetPickable(0);
354         this->UpdateDisplayExtent();
355         this->GetRenderer()->AddActor(mVFActor);
356
357         //Synchronize slice
358         SetTSlice(mCurrentTSlice);
359     }
360 }
361
362 void vvSlicer::SetLandmarks(vvLandmarks* landmarks)
363 {
364     mLandmarks = landmarks;
365     if (landmarks)
366     {
367
368         if (!mCross)
369             mCross = vtkCursor3D::New();
370         mCross->SetFocalPoint(0.0,0.0,0.0);
371         mCross->SetModelBounds(-10,10,-10,10,-10,10);
372         mCross->AllOff();
373         mCross->AxesOn();
374
375         if (!mLandGlyph)
376             mLandGlyph = vtkGlyph3D::New();
377         mLandGlyph->SetSource(mCross->GetOutput());
378         mLandGlyph->SetInput(landmarks->GetOutput());
379         //mLandGlyph->SetIndexModeToScalar();
380         mLandGlyph->SetRange(0,1);
381         mLandGlyph->ScalingOff();
382
383         mLandGlyph->SetColorModeToColorByScalar();
384
385         if (!mClipBox)
386             mClipBox = vtkBox::New();
387         if (!mLandClipper)
388             mLandClipper = vtkClipPolyData::New();
389         mLandClipper->InsideOutOn();
390         mLandClipper->SetInput(mLandGlyph->GetOutput());
391         mLandClipper->SetClipFunction(mClipBox);
392
393         if (!mLandMapper)
394             mLandMapper = vtkPolyDataMapper::New();
395         mLandMapper->SetInputConnection(mLandClipper->GetOutputPort());
396         //mLandMapper->ScalarVisibilityOff();
397
398         if (!mLandActor)
399             mLandActor = vtkActor::New();
400         mLandActor->SetMapper(mLandMapper);
401         mLandActor->GetProperty()->SetColor(255,10,212);
402         mLandActor->SetPickable(0);
403         mLandActor->SetVisibility(true);
404         this->UpdateDisplayExtent();
405         this->GetRenderer()->AddActor(mLandActor);
406     }
407 }
408
409 //FIXME: this function leaks memory, we should fix it someday :)
410 void vvSlicer::RemoveActor(const std::string& actor_type, int overlay_index)
411 {
412     if (actor_type == "vector")
413     {
414         Renderer->RemoveActor(mVFActor);
415         mGlyphFilter=NULL;
416         mVF = NULL;
417         mArrow = NULL;
418         mAAFilter=NULL;
419         mVOIFilter = NULL;
420         mVFMapper = NULL;
421         mVFActor = NULL;
422     }
423     if (actor_type == "overlay")
424     {
425         Renderer->RemoveActor(mOverlayActor);
426         mOverlay = NULL;
427         mOverlayActor = NULL;
428         mOverlayMapper = NULL;
429     }
430     if (actor_type == "fusion")
431     {
432         Renderer->RemoveActor(mFusionActor);
433         mFusion = NULL;
434         mFusionActor = NULL;
435         mFusionMapper = NULL;
436     }
437     if (actor_type == "contour")
438     {
439         Renderer->RemoveActor(this->mSurfaceCutActors[overlay_index]->GetActor());
440         mSurfaceCutActors.erase(mSurfaceCutActors.begin()+overlay_index);
441     }
442 }
443
444 void vvSlicer::SetVFSubSampling(int sub)
445 {
446     if (mVOIFilter)
447     {
448         mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
449         mSubSampling = sub;
450     }
451     UpdateDisplayExtent();
452     Render();
453 }
454
455 void vvSlicer::SetVFScale(int scale)
456 {
457     mScale = scale;
458     if (mArrow)
459         mArrow->SetScale(mScale);
460     UpdateDisplayExtent();
461     Render();
462 }
463
464 void vvSlicer::SetVFLog(int log)
465 {
466     mVFLog = log;
467     if (mGlyphFilter)
468     {
469         mGlyphFilter->SetUseLog(mVFLog);
470         mGlyphFilter->Modified();
471     }
472     UpdateDisplayExtent();
473     Render();
474 }
475
476 void vvSlicer::SetTSlice(int t)
477 {
478     if (t < 0)
479         t = 0;
480     else if ((unsigned int)t >= mImage->GetVTKImages().size())
481         t = mImage->GetVTKImages().size() -1;
482     mCurrentTSlice = t;
483     this->SetInput(mImage->GetVTKImages()[t]);
484     if (mVF && mVFActor->GetVisibility())
485     {
486         if (mVF->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
487             mVOIFilter->SetInput(mVF->GetVTKImages()[mCurrentTSlice]);
488     }
489     if (mOverlay && mOverlayActor->GetVisibility())
490     {
491         if (mOverlay->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
492             mOverlayMapper->SetInput(mOverlay->GetVTKImages()[mCurrentTSlice]);
493     }
494     if (mFusion && mFusionActor->GetVisibility())
495     {
496         if (mFusion->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
497             mFusionMapper->SetInput(mFusion->GetVTKImages()[mCurrentTSlice]);
498     }
499     if (mSurfaceCutActors.size() > 0)
500         for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
501                 i!=mSurfaceCutActors.end();i++)
502             (*i)->SetTimeSlice(mCurrentTSlice);
503     UpdateDisplayExtent();
504 }
505
506 int vvSlicer::GetTSlice()
507 {
508     return mCurrentTSlice;
509 }
510
511 void vvSlicer::SetSliceOrientation(int orientation)
512 {
513     //if 2D image, force to watch in Axial View
514     int extent[6];
515     this->GetInput()->GetWholeExtent(extent);
516     if (extent[5]-extent[4] <= 2)
517         orientation=2;
518
519     if (orientation < vtkImageViewer2::SLICE_ORIENTATION_YZ ||
520             orientation > vtkImageViewer2::SLICE_ORIENTATION_XY)
521     {
522         vtkErrorMacro("Error - invalid slice orientation " << orientation);
523         return;
524     }
525
526     this->SliceOrientation = orientation;
527     
528     // Update the viewer
529     int *range = this->GetSliceRange();
530     if (range)
531         this->Slice = static_cast<int>((range[0] + range[1]) * 0.5);
532
533     this->UpdateOrientation();
534     this->UpdateDisplayExtent();
535
536     if (this->Renderer && this->GetInput())
537     {
538         double scale = this->Renderer->GetActiveCamera()->GetParallelScale();
539         this->Renderer->ResetCamera();
540         this->Renderer->GetActiveCamera()->SetParallelScale(scale);
541     }
542
543     SetContourSlice();
544 }
545
546 //----------------------------------------------------------------------------
547 void vvSlicer::UpdateDisplayExtent()
548 {
549     vtkImageData *input = this->GetInput();
550     if (!input || !this->ImageActor)
551     {
552         return;
553     }
554     input->UpdateInformation();
555     int *w_ext = input->GetWholeExtent();
556
557     switch (this->SliceOrientation)
558     {
559         case vtkImageViewer2::SLICE_ORIENTATION_XY:
560             this->ImageActor->SetDisplayExtent(
561                     w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice);
562             if (mVF && mVFActor->GetVisibility())
563             {
564                 int vfExtent[6];
565                 ComputeVFDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,vfExtent);
566                 mVOIFilter->SetVOI(vfExtent);
567                 mGlyphFilter->SetOrientation(1,1,0);
568                 mVFMapper->Update();
569                 // put the vector field between the image and the camera
570                 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
571                     mVFActor->SetPosition(0,0,ImageActor->GetBounds()[5]+2);
572                 else
573                     mVFActor->SetPosition(0,0,ImageActor->GetBounds()[4]-2);
574             }
575             if (mOverlay && mOverlayActor->GetVisibility())
576             {
577                 int overExtent[6];
578                 ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,overExtent);
579                 mOverlayActor->SetDisplayExtent(overExtent);
580                 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
581                     mOverlayActor->SetPosition(0,0,1);
582                 else
583                     mOverlayActor->SetPosition(0,0,-1);
584             }
585             if (mFusion && mFusionActor->GetVisibility())
586             {
587                 int fusExtent[6];
588                 ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,fusExtent);
589                 mFusionActor->SetDisplayExtent(fusExtent);
590                 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
591                     mFusionActor->SetPosition(0,0,1.5);
592                 else
593                     mFusionActor->SetPosition(0,0,-1.5);
594             }
595             if (mLandActor)
596             {
597                 if (mClipBox)
598                 {
599                     double bounds [6];
600                     bounds[0] = ImageActor->GetBounds()[0];
601                     bounds[1] = ImageActor->GetBounds()[1];
602                     bounds[2] = ImageActor->GetBounds()[2];
603                     bounds[3] = ImageActor->GetBounds()[3];
604                     bounds[4] = ImageActor->GetBounds()[4]-(0.9/this->GetInput()->GetSpacing()[2]);
605                     bounds[5] = ImageActor->GetBounds()[5]+(0.9/this->GetInput()->GetSpacing()[2]);
606                     mClipBox->SetBounds(bounds);
607                     UpdateLandmarks();
608                 }
609                 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
610                     mLandActor->SetPosition(0,0,1.5);
611                 else
612                     mLandActor->SetPosition(0,0,-1.5);
613             }
614             break;
615
616         case vtkImageViewer2::SLICE_ORIENTATION_XZ:
617             this->ImageActor->SetDisplayExtent(
618                     w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5]);
619             if (mVF && mVFActor->GetVisibility())
620             {
621                 int vfExtent[6];
622                 ComputeVFDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],vfExtent);
623                 mVOIFilter->SetVOI(vfExtent);
624                 mGlyphFilter->SetOrientation(1,0,1);
625                 mVFMapper->Update();
626                 // put the vector field between the image aSpacingnd the camera
627                 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
628                     mVFActor->SetPosition(0,ImageActor->GetBounds()[3]+2,0);
629                 else
630                     mVFActor->SetPosition(0,ImageActor->GetBounds()[2]-2,0);
631             }
632             if (mOverlay && mOverlayActor->GetVisibility())
633             {
634                 int overExtent[6];
635                 ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],overExtent);
636                 mOverlayActor->SetDisplayExtent(overExtent);
637                 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
638                     mOverlayActor->SetPosition(0,1,0);
639                 else
640                     mOverlayActor->SetPosition(0,-1,0);
641             }
642             if (mFusion && mFusionActor->GetVisibility())
643             {
644                 int fusExtent[6];
645                 ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],fusExtent);
646                 mFusionActor->SetDisplayExtent(fusExtent);
647                 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
648                     mFusionActor->SetPosition(0,1.5,0);
649                 else
650                     mFusionActor->SetPosition(0,-1.5,0);
651             }
652             if (mLandActor)
653             {
654                 if (mClipBox)
655                 {
656                     double bounds [6];
657                     bounds[0] = ImageActor->GetBounds()[0];
658                     bounds[1] = ImageActor->GetBounds()[1];
659                     bounds[2] = ImageActor->GetBounds()[2]-(0.5/this->GetInput()->GetSpacing()[1]);
660                     bounds[3] = ImageActor->GetBounds()[3]+(0.5/this->GetInput()->GetSpacing()[1]);
661                     bounds[4] = ImageActor->GetBounds()[4];
662                     bounds[5] = ImageActor->GetBounds()[5];
663                     mClipBox->SetBounds(bounds);
664                     UpdateLandmarks();
665                 }
666                 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
667                     mLandActor->SetPosition(0,1.5,0);
668                 else
669                     mLandActor->SetPosition(0,-1.5,0);
670             }
671             break;
672
673         case vtkImageViewer2::SLICE_ORIENTATION_YZ:
674             this->ImageActor->SetDisplayExtent(
675                     this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5]);
676             if (mVF && mVFActor->GetVisibility())
677             {
678                 int vfExtent[6];
679                 ComputeVFDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],vfExtent);
680                 mVOIFilter->SetVOI(vfExtent);
681                 mGlyphFilter->SetOrientation(0,1,1);
682                 mVFMapper->Update();
683                 // put the vector field between the image and the camera
684                 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
685                     mVFActor->SetPosition(ImageActor->GetBounds()[1]+2,0,0);
686                 else
687                     mVFActor->SetPosition(ImageActor->GetBounds()[0]-2,0,0);
688             }
689             if (mOverlay && mOverlayActor->GetVisibility())
690             {
691                 int overExtent[6];
692                 ComputeOverlayDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],overExtent);
693                 mOverlayActor->SetDisplayExtent(overExtent);
694                 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
695                     mOverlayActor->SetPosition(1,0,0);
696                 else
697                     mOverlayActor->SetPosition(-1,0,0);
698             }
699             if (mFusion && mFusionActor->GetVisibility())
700             {
701                 int fusExtent[6];
702                 ComputeFusionDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],fusExtent);
703                 mFusionActor->SetDisplayExtent(fusExtent);
704                 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
705                     mFusionActor->SetPosition(1.5,0,0);
706                 else
707                     mFusionActor->SetPosition(-1.5,0,0);
708             }
709             if (mLandActor)
710             {
711                 if (mClipBox)
712                 {
713                     double bounds [6];
714                     bounds[0] = ImageActor->GetBounds()[0]-(0.5/this->GetInput()->GetSpacing()[0]);
715                     bounds[1] = ImageActor->GetBounds()[1]+(0.5/this->GetInput()->GetSpacing()[0]);
716                     bounds[2] = ImageActor->GetBounds()[2];
717                     bounds[3] = ImageActor->GetBounds()[3];
718                     bounds[4] = ImageActor->GetBounds()[4];
719                     bounds[5] = ImageActor->GetBounds()[5];
720                     mClipBox->SetBounds(bounds);
721                     UpdateLandmarks();
722                 }
723                 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
724                     mLandActor->SetPosition(1.5,0,0);
725                 else
726                     mLandActor->SetPosition(-1.5,0,0);
727             }
728             break;
729     }
730
731     // Figure out the correct clipping range
732
733     if (this->Renderer)
734     {
735         if (this->InteractorStyle &&
736                 this->InteractorStyle->GetAutoAdjustCameraClippingRange())
737         {
738             this->Renderer->ResetCameraClippingRange();
739         }
740         else
741         {
742             vtkCamera *cam = this->Renderer->GetActiveCamera();
743             if (cam)
744             {
745                 double bounds[6];
746                 this->ImageActor->GetBounds(bounds);
747                 double spos = (double)bounds[this->SliceOrientation * 2];
748                 double cpos = (double)cam->GetPosition()[this->SliceOrientation];
749                 double range = fabs(spos - cpos);
750                 double *spacing = input->GetSpacing();
751                 double avg_spacing =
752                     ((double)spacing[0] + (double)spacing[1] + (double)spacing[2]) / 3.0;
753                 cam->SetClippingRange(
754                         range - avg_spacing * 3.0, range + avg_spacing * 3.0);
755             }
756         }
757     }
758 }
759
760 void vvSlicer::ComputeVFDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int vfExtent[6])
761 {
762     vtkImageData* image=this->GetInput();
763     vfExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mVF->GetOrigin()[0]) /
764                 mVF->GetSpacing()[0];
765     vfExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mVF->GetOrigin()[0]) /
766                 mVF->GetSpacing()[0];
767     vfExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mVF->GetOrigin()[1]) /
768                 mVF->GetSpacing()[1];
769     vfExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mVF->GetOrigin()[1]) /
770                 mVF->GetSpacing()[1];
771     vfExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mVF->GetOrigin()[2]) /
772                 mVF->GetSpacing()[2];
773     vfExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mVF->GetOrigin()[2]) /
774                 mVF->GetSpacing()[2];
775
776     ClipDisplayedExtent(vfExtent,mVOIFilter->GetInput()->GetWholeExtent());
777 }
778
779 void vvSlicer::ComputeOverlayDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int overExtent[6])
780 {
781     vtkImageData* image=this->GetInput();
782     overExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mOverlay->GetOrigin()[0]) /
783                 mOverlay->GetSpacing()[0];
784     overExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mOverlay->GetOrigin()[0]) /
785                 mOverlay->GetSpacing()[0];
786     overExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mOverlay->GetOrigin()[1]) /
787                 mOverlay->GetSpacing()[1];
788     overExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mOverlay->GetOrigin()[1]) /
789                 mOverlay->GetSpacing()[1];
790     overExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mOverlay->GetOrigin()[2]) /
791                 mOverlay->GetSpacing()[2];
792     overExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mOverlay->GetOrigin()[2]) /
793                 mOverlay->GetSpacing()[2];
794     ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
795 }
796
797 void vvSlicer::ComputeFusionDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int fusExtent[6])
798 {
799     vtkImageData* image=this->GetInput();
800     fusExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mFusion->GetOrigin()[0]) /
801                 mFusion->GetSpacing()[0];
802     fusExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mFusion->GetOrigin()[0]) /
803                 mFusion->GetSpacing()[0];
804     fusExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mFusion->GetOrigin()[1]) /
805                 mFusion->GetSpacing()[1];
806     fusExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mFusion->GetOrigin()[1]) /
807                 mFusion->GetSpacing()[1];
808     fusExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mFusion->GetOrigin()[2]) /
809                 mFusion->GetSpacing()[2];
810     fusExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mFusion->GetOrigin()[2]) /
811                 mFusion->GetSpacing()[2];
812     ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
813 }
814
815 void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
816 {
817     bool out = false;
818     int maxBound = 6;
819
820     //2D overlay on 3D image specific case
821     if (refExtent[4] == refExtent[5])
822     {
823         maxBound = 4;
824         extent[4] = refExtent[4];
825         extent[5] = refExtent[5];
826     }
827
828     for (int i = 0; i < maxBound; i = i+2)
829     {
830         //if we are totally outside the image
831         if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] )
832         {
833             out = true;
834             break;
835         }
836         //crop to the limit of the image
837         extent[i] = (extent[i] > refExtent[i]) ? extent[i] : refExtent[i];
838         extent[i] = (extent[i] < refExtent[i+1]) ? extent[i] : refExtent[i+1];
839         extent[i+1] = (extent[i+1] > refExtent[i]) ? extent[i+1] : refExtent[i];
840         extent[i+1] = (extent[i+1] < refExtent[i+1]) ? extent[i+1] : refExtent[i+1];
841     }
842     if (out)
843         for (int i = 0; i < maxBound; i = i+2)
844         {
845             extent[i] = refExtent[i];
846             extent[i+1] = refExtent[i];
847         }
848 }
849
850 void vvSlicer::UpdateOrientation()
851 {
852     // Set the camera position
853     vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
854     if (cam)
855     {
856         switch (this->SliceOrientation)
857         {
858             case vtkImageViewer2::SLICE_ORIENTATION_XY:
859                 cam->SetFocalPoint(0,0,0);
860                 cam->SetPosition(0,0,-1); // -1 if medical ?
861                 cam->SetViewUp(0,-1,0);
862                 break;
863
864             case vtkImageViewer2::SLICE_ORIENTATION_XZ:
865                 cam->SetFocalPoint(0,0,0);
866                 cam->SetPosition(0,-1,0); // 1 if medical ?
867                 cam->SetViewUp(0,0,1);
868                 break;
869
870             case vtkImageViewer2::SLICE_ORIENTATION_YZ:
871                 cam->SetFocalPoint(0,0,0);
872                 cam->SetPosition(-1,0,0); // -1 if medical ?
873                 cam->SetViewUp(0,0,1);
874                 break;
875         }
876     }
877 }
878
879 void vvSlicer::SetOpacity(double s)
880 {
881     this->GetImageActor()->SetOpacity(s);
882 }
883
884 void vvSlicer::SetRenderWindow(int orientation, vtkRenderWindow * rw)
885 {
886     this->Superclass::SetRenderWindow(rw);
887     this->SetupInteractor(rw->GetInteractor());
888     ca->SetImageActor(this->GetImageActor());
889     ca->SetWindowLevel(this->GetWindowLevel());
890     ca->SetText(2, "<slice>");
891     ca->SetText(3, "<window>\n<level>");
892
893     double bounds[6];
894     double max = 65000;
895
896     bounds[0] = -max;
897     bounds[1] = max;
898     bounds[2] = -max;
899     bounds[3] = max;
900     bounds[4] = -max;
901     bounds[5] = max;
902
903     crossCursor->SetModelBounds(bounds);
904     this->GetRenderer()->AddActor(pdmA);
905     this->GetRenderer()->AddActor(ca);
906     this->GetRenderer()->ResetCamera();
907
908     //this is just a mapping between the labeling of the orientations presented to the user and
909     //the one used by vtk
910     SetSliceOrientation(2-(orientation%3));
911     ResetCamera();
912 }
913
914 void vvSlicer::ResetCamera()
915 {
916     if (this->GetInput())
917     {
918         double* input_bounds=this->GetInput()->GetBounds();
919         double bmax=input_bounds[1]-input_bounds[0];
920         if (bmax < input_bounds[3]-input_bounds[2]) bmax=input_bounds[3]-input_bounds[2];
921         if (bmax < input_bounds[5]-input_bounds[4]) bmax=input_bounds[5]-input_bounds[4];
922         this->GetRenderer()->ResetCamera();
923         this->GetRenderer()->GetActiveCamera()->SetParallelScale(bmax/2);
924     }
925 }
926
927 void vvSlicer::SetDisplayMode(bool i)
928 {
929     this->GetImageActor()->SetVisibility(i);
930     this->GetAnnotation()->SetVisibility(i);
931     this->GetRenderer()->SetDraw(i);
932     if (mLandActor)
933         mLandActor->SetVisibility(i);
934     pdmA->SetVisibility(i);
935     if (i)
936         UpdateDisplayExtent();
937 }
938
939 void vvSlicer::FlipHorizontalView()
940 {
941     vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
942     if (cam)
943     {
944         double *position = cam->GetPosition();
945         switch (this->SliceOrientation)
946         {
947             case vtkImageViewer2::SLICE_ORIENTATION_XY:
948                 cam->SetPosition(position[0],position[1],-position[2]);
949                 break;
950
951             case vtkImageViewer2::SLICE_ORIENTATION_XZ:
952                 cam->SetPosition(position[0],-position[1],position[2]);
953                 break;
954
955             case vtkImageViewer2::SLICE_ORIENTATION_YZ:
956                 cam->SetPosition(-position[0],position[1],position[2]);
957                 break;
958         }
959         this->Renderer->ResetCameraClippingRange();
960         this->UpdateDisplayExtent();
961     }
962 }
963
964 void vvSlicer::FlipVerticalView()
965 {
966     vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
967     if (cam)
968     {
969         FlipHorizontalView();
970         double *viewup = cam->GetViewUp();
971         cam->SetViewUp(-viewup[0],-viewup[1],-viewup[2]);
972         this->UpdateDisplayExtent();
973     }
974 }
975
976 void vvSlicer::Render()
977 {
978     if (this->GetWindowLevel()->GetLookupTable() && !this->mOverlay && !this->mFusion)
979     {
980         legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable());
981         legend->SetVisibility(1);
982     }
983     else legend->SetVisibility(0);
984
985     if (ca->GetVisibility())
986     {
987         std::string worldPos = "";
988         std::stringstream world1;
989         std::stringstream world2;
990         std::stringstream world3;
991         world1 << (int)mCurrent[0];
992         world2 << (int)mCurrent[1];
993         world3 << (int)mCurrent[2];
994         double X = (mCurrent[0] - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
995         double Y = (mCurrent[1] - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
996         double Z = (mCurrent[2] - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
997
998         if (pdmA->GetVisibility())
999         {
1000             double x = mCursor[0];
1001             double y = mCursor[1];
1002             double z = mCursor[2];
1003             double xCursor = (x - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1004             double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1005             double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1006
1007             if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0] &&
1008                     xCursor < this->GetImageActor()->GetDisplayExtent()[1]+1 &&
1009                     yCursor >= this->GetImageActor()->GetDisplayExtent()[2] &&
1010                     yCursor < this->GetImageActor()->GetDisplayExtent()[3]+1 &&
1011                     zCursor >= this->GetImageActor()->GetDisplayExtent()[4] &&
1012                     zCursor < this->GetImageActor()->GetDisplayExtent()[5]+1 )
1013             {
1014                 vtkRenderer * renderer = this->Renderer;
1015
1016                 renderer->WorldToView(x,y,z);
1017                 renderer->ViewToNormalizedViewport(x,y,z);
1018                 renderer->NormalizedViewportToViewport(x,y);
1019                 renderer->ViewportToNormalizedDisplay(x,y);
1020                 renderer->NormalizedDisplayToDisplay(x,y);
1021                 crossCursor->SetFocalPoint(x,y,z);
1022             }
1023             else
1024                 crossCursor->SetFocalPoint(-1,-1,z);
1025         }
1026
1027         if (X >= this->GetInput()->GetWholeExtent()[0] &&
1028                 X <= this->GetInput()->GetWholeExtent()[1] &&
1029                 Y >= this->GetInput()->GetWholeExtent()[2] &&
1030                 Y <= this->GetInput()->GetWholeExtent()[3] &&
1031                 Z >= this->GetInput()->GetWholeExtent()[4] &&
1032                 Z <= this->GetInput()->GetWholeExtent()[5])
1033         {
1034             std::stringstream pixel1;
1035             std::stringstream pixel2;
1036             std::stringstream pixel3;
1037             std::stringstream temps;
1038             pixel1 << (int)X;
1039             pixel2 << (int)Y;
1040             pixel3 << (int)Z;
1041             temps << mCurrentTSlice;
1042             double value = this->GetInput()->GetScalarComponentAsDouble(
1043                     (int)X,
1044                     (int)Y,
1045                     (int)Z,0);
1046
1047             std::stringstream val;
1048             val << value;
1049             worldPos += "data value : " + val.str();
1050             worldPos += "\n mm : " + world1.str() + " " + world2.str() + " " + world3.str() + " " + temps.str();
1051             worldPos += "\n pixel : " + pixel1.str() + " " + pixel2.str() + " " + pixel3.str() + " " + temps.str();
1052         }
1053         ca->SetText(1,worldPos.c_str());
1054     }
1055     if (mOverlay && mOverlayActor->GetVisibility())
1056     {
1057         mOverlayMapper->SetWindow(this->GetColorWindow());
1058         mOverlayMapper->SetLevel(this->GetColorLevel());
1059         mOverlayMapper->Update();
1060     }
1061     if (mLandMapper)
1062         UpdateLandmarks();
1063     //this->Superclass::Render();
1064     this->GetRenderWindow()->Render();
1065 }
1066
1067 void vvSlicer::UpdateCursorPosition()
1068 {
1069     if (this->GetImageActor()->GetVisibility())
1070     {
1071         pdmA->SetVisibility(true);
1072         mCursor[0] = mCurrent[0];
1073         mCursor[1] = mCurrent[1];
1074         mCursor[2] = mCurrent[2];
1075         mCursor[3] = mCurrentTSlice;
1076     }
1077 }
1078
1079 void vvSlicer::UpdateLandmarks()
1080 {
1081     vtkPolyData *pd = static_cast<vtkPolyData*>(mLandClipper->GetInput());
1082     if (pd->GetPoints())
1083     {
1084         mLandGlyph->SetRange(0,1);
1085         mLandGlyph->Modified();
1086         mLandGlyph->Update();
1087
1088         mClipBox->Modified();
1089         mLandClipper->Update();
1090         mLandMapper->Update();
1091     }
1092
1093 }
1094
1095 //----------------------------------------------------------------------------
1096 void vvSlicer::SetSlice(int slice)
1097 {
1098     int *range = this->GetSliceRange();
1099     if (range)
1100     {
1101         if (slice < range[0])
1102         {
1103             slice = range[0];
1104         }
1105         else if (slice > range[1])
1106         {
1107             slice = range[1];
1108         }
1109     }
1110
1111     if (this->Slice == slice)
1112     {
1113         return;
1114     }
1115
1116     this->Slice = slice;
1117     SetContourSlice();
1118     this->Modified();
1119     this->UpdateDisplayExtent();
1120     this->Render();
1121 }
1122
1123 void vvSlicer::SetContourSlice()
1124 {
1125     if (mSurfaceCutActors.size() > 0)
1126         for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
1127                 i!=mSurfaceCutActors.end();i++)
1128             (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+
1129                     this->GetImage()->GetOrigin()[this->SliceOrientation]);
1130 }
1131
1132 void vvSlicer::ForceUpdateDisplayExtent()
1133 {
1134     this->UpdateDisplayExtent();
1135 }
1136
1137 int* vvSlicer::GetDisplayExtent()
1138 {
1139     return this->GetImageActor()->GetDisplayExtent();
1140 }
1141
1142 void vvSlicer::PrintSelf(ostream& os, vtkIndent indent)
1143 {
1144     this->Superclass::PrintSelf(os, indent);
1145 }