1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
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.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ======================================================================-====*/
21 #include "vvSlicerManagerCommand.h"
22 #include "vvGlyphSource.h"
23 #include "vvGlyph2D.h"
24 #include "vvImageMapToWLColors.h"
26 #include <vtkTextProperty.h>
27 #include <vtkTextActor.h>
28 #include <vtkTextSource.h>
29 #include <vtkActor2D.h>
30 #include <vtkCursor2D.h>
31 #include <vtkPolyDataMapper2D.h>
32 #include <vtkProperty2D.h>
33 #include <vtkCornerAnnotation.h>
34 #include <vtkImageMapToWindowLevelColors.h>
35 #include <vtkImageData.h>
36 #include <vtkImageActor.h>
37 #include <vtkToolkits.h>
38 #include <vtkObjectFactory.h>
39 #include <vtkPointData.h>
40 #include <vtkDataArray.h>
41 #include <vtkFloatArray.h>
42 #include <vtkClipPolyData.h>
43 #include <vtkGlyph3D.h>
45 #include <vtkCursor3D.h>
46 #include <vtkProperty.h>
48 #include <vtkLightCollection.h>
49 #include <vtkScalarBarActor.h>
50 #include <vtkLookupTable.h>
52 #include <vtkRenderer.h>
53 #include <vtkRendererCollection.h>
54 #include <vtkRenderWindow.h>
55 #include <vtkRenderWindowInteractor.h>
56 #include <vtkCamera.h>
57 #include <vtkCallbackCommand.h>
58 #include <vtkCommand.h>
59 #include <vtkPolyDataMapper.h>
62 #include <vtkExtractVOI.h>
63 #include <vtkSphereSource.h>
64 #include <vtkCutter.h>
65 #include <vtkAssignAttribute.h>
66 #include <vtkImageAccumulate.h>
68 vtkCxxRevisionMacro(vvSlicer, "DummyRevision");
69 vtkStandardNewMacro(vvSlicer);
71 //------------------------------------------------------------------------------
76 mUseReducedExtent = false;
78 mCurrent[0] = -VTK_DOUBLE_MAX;
79 mCurrent[1] = -VTK_DOUBLE_MAX;
80 mCurrent[2] = -VTK_DOUBLE_MAX;
82 mCursor[0] = -VTK_DOUBLE_MAX;
83 mCursor[1] = -VTK_DOUBLE_MAX;
84 mCursor[2] = -VTK_DOUBLE_MAX;
85 mCursor[3] = -VTK_DOUBLE_MAX;
91 std::string text = "F1 = sagital; F2 = coronal; F3 = axial\n";
92 text += "F5 = horizontal flip; F6 = vertical flip\n\n";
93 text += "0,1,2,3,4,5 : preset windowing\n";
94 text += "6,7,8,9 : preset colormap\n";
95 text += "z : local windowing\n";
96 text += "r : reset view\n";
97 text += "l : reload image\n";
98 text += "f : fly to mouse position\n";
99 text += "g : go to cross hair position\n\n";
100 text += "Up,down : change slice\n";
101 text += "Left,right : change tenporal slice\n\n";
102 text += "Scrollbar (or w/x) : zoom in/out\n";
103 text += "left button : synchronize all views\n";
104 text += "middle button : grab image\n";
105 text += "right button : change windowing\n";
107 crossCursor = vtkCursor2D::New();
108 crossCursor->AllOff();
109 crossCursor->AxesOn();
110 crossCursor->SetTranslationMode(1);
111 crossCursor->SetRadius(2);
113 pdm = vtkPolyDataMapper2D::New();
114 pdm->SetInput(crossCursor->GetOutput());
116 pdmA = vtkActor2D::New();
117 pdmA->SetMapper(pdm);
118 pdmA->GetProperty()->SetColor(255,10,212);
119 pdmA->SetVisibility(0);
120 pdmA->SetPickable(0);
122 ca = vtkCornerAnnotation::New();
123 ca->GetTextProperty()->SetColor(255,10,212);
124 ca->SetVisibility(1);
132 legend = vtkSmartPointer<vtkScalarBarActor>::New();
133 //legend->SetTitle("test!");
134 legend->SetPosition(0.82,0.18);
135 legend->SetWidth(0.1);
136 legend->SetVisibility(0);
137 legend->SetLabelFormat("%.1f");
138 this->GetRenderer()->AddActor(legend);
140 this->WindowLevel->Delete();
141 this->WindowLevel = vvImageMapToWLColors::New();
142 this->InstallPipeline();
144 //------------------------------------------------------------------------------
147 //------------------------------------------------------------------------------
148 vtkImageMapToWindowLevelColors* vvSlicer::GetOverlayMapper() {
149 return mOverlayMapper.GetPointer();
151 //------------------------------------------------------------------------------
154 //------------------------------------------------------------------------------
155 vtkImageActor* vvSlicer::GetOverlayActor() {
156 return mOverlayActor.GetPointer();
158 //------------------------------------------------------------------------------
161 //------------------------------------------------------------------------------
162 vtkImageMapToWindowLevelColors* vvSlicer::GetFusionMapper() {
163 return mFusionMapper.GetPointer();
165 //------------------------------------------------------------------------------
168 //------------------------------------------------------------------------------
169 vtkImageActor* vvSlicer::GetFusionActor() {
170 return mFusionActor.GetPointer();
172 //------------------------------------------------------------------------------
175 //------------------------------------------------------------------------------
176 vtkActor* vvSlicer::GetVFActor() {
177 return mVFActor.GetPointer();
179 //------------------------------------------------------------------------------
182 //------------------------------------------------------------------------------
183 vtkCornerAnnotation* vvSlicer::GetAnnotation() {
184 return ca.GetPointer();
186 //------------------------------------------------------------------------------
189 //------------------------------------------------------------------------------
190 void vvSlicer::EnableReducedExtent(bool b) {
191 mUseReducedExtent = b;
193 //------------------------------------------------------------------------------
196 //------------------------------------------------------------------------------
197 void vvSlicer::SetReducedExtent(int * ext) {
198 mReducedExtent = ext;
200 //------------------------------------------------------------------------------
203 //------------------------------------------------------------------------------
204 void vvSlicer::AddContour(vvMesh::Pointer contour,bool propagate)
207 mSurfaceCutActors.push_back(new vvMeshActor());
209 mSurfaceCutActors.back()->Init(contour,mCurrentTSlice,mVF);
211 mSurfaceCutActors.back()->Init(contour,mCurrentTSlice);
212 mSurfaceCutActors.back()->SetSlicingOrientation(SliceOrientation);
213 this->GetRenderer()->AddActor(mSurfaceCutActors.back()->GetActor());
217 //------------------------------------------------------------------------------
220 //------------------------------------------------------------------------------
221 void vvSlicer::ToggleContourSuperposition()
223 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
224 i!=mSurfaceCutActors.end();i++)
225 (*i)->ToggleSuperposition();
227 //------------------------------------------------------------------------------
230 //------------------------------------------------------------------------------
231 void vvSlicer::SetCursorColor(int r,int g, int b)
233 pdmA->GetProperty()->SetColor(r,g,b);
235 //------------------------------------------------------------------------------
238 //------------------------------------------------------------------------------
239 void vvSlicer::SetCursorVisibility(bool s)
241 pdmA->SetVisibility(s);
243 //------------------------------------------------------------------------------
246 //------------------------------------------------------------------------------
247 bool vvSlicer::GetCursorVisibility()
249 return pdmA->GetVisibility();
251 //------------------------------------------------------------------------------
254 //------------------------------------------------------------------------------
255 vvSlicer::~vvSlicer()
257 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
258 i!=mSurfaceCutActors.end();i++)
261 //------------------------------------------------------------------------------
264 //------------------------------------------------------------------------------
265 void vvSlicer::SetCurrentPosition(double x, double y, double z, int t)
272 //------------------------------------------------------------------------------
275 //------------------------------------------------------------------------------
276 void vvSlicer::SetImage(vvImage::Pointer image)
278 if (image->GetVTKImages().size())
281 this->Superclass::SetInput(image->GetVTKImages()[0]);
282 this->UpdateDisplayExtent();
284 ca->SetText(0,mFileName.c_str());
287 //------------------------------------------------------------------------------
290 //------------------------------------------------------------------------------
291 void vvSlicer::SetOverlay(vvImage::Pointer overlay)
293 if (overlay->GetVTKImages().size())
298 mOverlayMapper = vtkImageMapToWindowLevelColors::New();
299 mOverlayMapper->SetInput(overlay->GetVTKImages()[0]);
303 mOverlayActor = vtkImageActor::New();
304 mOverlayActor->SetInput(mOverlayMapper->GetOutput());
305 mOverlayActor->SetPickable(0);
306 mOverlayActor->SetVisibility(false);
307 mOverlayActor->SetOpacity(0.5);
308 this->UpdateDisplayExtent();
311 //stupid but necessary : the Overlay need to be rendered before fusion
314 this->GetRenderer()->RemoveActor(mFusionActor);
315 this->GetRenderer()->AddActor(mOverlayActor);
316 this->GetRenderer()->AddActor(mFusionActor);
319 this->GetRenderer()->AddActor(mOverlayActor);
322 SetTSlice(mCurrentTSlice);
325 //------------------------------------------------------------------------------
328 //------------------------------------------------------------------------------
329 void vvSlicer::SetFusion(vvImage::Pointer fusion)
331 if (fusion->GetVTKImages().size())
336 mFusionMapper = vtkImageMapToWindowLevelColors::New();
337 mFusionMapper->SetInput(fusion->GetVTKImages()[0]);
341 mFusionActor = vtkImageActor::New();
342 mFusionActor->SetInput(mFusionMapper->GetOutput());
343 mFusionActor->SetPickable(0);
344 mFusionActor->SetVisibility(false);
345 mFusionActor->SetOpacity(0.7);
346 this->UpdateDisplayExtent();
347 this->GetRenderer()->AddActor(mFusionActor);
351 SetTSlice(mCurrentTSlice);
354 //------------------------------------------------------------------------------
357 //------------------------------------------------------------------------------
358 void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis)
360 if (actor_type == "vector")
362 this->mVFActor->SetVisibility(vis);
364 if (actor_type == "overlay")
366 this->mOverlayActor->SetVisibility(vis);
368 if (actor_type == "fusion")
370 this->mFusionActor->SetVisibility(vis);
372 if (actor_type == "contour")
373 this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis);
374 UpdateDisplayExtent();
376 //------------------------------------------------------------------------------
379 //------------------------------------------------------------------------------
380 void vvSlicer::SetVF(vvImage::Pointer vf)
382 if (vf->GetVTKImages().size())
388 mAAFilter=vtkAssignAttribute::New();
389 mVOIFilter = vtkExtractVOI::New();
390 mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
392 mVOIFilter->SetInput(vf->GetVTKImages()[0]);
393 mAAFilter->SetInput(mVOIFilter->GetOutput());
394 ///This tells VTK to use the scalar (pixel) data of the image to draw the little arrows
395 mAAFilter->Assign(vtkDataSetAttributes::SCALARS, vtkDataSetAttributes::VECTORS, vtkAssignAttribute::POINT_DATA);
398 mArrow = vvGlyphSource::New();
399 mArrow->SetGlyphTypeToSpecificArrow();
400 mArrow->SetScale(mScale);
403 // Glyph the gradient vector (with arrows)
405 mGlyphFilter = vvGlyph2D::New();
406 mGlyphFilter->SetInput(mAAFilter->GetOutput());
407 mGlyphFilter->SetSource(mArrow->GetOutput());
408 mGlyphFilter->ScalingOn();
409 mGlyphFilter->SetScaleModeToScaleByVector();
410 mGlyphFilter->OrientOn();
411 mGlyphFilter->SetVectorModeToUseVector();
412 mGlyphFilter->SetColorModeToColorByVector();
415 mVFMapper = vtkPolyDataMapper::New();
416 //mVFMapper->SetInputConnection(mGlyphFilter->GetOutputPort());
417 mVFMapper->SetInput(mGlyphFilter->GetOutput());
418 mVFMapper->ImmediateModeRenderingOn();
421 mVFActor = vtkActor::New();
422 mVFActor->SetMapper(mVFMapper);
423 mVFActor->SetPickable(0);
424 this->UpdateDisplayExtent();
425 this->GetRenderer()->AddActor(mVFActor);
428 SetTSlice(mCurrentTSlice);
431 //------------------------------------------------------------------------------
434 //------------------------------------------------------------------------------
435 void vvSlicer::SetLandmarks(vvLandmarks* landmarks)
437 mLandmarks = landmarks;
442 mCross = vtkCursor3D::New();
443 mCross->SetFocalPoint(0.0,0.0,0.0);
444 mCross->SetModelBounds(-10,10,-10,10,-10,10);
449 mLandGlyph = vtkGlyph3D::New();
450 mLandGlyph->SetSource(mCross->GetOutput());
451 mLandGlyph->SetInput(landmarks->GetOutput());
452 //mLandGlyph->SetIndexModeToScalar();
453 mLandGlyph->SetRange(0,1);
454 mLandGlyph->ScalingOff();
456 mLandGlyph->SetColorModeToColorByScalar();
459 mClipBox = vtkBox::New();
461 mLandClipper = vtkClipPolyData::New();
462 mLandClipper->InsideOutOn();
463 mLandClipper->SetInput(mLandGlyph->GetOutput());
464 mLandClipper->SetClipFunction(mClipBox);
467 mLandMapper = vtkPolyDataMapper::New();
468 mLandMapper->SetInputConnection(mLandClipper->GetOutputPort());
469 //mLandMapper->ScalarVisibilityOff();
472 mLandActor = vtkActor::New();
473 mLandActor->SetMapper(mLandMapper);
474 mLandActor->GetProperty()->SetColor(255,10,212);
475 mLandActor->SetPickable(0);
476 mLandActor->SetVisibility(true);
477 this->UpdateDisplayExtent();
478 this->GetRenderer()->AddActor(mLandActor);
481 //------------------------------------------------------------------------------
483 //------------------------------------------------------------------------------
484 //FIXME: this function leaks memory, we should fix it someday :)
485 void vvSlicer::RemoveActor(const std::string& actor_type, int overlay_index)
487 if (actor_type == "vector")
489 Renderer->RemoveActor(mVFActor);
498 if (actor_type == "overlay")
500 Renderer->RemoveActor(mOverlayActor);
502 mOverlayActor = NULL;
503 mOverlayMapper = NULL;
505 if (actor_type == "fusion")
507 Renderer->RemoveActor(mFusionActor);
510 mFusionMapper = NULL;
512 if (actor_type == "contour")
514 Renderer->RemoveActor(this->mSurfaceCutActors[overlay_index]->GetActor());
515 mSurfaceCutActors.erase(mSurfaceCutActors.begin()+overlay_index);
518 //------------------------------------------------------------------------------
521 //------------------------------------------------------------------------------
522 void vvSlicer::SetVFSubSampling(int sub)
526 mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
529 UpdateDisplayExtent();
532 //------------------------------------------------------------------------------
535 //------------------------------------------------------------------------------
536 void vvSlicer::SetVFScale(int scale)
540 mArrow->SetScale(mScale);
541 UpdateDisplayExtent();
544 //------------------------------------------------------------------------------
547 //------------------------------------------------------------------------------
548 void vvSlicer::SetVFLog(int log)
553 mGlyphFilter->SetUseLog(mVFLog);
554 mGlyphFilter->Modified();
556 UpdateDisplayExtent();
559 //------------------------------------------------------------------------------
562 //------------------------------------------------------------------------------
563 void vvSlicer::SetTSlice(int t)
567 else if ((unsigned int)t >= mImage->GetVTKImages().size())
568 t = mImage->GetVTKImages().size() -1;
570 if (mCurrentTSlice == t) return;
573 this->SetInput(mImage->GetVTKImages()[t]);
574 if (mVF && mVFActor->GetVisibility())
576 if (mVF->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
577 mVOIFilter->SetInput(mVF->GetVTKImages()[mCurrentTSlice]);
579 if (mOverlay && mOverlayActor->GetVisibility())
581 if (mOverlay->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
582 mOverlayMapper->SetInput(mOverlay->GetVTKImages()[mCurrentTSlice]);
584 if (mFusion && mFusionActor->GetVisibility())
586 if (mFusion->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
587 mFusionMapper->SetInput(mFusion->GetVTKImages()[mCurrentTSlice]);
589 if (mSurfaceCutActors.size() > 0)
590 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
591 i!=mSurfaceCutActors.end();i++)
592 (*i)->SetTimeSlice(mCurrentTSlice);
593 UpdateDisplayExtent();
595 //------------------------------------------------------------------------------
598 //------------------------------------------------------------------------------
599 int vvSlicer::GetTSlice()
601 return mCurrentTSlice;
603 //------------------------------------------------------------------------------
606 //------------------------------------------------------------------------------
607 void vvSlicer::SetSliceOrientation(int orientation)
609 //if 2D image, force to watch in Axial View
611 this->GetInput()->GetWholeExtent(extent);
612 if (extent[5]-extent[4] <= 2)
615 if (orientation < vtkImageViewer2::SLICE_ORIENTATION_YZ ||
616 orientation > vtkImageViewer2::SLICE_ORIENTATION_XY)
618 vtkErrorMacro("Error - invalid slice orientation " << orientation);
622 this->SliceOrientation = orientation;
625 int *range = this->GetSliceRange();
627 this->Slice = static_cast<int>((range[0] + range[1]) * 0.5);
629 this->UpdateOrientation();
630 this->UpdateDisplayExtent();
632 if (this->Renderer && this->GetInput())
634 double scale = this->Renderer->GetActiveCamera()->GetParallelScale();
635 this->Renderer->ResetCamera();
636 this->Renderer->GetActiveCamera()->SetParallelScale(scale);
641 //----------------------------------------------------------------------------
644 //----------------------------------------------------------------------------
645 int * vvSlicer::GetExtent() {
647 if (mUseReducedExtent) {
648 w_ext = mReducedExtent;
650 else w_ext = GetInput()->GetWholeExtent();
653 //----------------------------------------------------------------------------
656 //----------------------------------------------------------------------------
657 int vvSlicer::GetOrientation() {
658 return this->SliceOrientation;
660 //----------------------------------------------------------------------------
663 //----------------------------------------------------------------------------
664 void vvSlicer::UpdateDisplayExtent()
666 vtkImageData *input = this->GetInput();
667 if (!input || !this->ImageActor)
671 input->UpdateInformation();
672 int *w_ext;// = input->GetWholeExtent();
674 if (mUseReducedExtent) {
675 w_ext = mReducedExtent;
677 else w_ext = input->GetWholeExtent();
679 switch (this->SliceOrientation)
681 case vtkImageViewer2::SLICE_ORIENTATION_XY:
682 this->ImageActor->SetDisplayExtent(
683 w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice);
684 if (mVF && mVFActor->GetVisibility())
687 ComputeVFDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,vfExtent);
688 mVOIFilter->SetVOI(vfExtent);
689 mGlyphFilter->SetOrientation(1,1,0);
691 // put the vector field between the image and the camera
692 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
693 mVFActor->SetPosition(0,0,ImageActor->GetBounds()[5]+2);
695 mVFActor->SetPosition(0,0,ImageActor->GetBounds()[4]-2);
697 if (mOverlay && mOverlayActor->GetVisibility())
700 ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,overExtent);
701 mOverlayActor->SetDisplayExtent(overExtent);
702 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
703 mOverlayActor->SetPosition(0,0,1);
705 mOverlayActor->SetPosition(0,0,-1);
707 if (mFusion && mFusionActor->GetVisibility())
710 ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,fusExtent);
711 mFusionActor->SetDisplayExtent(fusExtent);
712 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
713 mFusionActor->SetPosition(0,0,1.5);
715 mFusionActor->SetPosition(0,0,-1.5);
722 bounds[0] = ImageActor->GetBounds()[0];
723 bounds[1] = ImageActor->GetBounds()[1];
724 bounds[2] = ImageActor->GetBounds()[2];
725 bounds[3] = ImageActor->GetBounds()[3];
726 bounds[4] = ImageActor->GetBounds()[4]-(0.9/this->GetInput()->GetSpacing()[2]);
727 bounds[5] = ImageActor->GetBounds()[5]+(0.9/this->GetInput()->GetSpacing()[2]);
728 mClipBox->SetBounds(bounds);
731 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
732 mLandActor->SetPosition(0,0,1.5);
734 mLandActor->SetPosition(0,0,-1.5);
738 case vtkImageViewer2::SLICE_ORIENTATION_XZ:
739 this->ImageActor->SetDisplayExtent(
740 w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5]);
741 if (mVF && mVFActor->GetVisibility())
744 ComputeVFDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],vfExtent);
745 mVOIFilter->SetVOI(vfExtent);
746 mGlyphFilter->SetOrientation(1,0,1);
748 // put the vector field between the image aSpacingnd the camera
749 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
750 mVFActor->SetPosition(0,ImageActor->GetBounds()[3]+2,0);
752 mVFActor->SetPosition(0,ImageActor->GetBounds()[2]-2,0);
754 if (mOverlay && mOverlayActor->GetVisibility())
757 ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],overExtent);
758 mOverlayActor->SetDisplayExtent(overExtent);
759 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
760 mOverlayActor->SetPosition(0,1,0);
762 mOverlayActor->SetPosition(0,-1,0);
764 if (mFusion && mFusionActor->GetVisibility())
767 ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],fusExtent);
768 mFusionActor->SetDisplayExtent(fusExtent);
769 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
770 mFusionActor->SetPosition(0,1.5,0);
772 mFusionActor->SetPosition(0,-1.5,0);
779 bounds[0] = ImageActor->GetBounds()[0];
780 bounds[1] = ImageActor->GetBounds()[1];
781 bounds[2] = ImageActor->GetBounds()[2]-(0.5/this->GetInput()->GetSpacing()[1]);
782 bounds[3] = ImageActor->GetBounds()[3]+(0.5/this->GetInput()->GetSpacing()[1]);
783 bounds[4] = ImageActor->GetBounds()[4];
784 bounds[5] = ImageActor->GetBounds()[5];
785 mClipBox->SetBounds(bounds);
788 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
789 mLandActor->SetPosition(0,1.5,0);
791 mLandActor->SetPosition(0,-1.5,0);
795 case vtkImageViewer2::SLICE_ORIENTATION_YZ:
796 this->ImageActor->SetDisplayExtent(
797 this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5]);
798 if (mVF && mVFActor->GetVisibility())
801 ComputeVFDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],vfExtent);
802 mVOIFilter->SetVOI(vfExtent);
803 mGlyphFilter->SetOrientation(0,1,1);
805 // put the vector field between the image and the camera
806 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
807 mVFActor->SetPosition(ImageActor->GetBounds()[1]+2,0,0);
809 mVFActor->SetPosition(ImageActor->GetBounds()[0]-2,0,0);
811 if (mOverlay && mOverlayActor->GetVisibility())
814 ComputeOverlayDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],overExtent);
815 mOverlayActor->SetDisplayExtent(overExtent);
816 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
817 mOverlayActor->SetPosition(1,0,0);
819 mOverlayActor->SetPosition(-1,0,0);
821 if (mFusion && mFusionActor->GetVisibility())
824 ComputeFusionDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],fusExtent);
825 mFusionActor->SetDisplayExtent(fusExtent);
826 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
827 mFusionActor->SetPosition(1.5,0,0);
829 mFusionActor->SetPosition(-1.5,0,0);
836 bounds[0] = ImageActor->GetBounds()[0]-(0.5/this->GetInput()->GetSpacing()[0]);
837 bounds[1] = ImageActor->GetBounds()[1]+(0.5/this->GetInput()->GetSpacing()[0]);
838 bounds[2] = ImageActor->GetBounds()[2];
839 bounds[3] = ImageActor->GetBounds()[3];
840 bounds[4] = ImageActor->GetBounds()[4];
841 bounds[5] = ImageActor->GetBounds()[5];
842 mClipBox->SetBounds(bounds);
845 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
846 mLandActor->SetPosition(1.5,0,0);
848 mLandActor->SetPosition(-1.5,0,0);
853 // Figure out the correct clipping range
857 if (this->InteractorStyle &&
858 this->InteractorStyle->GetAutoAdjustCameraClippingRange())
860 this->Renderer->ResetCameraClippingRange();
864 vtkCamera *cam = this->Renderer->GetActiveCamera();
868 this->ImageActor->GetBounds(bounds);
869 double spos = (double)bounds[this->SliceOrientation * 2];
870 double cpos = (double)cam->GetPosition()[this->SliceOrientation];
871 double range = fabs(spos - cpos);
872 double *spacing = input->GetSpacing();
874 ((double)spacing[0] + (double)spacing[1] + (double)spacing[2]) / 3.0;
875 cam->SetClippingRange(
876 range - avg_spacing * 3.0, range + avg_spacing * 3.0);
881 //----------------------------------------------------------------------------
884 //----------------------------------------------------------------------------
885 void vvSlicer::ComputeVFDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int vfExtent[6])
887 vtkImageData* image=this->GetInput();
888 vfExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mVF->GetOrigin()[0]) /
889 mVF->GetSpacing()[0];
890 vfExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mVF->GetOrigin()[0]) /
891 mVF->GetSpacing()[0];
892 vfExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mVF->GetOrigin()[1]) /
893 mVF->GetSpacing()[1];
894 vfExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mVF->GetOrigin()[1]) /
895 mVF->GetSpacing()[1];
896 vfExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mVF->GetOrigin()[2]) /
897 mVF->GetSpacing()[2];
898 vfExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mVF->GetOrigin()[2]) /
899 mVF->GetSpacing()[2];
901 ClipDisplayedExtent(vfExtent,mVOIFilter->GetInput()->GetWholeExtent());
903 //----------------------------------------------------------------------------
906 //----------------------------------------------------------------------------
907 void vvSlicer::ComputeOverlayDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int overExtent[6])
909 vtkImageData* image=this->GetInput();
910 overExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mOverlay->GetOrigin()[0]) /
911 mOverlay->GetSpacing()[0];
912 overExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mOverlay->GetOrigin()[0]) /
913 mOverlay->GetSpacing()[0];
914 overExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mOverlay->GetOrigin()[1]) /
915 mOverlay->GetSpacing()[1];
916 overExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mOverlay->GetOrigin()[1]) /
917 mOverlay->GetSpacing()[1];
918 overExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mOverlay->GetOrigin()[2]) /
919 mOverlay->GetSpacing()[2];
920 overExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mOverlay->GetOrigin()[2]) /
921 mOverlay->GetSpacing()[2];
922 ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
924 //----------------------------------------------------------------------------
927 //----------------------------------------------------------------------------
928 void vvSlicer::ComputeFusionDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int fusExtent[6])
930 vtkImageData* image=this->GetInput();
931 fusExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mFusion->GetOrigin()[0]) /
932 mFusion->GetSpacing()[0];
933 fusExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mFusion->GetOrigin()[0]) /
934 mFusion->GetSpacing()[0];
935 fusExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mFusion->GetOrigin()[1]) /
936 mFusion->GetSpacing()[1];
937 fusExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mFusion->GetOrigin()[1]) /
938 mFusion->GetSpacing()[1];
939 fusExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mFusion->GetOrigin()[2]) /
940 mFusion->GetSpacing()[2];
941 fusExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mFusion->GetOrigin()[2]) /
942 mFusion->GetSpacing()[2];
943 ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
945 //----------------------------------------------------------------------------
948 //----------------------------------------------------------------------------
949 void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
954 //2D overlay on 3D image specific case
955 if (refExtent[4] == refExtent[5])
958 extent[4] = refExtent[4];
959 extent[5] = refExtent[5];
962 for (int i = 0; i < maxBound; i = i+2)
964 //if we are totally outside the image
965 if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] )
970 //crop to the limit of the image
971 extent[i] = (extent[i] > refExtent[i]) ? extent[i] : refExtent[i];
972 extent[i] = (extent[i] < refExtent[i+1]) ? extent[i] : refExtent[i+1];
973 extent[i+1] = (extent[i+1] > refExtent[i]) ? extent[i+1] : refExtent[i];
974 extent[i+1] = (extent[i+1] < refExtent[i+1]) ? extent[i+1] : refExtent[i+1];
977 for (int i = 0; i < maxBound; i = i+2)
979 extent[i] = refExtent[i];
980 extent[i+1] = refExtent[i];
983 //----------------------------------------------------------------------------
986 //----------------------------------------------------------------------------
987 void vvSlicer::UpdateOrientation()
989 // Set the camera position
990 vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
993 switch (this->SliceOrientation)
995 case vtkImageViewer2::SLICE_ORIENTATION_XY:
996 cam->SetFocalPoint(0,0,0);
997 cam->SetPosition(0,0,-1); // -1 if medical ?
998 cam->SetViewUp(0,-1,0);
1001 case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1002 cam->SetFocalPoint(0,0,0);
1003 cam->SetPosition(0,-1,0); // 1 if medical ?
1004 cam->SetViewUp(0,0,1);
1007 case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1008 cam->SetFocalPoint(0,0,0);
1009 cam->SetPosition(-1,0,0); // -1 if medical ?
1010 cam->SetViewUp(0,0,1);
1015 //----------------------------------------------------------------------------
1018 //----------------------------------------------------------------------------
1019 void vvSlicer::SetOpacity(double s)
1021 this->GetImageActor()->SetOpacity(s);
1023 //----------------------------------------------------------------------------
1026 //----------------------------------------------------------------------------
1027 void vvSlicer::SetRenderWindow(int orientation, vtkRenderWindow * rw)
1029 this->Superclass::SetRenderWindow(rw);
1030 this->SetupInteractor(rw->GetInteractor());
1031 ca->SetImageActor(this->GetImageActor());
1032 ca->SetWindowLevel(this->GetWindowLevel());
1033 ca->SetText(2, "<slice>");
1034 ca->SetText(3, "<window>\n<level>");
1046 crossCursor->SetModelBounds(bounds);
1047 this->GetRenderer()->AddActor(pdmA);
1048 this->GetRenderer()->AddActor(ca);
1049 this->GetRenderer()->ResetCamera();
1051 //this is just a mapping between the labeling of the orientations presented to the user and
1052 //the one used by vtk
1053 SetSliceOrientation(2-(orientation%3));
1056 //----------------------------------------------------------------------------
1059 //----------------------------------------------------------------------------
1060 void vvSlicer::ResetCamera()
1062 if (this->GetInput())
1064 double* input_bounds=this->GetInput()->GetBounds();
1065 double bmax=input_bounds[1]-input_bounds[0];
1066 if (bmax < input_bounds[3]-input_bounds[2]) bmax=input_bounds[3]-input_bounds[2];
1067 if (bmax < input_bounds[5]-input_bounds[4]) bmax=input_bounds[5]-input_bounds[4];
1068 this->GetRenderer()->ResetCamera();
1069 this->GetRenderer()->GetActiveCamera()->SetParallelScale(bmax/2);
1072 //----------------------------------------------------------------------------
1075 //----------------------------------------------------------------------------
1076 void vvSlicer::SetDisplayMode(bool i)
1078 this->GetImageActor()->SetVisibility(i);
1079 this->GetAnnotation()->SetVisibility(i);
1080 this->GetRenderer()->SetDraw(i);
1082 mLandActor->SetVisibility(i);
1083 pdmA->SetVisibility(i);
1085 UpdateDisplayExtent();
1087 //----------------------------------------------------------------------------
1090 //----------------------------------------------------------------------------
1091 void vvSlicer::FlipHorizontalView()
1093 vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1096 double *position = cam->GetPosition();
1097 switch (this->SliceOrientation)
1099 case vtkImageViewer2::SLICE_ORIENTATION_XY:
1100 cam->SetPosition(position[0],position[1],-position[2]);
1103 case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1104 cam->SetPosition(position[0],-position[1],position[2]);
1107 case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1108 cam->SetPosition(-position[0],position[1],position[2]);
1111 this->Renderer->ResetCameraClippingRange();
1112 this->UpdateDisplayExtent();
1115 //----------------------------------------------------------------------------
1118 //----------------------------------------------------------------------------
1119 void vvSlicer::FlipVerticalView()
1121 vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1124 FlipHorizontalView();
1125 double *viewup = cam->GetViewUp();
1126 cam->SetViewUp(-viewup[0],-viewup[1],-viewup[2]);
1127 this->UpdateDisplayExtent();
1130 //----------------------------------------------------------------------------
1133 //----------------------------------------------------------------------------
1134 void vvSlicer::SetColorWindow(double window)
1136 vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1139 double level = this->GetWindowLevel()->GetLevel();
1140 LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
1143 this->vtkImageViewer2::SetColorWindow(window);
1145 //----------------------------------------------------------------------------
1148 //----------------------------------------------------------------------------
1149 void vvSlicer::SetColorLevel(double level)
1151 vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1154 double window = this->GetWindowLevel()->GetWindow();
1155 LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
1158 this->vtkImageViewer2::SetColorLevel(level);
1160 //----------------------------------------------------------------------------
1162 //----------------------------------------------------------------------------
1163 // Returns the min an the max value in a 41x41 region around the mouse pointer
1164 void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max)
1166 //Get mouse pointer position in view coordinates
1167 double fLocalExtents[6];
1168 for(int i=0; i<3; i++)
1170 fLocalExtents[i*2 ] = mCurrent[i];
1171 fLocalExtents[i*2+1] = mCurrent[i];
1173 this->Renderer->WorldToView(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
1174 this->Renderer->WorldToView(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
1175 for(int i=0; i<3; i++)
1177 if (i!=SliceOrientation) //SR: assumes that SliceOrientation is valid in ViewCoordinates (???)
1179 fLocalExtents[i*2 ] -= 0.2;
1180 fLocalExtents[i*2+1] += 0.2;
1183 this->Renderer->ViewToWorld(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
1184 this->Renderer->ViewToWorld(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
1186 //Convert to image pixel coordinates (rounded)
1187 int iLocalExtents[6];
1188 for(int i=0; i<3; i++)
1190 fLocalExtents[i*2 ] = (fLocalExtents[i*2 ] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
1191 fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
1193 iLocalExtents[i*2 ] = lrint(fLocalExtents[i*2 ]);
1194 iLocalExtents[i*2+1] = lrint(fLocalExtents[i*2+1]);
1196 if(iLocalExtents[i*2 ]>iLocalExtents[i*2+1])
1197 std::swap(iLocalExtents[i*2], iLocalExtents[i*2+1]);
1200 vtkSmartPointer<vtkExtractVOI> voiFilter = vtkExtractVOI::New();
1201 voiFilter->SetInput(this->GetInput());
1202 voiFilter->SetVOI(iLocalExtents);
1204 vtkSmartPointer<vtkImageAccumulate> accFilter = vtkImageAccumulate::New();
1205 accFilter->SetInput(voiFilter->GetOutput());
1206 accFilter->Update();
1208 min = *(accFilter->GetMin());
1209 max = *(accFilter->GetMax());
1211 //----------------------------------------------------------------------------
1213 //----------------------------------------------------------------------------
1214 void vvSlicer::Render()
1217 //DD(SliceOrientation);
1218 if (this->GetWindowLevel()->GetLookupTable() && !this->mOverlay && !this->mFusion)
1220 legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable());
1221 legend->SetVisibility(1);
1223 else legend->SetVisibility(0);
1225 if (ca->GetVisibility())
1227 std::string worldPos = "";
1228 std::stringstream world1;
1229 std::stringstream world2;
1230 std::stringstream world3;
1231 world1 << (int)mCurrent[0];
1232 world2 << (int)mCurrent[1];
1233 world3 << (int)mCurrent[2];
1234 double X = (mCurrent[0] - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1235 double Y = (mCurrent[1] - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1236 double Z = (mCurrent[2] - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1238 if (pdmA->GetVisibility())
1240 double x = mCursor[0];
1241 double y = mCursor[1];
1242 double z = mCursor[2];
1243 double xCursor = (x - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1244 double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1245 double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1247 if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0] &&
1248 xCursor < this->GetImageActor()->GetDisplayExtent()[1]+1 &&
1249 yCursor >= this->GetImageActor()->GetDisplayExtent()[2] &&
1250 yCursor < this->GetImageActor()->GetDisplayExtent()[3]+1 &&
1251 zCursor >= this->GetImageActor()->GetDisplayExtent()[4] &&
1252 zCursor < this->GetImageActor()->GetDisplayExtent()[5]+1 )
1254 vtkRenderer * renderer = this->Renderer;
1256 renderer->WorldToView(x,y,z);
1257 renderer->ViewToNormalizedViewport(x,y,z);
1258 renderer->NormalizedViewportToViewport(x,y);
1259 renderer->ViewportToNormalizedDisplay(x,y);
1260 renderer->NormalizedDisplayToDisplay(x,y);
1261 crossCursor->SetFocalPoint(x,y,z);
1264 crossCursor->SetFocalPoint(-1,-1,z);
1267 if (X >= this->GetInput()->GetWholeExtent()[0] &&
1268 X <= this->GetInput()->GetWholeExtent()[1] &&
1269 Y >= this->GetInput()->GetWholeExtent()[2] &&
1270 Y <= this->GetInput()->GetWholeExtent()[3] &&
1271 Z >= this->GetInput()->GetWholeExtent()[4] &&
1272 Z <= this->GetInput()->GetWholeExtent()[5])
1274 std::stringstream pixel1;
1275 std::stringstream pixel2;
1276 std::stringstream pixel3;
1277 std::stringstream temps;
1281 temps << mCurrentTSlice;
1282 double value = this->GetInput()->GetScalarComponentAsDouble(
1287 std::stringstream val;
1289 worldPos += "data value : " + val.str();
1290 worldPos += "\n mm : " + world1.str() + " " + world2.str() + " " +
1291 world3.str() + " " + temps.str();
1292 worldPos += "\n pixel : " + pixel1.str() + " " + pixel2.str() + " " +
1293 pixel3.str() + " " + temps.str();
1295 ca->SetText(1,worldPos.c_str());
1297 if (mOverlay && mOverlayActor->GetVisibility())
1299 mOverlayMapper->SetWindow(this->GetColorWindow());
1300 mOverlayMapper->SetLevel(this->GetColorLevel());
1301 mOverlayMapper->Update();
1305 //this->Superclass::Render();
1306 this->GetRenderWindow()->Render();
1308 //----------------------------------------------------------------------------
1311 //----------------------------------------------------------------------------
1312 void vvSlicer::UpdateCursorPosition()
1314 if (this->GetImageActor()->GetVisibility())
1316 pdmA->SetVisibility(true);
1317 mCursor[0] = mCurrent[0];
1318 mCursor[1] = mCurrent[1];
1319 mCursor[2] = mCurrent[2];
1320 mCursor[3] = mCurrentTSlice;
1323 //----------------------------------------------------------------------------
1326 //----------------------------------------------------------------------------
1327 void vvSlicer::UpdateLandmarks()
1329 vtkPolyData *pd = static_cast<vtkPolyData*>(mLandClipper->GetInput());
1330 if (pd->GetPoints())
1332 mLandGlyph->SetRange(0,1);
1333 mLandGlyph->Modified();
1334 mLandGlyph->Update();
1336 mClipBox->Modified();
1337 mLandClipper->Update();
1338 mLandMapper->Update();
1342 //----------------------------------------------------------------------------
1345 //----------------------------------------------------------------------------
1346 void vvSlicer::SetSlice(int slice)
1348 int *range = this->GetSliceRange();
1351 if (slice < range[0])
1355 else if (slice > range[1])
1361 if (this->Slice == slice)
1366 this->Slice = slice;
1369 this->UpdateDisplayExtent();
1372 //----------------------------------------------------------------------------
1375 //----------------------------------------------------------------------------
1376 void vvSlicer::SetContourSlice()
1378 if (mSurfaceCutActors.size() > 0)
1379 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
1380 i!=mSurfaceCutActors.end();i++)
1381 (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+
1382 this->GetImage()->GetOrigin()[this->SliceOrientation]);
1384 //----------------------------------------------------------------------------
1387 //----------------------------------------------------------------------------
1388 void vvSlicer::ForceUpdateDisplayExtent()
1390 this->UpdateDisplayExtent();
1392 //----------------------------------------------------------------------------
1395 //----------------------------------------------------------------------------
1396 int* vvSlicer::GetDisplayExtent()
1398 return this->GetImageActor()->GetDisplayExtent();
1400 //----------------------------------------------------------------------------
1403 //----------------------------------------------------------------------------
1404 void vvSlicer::PrintSelf(ostream& os, vtkIndent indent)
1406 this->Superclass::PrintSelf(os, indent);
1408 //----------------------------------------------------------------------------