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 ===========================================================================**/
19 #include <QMessageBox>
24 #include "vvSlicerManagerCommand.h"
25 #include "vvGlyphSource.h"
26 #include "vvGlyph2D.h"
28 #include <vtkVersion.h>
29 #include <vtkExtentTranslator.h>
30 #include <vtkAlgorithm.h>
31 #include <vtkExecutive.h>
32 #include <vtkStreamingDemandDrivenPipeline.h>
33 #include <vtkInformation.h>
34 #include <vtkTextProperty.h>
35 #include <vtkTextActor.h>
36 #include <vtkTextSource.h>
37 #include <vtkActor2D.h>
38 #include <vtkCursor2D.h>
39 #include <vtkPolyDataMapper2D.h>
40 #include <vtkProperty2D.h>
41 #include <vtkCornerAnnotation.h>
42 #include <vtkImageMapToWindowLevelColors.h>
43 #include <vtkImageData.h>
44 #include <vtkImageActor.h>
45 #include <vvBlendImageActor.h>
46 #include <vtkToolkits.h>
47 #include <vtkObjectFactory.h>
48 #include <vtkPointData.h>
49 #include <vtkDataArray.h>
50 #include <vtkFloatArray.h>
51 #include <vtkClipPolyData.h>
52 #include <vtkActor2DCollection.h>
53 #include <vtkGlyph3D.h>
55 #include <vtkCursor3D.h>
56 #include <vtkProperty.h>
58 #include <vtkLightCollection.h>
59 #include <vtkScalarBarActor.h>
60 #include <vtkImageProperty.h>
61 #include <vtkLookupTable.h>
63 #include <vtkRenderer.h>
64 #include <vtkRendererCollection.h>
65 #include <vtkRenderWindow.h>
66 #include <vtkRenderWindowInteractor.h>
67 #include <vtkCamera.h>
68 #include <vtkCallbackCommand.h>
69 #include <vtkCommand.h>
70 #include <vtkPolyDataMapper.h>
73 #include <vtkExtractVOI.h>
74 #include <vtkSphereSource.h>
75 #include <vtkCutter.h>
76 #include <vtkAssignAttribute.h>
77 #include <vtkImageAccumulate.h>
78 #include <vtkImageReslice.h>
79 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
80 # include <vtkOpenGLImageSliceMapper.h>
81 # include <vtkImageMapper3D.h>
82 # include <vtkImageSliceMapper.h>
85 vtkStandardNewMacro(vvSlicer);
86 static void copyExtent(int* in, int* to){
87 for(int i=0; i<6; ++i)
92 //------------------------------------------------------------------------------
95 mFusionSequenceCode = -1;
96 this->UnInstallPipeline();
98 mReducedExtent = new int[6];
99 mRegisterExtent = NULL;
101 mCurrentFusionTSlice = 0;
102 mCurrentOverlayTSlice = 0;
103 mUseReducedExtent = false;
105 mCurrent[0] = -VTK_DOUBLE_MAX;
106 mCurrent[1] = -VTK_DOUBLE_MAX;
107 mCurrent[2] = -VTK_DOUBLE_MAX;
109 mCursor[0] = 0;//-VTK_DOUBLE_MAX;
110 mCursor[1] = 0;//-VTK_DOUBLE_MAX;
111 mCursor[2] = 0;//-VTK_DOUBLE_MAX;
112 mCursor[3] = 0;//-VTK_DOUBLE_MAX;
122 crossCursor = vtkSmartPointer<vtkCursor2D>::New();
123 crossCursor->AllOff();
124 crossCursor->AxesOn();
125 crossCursor->SetTranslationMode(1);
126 crossCursor->SetRadius(2);
128 pdm = vtkSmartPointer<vtkPolyDataMapper2D>::New();
129 #if VTK_MAJOR_VERSION <= 5
130 pdm->SetInput(crossCursor->GetOutput());
132 pdm->SetInputConnection(crossCursor->GetOutputPort(0));
135 pdmA = vtkSmartPointer<vtkActor2D>::New();
136 pdmA->SetMapper(pdm);
137 pdmA->GetProperty()->SetColor(255,10,212);
138 pdmA->SetVisibility(0);
139 pdmA->SetPickable(0);
141 ca = vtkSmartPointer<vtkCornerAnnotation>::New();
142 ca->GetTextProperty()->SetColor(255,10,212);
143 ca->SetVisibility(1);
151 legend = vtkSmartPointer<vtkScalarBarActor>::New();
152 //legend->SetTitle("test!");
153 legend->SetPosition(0.82,0.08);
154 //legend->SetWidth(0.1);
155 legend->SetVisibility(0);
156 legend->SetLabelFormat("%.1e");
157 this->GetRenderer()->AddActor(legend);
158 showFusionLegend = false;
160 this->InstallPipeline();
162 mLinkOverlayWindowLevel = true;
163 mImageVisibility = true;
165 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
166 this->GetImageActor()->GetMapper()->BorderOn();
169 mSlicingTransform = vtkSmartPointer<vtkTransform>::New();
170 mConcatenatedTransform = vtkSmartPointer<vtkTransform>::New();
171 mConcatenatedFusionTransform = vtkSmartPointer<vtkTransform>::New();
172 mConcatenatedOverlayTransform = vtkSmartPointer<vtkTransform>::New();
173 mConcatenatedVFTransform = vtkSmartPointer<vtkTransform>::New();
174 mFirstSetSliceOrientation = true;
176 //------------------------------------------------------------------------------
179 //------------------------------------------------------------------------------
180 vtkImageMapToWindowLevelColors* vvSlicer::GetOverlayMapper()
182 return mOverlayMapper.GetPointer();
184 //------------------------------------------------------------------------------
187 //------------------------------------------------------------------------------
188 vvBlendImageActor* vvSlicer::GetOverlayActor()
190 return mOverlayActor.GetPointer();
192 //------------------------------------------------------------------------------
195 //------------------------------------------------------------------------------
196 vtkImageMapToColors* vvSlicer::GetFusionMapper()
198 return mFusionMapper.GetPointer();
200 //------------------------------------------------------------------------------
203 //------------------------------------------------------------------------------
204 vtkImageActor* vvSlicer::GetFusionActor()
206 return mFusionActor.GetPointer();
208 //------------------------------------------------------------------------------
211 //------------------------------------------------------------------------------
212 vtkActor* vvSlicer::GetVFActor()
214 return mVFActor.GetPointer();
216 //------------------------------------------------------------------------------
219 //------------------------------------------------------------------------------
220 vtkCornerAnnotation* vvSlicer::GetAnnotation()
222 return ca.GetPointer();
224 //------------------------------------------------------------------------------
227 //------------------------------------------------------------------------------
228 void vvSlicer::EnableReducedExtent(bool b)
230 mUseReducedExtent = b;
232 //------------------------------------------------------------------------------
235 //------------------------------------------------------------------------------
236 void vvSlicer::SetReducedExtent(int * ext)
238 copyExtent(ext, mReducedExtent);
240 //------------------------------------------------------------------------------
243 //------------------------------------------------------------------------------
244 void vvSlicer::AddContour(vvMesh::Pointer contour,bool propagate)
247 mSurfaceCutActors.push_back(new vvMeshActor());
249 mSurfaceCutActors.back()->Init(contour,mCurrentTSlice,mVF);
251 mSurfaceCutActors.back()->Init(contour,mCurrentTSlice);
252 mSurfaceCutActors.back()->SetSlicingOrientation(SliceOrientation);
253 this->GetRenderer()->AddActor(mSurfaceCutActors.back()->GetActor());
257 //------------------------------------------------------------------------------
260 //------------------------------------------------------------------------------
261 void vvSlicer::ToggleContourSuperposition()
263 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
264 i!=mSurfaceCutActors.end(); i++)
265 (*i)->ToggleSuperposition();
267 //------------------------------------------------------------------------------
270 //------------------------------------------------------------------------------
271 void vvSlicer::SetCursorColor(int r,int g, int b)
273 pdmA->GetProperty()->SetColor(r,g,b);
275 //------------------------------------------------------------------------------
278 //------------------------------------------------------------------------------
279 void vvSlicer::SetCursorVisibility(bool s)
281 pdmA->SetVisibility(s);
283 //------------------------------------------------------------------------------
286 //------------------------------------------------------------------------------
287 bool vvSlicer::GetCursorVisibility()
289 return pdmA->GetVisibility();
291 //------------------------------------------------------------------------------
294 //------------------------------------------------------------------------------
295 void vvSlicer::SetCornerAnnotationVisibility(bool s)
297 ca->SetVisibility(s);
299 //------------------------------------------------------------------------------
302 //------------------------------------------------------------------------------
303 bool vvSlicer::GetCornerAnnotationVisibility()
305 return ca->GetVisibility();
307 //------------------------------------------------------------------------------
310 //------------------------------------------------------------------------------
311 vvSlicer::~vvSlicer()
313 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
314 i!=mSurfaceCutActors.end(); i++)
316 delete [] mReducedExtent;
318 //------------------------------------------------------------------------------
320 //------------------------------------------------------------------------------
321 double* vvSlicer::GetCurrentPosition()
323 return mCurrentBeforeSlicingTransform;
325 //------------------------------------------------------------------------------
327 //------------------------------------------------------------------------------
328 void vvSlicer::SetInterpolationImageReslice(int interpolation)
330 mImageReslice->SetInterpolationMode(interpolation);
332 //------------------------------------------------------------------------------
334 //------------------------------------------------------------------------------
335 void vvSlicer::SetCurrentPosition(double x, double y, double z, int t)
337 mCurrentBeforeSlicingTransform[0]=x;
338 mCurrentBeforeSlicingTransform[1]=y;
339 mCurrentBeforeSlicingTransform[2]=z;
340 mSlicingTransform->GetInverse()->TransformPoint(mCurrentBeforeSlicingTransform,mCurrent);
341 if (t>=0) SetTSlice(t);
343 //------------------------------------------------------------------------------
346 //------------------------------------------------------------------------------
347 void vvSlicer::SetImage(vvImage::Pointer image)
349 if (image->GetVTKImages().size()) {
352 if (!mImageReslice) {
353 mImageReslice = vtkSmartPointer<vtkImageReslice>::New();
354 mImageReslice->SetInterpolationModeToLinear();
355 mImageReslice->AutoCropOutputOn();
356 mImageReslice->SetBackgroundColor(-1000,-1000,-1000,1);
359 mConcatenatedTransform->Identity();
360 mConcatenatedTransform->Concatenate(mImage->GetTransform()[0]);
361 mConcatenatedTransform->Concatenate(mSlicingTransform);
362 mImageReslice->SetResliceTransform(mConcatenatedTransform);
363 //mImageReslice->SetResliceAxes(mConcatenatedTransform->GetMatrix());
364 #if VTK_MAJOR_VERSION <= 5
365 mImageReslice->SetInput(0, mImage->GetFirstVTKImageData());
367 mImageReslice->SetInputData(0, mImage->GetFirstVTKImageData());
369 mImageReslice->UpdateInformation();
371 #if VTK_MAJOR_VERSION <= 5
372 this->Superclass::SetInput(mImageReslice->GetOutput());
374 this->Superclass::SetInputConnection(mImageReslice->GetOutputPort());
378 #if VTK_MAJOR_VERSION <= 5
379 this->GetInput()->GetWholeExtent(extent);
381 int* ext = mImageReslice->GetInputInformation()->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT());
382 copyExtent(ext, extent);
385 // Prevent crash when reload -> change slice if outside extent
386 if (Slice < extent[SliceOrientation*2] || Slice>=extent[SliceOrientation*2+1]) {
387 Slice = (extent[SliceOrientation*2+1]+extent[SliceOrientation*2])/2.0;
390 // Make sure that the required part image has been computed
391 extent[SliceOrientation*2] = Slice;
392 extent[SliceOrientation*2+1] = Slice;
393 #if VTK_MAJOR_VERSION <= 5
394 mImageReslice->GetOutput()->SetUpdateExtent(extent);
395 mImageReslice->GetOutput()->Update();
397 mImageReslice->SetUpdateExtent(extent);
398 mImageReslice->Update();
401 this->UpdateDisplayExtent();
404 ca->SetText(0,mFileName.c_str());
407 //------------------------------------------------------------------------------
410 //------------------------------------------------------------------------------
411 void vvSlicer::SetOverlay(vvImage::Pointer overlay)
413 if (overlay->GetVTKImages().size()) {
415 mOverlayVisibility = true;
417 if (!mOverlayReslice) {
418 mOverlayReslice = vtkSmartPointer<vtkImageReslice>::New();
419 mOverlayReslice->SetInterpolationModeToLinear();
420 mOverlayReslice->AutoCropOutputOn();
421 mOverlayReslice->SetBackgroundColor(-1000,-1000,-1000,1);
424 mConcatenatedOverlayTransform->Identity();
425 mConcatenatedOverlayTransform->Concatenate(mOverlay->GetTransform()[0]);
426 mConcatenatedOverlayTransform->Concatenate(mSlicingTransform);
427 mOverlayReslice->SetResliceTransform(mConcatenatedOverlayTransform);
428 #if VTK_MAJOR_VERSION <= 5
429 mOverlayReslice->SetInput(0, mOverlay->GetFirstVTKImageData());
430 mImageReslice->UpdateInformation();
432 mOverlayReslice->SetInputData(0, mOverlay->GetFirstVTKImageData());
434 mOverlayReslice->Update();
437 mOverlayMapper = vtkSmartPointer<vtkImageMapToWindowLevelColors>::New();
438 #if VTK_MAJOR_VERSION <= 5
439 mOverlayMapper->SetInput(mOverlayReslice->GetOutput());
441 mOverlayMapper->SetInputConnection(mOverlayReslice->GetOutputPort(0));
444 if (!mOverlayActor) {
445 mOverlayActor = vtkSmartPointer<vvBlendImageActor>::New();
446 #if VTK_MAJOR_VERSION <= 5
447 mOverlayActor->SetInput(mOverlayMapper->GetOutput());
449 mOverlayActor->GetMapper()->SetInputConnection(mOverlayMapper->GetOutputPort());
451 mOverlayActor->SetPickable(0);
452 mOverlayActor->SetVisibility(true);
453 mOverlayActor->SetOpacity(0.5);
454 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
455 mOverlayActor->GetMapper()->BorderOn();
459 //stupid but necessary : the Overlay need to be rendered before fusion
461 this->GetRenderer()->RemoveActor(mFusionActor);
462 this->GetRenderer()->AddActor(mOverlayActor);
463 this->GetRenderer()->AddActor(mFusionActor);
465 this->GetRenderer()->AddActor(mOverlayActor);
467 //Synchronize orientation and slice
468 AdjustResliceToSliceOrientation(mOverlayReslice);
469 this->UpdateDisplayExtent();
470 this->SetTSlice(mCurrentTSlice);
473 //------------------------------------------------------------------------------
476 //------------------------------------------------------------------------------
477 void vvSlicer::SetFusion(vvImage::Pointer fusion, int fusionSequenceCode)
479 mFusionSequenceCode = fusionSequenceCode;
480 if (fusion->GetVTKImages().size()) {
482 mFusionVisibility = true;
484 if (!mFusionReslice) {
485 mFusionReslice = vtkSmartPointer<vtkImageReslice>::New();
486 mFusionReslice->SetInterpolationModeToLinear();
487 mFusionReslice->AutoCropOutputOn();
488 mFusionReslice->SetBackgroundColor(-1000,-1000,-1000,1);
491 mConcatenatedFusionTransform->Identity();
492 mConcatenatedFusionTransform->Concatenate(mFusion->GetTransform()[0]);
493 mConcatenatedFusionTransform->Concatenate(mSlicingTransform);
494 mFusionReslice->SetResliceTransform(mConcatenatedFusionTransform);
495 #if VTK_MAJOR_VERSION <= 5
496 mFusionReslice->SetInput(0, mFusion->GetFirstVTKImageData());
497 mFusionReslice->UpdateInformation();
499 mFusionReslice->SetInputData(0, mFusion->GetFirstVTKImageData());
501 mFusionReslice->Update();
504 mFusionMapper = vtkSmartPointer<vtkImageMapToColors>::New();
506 vtkSmartPointer<vtkLookupTable> lut = vtkLookupTable::New();
508 lut->SetValueRange(0, 1);
509 lut->SetSaturationRange(0, 0);
511 mFusionMapper->SetLookupTable(lut);
512 #if VTK_MAJOR_VERSION <= 5
513 mFusionMapper->SetInput(mFusionReslice->GetOutput());
515 mFusionMapper->SetInputConnection(mFusionReslice->GetOutputPort(0));
519 mFusionActor = vtkSmartPointer<vtkImageActor>::New();
520 #if VTK_MAJOR_VERSION <= 5
521 mFusionActor->SetInput(mFusionMapper->GetOutput());
523 mFusionActor->GetMapper()->SetInputConnection(mFusionMapper->GetOutputPort());
525 mFusionActor->SetPickable(0);
526 mFusionActor->SetVisibility(true);
527 mFusionActor->SetOpacity(0.7);
528 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
529 mFusionActor->GetMapper()->BorderOn();
532 this->GetRenderer()->AddActor(mFusionActor);
535 //Synchronize orientation and slice
536 AdjustResliceToSliceOrientation(mFusionReslice);
537 this->UpdateDisplayExtent();
538 this->SetTSlice(mCurrentTSlice);
541 //------------------------------------------------------------------------------
544 //------------------------------------------------------------------------------
545 bool vvSlicer::GetActorVisibility(const std::string& actor_type, int overlay_index)
548 if (actor_type == "image")
549 vis = mImageVisibility;
550 else if (actor_type == "vector")
552 else if (actor_type == "overlay")
553 vis = mOverlayVisibility;
554 else if ( (actor_type == "fusion") || (actor_type == "fusionSequence") )
555 vis = mFusionVisibility;
556 else if (actor_type == "contour")
557 vis = this->mSurfaceCutActors[overlay_index]->GetActor()->GetVisibility();
560 //------------------------------------------------------------------------------
562 //------------------------------------------------------------------------------
563 void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis)
565 if (actor_type == "image")
566 mImageVisibility = vis;
567 else if (actor_type == "vector")
569 else if (actor_type == "overlay")
570 mOverlayVisibility = vis;
571 else if ( (actor_type == "fusion") || (actor_type == "fusionSequence") )
572 mFusionVisibility = vis;
573 else if (actor_type == "contour")
574 this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis);
575 UpdateDisplayExtent();
577 //------------------------------------------------------------------------------
579 //------------------------------------------------------------------------------
580 void vvSlicer::SetVF(vvImage::Pointer vf)
582 if (vf->GetVTKImages().size()) {
584 mVFVisibility = true;
587 mVFReslice = vtkSmartPointer<vtkImageReslice>::New();
588 mVFReslice->SetInterpolationModeToLinear();
589 mVFReslice->AutoCropOutputOn();
590 mVFReslice->SetBackgroundColor(-1000,-1000,-1000,1);
591 mAAFilter= vtkSmartPointer<vtkAssignAttribute>::New();
592 mVOIFilter = vtkSmartPointer<vtkExtractVOI>::New();
593 mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
596 mConcatenatedVFTransform->Identity();
597 mConcatenatedVFTransform->Concatenate(mVF->GetTransform()[0]);
598 mConcatenatedVFTransform->Concatenate(mSlicingTransform);
599 mVFReslice->SetResliceTransform(mConcatenatedVFTransform);
600 #if VTK_MAJOR_VERSION <= 5
601 mVFReslice->SetInput(0, mVF->GetFirstVTKImageData());
603 mVFReslice->SetInputData(0, mVF->GetFirstVTKImageData());
605 mVFReslice->Update();
607 #if VTK_MAJOR_VERSION <= 5
608 mVOIFilter->SetInput(mVFReslice->GetOutput());
609 mAAFilter->SetInput(mVOIFilter->GetOutput());
611 mVOIFilter->SetInputConnection(mVFReslice->GetOutputPort());
612 mAAFilter->SetInputConnection(mVOIFilter->GetOutputPort());
614 ///This tells VTK to use the scalar (pixel) data of the image to draw the little arrows
615 mAAFilter->Assign(vtkDataSetAttributes::SCALARS, vtkDataSetAttributes::VECTORS, vtkAssignAttribute::POINT_DATA);
618 mArrow = vtkSmartPointer<vvGlyphSource>::New();
619 mArrow->SetGlyphTypeToSpecificArrow();
620 mArrow->SetScale(mScale);
623 // Glyph the gradient vector (with arrows)
625 mGlyphFilter = vtkSmartPointer<vvGlyph2D>::New();
626 #if VTK_MAJOR_VERSION <= 5
627 mGlyphFilter->SetInput(mAAFilter->GetOutput());
628 mGlyphFilter->SetSource(mArrow->GetOutput());
630 mGlyphFilter->SetInputConnection(mAAFilter->GetOutputPort());
631 mGlyphFilter->SetSourceConnection(mArrow->GetOutputPort());
633 mGlyphFilter->ScalingOn();
634 mGlyphFilter->SetScaleModeToScaleByVector();
635 mGlyphFilter->OrientOn();
636 mGlyphFilter->SetVectorModeToUseVector();
637 mGlyphFilter->SetColorModeToColorByVector();
640 mVFColorLUT = vtkSmartPointer<vtkLookupTable>::New();
642 double mVFColorHSV[3];
643 vtkMath::RGBToHSV(mVFColor, mVFColorHSV);
644 mVFColorLUT->SetHueRange(mVFColorHSV[0], mVFColorHSV[0]);
645 mVFColorLUT->SetSaturationRange(mVFColorHSV[1],mVFColorHSV[1]);
646 mVFColorLUT->SetValueRange(mVFColorHSV[2], mVFColorHSV[2]);
649 mVFMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
650 #if VTK_MAJOR_VERSION <= 5
651 mVFMapper->SetInput(mGlyphFilter->GetOutput());
653 mVFMapper->SetInputConnection(mGlyphFilter->GetOutputPort());
655 mVFMapper->ImmediateModeRenderingOn();
656 mVFMapper->SetLookupTable(mVFColorLUT);
659 mVFActor = vtkSmartPointer<vtkActor>::New();
660 mVFActor->SetMapper(mVFMapper);
661 mVFActor->SetPickable(0);
662 mVFActor->GetProperty()->SetLineWidth(mVFWidth);
663 this->UpdateDisplayExtent();
664 this->GetRenderer()->AddActor(mVFActor);
667 SetTSlice(mCurrentTSlice);
670 //------------------------------------------------------------------------------
673 //------------------------------------------------------------------------------
674 void vvSlicer::SetLandmarks(vvLandmarks* landmarks)
676 mLandmarks = landmarks;
680 mCross = vtkSmartPointer<vtkCursor3D>::New();
682 mClipBox = vtkSmartPointer<vtkBox>::New();
684 mLandClipper = vtkSmartPointer<vvClipPolyData>::New();
686 mLandGlyph = vtkSmartPointer<vtkGlyph3D>::New();
688 mLandMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
690 mLandActor = vtkSmartPointer<vtkActor>::New();
692 mCross->SetFocalPoint(0.0,0.0,0.0);
693 mCross->SetModelBounds(-10,10,-10,10,-10,10);
697 mLandClipper->SetClipFunction(mClipBox);
698 mLandClipper->InsideOutOn();
699 #if VTK_MAJOR_VERSION <= 5
700 mLandmarkTransform = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
701 mLandmarkTransform->SetInput(mLandmarks->GetOutput());
702 mConcatenatedTransform->Identity();
703 mConcatenatedTransform->Concatenate(mImage->GetTransform()[0]);
704 mConcatenatedTransform->Concatenate(mSlicingTransform);
705 mLandmarkTransform->SetTransform(mConcatenatedTransform->GetInverse());
706 mLandClipper->SetInput(mLandmarkTransform->GetOutput());
708 mLandGlyph->SetSource(mCross->GetOutput());
709 mLandGlyph->SetInput(mLandClipper->GetOutput());
711 mLandmarkTransform = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
712 mLandmarkTransform->SetInputData(mLandmarks->GetOutput());
713 mConcatenatedTransform->Identity();
714 mConcatenatedTransform->Concatenate(mImage->GetTransform()[0]);
715 mConcatenatedTransform->Concatenate(mSlicingTransform);
716 mLandmarkTransform->SetTransform(mConcatenatedTransform->GetInverse());
717 mLandClipper->SetInputConnection(mLandmarkTransform->GetOutputPort());
719 mLandGlyph->SetSourceConnection(mCross->GetOutputPort());
720 mLandGlyph->SetInputConnection(mLandClipper->GetOutputPort());
722 //mLandGlyph->SetIndexModeToScalar();
723 //mLandGlyph->SetRange(0,1);
724 //mLandGlyph->ScalingOff();
726 //mLandGlyph->SetColorModeToColorByScalar();
728 mLandGlyph->SetScaleModeToDataScalingOff();
729 mLandGlyph->SetIndexModeToOff();
731 mLandMapper->SetInputConnection(mLandGlyph->GetOutputPort());
732 //mLandMapper->ScalarVisibilityOff();
734 mLandActor->SetMapper(mLandMapper);
735 mLandActor->GetProperty()->SetOpacity(0.995); //in order to get VTK to turn on the alpha-blending in OpenGL
736 mLandActor->GetProperty()->SetColor(255,10,212);
737 mLandActor->SetPickable(0);
738 mLandActor->SetVisibility(true);
739 this->UpdateDisplayExtent();
742 //------------------------------------------------------------------------------
744 //------------------------------------------------------------------------------
745 //FIXME: this function leaks memory, we should fix it someday :)
746 void vvSlicer::RemoveActor(const std::string& actor_type, int overlay_index)
748 if (actor_type == "vector") {
749 Renderer->RemoveActor(mVFActor);
758 if (actor_type == "overlay") {
759 Renderer->RemoveActor(mOverlayActor);
761 mOverlayActor = NULL;
762 mOverlayMapper = NULL;
764 if ( (actor_type == "fusion") || (actor_type == "fusionSequence") ) {
765 Renderer->RemoveActor(mFusionActor);
768 mFusionMapper = NULL;
770 if (actor_type == "contour") {
771 Renderer->RemoveActor(this->mSurfaceCutActors[overlay_index]->GetActor());
772 mSurfaceCutActors.erase(mSurfaceCutActors.begin()+overlay_index);
775 //------------------------------------------------------------------------------
778 //------------------------------------------------------------------------------
779 void vvSlicer::SetVFSubSampling(int sub)
782 mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling);
785 UpdateDisplayExtent();
788 //------------------------------------------------------------------------------
791 //------------------------------------------------------------------------------
792 void vvSlicer::SetVFScale(int scale)
796 mArrow->SetScale(mScale);
797 UpdateDisplayExtent();
800 //------------------------------------------------------------------------------
802 //------------------------------------------------------------------------------
803 void vvSlicer::SetVFWidth(int width)
807 mVFActor->GetProperty()->SetLineWidth(mVFWidth);
808 UpdateDisplayExtent();
811 //------------------------------------------------------------------------------
814 //------------------------------------------------------------------------------
815 void vvSlicer::SetVFLog(int log)
819 mGlyphFilter->SetUseLog(mVFLog);
820 mGlyphFilter->Modified();
822 UpdateDisplayExtent();
825 //------------------------------------------------------------------------------
828 //------------------------------------------------------------------------------
829 void vvSlicer::SetTSlice(int t, bool updateLinkedImages)
831 if (!updateLinkedImages) {
833 #if VTK_MAJOR_VERSION <= 5
834 mImageReslice->SetInput( mImage->GetVTKImages()[mCurrentTSlice] );
836 mImageReslice->SetInputData( mImage->GetVTKImages()[mCurrentTSlice] );
839 mConcatenatedTransform->Identity();
840 mConcatenatedTransform->Concatenate(mImage->GetTransform()[mCurrentTSlice]);
841 mConcatenatedTransform->Concatenate(mSlicingTransform);
842 UpdateDisplayExtent();
847 else if ((unsigned int)t >= mImage->GetVTKImages().size())
848 mCurrentTSlice = mImage->GetVTKImages().size() -1;
853 mConcatenatedTransform->Identity();
854 mConcatenatedTransform->Concatenate(mImage->GetTransform()[mCurrentTSlice]);
855 mConcatenatedTransform->Concatenate(mSlicingTransform);
858 #if VTK_MAJOR_VERSION <= 5
859 mImageReslice->SetInput( mImage->GetVTKImages()[mCurrentTSlice] );
861 mImageReslice->SetInputData( mImage->GetVTKImages()[mCurrentTSlice] );
863 if (mVF && mVFActor->GetVisibility()) {
864 if (mVF->GetVTKImages().size() > (unsigned int)mCurrentTSlice)
865 #if VTK_MAJOR_VERSION <= 5
866 mVFReslice->SetInput(mVF->GetVTKImages()[mCurrentTSlice]);
868 mVFReslice->SetInputData(mVF->GetVTKImages()[mCurrentTSlice]);
870 // Update overlay transform
871 mConcatenatedVFTransform->Identity();
872 mConcatenatedVFTransform->Concatenate(mVF->GetTransform()[mCurrentTSlice]);
873 mConcatenatedVFTransform->Concatenate(mSlicingTransform);
876 if (mOverlay && mOverlayActor->GetVisibility()) {
877 if (mOverlay->GetVTKImages().size() > (unsigned int)t) {
878 mCurrentOverlayTSlice = t;
879 #if VTK_MAJOR_VERSION <= 5
880 mOverlayReslice->SetInput( mOverlay->GetVTKImages()[mCurrentOverlayTSlice] );
882 mOverlayReslice->SetInputData( mOverlay->GetVTKImages()[mCurrentOverlayTSlice] );
884 // Update overlay transform
885 mConcatenatedOverlayTransform->Identity();
886 mConcatenatedOverlayTransform->Concatenate(mOverlay->GetTransform()[mCurrentOverlayTSlice]);
887 mConcatenatedOverlayTransform->Concatenate(mSlicingTransform);
890 //update the fusion ; except in case this is a fusionSequence, in which case both 'times' should be independent.
891 if (mFusion && mFusionActor->GetVisibility() && (mFusionSequenceCode<0)) {
892 if (mFusion->GetVTKImages().size() > (unsigned int)t) {
893 mCurrentFusionTSlice = t;
894 #if VTK_MAJOR_VERSION <= 5
895 mFusionReslice->SetInput( mFusion->GetVTKImages()[mCurrentFusionTSlice]);
897 mFusionReslice->SetInputData( mFusion->GetVTKImages()[mCurrentFusionTSlice]);
900 // Update fusion transform
901 mConcatenatedFusionTransform->Identity();
902 mConcatenatedFusionTransform->Concatenate(mFusion->GetTransform()[mCurrentFusionTSlice]);
903 mConcatenatedFusionTransform->Concatenate(mSlicingTransform);
906 if (mSurfaceCutActors.size() > 0)
907 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
908 i!=mSurfaceCutActors.end(); i++)
909 (*i)->SetTimeSlice(mCurrentTSlice);
910 UpdateDisplayExtent();
912 //------------------------------------------------------------------------------
915 //------------------------------------------------------------------------------
916 void vvSlicer::SetFusionSequenceTSlice(int t)
918 if (mFusion && mFusionActor->GetVisibility() && (mFusionSequenceCode>=0)) {
919 if (mFusion->GetVTKImages().size() > (unsigned int)t) {
920 mCurrentFusionTSlice = t;
921 #if VTK_MAJOR_VERSION <= 5
922 mFusionReslice->SetInput( mFusion->GetVTKImages()[mCurrentFusionTSlice] );
924 mFusionReslice->SetInputData( mFusion->GetVTKImages()[mCurrentFusionTSlice] );
926 // Update fusion transform
927 mConcatenatedFusionTransform->Identity();
928 mConcatenatedFusionTransform->Concatenate(mFusion->GetTransform()[mCurrentFusionTSlice]); //not really useful...
929 mConcatenatedFusionTransform->Concatenate(mSlicingTransform);
933 UpdateDisplayExtent();
935 //------------------------------------------------------------------------------
938 //------------------------------------------------------------------------------
939 int vvSlicer::GetTSlice()
941 return mCurrentTSlice;
943 //------------------------------------------------------------------------------
945 //------------------------------------------------------------------------------
946 int vvSlicer::GetMaxCurrentTSlice()
948 int t = mCurrentTSlice;
949 if(mOverlay && mOverlayActor->GetVisibility())
950 t = std::max(t, mCurrentOverlayTSlice);
951 if(mFusion&& (mFusionSequenceCode<0) && mFusionActor->GetVisibility()) //ignore fusionSequence data: for these, the times are not to be related (this way)
952 t = std::max(t, mCurrentFusionTSlice);
955 //------------------------------------------------------------------------------
957 //------------------------------------------------------------------------------
958 int vvSlicer::GetFusionTSlice()
960 return mCurrentFusionTSlice;
962 //------------------------------------------------------------------------------
964 //------------------------------------------------------------------------------
965 int vvSlicer::GetOverlayTSlice()
967 return mCurrentOverlayTSlice;
969 //------------------------------------------------------------------------------
971 //------------------------------------------------------------------------------
972 void vvSlicer::SetSliceOrientation(int orientation)
974 //if 2D image, force to watch in Axial View
976 #if VTK_MAJOR_VERSION <= 5
977 this->GetInput()->GetWholeExtent(extent);
979 int* ext = mImageReslice->GetInputInformation()->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT());
980 copyExtent(ext, extent);
983 if (extent[5]-extent[4] <= 2)
984 orientation = vtkImageViewer2::SLICE_ORIENTATION_XY;
986 if (orientation < vtkImageViewer2::SLICE_ORIENTATION_YZ ||
987 orientation > vtkImageViewer2::SLICE_ORIENTATION_XY) {
988 vtkErrorMacro("Error - invalid slice orientation " << orientation);
992 this->SliceOrientation = orientation;
995 AdjustResliceToSliceOrientation(mFusionReslice);
998 AdjustResliceToSliceOrientation(mOverlayReslice);
1001 AdjustResliceToSliceOrientation(mVFReslice);
1003 // Update the viewer
1005 // Go to current cursor position
1006 // double* cursorPos = GetCursorPosition();
1007 // DDV(cursorPos, 3);
1008 // SetCurrentPosition(cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]);
1010 if (mFirstSetSliceOrientation) {
1011 int *range = this->GetSliceRange();
1013 this->Slice = static_cast<int>((range[0] + range[1]) * 0.5);
1014 #if VTK_MAJOR_VERSION <= 5
1015 mFirstSetSliceOrientation = false;
1018 else if (this->Renderer && this->GetInput()) {
1019 double s = mCursor[orientation];
1020 double sCursor = (s - this->GetInput()->GetOrigin()[orientation])/this->GetInput()->GetSpacing()[orientation];
1021 this->Slice = static_cast<int>(sCursor);
1024 this->UpdateOrientation();
1026 this->UpdateDisplayExtent();
1028 if (mFirstSetSliceOrientation) {
1029 mFirstSetSliceOrientation = false;
1032 if (this->Renderer && this->GetInput()) {
1033 double scale = this->Renderer->GetActiveCamera()->GetParallelScale();
1034 this->Renderer->ResetCamera();
1035 this->Renderer->GetActiveCamera()->SetParallelScale(scale);
1040 //----------------------------------------------------------------------------
1042 //------------------------------------------------------------------------------
1043 // This function ensures that we sample the slices of a vtkImageReslice filter
1044 // in the direction of the slicer (SliceOrientation) similarly as mImageReslice.
1045 // In other words, we change the grid of the reslice in the same way as the grid
1046 // of the displayed image in the slicing direction.
1047 void vvSlicer::AdjustResliceToSliceOrientation(vtkImageReslice *reslice)
1049 // Reset autocrop and update output information
1050 reslice->SetOutputOriginToDefault();
1051 reslice->SetOutputSpacingToDefault();
1052 #if VTK_MAJOR_VERSION <= 5
1053 reslice->GetOutput()->UpdateInformation();
1055 reslice->UpdateInformation();
1058 // Ge new origin / spacing
1061 reslice->GetOutput()->GetOrigin(origin);
1062 reslice->GetOutput()->GetSpacing(spacing);
1064 // Use similar spacing as the image in the direction SliceOrientation
1065 spacing[this->SliceOrientation] = mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation];
1067 // Modify origin to be on the image grid in the direction SliceOrientation in 3 steps
1068 // Step 1: from world coordinates to image coordinates
1069 origin[this->SliceOrientation] -= mImageReslice->GetOutput()->GetOrigin()[this->SliceOrientation];
1070 origin[this->SliceOrientation] /= mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation];
1072 // Step 2: round to nearest grid positionInc. This has been validated as the only
1073 // way to have something consistent with the thickness of a 2D slice visible on the
1074 // other slices. The thickness is accounted for so if the 2D slice is to thin and
1075 // between two slices, one will never be able to see this 2D slice (bug #1883).
1076 origin[this->SliceOrientation] = itk::Math::Round<double>(origin[this->SliceOrientation]);
1078 // Step 3: back to world coordinates
1079 origin[this->SliceOrientation] *= mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation];
1080 origin[this->SliceOrientation] += mImageReslice->GetOutput()->GetOrigin()[this->SliceOrientation];
1082 // Set new spacing and origin
1083 reslice->SetOutputOrigin(origin);
1084 reslice->SetOutputSpacing(spacing);
1085 reslice->UpdateInformation();
1086 #if VTK_MAJOR_VERSION <= 5
1087 reslice->GetOutput()->UpdateInformation();
1090 //------------------------------------------------------------------------------
1092 //----------------------------------------------------------------------------
1093 int * vvSlicer::GetExtent()
1096 if (mUseReducedExtent) {
1097 w_ext = mReducedExtent;
1100 #if VTK_MAJOR_VERSION <= 5
1101 w_ext = GetInput()->GetWholeExtent();
1103 w_ext = mImageReslice->GetInputInformation()->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT());
1108 //----------------------------------------------------------------------------
1111 //----------------------------------------------------------------------------
1112 int vvSlicer::GetOrientation()
1114 return this->SliceOrientation;
1116 //----------------------------------------------------------------------------
1119 //----------------------------------------------------------------------------
1120 void vvSlicer::UpdateDisplayExtent()
1122 emit UpdateDisplayExtentBegin(mSlicerNumber);
1123 vtkImageData *input = this->GetInput();
1124 if (!input || !this->ImageActor) {
1128 #if VTK_MAJOR_VERSION <= 5
1129 input->UpdateInformation();
1131 mRegisterExtent = mImageReslice->GetOutputInformation(0)->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT());
1133 this->SetSlice( this->GetSlice() ); //SR: make sure the update let the slice in extents
1135 // Local copy of extent
1137 #if VTK_MAJOR_VERSION <= 5
1138 int* ext = GetExtent();
1140 int* ext = mImageReslice->GetOutputInformation(0)->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT());
1142 copyExtent(ext, w_ext);
1143 if (mUseReducedExtent) {
1144 copyExtent(mReducedExtent, w_ext);
1148 w_ext[ this->SliceOrientation*2 ] = this->Slice;
1149 w_ext[ this->SliceOrientation*2+1 ] = this->Slice;
1152 this->ImageActor->SetVisibility(mImageVisibility);
1153 this->ImageActor->SetDisplayExtent(w_ext);
1155 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
1156 // Fix for bug #1882
1157 dynamic_cast<vtkImageSliceMapper *>(this->ImageActor->GetMapper())->SetOrientation(this->GetOrientation());
1160 // Overlay image actor
1161 if (mOverlay && mOverlayVisibility) {
1162 AdjustResliceToSliceOrientation(mOverlayReslice);
1164 #if VTK_MAJOR_VERSION <= 5
1165 this->ConvertImageToImageDisplayExtent(input, w_ext, mOverlayReslice->GetOutput(), overExtent);
1166 bool out = ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
1168 this->ConvertImageToImageDisplayExtent(mImageReslice->GetOutputInformation(0), w_ext, mOverlayReslice->GetOutput(), overExtent);
1169 bool out = ClipDisplayedExtent(overExtent, mOverlayMapper->GetInputInformation()->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()));
1171 mOverlayActor->SetVisibility(!out);
1172 mOverlayActor->SetDisplayExtent( overExtent );
1173 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
1174 // Fix for bug #1882
1175 dynamic_cast<vtkImageSliceMapper *>(mOverlayActor->GetMapper())->SetOrientation(this->GetOrientation());
1179 mOverlayActor->SetVisibility(false);
1181 // Fusion image actor
1182 if (mFusion && mFusionVisibility) {
1183 AdjustResliceToSliceOrientation(mFusionReslice);
1185 #if VTK_MAJOR_VERSION <= 5
1186 this->ConvertImageToImageDisplayExtent(input, w_ext, mFusionReslice->GetOutput(), fusExtent);
1187 bool out = ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
1189 this->ConvertImageToImageDisplayExtent(mImageReslice->GetOutputInformation(0), w_ext, mFusionReslice->GetOutput(), fusExtent);
1190 bool out = ClipDisplayedExtent(fusExtent, mFusionMapper->GetInputInformation()->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()));
1192 mFusionActor->SetVisibility(!out);
1193 mFusionActor->SetDisplayExtent( fusExtent );
1194 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
1195 // Fix for bug #1882
1196 dynamic_cast<vtkImageSliceMapper *>(mFusionActor->GetMapper())->SetOrientation(this->GetOrientation());
1200 mFusionActor->SetVisibility(false);
1201 // Vector field actor
1202 double* camera = Renderer->GetActiveCamera()->GetPosition();
1203 double* image_bounds = ImageActor->GetBounds();
1204 double position[3] = {0, 0, 0};
1205 position[this->SliceOrientation] = image_bounds[this->SliceOrientation*2];
1207 //print_vector<double, 6>("camera", camera);
1208 //print_vector<double, 6>("image_bounds", image_bounds);
1209 //print_vector<double, 3>("position", position);
1211 // find where to place the VF actor. to deal with
1212 // z-buffer issues, the VF is placed right in front of the image,
1213 // subject to a small offset. the position actually depends on the
1214 // the location of the camera relative to the image.
1216 if (camera[this->SliceOrientation] < image_bounds[this->SliceOrientation*2])
1219 if (mVF && mVFVisibility) {
1220 AdjustResliceToSliceOrientation(mVFReslice);
1222 #if VTK_MAJOR_VERSION <= 5
1223 mVF->GetVTKImages()[0]->UpdateInformation();
1224 this->ConvertImageToImageDisplayExtent(input, w_ext, mVFReslice->GetOutput(), vfExtent);
1225 bool out = ClipDisplayedExtent(vfExtent, mVOIFilter->GetInput()->GetWholeExtent());
1227 mVOIFilter->Update();
1228 this->ConvertImageToImageDisplayExtent(mImageReslice->GetOutputInformation(0), w_ext, mVFReslice->GetOutput(), vfExtent);
1229 bool out = ClipDisplayedExtent(vfExtent, mVOIFilter->GetInputInformation()->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()));
1231 mVFActor->SetVisibility(!out);
1232 mVOIFilter->SetVOI(vfExtent);
1233 int orientation[3] = {1,1,1};
1234 orientation[this->SliceOrientation] = 0;
1235 mGlyphFilter->SetOrientation(orientation[0], orientation[1], orientation[2]);
1236 position[this->SliceOrientation] += offset;
1237 mVFActor->SetPosition(position);
1238 mVFActor->GetProperty()->SetOpacity(0.995); //in order to get VTK to turn on the alpha-blending in OpenGL
1239 mVFMapper->Update();
1243 mVFActor->SetVisibility(false);
1247 for(unsigned int i=0; i<6; i++)
1248 boundsT[i] = ImageActor->GetBounds()[i];
1249 boundsT[ this->SliceOrientation*2 ] = ImageActor->GetBounds()[ this->SliceOrientation*2 ]-fabs(this->GetInput()->GetSpacing()[this->SliceOrientation]);
1250 boundsT[ this->SliceOrientation*2+1 ] = ImageActor->GetBounds()[ this->SliceOrientation*2+1 ]+fabs(this->GetInput()->GetSpacing()[this->SliceOrientation]);
1259 position[this->SliceOrientation] = offset;
1260 mLandActor->SetPosition(position);
1263 // Figure out the correct clipping range
1264 if (this->Renderer) {
1265 if (this->InteractorStyle &&
1266 this->InteractorStyle->GetAutoAdjustCameraClippingRange()) {
1267 this->Renderer->ResetCameraClippingRange();
1269 vtkCamera *cam = this->Renderer->GetActiveCamera();
1272 this->ImageActor->GetBounds(bounds);
1273 double spos = (double)bounds[this->SliceOrientation * 2];
1274 double cpos = (double)cam->GetPosition()[this->SliceOrientation];
1275 double range = fabs(spos - cpos);
1276 double *spacing = input->GetSpacing();
1277 double sumSpacing = spacing[0] + spacing[1] + spacing[2];
1278 cam->SetClippingRange(range - sumSpacing, range + sumSpacing);
1288 emit UpdateDisplayExtentEnd(mSlicerNumber);
1290 //----------------------------------------------------------------------------
1292 //----------------------------------------------------------------------------
1293 void vvSlicer::ConvertImageToImageDisplayExtent(vtkInformation *sourceImage, const int sourceExtent[6],
1294 vtkImageData *targetImage, int targetExtent[6])
1297 double *origin, *spacing;
1298 origin = sourceImage->Get(vtkDataObject::ORIGIN());
1299 spacing = sourceImage->Get(vtkDataObject::SPACING());
1300 for(unsigned int i=0; i<6; i++) {
1301 // From source voxel coordinates to world coordinates
1302 dExtents[i] = origin[i/2] + spacing[i/2] * sourceExtent[i];
1304 // From world coordinates to floating point target voxel coordinates
1305 dExtents[i] = (dExtents[i]- targetImage->GetOrigin()[i/2]) / targetImage->GetSpacing()[i/2];
1307 // Round to current slice or larger extent
1308 if(i/2==this->GetOrientation())
1309 targetExtent[i] = itk::Math::Round<double>(dExtents[i]);
1311 targetExtent[i] = itk::Math::Ceil<double>(dExtents[i]);
1313 targetExtent[i] = itk::Math::Floor<double>(dExtents[i]);
1316 //----------------------------------------------------------------------------
1318 //----------------------------------------------------------------------------
1319 void vvSlicer::ConvertImageToImageDisplayExtent(vtkImageData *sourceImage, const int sourceExtent[6],
1320 vtkImageData *targetImage, int targetExtent[6])
1323 for(unsigned int i=0; i<6; i++) {
1324 // From source voxel coordinates to world coordinates
1325 dExtents[i] = sourceImage->GetOrigin()[i/2] + sourceImage->GetSpacing()[i/2] * sourceExtent[i];
1327 // From world coordinates to floating point target voxel coordinates
1328 dExtents[i] = (dExtents[i]- targetImage->GetOrigin()[i/2]) / targetImage->GetSpacing()[i/2];
1330 // Round to current slice or larger extent
1331 if(i/2==this->GetOrientation())
1332 targetExtent[i] = itk::Math::Round<double>(dExtents[i]);
1334 targetExtent[i] = itk::Math::Ceil<double>(dExtents[i]);
1336 targetExtent[i] = itk::Math::Floor<double>(dExtents[i]);
1339 //----------------------------------------------------------------------------
1341 //----------------------------------------------------------------------------
1342 bool vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
1347 for (int i = 0; i < maxBound; i = i+2) {
1348 //if we are totally outside the image
1349 if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] ) {
1353 //crop to the limit of the image
1354 extent[i] = std::max(extent[i], refExtent[i]);
1355 extent[i] = std::min(extent[i], refExtent[i+1]);;
1356 extent[i+1] = std::max(extent[i+1], refExtent[i]);
1357 extent[i+1] = std::min(extent[i+1], refExtent[i+1]);;
1360 for (int i = 0; i < maxBound; i = i+2) {
1361 extent[i] = refExtent[i];
1362 extent[i+1] = refExtent[i];
1366 //----------------------------------------------------------------------------
1369 //----------------------------------------------------------------------------
1370 void vvSlicer::UpdateOrientation()
1372 // Set the camera position
1373 vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1375 switch (this->SliceOrientation) {
1376 case vtkImageViewer2::SLICE_ORIENTATION_XY:
1377 cam->SetFocalPoint(0,0,0);
1378 cam->SetPosition(0,0,-1); // -1 if medical ?
1379 cam->SetViewUp(0,-1,0);
1382 case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1383 cam->SetFocalPoint(0,0,0);
1384 cam->SetPosition(0,-1,0); // 1 if medical ?
1385 cam->SetViewUp(0,0,1);
1388 case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1389 cam->SetFocalPoint(0,0,0);
1390 cam->SetPosition(-1,0,0); // -1 if medical ?
1391 cam->SetViewUp(0,0,1);
1396 //----------------------------------------------------------------------------
1399 //----------------------------------------------------------------------------
1400 void vvSlicer::SetOpacity(double s)
1402 this->GetImageActor()->SetOpacity(s);
1404 //----------------------------------------------------------------------------
1407 //----------------------------------------------------------------------------
1408 void vvSlicer::SetRenderWindow(int orientation, vtkRenderWindow * rw)
1410 this->Superclass::SetRenderWindow(rw);
1411 this->SetupInteractor(rw->GetInteractor());
1412 ca->SetImageActor(this->GetImageActor());
1413 ca->SetWindowLevel(this->GetWindowLevel());
1414 ca->SetText(3, "<window>\n<level>");
1425 crossCursor->SetModelBounds(bounds);
1427 this->GetRenderer()->AddActor(pdmA);
1428 this->GetRenderer()->AddActor(ca);
1429 this->GetRenderer()->ResetCamera();
1431 //this is just a mapping between the labeling of the orientations presented to the user and
1432 //the one used by vtk
1433 SetSliceOrientation(2-(orientation%3));
1436 //----------------------------------------------------------------------------
1439 //----------------------------------------------------------------------------
1440 void vvSlicer::ResetCamera()
1442 this->GetRenderer()->ResetCamera();
1444 //----------------------------------------------------------------------------
1447 //----------------------------------------------------------------------------
1448 void vvSlicer::SetDisplayMode(bool i)
1450 this->GetRenderer()->SetDraw(i);
1451 if (i) UpdateDisplayExtent();
1453 //----------------------------------------------------------------------------
1456 //----------------------------------------------------------------------------
1457 void vvSlicer::FlipHorizontalView()
1459 vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1461 double *position = cam->GetPosition();
1462 double factor[3] = {1, 1, 1};
1463 factor[this->SliceOrientation] = -1;
1464 cam->SetPosition(factor[0]*position[0],factor[1]*position[1],factor[2]*position[2]);
1466 /* switch (this->SliceOrientation) {
1467 case vtkImageViewer2::SLICE_ORIENTATION_XY:
1468 cam->SetPosition(position[0],position[1],-position[2]);
1471 case vtkImageViewer2::SLICE_ORIENTATION_XZ:
1472 cam->SetPosition(position[0],-position[1],position[2]);
1475 case vtkImageViewer2::SLICE_ORIENTATION_YZ:
1476 cam->SetPosition(-position[0],position[1],position[2]);
1480 this->Renderer->ResetCameraClippingRange();
1481 this->UpdateDisplayExtent();
1484 //----------------------------------------------------------------------------
1487 //----------------------------------------------------------------------------
1488 void vvSlicer::FlipVerticalView()
1490 vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
1492 FlipHorizontalView();
1493 double *viewup = cam->GetViewUp();
1494 cam->SetViewUp(-viewup[0],-viewup[1],-viewup[2]);
1495 this->UpdateDisplayExtent();
1498 //----------------------------------------------------------------------------
1501 //----------------------------------------------------------------------------
1502 void vvSlicer::SetColorWindow(double window)
1504 vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1506 double level = this->GetWindowLevel()->GetLevel();
1507 LUT->SetTableRange(level-fabs(window)/2,level+fabs(window)/2);
1510 this->vtkImageViewer2::SetColorWindow(window);
1512 //----------------------------------------------------------------------------
1514 //----------------------------------------------------------------------------
1515 void vvSlicer::SetColorLevel(double level)
1517 vtkLookupTable* LUT = static_cast<vtkLookupTable*>(this->GetWindowLevel()->GetLookupTable());
1519 double window = this->GetWindowLevel()->GetWindow();
1520 LUT->SetTableRange(level-fabs(window)/2,level+fabs(window)/2);
1523 this->vtkImageViewer2::SetColorLevel(level);
1525 //----------------------------------------------------------------------------
1527 //----------------------------------------------------------------------------
1528 double vvSlicer::GetOverlayColorWindow()
1531 return mOverlayMapper->GetWindow();
1535 //----------------------------------------------------------------------------
1537 //----------------------------------------------------------------------------
1538 double vvSlicer::GetOverlayColorLevel()
1541 return mOverlayMapper->GetLevel();
1545 //----------------------------------------------------------------------------
1547 //----------------------------------------------------------------------------
1548 void vvSlicer::SetOverlayColorWindow(double window)
1551 mOverlayMapper->SetWindow(window);
1553 //----------------------------------------------------------------------------
1555 //----------------------------------------------------------------------------
1556 void vvSlicer::SetOverlayColorLevel(double level)
1559 mOverlayMapper->SetLevel(level);
1561 //----------------------------------------------------------------------------
1563 //----------------------------------------------------------------------------
1564 // Returns the min an the max value in a 20%x20% region around the mouse pointer
1565 void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image, vtkTransform *transform)
1567 //Get mouse pointer position in view coordinates
1570 for(int i=0; i<3; i++) {
1571 corner1[i] = mCurrent[i];
1572 corner2[i] = mCurrent[i];
1575 this->Renderer->WorldToView(corner1[0], corner1[1], corner1[2]);
1576 this->Renderer->WorldToView(corner2[0], corner2[1], corner2[2]);
1578 // In view coordinates, x is the slicer width and y is the slicer height are the in-plane axis
1580 this->Renderer->GetTiledSize(&w, &h);
1581 corner1[0] -= 0.2*h/(double)w;
1582 corner2[0] += 0.2*h/(double)w;
1585 this->Renderer->ViewToWorld(corner1[0], corner1[1], corner1[2]);
1586 this->Renderer->ViewToWorld(corner2[0], corner2[1], corner2[2]);
1588 //Convert to image pixel coordinates (rounded)
1589 transform->TransformPoint(corner1, corner1);
1590 transform->TransformPoint(corner2, corner2);
1591 int iLocalExtents[6];
1592 for(int i=0; i<3; i++) {
1593 corner1[i] = (corner1[i] - image->GetOrigin()[i])/image->GetSpacing()[i];
1594 corner2[i] = (corner2[i] - image->GetOrigin()[i])/image->GetSpacing()[i];
1596 iLocalExtents[i*2 ] = lrint(corner1[i]);
1597 iLocalExtents[i*2+1] = lrint(corner2[i]);
1599 if(iLocalExtents[i*2 ]>iLocalExtents[i*2+1])
1600 std::swap(iLocalExtents[i*2], iLocalExtents[i*2+1]);
1602 #if VTK_MAJOR_VERSION > 5
1603 for(int j=0;j<2; j++) {
1604 if(iLocalExtents[i*2+j]< mImageReslice->GetInputInformation()->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT())[2*i])
1605 iLocalExtents[i*2+j] = mImageReslice->GetInputInformation()->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT())[2*i];
1607 if(iLocalExtents[i*2+j]> mImageReslice->GetInputInformation()->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT())[2*i+1])
1608 iLocalExtents[i*2+j] = mImageReslice->GetInputInformation()->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT())[2*i+1];
1613 vtkSmartPointer<vtkExtractVOI> voiFilter = vtkSmartPointer<vtkExtractVOI>::New();
1614 #if VTK_MAJOR_VERSION <= 5
1615 voiFilter->SetInput(image);
1617 voiFilter->SetInputData(image);
1619 voiFilter->SetVOI(iLocalExtents);
1620 voiFilter->Update();
1621 if (!voiFilter->GetOutput()->GetNumberOfPoints()) {
1627 vtkSmartPointer<vtkImageAccumulate> accFilter = vtkSmartPointer<vtkImageAccumulate>::New();
1628 #if VTK_MAJOR_VERSION <= 5
1629 accFilter->SetInput(voiFilter->GetOutput());
1631 accFilter->SetInputConnection(voiFilter->GetOutputPort(0));
1633 accFilter->Update();
1635 min = *(accFilter->GetMin());
1636 max = *(accFilter->GetMax());
1638 //----------------------------------------------------------------------------
1640 //----------------------------------------------------------------------------
1641 double vvSlicer::GetScalarComponentAsDouble(vtkImageData *image, double X, double Y, double Z, int &ix, int &iy, int &iz, int component)
1646 #if VTK_MAJOR_VERSION <= 5
1647 if (ix < image->GetWholeExtent()[0] ||
1648 ix > image->GetWholeExtent()[1] ||
1649 iy < image->GetWholeExtent()[2] ||
1650 iy > image->GetWholeExtent()[3] ||
1651 iz < image->GetWholeExtent()[4] ||
1652 iz > image->GetWholeExtent()[5] )
1653 return std::numeric_limits<double>::quiet_NaN();
1654 image->SetUpdateExtent(ix, ix, iy, iy, iz, iz);
1657 if (ix < image->GetInformation()->Get(vtkDataObject::DATA_EXTENT())[0] ||
1658 ix > image->GetInformation()->Get(vtkDataObject::DATA_EXTENT())[1] ||
1659 iy < image->GetInformation()->Get(vtkDataObject::DATA_EXTENT())[2] ||
1660 iy > image->GetInformation()->Get(vtkDataObject::DATA_EXTENT())[3] ||
1661 iz < image->GetInformation()->Get(vtkDataObject::DATA_EXTENT())[4] ||
1662 iz > image->GetInformation()->Get(vtkDataObject::DATA_EXTENT())[5] )
1663 return std::numeric_limits<double>::quiet_NaN();
1664 //image->SetUpdateExtent(ix, ix, iy, iy, iz, iz);
1667 return image->GetScalarComponentAsDouble(ix, iy, iz, component);
1669 //----------------------------------------------------------------------------
1671 //----------------------------------------------------------------------------
1672 void vvSlicer::Render()
1674 if (this->mFusion && mFusionActor->GetVisibility() && showFusionLegend) {
1675 legend->SetLookupTable(this->GetFusionMapper()->GetLookupTable());
1676 legend->UseOpacityOn();
1677 legend->SetVisibility(1);
1679 else if (this->GetWindowLevel()->GetLookupTable() && !this->mOverlay) {
1680 legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable());
1681 legend->UseOpacityOff();
1682 legend->SetVisibility(1);
1683 } else legend->SetVisibility(0);
1685 if (ca->GetVisibility()) {
1686 std::stringstream worldPos(" ");
1688 mConcatenatedTransform->TransformPoint(mCurrent, pt);
1689 double X = (pt[0] - mImage->GetVTKImages()[mCurrentTSlice]->GetOrigin()[0])/mImage->GetVTKImages()[mCurrentTSlice]->GetSpacing()[0];
1690 double Y = (pt[1] - mImage->GetVTKImages()[mCurrentTSlice]->GetOrigin()[1])/mImage->GetVTKImages()[mCurrentTSlice]->GetSpacing()[1];
1691 double Z = (pt[2] - mImage->GetVTKImages()[mCurrentTSlice]->GetOrigin()[2])/mImage->GetVTKImages()[mCurrentTSlice]->GetSpacing()[2];
1692 #if VTK_MAJOR_VERSION <= 5
1693 if (X >= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[0]-0.5 &&
1694 X <= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[1]+0.5 &&
1695 Y >= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[2]-0.5 &&
1696 Y <= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[3]+0.5 &&
1697 Z >= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[4]-0.5 &&
1698 Z <= mImage->GetVTKImages()[mCurrentTSlice]->GetWholeExtent()[5]+0.5) {
1700 if (X >= mImage->GetVTKImages()[mCurrentTSlice]->GetInformation()->Get(vtkDataObject::DATA_EXTENT())[0]-0.5 &&
1701 X <= mImage->GetVTKImages()[mCurrentTSlice]->GetInformation()->Get(vtkDataObject::DATA_EXTENT())[1]+0.5 &&
1702 Y >= mImage->GetVTKImages()[mCurrentTSlice]->GetInformation()->Get(vtkDataObject::DATA_EXTENT())[2]-0.5 &&
1703 Y <= mImage->GetVTKImages()[mCurrentTSlice]->GetInformation()->Get(vtkDataObject::DATA_EXTENT())[3]+0.5 &&
1704 Z >= mImage->GetVTKImages()[mCurrentTSlice]->GetInformation()->Get(vtkDataObject::DATA_EXTENT())[4]-0.5 &&
1705 Z <= mImage->GetVTKImages()[mCurrentTSlice]->GetInformation()->Get(vtkDataObject::DATA_EXTENT())[5]+0.5) {
1708 double value = this->GetScalarComponentAsDouble(mImage->GetVTKImages()[mCurrentTSlice], X, Y, Z, ix, iy, iz);
1709 if(ImageActor->GetVisibility())
1710 worldPos << "data value : " << value << std::endl;
1711 worldPos << "mm : " << lrint(mCurrent[0]) << ' '
1712 << lrint(mCurrent[1]) << ' '
1713 << lrint(mCurrent[2]) << ' '
1716 worldPos << "pixel : " << ix << ' '
1723 ca->SetText(1,worldPos.str().c_str());
1725 std::stringstream slicePos;
1726 slicePos << "Slice: " << this->GetSlice();
1727 ca->SetText(2, slicePos.str().c_str());
1730 if (pdmA->GetVisibility()) {
1731 double x = mCursor[0];
1732 double y = mCursor[1];
1733 double z = mCursor[2];
1734 double xCursor = (x - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0];
1735 double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1];
1736 double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2];
1737 #if VTK_MAJOR_VERSION <= 5
1738 if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0]-0.5 &&
1739 xCursor < this->GetImageActor()->GetDisplayExtent()[1]+0.5 &&
1740 yCursor >= this->GetImageActor()->GetDisplayExtent()[2]-0.5 &&
1741 yCursor < this->GetImageActor()->GetDisplayExtent()[3]+0.5 &&
1742 zCursor >= this->GetImageActor()->GetDisplayExtent()[4]-0.5 &&
1743 zCursor < this->GetImageActor()->GetDisplayExtent()[5]+0.5 ) {
1744 vtkRenderer * renderer = this->Renderer;
1746 renderer->WorldToView(x,y,z);
1747 renderer->ViewToNormalizedViewport(x,y,z);
1748 renderer->NormalizedViewportToViewport(x,y);
1749 renderer->ViewportToNormalizedDisplay(x,y);
1750 renderer->NormalizedDisplayToDisplay(x,y);
1751 crossCursor->SetFocalPoint(x,y,z);
1753 crossCursor->SetFocalPoint(-1,-1,z);
1754 crossCursor->Update();
1757 vtkSmartPointer<vtkOpenGLImageSliceMapper> mapperOpenGL= vtkSmartPointer<vtkOpenGLImageSliceMapper>::New();
1759 mapperOpenGL = dynamic_cast<vtkOpenGLImageSliceMapper*>(GetImageActor()->GetMapper());
1760 } catch (const std::bad_cast& e) {
1761 std::cerr << e.what() << std::endl;
1762 std::cerr << "Conversion error" << std::endl;
1766 if (xCursor >= mapperOpenGL->GetCroppingRegion()[0]-0.5 &&
1767 xCursor < mapperOpenGL->GetCroppingRegion()[1]+0.5 &&
1768 yCursor >= mapperOpenGL->GetCroppingRegion()[2]-0.5 &&
1769 yCursor < mapperOpenGL->GetCroppingRegion()[3]+0.5 &&
1770 zCursor >= mapperOpenGL->GetCroppingRegion()[4]-0.5 &&
1771 zCursor < mapperOpenGL->GetCroppingRegion()[5]+0.5 ) {
1772 vtkRenderer * renderer = this->Renderer;
1774 renderer->WorldToView(x,y,z);
1775 renderer->ViewToNormalizedViewport(x,y,z);
1776 renderer->NormalizedViewportToViewport(x,y);
1777 renderer->ViewportToNormalizedDisplay(x,y);
1778 renderer->NormalizedDisplayToDisplay(x,y);
1779 crossCursor->SetFocalPoint(x,y,z);
1781 crossCursor->SetFocalPoint(-1,-1,z);
1782 crossCursor->Update();
1786 if (mOverlay && mOverlayActor->GetVisibility()) {
1787 if(mLinkOverlayWindowLevel) {
1788 mOverlayMapper->SetWindow(this->GetColorWindow());
1789 mOverlayMapper->SetLevel(this->GetColorLevel());
1791 #if VTK_MAJOR_VERSION <= 5
1792 mOverlayMapper->GetOutput()->SetUpdateExtent(mOverlayActor->GetDisplayExtent());
1794 mOverlayMapper->SetUpdateExtent(mOverlayActor->GetDisplayExtent());
1796 mOverlayMapper->Update();
1798 if (mFusion && mFusionActor->GetVisibility()) {
1799 #if VTK_MAJOR_VERSION <= 5
1800 mFusionMapper->GetOutput()->SetUpdateExtent(mFusionActor->GetDisplayExtent());
1802 mFusionMapper->SetUpdateExtent(mFusionActor->GetDisplayExtent());
1804 mFusionMapper->Update();
1811 this->GetRenderWindow()->Render();
1813 //----------------------------------------------------------------------------
1816 //----------------------------------------------------------------------------
1817 void vvSlicer::UpdateCursorPosition()
1819 pdmA->SetVisibility(true);
1820 mCursor[0] = mCurrent[0];
1821 mCursor[1] = mCurrent[1];
1822 mCursor[2] = mCurrent[2];
1823 mCursor[3] = mCurrentTSlice;
1825 //----------------------------------------------------------------------------
1828 //----------------------------------------------------------------------------
1829 void vvSlicer::RemoveLandmarks()
1831 vtkPolyData *pd = static_cast<vtkPolyData*>(mLandmarks->GetOutput());
1832 if (pd->GetPoints()) {
1834 //First remove all captions:
1835 for(unsigned int i=0;i<mLandLabelActors.size();i++) {
1836 this->Renderer->RemoveActor2D(mLandLabelActors[i]);
1837 //allActors2D->Remove (mLandLabelActors[i]);
1839 mLandLabelActors.clear();
1842 //----------------------------------------------------------------------------
1845 //----------------------------------------------------------------------------
1846 void vvSlicer::DisplayLandmarks()
1850 for(unsigned int i=0; i<6; i++)
1851 bounds[i] = ImageActor->GetBounds()[i];
1852 bounds[ this->SliceOrientation*2 ] = ImageActor->GetBounds()[ this->SliceOrientation*2 ]-fabs(this->GetInput()->GetSpacing()[this->SliceOrientation]);
1853 bounds[ this->SliceOrientation*2+1 ] = ImageActor->GetBounds()[ this->SliceOrientation*2+1 ]+fabs(this->GetInput()->GetSpacing()[this->SliceOrientation]);
1854 mClipBox->SetBounds(bounds);
1857 vtkPolyData *pd = static_cast<vtkPolyData*>(mLandmarks->GetOutput());
1858 if (pd->GetPoints()) {
1859 this->GetRenderer()->AddActor(mLandActor);
1860 //mLandGlyph->SetRange(0,1);
1861 //mLandGlyph->Modified();
1862 //mLandGlyph->Update();
1863 mClipBox->Modified();
1864 mLandClipper->Update();
1865 mLandMapper->Update();
1866 //Next add the captions to the displayed points
1867 for (vtkIdType id=0; id<mLandClipper->GetOutput()->GetNumberOfPoints(); id++) {
1868 double *position = mLandClipper->GetOutput()->GetPoint(id);
1869 vtkStdString label = static_cast<vtkStringArray*>(mLandClipper->GetOutput()->GetPointData()->GetAbstractArray("labels"))->GetValue(id);
1870 vtkSmartPointer<vtkCaptionActor2D> label_actor = vtkSmartPointer<vtkCaptionActor2D>::New();
1871 label_actor->SetCaption(label);
1872 label_actor->SetAttachmentPoint(position);
1873 label_actor->GetCaptionTextProperty()->SetColor(1,0,0);
1874 label_actor->GetCaptionTextProperty()->SetOrientation(33.333333);
1875 label_actor->GetCaptionTextProperty()->SetFontFamilyToTimes();
1876 label_actor->GetCaptionTextProperty()->SetBold(0);
1877 label_actor->GetCaptionTextProperty()->SetFontSize(6);
1878 label_actor->BorderOff();
1879 label_actor->LeaderOff();
1880 label_actor->ThreeDimensionalLeaderOff();
1881 mLandLabelActors.push_back(label_actor);
1882 this->Renderer->AddActor2D(mLandLabelActors[id]);
1887 //----------------------------------------------------------------------------
1890 //----------------------------------------------------------------------------
1891 void vvSlicer::SetSlice(int slice)
1893 int *range = this->GetSliceRange();
1895 if (slice < range[0]) {
1897 } else if (slice > range[1]) {
1902 if (this->Slice == slice) {
1906 this->Slice = slice;
1909 this->UpdateDisplayExtent();
1911 // Seems to work without this line
1914 //----------------------------------------------------------------------------
1916 //----------------------------------------------------------------------------
1917 int vvSlicer::GetTMax()
1919 int tmax = (int)mImage->GetVTKImages().size() - 1;
1921 tmax = std::max(tmax, (int)mOverlay->GetVTKImages().size()-1);
1924 //----------------------------------------------------------------------------
1926 //----------------------------------------------------------------------------
1927 void vvSlicer::SetContourSlice()
1929 if (mSurfaceCutActors.size() > 0)
1930 for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
1931 i!=mSurfaceCutActors.end(); i++) {
1933 (*i)->SetSlicingOrientation(this->SliceOrientation);
1934 (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+
1935 this->GetImage()->GetOrigin()[this->SliceOrientation]);
1938 //----------------------------------------------------------------------------
1941 //----------------------------------------------------------------------------
1942 void vvSlicer::ForceUpdateDisplayExtent()
1944 this->UpdateDisplayExtent();
1946 //----------------------------------------------------------------------------
1949 //----------------------------------------------------------------------------
1950 int* vvSlicer::GetDisplayExtent()
1952 return this->GetImageActor()->GetDisplayExtent();
1954 //----------------------------------------------------------------------------
1957 //----------------------------------------------------------------------------
1958 void vvSlicer::PrintSelf(ostream& os, vtkIndent indent)
1960 this->Superclass::PrintSelf(os, indent);
1962 //----------------------------------------------------------------------------
1965 //----------------------------------------------------------------------------
1966 void vvSlicer::SetVFColor(double r, double g, double b)
1968 double mVFColorHSV[3];
1973 vtkMath::RGBToHSV(mVFColor, mVFColorHSV);
1974 mVFColorLUT->SetHueRange(mVFColorHSV[0], mVFColorHSV[0]);
1975 mVFColorLUT->SetSaturationRange(mVFColorHSV[1],mVFColorHSV[1]);
1976 mVFColorLUT->SetValueRange(mVFColorHSV[2], mVFColorHSV[2]);
1980 //----------------------------------------------------------------------------
1983 //----------------------------------------------------------------------------
1984 void vvSlicer::SetRegisterExtent(int ext[6])
1986 copyExtent(ext, mRegisterExtent);
1988 //----------------------------------------------------------------------------
1991 //----------------------------------------------------------------------------
1992 void vvSlicer::GetRegisterExtent(int ext[6])
1994 copyExtent(mRegisterExtent, ext);
1996 //----------------------------------------------------------------------------