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 this->SetInput(mImage->GetVTKImages()[t]);
571 if (mVF && mVFActor->GetVisibility())
573 if (mVF->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
574 mVOIFilter->SetInput(mVF->GetVTKImages()[mCurrentTSlice]);
576 if (mOverlay && mOverlayActor->GetVisibility())
578 if (mOverlay->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
579 mOverlayMapper->SetInput(mOverlay->GetVTKImages()[mCurrentTSlice]);
581 if (mFusion && mFusionActor->GetVisibility())
583 if (mFusion->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
584 mFusionMapper->SetInput(mFusion->GetVTKImages()[mCurrentTSlice]);
586 if (mSurfaceCutActors.size() > 0)
587 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
588 i!=mSurfaceCutActors.end();i++)
589 (*i)->SetTimeSlice(mCurrentTSlice);
590 UpdateDisplayExtent();
592 //------------------------------------------------------------------------------
595 //------------------------------------------------------------------------------
596 int vvSlicer::GetTSlice()
598 return mCurrentTSlice;
600 //------------------------------------------------------------------------------
603 //------------------------------------------------------------------------------
604 void vvSlicer::SetSliceOrientation(int orientation)
606 //if 2D image, force to watch in Axial View
608 this->GetInput()->GetWholeExtent(extent);
609 if (extent[5]-extent[4] <= 2)
612 if (orientation < vtkImageViewer2::SLICE_ORIENTATION_YZ ||
613 orientation > vtkImageViewer2::SLICE_ORIENTATION_XY)
615 vtkErrorMacro("Error - invalid slice orientation " << orientation);
619 this->SliceOrientation = orientation;
622 int *range = this->GetSliceRange();
624 this->Slice = static_cast<int>((range[0] + range[1]) * 0.5);
626 this->UpdateOrientation();
627 this->UpdateDisplayExtent();
629 if (this->Renderer && this->GetInput())
631 double scale = this->Renderer->GetActiveCamera()->GetParallelScale();
632 this->Renderer->ResetCamera();
633 this->Renderer->GetActiveCamera()->SetParallelScale(scale);
639 //----------------------------------------------------------------------------
640 void vvSlicer::UpdateDisplayExtent()
642 vtkImageData *input = this->GetInput();
643 if (!input || !this->ImageActor)
647 input->UpdateInformation();
648 int *w_ext;// = input->GetWholeExtent();
650 if (mUseReducedExtent) {
651 w_ext = mReducedExtent;
653 else w_ext = input->GetWholeExtent();
655 switch (this->SliceOrientation)
657 case vtkImageViewer2::SLICE_ORIENTATION_XY:
658 this->ImageActor->SetDisplayExtent(
659 w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice);
660 if (mVF && mVFActor->GetVisibility())
663 ComputeVFDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,vfExtent);
664 mVOIFilter->SetVOI(vfExtent);
665 mGlyphFilter->SetOrientation(1,1,0);
667 // put the vector field between the image and the camera
668 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
669 mVFActor->SetPosition(0,0,ImageActor->GetBounds()[5]+2);
671 mVFActor->SetPosition(0,0,ImageActor->GetBounds()[4]-2);
673 if (mOverlay && mOverlayActor->GetVisibility())
676 ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,overExtent);
677 mOverlayActor->SetDisplayExtent(overExtent);
678 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
679 mOverlayActor->SetPosition(0,0,1);
681 mOverlayActor->SetPosition(0,0,-1);
683 if (mFusion && mFusionActor->GetVisibility())
686 ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,fusExtent);
687 mFusionActor->SetDisplayExtent(fusExtent);
688 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
689 mFusionActor->SetPosition(0,0,1.5);
691 mFusionActor->SetPosition(0,0,-1.5);
698 bounds[0] = ImageActor->GetBounds()[0];
699 bounds[1] = ImageActor->GetBounds()[1];
700 bounds[2] = ImageActor->GetBounds()[2];
701 bounds[3] = ImageActor->GetBounds()[3];
702 bounds[4] = ImageActor->GetBounds()[4]-(0.9/this->GetInput()->GetSpacing()[2]);
703 bounds[5] = ImageActor->GetBounds()[5]+(0.9/this->GetInput()->GetSpacing()[2]);
704 mClipBox->SetBounds(bounds);
707 if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice)
708 mLandActor->SetPosition(0,0,1.5);
710 mLandActor->SetPosition(0,0,-1.5);
714 case vtkImageViewer2::SLICE_ORIENTATION_XZ:
715 this->ImageActor->SetDisplayExtent(
716 w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5]);
717 if (mVF && mVFActor->GetVisibility())
720 ComputeVFDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],vfExtent);
721 mVOIFilter->SetVOI(vfExtent);
722 mGlyphFilter->SetOrientation(1,0,1);
724 // put the vector field between the image aSpacingnd the camera
725 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
726 mVFActor->SetPosition(0,ImageActor->GetBounds()[3]+2,0);
728 mVFActor->SetPosition(0,ImageActor->GetBounds()[2]-2,0);
730 if (mOverlay && mOverlayActor->GetVisibility())
733 ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],overExtent);
734 mOverlayActor->SetDisplayExtent(overExtent);
735 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
736 mOverlayActor->SetPosition(0,1,0);
738 mOverlayActor->SetPosition(0,-1,0);
740 if (mFusion && mFusionActor->GetVisibility())
743 ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],fusExtent);
744 mFusionActor->SetDisplayExtent(fusExtent);
745 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
746 mFusionActor->SetPosition(0,1.5,0);
748 mFusionActor->SetPosition(0,-1.5,0);
755 bounds[0] = ImageActor->GetBounds()[0];
756 bounds[1] = ImageActor->GetBounds()[1];
757 bounds[2] = ImageActor->GetBounds()[2]-(0.5/this->GetInput()->GetSpacing()[1]);
758 bounds[3] = ImageActor->GetBounds()[3]+(0.5/this->GetInput()->GetSpacing()[1]);
759 bounds[4] = ImageActor->GetBounds()[4];
760 bounds[5] = ImageActor->GetBounds()[5];
761 mClipBox->SetBounds(bounds);
764 if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice)
765 mLandActor->SetPosition(0,1.5,0);
767 mLandActor->SetPosition(0,-1.5,0);
771 case vtkImageViewer2::SLICE_ORIENTATION_YZ:
772 this->ImageActor->SetDisplayExtent(
773 this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5]);
774 if (mVF && mVFActor->GetVisibility())
777 ComputeVFDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],vfExtent);
778 mVOIFilter->SetVOI(vfExtent);
779 mGlyphFilter->SetOrientation(0,1,1);
781 // put the vector field between the image and the camera
782 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
783 mVFActor->SetPosition(ImageActor->GetBounds()[1]+2,0,0);
785 mVFActor->SetPosition(ImageActor->GetBounds()[0]-2,0,0);
787 if (mOverlay && mOverlayActor->GetVisibility())
790 ComputeOverlayDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],overExtent);
791 mOverlayActor->SetDisplayExtent(overExtent);
792 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
793 mOverlayActor->SetPosition(1,0,0);
795 mOverlayActor->SetPosition(-1,0,0);
797 if (mFusion && mFusionActor->GetVisibility())
800 ComputeFusionDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],fusExtent);
801 mFusionActor->SetDisplayExtent(fusExtent);
802 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
803 mFusionActor->SetPosition(1.5,0,0);
805 mFusionActor->SetPosition(-1.5,0,0);
812 bounds[0] = ImageActor->GetBounds()[0]-(0.5/this->GetInput()->GetSpacing()[0]);
813 bounds[1] = ImageActor->GetBounds()[1]+(0.5/this->GetInput()->GetSpacing()[0]);
814 bounds[2] = ImageActor->GetBounds()[2];
815 bounds[3] = ImageActor->GetBounds()[3];
816 bounds[4] = ImageActor->GetBounds()[4];
817 bounds[5] = ImageActor->GetBounds()[5];
818 mClipBox->SetBounds(bounds);
821 if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice)
822 mLandActor->SetPosition(1.5,0,0);
824 mLandActor->SetPosition(-1.5,0,0);
829 // Figure out the correct clipping range
833 if (this->InteractorStyle &&
834 this->InteractorStyle->GetAutoAdjustCameraClippingRange())
836 this->Renderer->ResetCameraClippingRange();
840 vtkCamera *cam = this->Renderer->GetActiveCamera();
844 this->ImageActor->GetBounds(bounds);
845 double spos = (double)bounds[this->SliceOrientation * 2];
846 double cpos = (double)cam->GetPosition()[this->SliceOrientation];
847 double range = fabs(spos - cpos);
848 double *spacing = input->GetSpacing();
850 ((double)spacing[0] + (double)spacing[1] + (double)spacing[2]) / 3.0;
851 cam->SetClippingRange(
852 range - avg_spacing * 3.0, range + avg_spacing * 3.0);
857 //----------------------------------------------------------------------------
860 //----------------------------------------------------------------------------
861 void vvSlicer::ComputeVFDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int vfExtent[6])
863 vtkImageData* image=this->GetInput();
864 vfExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mVF->GetOrigin()[0]) /
865 mVF->GetSpacing()[0];
866 vfExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mVF->GetOrigin()[0]) /
867 mVF->GetSpacing()[0];
868 vfExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mVF->GetOrigin()[1]) /
869 mVF->GetSpacing()[1];
870 vfExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mVF->GetOrigin()[1]) /
871 mVF->GetSpacing()[1];
872 vfExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mVF->GetOrigin()[2]) /
873 mVF->GetSpacing()[2];
874 vfExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mVF->GetOrigin()[2]) /
875 mVF->GetSpacing()[2];
877 ClipDisplayedExtent(vfExtent,mVOIFilter->GetInput()->GetWholeExtent());
879 //----------------------------------------------------------------------------
882 //----------------------------------------------------------------------------
883 void vvSlicer::ComputeOverlayDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int overExtent[6])
885 vtkImageData* image=this->GetInput();
886 overExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mOverlay->GetOrigin()[0]) /
887 mOverlay->GetSpacing()[0];
888 overExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mOverlay->GetOrigin()[0]) /
889 mOverlay->GetSpacing()[0];
890 overExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mOverlay->GetOrigin()[1]) /
891 mOverlay->GetSpacing()[1];
892 overExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mOverlay->GetOrigin()[1]) /
893 mOverlay->GetSpacing()[1];
894 overExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mOverlay->GetOrigin()[2]) /
895 mOverlay->GetSpacing()[2];
896 overExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mOverlay->GetOrigin()[2]) /
897 mOverlay->GetSpacing()[2];
898 ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
900 //----------------------------------------------------------------------------
903 //----------------------------------------------------------------------------
904 void vvSlicer::ComputeFusionDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int fusExtent[6])
906 vtkImageData* image=this->GetInput();
907 fusExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mFusion->GetOrigin()[0]) /
908 mFusion->GetSpacing()[0];
909 fusExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mFusion->GetOrigin()[0]) /
910 mFusion->GetSpacing()[0];
911 fusExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mFusion->GetOrigin()[1]) /
912 mFusion->GetSpacing()[1];
913 fusExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mFusion->GetOrigin()[1]) /
914 mFusion->GetSpacing()[1];
915 fusExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mFusion->GetOrigin()[2]) /
916 mFusion->GetSpacing()[2];
917 fusExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mFusion->GetOrigin()[2]) /
918 mFusion->GetSpacing()[2];
919 ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
921 //----------------------------------------------------------------------------
924 //----------------------------------------------------------------------------
925 void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
930 //2D overlay on 3D image specific case
931 if (refExtent[4] == refExtent[5])
934 extent[4] = refExtent[4];
935 extent[5] = refExtent[5];
938 for (int i = 0; i < maxBound; i = i+2)
940 //if we are totally outside the image
941 if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] )
946 //crop to the limit of the image
947 extent[i] = (extent[i] > refExtent[i]) ? extent[i] : refExtent[i];
948 extent[i] = (extent[i] < refExtent[i+1]) ? extent[i] : refExtent[i+1];
949 extent[i+1] = (extent[i+1] > refExtent[i]) ? extent[i+1] : refExtent[i];
950 extent[i+1] = (extent[i+1] < refExtent[i+1]) ? extent[i+1] : refExtent[i+1];
953 for (int i = 0; i < maxBound; i = i+2)
955 extent[i] = refExtent[i];
956 extent[i+1] = refExtent[i];
959 //----------------------------------------------------------------------------
962 //----------------------------------------------------------------------------
963 void vvSlicer::UpdateOrientation()
965 // Set the camera position
966 vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
969 switch (this->SliceOrientation)
971 case vtkImageViewer2::SLICE_ORIENTATION_XY:
972 cam->SetFocalPoint(0,0,0);
973 cam->SetPosition(0,0,-1); // -1 if medical ?
974 cam->SetViewUp(0,-1,0);
977 case vtkImageViewer2::SLICE_ORIENTATION_XZ:
978 cam->SetFocalPoint(0,0,0);
979 cam->SetPosition(0,-1,0); // 1 if medical ?
980 cam->SetViewUp(0,0,1);
983 case vtkImageViewer2::SLICE_ORIENTATION_YZ:
984 cam->SetFocalPoint(0,0,0);
985 cam->SetPosition(-1,0,0); // -1 if medical ?
986 cam->SetViewUp(0,0,1);
991 //----------------------------------------------------------------------------
994 //----------------------------------------------------------------------------
995 void vvSlicer::SetOpacity(double s)
997 this->GetImageActor()->SetOpacity(s);
999 //----------------------------------------------------------------------------
1002 //----------------------------------------------------------------------------
1003 void vvSlicer::SetRenderWindow(int orientation, vtkRenderWindow * rw)
1005 this->Superclass::SetRenderWindow(rw);
1006 this->SetupInteractor(rw->GetInteractor());
1007 ca->SetImageActor(this->GetImageActor());
1008 ca->SetWindowLevel(this->GetWindowLevel());
1009 ca->SetText(2, "<slice>");
1010 ca->SetText(3, "<window>\n<level>");
1022 crossCursor->SetModelBounds(bounds);
1023 this->GetRenderer()->AddActor(pdmA);
1024 this->GetRenderer()->AddActor(ca);
1025 this->GetRenderer()->ResetCamera();
1027 //this is just a mapping between the labeling of the orientations presented to the user and
1028 //the one used by vtk
1029 SetSliceOrientation(2-(orientation%3));
1032 //----------------------------------------------------------------------------
1035 //----------------------------------------------------------------------------
1036 void vvSlicer::ResetCamera()
1038 if (this->GetInput())
1040 double* input_bounds=this->GetInput()->GetBounds();
1041 double bmax=input_bounds[1]-input_bounds[0];
1042 if (bmax < input_bounds[3]-input_bounds[2]) bmax=input_bounds[3]-input_bounds[2];
1043 if (bmax < input_bounds[5]-input_bounds[4]) bmax=input_bounds[5]-input_bounds[4];
1044 this->GetRenderer()->ResetCamera();
1045 this->GetRenderer()->GetActiveCamera()->SetParallelScale(bmax/2);
1048 //----------------------------------------------------------------------------
1051 //----------------------------------------------------------------------------
1052 void vvSlicer::SetDisplayMode(bool i)
1054 this->GetImageActor()->SetVisibility(i);
1055 this->GetAnnotation()->SetVisibility(i);
1056 this->GetRenderer()->SetDraw(i);
1058 mLandActor->SetVisibility(i);
1059 pdmA->SetVisibility(i);
1061 UpdateDisplayExtent();
1063 //----------------------------------------------------------------------------
1066 //----------------------------------------------------------------------------
1067 void vvSlicer::FlipHorizontalView()
1069 vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1072 double *position = cam->GetPosition();
1073 switch (this->SliceOrientation)
1075 case vtkImageViewer2::SLICE_ORIENTATION_XY:
1076 cam->SetPosition(position[0],position[1],-position[2]);
1079 case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1080 cam->SetPosition(position[0],-position[1],position[2]);
1083 case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1084 cam->SetPosition(-position[0],position[1],position[2]);
1087 this->Renderer->ResetCameraClippingRange();
1088 this->UpdateDisplayExtent();
1091 //----------------------------------------------------------------------------
1094 //----------------------------------------------------------------------------
1095 void vvSlicer::FlipVerticalView()
1097 vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1100 FlipHorizontalView();
1101 double *viewup = cam->GetViewUp();
1102 cam->SetViewUp(-viewup[0],-viewup[1],-viewup[2]);
1103 this->UpdateDisplayExtent();
1106 //----------------------------------------------------------------------------
1109 //----------------------------------------------------------------------------
1110 void vvSlicer::SetColorWindow(double window)
1112 vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1115 double level = this->GetWindowLevel()->GetLevel();
1116 LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
1119 this->vtkImageViewer2::SetColorWindow(window);
1121 //----------------------------------------------------------------------------
1124 //----------------------------------------------------------------------------
1125 void vvSlicer::SetColorLevel(double level)
1127 vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1130 double window = this->GetWindowLevel()->GetWindow();
1131 LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
1134 this->vtkImageViewer2::SetColorLevel(level);
1136 //----------------------------------------------------------------------------
1138 //----------------------------------------------------------------------------
1139 // Returns the min an the max value in a 41x41 region around the mouse pointer
1140 void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max)
1142 //Get mouse pointer position in view coordinates
1143 double fLocalExtents[6];
1144 for(int i=0; i<3; i++)
1146 fLocalExtents[i*2 ] = mCurrent[i];
1147 fLocalExtents[i*2+1] = mCurrent[i];
1149 this->Renderer->WorldToView(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
1150 this->Renderer->WorldToView(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
1151 for(int i=0; i<3; i++)
1153 if (i!=SliceOrientation) //SR: assumes that SliceOrientation is valid in ViewCoordinates (???)
1155 fLocalExtents[i*2 ] -= 0.2;
1156 fLocalExtents[i*2+1] += 0.2;
1159 this->Renderer->ViewToWorld(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
1160 this->Renderer->ViewToWorld(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
1162 //Convert to image pixel coordinates (rounded)
1163 int iLocalExtents[6];
1164 for(int i=0; i<3; i++)
1166 fLocalExtents[i*2 ] = (fLocalExtents[i*2 ] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
1167 fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
1169 iLocalExtents[i*2 ] = lrint(fLocalExtents[i*2 ]);
1170 iLocalExtents[i*2+1] = lrint(fLocalExtents[i*2+1]);
1172 if(iLocalExtents[i*2 ]>iLocalExtents[i*2+1])
1173 std::swap(iLocalExtents[i*2], iLocalExtents[i*2+1]);
1176 vtkSmartPointer<vtkExtractVOI> voiFilter = vtkExtractVOI::New();
1177 voiFilter->SetInput(this->GetInput());
1178 voiFilter->SetVOI(iLocalExtents);
1180 vtkSmartPointer<vtkImageAccumulate> accFilter = vtkImageAccumulate::New();
1181 accFilter->SetInput(voiFilter->GetOutput());
1182 accFilter->Update();
1184 min = *(accFilter->GetMin());
1185 max = *(accFilter->GetMax());
1187 //----------------------------------------------------------------------------
1189 //----------------------------------------------------------------------------
1190 void vvSlicer::Render()
1192 if (this->GetWindowLevel()->GetLookupTable() && !this->mOverlay && !this->mFusion)
1194 legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable());
1195 legend->SetVisibility(1);
1197 else legend->SetVisibility(0);
1199 if (ca->GetVisibility())
1201 std::string worldPos = "";
1202 std::stringstream world1;
1203 std::stringstream world2;
1204 std::stringstream world3;
1205 world1 << (int)mCurrent[0];
1206 world2 << (int)mCurrent[1];
1207 world3 << (int)mCurrent[2];
1208 double X = (mCurrent[0] - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1209 double Y = (mCurrent[1] - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1210 double Z = (mCurrent[2] - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1212 if (pdmA->GetVisibility())
1214 double x = mCursor[0];
1215 double y = mCursor[1];
1216 double z = mCursor[2];
1217 double xCursor = (x - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1218 double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1219 double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1221 if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0] &&
1222 xCursor < this->GetImageActor()->GetDisplayExtent()[1]+1 &&
1223 yCursor >= this->GetImageActor()->GetDisplayExtent()[2] &&
1224 yCursor < this->GetImageActor()->GetDisplayExtent()[3]+1 &&
1225 zCursor >= this->GetImageActor()->GetDisplayExtent()[4] &&
1226 zCursor < this->GetImageActor()->GetDisplayExtent()[5]+1 )
1228 vtkRenderer * renderer = this->Renderer;
1230 renderer->WorldToView(x,y,z);
1231 renderer->ViewToNormalizedViewport(x,y,z);
1232 renderer->NormalizedViewportToViewport(x,y);
1233 renderer->ViewportToNormalizedDisplay(x,y);
1234 renderer->NormalizedDisplayToDisplay(x,y);
1235 crossCursor->SetFocalPoint(x,y,z);
1238 crossCursor->SetFocalPoint(-1,-1,z);
1241 if (X >= this->GetInput()->GetWholeExtent()[0] &&
1242 X <= this->GetInput()->GetWholeExtent()[1] &&
1243 Y >= this->GetInput()->GetWholeExtent()[2] &&
1244 Y <= this->GetInput()->GetWholeExtent()[3] &&
1245 Z >= this->GetInput()->GetWholeExtent()[4] &&
1246 Z <= this->GetInput()->GetWholeExtent()[5])
1248 std::stringstream pixel1;
1249 std::stringstream pixel2;
1250 std::stringstream pixel3;
1251 std::stringstream temps;
1255 temps << mCurrentTSlice;
1256 double value = this->GetInput()->GetScalarComponentAsDouble(
1261 std::stringstream val;
1263 worldPos += "data value : " + val.str();
1264 worldPos += "\n mm : " + world1.str() + " " + world2.str() + " " +
1265 world3.str() + " " + temps.str();
1266 worldPos += "\n pixel : " + pixel1.str() + " " + pixel2.str() + " " +
1267 pixel3.str() + " " + temps.str();
1269 ca->SetText(1,worldPos.c_str());
1271 if (mOverlay && mOverlayActor->GetVisibility())
1273 mOverlayMapper->SetWindow(this->GetColorWindow());
1274 mOverlayMapper->SetLevel(this->GetColorLevel());
1275 mOverlayMapper->Update();
1279 //this->Superclass::Render();
1280 this->GetRenderWindow()->Render();
1282 //----------------------------------------------------------------------------
1285 //----------------------------------------------------------------------------
1286 void vvSlicer::UpdateCursorPosition()
1288 if (this->GetImageActor()->GetVisibility())
1290 pdmA->SetVisibility(true);
1291 mCursor[0] = mCurrent[0];
1292 mCursor[1] = mCurrent[1];
1293 mCursor[2] = mCurrent[2];
1294 mCursor[3] = mCurrentTSlice;
1297 //----------------------------------------------------------------------------
1300 //----------------------------------------------------------------------------
1301 void vvSlicer::UpdateLandmarks()
1303 vtkPolyData *pd = static_cast<vtkPolyData*>(mLandClipper->GetInput());
1304 if (pd->GetPoints())
1306 mLandGlyph->SetRange(0,1);
1307 mLandGlyph->Modified();
1308 mLandGlyph->Update();
1310 mClipBox->Modified();
1311 mLandClipper->Update();
1312 mLandMapper->Update();
1316 //----------------------------------------------------------------------------
1319 //----------------------------------------------------------------------------
1320 void vvSlicer::SetSlice(int slice)
1322 int *range = this->GetSliceRange();
1325 if (slice < range[0])
1329 else if (slice > range[1])
1335 if (this->Slice == slice)
1340 this->Slice = slice;
1343 this->UpdateDisplayExtent();
1346 //----------------------------------------------------------------------------
1349 //----------------------------------------------------------------------------
1350 void vvSlicer::SetContourSlice()
1352 if (mSurfaceCutActors.size() > 0)
1353 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
1354 i!=mSurfaceCutActors.end();i++)
1355 (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+
1356 this->GetImage()->GetOrigin()[this->SliceOrientation]);
1358 //----------------------------------------------------------------------------
1361 //----------------------------------------------------------------------------
1362 void vvSlicer::ForceUpdateDisplayExtent()
1364 this->UpdateDisplayExtent();
1366 //----------------------------------------------------------------------------
1369 //----------------------------------------------------------------------------
1370 int* vvSlicer::GetDisplayExtent()
1372 return this->GetImageActor()->GetDisplayExtent();
1374 //----------------------------------------------------------------------------
1377 //----------------------------------------------------------------------------
1378 void vvSlicer::PrintSelf(ostream& os, vtkIndent indent)
1380 this->Superclass::PrintSelf(os, indent);
1382 //----------------------------------------------------------------------------