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://www.centreleonberard.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"
25 #include <vtkTextProperty.h>
26 #include <vtkTextActor.h>
27 #include <vtkTextSource.h>
28 #include <vtkActor2D.h>
29 #include <vtkCursor2D.h>
30 #include <vtkPolyDataMapper2D.h>
31 #include <vtkProperty2D.h>
32 #include <vtkCornerAnnotation.h>
33 #include <vtkImageMapToWindowLevelColors.h>
34 #include <vtkImageData.h>
35 #include <vtkImageActor.h>
36 #include <vvBlendImageActor.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>
67 #include <vtkImageReslice.h>
68 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
69 # include <vtkImageMapper3D.h>
72 vtkCxxRevisionMacro(vvSlicer, "DummyRevision");
73 vtkStandardNewMacro(vvSlicer);
74 static void copyExtent(int* in, int* to){
75 for(int i=0; i<6; ++i) to[i]=in[i];
77 //------------------------------------------------------------------------------
80 this->UnInstallPipeline();
82 mReducedExtent = new int[6];
84 mCurrentFusionTSlice = 0;
85 mCurrentOverlayTSlice = 0;
86 mUseReducedExtent = false;
88 mCurrent[0] = -VTK_DOUBLE_MAX;
89 mCurrent[1] = -VTK_DOUBLE_MAX;
90 mCurrent[2] = -VTK_DOUBLE_MAX;
92 mCursor[0] = 0;//-VTK_DOUBLE_MAX;
93 mCursor[1] = 0;//-VTK_DOUBLE_MAX;
94 mCursor[2] = 0;//-VTK_DOUBLE_MAX;
95 mCursor[3] = 0;//-VTK_DOUBLE_MAX;
105 crossCursor = vtkSmartPointer<vtkCursor2D>::New();
106 crossCursor->AllOff();
107 crossCursor->AxesOn();
108 crossCursor->SetTranslationMode(1);
109 crossCursor->SetRadius(2);
111 pdm = vtkSmartPointer<vtkPolyDataMapper2D>::New();
112 pdm->SetInput(crossCursor->GetOutput());
114 pdmA = vtkSmartPointer<vtkActor2D>::New();
115 pdmA->SetMapper(pdm);
116 pdmA->GetProperty()->SetColor(255,10,212);
117 pdmA->SetVisibility(0);
118 pdmA->SetPickable(0);
120 ca = vtkSmartPointer<vtkCornerAnnotation>::New();
121 ca->GetTextProperty()->SetColor(255,10,212);
122 ca->SetVisibility(1);
130 legend = vtkSmartPointer<vtkScalarBarActor>::New();
131 //legend->SetTitle("test!");
132 legend->SetPosition(0.82,0.18);
133 legend->SetWidth(0.1);
134 legend->SetVisibility(0);
135 legend->SetLabelFormat("%.1f");
136 this->GetRenderer()->AddActor(legend);
137 showFusionLegend = false;
139 this->InstallPipeline();
141 mLinkOverlayWindowLevel = true;
143 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
144 this->GetImageActor()->GetMapper()->BorderOn();
147 mSlicingTransform = vtkSmartPointer<vtkTransform>::New();
148 mConcatenatedTransform = vtkSmartPointer<vtkTransform>::New();
149 mConcatenatedFusionTransform = vtkSmartPointer<vtkTransform>::New();
150 mConcatenatedOverlayTransform = vtkSmartPointer<vtkTransform>::New();
152 //------------------------------------------------------------------------------
155 //------------------------------------------------------------------------------
156 vtkImageMapToWindowLevelColors* vvSlicer::GetOverlayMapper()
158 return mOverlayMapper.GetPointer();
160 //------------------------------------------------------------------------------
163 //------------------------------------------------------------------------------
164 vvBlendImageActor* vvSlicer::GetOverlayActor()
166 return mOverlayActor.GetPointer();
168 //------------------------------------------------------------------------------
171 //------------------------------------------------------------------------------
172 vtkImageMapToColors* vvSlicer::GetFusionMapper()
174 return mFusionMapper.GetPointer();
176 //------------------------------------------------------------------------------
179 //------------------------------------------------------------------------------
180 vtkImageActor* vvSlicer::GetFusionActor()
182 return mFusionActor.GetPointer();
184 //------------------------------------------------------------------------------
187 //------------------------------------------------------------------------------
188 vtkActor* vvSlicer::GetVFActor()
190 return mVFActor.GetPointer();
192 //------------------------------------------------------------------------------
195 //------------------------------------------------------------------------------
196 vtkCornerAnnotation* vvSlicer::GetAnnotation()
198 return ca.GetPointer();
200 //------------------------------------------------------------------------------
203 //------------------------------------------------------------------------------
204 void vvSlicer::EnableReducedExtent(bool b)
206 mUseReducedExtent = b;
208 //------------------------------------------------------------------------------
211 //------------------------------------------------------------------------------
212 void vvSlicer::SetReducedExtent(int * ext)
214 copyExtent(ext, mReducedExtent);
216 //------------------------------------------------------------------------------
219 //------------------------------------------------------------------------------
220 void vvSlicer::AddContour(vvMesh::Pointer contour,bool propagate)
223 mSurfaceCutActors.push_back(new vvMeshActor());
225 mSurfaceCutActors.back()->Init(contour,mCurrentTSlice,mVF);
227 mSurfaceCutActors.back()->Init(contour,mCurrentTSlice);
228 mSurfaceCutActors.back()->SetSlicingOrientation(SliceOrientation);
229 this->GetRenderer()->AddActor(mSurfaceCutActors.back()->GetActor());
233 //------------------------------------------------------------------------------
236 //------------------------------------------------------------------------------
237 void vvSlicer::ToggleContourSuperposition()
239 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
240 i!=mSurfaceCutActors.end(); i++)
241 (*i)->ToggleSuperposition();
243 //------------------------------------------------------------------------------
246 //------------------------------------------------------------------------------
247 void vvSlicer::SetCursorColor(int r,int g, int b)
249 pdmA->GetProperty()->SetColor(r,g,b);
251 //------------------------------------------------------------------------------
254 //------------------------------------------------------------------------------
255 void vvSlicer::SetCursorVisibility(bool s)
257 pdmA->SetVisibility(s);
259 //------------------------------------------------------------------------------
262 //------------------------------------------------------------------------------
263 bool vvSlicer::GetCursorVisibility()
265 return pdmA->GetVisibility();
267 //------------------------------------------------------------------------------
270 //------------------------------------------------------------------------------
271 void vvSlicer::SetCornerAnnotationVisibility(bool s)
273 ca->SetVisibility(s);
275 //------------------------------------------------------------------------------
278 //------------------------------------------------------------------------------
279 bool vvSlicer::GetCornerAnnotationVisibility()
281 return ca->GetVisibility();
283 //------------------------------------------------------------------------------
286 //------------------------------------------------------------------------------
287 vvSlicer::~vvSlicer()
289 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
290 i!=mSurfaceCutActors.end(); i++)
292 delete [] mReducedExtent;
294 //------------------------------------------------------------------------------
296 //------------------------------------------------------------------------------
297 double* vvSlicer::GetCurrentPosition()
299 return mCurrentBeforeSlicingTransform;
301 //------------------------------------------------------------------------------
303 //------------------------------------------------------------------------------
304 void vvSlicer::SetCurrentPosition(double x, double y, double z, int t)
306 mCurrentBeforeSlicingTransform[0]=x;
307 mCurrentBeforeSlicingTransform[1]=y;
308 mCurrentBeforeSlicingTransform[2]=z;
309 mSlicingTransform->GetInverse()->TransformPoint(mCurrentBeforeSlicingTransform,mCurrent);
312 //------------------------------------------------------------------------------
315 //------------------------------------------------------------------------------
316 void vvSlicer::SetImage(vvImage::Pointer image)
318 if (image->GetVTKImages().size()) {
321 if (!mImageReslice) {
322 mImageReslice = vtkSmartPointer<vtkImageReslice>::New();
323 mImageReslice->SetInterpolationModeToLinear();
324 mImageReslice->AutoCropOutputOn();
325 mImageReslice->SetBackgroundColor(-1000,-1000,-1000,1);
328 mConcatenatedTransform->Identity();
329 mConcatenatedTransform->Concatenate(mImage->GetTransform()[0]);
330 mConcatenatedTransform->Concatenate(mSlicingTransform);
331 mImageReslice->SetResliceTransform(mConcatenatedTransform);
332 mImageReslice->SetInput(0, mImage->GetFirstVTKImageData());
333 mImageReslice->UpdateInformation();
335 this->Superclass::SetInput(mImageReslice->GetOutput());
338 this->GetInput()->GetWholeExtent(extent);
340 // Prevent crash when reload -> change slice if outside extent
341 if (Slice < extent[SliceOrientation*2] || Slice>=extent[SliceOrientation*2+1]) {
342 Slice = (extent[SliceOrientation*2+1]+extent[SliceOrientation*2])/2.0;
345 // Make sure that the required part image has been computed
346 extent[SliceOrientation*2] = Slice;
347 extent[SliceOrientation*2+1] = Slice;
348 mImageReslice->GetOutput()->SetUpdateExtent(extent);
349 mImageReslice->GetOutput()->Update();
351 this->UpdateDisplayExtent();
354 ca->SetText(0,mFileName.c_str());
357 //------------------------------------------------------------------------------
360 //------------------------------------------------------------------------------
361 void vvSlicer::SetOverlay(vvImage::Pointer overlay)
363 if (overlay->GetVTKImages().size()) {
366 if (!mOverlayReslice) {
367 mOverlayReslice = vtkSmartPointer<vtkImageReslice>::New();
368 mOverlayReslice->SetInterpolationModeToLinear();
369 mOverlayReslice->AutoCropOutputOn();
370 mOverlayReslice->SetBackgroundColor(-1000,-1000,-1000,1);
373 mConcatenatedOverlayTransform->Identity();
374 mConcatenatedOverlayTransform->Concatenate(mOverlay->GetTransform()[0]);
375 mConcatenatedOverlayTransform->Concatenate(mSlicingTransform);
376 mOverlayReslice->SetResliceTransform(mConcatenatedOverlayTransform);
377 mOverlayReslice->SetInput(0, mOverlay->GetFirstVTKImageData());
378 mImageReslice->UpdateInformation();
381 mOverlayMapper = vtkSmartPointer<vtkImageMapToWindowLevelColors>::New();
382 mOverlayMapper->SetInput(mOverlayReslice->GetOutput());
384 if (!mOverlayActor) {
385 mOverlayActor = vtkSmartPointer<vvBlendImageActor>::New();
386 mOverlayActor->SetInput(mOverlayMapper->GetOutput());
387 mOverlayActor->SetPickable(0);
388 mOverlayActor->SetVisibility(true);
389 mOverlayActor->SetOpacity(0.5);
390 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
391 mOverlayActor->GetMapper()->BorderOn();
395 //stupid but necessary : the Overlay need to be rendered before fusion
397 this->GetRenderer()->RemoveActor(mFusionActor);
398 this->GetRenderer()->AddActor(mOverlayActor);
399 this->GetRenderer()->AddActor(mFusionActor);
401 this->GetRenderer()->AddActor(mOverlayActor);
403 //Synchronize orientation and slice
404 AdjustResliceToSliceOrientation(mOverlayReslice);
405 this->UpdateDisplayExtent();
406 this->SetTSlice(mCurrentTSlice);
409 //------------------------------------------------------------------------------
412 //------------------------------------------------------------------------------
413 void vvSlicer::SetFusion(vvImage::Pointer fusion)
415 if (fusion->GetVTKImages().size()) {
418 if (!mFusionReslice) {
419 mFusionReslice = vtkSmartPointer<vtkImageReslice>::New();
420 mFusionReslice->SetInterpolationModeToLinear();
421 mFusionReslice->AutoCropOutputOn();
422 mFusionReslice->SetBackgroundColor(-1000,-1000,-1000,1);
425 mConcatenatedFusionTransform->Identity();
426 mConcatenatedFusionTransform->Concatenate(mFusion->GetTransform()[0]);
427 mConcatenatedFusionTransform->Concatenate(mSlicingTransform);
428 mFusionReslice->SetResliceTransform(mConcatenatedFusionTransform);
429 mFusionReslice->SetInput(0, mFusion->GetFirstVTKImageData());
430 mFusionReslice->UpdateInformation();
433 mFusionMapper = vtkSmartPointer<vtkImageMapToColors>::New();
435 vtkSmartPointer<vtkLookupTable> lut = vtkLookupTable::New();
437 lut->SetValueRange(0, 1);
438 lut->SetSaturationRange(0, 0);
440 mFusionMapper->SetLookupTable(lut);
441 mFusionMapper->SetInput(mFusionReslice->GetOutput());
444 mFusionActor = vtkSmartPointer<vtkImageActor>::New();
445 mFusionActor->SetInput(mFusionMapper->GetOutput());
446 mFusionActor->SetPickable(0);
447 mFusionActor->SetVisibility(true);
448 mFusionActor->SetOpacity(0.7);
449 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
450 mFusionActor->GetMapper()->BorderOn();
452 this->GetRenderer()->AddActor(mFusionActor);
455 //Synchronize orientation and slice
456 AdjustResliceToSliceOrientation(mFusionReslice);
457 this->UpdateDisplayExtent();
458 this->SetTSlice(mCurrentTSlice);
461 //------------------------------------------------------------------------------
464 //------------------------------------------------------------------------------
465 bool vvSlicer::GetActorVisibility(const std::string& actor_type, int overlay_index)
468 if (actor_type == "image") {
469 vis = this->ImageActor->GetVisibility();
471 else if (actor_type == "vector") {
472 vis = this->mVFActor->GetVisibility();
474 else if (actor_type == "overlay") {
475 vis = this->mOverlayActor->GetVisibility();
477 else if (actor_type == "fusion") {
478 vis = this->mFusionActor->GetVisibility();
480 else if (actor_type == "contour")
481 vis = this->mSurfaceCutActors[overlay_index]->GetActor()->GetVisibility();
485 //------------------------------------------------------------------------------
487 //------------------------------------------------------------------------------
488 void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis)
490 if (actor_type == "image") {
491 this->ImageActor->SetVisibility(vis);
493 else if (actor_type == "vector") {
494 this->mVFActor->SetVisibility(vis);
496 else if (actor_type == "overlay") {
497 this->mOverlayActor->SetVisibility(vis);
499 else if (actor_type == "fusion") {
500 this->mFusionActor->SetVisibility(vis);
502 else if (actor_type == "contour")
503 this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis);
504 UpdateDisplayExtent();
506 //------------------------------------------------------------------------------
508 //------------------------------------------------------------------------------
509 void vvSlicer::SetVF(vvImage::Pointer vf)
511 if (vf->GetVTKImages().size()) {
515 mAAFilter= vtkSmartPointer<vtkAssignAttribute>::New();
516 mVOIFilter = vtkSmartPointer<vtkExtractVOI>::New();
517 mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
519 mVOIFilter->SetInput(vf->GetFirstVTKImageData());
520 mAAFilter->SetInput(mVOIFilter->GetOutput());
521 ///This tells VTK to use the scalar (pixel) data of the image to draw the little arrows
522 mAAFilter->Assign(vtkDataSetAttributes::SCALARS, vtkDataSetAttributes::VECTORS, vtkAssignAttribute::POINT_DATA);
525 mArrow = vtkSmartPointer<vvGlyphSource>::New();
526 mArrow->SetGlyphTypeToSpecificArrow();
527 mArrow->SetScale(mScale);
530 // Glyph the gradient vector (with arrows)
532 mGlyphFilter = vtkSmartPointer<vvGlyph2D>::New();
533 mGlyphFilter->SetInput(mAAFilter->GetOutput());
534 mGlyphFilter->SetSource(mArrow->GetOutput());
535 mGlyphFilter->ScalingOn();
536 mGlyphFilter->SetScaleModeToScaleByVector();
537 mGlyphFilter->OrientOn();
538 mGlyphFilter->SetVectorModeToUseVector();
539 mGlyphFilter->SetColorModeToColorByVector();
542 mVFColorLUT = vtkSmartPointer<vtkLookupTable>::New();
544 double mVFColorHSV[3];
545 vtkMath::RGBToHSV(mVFColor, mVFColorHSV);
546 mVFColorLUT->SetHueRange(mVFColorHSV[0], mVFColorHSV[0]);
547 mVFColorLUT->SetSaturationRange(mVFColorHSV[1],mVFColorHSV[1]);
548 mVFColorLUT->SetValueRange(mVFColorHSV[2], mVFColorHSV[2]);
551 mVFMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
552 mVFMapper->SetInput(mGlyphFilter->GetOutput());
553 mVFMapper->ImmediateModeRenderingOn();
554 mVFMapper->SetLookupTable(mVFColorLUT);
557 mVFActor = vtkSmartPointer<vtkActor>::New();
558 mVFActor->SetMapper(mVFMapper);
559 mVFActor->SetPickable(0);
560 mVFActor->GetProperty()->SetLineWidth(mVFWidth);
561 this->UpdateDisplayExtent();
562 this->GetRenderer()->AddActor(mVFActor);
565 SetTSlice(mCurrentTSlice);
568 //------------------------------------------------------------------------------
571 //------------------------------------------------------------------------------
572 void vvSlicer::SetLandmarks(vvLandmarks* landmarks)
574 mLandmarks = landmarks;
578 mCross = vtkSmartPointer<vtkCursor3D>::New();
579 mCross->SetFocalPoint(0.0,0.0,0.0);
580 mCross->SetModelBounds(-10,10,-10,10,-10,10);
585 mLandGlyph = vtkSmartPointer<vtkGlyph3D>::New();
586 mLandGlyph->SetSource(mCross->GetOutput());
587 mLandGlyph->SetInput(landmarks->GetOutput());
588 //mLandGlyph->SetIndexModeToScalar();
589 mLandGlyph->SetRange(0,1);
590 mLandGlyph->ScalingOff();
592 mLandGlyph->SetColorModeToColorByScalar();
595 mClipBox = vtkSmartPointer<vtkBox>::New();
597 mLandClipper = vtkSmartPointer<vtkClipPolyData>::New();
598 mLandClipper->InsideOutOn();
599 mLandClipper->SetInput(mLandGlyph->GetOutput());
600 mLandClipper->SetClipFunction(mClipBox);
603 mLandMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
604 mLandMapper->SetInputConnection(mLandClipper->GetOutputPort());
605 //mLandMapper->ScalarVisibilityOff();
608 mLandActor = vtkSmartPointer<vtkActor>::New();
609 mLandActor->SetMapper(mLandMapper);
610 mLandActor->GetProperty()->SetColor(255,10,212);
611 mLandActor->SetPickable(0);
612 mLandActor->SetVisibility(true);
613 this->UpdateDisplayExtent();
614 this->GetRenderer()->AddActor(mLandActor);
617 //------------------------------------------------------------------------------
619 //------------------------------------------------------------------------------
620 //FIXME: this function leaks memory, we should fix it someday :)
621 void vvSlicer::RemoveActor(const std::string& actor_type, int overlay_index)
623 if (actor_type == "vector") {
624 Renderer->RemoveActor(mVFActor);
633 if (actor_type == "overlay") {
634 Renderer->RemoveActor(mOverlayActor);
636 mOverlayActor = NULL;
637 mOverlayMapper = NULL;
639 if (actor_type == "fusion") {
640 Renderer->RemoveActor(mFusionActor);
643 mFusionMapper = NULL;
645 if (actor_type == "contour") {
646 Renderer->RemoveActor(this->mSurfaceCutActors[overlay_index]->GetActor());
647 mSurfaceCutActors.erase(mSurfaceCutActors.begin()+overlay_index);
650 //------------------------------------------------------------------------------
653 //------------------------------------------------------------------------------
654 void vvSlicer::SetVFSubSampling(int sub)
657 mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
660 UpdateDisplayExtent();
663 //------------------------------------------------------------------------------
666 //------------------------------------------------------------------------------
667 void vvSlicer::SetVFScale(int scale)
671 mArrow->SetScale(mScale);
672 UpdateDisplayExtent();
675 //------------------------------------------------------------------------------
677 //------------------------------------------------------------------------------
678 void vvSlicer::SetVFWidth(int width)
682 mVFActor->GetProperty()->SetLineWidth(mVFWidth);
683 UpdateDisplayExtent();
686 //------------------------------------------------------------------------------
689 //------------------------------------------------------------------------------
690 void vvSlicer::SetVFLog(int log)
694 mGlyphFilter->SetUseLog(mVFLog);
695 mGlyphFilter->Modified();
697 UpdateDisplayExtent();
700 //------------------------------------------------------------------------------
703 //------------------------------------------------------------------------------
704 void vvSlicer::SetTSlice(int t)
708 else if ((unsigned int)t >= mImage->GetVTKImages().size())
709 mCurrentTSlice = mImage->GetVTKImages().size() -1;
714 mConcatenatedTransform->Identity();
715 mConcatenatedTransform->Concatenate(mImage->GetTransform()[mCurrentTSlice]);
716 mConcatenatedTransform->Concatenate(mSlicingTransform);
719 mImageReslice->SetInput( mImage->GetVTKImages()[mCurrentTSlice] );
720 if (mVF && mVFActor->GetVisibility()) {
721 if (mVF->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
722 mVOIFilter->SetInput(mVF->GetVTKImages()[mCurrentTSlice]);
724 if (mOverlay && mOverlayActor->GetVisibility()) {
725 if (mOverlay->GetVTKImages().size() > (unsigned int)t) {
726 mCurrentOverlayTSlice = t;
727 mOverlayReslice->SetInput( mOverlay->GetVTKImages()[mCurrentOverlayTSlice] );
729 // Update overlay transform
730 mConcatenatedOverlayTransform->Identity();
731 mConcatenatedOverlayTransform->Concatenate(mOverlay->GetTransform()[mCurrentOverlayTSlice]);
732 mConcatenatedOverlayTransform->Concatenate(mSlicingTransform);
735 if (mFusion && mFusionActor->GetVisibility()) {
736 if (mFusion->GetVTKImages().size() > (unsigned int)t) {
737 mCurrentFusionTSlice = t;
738 mFusionReslice->SetInput( mFusion->GetVTKImages()[mCurrentFusionTSlice]);
740 // Update fusion transform
741 mConcatenatedFusionTransform->Identity();
742 mConcatenatedFusionTransform->Concatenate(mFusion->GetTransform()[mCurrentFusionTSlice]);
743 mConcatenatedFusionTransform->Concatenate(mSlicingTransform);
746 if (mSurfaceCutActors.size() > 0)
747 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
748 i!=mSurfaceCutActors.end(); i++)
749 (*i)->SetTimeSlice(mCurrentTSlice);
750 UpdateDisplayExtent();
752 //------------------------------------------------------------------------------
755 //------------------------------------------------------------------------------
756 int vvSlicer::GetTSlice()
758 return mCurrentTSlice;
760 //------------------------------------------------------------------------------
762 //------------------------------------------------------------------------------
763 int vvSlicer::GetMaxCurrentTSlice()
765 int t = mCurrentTSlice;
767 t = std::max(t, mCurrentOverlayTSlice);
769 t = std::max(t, mCurrentFusionTSlice);
772 //------------------------------------------------------------------------------
774 //------------------------------------------------------------------------------
775 int vvSlicer::GetFusionTSlice()
777 return mCurrentFusionTSlice;
779 //------------------------------------------------------------------------------
781 //------------------------------------------------------------------------------
782 int vvSlicer::GetOverlayTSlice()
784 return mCurrentOverlayTSlice;
786 //------------------------------------------------------------------------------
788 //------------------------------------------------------------------------------
789 void vvSlicer::SetSliceOrientation(int orientation)
791 //if 2D image, force to watch in Axial View
793 this->GetInput()->GetWholeExtent(extent);
794 if (extent[5]-extent[4] <= 2)
795 orientation = vtkImageViewer2::SLICE_ORIENTATION_XY;
797 if (orientation < vtkImageViewer2::SLICE_ORIENTATION_YZ ||
798 orientation > vtkImageViewer2::SLICE_ORIENTATION_XY) {
799 vtkErrorMacro("Error - invalid slice orientation " << orientation);
803 this->SliceOrientation = orientation;
806 AdjustResliceToSliceOrientation(mFusionReslice);
809 AdjustResliceToSliceOrientation(mOverlayReslice);
813 // Go to current cursor position
814 // double* cursorPos = GetCursorPosition();
815 // DDV(cursorPos, 3);
816 // SetCurrentPosition(cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]);
818 if (this->Renderer && this->GetInput()) {
819 double s = mCursor[orientation];
820 double sCursor = (s - this->GetInput()->GetOrigin()[orientation])/this->GetInput()->GetSpacing()[orientation];
821 this->Slice = static_cast<int>(sCursor);
824 // int *range = this->GetSliceRange();
826 // this->Slice = static_cast<int>((range[0] + range[1]) * 0.5);
828 this->UpdateOrientation();
829 this->UpdateDisplayExtent();
831 if (this->Renderer && this->GetInput()) {
832 double scale = this->Renderer->GetActiveCamera()->GetParallelScale();
833 this->Renderer->ResetCamera();
834 this->Renderer->GetActiveCamera()->SetParallelScale(scale);
839 //----------------------------------------------------------------------------
841 //------------------------------------------------------------------------------
842 // This function ensures that we sample the slices of a vtkImageReslice filter
843 // in the direction of the slicer (SliceOrientation) similarly as mImageReslice.
844 // In other words, we change the grid of the reslice in the same way as the grid
845 // of the displayed image in the slicing direction.
846 void vvSlicer::AdjustResliceToSliceOrientation(vtkImageReslice *reslice)
848 // Reset autocrop and update output information
849 reslice->SetOutputOriginToDefault();
850 reslice->SetOutputSpacingToDefault();
851 reslice->GetOutput()->UpdateInformation();
853 // Ge new origin / spacing
856 reslice->GetOutput()->GetOrigin(origin);
857 reslice->GetOutput()->GetSpacing(spacing);
859 // Use similar spacing as the image in the direction SliceOrientation
860 spacing[this->SliceOrientation] = mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation];
862 // Modify origin to be on the image grid in the direction SliceOrientation in 3 steps
863 // Step 1: from world coordinates to image coordinates
864 origin[this->SliceOrientation] -= mImageReslice->GetOutput()->GetOrigin()[this->SliceOrientation];
865 origin[this->SliceOrientation] /= mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation];
866 // Step 2: round to superior grid positionInc
867 origin[this->SliceOrientation] = itk::Math::Ceil<double>(origin[this->SliceOrientation]);
868 // Step 3: back to world coordinates
869 origin[this->SliceOrientation] *= mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation];
870 origin[this->SliceOrientation] += mImageReslice->GetOutput()->GetOrigin()[this->SliceOrientation];
872 // Set new spacing and origin
873 reslice->SetOutputOrigin(origin);
874 reslice->SetOutputSpacing(spacing);
875 reslice->UpdateInformation();
876 reslice->GetOutput()->UpdateInformation();
878 //------------------------------------------------------------------------------
880 //----------------------------------------------------------------------------
881 int * vvSlicer::GetExtent(){
883 if (mUseReducedExtent) {
884 w_ext = mReducedExtent;
885 } else w_ext = GetInput()->GetWholeExtent();
888 //----------------------------------------------------------------------------
891 //----------------------------------------------------------------------------
892 int vvSlicer::GetOrientation()
894 return this->SliceOrientation;
896 //----------------------------------------------------------------------------
899 //----------------------------------------------------------------------------
900 void vvSlicer::UpdateDisplayExtent()
902 vtkImageData *input = this->GetInput();
903 if (!input || !this->ImageActor) {
906 input->UpdateInformation();
908 // Local copy of extent
910 int* ext = GetExtent();
911 copyExtent(ext, w_ext);
913 int s = this->Slice > ext[this->SliceOrientation*2+1] ? ext[this->SliceOrientation*2 + 1] : this->Slice;
914 w_ext[ this->SliceOrientation*2 ] = s;
915 w_ext[ this->SliceOrientation*2+1 ] = s;
918 this->ImageActor->SetDisplayExtent(w_ext);
920 // Overlay image actor
921 if (mOverlay && mOverlayActor->GetVisibility()) {
922 AdjustResliceToSliceOrientation(mOverlayReslice);
924 this->ConvertImageToImageDisplayExtent(input, w_ext, mOverlayReslice->GetOutput(), overExtent);
925 ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
926 mOverlayActor->SetDisplayExtent( overExtent );
929 // Fusion image actor
930 if (mFusion && mFusionActor->GetVisibility()) {
931 AdjustResliceToSliceOrientation(mFusionReslice);
933 this->ConvertImageToImageDisplayExtent(input, w_ext, mFusionReslice->GetOutput(), fusExtent);
934 ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
935 mFusionActor->SetDisplayExtent(fusExtent);
938 // Vector field actor
939 double* camera = Renderer->GetActiveCamera()->GetPosition();
940 double* image_bounds = ImageActor->GetBounds();
941 double position[3] = {0, 0, 0};
942 position[this->SliceOrientation] = image_bounds[this->SliceOrientation*2];
944 //print_vector<double, 6>("camera", camera);
945 //print_vector<double, 6>("image_bounds", image_bounds);
946 //print_vector<double, 3>("position", position);
948 // find where to place the VF actor. to deal with
949 // z-buffer issues, the VF is placed right in front of the image,
950 // subject to a small offset. the position actually depends on the
951 // the location of the camera relative to the image.
953 if (camera[this->SliceOrientation] < image_bounds[this->SliceOrientation*2])
956 if (mVF && mVFActor->GetVisibility()) {
958 mVF->GetVTKImages()[0]->UpdateInformation();
959 this->ConvertImageToImageDisplayExtent(input, w_ext, mVF->GetVTKImages()[0], vfExtent);
960 ClipDisplayedExtent(vfExtent, mVOIFilter->GetInput()->GetWholeExtent());
961 mVOIFilter->SetVOI(vfExtent);
962 int orientation[3] = {1,1,1};
963 orientation[this->SliceOrientation] = 0;
964 mGlyphFilter->SetOrientation(orientation[0], orientation[1], orientation[2]);
967 position[this->SliceOrientation] += offset;
968 mVFActor->SetPosition(position);
975 for(unsigned int i=0; i<6; i++)
976 bounds[i] = ImageActor->GetBounds()[i];
977 bounds[ this->SliceOrientation*2 ] = ImageActor->GetBounds()[ this->SliceOrientation*2 ]-fabs(this->GetInput()->GetSpacing()[this->SliceOrientation]);
978 bounds[ this->SliceOrientation*2+1 ] = ImageActor->GetBounds()[ this->SliceOrientation*2+1 ]+fabs(this->GetInput()->GetSpacing()[this->SliceOrientation]);
979 mClipBox->SetBounds(bounds);
983 position[this->SliceOrientation] = offset;
984 mLandActor->SetPosition(position);
987 // Figure out the correct clipping range
988 if (this->Renderer) {
989 if (this->InteractorStyle &&
990 this->InteractorStyle->GetAutoAdjustCameraClippingRange()) {
991 this->Renderer->ResetCameraClippingRange();
993 vtkCamera *cam = this->Renderer->GetActiveCamera();
996 this->ImageActor->GetBounds(bounds);
997 double spos = (double)bounds[this->SliceOrientation * 2];
998 double cpos = (double)cam->GetPosition()[this->SliceOrientation];
999 double range = fabs(spos - cpos);
1000 double *spacing = input->GetSpacing();
1001 double sumSpacing = spacing[0] + spacing[1] + spacing[2];
1002 cam->SetClippingRange(range - sumSpacing, range + sumSpacing);
1008 //----------------------------------------------------------------------------
1010 //----------------------------------------------------------------------------
1011 void vvSlicer::ConvertImageToImageDisplayExtent(vtkImageData *sourceImage, const int sourceExtent[6],
1012 vtkImageData *targetImage, int targetExtent[6])
1015 for(unsigned int i=0; i<6; i++) {
1016 // From source voxel coordinates to world coordinates
1017 dExtents[i] = sourceImage->GetOrigin()[i/2] + sourceImage->GetSpacing()[i/2] * sourceExtent[i];
1019 // From world coordinates to floating point target voxel coordinates
1020 dExtents[i] = (dExtents[i]- targetImage->GetOrigin()[i/2]) / targetImage->GetSpacing()[i/2];
1023 //targetExtent[i] = itk::Math::Round<double>(dExtents[i]);
1024 targetExtent[i] = itk::Math::Floor<double>(dExtents[i]);
1027 //----------------------------------------------------------------------------
1029 //----------------------------------------------------------------------------
1030 void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
1035 //2D overlay on 3D image specific case
1036 if (refExtent[4] == refExtent[5]) {
1038 extent[4] = refExtent[4];
1039 extent[5] = refExtent[5];
1042 for (int i = 0; i < maxBound; i = i+2) {
1043 //if we are totally outside the image
1044 if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] ) {
1048 //crop to the limit of the image
1049 extent[i] = (extent[i] > refExtent[i]) ? extent[i] : refExtent[i];
1050 extent[i] = (extent[i] < refExtent[i+1]) ? extent[i] : refExtent[i+1];
1051 extent[i+1] = (extent[i+1] > refExtent[i]) ? extent[i+1] : refExtent[i];
1052 extent[i+1] = (extent[i+1] < refExtent[i+1]) ? extent[i+1] : refExtent[i+1];
1055 for (int i = 0; i < maxBound; i = i+2) {
1056 extent[i] = refExtent[i];
1057 extent[i+1] = refExtent[i];
1060 //----------------------------------------------------------------------------
1063 //----------------------------------------------------------------------------
1064 void vvSlicer::UpdateOrientation()
1066 // Set the camera position
1067 vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1069 switch (this->SliceOrientation) {
1070 case vtkImageViewer2::SLICE_ORIENTATION_XY:
1071 cam->SetFocalPoint(0,0,0);
1072 cam->SetPosition(0,0,-1); // -1 if medical ?
1073 cam->SetViewUp(0,-1,0);
1076 case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1077 cam->SetFocalPoint(0,0,0);
1078 cam->SetPosition(0,-1,0); // 1 if medical ?
1079 cam->SetViewUp(0,0,1);
1082 case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1083 cam->SetFocalPoint(0,0,0);
1084 cam->SetPosition(-1,0,0); // -1 if medical ?
1085 cam->SetViewUp(0,0,1);
1090 //----------------------------------------------------------------------------
1093 //----------------------------------------------------------------------------
1094 void vvSlicer::SetOpacity(double s)
1096 this->GetImageActor()->SetOpacity(s);
1098 //----------------------------------------------------------------------------
1101 //----------------------------------------------------------------------------
1102 void vvSlicer::SetRenderWindow(int orientation, vtkRenderWindow * rw)
1104 this->Superclass::SetRenderWindow(rw);
1105 this->SetupInteractor(rw->GetInteractor());
1106 ca->SetImageActor(this->GetImageActor());
1107 ca->SetWindowLevel(this->GetWindowLevel());
1108 ca->SetText(2, "<slice>");
1109 ca->SetText(3, "<window>\n<level>");
1121 crossCursor->SetModelBounds(bounds);
1122 this->GetRenderer()->AddActor(pdmA);
1123 this->GetRenderer()->AddActor(ca);
1124 this->GetRenderer()->ResetCamera();
1126 //this is just a mapping between the labeling of the orientations presented to the user and
1127 //the one used by vtk
1128 SetSliceOrientation(2-(orientation%3));
1131 //----------------------------------------------------------------------------
1134 //----------------------------------------------------------------------------
1135 void vvSlicer::ResetCamera()
1137 this->GetRenderer()->ResetCamera();
1139 //----------------------------------------------------------------------------
1142 //----------------------------------------------------------------------------
1143 void vvSlicer::SetDisplayMode(bool i)
1145 this->GetRenderer()->SetDraw(i);
1147 UpdateDisplayExtent();
1149 //----------------------------------------------------------------------------
1152 //----------------------------------------------------------------------------
1153 void vvSlicer::FlipHorizontalView()
1155 vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1157 double *position = cam->GetPosition();
1158 double factor[3] = {1, 1, 1};
1159 factor[this->SliceOrientation] = -1;
1160 cam->SetPosition(factor[0]*position[0],factor[1]*position[1],factor[2]*position[2]);
1162 /* switch (this->SliceOrientation) {
1163 case vtkImageViewer2::SLICE_ORIENTATION_XY:
1164 cam->SetPosition(position[0],position[1],-position[2]);
1167 case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1168 cam->SetPosition(position[0],-position[1],position[2]);
1171 case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1172 cam->SetPosition(-position[0],position[1],position[2]);
1176 this->Renderer->ResetCameraClippingRange();
1177 this->UpdateDisplayExtent();
1180 //----------------------------------------------------------------------------
1183 //----------------------------------------------------------------------------
1184 void vvSlicer::FlipVerticalView()
1186 vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1188 FlipHorizontalView();
1189 double *viewup = cam->GetViewUp();
1190 cam->SetViewUp(-viewup[0],-viewup[1],-viewup[2]);
1191 this->UpdateDisplayExtent();
1194 //----------------------------------------------------------------------------
1197 //----------------------------------------------------------------------------
1198 void vvSlicer::SetColorWindow(double window)
1200 vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1202 double level = this->GetWindowLevel()->GetLevel();
1203 LUT->SetTableRange(level-fabs(window)/2,level+fabs(window)/2);
1206 this->vtkImageViewer2::SetColorWindow(window);
1208 //----------------------------------------------------------------------------
1210 //----------------------------------------------------------------------------
1211 void vvSlicer::SetColorLevel(double level)
1213 vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1215 double window = this->GetWindowLevel()->GetWindow();
1216 LUT->SetTableRange(level-fabs(window)/2,level+fabs(window)/2);
1219 this->vtkImageViewer2::SetColorLevel(level);
1221 //----------------------------------------------------------------------------
1223 //----------------------------------------------------------------------------
1224 double vvSlicer::GetOverlayColorWindow()
1227 return mOverlayMapper->GetWindow();
1231 //----------------------------------------------------------------------------
1233 //----------------------------------------------------------------------------
1234 double vvSlicer::GetOverlayColorLevel()
1237 return mOverlayMapper->GetLevel();
1241 //----------------------------------------------------------------------------
1243 //----------------------------------------------------------------------------
1244 void vvSlicer::SetOverlayColorWindow(double window)
1246 mOverlayMapper->SetWindow(window);
1248 //----------------------------------------------------------------------------
1250 //----------------------------------------------------------------------------
1251 void vvSlicer::SetOverlayColorLevel(double level)
1253 mOverlayMapper->SetLevel(level);
1255 //----------------------------------------------------------------------------
1257 //----------------------------------------------------------------------------
1258 // Returns the min an the max value in a 20%x20% region around the mouse pointer
1259 void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image, vtkTransform *transform)
1261 //Get mouse pointer position in view coordinates
1264 for(int i=0; i<3; i++) {
1265 corner1[i] = mCurrent[i];
1266 corner2[i] = mCurrent[i];
1269 this->Renderer->WorldToView(corner1[0], corner1[1], corner1[2]);
1270 this->Renderer->WorldToView(corner2[0], corner2[1], corner2[2]);
1272 // In view coordinates, x is the slicer width and y is the slicer height are the in-plane axis
1274 this->Renderer->GetTiledSize(&w, &h);
1275 corner1[0] -= 0.2*h/(double)w;
1276 corner2[0] += 0.2*h/(double)w;
1279 this->Renderer->ViewToWorld(corner1[0], corner1[1], corner1[2]);
1280 this->Renderer->ViewToWorld(corner2[0], corner2[1], corner2[2]);
1282 //Convert to image pixel coordinates (rounded)
1283 transform->TransformPoint(corner1, corner1);
1284 transform->TransformPoint(corner2, corner2);
1285 int iLocalExtents[6];
1286 for(int i=0; i<3; i++) {
1287 corner1[i] = (corner1[i] - image->GetOrigin()[i])/image->GetSpacing()[i];
1288 corner2[i] = (corner2[i] - image->GetOrigin()[i])/image->GetSpacing()[i];
1290 iLocalExtents[i*2 ] = lrint(corner1[i]);
1291 iLocalExtents[i*2+1] = lrint(corner2[i]);
1293 if(iLocalExtents[i*2 ]>iLocalExtents[i*2+1])
1294 std::swap(iLocalExtents[i*2], iLocalExtents[i*2+1]);
1297 vtkSmartPointer<vtkExtractVOI> voiFilter = vtkSmartPointer<vtkExtractVOI>::New();
1298 voiFilter->SetInput(image);
1299 voiFilter->SetVOI(iLocalExtents);
1300 voiFilter->Update();
1301 if (!voiFilter->GetOutput()->GetNumberOfPoints()) {
1307 vtkSmartPointer<vtkImageAccumulate> accFilter = vtkSmartPointer<vtkImageAccumulate>::New();
1308 accFilter->SetInput(voiFilter->GetOutput());
1309 accFilter->Update();
1311 min = *(accFilter->GetMin());
1312 max = *(accFilter->GetMax());
1314 //----------------------------------------------------------------------------
1316 //----------------------------------------------------------------------------
1317 double vvSlicer::GetScalarComponentAsDouble(vtkImageData *image, double X, double Y, double Z, int &ix, int &iy, int &iz, int component)
1322 if (ix < image->GetWholeExtent()[0] ||
1323 ix > image->GetWholeExtent()[1] ||
1324 iy < image->GetWholeExtent()[2] ||
1325 iy > image->GetWholeExtent()[3] ||
1326 iz < image->GetWholeExtent()[4] ||
1327 iz > image->GetWholeExtent()[5] )
1328 return std::numeric_limits<double>::quiet_NaN();
1330 image->SetUpdateExtent(ix, ix, iy, iy, iz, iz);
1332 return image->GetScalarComponentAsDouble(ix, iy, iz, component);
1334 //----------------------------------------------------------------------------
1336 //----------------------------------------------------------------------------
1337 void vvSlicer::Render()
1339 if (this->mFusion && mFusionActor->GetVisibility() && showFusionLegend) {
1340 legend->SetLookupTable(this->GetFusionMapper()->GetLookupTable());
1341 legend->UseOpacityOn();
1342 legend->SetVisibility(1);
1344 else if (this->GetWindowLevel()->GetLookupTable() && !this->mOverlay) {
1345 legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable());
1346 legend->UseOpacityOff();
1347 legend->SetVisibility(1);
1348 } else legend->SetVisibility(0);
1350 if (ca->GetVisibility()) {
1351 std::stringstream worldPos;
1353 mConcatenatedTransform->TransformPoint(mCurrent, pt);
1354 double X = (pt[0] - mImage->GetVTKImages()[mCurrentTSlice]->GetOrigin()[0])/mImage->GetVTKImages()[mCurrentTSlice]->GetSpacing()[0];
1355 double Y = (pt[1] - mImage->GetVTKImages()[mCurrentTSlice]->GetOrigin()[1])/mImage->GetVTKImages()[mCurrentTSlice]->GetSpacing()[1];
1356 double Z = (pt[2] - mImage->GetVTKImages()[mCurrentTSlice]->GetOrigin()[2])/mImage->GetVTKImages()[mCurrentTSlice]->GetSpacing()[2];
1358 if (X >= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[0]-0.5 &&
1359 X <= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[1]+0.5 &&
1360 Y >= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[2]-0.5 &&
1361 Y <= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[3]+0.5 &&
1362 Z >= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[4]-0.5 &&
1363 Z <= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[5]+0.5) {
1367 double value = this->GetScalarComponentAsDouble(mImage->GetVTKImages()[mCurrentTSlice], X, Y, Z, ix, iy, iz);
1369 if(ImageActor->GetVisibility())
1370 worldPos << "data value : " << value << std::endl;
1372 worldPos << "mm : " << lrint(mCurrentBeforeSlicingTransform[0]) << ' '
1373 << lrint(mCurrentBeforeSlicingTransform[1]) << ' '
1374 << lrint(mCurrentBeforeSlicingTransform[2]) << ' '
1377 worldPos << "pixel : " << ix << ' '
1383 ca->SetText(1,worldPos.str().c_str());
1386 if (pdmA->GetVisibility()) {
1387 double x = mCursor[0];
1388 double y = mCursor[1];
1389 double z = mCursor[2];
1390 double xCursor = (x - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1391 double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1392 double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1394 if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0] &&
1395 xCursor < this->GetImageActor()->GetDisplayExtent()[1]+1 &&
1396 yCursor >= this->GetImageActor()->GetDisplayExtent()[2] &&
1397 yCursor < this->GetImageActor()->GetDisplayExtent()[3]+1 &&
1398 zCursor >= this->GetImageActor()->GetDisplayExtent()[4] &&
1399 zCursor < this->GetImageActor()->GetDisplayExtent()[5]+1 ) {
1400 vtkRenderer * renderer = this->Renderer;
1402 renderer->WorldToView(x,y,z);
1403 renderer->ViewToNormalizedViewport(x,y,z);
1404 renderer->NormalizedViewportToViewport(x,y);
1405 renderer->ViewportToNormalizedDisplay(x,y);
1406 renderer->NormalizedDisplayToDisplay(x,y);
1407 crossCursor->SetFocalPoint(x,y,z);
1409 crossCursor->SetFocalPoint(-1,-1,z);
1413 if (mOverlay && mOverlayActor->GetVisibility()) {
1414 if(mLinkOverlayWindowLevel) {
1415 mOverlayMapper->SetWindow(this->GetColorWindow());
1416 mOverlayMapper->SetLevel(this->GetColorLevel());
1418 mOverlayMapper->GetOutput()->SetUpdateExtent(mOverlayActor->GetDisplayExtent());
1419 mOverlayMapper->GetOutput()->Update();
1420 mOverlayMapper->Update();
1425 this->GetRenderWindow()->Render();
1427 //----------------------------------------------------------------------------
1430 //----------------------------------------------------------------------------
1431 void vvSlicer::UpdateCursorPosition()
1433 pdmA->SetVisibility(true);
1434 mCursor[0] = mCurrent[0];
1435 mCursor[1] = mCurrent[1];
1436 mCursor[2] = mCurrent[2];
1437 mCursor[3] = mCurrentTSlice;
1439 //----------------------------------------------------------------------------
1442 //----------------------------------------------------------------------------
1443 void vvSlicer::UpdateLandmarks()
1445 vtkPolyData *pd = static_cast<vtkPolyData*>(mLandClipper->GetInput());
1446 if (pd->GetPoints()) {
1447 mLandGlyph->SetRange(0,1);
1448 mLandGlyph->Modified();
1449 mLandGlyph->Update();
1451 mClipBox->Modified();
1452 mLandClipper->Update();
1453 mLandMapper->Update();
1457 //----------------------------------------------------------------------------
1460 //----------------------------------------------------------------------------
1461 void vvSlicer::SetSlice(int slice)
1463 int *range = this->GetSliceRange();
1465 if (slice < range[0]) {
1467 } else if (slice > range[1]) {
1472 if (this->Slice == slice) {
1476 this->Slice = slice;
1479 this->UpdateDisplayExtent();
1481 // Seems to work without this line
1484 //----------------------------------------------------------------------------
1486 //----------------------------------------------------------------------------
1487 int vvSlicer::GetTMax() {
1488 int tmax = (int)mImage->GetVTKImages().size() - 1;
1490 tmax = std::max(tmax, (int)mOverlay->GetVTKImages().size()-1);
1493 //----------------------------------------------------------------------------
1495 //----------------------------------------------------------------------------
1496 void vvSlicer::SetContourSlice()
1498 if (mSurfaceCutActors.size() > 0)
1499 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
1500 i!=mSurfaceCutActors.end(); i++) {
1502 (*i)->SetSlicingOrientation(this->SliceOrientation);
1503 (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+
1504 this->GetImage()->GetOrigin()[this->SliceOrientation]);
1507 //----------------------------------------------------------------------------
1510 //----------------------------------------------------------------------------
1511 void vvSlicer::ForceUpdateDisplayExtent()
1513 this->UpdateDisplayExtent();
1515 //----------------------------------------------------------------------------
1518 //----------------------------------------------------------------------------
1519 int* vvSlicer::GetDisplayExtent()
1521 return this->GetImageActor()->GetDisplayExtent();
1523 //----------------------------------------------------------------------------
1526 //----------------------------------------------------------------------------
1527 void vvSlicer::PrintSelf(ostream& os, vtkIndent indent)
1529 this->Superclass::PrintSelf(os, indent);
1531 //----------------------------------------------------------------------------
1533 //----------------------------------------------------------------------------
1534 void vvSlicer::SetVFColor(double r, double g, double b)
1536 double mVFColorHSV[3];
1541 vtkMath::RGBToHSV(mVFColor, mVFColorHSV);
1542 mVFColorLUT->SetHueRange(mVFColorHSV[0], mVFColorHSV[0]);
1543 mVFColorLUT->SetSaturationRange(mVFColorHSV[1],mVFColorHSV[1]);
1544 mVFColorLUT->SetValueRange(mVFColorHSV[2], mVFColorHSV[2]);