]> Creatis software - clitk.git/blob - vv/vvSlicer.cxx
remove antique RCS headers
[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, "$Revision: 1.3 $");
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             mOverlayActor = vtkImageActor::New();
242         mOverlayActor->SetInput(mOverlayMapper->GetOutput());
243         mOverlayActor->SetPickable(0);
244         mOverlayActor->SetVisibility(false);
245         mOverlayActor->SetOpacity(0.5);
246         this->UpdateDisplayExtent();
247
248         //stupid but necessary : the Overlay need to be render before fusion
249         if (mFusionActor)
250         {
251             this->GetRenderer()->RemoveActor(mFusionActor);
252             this->GetRenderer()->AddActor(mOverlayActor);
253             this->GetRenderer()->AddActor(mFusionActor);
254         }
255         else
256             this->GetRenderer()->AddActor(mOverlayActor);
257
258         //Synchronize slice
259         SetTSlice(mCurrentTSlice);
260     }
261 }
262
263 void vvSlicer::SetFusion(vvImage::Pointer fusion)
264 {
265     if (fusion->GetVTKImages().size())
266     {
267         mFusion = fusion;
268
269         if (!mFusionMapper)
270             mFusionMapper = vtkImageMapToWindowLevelColors::New();
271         mFusionMapper->SetInput(fusion->GetVTKImages()[0]);
272
273         if (!mFusionActor)
274             mFusionActor = vtkImageActor::New();
275         mFusionActor->SetInput(mFusionMapper->GetOutput());
276         mFusionActor->SetPickable(0);
277         mFusionActor->SetVisibility(false);
278         mFusionActor->SetOpacity(0.7);
279         this->UpdateDisplayExtent();
280         this->GetRenderer()->AddActor(mFusionActor);
281
282         //Synchronize slice
283         SetTSlice(mCurrentTSlice);
284     }
285 }
286
287 void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis)
288 {
289     if (actor_type == "vector")
290     {
291         this->mVFActor->SetVisibility(vis);
292     }
293     if (actor_type == "overlay")
294     {
295         this->mOverlayActor->SetVisibility(vis);
296     }
297     if (actor_type == "fusion")
298     {
299         this->mFusionActor->SetVisibility(vis);
300     }
301     if (actor_type == "contour")
302         this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis);
303     UpdateDisplayExtent();
304 }
305
306 void vvSlicer::SetVF(vvImage::Pointer vf)
307 {
308     if (vf->GetVTKImages().size())
309     {
310         mVF = vf;
311
312         if (!mAAFilter)
313         {
314             mAAFilter=vtkAssignAttribute::New();
315             mVOIFilter = vtkExtractVOI::New();
316             mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
317         }
318         mVOIFilter->SetInput(vf->GetVTKImages()[0]);
319         mAAFilter->SetInput(mVOIFilter->GetOutput());
320         ///This tells VTK to use the scalar (pixel) data of the image to draw the little arrows
321         mAAFilter->Assign(vtkDataSetAttributes::SCALARS, vtkDataSetAttributes::VECTORS, vtkAssignAttribute::POINT_DATA);
322
323         if (!mArrow)
324             mArrow = vvGlyphSource::New();
325         mArrow->SetGlyphTypeToSpecificArrow();
326         mArrow->SetScale(mScale);
327         mArrow->FilledOff();
328
329         // Glyph the gradient vector (with arrows)
330         if (!mGlyphFilter)
331             mGlyphFilter = vvGlyph2D::New();
332         mGlyphFilter->SetInput(mAAFilter->GetOutput());
333         mGlyphFilter->SetSource(mArrow->GetOutput());
334         mGlyphFilter->ScalingOn();
335         mGlyphFilter->SetScaleModeToScaleByVector();
336         mGlyphFilter->OrientOn();
337         mGlyphFilter->SetVectorModeToUseVector();
338         mGlyphFilter->SetColorModeToColorByVector();
339
340         if (!mVFMapper)
341             mVFMapper = vtkPolyDataMapper::New();
342         //mVFMapper->SetInputConnection(mGlyphFilter->GetOutputPort());
343         mVFMapper->SetInput(mGlyphFilter->GetOutput());
344         mVFMapper->ImmediateModeRenderingOn();
345
346         if (!mVFActor)
347             mVFActor = vtkActor::New();
348         mVFActor->SetMapper(mVFMapper);
349         mVFActor->SetPickable(0);
350         this->UpdateDisplayExtent();
351         this->GetRenderer()->AddActor(mVFActor);
352
353         //Synchronize slice
354         SetTSlice(mCurrentTSlice);
355     }
356 }
357
358 void vvSlicer::SetLandmarks(vvLandmarks* landmarks)
359 {
360     mLandmarks = landmarks;
361     if (landmarks)
362     {
363
364         if (!mCross)
365             mCross = vtkCursor3D::New();
366         mCross->SetFocalPoint(0.0,0.0,0.0);
367         mCross->SetModelBounds(-10,10,-10,10,-10,10);
368         mCross->AllOff();
369         mCross->AxesOn();
370
371         if (!mLandGlyph)
372             mLandGlyph = vtkGlyph3D::New();
373         mLandGlyph->SetSource(mCross->GetOutput());
374         mLandGlyph->SetInput(landmarks->GetOutput());
375         //mLandGlyph->SetIndexModeToScalar();
376         mLandGlyph->SetRange(0,1);
377         mLandGlyph->ScalingOff();
378
379         mLandGlyph->SetColorModeToColorByScalar();
380
381         if (!mClipBox)
382             mClipBox = vtkBox::New();
383         if (!mLandClipper)
384             mLandClipper = vtkClipPolyData::New();
385         mLandClipper->InsideOutOn();
386         mLandClipper->SetInput(mLandGlyph->GetOutput());
387         mLandClipper->SetClipFunction(mClipBox);
388
389         if (!mLandMapper)
390             mLandMapper = vtkPolyDataMapper::New();
391         mLandMapper->SetInputConnection(mLandClipper->GetOutputPort());
392         //mLandMapper->ScalarVisibilityOff();
393
394         if (!mLandActor)
395             mLandActor = vtkActor::New();
396         mLandActor->SetMapper(mLandMapper);
397         mLandActor->GetProperty()->SetColor(255,10,212);
398         mLandActor->SetPickable(0);
399         mLandActor->SetVisibility(true);
400         this->UpdateDisplayExtent();
401         this->GetRenderer()->AddActor(mLandActor);
402     }
403 }
404
405 void vvSlicer::RemoveActor(const std::string& actor_type, int overlay_index)
406 {
407     if (actor_type == "vector")
408     {
409         mGlyphFilter=NULL;
410         mVF = NULL;
411         mArrow = NULL;
412         mAAFilter=NULL;
413         mVOIFilter = NULL;
414         mVFMapper = NULL;
415         mVFActor = NULL;
416     }
417     if (actor_type == "overlay")
418     {
419         Renderer->RemoveActor(mOverlayActor);
420         mOverlay = NULL;
421         mOverlayActor = NULL;
422         mOverlayMapper = NULL;
423     }
424     if (actor_type == "fusion")
425     {
426         Renderer->RemoveActor(mFusionActor);
427         mFusion = NULL;
428         mFusionActor = NULL;
429         mFusionMapper = NULL;
430     }
431     if (actor_type == "contour")
432     {
433         Renderer->RemoveActor(this->mSurfaceCutActors[overlay_index]->GetActor());
434         mSurfaceCutActors.erase(mSurfaceCutActors.begin()+overlay_index);
435     }
436 }
437
438 void vvSlicer::SetVFSubSampling(int sub)
439 {
440     if (mVOIFilter)
441     {
442         mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
443         mSubSampling = sub;
444     }
445     UpdateDisplayExtent();
446     Render();
447 }
448
449 void vvSlicer::SetVFScale(int scale)
450 {
451     mScale = scale;
452     if (mArrow)
453         mArrow->SetScale(mScale);
454     UpdateDisplayExtent();
455     Render();
456 }
457
458 void vvSlicer::SetVFLog(int log)
459 {
460     mVFLog = log;
461     if (mGlyphFilter)
462     {
463         mGlyphFilter->SetUseLog(mVFLog);
464         mGlyphFilter->Modified();
465     }
466     UpdateDisplayExtent();
467     Render();
468 }
469
470 void vvSlicer::SetTSlice(int t)
471 {
472     if (t < 0)
473         t = 0;
474     else if ((unsigned int)t >= mImage->GetVTKImages().size())
475         t = mImage->GetVTKImages().size() -1;
476     mCurrentTSlice = t;
477     this->SetInput(mImage->GetVTKImages()[t]);
478     if (mVF && mVFActor->GetVisibility())
479     {
480         if (mVF->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
481             mVOIFilter->SetInput(mVF->GetVTKImages()[mCurrentTSlice]);
482     }
483     if (mOverlay && mOverlayActor->GetVisibility())
484     {
485         if (mOverlay->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
486             mOverlayMapper->SetInput(mOverlay->GetVTKImages()[mCurrentTSlice]);
487     }
488     if (mFusion && mFusionActor->GetVisibility())
489     {
490         if (mFusion->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
491             mFusionMapper->SetInput(mFusion->GetVTKImages()[mCurrentTSlice]);
492     }
493     if (mSurfaceCutActors.size() > 0)
494         for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
495                 i!=mSurfaceCutActors.end();i++)
496             (*i)->SetTimeSlice(mCurrentTSlice);
497     UpdateDisplayExtent();
498 }
499
500 int vvSlicer::GetTSlice()
501 {
502     return mCurrentTSlice;
503 }
504
505 void vvSlicer::SetSliceOrientation(int orientation)
506 {
507     //if 2D image, force to watch in Axial View
508     int extent[6];
509     this->GetInput()->GetWholeExtent(extent);
510     if (extent[5]-extent[4] <= 2)
511         orientation=2;
512
513     if (orientation < vtkImageViewer2::SLICE_ORIENTATION_YZ ||
514             orientation > vtkImageViewer2::SLICE_ORIENTATION_XY)
515     {
516         vtkErrorMacro("Error - invalid slice orientation " << orientation);
517         return;
518     }
519
520     this->SliceOrientation = orientation;
521     
522     // Update the viewer
523     int *range = this->GetSliceRange();
524     if (range)
525         this->Slice = static_cast<int>((range[0] + range[1]) * 0.5);
526
527     this->UpdateOrientation();
528     this->UpdateDisplayExtent();
529
530     if (this->Renderer && this->GetInput())
531     {
532         double scale = this->Renderer->GetActiveCamera()->GetParallelScale();
533         this->Renderer->ResetCamera();
534         this->Renderer->GetActiveCamera()->SetParallelScale(scale);
535     }
536
537     SetContourSlice();
538 }
539
540 //----------------------------------------------------------------------------
541 void vvSlicer::UpdateDisplayExtent()
542 {
543     vtkImageData *input = this->GetInput();
544     if (!input || !this->ImageActor)
545     {
546         return;
547     }
548     input->UpdateInformation();
549     int *w_ext = input->GetWholeExtent();
550
551     switch (this->SliceOrientation)
552     {
553         case vtkImageViewer2::SLICE_ORIENTATION_XY:
554             this->ImageActor->SetDisplayExtent(
555                     w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice);
556             if (mVF && mVFActor->GetVisibility())
557             {
558                 int vfExtent[6];
559                 ComputeVFDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,vfExtent);
560                 mVOIFilter->SetVOI(vfExtent);
561                 mGlyphFilter->SetOrientation(1,1,0);
562                 mVFMapper->Update();
563                 // put the vector field between the image and the camera
564                 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
565                     mVFActor->SetPosition(0,0,ImageActor->GetBounds()[5]+2);
566                 else
567                     mVFActor->SetPosition(0,0,ImageActor->GetBounds()[4]-2);
568             }
569             if (mOverlay && mOverlayActor->GetVisibility())
570             {
571                 int overExtent[6];
572                 ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,overExtent);
573                 mOverlayActor->SetDisplayExtent(overExtent);
574                 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
575                     mOverlayActor->SetPosition(0,0,1);
576                 else
577                     mOverlayActor->SetPosition(0,0,-1);
578             }
579             if (mFusion && mFusionActor->GetVisibility())
580             {
581                 int fusExtent[6];
582                 ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,fusExtent);
583                 mFusionActor->SetDisplayExtent(fusExtent);
584                 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
585                     mFusionActor->SetPosition(0,0,1.5);
586                 else
587                     mFusionActor->SetPosition(0,0,-1.5);
588             }
589             if (mLandActor)
590             {
591                 if (mClipBox)
592                 {
593                     double bounds [6];
594                     bounds[0] = ImageActor->GetBounds()[0];
595                     bounds[1] = ImageActor->GetBounds()[1];
596                     bounds[2] = ImageActor->GetBounds()[2];
597                     bounds[3] = ImageActor->GetBounds()[3];
598                     bounds[4] = ImageActor->GetBounds()[4]-(0.9/this->GetInput()->GetSpacing()[2]);
599                     bounds[5] = ImageActor->GetBounds()[5]+(0.9/this->GetInput()->GetSpacing()[2]);
600                     mClipBox->SetBounds(bounds);
601                     UpdateLandmarks();
602                 }
603                 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
604                     mLandActor->SetPosition(0,0,1.5);
605                 else
606                     mLandActor->SetPosition(0,0,-1.5);
607             }
608             break;
609
610         case vtkImageViewer2::SLICE_ORIENTATION_XZ:
611             this->ImageActor->SetDisplayExtent(
612                     w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5]);
613             if (mVF && mVFActor->GetVisibility())
614             {
615                 int vfExtent[6];
616                 ComputeVFDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],vfExtent);
617                 mVOIFilter->SetVOI(vfExtent);
618                 mGlyphFilter->SetOrientation(1,0,1);
619                 mVFMapper->Update();
620                 // put the vector field between the image aSpacingnd the camera
621                 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
622                     mVFActor->SetPosition(0,ImageActor->GetBounds()[3]+2,0);
623                 else
624                     mVFActor->SetPosition(0,ImageActor->GetBounds()[2]-2,0);
625             }
626             if (mOverlay && mOverlayActor->GetVisibility())
627             {
628                 int overExtent[6];
629                 ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],overExtent);
630                 mOverlayActor->SetDisplayExtent(overExtent);
631                 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
632                     mOverlayActor->SetPosition(0,1,0);
633                 else
634                     mOverlayActor->SetPosition(0,-1,0);
635             }
636             if (mFusion && mFusionActor->GetVisibility())
637             {
638                 int fusExtent[6];
639                 ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],fusExtent);
640                 mFusionActor->SetDisplayExtent(fusExtent);
641                 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
642                     mFusionActor->SetPosition(0,1.5,0);
643                 else
644                     mFusionActor->SetPosition(0,-1.5,0);
645             }
646             if (mLandActor)
647             {
648                 if (mClipBox)
649                 {
650                     double bounds [6];
651                     bounds[0] = ImageActor->GetBounds()[0];
652                     bounds[1] = ImageActor->GetBounds()[1];
653                     bounds[2] = ImageActor->GetBounds()[2]-(0.5/this->GetInput()->GetSpacing()[1]);
654                     bounds[3] = ImageActor->GetBounds()[3]+(0.5/this->GetInput()->GetSpacing()[1]);
655                     bounds[4] = ImageActor->GetBounds()[4];
656                     bounds[5] = ImageActor->GetBounds()[5];
657                     mClipBox->SetBounds(bounds);
658                     UpdateLandmarks();
659                 }
660                 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
661                     mLandActor->SetPosition(0,1.5,0);
662                 else
663                     mLandActor->SetPosition(0,-1.5,0);
664             }
665             break;
666
667         case vtkImageViewer2::SLICE_ORIENTATION_YZ:
668             this->ImageActor->SetDisplayExtent(
669                     this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5]);
670             if (mVF && mVFActor->GetVisibility())
671             {
672                 int vfExtent[6];
673                 ComputeVFDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],vfExtent);
674                 mVOIFilter->SetVOI(vfExtent);
675                 mGlyphFilter->SetOrientation(0,1,1);
676                 mVFMapper->Update();
677                 // put the vector field between the image and the camera
678                 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
679                     mVFActor->SetPosition(ImageActor->GetBounds()[1]+2,0,0);
680                 else
681                     mVFActor->SetPosition(ImageActor->GetBounds()[0]-2,0,0);
682             }
683             if (mOverlay && mOverlayActor->GetVisibility())
684             {
685                 int overExtent[6];
686                 ComputeOverlayDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],overExtent);
687                 mOverlayActor->SetDisplayExtent(overExtent);
688                 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
689                     mOverlayActor->SetPosition(1,0,0);
690                 else
691                     mOverlayActor->SetPosition(-1,0,0);
692             }
693             if (mFusion && mFusionActor->GetVisibility())
694             {
695                 int fusExtent[6];
696                 ComputeFusionDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],fusExtent);
697                 mFusionActor->SetDisplayExtent(fusExtent);
698                 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
699                     mFusionActor->SetPosition(1.5,0,0);
700                 else
701                     mFusionActor->SetPosition(-1.5,0,0);
702             }
703             if (mLandActor)
704             {
705                 if (mClipBox)
706                 {
707                     double bounds [6];
708                     bounds[0] = ImageActor->GetBounds()[0]-(0.5/this->GetInput()->GetSpacing()[0]);
709                     bounds[1] = ImageActor->GetBounds()[1]+(0.5/this->GetInput()->GetSpacing()[0]);
710                     bounds[2] = ImageActor->GetBounds()[2];
711                     bounds[3] = ImageActor->GetBounds()[3];
712                     bounds[4] = ImageActor->GetBounds()[4];
713                     bounds[5] = ImageActor->GetBounds()[5];
714                     mClipBox->SetBounds(bounds);
715                     UpdateLandmarks();
716                 }
717                 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
718                     mLandActor->SetPosition(1.5,0,0);
719                 else
720                     mLandActor->SetPosition(-1.5,0,0);
721             }
722             break;
723     }
724
725     // Figure out the correct clipping range
726
727     if (this->Renderer)
728     {
729         if (this->InteractorStyle &&
730                 this->InteractorStyle->GetAutoAdjustCameraClippingRange())
731         {
732             this->Renderer->ResetCameraClippingRange();
733         }
734         else
735         {
736             vtkCamera *cam = this->Renderer->GetActiveCamera();
737             if (cam)
738             {
739                 double bounds[6];
740                 this->ImageActor->GetBounds(bounds);
741                 double spos = (double)bounds[this->SliceOrientation * 2];
742                 double cpos = (double)cam->GetPosition()[this->SliceOrientation];
743                 double range = fabs(spos - cpos);
744                 double *spacing = input->GetSpacing();
745                 double avg_spacing =
746                     ((double)spacing[0] + (double)spacing[1] + (double)spacing[2]) / 3.0;
747                 cam->SetClippingRange(
748                         range - avg_spacing * 3.0, range + avg_spacing * 3.0);
749             }
750         }
751     }
752 }
753
754 void vvSlicer::ComputeVFDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int vfExtent[6])
755 {
756     vtkImageData* image=this->GetInput();
757     vfExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mVF->GetOrigin()[0]) /
758                 mVF->GetSpacing()[0];
759     vfExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mVF->GetOrigin()[0]) /
760                 mVF->GetSpacing()[0];
761     vfExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mVF->GetOrigin()[1]) /
762                 mVF->GetSpacing()[1];
763     vfExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mVF->GetOrigin()[1]) /
764                 mVF->GetSpacing()[1];
765     vfExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mVF->GetOrigin()[2]) /
766                 mVF->GetSpacing()[2];
767     vfExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mVF->GetOrigin()[2]) /
768                 mVF->GetSpacing()[2];
769
770     ClipDisplayedExtent(vfExtent,mVOIFilter->GetInput()->GetWholeExtent());
771 }
772
773 void vvSlicer::ComputeOverlayDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int overExtent[6])
774 {
775     vtkImageData* image=this->GetInput();
776     overExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mOverlay->GetOrigin()[0]) /
777                 mOverlay->GetSpacing()[0];
778     overExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mOverlay->GetOrigin()[0]) /
779                 mOverlay->GetSpacing()[0];
780     overExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mOverlay->GetOrigin()[1]) /
781                 mOverlay->GetSpacing()[1];
782     overExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mOverlay->GetOrigin()[1]) /
783                 mOverlay->GetSpacing()[1];
784     overExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mOverlay->GetOrigin()[2]) /
785                 mOverlay->GetSpacing()[2];
786     overExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mOverlay->GetOrigin()[2]) /
787                 mOverlay->GetSpacing()[2];
788     ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
789 }
790
791 void vvSlicer::ComputeFusionDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int fusExtent[6])
792 {
793     vtkImageData* image=this->GetInput();
794     fusExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mFusion->GetOrigin()[0]) /
795                 mFusion->GetSpacing()[0];
796     fusExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mFusion->GetOrigin()[0]) /
797                 mFusion->GetSpacing()[0];
798     fusExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mFusion->GetOrigin()[1]) /
799                 mFusion->GetSpacing()[1];
800     fusExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mFusion->GetOrigin()[1]) /
801                 mFusion->GetSpacing()[1];
802     fusExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mFusion->GetOrigin()[2]) /
803                 mFusion->GetSpacing()[2];
804     fusExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mFusion->GetOrigin()[2]) /
805                 mFusion->GetSpacing()[2];
806     ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
807 }
808
809 void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
810 {
811     bool out = false;
812     int maxBound = 6;
813
814     //2D overlay on 3D image specific case
815     if (refExtent[4] == refExtent[5])
816     {
817         maxBound = 4;
818         extent[4] = refExtent[4];
819         extent[5] = refExtent[5];
820     }
821
822     for (int i = 0; i < maxBound; i = i+2)
823     {
824         //if we are totally outside the image
825         if ( extent[i] > refExtent[i+1] or extent[i+1] < refExtent[i] )
826         {
827             out = true;
828             break;
829         }
830         //crop to the limit of the image
831         extent[i] = (extent[i] > refExtent[i]) ? extent[i] : refExtent[i];
832         extent[i] = (extent[i] < refExtent[i+1]) ? extent[i] : refExtent[i+1];
833         extent[i+1] = (extent[i+1] > refExtent[i]) ? extent[i+1] : refExtent[i];
834         extent[i+1] = (extent[i+1] < refExtent[i+1]) ? extent[i+1] : refExtent[i+1];
835     }
836     if (out)
837         for (int i = 0; i < maxBound; i = i+2)
838         {
839             extent[i] = refExtent[i];
840             extent[i+1] = refExtent[i];
841         }
842 }
843
844 void vvSlicer::UpdateOrientation()
845 {
846     // Set the camera position
847     vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
848     if (cam)
849     {
850         switch (this->SliceOrientation)
851         {
852             case vtkImageViewer2::SLICE_ORIENTATION_XY:
853                 cam->SetFocalPoint(0,0,0);
854                 cam->SetPosition(0,0,-1); // -1 if medical ?
855                 cam->SetViewUp(0,-1,0);
856                 break;
857
858             case vtkImageViewer2::SLICE_ORIENTATION_XZ:
859                 cam->SetFocalPoint(0,0,0);
860                 cam->SetPosition(0,-1,0); // 1 if medical ?
861                 cam->SetViewUp(0,0,1);
862                 break;
863
864             case vtkImageViewer2::SLICE_ORIENTATION_YZ:
865                 cam->SetFocalPoint(0,0,0);
866                 cam->SetPosition(-1,0,0); // -1 if medical ?
867                 cam->SetViewUp(0,0,1);
868                 break;
869         }
870     }
871 }
872
873 void vvSlicer::SetOpacity(double s)
874 {
875     this->GetImageActor()->SetOpacity(s);
876 }
877
878 void vvSlicer::SetRenderWindow(int orientation, vtkRenderWindow * rw)
879 {
880     this->Superclass::SetRenderWindow(rw);
881     this->SetupInteractor(rw->GetInteractor());
882     ca->SetImageActor(this->GetImageActor());
883     ca->SetWindowLevel(this->GetWindowLevel());
884     ca->SetText(2, "<slice>");
885     ca->SetText(3, "<window>\n<level>");
886
887     double bounds[6];
888     double max = 65000;
889
890     bounds[0] = -max;
891     bounds[1] = max;
892     bounds[2] = -max;
893     bounds[3] = max;
894     bounds[4] = -max;
895     bounds[5] = max;
896
897     crossCursor->SetModelBounds(bounds);
898     this->GetRenderer()->AddActor(pdmA);
899     this->GetRenderer()->AddActor(ca);
900     this->GetRenderer()->ResetCamera();
901
902     //this is just a mapping between the labeling of the orientations presented to the user and
903     //the one used by vtk
904     SetSliceOrientation(2-(orientation%3));
905     ResetCamera();
906 }
907
908 void vvSlicer::ResetCamera()
909 {
910     if (this->GetInput())
911     {
912         double* input_bounds=this->GetInput()->GetBounds();
913         double bmax=input_bounds[1]-input_bounds[0];
914         if (bmax < input_bounds[3]-input_bounds[2]) bmax=input_bounds[3]-input_bounds[2];
915         if (bmax < input_bounds[5]-input_bounds[4]) bmax=input_bounds[5]-input_bounds[4];
916         this->GetRenderer()->ResetCamera();
917         this->GetRenderer()->GetActiveCamera()->SetParallelScale(bmax/2);
918     }
919 }
920
921 void vvSlicer::SetDisplayMode(bool i)
922 {
923     this->GetImageActor()->SetVisibility(i);
924     this->GetAnnotation()->SetVisibility(i);
925     this->GetRenderer()->SetDraw(i);
926     if (mLandActor)
927         mLandActor->SetVisibility(i);
928     pdmA->SetVisibility(i);
929     if (i)
930         UpdateDisplayExtent();
931 }
932
933 void vvSlicer::FlipHorizontalView()
934 {
935     vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
936     if (cam)
937     {
938         double *position = cam->GetPosition();
939         switch (this->SliceOrientation)
940         {
941             case vtkImageViewer2::SLICE_ORIENTATION_XY:
942                 cam->SetPosition(position[0],position[1],-position[2]);
943                 break;
944
945             case vtkImageViewer2::SLICE_ORIENTATION_XZ:
946                 cam->SetPosition(position[0],-position[1],position[2]);
947                 break;
948
949             case vtkImageViewer2::SLICE_ORIENTATION_YZ:
950                 cam->SetPosition(-position[0],position[1],position[2]);
951                 break;
952         }
953         this->Renderer->ResetCameraClippingRange();
954         this->UpdateDisplayExtent();
955     }
956 }
957
958 void vvSlicer::FlipVerticalView()
959 {
960     vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
961     if (cam)
962     {
963         FlipHorizontalView();
964         double *viewup = cam->GetViewUp();
965         cam->SetViewUp(-viewup[0],-viewup[1],-viewup[2]);
966         this->UpdateDisplayExtent();
967     }
968 }
969
970 void vvSlicer::Render()
971 {
972     if (this->GetWindowLevel()->GetLookupTable() and not this->mOverlay and not
973             this->mFusion)
974     {
975         legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable());
976         legend->SetVisibility(1);
977     }
978     else legend->SetVisibility(0);
979
980     if (ca->GetVisibility())
981     {
982         std::string worldPos = "";
983         std::stringstream world1;
984         std::stringstream world2;
985         std::stringstream world3;
986         world1 << (int)mCurrent[0];
987         world2 << (int)mCurrent[1];
988         world3 << (int)mCurrent[2];
989         double X = (mCurrent[0] - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
990         double Y = (mCurrent[1] - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
991         double Z = (mCurrent[2] - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
992
993         if (pdmA->GetVisibility())
994         {
995             double x = mCursor[0];
996             double y = mCursor[1];
997             double z = mCursor[2];
998             double xCursor = (x - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
999             double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1000             double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1001
1002             if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0] &&
1003                     xCursor < this->GetImageActor()->GetDisplayExtent()[1]+1 &&
1004                     yCursor >= this->GetImageActor()->GetDisplayExtent()[2] &&
1005                     yCursor < this->GetImageActor()->GetDisplayExtent()[3]+1 &&
1006                     zCursor >= this->GetImageActor()->GetDisplayExtent()[4] &&
1007                     zCursor < this->GetImageActor()->GetDisplayExtent()[5]+1 )
1008             {
1009                 vtkRenderer * renderer = this->Renderer;
1010
1011                 renderer->WorldToView(x,y,z);
1012                 renderer->ViewToNormalizedViewport(x,y,z);
1013                 renderer->NormalizedViewportToViewport(x,y);
1014                 renderer->ViewportToNormalizedDisplay(x,y);
1015                 renderer->NormalizedDisplayToDisplay(x,y);
1016                 crossCursor->SetFocalPoint(x,y,z);
1017             }
1018             else
1019                 crossCursor->SetFocalPoint(-1,-1,z);
1020         }
1021
1022         if (X >= this->GetInput()->GetWholeExtent()[0] &&
1023                 X <= this->GetInput()->GetWholeExtent()[1] &&
1024                 Y >= this->GetInput()->GetWholeExtent()[2] &&
1025                 Y <= this->GetInput()->GetWholeExtent()[3] &&
1026                 Z >= this->GetInput()->GetWholeExtent()[4] &&
1027                 Z <= this->GetInput()->GetWholeExtent()[5])
1028         {
1029             std::stringstream pixel1;
1030             std::stringstream pixel2;
1031             std::stringstream pixel3;
1032             std::stringstream temps;
1033             pixel1 << (int)X;
1034             pixel2 << (int)Y;
1035             pixel3 << (int)Z;
1036             temps << mCurrentTSlice;
1037             double value = this->GetInput()->GetScalarComponentAsDouble(
1038                     (int)X,
1039                     (int)Y,
1040                     (int)Z,0);
1041
1042             std::stringstream val;
1043             val << value;
1044             worldPos += "data value : " + val.str();
1045             worldPos += "\n mm : " + world1.str() + " " + world2.str() + " " + world3.str() + " " + temps.str();
1046             worldPos += "\n pixel : " + pixel1.str() + " " + pixel2.str() + " " + pixel3.str() + " " + temps.str();
1047         }
1048         ca->SetText(1,worldPos.c_str());
1049     }
1050     if (mOverlay && mOverlayActor->GetVisibility())
1051     {
1052         mOverlayMapper->SetWindow(this->GetColorWindow());
1053         mOverlayMapper->SetLevel(this->GetColorLevel());
1054         mOverlayMapper->Update();
1055     }
1056     if (mLandMapper)
1057         UpdateLandmarks();
1058     //this->Superclass::Render();
1059     this->GetRenderWindow()->Render();
1060 }
1061
1062 void vvSlicer::UpdateCursorPosition()
1063 {
1064     if (this->GetImageActor()->GetVisibility())
1065     {
1066         pdmA->SetVisibility(true);
1067         mCursor[0] = mCurrent[0];
1068         mCursor[1] = mCurrent[1];
1069         mCursor[2] = mCurrent[2];
1070         mCursor[3] = mCurrentTSlice;
1071     }
1072 }
1073
1074 void vvSlicer::UpdateLandmarks()
1075 {
1076     vtkPolyData *pd = static_cast<vtkPolyData*>(mLandClipper->GetInput());
1077     if (pd->GetPoints())
1078     {
1079         mLandGlyph->SetRange(0,1);
1080         mLandGlyph->Modified();
1081         mLandGlyph->Update();
1082
1083         mClipBox->Modified();
1084         mLandClipper->Update();
1085         mLandMapper->Update();
1086     }
1087
1088 }
1089
1090 //----------------------------------------------------------------------------
1091 void vvSlicer::SetSlice(int slice)
1092 {
1093     int *range = this->GetSliceRange();
1094     if (range)
1095     {
1096         if (slice < range[0])
1097         {
1098             slice = range[0];
1099         }
1100         else if (slice > range[1])
1101         {
1102             slice = range[1];
1103         }
1104     }
1105
1106     if (this->Slice == slice)
1107     {
1108         return;
1109     }
1110
1111     this->Slice = slice;
1112     SetContourSlice();
1113     this->Modified();
1114     this->UpdateDisplayExtent();
1115     this->Render();
1116 }
1117
1118 void vvSlicer::SetContourSlice()
1119 {
1120     if (mSurfaceCutActors.size() > 0)
1121         for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
1122                 i!=mSurfaceCutActors.end();i++)
1123             (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+
1124                     this->GetImage()->GetOrigin()[this->SliceOrientation]);
1125 }
1126
1127 void vvSlicer::ForceUpdateDisplayExtent()
1128 {
1129     this->UpdateDisplayExtent();
1130 }
1131
1132 int* vvSlicer::GetDisplayExtent()
1133 {
1134     return this->GetImageActor()->GetDisplayExtent();
1135 }
1136
1137 void vvSlicer::PrintSelf(ostream& os, vtkIndent indent)
1138 {
1139     this->Superclass::PrintSelf(os, indent);
1140 }