X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=vv%2FvvSlicer.cxx;h=89ea9786e61598739c934d84dc06e31632e7e2df;hb=f57924a2649534451ac1ae5a2bdc63e0b6a0092d;hp=1de1738c030f39925a49c96fe740945d07bea407;hpb=26c6b8e9d0333a9e0be98c3fb9d57f133477d97d;p=clitk.git diff --git a/vv/vvSlicer.cxx b/vv/vvSlicer.cxx index 1de1738..89ea978 100644 --- a/vv/vvSlicer.cxx +++ b/vv/vvSlicer.cxx @@ -1,7 +1,7 @@ /*========================================================================= Program: vv http://www.creatis.insa-lyon.fr/rio/vv - Authors belong to: + Authors belong to: - University of LYON http://www.universite-lyon.fr/ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr @@ -73,6 +73,7 @@ vtkStandardNewMacro(vvSlicer); //------------------------------------------------------------------------------ vvSlicer::vvSlicer() { + this->UnInstallPipeline(); mImage = NULL; mCurrentTSlice = 0; mUseReducedExtent = false; @@ -90,6 +91,9 @@ vvSlicer::vvSlicer() mScale = 1; mVFLog = 0; mVFWidth = 1; + mVFColor[0] = 0; + mVFColor[1] = 1; + mVFColor[2] = 0; std::string text = "F1 = sagital; F2 = coronal; F3 = axial\n"; text += "F5 = horizontal flip; F6 = vertical flip\n\n"; @@ -107,22 +111,22 @@ vvSlicer::vvSlicer() text += "middle button : grab image\n"; text += "right button : change windowing\n"; - crossCursor = vtkCursor2D::New(); + crossCursor = vtkSmartPointer::New(); crossCursor->AllOff(); crossCursor->AxesOn(); crossCursor->SetTranslationMode(1); crossCursor->SetRadius(2); - pdm = vtkPolyDataMapper2D::New(); + pdm = vtkSmartPointer::New(); pdm->SetInput(crossCursor->GetOutput()); - pdmA = vtkActor2D::New(); + pdmA = vtkSmartPointer::New(); pdmA->SetMapper(pdm); pdmA->GetProperty()->SetColor(255,10,212); pdmA->SetVisibility(0); pdmA->SetPickable(0); - ca = vtkCornerAnnotation::New(); + ca = vtkSmartPointer::New(); ca->GetTextProperty()->SetColor(255,10,212); ca->SetVisibility(1); mFileName = ""; @@ -142,63 +146,71 @@ vvSlicer::vvSlicer() this->WindowLevel->Delete(); this->WindowLevel = vvImageMapToWLColors::New(); + this->InstallPipeline(); - } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -vtkImageMapToWindowLevelColors* vvSlicer::GetOverlayMapper() { +vtkImageMapToWindowLevelColors* vvSlicer::GetOverlayMapper() +{ return mOverlayMapper.GetPointer(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -vvBlendImageActor* vvSlicer::GetOverlayActor() { +vvBlendImageActor* vvSlicer::GetOverlayActor() +{ return mOverlayActor.GetPointer(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -vtkImageMapToWindowLevelColors* vvSlicer::GetFusionMapper() { +vtkImageMapToWindowLevelColors* vvSlicer::GetFusionMapper() +{ return mFusionMapper.GetPointer(); } //------------------------------------------------------------------------------ - + //------------------------------------------------------------------------------ -vtkImageActor* vvSlicer::GetFusionActor() { +vtkImageActor* vvSlicer::GetFusionActor() +{ return mFusionActor.GetPointer(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -vtkActor* vvSlicer::GetVFActor() { +vtkActor* vvSlicer::GetVFActor() +{ return mVFActor.GetPointer(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -vtkCornerAnnotation* vvSlicer::GetAnnotation() { +vtkCornerAnnotation* vvSlicer::GetAnnotation() +{ return ca.GetPointer(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -void vvSlicer::EnableReducedExtent(bool b) { +void vvSlicer::EnableReducedExtent(bool b) +{ mUseReducedExtent = b; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -void vvSlicer::SetReducedExtent(int * ext) { +void vvSlicer::SetReducedExtent(int * ext) +{ mReducedExtent = ext; } //------------------------------------------------------------------------------ @@ -225,7 +237,7 @@ void vvSlicer::AddContour(vvMesh::Pointer contour,bool propagate) void vvSlicer::ToggleContourSuperposition() { for (std::vector::iterator i=mSurfaceCutActors.begin(); - i!=mSurfaceCutActors.end();i++) + i!=mSurfaceCutActors.end(); i++) (*i)->ToggleSuperposition(); } //------------------------------------------------------------------------------ @@ -255,11 +267,27 @@ bool vvSlicer::GetCursorVisibility() //------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +void vvSlicer::SetCornerAnnotationVisibility(bool s) +{ + ca->SetVisibility(s); +} +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +bool vvSlicer::GetCornerAnnotationVisibility() +{ + return ca->GetVisibility(); +} +//------------------------------------------------------------------------------ + + //------------------------------------------------------------------------------ vvSlicer::~vvSlicer() { for (std::vector::iterator i=mSurfaceCutActors.begin(); - i!=mSurfaceCutActors.end();i++) + i!=mSurfaceCutActors.end(); i++) delete (*i); } //------------------------------------------------------------------------------ @@ -279,34 +307,40 @@ void vvSlicer::SetCurrentPosition(double x, double y, double z, int t) //------------------------------------------------------------------------------ void vvSlicer::SetImage(vvImage::Pointer image) { - if (image->GetVTKImages().size()) - { - mImage = image; - this->Superclass::SetInput(image->GetVTKImages()[0]); - - // Prevent crash when reload -> change slice if outside extent - int extent[6]; - this->GetInput()->GetWholeExtent(extent); - if (SliceOrientation == 0) { - if (Slice >= extent[1]) { - Slice = (extent[1]-extent[0])/2.0; - } - } - if (SliceOrientation == 1) { - if (Slice >= extent[3]) { - Slice = (extent[3]-extent[2])/2.0; - } - } - if (SliceOrientation == 2) { - if (Slice >= extent[5]) { - Slice = (extent[5]-extent[4])/2.0; - } - } + if (image->GetVTKImages().size()) { + mImage = image; + + if (!mImageReslice) { + mImageReslice = vtkSmartPointer::New(); + mImageReslice->SetInterpolationModeToLinear(); + mImageReslice->AutoCropOutputOn(); + mImageReslice->SetBackgroundColor(-1000,-1000,-1000,1); + } + mImageReslice->SetResliceTransform(mImage->GetTransform()); + mImageReslice->SetInput(0, mImage->GetFirstVTKImageData()); + mImageReslice->UpdateInformation(); + + this->Superclass::SetInput(mImageReslice->GetOutput()); + + int extent[6]; + this->GetInput()->GetWholeExtent(extent); - this->UpdateDisplayExtent(); - mCurrentTSlice = 0; - ca->SetText(0,mFileName.c_str()); + // Prevent crash when reload -> change slice if outside extent + if (Slice < extent[SliceOrientation*2] || Slice>=extent[SliceOrientation*2+1]) { + Slice = (extent[SliceOrientation*2+1]-extent[SliceOrientation*2])/2.0; } + + // Make sure that the required part image has been computed + extent[SliceOrientation*2] = Slice; + extent[SliceOrientation*2+1] = Slice; + mImageReslice->GetOutput()->SetUpdateExtent(extent); + mImageReslice->GetOutput()->Update(); + + this->UpdateDisplayExtent(); + + mCurrentTSlice = 0; + ca->SetText(0,mFileName.c_str()); + } } //------------------------------------------------------------------------------ @@ -314,37 +348,42 @@ void vvSlicer::SetImage(vvImage::Pointer image) //------------------------------------------------------------------------------ void vvSlicer::SetOverlay(vvImage::Pointer overlay) { - if (overlay->GetVTKImages().size()) - { - mOverlay = overlay; - - if (!mOverlayMapper) - mOverlayMapper = vtkImageMapToWindowLevelColors::New(); - mOverlayMapper->SetInput(overlay->GetVTKImages()[0]); - - if (!mOverlayActor) - { - mOverlayActor = vvBlendImageActor::New(); - mOverlayActor->SetInput(mOverlayMapper->GetOutput()); - mOverlayActor->SetPickable(0); - mOverlayActor->SetVisibility(false); - mOverlayActor->SetOpacity(0.5); - this->UpdateDisplayExtent(); - } - - //stupid but necessary : the Overlay need to be rendered before fusion - if (mFusionActor) - { - this->GetRenderer()->RemoveActor(mFusionActor); - this->GetRenderer()->AddActor(mOverlayActor); - this->GetRenderer()->AddActor(mFusionActor); - } - else - this->GetRenderer()->AddActor(mOverlayActor); - - //Synchronize slice - SetTSlice(mCurrentTSlice); + if (overlay->GetVTKImages().size()) { + mOverlay = overlay; + + if (!mOverlayReslice) { + mOverlayReslice = vtkSmartPointer::New(); + mOverlayReslice->SetInterpolationModeToLinear(); + mOverlayReslice->AutoCropOutputOn(); + mOverlayReslice->SetBackgroundColor(-1000,-1000,-1000,1); + } + mOverlayReslice->SetResliceTransform(mOverlay->GetTransform()); + mOverlayReslice->SetInput(0, mOverlay->GetFirstVTKImageData()); + + if (!mOverlayMapper) + mOverlayMapper = vtkSmartPointer::New(); + mOverlayMapper->SetInput(mOverlayReslice->GetOutput()); + + if (!mOverlayActor) { + mOverlayActor = vtkSmartPointer::New(); + mOverlayActor->SetInput(mOverlayMapper->GetOutput()); + mOverlayActor->SetPickable(0); + mOverlayActor->SetVisibility(false); + mOverlayActor->SetOpacity(0.5); } + + //stupid but necessary : the Overlay need to be rendered before fusion + if (mFusionActor) { + this->GetRenderer()->RemoveActor(mFusionActor); + this->GetRenderer()->AddActor(mOverlayActor); + this->GetRenderer()->AddActor(mFusionActor); + } else + this->GetRenderer()->AddActor(mOverlayActor); + + //Synchronize orientation and slice + this->SetSliceOrientation(this->SliceOrientation); + this->SetTSlice(mCurrentTSlice); + } } //------------------------------------------------------------------------------ @@ -352,28 +391,35 @@ void vvSlicer::SetOverlay(vvImage::Pointer overlay) //------------------------------------------------------------------------------ void vvSlicer::SetFusion(vvImage::Pointer fusion) { - if (fusion->GetVTKImages().size()) - { - mFusion = fusion; - - if (!mFusionMapper) - mFusionMapper = vtkImageMapToWindowLevelColors::New(); - mFusionMapper->SetInput(fusion->GetVTKImages()[0]); - - if (!mFusionActor) - { - mFusionActor = vtkImageActor::New(); - mFusionActor->SetInput(mFusionMapper->GetOutput()); - mFusionActor->SetPickable(0); - mFusionActor->SetVisibility(false); - mFusionActor->SetOpacity(0.7); - this->UpdateDisplayExtent(); - this->GetRenderer()->AddActor(mFusionActor); - } - - //Synchronize slice - SetTSlice(mCurrentTSlice); + if (fusion->GetVTKImages().size()) { + mFusion = fusion; + + if (!mFusionReslice) { + mFusionReslice = vtkSmartPointer::New(); + mFusionReslice->SetInterpolationModeToLinear(); + mFusionReslice->AutoCropOutputOn(); + mFusionReslice->SetBackgroundColor(-1000,-1000,-1000,1); + } + mFusionReslice->SetResliceTransform(mFusion->GetTransform()); + mFusionReslice->SetInput(0, mFusion->GetFirstVTKImageData()); + + if (!mFusionMapper) + mFusionMapper = vtkSmartPointer::New(); + mFusionMapper->SetInput(mFusionReslice->GetOutput()); + + if (!mFusionActor) { + mFusionActor = vtkSmartPointer::New(); + mFusionActor->SetInput(mFusionMapper->GetOutput()); + mFusionActor->SetPickable(0); + mFusionActor->SetVisibility(false); + mFusionActor->SetOpacity(0.7); + this->GetRenderer()->AddActor(mFusionActor); } + + //Synchronize orientation and slice + this->SetSliceOrientation(this->SliceOrientation); + this->SetTSlice(mCurrentTSlice); + } } //------------------------------------------------------------------------------ @@ -381,18 +427,15 @@ void vvSlicer::SetFusion(vvImage::Pointer fusion) //------------------------------------------------------------------------------ void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis) { - if (actor_type == "vector") - { - this->mVFActor->SetVisibility(vis); - } - if (actor_type == "overlay") - { - this->mOverlayActor->SetVisibility(vis); - } - if (actor_type == "fusion") - { - this->mFusionActor->SetVisibility(vis); - } + if (actor_type == "vector") { + this->mVFActor->SetVisibility(vis); + } + if (actor_type == "overlay") { + this->mOverlayActor->SetVisibility(vis); + } + if (actor_type == "fusion") { + this->mFusionActor->SetVisibility(vis); + } if (actor_type == "contour") this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis); UpdateDisplayExtent(); @@ -403,55 +446,62 @@ void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_ind //------------------------------------------------------------------------------ void vvSlicer::SetVF(vvImage::Pointer vf) { - if (vf->GetVTKImages().size()) - { - mVF = vf; - - if (!mAAFilter) - { - mAAFilter=vtkAssignAttribute::New(); - mVOIFilter = vtkExtractVOI::New(); - mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling); - } - mVOIFilter->SetInput(vf->GetVTKImages()[0]); - mAAFilter->SetInput(mVOIFilter->GetOutput()); - ///This tells VTK to use the scalar (pixel) data of the image to draw the little arrows - mAAFilter->Assign(vtkDataSetAttributes::SCALARS, vtkDataSetAttributes::VECTORS, vtkAssignAttribute::POINT_DATA); - - if (!mArrow) - mArrow = vvGlyphSource::New(); - mArrow->SetGlyphTypeToSpecificArrow(); - mArrow->SetScale(mScale); - mArrow->FilledOff(); - - // Glyph the gradient vector (with arrows) - if (!mGlyphFilter) - mGlyphFilter = vvGlyph2D::New(); - mGlyphFilter->SetInput(mAAFilter->GetOutput()); - mGlyphFilter->SetSource(mArrow->GetOutput()); - mGlyphFilter->ScalingOn(); - mGlyphFilter->SetScaleModeToScaleByVector(); - mGlyphFilter->OrientOn(); - mGlyphFilter->SetVectorModeToUseVector(); - mGlyphFilter->SetColorModeToColorByVector(); - - if (!mVFMapper) - mVFMapper = vtkPolyDataMapper::New(); - //mVFMapper->SetInputConnection(mGlyphFilter->GetOutputPort()); - mVFMapper->SetInput(mGlyphFilter->GetOutput()); - mVFMapper->ImmediateModeRenderingOn(); - - if (!mVFActor) - mVFActor = vtkActor::New(); - mVFActor->SetMapper(mVFMapper); - mVFActor->SetPickable(0); - mVFActor->GetProperty()->SetLineWidth(mVFWidth); - this->UpdateDisplayExtent(); - this->GetRenderer()->AddActor(mVFActor); - - //Synchronize slice - SetTSlice(mCurrentTSlice); + if (vf->GetVTKImages().size()) { + mVF = vf; + + if (!mAAFilter) { + mAAFilter= vtkSmartPointer::New(); + mVOIFilter = vtkSmartPointer::New(); + mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling); } + mVOIFilter->SetInput(vf->GetFirstVTKImageData()); + mAAFilter->SetInput(mVOIFilter->GetOutput()); + ///This tells VTK to use the scalar (pixel) data of the image to draw the little arrows + mAAFilter->Assign(vtkDataSetAttributes::SCALARS, vtkDataSetAttributes::VECTORS, vtkAssignAttribute::POINT_DATA); + + if (!mArrow) + mArrow = vtkSmartPointer::New(); + mArrow->SetGlyphTypeToSpecificArrow(); + mArrow->SetScale(mScale); + mArrow->FilledOff(); + + // Glyph the gradient vector (with arrows) + if (!mGlyphFilter) + mGlyphFilter = vtkSmartPointer::New(); + mGlyphFilter->SetInput(mAAFilter->GetOutput()); + mGlyphFilter->SetSource(mArrow->GetOutput()); + mGlyphFilter->ScalingOn(); + mGlyphFilter->SetScaleModeToScaleByVector(); + mGlyphFilter->OrientOn(); + mGlyphFilter->SetVectorModeToUseVector(); + mGlyphFilter->SetColorModeToColorByVector(); + + if (!mVFColorLUT) + mVFColorLUT = vtkSmartPointer::New(); + + double mVFColorHSV[3]; + vtkMath::RGBToHSV(mVFColor, mVFColorHSV); + mVFColorLUT->SetHueRange(mVFColorHSV[0], mVFColorHSV[0]); + mVFColorLUT->SetSaturationRange(mVFColorHSV[1],mVFColorHSV[1]); + mVFColorLUT->SetValueRange(mVFColorHSV[2], mVFColorHSV[2]); + + if (!mVFMapper) + mVFMapper = vtkSmartPointer::New(); + mVFMapper->SetInput(mGlyphFilter->GetOutput()); + mVFMapper->ImmediateModeRenderingOn(); + mVFMapper->SetLookupTable(mVFColorLUT); + + if (!mVFActor) + mVFActor = vtkSmartPointer::New(); + mVFActor->SetMapper(mVFMapper); + mVFActor->SetPickable(0); + mVFActor->GetProperty()->SetLineWidth(mVFWidth); + this->UpdateDisplayExtent(); + this->GetRenderer()->AddActor(mVFActor); + + //Synchronize slice + SetTSlice(mCurrentTSlice); + } } //------------------------------------------------------------------------------ @@ -460,48 +510,47 @@ void vvSlicer::SetVF(vvImage::Pointer vf) void vvSlicer::SetLandmarks(vvLandmarks* landmarks) { mLandmarks = landmarks; - if (landmarks) - { - - if (!mCross) - mCross = vtkCursor3D::New(); - mCross->SetFocalPoint(0.0,0.0,0.0); - mCross->SetModelBounds(-10,10,-10,10,-10,10); - mCross->AllOff(); - mCross->AxesOn(); - - if (!mLandGlyph) - mLandGlyph = vtkGlyph3D::New(); - mLandGlyph->SetSource(mCross->GetOutput()); - mLandGlyph->SetInput(landmarks->GetOutput()); - //mLandGlyph->SetIndexModeToScalar(); - mLandGlyph->SetRange(0,1); - mLandGlyph->ScalingOff(); - - mLandGlyph->SetColorModeToColorByScalar(); - - if (!mClipBox) - mClipBox = vtkBox::New(); - if (!mLandClipper) - mLandClipper = vtkClipPolyData::New(); - mLandClipper->InsideOutOn(); - mLandClipper->SetInput(mLandGlyph->GetOutput()); - mLandClipper->SetClipFunction(mClipBox); - - if (!mLandMapper) - mLandMapper = vtkPolyDataMapper::New(); - mLandMapper->SetInputConnection(mLandClipper->GetOutputPort()); - //mLandMapper->ScalarVisibilityOff(); - - if (!mLandActor) - mLandActor = vtkActor::New(); - mLandActor->SetMapper(mLandMapper); - mLandActor->GetProperty()->SetColor(255,10,212); - mLandActor->SetPickable(0); - mLandActor->SetVisibility(true); - this->UpdateDisplayExtent(); - this->GetRenderer()->AddActor(mLandActor); - } + if (landmarks) { + + if (!mCross) + mCross = vtkSmartPointer::New(); + mCross->SetFocalPoint(0.0,0.0,0.0); + mCross->SetModelBounds(-10,10,-10,10,-10,10); + mCross->AllOff(); + mCross->AxesOn(); + + if (!mLandGlyph) + mLandGlyph = vtkSmartPointer::New(); + mLandGlyph->SetSource(mCross->GetOutput()); + mLandGlyph->SetInput(landmarks->GetOutput()); + //mLandGlyph->SetIndexModeToScalar(); + mLandGlyph->SetRange(0,1); + mLandGlyph->ScalingOff(); + + mLandGlyph->SetColorModeToColorByScalar(); + + if (!mClipBox) + mClipBox = vtkSmartPointer::New(); + if (!mLandClipper) + mLandClipper = vtkSmartPointer::New(); + mLandClipper->InsideOutOn(); + mLandClipper->SetInput(mLandGlyph->GetOutput()); + mLandClipper->SetClipFunction(mClipBox); + + if (!mLandMapper) + mLandMapper = vtkSmartPointer::New(); + mLandMapper->SetInputConnection(mLandClipper->GetOutputPort()); + //mLandMapper->ScalarVisibilityOff(); + + if (!mLandActor) + mLandActor = vtkSmartPointer::New(); + mLandActor->SetMapper(mLandMapper); + mLandActor->GetProperty()->SetColor(255,10,212); + mLandActor->SetPickable(0); + mLandActor->SetVisibility(true); + this->UpdateDisplayExtent(); + this->GetRenderer()->AddActor(mLandActor); + } } //------------------------------------------------------------------------------ @@ -509,36 +558,32 @@ void vvSlicer::SetLandmarks(vvLandmarks* landmarks) //FIXME: this function leaks memory, we should fix it someday :) void vvSlicer::RemoveActor(const std::string& actor_type, int overlay_index) { - if (actor_type == "vector") - { - Renderer->RemoveActor(mVFActor); - mGlyphFilter=NULL; - mVF = NULL; - mArrow = NULL; - mAAFilter=NULL; - mVOIFilter = NULL; - mVFMapper = NULL; - mVFActor = NULL; - } - if (actor_type == "overlay") - { - Renderer->RemoveActor(mOverlayActor); - mOverlay = NULL; - mOverlayActor = NULL; - mOverlayMapper = NULL; - } - if (actor_type == "fusion") - { - Renderer->RemoveActor(mFusionActor); - mFusion = NULL; - mFusionActor = NULL; - mFusionMapper = NULL; - } - if (actor_type == "contour") - { - Renderer->RemoveActor(this->mSurfaceCutActors[overlay_index]->GetActor()); - mSurfaceCutActors.erase(mSurfaceCutActors.begin()+overlay_index); - } + if (actor_type == "vector") { + Renderer->RemoveActor(mVFActor); + mGlyphFilter=NULL; + mVF = NULL; + mArrow = NULL; + mAAFilter=NULL; + mVOIFilter = NULL; + mVFMapper = NULL; + mVFActor = NULL; + } + if (actor_type == "overlay") { + Renderer->RemoveActor(mOverlayActor); + mOverlay = NULL; + mOverlayActor = NULL; + mOverlayMapper = NULL; + } + if (actor_type == "fusion") { + Renderer->RemoveActor(mFusionActor); + mFusion = NULL; + mFusionActor = NULL; + mFusionMapper = NULL; + } + if (actor_type == "contour") { + Renderer->RemoveActor(this->mSurfaceCutActors[overlay_index]->GetActor()); + mSurfaceCutActors.erase(mSurfaceCutActors.begin()+overlay_index); + } } //------------------------------------------------------------------------------ @@ -546,11 +591,10 @@ void vvSlicer::RemoveActor(const std::string& actor_type, int overlay_index) //------------------------------------------------------------------------------ void vvSlicer::SetVFSubSampling(int sub) { - if (mVOIFilter) - { - mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling); - mSubSampling = sub; - } + if (mVOIFilter) { + mVOIFilter->SetSampleRate(mSubSampling,mSubSampling,mSubSampling); + mSubSampling = sub; + } UpdateDisplayExtent(); Render(); } @@ -584,11 +628,10 @@ void vvSlicer::SetVFWidth(int width) void vvSlicer::SetVFLog(int log) { mVFLog = log; - if (mGlyphFilter) - { - mGlyphFilter->SetUseLog(mVFLog); - mGlyphFilter->Modified(); - } + if (mGlyphFilter) { + mGlyphFilter->SetUseLog(mVFLog); + mGlyphFilter->Modified(); + } UpdateDisplayExtent(); Render(); } @@ -606,25 +649,22 @@ void vvSlicer::SetTSlice(int t) if (mCurrentTSlice == t) return; mCurrentTSlice = t; - this->SetInput(mImage->GetVTKImages()[t]); - if (mVF && mVFActor->GetVisibility()) - { - if (mVF->GetVTKImages().size() > (unsigned int)mCurrentTSlice) - mVOIFilter->SetInput(mVF->GetVTKImages()[mCurrentTSlice]); - } - if (mOverlay && mOverlayActor->GetVisibility()) - { - if (mOverlay->GetVTKImages().size() > (unsigned int)mCurrentTSlice) - mOverlayMapper->SetInput(mOverlay->GetVTKImages()[mCurrentTSlice]); - } - if (mFusion && mFusionActor->GetVisibility()) - { - if (mFusion->GetVTKImages().size() > (unsigned int)mCurrentTSlice) - mFusionMapper->SetInput(mFusion->GetVTKImages()[mCurrentTSlice]); - } + mImageReslice->SetInput( mImage->GetVTKImages()[mCurrentTSlice] ); + if (mVF && mVFActor->GetVisibility()) { + if (mVF->GetVTKImages().size() > (unsigned int)mCurrentTSlice) + mVOIFilter->SetInput(mVF->GetVTKImages()[mCurrentTSlice]); + } + if (mOverlay && mOverlayActor->GetVisibility()) { + if (mOverlay->GetVTKImages().size() > (unsigned int)mCurrentTSlice) + mOverlayReslice->SetInput( mOverlay->GetVTKImages()[mCurrentTSlice] ); + } + if (mFusion && mFusionActor->GetVisibility()) { + if (mFusion->GetVTKImages().size() > (unsigned int)mCurrentTSlice) + mFusionReslice->SetInput( mFusion->GetVTKImages()[mCurrentTSlice]); + } if (mSurfaceCutActors.size() > 0) for (std::vector::iterator i=mSurfaceCutActors.begin(); - i!=mSurfaceCutActors.end();i++) + i!=mSurfaceCutActors.end(); i++) (*i)->SetTimeSlice(mCurrentTSlice); UpdateDisplayExtent(); } @@ -638,7 +678,6 @@ int vvSlicer::GetTSlice() } //------------------------------------------------------------------------------ - //------------------------------------------------------------------------------ void vvSlicer::SetSliceOrientation(int orientation) { @@ -646,341 +685,222 @@ void vvSlicer::SetSliceOrientation(int orientation) int extent[6]; this->GetInput()->GetWholeExtent(extent); if (extent[5]-extent[4] <= 2) - orientation=2; + orientation = vtkImageViewer2::SLICE_ORIENTATION_XY; if (orientation < vtkImageViewer2::SLICE_ORIENTATION_YZ || - orientation > vtkImageViewer2::SLICE_ORIENTATION_XY) - { - vtkErrorMacro("Error - invalid slice orientation " << orientation); - return; - } - + orientation > vtkImageViewer2::SLICE_ORIENTATION_XY) { + vtkErrorMacro("Error - invalid slice orientation " << orientation); + return; + } + this->SliceOrientation = orientation; - + + if(mFusion) + AdjustResliceToSliceOrientation(mFusionReslice); + + if(mOverlay) + AdjustResliceToSliceOrientation(mOverlayReslice); + // Update the viewer int *range = this->GetSliceRange(); if (range) this->Slice = static_cast((range[0] + range[1]) * 0.5); + // Go to current cursor position + // double* cursorPos = GetCursorPosition(); + // DDV(cursorPos, 3); + // SetCurrentPosition(cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]); + this->UpdateOrientation(); this->UpdateDisplayExtent(); - if (this->Renderer && this->GetInput()) - { - double scale = this->Renderer->GetActiveCamera()->GetParallelScale(); - this->Renderer->ResetCamera(); - this->Renderer->GetActiveCamera()->SetParallelScale(scale); - } + if (this->Renderer && this->GetInput()) { + double scale = this->Renderer->GetActiveCamera()->GetParallelScale(); + this->Renderer->ResetCamera(); + this->Renderer->GetActiveCamera()->SetParallelScale(scale); + } SetContourSlice(); } //---------------------------------------------------------------------------- +//------------------------------------------------------------------------------ +// This function ensures that we sample the slices of a vtkImageReslice filter +// in the direction of the slicer (SliceOrientation) similarly as mImageReslice. +// In other words, we change the grid of the reslice in the same way as the grid +// of the displayed image in the slicing direction. +void vvSlicer::AdjustResliceToSliceOrientation(vtkImageReslice *reslice) +{ + // Reset autocrop + double origin[3] = {VTK_DOUBLE_MAX, VTK_DOUBLE_MAX, VTK_DOUBLE_MAX}; + double spacing[3] = {VTK_DOUBLE_MAX, VTK_DOUBLE_MAX, VTK_DOUBLE_MAX}; + reslice->SetOutputOrigin(origin); + reslice->SetOutputSpacing(spacing); + reslice->GetOutput()->UpdateInformation(); + reslice->GetOutput()->GetOrigin(origin); + reslice->GetOutput()->GetSpacing(spacing); + + // Use similar spacing as the image in the direction SliceOrientation + spacing[this->SliceOrientation] = mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation]; + + // Modify origin to be on the image grid in the direction SliceOrientation in 3 steps + // Step 1: from world coordinates to image coordinates + origin[this->SliceOrientation] -= mImageReslice->GetOutput()->GetOrigin()[this->SliceOrientation]; + origin[this->SliceOrientation] /= mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation]; + // Step 2: round to superior grid positionInc + origin[this->SliceOrientation] = itk::Math::Ceil(origin[this->SliceOrientation]); + // Step 3: back to world coordinates + origin[this->SliceOrientation] *= mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation]; + origin[this->SliceOrientation] += mImageReslice->GetOutput()->GetOrigin()[this->SliceOrientation]; + + // Set new spacing and origin + reslice->SetOutputOrigin(origin); + reslice->SetOutputSpacing(spacing); + reslice->UpdateInformation(); +} +//------------------------------------------------------------------------------ //---------------------------------------------------------------------------- -int * vvSlicer::GetExtent() { +int * vvSlicer::GetExtent() +{ int *w_ext; if (mUseReducedExtent) { w_ext = mReducedExtent; - } - else w_ext = GetInput()->GetWholeExtent(); + } else w_ext = GetInput()->GetWholeExtent(); return w_ext; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- -int vvSlicer::GetOrientation() { +int vvSlicer::GetOrientation() +{ return this->SliceOrientation; } //---------------------------------------------------------------------------- - //---------------------------------------------------------------------------- void vvSlicer::UpdateDisplayExtent() { vtkImageData *input = this->GetInput(); - if (!input || !this->ImageActor) - { - return; - } + if (!input || !this->ImageActor) { + return; + } input->UpdateInformation(); - int *w_ext;// = input->GetWholeExtent(); - if (mUseReducedExtent) { - w_ext = mReducedExtent; + // Local copy of extent + int w_ext[6]; + for(unsigned int i=0; i<6; i++){ + if (mUseReducedExtent) + w_ext[i] = mReducedExtent[i]; + else + w_ext[i] = input->GetWholeExtent()[i]; } - else w_ext = input->GetWholeExtent(); - - switch (this->SliceOrientation) - { - case vtkImageViewer2::SLICE_ORIENTATION_XY: - this->ImageActor->SetDisplayExtent( - w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice); - if (mVF && mVFActor->GetVisibility()) - { - int vfExtent[6]; - ComputeVFDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,vfExtent); - mVOIFilter->SetVOI(vfExtent); - mGlyphFilter->SetOrientation(1,1,0); - mVFMapper->Update(); - // put the vector field between the image and the camera - if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice) - mVFActor->SetPosition(0,0,ImageActor->GetBounds()[5]+2); - else - mVFActor->SetPosition(0,0,ImageActor->GetBounds()[4]-2); - } - if (mOverlay && mOverlayActor->GetVisibility()) - { - int overExtent[6]; - ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,overExtent); - mOverlayActor->SetDisplayExtent(overExtent); - if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice) - mOverlayActor->SetPosition(0,0,1); - else - mOverlayActor->SetPosition(0,0,-1); - } - if (mFusion && mFusionActor->GetVisibility()) - { - int fusExtent[6]; - ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], w_ext[2], w_ext[3], this->Slice, this->Slice,fusExtent); - mFusionActor->SetDisplayExtent(fusExtent); - if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice) - mFusionActor->SetPosition(0,0,1.5); - else - mFusionActor->SetPosition(0,0,-1.5); - } - if (mLandActor) - { - if (mClipBox) - { - double bounds [6]; - bounds[0] = ImageActor->GetBounds()[0]; - bounds[1] = ImageActor->GetBounds()[1]; - bounds[2] = ImageActor->GetBounds()[2]; - bounds[3] = ImageActor->GetBounds()[3]; - bounds[4] = ImageActor->GetBounds()[4]-(0.9/this->GetInput()->GetSpacing()[2]); - bounds[5] = ImageActor->GetBounds()[5]+(0.9/this->GetInput()->GetSpacing()[2]); - mClipBox->SetBounds(bounds); - UpdateLandmarks(); - } - if (Renderer->GetActiveCamera()->GetPosition()[2] > this->Slice) - mLandActor->SetPosition(0,0,1.5); - else - mLandActor->SetPosition(0,0,-1.5); - } - break; - - case vtkImageViewer2::SLICE_ORIENTATION_XZ: - this->ImageActor->SetDisplayExtent( - w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5]); - if (mVF && mVFActor->GetVisibility()) - { - int vfExtent[6]; - ComputeVFDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],vfExtent); - mVOIFilter->SetVOI(vfExtent); - mGlyphFilter->SetOrientation(1,0,1); - mVFMapper->Update(); - // put the vector field between the image aSpacingnd the camera - if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice) - mVFActor->SetPosition(0,ImageActor->GetBounds()[3]+2,0); - else - mVFActor->SetPosition(0,ImageActor->GetBounds()[2]-2,0); - } - if (mOverlay && mOverlayActor->GetVisibility()) - { - int overExtent[6]; - ComputeOverlayDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],overExtent); - mOverlayActor->SetDisplayExtent(overExtent); - if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice) - mOverlayActor->SetPosition(0,1,0); - else - mOverlayActor->SetPosition(0,-1,0); - } - if (mFusion && mFusionActor->GetVisibility()) - { - int fusExtent[6]; - ComputeFusionDisplayedExtent(w_ext[0], w_ext[1], this->Slice, this->Slice, w_ext[4], w_ext[5],fusExtent); - mFusionActor->SetDisplayExtent(fusExtent); - if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice) - mFusionActor->SetPosition(0,1.5,0); - else - mFusionActor->SetPosition(0,-1.5,0); - } - if (mLandActor) - { - if (mClipBox) - { - double bounds [6]; - bounds[0] = ImageActor->GetBounds()[0]; - bounds[1] = ImageActor->GetBounds()[1]; - bounds[2] = ImageActor->GetBounds()[2]-(0.5/this->GetInput()->GetSpacing()[1]); - bounds[3] = ImageActor->GetBounds()[3]+(0.5/this->GetInput()->GetSpacing()[1]); - bounds[4] = ImageActor->GetBounds()[4]; - bounds[5] = ImageActor->GetBounds()[5]; - mClipBox->SetBounds(bounds); - UpdateLandmarks(); - } - if (Renderer->GetActiveCamera()->GetPosition()[1] > this->Slice) - mLandActor->SetPosition(0,1.5,0); - else - mLandActor->SetPosition(0,-1.5,0); - } - break; - case vtkImageViewer2::SLICE_ORIENTATION_YZ: - this->ImageActor->SetDisplayExtent( - this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5]); - if (mVF && mVFActor->GetVisibility()) - { - int vfExtent[6]; - ComputeVFDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],vfExtent); - mVOIFilter->SetVOI(vfExtent); - mGlyphFilter->SetOrientation(0,1,1); - mVFMapper->Update(); - // put the vector field between the image and the camera - if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice) - mVFActor->SetPosition(ImageActor->GetBounds()[1]+2,0,0); - else - mVFActor->SetPosition(ImageActor->GetBounds()[0]-2,0,0); - } - if (mOverlay && mOverlayActor->GetVisibility()) - { - int overExtent[6]; - ComputeOverlayDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],overExtent); - mOverlayActor->SetDisplayExtent(overExtent); - if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice) - mOverlayActor->SetPosition(1,0,0); - else - mOverlayActor->SetPosition(-1,0,0); - } - if (mFusion && mFusionActor->GetVisibility()) - { - int fusExtent[6]; - ComputeFusionDisplayedExtent(this->Slice, this->Slice, w_ext[2], w_ext[3], w_ext[4], w_ext[5],fusExtent); - mFusionActor->SetDisplayExtent(fusExtent); - if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice) - mFusionActor->SetPosition(1.5,0,0); - else - mFusionActor->SetPosition(-1.5,0,0); - } - if (mLandActor) - { - if (mClipBox) - { - double bounds [6]; - bounds[0] = ImageActor->GetBounds()[0]-(0.5/this->GetInput()->GetSpacing()[0]); - bounds[1] = ImageActor->GetBounds()[1]+(0.5/this->GetInput()->GetSpacing()[0]); - bounds[2] = ImageActor->GetBounds()[2]; - bounds[3] = ImageActor->GetBounds()[3]; - bounds[4] = ImageActor->GetBounds()[4]; - bounds[5] = ImageActor->GetBounds()[5]; - mClipBox->SetBounds(bounds); - UpdateLandmarks(); - } - if (Renderer->GetActiveCamera()->GetPosition()[0] > this->Slice) - mLandActor->SetPosition(1.5,0,0); - else - mLandActor->SetPosition(-1.5,0,0); - } - break; + // Set slice value + w_ext[ this->SliceOrientation*2 ] = this->Slice; + w_ext[ this->SliceOrientation*2+1 ] = this->Slice; + + // Image actor + this->ImageActor->SetDisplayExtent(w_ext); + + // Position vector + double position[3] = {0.,0.,0.}; + double positionInc = (Renderer->GetActiveCamera()->GetPosition()[this->SliceOrientation] > this->Slice)?10:-10; + position[this->SliceOrientation] += positionInc; + + // Overlay image actor + if (mOverlay && mOverlayActor->GetVisibility()) { + int overExtent[6]; + mOverlayReslice->GetOutput()->UpdateInformation(); + this->ConvertImageToImageDisplayExtent(input, w_ext, mOverlayReslice->GetOutput(), overExtent); + ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent()); + mOverlayActor->SetDisplayExtent( overExtent ); + mOverlayActor->SetPosition(position); + } + position[this->SliceOrientation] += positionInc; + + // Fusion image actor + if (mFusion && mFusionActor->GetVisibility()) { + int fusExtent[6]; + mFusionReslice->GetOutput()->UpdateInformation(); + this->ConvertImageToImageDisplayExtent(input, w_ext, mFusionReslice->GetOutput(), fusExtent); + ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent()); + mFusionActor->SetDisplayExtent(fusExtent); + mFusionActor->SetPosition(position); + } + position[this->SliceOrientation] += positionInc; + + // Vector field actor + if (mVF && mVFActor->GetVisibility()) { + int vfExtent[6]; + mVF->GetVTKImages()[0]->UpdateInformation(); + this->ConvertImageToImageDisplayExtent(input, w_ext, mVF->GetVTKImages()[0], vfExtent); + ClipDisplayedExtent(vfExtent, mVOIFilter->GetInput()->GetWholeExtent()); + mVOIFilter->SetVOI(vfExtent); + int orientation[3] = {1,1,1}; + orientation[this->SliceOrientation] = 0; + mGlyphFilter->SetOrientation(orientation[0], orientation[1], orientation[2]); + mVFMapper->Update(); + mVFActor->SetPosition(position); + } + position[this->SliceOrientation] += positionInc; + + // Landmarks actor + if (mLandActor) { + if (mClipBox) { + double bounds [6]; + for(unsigned int i=0; i<6; i++) + bounds[i] = ImageActor->GetBounds()[i]; + bounds[ this->SliceOrientation*2 ] = ImageActor->GetBounds()[ this->SliceOrientation*2 ]-fabs(0.5/this->GetInput()->GetSpacing()[this->SliceOrientation]); + bounds[ this->SliceOrientation*2+1 ] = ImageActor->GetBounds()[ this->SliceOrientation*2+1 ]+fabs(0.5/this->GetInput()->GetSpacing()[this->SliceOrientation]); + mClipBox->SetBounds(bounds); + UpdateLandmarks(); } + mLandActor->SetPosition(position); + } // Figure out the correct clipping range - - if (this->Renderer) - { - if (this->InteractorStyle && - this->InteractorStyle->GetAutoAdjustCameraClippingRange()) - { - this->Renderer->ResetCameraClippingRange(); - } - else - { - vtkCamera *cam = this->Renderer->GetActiveCamera(); - if (cam) - { - double bounds[6]; - this->ImageActor->GetBounds(bounds); - double spos = (double)bounds[this->SliceOrientation * 2]; - double cpos = (double)cam->GetPosition()[this->SliceOrientation]; - double range = fabs(spos - cpos); - double *spacing = input->GetSpacing(); - double avg_spacing = - ((double)spacing[0] + (double)spacing[1] + (double)spacing[2]) / 3.0; - cam->SetClippingRange( - range - avg_spacing * 3.0, range + avg_spacing * 3.0); - } - } + if (this->Renderer) { + if (this->InteractorStyle && + this->InteractorStyle->GetAutoAdjustCameraClippingRange()) { + this->Renderer->ResetCameraClippingRange(); + } else { + vtkCamera *cam = this->Renderer->GetActiveCamera(); + if (cam) { + double bounds[6]; + this->ImageActor->GetBounds(bounds); + double spos = (double)bounds[this->SliceOrientation * 2]; + double cpos = (double)cam->GetPosition()[this->SliceOrientation]; + double range = fabs(spos - cpos); + double *spacing = input->GetSpacing(); + double avg_spacing = + ((double)spacing[0] + (double)spacing[1] + (double)spacing[2]) / 3.0; + cam->SetClippingRange(range - avg_spacing * 3.0, range + avg_spacing * 3.0); + } } + } } //---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -void vvSlicer::ComputeVFDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int vfExtent[6]) -{ - vtkImageData* image=this->GetInput(); - vfExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mVF->GetOrigin()[0]) / - mVF->GetSpacing()[0]; - vfExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mVF->GetOrigin()[0]) / - mVF->GetSpacing()[0]; - vfExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mVF->GetOrigin()[1]) / - mVF->GetSpacing()[1]; - vfExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mVF->GetOrigin()[1]) / - mVF->GetSpacing()[1]; - vfExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mVF->GetOrigin()[2]) / - mVF->GetSpacing()[2]; - vfExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mVF->GetOrigin()[2]) / - mVF->GetSpacing()[2]; - - ClipDisplayedExtent(vfExtent,mVOIFilter->GetInput()->GetWholeExtent()); -} -//---------------------------------------------------------------------------- - - //---------------------------------------------------------------------------- -void vvSlicer::ComputeOverlayDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int overExtent[6]) +void vvSlicer::ConvertImageToImageDisplayExtent(vtkImageData *sourceImage, const int sourceExtent[6], + vtkImageData *targetImage, int targetExtent[6]) { - vtkImageData* image=this->GetInput(); - overExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mOverlay->GetOrigin()[0]) / - mOverlay->GetSpacing()[0]; - overExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mOverlay->GetOrigin()[0]) / - mOverlay->GetSpacing()[0]; - overExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mOverlay->GetOrigin()[1]) / - mOverlay->GetSpacing()[1]; - overExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mOverlay->GetOrigin()[1]) / - mOverlay->GetSpacing()[1]; - overExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mOverlay->GetOrigin()[2]) / - mOverlay->GetSpacing()[2]; - overExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mOverlay->GetOrigin()[2]) / - mOverlay->GetSpacing()[2]; - ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent()); -} -//---------------------------------------------------------------------------- - + double dExtents[6]; + for(unsigned int i=0; i<6; i++) { + // From source voxel coordinates to world coordinates + dExtents[i] = sourceImage->GetOrigin()[i/2] + sourceImage->GetSpacing()[i/2] * sourceExtent[i]; -//---------------------------------------------------------------------------- -void vvSlicer::ComputeFusionDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int fusExtent[6]) -{ - vtkImageData* image=this->GetInput(); - fusExtent[0] = (( image->GetOrigin()[0] + x1*image->GetSpacing()[0] ) - mFusion->GetOrigin()[0]) / - mFusion->GetSpacing()[0]; - fusExtent[1] = (( image->GetOrigin()[0] + x2*image->GetSpacing()[0] ) - mFusion->GetOrigin()[0]) / - mFusion->GetSpacing()[0]; - fusExtent[2] = (( image->GetOrigin()[1] + y1*image->GetSpacing()[1] ) - mFusion->GetOrigin()[1]) / - mFusion->GetSpacing()[1]; - fusExtent[3] = (( image->GetOrigin()[1] + y2*image->GetSpacing()[1] ) - mFusion->GetOrigin()[1]) / - mFusion->GetSpacing()[1]; - fusExtent[4] = (( image->GetOrigin()[2] + z1*image->GetSpacing()[2] ) - mFusion->GetOrigin()[2]) / - mFusion->GetSpacing()[2]; - fusExtent[5] = (( image->GetOrigin()[2] + z2*image->GetSpacing()[2] ) - mFusion->GetOrigin()[2]) / - mFusion->GetSpacing()[2]; - ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent()); + // From world coordinates to floating point target voxel coordinates + dExtents[i] = (dExtents[i]- targetImage->GetOrigin()[i/2]) / targetImage->GetSpacing()[i/2]; + + // Round to nearest + targetExtent[i] = itk::Math::Round(dExtents[i]); + } } //---------------------------------------------------------------------------- - //---------------------------------------------------------------------------- void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6]) { @@ -988,33 +908,29 @@ void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6]) int maxBound = 6; //2D overlay on 3D image specific case - if (refExtent[4] == refExtent[5]) - { - maxBound = 4; - extent[4] = refExtent[4]; - extent[5] = refExtent[5]; - } + if (refExtent[4] == refExtent[5]) { + maxBound = 4; + extent[4] = refExtent[4]; + extent[5] = refExtent[5]; + } - for (int i = 0; i < maxBound; i = i+2) - { - //if we are totally outside the image - if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] ) - { - out = true; - break; - } - //crop to the limit of the image - extent[i] = (extent[i] > refExtent[i]) ? extent[i] : refExtent[i]; - extent[i] = (extent[i] < refExtent[i+1]) ? extent[i] : refExtent[i+1]; - extent[i+1] = (extent[i+1] > refExtent[i]) ? extent[i+1] : refExtent[i]; - extent[i+1] = (extent[i+1] < refExtent[i+1]) ? extent[i+1] : refExtent[i+1]; + for (int i = 0; i < maxBound; i = i+2) { + //if we are totally outside the image + if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] ) { + out = true; + break; } + //crop to the limit of the image + extent[i] = (extent[i] > refExtent[i]) ? extent[i] : refExtent[i]; + extent[i] = (extent[i] < refExtent[i+1]) ? extent[i] : refExtent[i+1]; + extent[i+1] = (extent[i+1] > refExtent[i]) ? extent[i+1] : refExtent[i]; + extent[i+1] = (extent[i+1] < refExtent[i+1]) ? extent[i+1] : refExtent[i+1]; + } if (out) - for (int i = 0; i < maxBound; i = i+2) - { - extent[i] = refExtent[i]; - extent[i+1] = refExtent[i]; - } + for (int i = 0; i < maxBound; i = i+2) { + extent[i] = refExtent[i]; + extent[i+1] = refExtent[i]; + } } //---------------------------------------------------------------------------- @@ -1024,29 +940,27 @@ void vvSlicer::UpdateOrientation() { // Set the camera position vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL; - if (cam) - { - switch (this->SliceOrientation) - { - case vtkImageViewer2::SLICE_ORIENTATION_XY: - cam->SetFocalPoint(0,0,0); - cam->SetPosition(0,0,-1); // -1 if medical ? - cam->SetViewUp(0,-1,0); - break; - - case vtkImageViewer2::SLICE_ORIENTATION_XZ: - cam->SetFocalPoint(0,0,0); - cam->SetPosition(0,-1,0); // 1 if medical ? - cam->SetViewUp(0,0,1); - break; - - case vtkImageViewer2::SLICE_ORIENTATION_YZ: - cam->SetFocalPoint(0,0,0); - cam->SetPosition(-1,0,0); // -1 if medical ? - cam->SetViewUp(0,0,1); - break; - } + if (cam) { + switch (this->SliceOrientation) { + case vtkImageViewer2::SLICE_ORIENTATION_XY: + cam->SetFocalPoint(0,0,0); + cam->SetPosition(0,0,-1); // -1 if medical ? + cam->SetViewUp(0,-1,0); + break; + + case vtkImageViewer2::SLICE_ORIENTATION_XZ: + cam->SetFocalPoint(0,0,0); + cam->SetPosition(0,-1,0); // 1 if medical ? + cam->SetViewUp(0,0,1); + break; + + case vtkImageViewer2::SLICE_ORIENTATION_YZ: + cam->SetFocalPoint(0,0,0); + cam->SetPosition(-1,0,0); // -1 if medical ? + cam->SetViewUp(0,0,1); + break; } + } } //---------------------------------------------------------------------------- @@ -1095,15 +1009,7 @@ void vvSlicer::SetRenderWindow(int orientation, vtkRenderWindow * rw) //---------------------------------------------------------------------------- void vvSlicer::ResetCamera() { - if (this->GetInput()) - { - double* input_bounds=this->GetInput()->GetBounds(); - double bmax=input_bounds[1]-input_bounds[0]; - if (bmax < input_bounds[3]-input_bounds[2]) bmax=input_bounds[3]-input_bounds[2]; - if (bmax < input_bounds[5]-input_bounds[4]) bmax=input_bounds[5]-input_bounds[4]; - this->GetRenderer()->ResetCamera(); - this->GetRenderer()->GetActiveCamera()->SetParallelScale(bmax/2); - } + this->GetRenderer()->ResetCamera(); } //---------------------------------------------------------------------------- @@ -1127,26 +1033,24 @@ void vvSlicer::SetDisplayMode(bool i) void vvSlicer::FlipHorizontalView() { vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL; - if (cam) - { - double *position = cam->GetPosition(); - switch (this->SliceOrientation) - { - case vtkImageViewer2::SLICE_ORIENTATION_XY: - cam->SetPosition(position[0],position[1],-position[2]); - break; - - case vtkImageViewer2::SLICE_ORIENTATION_XZ: - cam->SetPosition(position[0],-position[1],position[2]); - break; - - case vtkImageViewer2::SLICE_ORIENTATION_YZ: - cam->SetPosition(-position[0],position[1],position[2]); - break; - } - this->Renderer->ResetCameraClippingRange(); - this->UpdateDisplayExtent(); + if (cam) { + double *position = cam->GetPosition(); + switch (this->SliceOrientation) { + case vtkImageViewer2::SLICE_ORIENTATION_XY: + cam->SetPosition(position[0],position[1],-position[2]); + break; + + case vtkImageViewer2::SLICE_ORIENTATION_XZ: + cam->SetPosition(position[0],-position[1],position[2]); + break; + + case vtkImageViewer2::SLICE_ORIENTATION_YZ: + cam->SetPosition(-position[0],position[1],position[2]); + break; } + this->Renderer->ResetCameraClippingRange(); + this->UpdateDisplayExtent(); + } } //---------------------------------------------------------------------------- @@ -1155,13 +1059,12 @@ void vvSlicer::FlipHorizontalView() void vvSlicer::FlipVerticalView() { vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL; - if (cam) - { - FlipHorizontalView(); - double *viewup = cam->GetViewUp(); - cam->SetViewUp(-viewup[0],-viewup[1],-viewup[2]); - this->UpdateDisplayExtent(); - } + if (cam) { + FlipHorizontalView(); + double *viewup = cam->GetViewUp(); + cam->SetViewUp(-viewup[0],-viewup[1],-viewup[2]); + this->UpdateDisplayExtent(); + } } //---------------------------------------------------------------------------- @@ -1170,12 +1073,11 @@ void vvSlicer::FlipVerticalView() void vvSlicer::SetColorWindow(double window) { vtkLookupTable* LUT = static_cast(this->GetWindowLevel()->GetLookupTable()); - if ( LUT ) - { - double level = this->GetWindowLevel()->GetLevel(); - LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4); - LUT->Build(); - } + if ( LUT ) { + double level = this->GetWindowLevel()->GetLevel(); + LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4); + LUT->Build(); + } this->vtkImageViewer2::SetColorWindow(window); } //---------------------------------------------------------------------------- @@ -1185,12 +1087,11 @@ void vvSlicer::SetColorWindow(double window) void vvSlicer::SetColorLevel(double level) { vtkLookupTable* LUT = static_cast(this->GetWindowLevel()->GetLookupTable()); - if ( LUT ) - { - double window = this->GetWindowLevel()->GetWindow(); - LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4); - LUT->Build(); - } + if ( LUT ) { + double window = this->GetWindowLevel()->GetWindow(); + LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4); + LUT->Build(); + } this->vtkImageViewer2::SetColorLevel(level); } //---------------------------------------------------------------------------- @@ -1201,150 +1102,168 @@ void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max) { //Get mouse pointer position in view coordinates double fLocalExtents[6]; - for(int i=0; i<3; i++) - { - fLocalExtents[i*2 ] = mCurrent[i]; - fLocalExtents[i*2+1] = mCurrent[i]; - } + for(int i=0; i<3; i++) { + fLocalExtents[i*2 ] = mCurrent[i]; + fLocalExtents[i*2+1] = mCurrent[i]; + } this->Renderer->WorldToView(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]); this->Renderer->WorldToView(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]); - for(int i=0; i<3; i++) - { - if (i!=SliceOrientation) //SR: assumes that SliceOrientation is valid in ViewCoordinates (???) - { - fLocalExtents[i*2 ] -= 0.2; - fLocalExtents[i*2+1] += 0.2; - } + for(int i=0; i<3; i++) { + if (i!=SliceOrientation) { //SR: assumes that SliceOrientation is valid in ViewCoordinates (???) + fLocalExtents[i*2 ] -= 0.2; + fLocalExtents[i*2+1] += 0.2; } + } this->Renderer->ViewToWorld(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]); this->Renderer->ViewToWorld(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]); //Convert to image pixel coordinates (rounded) int iLocalExtents[6]; - for(int i=0; i<3; i++) - { - fLocalExtents[i*2 ] = (fLocalExtents[i*2 ] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i]; - fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i]; - - iLocalExtents[i*2 ] = lrint(fLocalExtents[i*2 ]); - iLocalExtents[i*2+1] = lrint(fLocalExtents[i*2+1]); + for(int i=0; i<3; i++) { + fLocalExtents[i*2 ] = (fLocalExtents[i*2 ] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i]; + fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i]; - if(iLocalExtents[i*2 ]>iLocalExtents[i*2+1]) - std::swap(iLocalExtents[i*2], iLocalExtents[i*2+1]); - } + iLocalExtents[i*2 ] = lrint(fLocalExtents[i*2 ]); + iLocalExtents[i*2+1] = lrint(fLocalExtents[i*2+1]); - vtkSmartPointer voiFilter = vtkExtractVOI::New(); + if(iLocalExtents[i*2 ]>iLocalExtents[i*2+1]) + std::swap(iLocalExtents[i*2], iLocalExtents[i*2+1]); + } + + vtkSmartPointer voiFilter = vtkSmartPointer::New(); voiFilter->SetInput(this->GetInput()); voiFilter->SetVOI(iLocalExtents); voiFilter->Update(); - if (!voiFilter->GetOutput()->GetNumberOfPoints()) - { - min = 0; - max = 0; - return; - } + if (!voiFilter->GetOutput()->GetNumberOfPoints()) { + min = 0; + max = 0; + return; + } - vtkSmartPointer accFilter = vtkImageAccumulate::New(); + vtkSmartPointer accFilter = vtkSmartPointer::New(); accFilter->SetInput(voiFilter->GetOutput()); accFilter->Update(); - + min = *(accFilter->GetMin()); max = *(accFilter->GetMax()); } //---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +double vvSlicer::GetScalarComponentAsDouble(vtkImageData *image, int X, double Y, double Z, int &ix, int &iy, int &iz, int component) +{ + ix = lrint(X); + iy = lrint(Y); + iz = lrint(Z); + if (ix < image->GetWholeExtent()[0] || + ix > image->GetWholeExtent()[1] || + iy < image->GetWholeExtent()[2] || + iy > image->GetWholeExtent()[3] || + iz < image->GetWholeExtent()[4] || + iz > image->GetWholeExtent()[5] ) + return sqrt(-1.); + + image->SetUpdateExtent(ix, ix, iy, iy, iz, iz); + image->Update(); + return image->GetScalarComponentAsDouble(ix, iy, iz, component); +} +//---------------------------------------------------------------------------- + //---------------------------------------------------------------------------- void vvSlicer::Render() { - // DD("vvSlicer::Render"); - // DD(SliceOrientation); - if (this->GetWindowLevel()->GetLookupTable() && !this->mOverlay && !this->mFusion) - { - legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable()); - legend->SetVisibility(1); - } - else legend->SetVisibility(0); - - if (ca->GetVisibility()) - { - std::string worldPos = ""; - std::stringstream world1; - std::stringstream world2; - std::stringstream world3; - world1 << (int)mCurrent[0]; - world2 << (int)mCurrent[1]; - world3 << (int)mCurrent[2]; - double X = (mCurrent[0] - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0]; - double Y = (mCurrent[1] - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1]; - double Z = (mCurrent[2] - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2]; - - if (pdmA->GetVisibility()) - { - double x = mCursor[0]; - double y = mCursor[1]; - double z = mCursor[2]; - double xCursor = (x - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0]; - double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1]; - double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2]; - - if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0] && - xCursor < this->GetImageActor()->GetDisplayExtent()[1]+1 && - yCursor >= this->GetImageActor()->GetDisplayExtent()[2] && - yCursor < this->GetImageActor()->GetDisplayExtent()[3]+1 && - zCursor >= this->GetImageActor()->GetDisplayExtent()[4] && - zCursor < this->GetImageActor()->GetDisplayExtent()[5]+1 ) - { - vtkRenderer * renderer = this->Renderer; - - renderer->WorldToView(x,y,z); - renderer->ViewToNormalizedViewport(x,y,z); - renderer->NormalizedViewportToViewport(x,y); - renderer->ViewportToNormalizedDisplay(x,y); - renderer->NormalizedDisplayToDisplay(x,y); - crossCursor->SetFocalPoint(x,y,z); - } - else - crossCursor->SetFocalPoint(-1,-1,z); - } - - if (X >= this->GetInput()->GetWholeExtent()[0] && - X <= this->GetInput()->GetWholeExtent()[1] && - Y >= this->GetInput()->GetWholeExtent()[2] && - Y <= this->GetInput()->GetWholeExtent()[3] && - Z >= this->GetInput()->GetWholeExtent()[4] && - Z <= this->GetInput()->GetWholeExtent()[5]) - { - std::stringstream pixel1; - std::stringstream pixel2; - std::stringstream pixel3; - std::stringstream temps; - pixel1 << (int)X; - pixel2 << (int)Y; - pixel3 << (int)Z; - temps << mCurrentTSlice; - double value = this->GetInput()->GetScalarComponentAsDouble(lrint(X), - lrint(Y), - lrint(Z),0); - - std::stringstream val; - val << value; - worldPos += "data value : " + val.str(); - worldPos += "\n mm : " + world1.str() + " " + world2.str() + " " + - world3.str() + " " + temps.str(); - worldPos += "\n pixel : " + pixel1.str() + " " + pixel2.str() + " " + - pixel3.str() + " " + temps.str(); - } - ca->SetText(1,worldPos.c_str()); - } - if (mOverlay && mOverlayActor->GetVisibility()) - { - mOverlayMapper->SetWindow(this->GetColorWindow()); - mOverlayMapper->SetLevel(this->GetColorLevel()); - mOverlayMapper->Update(); + if (this->GetWindowLevel()->GetLookupTable() && !this->mOverlay && !this->mFusion) { + legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable()); + legend->SetVisibility(1); + } else legend->SetVisibility(0); + + if (ca->GetVisibility()) { + std::string worldPos = ""; + std::stringstream world1; + std::stringstream world2; + std::stringstream world3; + world1 << (int)mCurrent[0]; + world2 << (int)mCurrent[1]; + world3 << (int)mCurrent[2]; + double X = (mCurrent[0] - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0]; + double Y = (mCurrent[1] - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1]; + double Z = (mCurrent[2] - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2]; + +// if (X < this->GetInput()->GetWholeExtent()[0]) X = this->GetInput()->GetWholeExtent()[0]; +// else if (X > this->GetInput()->GetWholeExtent()[1]) X = this->GetInput()->GetWholeExtent()[1]; +// if (Y < this->GetInput()->GetWholeExtent()[2]) Y = this->GetInput()->GetWholeExtent()[2]; +// else if (Y > this->GetInput()->GetWholeExtent()[3]) Y = this->GetInput()->GetWholeExtent()[3]; +// if (Z < this->GetInput()->GetWholeExtent()[4]) Z = this->GetInput()->GetWholeExtent()[4]; +// else if (Z > this->GetInput()->GetWholeExtent()[5]) Z = this->GetInput()->GetWholeExtent()[5]; + + if (X >= this->GetInput()->GetWholeExtent()[0] && + X <= this->GetInput()->GetWholeExtent()[1] && + Y >= this->GetInput()->GetWholeExtent()[2] && + Y <= this->GetInput()->GetWholeExtent()[3] && + Z >= this->GetInput()->GetWholeExtent()[4] && + Z <= this->GetInput()->GetWholeExtent()[5]) { + + + int ix, iy, iz; + double value = this->GetScalarComponentAsDouble(this->GetInput(), X, Y, Z, ix, iy, iz); + + std::stringstream pixel1; + std::stringstream pixel2; + std::stringstream pixel3; + std::stringstream temps; + pixel1 << ix; + pixel2 << iy; + pixel3 << iz; + temps << mCurrentTSlice; + + std::stringstream val; + val << value; + worldPos += "data value : " + val.str(); + worldPos += "\n mm : " + world1.str() + " " + world2.str() + " " + + world3.str() + " " + temps.str(); + worldPos += "\n pixel : " + pixel1.str() + " " + pixel2.str() + " " + + pixel3.str() + " " + temps.str(); } + ca->SetText(1,worldPos.c_str()); + } + + if (pdmA->GetVisibility()) { + double x = mCursor[0]; + double y = mCursor[1]; + double z = mCursor[2]; + double xCursor = (x - this->GetInput()->GetOrigin()[0])/this->GetInput()->GetSpacing()[0]; + double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1]; + double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2]; + + if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0] && + xCursor < this->GetImageActor()->GetDisplayExtent()[1]+1 && + yCursor >= this->GetImageActor()->GetDisplayExtent()[2] && + yCursor < this->GetImageActor()->GetDisplayExtent()[3]+1 && + zCursor >= this->GetImageActor()->GetDisplayExtent()[4] && + zCursor < this->GetImageActor()->GetDisplayExtent()[5]+1 ) { + vtkRenderer * renderer = this->Renderer; + + renderer->WorldToView(x,y,z); + renderer->ViewToNormalizedViewport(x,y,z); + renderer->NormalizedViewportToViewport(x,y); + renderer->ViewportToNormalizedDisplay(x,y); + renderer->NormalizedDisplayToDisplay(x,y); + crossCursor->SetFocalPoint(x,y,z); + } else + crossCursor->SetFocalPoint(-1,-1,z); + } + + + if (mOverlay && mOverlayActor->GetVisibility()) { + mOverlayMapper->SetWindow(this->GetColorWindow()); + mOverlayMapper->SetLevel(this->GetColorLevel()); + mOverlayMapper->GetOutput()->SetUpdateExtent(mOverlayActor->GetDisplayExtent()); + mOverlayMapper->GetOutput()->Update(); + mOverlayMapper->Update(); + } if (mLandMapper) UpdateLandmarks(); - //this->Superclass::Render(); + this->GetRenderWindow()->Render(); } //---------------------------------------------------------------------------- @@ -1353,14 +1272,13 @@ void vvSlicer::Render() //---------------------------------------------------------------------------- void vvSlicer::UpdateCursorPosition() { - if (this->GetImageActor()->GetVisibility()) - { - pdmA->SetVisibility(true); - mCursor[0] = mCurrent[0]; - mCursor[1] = mCurrent[1]; - mCursor[2] = mCurrent[2]; - mCursor[3] = mCurrentTSlice; - } + if (this->GetImageActor()->GetVisibility()) { + pdmA->SetVisibility(true); + mCursor[0] = mCurrent[0]; + mCursor[1] = mCurrent[1]; + mCursor[2] = mCurrent[2]; + mCursor[3] = mCurrentTSlice; + } } //---------------------------------------------------------------------------- @@ -1369,16 +1287,15 @@ void vvSlicer::UpdateCursorPosition() void vvSlicer::UpdateLandmarks() { vtkPolyData *pd = static_cast(mLandClipper->GetInput()); - if (pd->GetPoints()) - { - mLandGlyph->SetRange(0,1); - mLandGlyph->Modified(); - mLandGlyph->Update(); - - mClipBox->Modified(); - mLandClipper->Update(); - mLandMapper->Update(); - } + if (pd->GetPoints()) { + mLandGlyph->SetRange(0,1); + mLandGlyph->Modified(); + mLandGlyph->Update(); + + mClipBox->Modified(); + mLandClipper->Update(); + mLandMapper->Update(); + } } //---------------------------------------------------------------------------- @@ -1388,32 +1305,25 @@ void vvSlicer::UpdateLandmarks() void vvSlicer::SetSlice(int slice) { int *range = this->GetSliceRange(); - if (range) - { - if (slice < range[0]) - { - slice = range[0]; - } - else if (slice > range[1]) - { - slice = range[1]; - } + if (range) { + if (slice < range[0]) { + slice = range[0]; + } else if (slice > range[1]) { + slice = range[1]; } + } - if (this->Slice == slice) - { - return; - } + if (this->Slice == slice) { + return; + } this->Slice = slice; SetContourSlice(); this->Modified(); this->UpdateDisplayExtent(); - // DD("SetSlice de slicer = Render"); - // Seems to work without this line - // this->Render(); + //this->Render(); } //---------------------------------------------------------------------------- @@ -1423,7 +1333,7 @@ void vvSlicer::SetContourSlice() { if (mSurfaceCutActors.size() > 0) for (std::vector::iterator i=mSurfaceCutActors.begin(); - i!=mSurfaceCutActors.end();i++) + i!=mSurfaceCutActors.end(); i++) (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+ this->GetImage()->GetOrigin()[this->SliceOrientation]); } @@ -1453,9 +1363,19 @@ void vvSlicer::PrintSelf(ostream& os, vtkIndent indent) } //---------------------------------------------------------------------------- - - - - - +//---------------------------------------------------------------------------- +void vvSlicer::SetVFColor(double r, double g, double b) +{ + double mVFColorHSV[3]; + mVFColor[0] = r; + mVFColor[1] = g; + mVFColor[2] = b; + + vtkMath::RGBToHSV(mVFColor, mVFColorHSV); + mVFColorLUT->SetHueRange(mVFColorHSV[0], mVFColorHSV[0]); + mVFColorLUT->SetSaturationRange(mVFColorHSV[1],mVFColorHSV[1]); + mVFColorLUT->SetValueRange(mVFColorHSV[2], mVFColorHSV[2]); + + this->Render(); +}