/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
- Program: vv
- Language: C++
- Author : Pierre Seroul (pierre.seroul@gmail.com)
+ 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
- Copyright (C) 2008
- Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
- CREATIS-LRMN http://www.creatis.insa-lyon.fr
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, version 3 of the License.
+ It is distributed under dual licence
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+ ======================================================================-====*/
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- =========================================================================*/
#include "vvSlicer.h"
-
#include "vvImage.h"
#include "vvSlicerManagerCommand.h"
#include "vvGlyphSource.h"
#include <vtkExtractVOI.h>
#include <vtkSphereSource.h>
#include <vtkCutter.h>
-#include <vtkPlane.h>
#include <vtkAssignAttribute.h>
+#include <vtkImageAccumulate.h>
+#include <vtkImageReslice.h>
vtkCxxRevisionMacro(vvSlicer, "DummyRevision");
vtkStandardNewMacro(vvSlicer);
+//------------------------------------------------------------------------------
vvSlicer::vvSlicer()
{
mImage = NULL;
mSubSampling = 5;
mScale = 1;
mVFLog = 0;
+ mVFWidth = 1;
std::string text = "F1 = sagital; F2 = coronal; F3 = axial\n";
text += "F5 = horizontal flip; F6 = vertical flip\n\n";
text += "0,1,2,3,4,5 : preset windowing\n";
text += "6,7,8,9 : preset colormap\n";
+ text += "z : local windowing\n";
text += "r : reset view\n";
text += "l : reload image\n";
text += "f : fly to mouse position\n";
this->WindowLevel->Delete();
this->WindowLevel = vvImageMapToWLColors::New();
this->InstallPipeline();
+
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
vtkImageMapToWindowLevelColors* vvSlicer::GetOverlayMapper() {
return mOverlayMapper.GetPointer();
}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
vtkImageActor* vvSlicer::GetOverlayActor() {
return mOverlayActor.GetPointer();
}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
vtkImageMapToWindowLevelColors* vvSlicer::GetFusionMapper() {
return mFusionMapper.GetPointer();
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
vtkImageActor* vvSlicer::GetFusionActor() {
return mFusionActor.GetPointer();
}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
vtkActor* vvSlicer::GetVFActor() {
return mVFActor.GetPointer();
}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
vtkCornerAnnotation* vvSlicer::GetAnnotation() {
return ca.GetPointer();
}
+//------------------------------------------------------------------------------
+
//------------------------------------------------------------------------------
void vvSlicer::EnableReducedExtent(bool b) {
SetContourSlice();
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
void vvSlicer::ToggleContourSuperposition()
{
for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
i!=mSurfaceCutActors.end();i++)
(*i)->ToggleSuperposition();
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
void vvSlicer::SetCursorColor(int r,int g, int b)
{
pdmA->GetProperty()->SetColor(r,g,b);
}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
void vvSlicer::SetCursorVisibility(bool s)
{
pdmA->SetVisibility(s);
}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
bool vvSlicer::GetCursorVisibility()
{
return pdmA->GetVisibility();
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
vvSlicer::~vvSlicer()
{
for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
i!=mSurfaceCutActors.end();i++)
delete (*i);
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
void vvSlicer::SetCurrentPosition(double x, double y, double z, int t)
{
mCurrent[0] = x;
mCurrent[2] = z;
mCurrentTSlice = 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;
+ }
+ }
+
this->UpdateDisplayExtent();
mCurrentTSlice = 0;
ca->SetText(0,mFileName.c_str());
}
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
void vvSlicer::SetOverlay(vvImage::Pointer overlay)
{
if (overlay->GetVTKImages().size())
SetTSlice(mCurrentTSlice);
}
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
void vvSlicer::SetFusion(vvImage::Pointer fusion)
{
if (fusion->GetVTKImages().size())
SetTSlice(mCurrentTSlice);
}
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis)
{
if (actor_type == "vector")
this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis);
UpdateDisplayExtent();
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
void vvSlicer::SetVF(vvImage::Pointer vf)
{
if (vf->GetVTKImages().size())
mVFActor = vtkActor::New();
mVFActor->SetMapper(mVFMapper);
mVFActor->SetPickable(0);
+ mVFActor->GetProperty()->SetLineWidth(mVFWidth);
this->UpdateDisplayExtent();
this->GetRenderer()->AddActor(mVFActor);
SetTSlice(mCurrentTSlice);
}
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
void vvSlicer::SetLandmarks(vvLandmarks* landmarks)
{
mLandmarks = landmarks;
this->GetRenderer()->AddActor(mLandActor);
}
}
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
//FIXME: this function leaks memory, we should fix it someday :)
void vvSlicer::RemoveActor(const std::string& actor_type, int overlay_index)
{
mSurfaceCutActors.erase(mSurfaceCutActors.begin()+overlay_index);
}
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
void vvSlicer::SetVFSubSampling(int sub)
{
if (mVOIFilter)
UpdateDisplayExtent();
Render();
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
void vvSlicer::SetVFScale(int scale)
{
mScale = scale;
UpdateDisplayExtent();
Render();
}
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+void vvSlicer::SetVFWidth(int width)
+{
+ mVFWidth = width;
+ if (mVFActor)
+ mVFActor->GetProperty()->SetLineWidth(mVFWidth);
+ UpdateDisplayExtent();
+ Render();
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
void vvSlicer::SetVFLog(int log)
{
mVFLog = log;
UpdateDisplayExtent();
Render();
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
void vvSlicer::SetTSlice(int t)
{
if (t < 0)
t = 0;
else if ((unsigned int)t >= mImage->GetVTKImages().size())
t = mImage->GetVTKImages().size() -1;
+
+ if (mCurrentTSlice == t) return;
+
mCurrentTSlice = t;
this->SetInput(mImage->GetVTKImages()[t]);
if (mVF && mVFActor->GetVisibility())
(*i)->SetTimeSlice(mCurrentTSlice);
UpdateDisplayExtent();
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
int vvSlicer::GetTSlice()
{
return mCurrentTSlice;
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
void vvSlicer::SetSliceOrientation(int orientation)
{
//if 2D image, force to watch in Axial View
SetContourSlice();
}
+//----------------------------------------------------------------------------
+
+
+//----------------------------------------------------------------------------
+int * vvSlicer::GetExtent() {
+ int *w_ext;
+ if (mUseReducedExtent) {
+ w_ext = mReducedExtent;
+ }
+ else w_ext = GetInput()->GetWholeExtent();
+ return w_ext;
+}
+//----------------------------------------------------------------------------
+
+
+//----------------------------------------------------------------------------
+int vvSlicer::GetOrientation() {
+ return this->SliceOrientation;
+}
+//----------------------------------------------------------------------------
+
//----------------------------------------------------------------------------
void vvSlicer::UpdateDisplayExtent()
}
else w_ext = input->GetWholeExtent();
- DD(w_ext[0]);
- DD(w_ext[1]);
- DD(w_ext[2]);
-
switch (this->SliceOrientation)
{
case vtkImageViewer2::SLICE_ORIENTATION_XY:
}
}
}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
void vvSlicer::ComputeVFDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int vfExtent[6])
{
vtkImageData* image=this->GetInput();
ClipDisplayedExtent(vfExtent,mVOIFilter->GetInput()->GetWholeExtent());
}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
void vvSlicer::ComputeOverlayDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int overExtent[6])
{
vtkImageData* image=this->GetInput();
mOverlay->GetSpacing()[2];
ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
void vvSlicer::ComputeFusionDisplayedExtent(int x1,int x2,int y1,int y2,int z1,int z2,int fusExtent[6])
{
vtkImageData* image=this->GetInput();
mFusion->GetSpacing()[2];
ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
{
bool out = false;
extent[i+1] = refExtent[i];
}
}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
void vvSlicer::UpdateOrientation()
{
// Set the camera position
}
}
}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
void vvSlicer::SetOpacity(double s)
{
this->GetImageActor()->SetOpacity(s);
}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
void vvSlicer::SetRenderWindow(int orientation, vtkRenderWindow * rw)
{
this->Superclass::SetRenderWindow(rw);
SetSliceOrientation(2-(orientation%3));
ResetCamera();
}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
void vvSlicer::ResetCamera()
{
if (this->GetInput())
this->GetRenderer()->GetActiveCamera()->SetParallelScale(bmax/2);
}
}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
void vvSlicer::SetDisplayMode(bool i)
{
this->GetImageActor()->SetVisibility(i);
}
//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+// Returns the min an the max value in a 41x41 region around the mouse pointer
+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];
+ }
+ 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;
+ }
+ }
+ 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]);
+
+ if(iLocalExtents[i*2 ]>iLocalExtents[i*2+1])
+ std::swap(iLocalExtents[i*2], iLocalExtents[i*2+1]);
+ }
+
+ vtkSmartPointer<vtkExtractVOI> voiFilter = vtkExtractVOI::New();
+ voiFilter->SetInput(this->GetInput());
+ voiFilter->SetVOI(iLocalExtents);
+ voiFilter->Update();
+ if (!voiFilter->GetOutput()->GetNumberOfPoints())
+ {
+ min = 0;
+ max = 0;
+ return;
+ }
+
+ vtkSmartPointer<vtkImageAccumulate> accFilter = vtkImageAccumulate::New();
+ accFilter->SetInput(voiFilter->GetOutput());
+ accFilter->Update();
+
+ min = *(accFilter->GetMin());
+ max = *(accFilter->GetMax());
+}
+//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void vvSlicer::Render()
{
+ // DD("vvSlicer::Render");
+ // DD(SliceOrientation);
if (this->GetWindowLevel()->GetLookupTable() && !this->mOverlay && !this->mFusion)
{
legend->SetLookupTable(this->GetWindowLevel()->GetLookupTable());
pixel2 << (int)Y;
pixel3 << (int)Z;
temps << mCurrentTSlice;
- double value = this->GetInput()->GetScalarComponentAsDouble(
- (int)X,
- (int)Y,
- (int)Z,0);
+ 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();
+ 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());
}
}
//----------------------------------------------------------------------------
+
//----------------------------------------------------------------------------
void vvSlicer::UpdateLandmarks()
{
//----------------------------------------------------------------------------
void vvSlicer::SetSlice(int slice)
{
- DD("vvSlicer::SetSlice");
- DD(slice);
int *range = this->GetSliceRange();
- DD(range[0]);
- DD(range[1]);
if (range)
{
if (slice < range[0])
SetContourSlice();
this->Modified();
this->UpdateDisplayExtent();
- this->Render();
+
+ // DD("SetSlice de slicer = Render");
+
+ // Seems to work without this line
+ // this->Render();
}
//----------------------------------------------------------------------------
this->Superclass::PrintSelf(os, indent);
}
//----------------------------------------------------------------------------
+
+
+
+
+
+
+