/*=========================================================================
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
+ - Léon Bérard cancer center http://www.centreleonberard.fr
- CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
This software is distributed WITHOUT ANY WARRANTY; without even
- BSD See included LICENSE.txt file
- CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
- ======================================================================-====*/
+ ===========================================================================**/
#include "vvBinaryImageOverlayActor.h"
#include "vvImage.h"
+#include <vtkVersion.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkInformation.h>
#include <vtkImageActor.h>
#include <vtkCamera.h>
#include <vtkRenderer.h>
#include <vtkProperty.h>
#include <vtkImageMapToRGBA.h>
#include <vtkLookupTable.h>
+#include <vtkImageMapper3D.h>
//------------------------------------------------------------------------------
-vvBinaryImageOverlayActor::vvBinaryImageOverlayActor() {
+vvBinaryImageOverlayActor::vvBinaryImageOverlayActor()
+{
mTSlice = -1;
mSlice = 0;
mColor.resize(3);
mAlpha = 0.6;
mImage = 0;
mSlicer = 0;
+ mColorLUT = vtkSmartPointer<vtkLookupTable>::New();
+ mForegroundValue = 1;
+ mBackgroundValue = 0;
+ m_modeBG = true;
+ mDepth = 1.0;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-vvBinaryImageOverlayActor::~vvBinaryImageOverlayActor() {
- for (unsigned int i = 0; i < mSlicer->GetImage()->GetVTKImages().size(); i++) {
- mSlicer->GetRenderer()->RemoveActor(mImageActorList[i]);
- }
+vvBinaryImageOverlayActor::~vvBinaryImageOverlayActor()
+{
mImageActorList.clear();
- mMapperList.clear();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-void vvBinaryImageOverlayActor::setColor(double r, double g, double b) {
+void vvBinaryImageOverlayActor::RemoveActors()
+{
+ for (unsigned int i = 0; i < mImageActorList.size(); i++) {
+ if (mSlicer != 0) {
+ if (mSlicer != NULL) {
+ if (mSlicer->GetRenderer() != 0) {
+ if (mImageActorList[i] != 0) {
+ mSlicer->GetRenderer()->RemoveActor(mImageActorList[i]);
+ }
+ }
+ }
+ }
+ }
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvBinaryImageOverlayActor::SetColor(double r, double g, double b)
+{
mColor[0] = r;
mColor[1] = g;
mColor[2] = b;
//------------------------------------------------------------------------------
-void vvBinaryImageOverlayActor::setSlicer(vvSlicer * slicer) {
+void vvBinaryImageOverlayActor::SetSlicer(vvSlicer * slicer)
+{
mSlicer = slicer;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-void vvBinaryImageOverlayActor::initialize() {
+void vvBinaryImageOverlayActor::Initialize(bool IsVisible)
+{
if (!mSlicer) {
std::cerr << "ERROR. Please use setSlicer before setSlicer in vvBinaryImageOverlayActor." << std::endl;
exit(0);
}
-
+
if (!mImage) {
std::cerr << "ERROR. Please use setImage before setSlicer in vvBinaryImageOverlayActor." << std::endl;
exit(0);
}
// Create an actor for each time slice
for (unsigned int numImage = 0; numImage < mSlicer->GetImage()->GetVTKImages().size(); numImage++) {
- DD(numImage);
-
- // how many intensity ?
+ // how many intensity ?
- vtkImageMapToRGBA * mOverlayMapper = vtkImageMapToRGBA::New();
- mOverlayMapper->SetInput(mImage->GetVTKImages()[0]); // DS TODO : to change if it is 4D !!!
- vtkLookupTable * lut = vtkLookupTable::New();
- DD(lut->IsOpaque ());
- lut->SetRange(0,1);
- lut->SetNumberOfTableValues(2);
- lut->SetTableValue(mBackgroundValue, 0, 0, 0, 0.0); // BG
- lut->SetTableValue(1, mColor[0], mColor[1], mColor[2], mAlpha); // FG
- DD(mColor[0]);
- mOverlayMapper->SetLookupTable(lut);
+
+ if (!mFusionReslice) {
+ mFusionReslice = vtkSmartPointer<vtkImageReslice>::New();
+ mFusionReslice->SetInterpolationModeToLinear();
+ mFusionReslice->AutoCropOutputOn();
+ mFusionReslice->SetBackgroundColor(-1000,-1000,-1000,1);
+ }
+
+ mConcatenatedFusionTransform = vtkSmartPointer<vtkTransform>::New();
+ mConcatenatedFusionTransform->Identity();
+ if (!mImage->GetTransform().empty()){
+ mConcatenatedFusionTransform->Concatenate(mImage->GetTransform()[0]);
+ }
+ mConcatenatedFusionTransform->Concatenate(mSlicer->GetSlicingTransform());
+ mFusionReslice->SetResliceAxes(mConcatenatedFusionTransform->GetMatrix());
+ if (mImage->IsTimeSequence()) {
+#if VTK_MAJOR_VERSION <= 5
+ mFusionReslice->SetInput(0, mImage->GetVTKImages()[numImage]);
+ mFusionReslice->UpdateInformation();
+#else
+ mFusionReslice->SetInputData(0, mImage->GetVTKImages()[numImage]);
+#endif
+ } else {
+#if VTK_MAJOR_VERSION <= 5
+ mFusionReslice->SetInput(0, mImage->GetVTKImages()[0]);
+ mFusionReslice->UpdateInformation();
+#else
+ mFusionReslice->SetInputData(0, mImage->GetVTKImages()[0]);
+#endif
+ }
+ mFusionReslice->Update();
+
+
- vtkImageActor * mOverlayActor = vtkImageActor::New();
+ vtkSmartPointer<vtkImageMapToRGBA> mOverlayMapper = vtkSmartPointer<vtkImageMapToRGBA>::New();
+#if VTK_MAJOR_VERSION <= 5
+ mOverlayMapper->SetInput(mFusionReslice->GetOutput());
+#else
+ mOverlayMapper->SetInputConnection(mFusionReslice->GetOutputPort(0));
+#endif
+
+ double range[2];
+ if (mImage->IsTimeSequence())
+ {
+ mImage->GetVTKImages()[numImage]->GetScalarRange(range);
+ }
+ else {
+ mImage->GetVTKImages()[0]->GetScalarRange(range);
+ }
+ int n = range[1]-range[0]+1;
+ mColorLUT->SetRange(range[0],range[1]);
+ mColorLUT->SetNumberOfTableValues(n);
+
+ // Mode BG -> all is color except BG
+ if (m_modeBG) {
+ for(int i=0; i<n; i++) {
+ mColorLUT->SetTableValue(i, mColor[0], mColor[1], mColor[2], mAlpha);
+ }
+ mColorLUT->SetTableValue(mBackgroundValue, 0, 0, 0, 0.0);
+ }
+ else {
+ // Mode FG -> all is BG, except FG which is color
+ for(int i=0; i<n; i++) {
+ mColorLUT->SetTableValue(i, 0, 0, 0, 0.0);
+ }
+ mColorLUT->SetTableValue(mForegroundValue, mColor[0], mColor[1], mColor[2], mAlpha);
+ }
+
+ mOverlayMapper->SetLookupTable(mColorLUT);
+
+ vtkSmartPointer<vtkImageActor> mOverlayActor = vtkSmartPointer<vtkImageActor>::New();
+#if VTK_MAJOR_VERSION <= 5
mOverlayActor->SetInput(mOverlayMapper->GetOutput());
+#else
+ mOverlayActor->GetMapper()->SetInputConnection(mOverlayMapper->GetOutputPort());
+#endif
mOverlayActor->SetPickable(0);
- mOverlayActor->SetVisibility(true);
- //mOverlayActor->SetOpacity(1.0);
+ mOverlayActor->SetVisibility(IsVisible);
+ //mOverlayActor->SetOpacity(1.0);
+
+ // FIXME : by default overlay is not interpolated.
+ // mOverlayActor->SetInterpolate(mSlicer->GetImageActor()->GetInterpolate());
+ mOverlayActor->InterpolateOff();
mMapperList.push_back(mOverlayMapper);
mImageActorList.push_back(mOverlayActor);
- mSlicer->GetRenderer()->AddActor(mOverlayActor);
+ mSlicer->GetRenderer()->AddActor(mImageActorList[numImage]);
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-void vvBinaryImageOverlayActor::SetOpacity(double d) {
+void vvBinaryImageOverlayActor::SetOpacity(double d)
+{
mAlpha = d;
- // TODO !!lut->SetTableValue(1, mColor[0], mColor[1], mColor[2], mAlpha); // FG
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-void vvBinaryImageOverlayActor::setImage(vvImage::Pointer image, double bg) {
+// void vvBinaryImageOverlayActor::UpdateOpacity(double d) {
+// mAlpha = d;
+// mColorLUT->SetTableValue(1, mColor[0], mColor[1], mColor[2], mAlpha); // FG
+// for (unsigned int numImage = 0; numImage < mSlicer->GetImage()->GetVTKImages().size(); numImage++) {
+// // how many intensity ?
+// vtkImageMapToRGBA * mOverlayMapper = mMapperList[numImage];
+// mOverlayMapper->SetLookupTable(mColorLUT);
+
+// vtkImageActor * mOverlayActor = mImageActorList[numImage];
+// mOverlayActor->SetInput(mOverlayMapper->GetOutput());
+// }
+// }
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+// void vvBinaryImageOverlayActor::SetColor(double r, double v, double b) {
+// mColor[0] = r;
+// mColor[1] = v;
+// mColor[2] = b;
+// // mColorLUT->SetTableValue(1, mColor[0], mColor[1], mColor[2], mAlpha); // FG
+// // for (unsigned int numImage = 0; numImage < mSlicer->GetImage()->GetVTKImages().size(); numImage++) {
+// // // how many intensity ?
+// // vtkImageMapToRGBA * mOverlayMapper = mMapperList[numImage];
+// // mOverlayMapper->SetLookupTable(mColorLUT);
+
+// // vtkImageActor * mOverlayActor = mImageActorList[numImage];
+// // mOverlayActor->SetInput(mOverlayMapper->GetOutput());
+// // }
+// }
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvBinaryImageOverlayActor::SetImage(vvImage::Pointer image, double bg, bool modeBG)
+{
mImage = image;
- mBackgroundValue = bg;
+ if (modeBG) {
+ mBackgroundValue = bg;
+ m_modeBG = true;
+ }
+ else {
+ mForegroundValue = bg;
+ m_modeBG = false;
+ }
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-void vvBinaryImageOverlayActor::hideActors() {
+void vvBinaryImageOverlayActor::HideActors()
+{
if (!mSlicer) return;
mSlice = mSlicer->GetSlice();
for(unsigned int i=0; i<mImageActorList.size(); i++) {
mImageActorList[i]->VisibilityOff();
}
+ // Caller MUST call Render
+ // mSlicer->Render();
}
//------------------------------------------------------------------------------
-
+
//------------------------------------------------------------------------------
-void vvBinaryImageOverlayActor::showActors() {
+void vvBinaryImageOverlayActor::ShowActors()
+{
if (!mSlicer) return;
mSlice = mSlicer->GetSlice();
mTSlice = mSlicer->GetTSlice();
- // for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
mImageActorList[mTSlice]->VisibilityOn();
- update(0, mSlice);
- //}
+ UpdateSlice(0, mSlice);
+ // Caller MUST call Render
+ //mSlicer->Render();
}
//------------------------------------------------------------------------------
-
+
//------------------------------------------------------------------------------
-void vvBinaryImageOverlayActor::update(int slicer, int slice) {
+void vvBinaryImageOverlayActor::UpdateColor()
+{
+ mColorLUT->SetTableValue(1, mColor[0], mColor[1], mColor[2], mAlpha); // FG
+ for (unsigned int numImage = 0; numImage < mSlicer->GetImage()->GetVTKImages().size(); numImage++) {
+ // how many intensity ?
+ vtkImageMapToRGBA * mOverlayMapper = mMapperList[numImage];
+ mOverlayMapper->SetLookupTable(mColorLUT);
+
+ vtkImageActor * mOverlayActor = mImageActorList[numImage];
+#if VTK_MAJOR_VERSION <= 5
+ mOverlayActor->SetInput(mOverlayMapper->GetOutput());
+#else
+ mOverlayActor->SetInputData(mOverlayMapper->GetOutput());
+#endif
+ }
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvBinaryImageOverlayActor::UpdateSlice(int slicer, int slice, bool force)
+{
if (!mSlicer) return;
- if (mPreviousSlice == mSlicer->GetSlice()) {
- if (mPreviousTSlice == mSlicer->GetTSlice()) {
- //DD("=========== NOTHING");
- return; // Nothing to do
+ if (!force) {
+ if (mPreviousSlice == mSlicer->GetSlice()) {
+ if (mPreviousTSlice == mSlicer->GetTSlice()) {
+ return; // Nothing to do
+ }
}
}
int orientation = mSlicer->GetOrientation();
int maskExtent[6];
ComputeExtent(orientation, mSlice, imageExtent, maskExtent);
- //ComputeExtent(imageExtent, maskExtent, mSlicer->GetImage()->GetFirstVTKImageData(), mImage->GetFirstVTKImageData());
- ComputeExtent(maskExtent, maskExtent, mSlicer->GetImage()->GetFirstVTKImageData(), mImage->GetFirstVTKImageData());
- // std::cout << "maskExtent = " << maskExtent[0] << " " << maskExtent[1] << " " << maskExtent[2] << " "
- // << maskExtent[3] << " " << maskExtent[4] << " " << maskExtent[5] << std::endl;
+ ComputeExtent(maskExtent, maskExtent, mSlicer->GetImage()->GetVTKImages()[mTSlice], mImage->GetVTKImages()[mTSlice]);
+#if VTK_MAJOR_VERSION <= 5
mSlicer->ClipDisplayedExtent(maskExtent, mMapperList[mTSlice]->GetInput()->GetWholeExtent());
- // std::cout << "maskExtent = " << maskExtent[0] << " " << maskExtent[1] << " " << maskExtent[2] << " "
- // << maskExtent[3] << " " << maskExtent[4] << " " << maskExtent[5] << std::endl;
- SetDisplayExtentAndCameraPosition(orientation, mSlice, maskExtent, mImageActorList[mTSlice], 0.0);
-
+#else
+ mSlicer->ClipDisplayedExtent(maskExtent, mMapperList[mTSlice]->GetInput()->GetInformation()->Get(vtkDataObject::DATA_EXTENT()));
+#endif
+ HideActors();
+ mImageActorList[mTSlice]->VisibilityOn();
+ SetDisplayExtentAndCameraPosition(orientation, mSlice, maskExtent, mImageActorList[mTSlice], mDepth);
+
// set previous slice
mPreviousTSlice = mSlicer->GetTSlice();
mPreviousSlice = mSlicer->GetSlice();
//------------------------------------------------------------------------------
-void vvBinaryImageOverlayActor::ComputeExtent(int orientation,
- int slice,
+void vvBinaryImageOverlayActor::ComputeExtent(int orientation,
+ int slice,
int * inExtent,
- int * outExtent) {
- // std::cout << "InExtent = " << inExtent[0] << " " << inExtent[1] << " " << inExtent[2] << " "
- // << inExtent[3] << " " << inExtent[4] << " " << inExtent[5] << std::endl;
- // DD(orientation);
+ int * outExtent)
+{
switch (orientation) {
case vtkImageViewer2::SLICE_ORIENTATION_XY:
for(int i=0; i<4; i++) outExtent[i] = inExtent[i];
- outExtent[4] = outExtent[5] = slice;
+ outExtent[4] = outExtent[5] = slice;
break;
case vtkImageViewer2::SLICE_ORIENTATION_XZ:
for(int i=0; i<2; i++) outExtent[i] = inExtent[i];
for(int i=4; i<6; i++) outExtent[i] = inExtent[i];
- outExtent[2] = outExtent[3] = slice;
+ outExtent[2] = outExtent[3] = slice;
break;
case vtkImageViewer2::SLICE_ORIENTATION_YZ:
for(int i=2; i<6; i++) outExtent[i] = inExtent[i];
- outExtent[0] = outExtent[1] = slice;
+ outExtent[0] = outExtent[1] = slice;
break;
}
- // std::cout << "OutExtent = " << outExtent[0] << " " << outExtent[1] << " " << outExtent[2] << " "
- // << outExtent[3] << " " << outExtent[4] << " " << outExtent[5] << std::endl;
}
//------------------------------------------------------------------------------
//----------------------------------------------------------------------------
void vvBinaryImageOverlayActor::ComputeExtent(int * inExtent, int * outExtent, vtkImageData * image, vtkImageData * overlay)
-{
- outExtent[0] = (( image->GetOrigin()[0] + inExtent[0]*image->GetSpacing()[0] ) - overlay->GetOrigin()[0]) /
- overlay->GetSpacing()[0];
- outExtent[1] = (( image->GetOrigin()[0] + inExtent[1]*image->GetSpacing()[0] ) - overlay->GetOrigin()[0]) /
- overlay->GetSpacing()[0];
- outExtent[2] = (( image->GetOrigin()[1] + inExtent[2]*image->GetSpacing()[1] ) - overlay->GetOrigin()[1]) /
- overlay->GetSpacing()[1];
- outExtent[3] = (( image->GetOrigin()[1] + inExtent[3]*image->GetSpacing()[1] ) - overlay->GetOrigin()[1]) /
- overlay->GetSpacing()[1];
- outExtent[4] = (( image->GetOrigin()[2] + inExtent[4]*image->GetSpacing()[2] ) - overlay->GetOrigin()[2]) /
- overlay->GetSpacing()[2];
- outExtent[5] = (( image->GetOrigin()[2] + inExtent[5]*image->GetSpacing()[2] ) - overlay->GetOrigin()[2]) /
- overlay->GetSpacing()[2];
+{
+ for(int i=0; i<3; i++) {
+ double a = (image->GetOrigin()[i] + inExtent[i*2]*image->GetSpacing()[i] -
+ overlay->GetOrigin()[i]) / overlay->GetSpacing()[i];
+ double b = (image->GetOrigin()[i] + inExtent[i*2+1]*image->GetSpacing()[i] -
+ overlay->GetOrigin()[i]) / overlay->GetSpacing()[i];
+ outExtent[i*2] = lrint(a);
+ outExtent[i*2+1] = lrint(b);
+ }
+
+ /* // FIXME (original)
+ outExtent[0] = (int)lrint(((image->GetOrigin()[0] + inExtent[0]*image->GetSpacing()[0]) - overlay->GetOrigin()[0]) / overlay->GetSpacing()[0]);
+ outExtent[1] = (int)lrint(((image->GetOrigin()[0] + inExtent[1]*image->GetSpacing()[0]) - overlay->GetOrigin()[0]) / overlay->GetSpacing()[0]);
+ outExtent[2] = (int)lrint(((image->GetOrigin()[1] + inExtent[2]*image->GetSpacing()[1]) - overlay->GetOrigin()[1]) / overlay->GetSpacing()[1]);
+ outExtent[3] = (int)lrint(((image->GetOrigin()[1] + inExtent[3]*image->GetSpacing()[1]) - overlay->GetOrigin()[1]) / overlay->GetSpacing()[1]);
+ outExtent[4] = (int)lrint(((image->GetOrigin()[2] + inExtent[4]*image->GetSpacing()[2]) - overlay->GetOrigin()[2]) / overlay->GetSpacing()[2]);
+ outExtent[5] = (int)lrint(((image->GetOrigin()[2] + inExtent[5]*image->GetSpacing()[2]) - overlay->GetOrigin()[2]) / overlay->GetSpacing()[2]);
+ */
}
//----------------------------------------------------------------------------
//------------------------------------------------------------------------------
-void vvBinaryImageOverlayActor::SetDisplayExtentAndCameraPosition(int orientation,
- int slice,
- int * extent,
- vtkImageActor * actor,
- double position) {
- actor->SetDisplayExtent(extent);
-
+void vvBinaryImageOverlayActor::SetDisplayExtentAndCameraPosition(int orientation,
+ int slice,
+ int * extent,
+ vtkImageActor * actor,
+ double position)
+{
+ /* FIXME
+ Error according to camera orientation
+ */
+
// Set position
if (orientation == vtkImageViewer2::SLICE_ORIENTATION_XY) {
- if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2] > slice)
- actor->SetPosition(0,0, position);
- else
- actor->SetPosition(0,0, -position);
+ //if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2] > slice)
+ actor->SetPosition(0,0, -position);
+ //else
+ //actor->SetPosition(0,0, position);
}
if (orientation == vtkImageViewer2::SLICE_ORIENTATION_XZ) {
- if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1] > slice)
- actor->SetPosition(0,position,0);
- else
- actor->SetPosition(0,-position,0);
+ //if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1] > slice)
+ // actor->SetPosition(0,position,0);
+ //else
+ actor->SetPosition(0,-position,0);
}
if (orientation == vtkImageViewer2::SLICE_ORIENTATION_YZ) {
- if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0] > slice)
- actor->SetPosition(position,0, 0);
- else
- actor->SetPosition(-position,0, 0);
+ //if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0] > slice)
+ // actor->SetPosition(position,0, 0);
+ //else
+ actor->SetPosition(-position,0, 0);
}
-
+ actor->SetDisplayExtent(extent);
}
//------------------------------------------------------------------------------
-
-
-