]> Creatis software - clitk.git/blobdiff - vv/vvSlicerManager.cxx
corrected bug in fusion opacity with double values
[clitk.git] / vv / vvSlicerManager.cxx
index 74a059863314c0634c9c0d42f413e922ee1a1b05..813ba2258bc1f2b247b342f9176e5b2be8f91a4b 100644 (file)
 /*=========================================================================
+  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 "vvSlicerManager.h"
-
 #include "vvSlicer.h"
 #include "vvImage.h"
 #include "vvSlicerManagerCommand.h"
 #include "vvInteractorStyleNavigator.h"
 #include "vvLandmarks.h"
-#include "vvImageReader.h"
-#include "vvImageReader.h"
 #include "vvMesh.h"
 #include "vvImageMapToWLColors.h"
-
-#include "vtkImageActor.h"
-#include "vtkImageData.h"
-#include "vtkRenderWindow.h"
-#include "vtkRendererCollection.h"
-#include "vtkRenderWindowInteractor.h"
-#include "vtkImageMapToWindowLevelColors.h"
-#include "vtkWindowLevelLookupTable.h"
-#include "vtkColorTransferFunction.h"
-#include "vtkImageClip.h"
+#include "vvBlendImageActor.h"
+
+#include <vtkImageActor.h>
+#include <vtkImageData.h>
+#include <vtkRenderWindow.h>
+#include <vtkRendererCollection.h>
+#include <vtkRenderWindowInteractor.h>
+#include <vtkImageMapToWindowLevelColors.h>
+#include <vtkWindowLevelLookupTable.h>
+#include <vtkColorTransferFunction.h>
+#include <vtkImageClip.h>
 #include <vtkLODActor.h>
 #include <vtkPointData.h>
-
 #include <vtksys/SystemTools.hxx>
-//----------------------------------------------------------------------------
+#include <vtkCamera.h>
+
+#include <qfileinfo.h>
 
+//----------------------------------------------------------------------------
 vvSlicerManager::vvSlicerManager(int numberOfSlicers)
 {
-    mFileName = "";
-    mId = "";
-    mVFName = "";
-    mOverlayName = "";
-    mFusionName = "";
-    mVFId = "";
-    mLastError = "";
-    mType = UNDEFINEDIMAGETYPE;
-    mColorMap = 0;
-    mPreset = 0;
-    mOverlayColor = 130;
-
-    mFusionOpacity = 70;
-    mFusionColorMap = 3;
-    mFusionWindow = 1000;
-    mFusionLevel = 1000;
-
-    mReader = NULL;
-    mImage = NULL;
-    mVF=NULL;
-    mVectorReader = NULL;
-    mOverlayReader = NULL;
-    mFusionReader = NULL;
-    mLandmarks = NULL;
-    mLinkedId.resize(0);
-
-    for ( int i = 0; i < numberOfSlicers; i++)
-    {
-        vvSlicer *slicer = vvSlicer::New();
-        mSlicers.push_back(slicer);
-    }
+  mFileName = "";
+  mId = "";
+  mVFName = "";
+  mOverlayName = "";
+  mFusionName = "";
+  mVFId = "";
+  mLastError = "";
+  mType = vvImageReader::UNDEFINEDIMAGETYPE;
+  mColorMap = 0;
+  mPreset = 0;
+  mOverlayColor = 130;
+
+  mFusionOpacity = 30;
+  mFusionThresOpacity = 1;
+  mFusionColorMap = 3;
+  mFusionWindow = 1000;
+  mFusionLevel = 1000;
+
+  mLandmarks = NULL;
+  mLinkedId.resize(0);
+
+  for ( int i = 0; i < numberOfSlicers; i++)
+    mSlicers.push_back(vtkSmartPointer<vvSlicer>::New());
+
+  mPreviousSlice.resize(numberOfSlicers);
+  mPreviousTSlice.resize(numberOfSlicers);
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 vvSlicerManager::~vvSlicerManager()
 {
-    for ( unsigned int i = 0; i < mSlicers.size(); i++)
-    {
-        if (mSlicers[i] != NULL)
-            mSlicers[i]->Delete();
-    }
-    if (mReader)
-    {
-        delete mReader;
-    }
-    if (mVectorReader)
-    {
-        delete mVectorReader;
-    }
-    if (mOverlayReader)
-    {
-        delete mOverlayReader;
-    }
-    if (mFusionReader)
-    {
-        delete mFusionReader;
-    }
-    if (mLandmarks)
-        delete mLandmarks;
+  if (mLandmarks)
+    delete mLandmarks;
+}
+//----------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvSlicerManager::SetFilename(std::string filename, int number)
+{
+  mFileName = filename;
+  mFileName = vtksys::SystemTools::GetFilenameName(mFileName);
+  mBaseFileName = vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(mFileName));
+  mBaseFileNameNumber = number;
+
+  mFileName = mBaseFileName;
+  if (number != 0) {
+    mFileName.append("_"+clitk::toString(number));
+  }
+  mFileName.append(vtksys::SystemTools::GetFilenameLastExtension(filename));
+
+  for(unsigned int i=0; i<mSlicers.size(); i++) {
+    mSlicers[i]->SetFileName(mFileName);//vtksys::SystemTools::GetFilenameWithoutLastExtension(filename));
+  }
+  
 }
+//------------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::AddContour(vvMesh::Pointer contour,bool propagate)
 {
-    for ( unsigned int i = 0; i < mSlicers.size(); i++)
-    {
-        mSlicers[i]->AddContour(contour,propagate);
-    }
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->AddContour(contour,propagate);
+  }
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::ToggleContourSuperposition()
 {
-    for ( unsigned int i = 0; i < mSlicers.size(); i++)
-        mSlicers[i]->ToggleContourSuperposition();
+  for ( unsigned int i = 0; i < mSlicers.size(); i++)
+    mSlicers[i]->ToggleContourSuperposition();
 }
+//----------------------------------------------------------------------------
 
-bool vvSlicerManager::SetImage(std::string filename,LoadedImageType type)
+//----------------------------------------------------------------------------
+std::string vvSlicerManager::GetListOfAbsoluteFilePathInOneString(const std::string &actorType)
 {
-    mFileName = filename;
-    mType = type;
-    if (mReader == NULL)
-        mReader = new vvImageReader;
-    std::vector<std::string> filenames;
-    filenames.push_back(filename);
-    mReader->SetInputFilenames(filenames);
-    mReader->Update(type);
-    if (mReader->GetLastError().size() == 0)
-    {
-        mImage=mReader->GetOutput();
-        for ( unsigned int i = 0; i < mSlicers.size(); i++)
-        {
-            mSlicers[i]->SetFileName(vtksys::SystemTools::GetFilenameWithoutLastExtension(filename));
-            mSlicers[i]->SetImage(mReader->GetOutput());
-        }
-    }
-    else
-    {
-        mLastError = mReader->GetLastError();
-        return false;
-    }
-    return true;
+  vvImageReader *reader = NULL;
+
+  if(actorType=="image")
+    reader = mReader;
+  else if(actorType=="overlay")
+    reader = mOverlayReader;
+  else if(actorType=="fusion")
+    reader = mFusionReader;
+  else if(actorType=="vector")
+    reader = mVectorReader;
+
+  if(!reader)
+    return "";
+
+  std::string list;
+  for(unsigned int i=0; i<reader->GetInputFilenames().size(); i++){
+    QFileInfo fileinfo(reader->GetInputFilenames()[i].c_str()); //Do not show the path
+    if(i)
+      list += '\n';
+    list += fileinfo.absoluteFilePath().toStdString();
+  }
+  return list;
 }
+//----------------------------------------------------------------------------
 
-void vvSlicerManager::SetImage(vvImage::Pointer image)
+
+//----------------------------------------------------------------------------
+bool vvSlicerManager::SetImage(std::string filename, vvImageReader::LoadedImageType type, int n, unsigned int slice)
 {
-    mImage=image;
-    for (unsigned int i = 0; i < mSlicers.size();i++)
-    {
-        mSlicers[i]->SetImage(image);
+  mType = type;
+  if (mReader.IsNull())
+    mReader = vvImageReader::New();
+  std::vector<std::string> filenames;
+  filenames.push_back(filename);
+  mReader->SetInputFilenames(filenames);
+  mReader->SetSlice(slice); // Only used for SLICED type
+  mReader->Update(type);
+
+  SetFilename(filename, n);
+  //  mFileName = vtksys::SystemTools::GetFilenameName(mFileName);
+  //mBaseFileName = vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(mFileName));
+  //mBaseFileNameNumber = n;
+
+  if (mReader->GetLastError().size() == 0) {
+    mImage=mReader->GetOutput();
+    for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+      mSlicers[i]->SetFileName(vtksys::SystemTools::GetFilenameWithoutLastExtension(filename));
+      mSlicers[i]->SetImage(mReader->GetOutput());
     }
+  } else {
+    mLastError = mReader->GetLastError();
+    return false;
+  }
+  // if (n!=0) {
+  //   mFileName.append("_"+clitk::toString(n));
+  // }
+  return true;
 }
+//----------------------------------------------------------------------------
 
-bool vvSlicerManager::SetImages(std::vector<std::string> filenames,LoadedImageType type)
-{
-    mType = type;
-    std::string fileWithoutExtension = vtksys::SystemTools::GetFilenameWithoutExtension(filenames[0]);
-    if (type == DICOM)
-        fileWithoutExtension += "_dicom";
-    else if (type == MERGED)
-        fileWithoutExtension += "_merged";
-    else if (type == MERGEDWITHTIME)
-        fileWithoutExtension += "_merged_wt";
 
-    mFileName = fileWithoutExtension + vtksys::SystemTools::GetFilenameExtension(filenames[0]);
-    if (mReader == NULL)
-        mReader = new vvImageReader;
-    mReader->SetInputFilenames(filenames);
-    mReader->Update(type);
+//----------------------------------------------------------------------------
+void vvSlicerManager::SetImage(vvImage::Pointer image)
+{
+  mImage=image;
+  for (unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetImage(image);
+  }
+}
+//----------------------------------------------------------------------------
 
 
-    if (mReader->GetLastError().size() == 0)
-    {
-        mImage=mReader->GetOutput();
-        for ( unsigned int i = 0; i < mSlicers.size(); i++)
-        {
-            mSlicers[i]->SetFileName(fileWithoutExtension);
-            mSlicers[i]->SetImage(mReader->GetOutput());
-        }
-    }
-    else
-    {
-        mLastError = mReader->GetLastError();
-        return false;
+//----------------------------------------------------------------------------
+bool vvSlicerManager::SetImages(std::vector<std::string> filenames, vvImageReader::LoadedImageType type, int n)
+{
+  mType = type;
+  std::string fileWithoutExtension = vtksys::SystemTools::GetFilenameWithoutExtension(filenames[0]);
+  if (type == vvImageReader::DICOM)
+    fileWithoutExtension += "_dicom";
+  else if (type == vvImageReader::MERGED)
+    fileWithoutExtension += "_merged";
+  else if (type == vvImageReader::MERGEDWITHTIME)
+    fileWithoutExtension += "_merged_wt";
+
+  mFileName = vtksys::SystemTools::GetFilenameName(mFileName);
+  mFileName = fileWithoutExtension + vtksys::SystemTools::GetFilenameExtension(filenames[0]);
+  if (mReader.IsNull())
+    mReader = vvImageReader::New();
+  mReader->SetInputFilenames(filenames);
+  mReader->Update(type);
+
+  mBaseFileName = vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(mFileName));
+  mBaseFileNameNumber = n;
+
+  if (mReader->GetLastError().size() == 0) {
+    mImage=mReader->GetOutput();
+    for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+      mSlicers[i]->SetFileName(fileWithoutExtension);
+      mSlicers[i]->SetImage(mReader->GetOutput());
     }
-    return true;
+  } else {
+    mLastError = mReader->GetLastError();
+    return false;
+  }
+  if (n!=0) {
+    mFileName.append("_"+clitk::toString(n));
+  }
+  return true;
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 bool vvSlicerManager::SetOverlay(std::string filename,int dim, std::string component)
 {
-    mOverlayName = filename;
-    mOverlayComponent = component;
-    if (dim > mImage->GetNumberOfDimensions())
-    {
-        mLastError = " Overlay dimension cannot be greater then reference image!";
-        return false;
-    }
-    if (mOverlayReader == NULL)
-        mOverlayReader = new vvImageReader;
-    std::vector<std::string> filenames;
-    filenames.push_back(filename);
-    mOverlayReader->SetInputFilenames(filenames);
-    mOverlayReader->Update(mImage->GetNumberOfDimensions(),component.c_str(),mType);
-    if (mOverlayReader->GetLastError().size() == 0)
-    {
-        for ( unsigned int i = 0; i < mSlicers.size(); i++)
-        {
-            mSlicers[i]->SetOverlay(mOverlayReader->GetOutput());
-        }
-    }
-    else
-    {
-        mLastError = mOverlayReader->GetLastError();
-        return false;
+  mOverlayName = filename;
+  mOverlayComponent = component;
+  if (dim > mImage->GetNumberOfDimensions()) {
+    mLastError = " Overlay dimension cannot be greater then reference image!";
+    return false;
+  }
+  if (mOverlayReader.IsNull())
+    mOverlayReader = vvImageReader::New();
+  std::vector<std::string> filenames;
+  filenames.push_back(filename);
+  mOverlayReader->SetInputFilenames(filenames);
+  mOverlayReader->Update(mImage->GetNumberOfDimensions(),component.c_str(),mType);
+  if (mOverlayReader->GetLastError().size() == 0) {
+    for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+      mSlicers[i]->SetOverlay(mOverlayReader->GetOutput());
     }
-    return true;
+  } else {
+    mLastError = mOverlayReader->GetLastError();
+    return false;
+  }
+  return true;
 }
+//----------------------------------------------------------------------------
 
+
+//----------------------------------------------------------------------------
 bool vvSlicerManager::SetFusion(std::string filename,int dim, std::string component)
 {
-    mFusionName = filename;
-    mFusionComponent = component;
-    if (dim > mImage->GetNumberOfDimensions())
-    {
-        mLastError = " Overlay dimension cannot be greater then reference image!";
-        return false;
-    }
-    if (mFusionReader == NULL)
-        mFusionReader = new vvImageReader;
-    std::vector<std::string> filenames;
-    filenames.push_back(filename);
-    mFusionReader->SetInputFilenames(filenames);
-    mFusionReader->Update(mImage->GetNumberOfDimensions(),component.c_str(),mType);
-    if (mFusionReader->GetLastError().size() == 0)
-    {
-        for ( unsigned int i = 0; i < mSlicers.size(); i++)
-        {
-            mSlicers[i]->SetFusion(mFusionReader->GetOutput());
-        }
-    }
-    else
-    {
-        mLastError = mFusionReader->GetLastError();
-        return false;
+  mFusionName = filename;
+  mFusionComponent = component;
+  if (dim > mImage->GetNumberOfDimensions()) {
+    mLastError = " Overlay dimension cannot be greater then reference image!";
+    return false;
+  }
+  if (mFusionReader.IsNull())
+    mFusionReader = vvImageReader::New();
+  std::vector<std::string> filenames;
+  filenames.push_back(filename);
+  mFusionReader->SetInputFilenames(filenames);
+  mFusionReader->Update(mImage->GetNumberOfDimensions(),component.c_str(),mType);
+  if (mFusionReader->GetLastError().size() == 0) {
+    for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+      mSlicers[i]->SetFusion(mFusionReader->GetOutput());
     }
-    double *fusRange = mFusionReader->GetOutput()->GetVTKImages()[0]->GetScalarRange();
-    mFusionLevel = (fusRange[0]+fusRange[1])/2;
-    mFusionWindow = fusRange[1]-fusRange[0];
-    return true;
+  } else {
+    mLastError = mFusionReader->GetLastError();
+    return false;
+  }
+  double *fusRange = mFusionReader->GetOutput()->GetVTKImages()[0]->GetScalarRange();
+  mFusionLevel = (fusRange[0]+fusRange[1])/2;
+  mFusionWindow = fusRange[1]-fusRange[0];
+
+  return true;
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 bool vvSlicerManager::SetVF(std::string filename)
 {
-    if (mVectorReader == NULL)
-        mVectorReader = new vvImageReader;
-    mVectorReader->SetInputFilename(filename);
-    mVectorReader->Update(VECTORFIELD);
-    if (mVectorReader->GetLastError().size() != 0)
-    {
-        mLastError = mVectorReader->GetLastError();
-        return false;
-    }
-    else
-        return SetVF(mVectorReader->GetOutput(),filename);
+  if (mVectorReader.IsNull())
+    mVectorReader = vvImageReader::New();
+  mVectorReader->SetInputFilename(filename);
+  
+  if (mType == vvImageReader::IMAGEWITHTIME)
+    mVectorReader->Update(vvImageReader::VECTORFIELDWITHTIME);
+  else
+    mVectorReader->Update(vvImageReader::VECTORFIELD);
+  if (mVectorReader->GetLastError().size() != 0) {
+    mLastError = mVectorReader->GetLastError();
+    return false;
+  } else
+    return SetVF(mVectorReader->GetOutput(),filename);
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 bool vvSlicerManager::SetVF(vvImage::Pointer vf,std::string filename)
 {
-    if (vf->GetNumberOfDimensions() > mImage->GetNumberOfDimensions())
-    {
-        mLastError = " Vector field dimension cannot be greater then reference image!";
-        return false;
+  if (vf->GetNumberOfDimensions() > mImage->GetNumberOfDimensions()) {
+    mLastError = "Sorry, vector field dimension cannot be greater then reference image.";
+    return false;
+  }
+  if (vf->GetNumberOfDimensions() == 4) {
+    if (vf->GetSpacing()[3] != mImage->GetSpacing()[3]) {
+      mLastError = "Sorry, vector field time spacing cannot be different from time spacing of the reference image.";
+      return false;
     }
-    mVF=vf;
-    mVFName = filename;
-    for ( unsigned int i = 0; i < mSlicers.size(); i++)
-    {
-        mSlicers[i]->SetVF(vf);
+    if (vf->GetOrigin()[3] != mImage->GetOrigin()[3]) {
+      mLastError = "Sorry, vector field time origin cannot be different from time origin of the reference image.";
+      return false;
     }
-    return true;
+  }
+  mVF=vf;
+  mVFName = filename;
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetVF(vf);
+  }
+  return true;
 }
+//----------------------------------------------------------------------------
 
-void vvSlicerManager::SetExtractedImage(std::string filename,vvImage::Pointer image, int slice)
-{
-    mFileName = filename;
-    mImage = vvImage::New();
-    if (image->GetNumberOfDimensions() == 4)
-    {
-        mImage->AddImage(image->GetVTKImages()[slice]);
-        for ( unsigned int i = 0; i < mSlicers.size(); i++)
-        {
-            mSlicers[i]->SetFileName(vtksys::SystemTools::GetFilenameWithoutLastExtension(filename));
-            mSlicers[i]->SetImage(mImage);
-        }
-    }
-    else
-    {
-        vtkImageClip* clipper = vtkImageClip::New();
-        int extent[6];
-        image->GetVTKImages()[0]->GetWholeExtent(extent);
-        clipper->SetInput(image->GetVTKImages()[0]);
-        clipper->SetOutputWholeExtent(extent[0],extent[1],extent[2],extent[3],slice,slice);
-        clipper->Update();
-        mImage->AddImage(clipper->GetOutput());
-        for ( unsigned int i = 0; i < mSlicers.size(); i++)
-        {
-            mSlicers[i]->SetFileName(vtksys::SystemTools::GetFilenameWithoutLastExtension(filename));
-            mSlicers[i]->SetImage(mImage);
-        }
-        clipper->Delete();
-    }
-}
 
+//----------------------------------------------------------------------------
 vvSlicer* vvSlicerManager::GetSlicer(int i)
 {
-    return mSlicers[i];
+  return mSlicers[i];
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::UpdateSlicer(int num, bool state)
 {
-    if (mSlicers[num]->GetImage())
-            mSlicers[num]->SetDisplayMode(state);
+  if (mSlicers[num]->GetImage())
+    mSlicers[num]->SetDisplayMode(state);
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::SetSlicerWindow(int i, vtkRenderWindow* RW)
 {
-    mSlicers[i]->SetRenderWindow(i,RW);
+  mSlicers[i]->SetRenderWindow(i,RW);
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::SetInteractorStyleNavigator(int i, vtkInteractorStyle* style)
 {
-    vvSlicerManagerCommand *smc = vvSlicerManagerCommand::New();
-    std::cerr << smc << ":" << i << "  " << this << endl;
-    smc->SM = this;
-    smc->SetSlicerNumber(i);
-    mSlicers[i]->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style);
+  vvSlicerManagerCommand *smc = vvSlicerManagerCommand::New();
+  smc->SM = this;
+  smc->SetSlicerNumber(i);
+  mSlicers[i]->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style);
 
-    mSlicers[i]->GetRenderWindow()->GetInteractor()->
+  mSlicers[i]->GetRenderWindow()->GetInteractor()->
     GetInteractorStyle()->AddObserver(vtkCommand::KeyPressEvent, smc);
-    mSlicers[i]->GetRenderWindow()->GetInteractor()->
+  mSlicers[i]->GetRenderWindow()->GetInteractor()->
     GetInteractorStyle()->AddObserver(vtkCommand::WindowLevelEvent, smc);
-    mSlicers[i]->GetRenderWindow()->GetInteractor()->
+  mSlicers[i]->GetRenderWindow()->GetInteractor()->
     GetInteractorStyle()->AddObserver(vtkCommand::EndWindowLevelEvent, smc);
-    mSlicers[i]->GetRenderWindow()->GetInteractor()->
+  mSlicers[i]->GetRenderWindow()->GetInteractor()->
     GetInteractorStyle()->AddObserver(vtkCommand::StartWindowLevelEvent, smc);
-    mSlicers[i]->GetRenderWindow()->GetInteractor()->
+  mSlicers[i]->GetRenderWindow()->GetInteractor()->
     GetInteractorStyle()->AddObserver(vtkCommand::PickEvent, smc);
-    mSlicers[i]->GetRenderWindow()->GetInteractor()->
+  mSlicers[i]->GetRenderWindow()->GetInteractor()->
     GetInteractorStyle()->AddObserver(vtkCommand::StartPickEvent, smc);
-    mSlicers[i]->GetRenderWindow()->GetInteractor()->
+  mSlicers[i]->GetRenderWindow()->GetInteractor()->
     GetInteractorStyle()->AddObserver(vtkCommand::LeaveEvent, smc);
-    mSlicers[i]->GetRenderWindow()->GetInteractor()->
+  mSlicers[i]->GetRenderWindow()->GetInteractor()->
     GetInteractorStyle()->AddObserver(vtkCommand::UserEvent, smc);
-    mSlicers[i]->GetRenderWindow()->GetInteractor()->
+  mSlicers[i]->GetRenderWindow()->GetInteractor()->
     GetInteractorStyle()->AddObserver(vtkCommand::MouseWheelForwardEvent, smc);
-    mSlicers[i]->GetRenderWindow()->GetInteractor()->
+  mSlicers[i]->GetRenderWindow()->GetInteractor()->
     GetInteractorStyle()->AddObserver(vtkCommand::MouseWheelBackwardEvent, smc);
-    smc->Delete();
+  // mSlicers[i]->GetRenderWindow()->GetInteractor()->
+  //   GetInteractorStyle()->AddObserver(vtkCommand::LeftButtonReleaseEvent, smc);
+  mSlicers[i]->GetRenderWindow()->GetInteractor()->
+    GetInteractorStyle()->AddObserver(vtkCommand::EndPickEvent, smc);
+  mSlicers[i]->GetRenderWindow()->GetInteractor()->
+    GetInteractorStyle()->AddObserver(vtkCommand::EndInteractionEvent, smc);
+  smc->Delete();
+}
+//----------------------------------------------------------------------------
+
+
+//----------------------------------------------------------------------------
+void vvSlicerManager::LeftButtonReleaseEvent(int slicer)
+{
+  emit LeftButtonReleaseSignal(slicer);
 }
+//----------------------------------------------------------------------------
 
+//----------------------------------------------------------------------------
+void vvSlicerManager::SetSliceOrientation(int slicer, int orientation)
+{
+  mSlicers[slicer]->SetSliceOrientation(orientation);
+  emit UpdateOrientation(slicer, orientation);
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
 void vvSlicerManager::SetTSlice(int slice)
 {
-    if (slice < 0)
-        slice = 0;
-    else if (slice > mSlicers[0]->GetTMax())
-        slice = mSlicers[0]->GetTMax();
-    if (mLandmarks)
-        mLandmarks->SetTime(slice);
-    for ( unsigned int i = 0; i < mSlicers.size(); i++)
-    {
-        mSlicers[i]->SetTSlice(slice);
-        if (mSlicers[i]->GetImageActor()->GetVisibility())
-            UpdateTSlice(i);
+  if (slice < 0)
+    slice = 0;
+  else if (slice > mSlicers[0]->GetTMax())
+    slice = mSlicers[0]->GetTMax();
+  if (mLandmarks)
+    mLandmarks->SetTime(slice);
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    if (slice != mSlicers[i]->GetTSlice()) {
+      mSlicers[i]->SetTSlice(slice);
+        UpdateTSlice(i);
     }
+  }
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::SetNextTSlice(int originating_slicer)
 {
-    int t = mSlicers[0]->GetTSlice();
-    t++;
-    if (t > mSlicers[0]->GetTMax())
-        t = 0;
-    emit UpdateTSlice(originating_slicer,t);
+  int t = mSlicers[0]->GetTSlice();
+  t++;
+  if (t > mSlicers[0]->GetTMax())
+    t = 0;
+  //std::cout << "vvSlicerManager::SetNextTSlice" << std::endl;
+  emit UpdateTSlice(originating_slicer,t);
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::SetPreviousTSlice(int originating_slicer)
 {
-    int t = mSlicers[0]->GetTSlice();
-    t--;
-    if (t < 0)
-        t = mSlicers[0]->GetTMax();
-    emit UpdateTSlice(originating_slicer,t);
+  int t = mSlicers[0]->GetTSlice();
+  t--;
+  if (t < 0)
+    t = mSlicers[0]->GetTMax();
+  //std::cout << "vvSlicerManager::SetPreviousTSlice" << std::endl;
+  emit UpdateTSlice(originating_slicer,t);
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::ToggleInterpolation()
 {
-    bool interpolate=!(mSlicers[0]->GetImageActor()->GetInterpolate());
-    for ( unsigned int i = 0; i < mSlicers.size(); i++)
-    {
-        mSlicers[i]->GetImageActor()->SetInterpolate(interpolate);
-    }
+  bool interpolate=!(mSlicers[0]->GetImageActor()->GetInterpolate());
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->GetImageActor()->SetInterpolate(interpolate);
+    if (mSlicers[i]->GetOverlayActor())
+      mSlicers[i]->GetOverlayActor()->SetInterpolate(interpolate);
+    if (mSlicers[i]->GetFusionActor())
+      mSlicers[i]->GetFusionActor()->SetInterpolate(interpolate);
+  }
 }
+//----------------------------------------------------------------------------
 
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::SetTSliceInSlicer(int tslice, int slicer)
 {
-    if (tslice < 0)
-        tslice = 0;
-    else if (tslice > mSlicers[slicer]->GetTMax())
-        tslice = mSlicers[slicer]->GetTMax();
-    if (mLandmarks)
-        mLandmarks->SetTime(tslice);
-    mSlicers[slicer]->SetTSlice(tslice);
-    if (mSlicers[slicer]->GetImageActor()->GetVisibility())
-        UpdateTSlice(slicer);
+  if (tslice < 0)
+    tslice = 0;
+  else if (tslice > mSlicers[slicer]->GetTMax())
+    tslice = mSlicers[slicer]->GetTMax();
+  if (mLandmarks)
+    mLandmarks->SetTime(tslice);
+
+  if (mSlicers[slicer]->GetTSlice() == tslice) return;
+
+  mSlicers[slicer]->SetTSlice(tslice);
+  UpdateTSlice(slicer);
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::SetColorWindow(double s)
 {
-    for ( unsigned int i = 0; i < mSlicers.size(); i++)
-    {
-        mSlicers[i]->SetColorWindow(s);
-    }
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetColorWindow(s);
+  }
 }
+//----------------------------------------------------------------------------
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::SetColorLevel(double s)
 {
-    for ( unsigned int i = 0; i < mSlicers.size(); i++)
-    {
-        mSlicers[i]->SetColorLevel(s);
-    }
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetColorLevel(s);
+  }
 }
+//----------------------------------------------------------------------------
 
-void vvSlicerManager::SetCursorVisibility(int s)
+//----------------------------------------------------------------------------
+void vvSlicerManager::SetOverlayColorWindow(double s)
 {
-    for ( unsigned int i = 0; i < mSlicers.size(); i++)
-    {
-        mSlicers[i]->SetCursorVisibility(s);
-    }
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetOverlayColorWindow(s);
+  }
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+void vvSlicerManager::SetOverlayColorLevel(double s)
+{
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetOverlayColorLevel(s);
+  }
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+void vvSlicerManager::SetLinkOverlayWindowLevel(bool b)
+{
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetLinkOverlayWindowLevel(b);
+  }
 }
+//----------------------------------------------------------------------------
 
+//----------------------------------------------------------------------------
+void vvSlicerManager::SetCursorAndCornerAnnotationVisibility(int s)
+{
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetCursorVisibility(s);
+    mSlicers[i]->SetCornerAnnotationVisibility(s);
+  }
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
 void vvSlicerManager::SetOpacity(int i, double factor)
 {
-    mSlicers[i]->SetOpacity(1/factor);
+  mSlicers[i]->SetOpacity(1/factor);
 }
+//----------------------------------------------------------------------------
 
+
+//----------------------------------------------------------------------------
 void vvSlicerManager::UpdateViews(int current,int slicer)
 {
-    double x = (mSlicers[slicer]->GetCurrentPosition()[0] - mSlicers[slicer]->GetInput()->GetOrigin()[0])
-               /mSlicers[slicer]->GetInput()->GetSpacing()[0];
-    double y = (mSlicers[slicer]->GetCurrentPosition()[1] - mSlicers[slicer]->GetInput()->GetOrigin()[1])
-               /mSlicers[slicer]->GetInput()->GetSpacing()[1];
-    double z = (mSlicers[slicer]->GetCurrentPosition()[2] - mSlicers[slicer]->GetInput()->GetOrigin()[2])
-               /mSlicers[slicer]->GetInput()->GetSpacing()[2];
-
-    if (x >= mSlicers[slicer]->GetInput()->GetWholeExtent()[0] &&
-            x <= mSlicers[slicer]->GetInput()->GetWholeExtent()[1] &&
-            y >= mSlicers[slicer]->GetInput()->GetWholeExtent()[2] &&
-            y <= mSlicers[slicer]->GetInput()->GetWholeExtent()[3] &&
-            z >= mSlicers[slicer]->GetInput()->GetWholeExtent()[4] &&
-            z <= mSlicers[slicer]->GetInput()->GetWholeExtent()[5])
-    {
-        mSlicers[slicer]->UpdateCursorPosition();
-        mSlicers[slicer]->SetCursorColor(10,212,255);
+  double x = (mSlicers[slicer]->GetCurrentPosition()[0] - mSlicers[slicer]->GetInput()->GetOrigin()[0])
+    /mSlicers[slicer]->GetInput()->GetSpacing()[0];
+  double y = (mSlicers[slicer]->GetCurrentPosition()[1] - mSlicers[slicer]->GetInput()->GetOrigin()[1])
+    /mSlicers[slicer]->GetInput()->GetSpacing()[1];
+  double z = (mSlicers[slicer]->GetCurrentPosition()[2] - mSlicers[slicer]->GetInput()->GetOrigin()[2])
+    /mSlicers[slicer]->GetInput()->GetSpacing()[2];
+
+  if (x >= mSlicers[slicer]->GetInput()->GetWholeExtent()[0] &&
+      x <= mSlicers[slicer]->GetInput()->GetWholeExtent()[1] &&
+      y >= mSlicers[slicer]->GetInput()->GetWholeExtent()[2] &&
+      y <= mSlicers[slicer]->GetInput()->GetWholeExtent()[3] &&
+      z >= mSlicers[slicer]->GetInput()->GetWholeExtent()[4] &&
+      z <= mSlicers[slicer]->GetInput()->GetWholeExtent()[5]) {
+    mSlicers[slicer]->UpdateCursorPosition();
+    mSlicers[slicer]->SetCursorColor(10,212,255);
+
+    switch (mSlicers[slicer]->GetSliceOrientation()) {
+    case vtkImageViewer2::SLICE_ORIENTATION_XY:
+      if (mSlicers[slicer]->GetSlice() != (int)floor(z))
+        mSlicers[slicer]->SetSlice((int)floor(z));
+      break;
+
+    case vtkImageViewer2::SLICE_ORIENTATION_XZ:
+      if (mSlicers[slicer]->GetSlice() != (int)floor(y))
+        mSlicers[slicer]->SetSlice((int)floor(y));
+      break;
+
+    case vtkImageViewer2::SLICE_ORIENTATION_YZ:
+      if (mSlicers[slicer]->GetSlice() != (int)floor(x))
+        mSlicers[slicer]->SetSlice((int)floor(x));
+      break;
+    }
+    mSlicers[slicer]->Render();
 
-        switch (mSlicers[slicer]->GetSliceOrientation())
-        {
+    for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+      if (i != (unsigned int)slicer
+          && mSlicers[i]->GetRenderer()->GetDraw()
+          && mSlicers[i]->GetRenderWindow()->GetSize()[0] > 2
+          && mSlicers[i]->GetRenderWindow()->GetSize()[1] > 2) {
+        mSlicers[i]->SetCurrentPosition(mSlicers[slicer]->GetCurrentPosition()[0],
+                                        mSlicers[slicer]->GetCurrentPosition()[1],
+                                        mSlicers[slicer]->GetCurrentPosition()[2],
+                                        mSlicers[slicer]->GetTSlice());
+        mSlicers[i]->UpdateCursorPosition();
+        if (current) { //do not display corner annotation if image is the one picked
+          mSlicers[i]->SetCurrentPosition(-VTK_DOUBLE_MAX,-VTK_DOUBLE_MAX,
+                                          -VTK_DOUBLE_MAX, mSlicers[slicer]->GetTSlice());
+          mSlicers[i]->SetCursorColor(255,10,212);
+        } else {
+          mSlicers[i]->SetCursorColor(150,10,282);
+        }
+        switch (mSlicers[i]->GetSliceOrientation()) {
         case vtkImageViewer2::SLICE_ORIENTATION_XY:
-            if (mSlicers[slicer]->GetSlice() == (int)floor(z))
-                mSlicers[slicer]->Render();
-            else
-                mSlicers[slicer]->SetSlice((int)floor(z));
-            break;
+          if (mSlicers[i]->GetSlice() != (int)floor(z))
+            mSlicers[i]->SetSlice((int)floor(z));
+          break;
 
         case vtkImageViewer2::SLICE_ORIENTATION_XZ:
-            if (mSlicers[slicer]->GetSlice() == (int)floor(y))
-                mSlicers[slicer]->Render();
-            else
-                mSlicers[slicer]->SetSlice((int)floor(y));
-            break;
+          if (mSlicers[i]->GetSlice() != (int)floor(y))
+            mSlicers[i]->SetSlice((int)floor(y));
+          break;
 
         case vtkImageViewer2::SLICE_ORIENTATION_YZ:
-            if (mSlicers[slicer]->GetSlice() == (int)floor(x))
-                mSlicers[slicer]->Render();
-            else
-                mSlicers[slicer]->SetSlice((int)floor(x));
-            break;
-        }
-
-        for ( unsigned int i = 0; i < mSlicers.size(); i++)
-        {
-            if (i != (unsigned int)slicer && mSlicers[i]->GetImageActor()->GetVisibility()
-                    && mSlicers[i]->GetRenderWindow()->GetSize()[0] > 2
-                    && mSlicers[i]->GetRenderWindow()->GetSize()[1] > 2)
-            {
-                mSlicers[i]->SetCurrentPosition(mSlicers[slicer]->GetCurrentPosition()[0],
-                                                mSlicers[slicer]->GetCurrentPosition()[1],
-                                                mSlicers[slicer]->GetCurrentPosition()[2],
-                                                mSlicers[slicer]->GetTSlice());
-                mSlicers[i]->UpdateCursorPosition();
-                if (current) //do not display corner annotation if image is the one picked
-                {
-                    mSlicers[i]->SetCurrentPosition(-VTK_DOUBLE_MAX,-VTK_DOUBLE_MAX,
-                                                    -VTK_DOUBLE_MAX, mSlicers[slicer]->GetTSlice());
-                    mSlicers[i]->SetCursorColor(255,10,212);
-                }
-                else
-                {
-                    mSlicers[i]->SetCursorColor(150,10,282);
-                }
-                switch (mSlicers[i]->GetSliceOrientation())
-                {
-                case vtkImageViewer2::SLICE_ORIENTATION_XY:
-                    if (mSlicers[i]->GetSlice() == (int)floor(z))
-                        mSlicers[i]->Render();
-                    else
-                        mSlicers[i]->SetSlice((int)floor(z));
-                    break;
-
-                case vtkImageViewer2::SLICE_ORIENTATION_XZ:
-                    if (mSlicers[i]->GetSlice() == (int)floor(y))
-                        mSlicers[i]->Render();
-                    else
-                        mSlicers[i]->SetSlice((int)floor(y));
-                    break;
-
-                case vtkImageViewer2::SLICE_ORIENTATION_YZ:
-                    if (mSlicers[i]->GetSlice() == (int)floor(x))
-                        mSlicers[i]->Render();
-                    else
-                        mSlicers[i]->SetSlice((int)floor(x));
-                    break;
-                }
-                UpdateSlice(i);
-                UpdateTSlice(i);
-            }
+          if (mSlicers[i]->GetSlice() != (int)floor(x))
+            mSlicers[i]->SetSlice((int)floor(x));
+          break;
         }
+        
+        mSlicers[i]->Render();
+        
+        UpdateSlice(i);
+        UpdateTSlice(i);
+      }
     }
+  }
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::UpdateLinked(int slicer)
 {
-    double x = (mSlicers[slicer]->GetCurrentPosition()[0] - mSlicers[slicer]->GetInput()->GetOrigin()[0])
-               /mSlicers[slicer]->GetInput()->GetSpacing()[0];
-    double y = (mSlicers[slicer]->GetCurrentPosition()[1] - mSlicers[slicer]->GetInput()->GetOrigin()[1])
-               /mSlicers[slicer]->GetInput()->GetSpacing()[1];
-    double z = (mSlicers[slicer]->GetCurrentPosition()[2] - mSlicers[slicer]->GetInput()->GetOrigin()[2])
-               /mSlicers[slicer]->GetInput()->GetSpacing()[2];
-
-    if (x >= mSlicers[slicer]->GetInput()->GetWholeExtent()[0] &&
-            x <= mSlicers[slicer]->GetInput()->GetWholeExtent()[1] &&
-            y >= mSlicers[slicer]->GetInput()->GetWholeExtent()[2] &&
-            y <= mSlicers[slicer]->GetInput()->GetWholeExtent()[3] &&
-            z >= mSlicers[slicer]->GetInput()->GetWholeExtent()[4] &&
-            z <= mSlicers[slicer]->GetInput()->GetWholeExtent()[5])
-    {
-        for (std::list<std::string>::const_iterator i = mLinkedId.begin(); i != mLinkedId.end(); i++)
-        {
-            emit UpdateLinkManager(*i, slicer,mSlicers[slicer]->GetCurrentPosition()[0],
-                                   mSlicers[slicer]->GetCurrentPosition()[1],
-                                   mSlicers[slicer]->GetCurrentPosition()[2],mSlicers[slicer]->GetTSlice());
-        }
+  double x = (mSlicers[slicer]->GetCurrentPosition()[0] - mSlicers[slicer]->GetInput()->GetOrigin()[0])
+    /mSlicers[slicer]->GetInput()->GetSpacing()[0];
+  double y = (mSlicers[slicer]->GetCurrentPosition()[1] - mSlicers[slicer]->GetInput()->GetOrigin()[1])
+    /mSlicers[slicer]->GetInput()->GetSpacing()[1];
+  double z = (mSlicers[slicer]->GetCurrentPosition()[2] - mSlicers[slicer]->GetInput()->GetOrigin()[2])
+    /mSlicers[slicer]->GetInput()->GetSpacing()[2];
+
+  if (x >= mSlicers[slicer]->GetInput()->GetWholeExtent()[0] &&
+      x <= mSlicers[slicer]->GetInput()->GetWholeExtent()[1] &&
+      y >= mSlicers[slicer]->GetInput()->GetWholeExtent()[2] &&
+      y <= mSlicers[slicer]->GetInput()->GetWholeExtent()[3] &&
+      z >= mSlicers[slicer]->GetInput()->GetWholeExtent()[4] &&
+      z <= mSlicers[slicer]->GetInput()->GetWholeExtent()[5]) {
+    for (std::list<std::string>::const_iterator i = mLinkedId.begin(); i != mLinkedId.end(); i++) {
+      emit UpdateLinkManager(*i, slicer,mSlicers[slicer]->GetCurrentPosition()[0],
+                             mSlicers[slicer]->GetCurrentPosition()[1],
+                             mSlicers[slicer]->GetCurrentPosition()[2],mSlicers[slicer]->GetTSlice());
     }
+  }
 }
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+void vvSlicerManager::UpdateLinkedNavigation(vvSlicer *refSlicer, bool bPropagate)
+{
+  vtkCamera *refCam = refSlicer->GetRenderer()->GetActiveCamera();
+  double refPosition[3], refFocal[3];
+  refCam->GetPosition(refPosition);
+  refCam->GetFocalPoint(refFocal);
+  
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    vtkCamera *camera = mSlicers[i]->GetRenderer()->GetActiveCamera();
+    camera->SetParallelScale(refCam->GetParallelScale());
+
+    double position[3], focal[3];
+    camera->GetPosition(position);
+    camera->GetFocalPoint(focal);
+
+    if(refSlicer->GetSliceOrientation()==mSlicers[i]->GetSliceOrientation()) {
+      for(int i=0; i<3; i++) {
+        position[i] = refPosition[i];
+        focal[i]    = refFocal[i];
+      }
+    }
+
+    if(refSlicer->GetSliceOrientation()==vtkImageViewer2::SLICE_ORIENTATION_XY) {
+      if(mSlicers[i]->GetSliceOrientation()==vtkImageViewer2::SLICE_ORIENTATION_XZ) {
+        position[0] = refPosition[0];
+        focal[0]    = refFocal[0];
+      }
+      if(mSlicers[i]->GetSliceOrientation()==vtkImageViewer2::SLICE_ORIENTATION_YZ) {
+        position[1] = refPosition[1];
+        focal[1]    = refFocal[1];
+      }
+    }
+
+    if(refSlicer->GetSliceOrientation()==vtkImageViewer2::SLICE_ORIENTATION_XZ) {
+      if(mSlicers[i]->GetSliceOrientation()==vtkImageViewer2::SLICE_ORIENTATION_YZ) {
+        position[2] = refPosition[2];
+        focal[2]    = refFocal[2];
+      }
+      if(mSlicers[i]->GetSliceOrientation()==vtkImageViewer2::SLICE_ORIENTATION_XY) {
+        position[0] = refPosition[0];
+        focal[0]    = refFocal[0];
+      }
+    }
+
+    if(refSlicer->GetSliceOrientation()==vtkImageViewer2::SLICE_ORIENTATION_YZ) {
+      if(mSlicers[i]->GetSliceOrientation()==vtkImageViewer2::SLICE_ORIENTATION_XY) {
+        position[1] = refPosition[1];
+        focal[1]    = refFocal[1];
+      }
+      if(mSlicers[i]->GetSliceOrientation()==vtkImageViewer2::SLICE_ORIENTATION_XZ) {
+        position[2] = refPosition[2];
+        focal[2]    = refFocal[2];
+      }
+    }
+
+    camera->SetFocalPoint(focal);
+    camera->SetPosition(position);
+  
+    //Fix for bug #243
+    mSlicers[i]->ForceUpdateDisplayExtent();
+  }
+  
+  Render();
+  if(bPropagate)
+    for (std::list<std::string>::const_iterator i = mLinkedId.begin(); i != mLinkedId.end(); i++)
+      emit UpdateLinkedNavigation(*i, this, refSlicer);
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
 double vvSlicerManager::GetColorWindow()
 {
-    if (mSlicers.size())
-        return mSlicers[0]->GetColorWindow();
-    return -1;
+  if (mSlicers.size())
+    return mSlicers[0]->GetColorWindow();
+  return -1;
 }
+//----------------------------------------------------------------------------
 
+
+//----------------------------------------------------------------------------
 double vvSlicerManager::GetColorLevel()
 {
-    if (mSlicers.size())
-        return mSlicers[0]->GetColorLevel();
-    return -1;
+  if (mSlicers.size())
+    return mSlicers[0]->GetColorLevel();
+  return -1;
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+double vvSlicerManager::GetOverlayColorWindow() const
+{
+  if (mSlicers.size())
+    return mSlicers[0]->GetOverlayColorWindow();
+  return -1;
 }
+//----------------------------------------------------------------------------
 
+//----------------------------------------------------------------------------
+double vvSlicerManager::GetOverlayColorLevel() const
+{
+  if (mSlicers.size())
+    return mSlicers[0]->GetOverlayColorLevel();
+  return -1;
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+bool vvSlicerManager::GetLinkOverlayWindowLevel() const
+{
+  if (mSlicers.size())
+    return mSlicers[0]->GetLinkOverlayWindowLevel();
+  return -1;
+}
+//----------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvSlicerManager::ResetTransformationToIdentity(const std::string actorType)
+{
+  if(actorType == "image")
+    this->GetImage()->GetTransform()->Identity();
+  else if(actorType == "overlay")
+    this->GetSlicer(0)->GetOverlay()->GetTransform()->Identity();
+  else if(actorType == "fusion")
+    this->GetSlicer(0)->GetFusion()->GetTransform()->Identity();
+  else if(actorType == "vf")
+    this->GetVF()->GetTransform()->Identity();
+  else
+    return;
+
+  for(int i=0; i< this->GetNumberOfSlicers(); i++){
+    this->GetSlicer(i)->ForceUpdateDisplayExtent();
+    this->GetSlicer(i)->ResetCamera();
+    this->GetSlicer(i)->Render();
+  }
+}
+//------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
 void vvSlicerManager::Render()
 {
-    for ( unsigned int i = 0; i < mSlicers.size(); i++)
-    {
-        mSlicers[i]->Render();
-    }
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->Render();
+  }
 }
+//----------------------------------------------------------------------------
 
+
+//----------------------------------------------------------------------------
 void vvSlicerManager::GenerateDefaultLookupTable()
 {
-    SetPreset(mPreset);
-    SetColorMap(mColorMap);
+  SetPreset(mPreset);
+  SetColorMap(mColorMap);
 }
+//----------------------------------------------------------------------------
 
+
+//----------------------------------------------------------------------------
 void vvSlicerManager::Reload()
 {
-    mReader->Update(mType);
-    mImage=mReader->GetOutput();
-    for ( unsigned int i = 0; i < mSlicers.size(); i++)
-    {
-        mSlicers[i]->SetImage(mImage);
-    }
+  mReader->Update(mType);
+  mImage=mReader->GetOutput();
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetImage(mImage);
+  }
 }
+//----------------------------------------------------------------------------
 
+
+//----------------------------------------------------------------------------
 void vvSlicerManager::ReloadFusion()
 {
-    mFusionReader->Update();
-    for ( unsigned int i = 0; i < mSlicers.size(); i++)
-    {
-        mSlicers[i]->SetFusion(mFusionReader->GetOutput());
-        mSlicers[i]->Render();
-    }
+  mFusionReader->Update();
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetFusion(mFusionReader->GetOutput());
+    mSlicers[i]->Render();
+  }
 }
+//----------------------------------------------------------------------------
 
+
+//----------------------------------------------------------------------------
 void vvSlicerManager::ReloadOverlay()
 {
-    mOverlayReader->Update();
-    for ( unsigned int i = 0; i < mSlicers.size(); i++)
-    {
-        mSlicers[i]->SetOverlay(mOverlayReader->GetOutput());
-        mSlicers[i]->Render();
-    }
+  mOverlayReader->Update();
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetOverlay(mOverlayReader->GetOutput());
+    mSlicers[i]->Render();
+  }
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::ReloadVF()
 {
-    mVectorReader->Update(VECTORFIELD); //deletes the old images through the VF::Init() function
-    mVF=mVectorReader->GetOutput();
-    for ( unsigned int i = 0; i < mSlicers.size(); i++)
-    {
-        mSlicers[i]->SetVF(mVF);
-        mSlicers[i]->Render();
-    }
+  mVectorReader->Update(vvImageReader::VECTORFIELD); //deletes the old images through the VF::Init() function
+  mVF=mVectorReader->GetOutput();
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetVF(mVF);
+    mSlicers[i]->Render();
+  }
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::RemoveActor(const std::string& actor_type, int overlay_index)
 {
-    for (unsigned int i = 0; i < mSlicers.size();i++)
-    {
-        mSlicers[i]->RemoveActor(actor_type,overlay_index);
-    }
-    if (actor_type=="vector")
-    {
-        mVF=NULL;
-        if (mVectorReader) {
-            delete mVectorReader;
-            mVectorReader=NULL;
-        }
-    }
+  if (actor_type =="overlay")
+    mOverlayReader = NULL;
+
+  if (actor_type =="fusion")
+    mFusionReader = NULL;
+
+  for (unsigned int i = 0; i < mSlicers.size(); i++)
+    mSlicers[i]->RemoveActor(actor_type,overlay_index);
+
+  if (actor_type=="vector") {
+    mVF=NULL;
+    mVectorReader=NULL;
+  }
 }
+//----------------------------------------------------------------------------
 
+
+//----------------------------------------------------------------------------
 void vvSlicerManager::RemoveActors()
 {
-    ///This method leaks a few objects. See RemoveActor for what a correct implementation would look like
-    for ( unsigned int i = 0; i < mSlicers.size(); i++)
-    {
-        mSlicers[i]->SetDisplayMode(0);
-        mSlicers[i]->GetRenderer()->RemoveActor(mSlicers[i]->GetImageActor());
-    }
+  ///This method leaks a few objects. See RemoveActor for what a
+  ///correct implementation would look like
+  //DS -> probably due to the reader (now released in the
+  //RemoveActor() function. (I hope)
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetDisplayMode(0);
+    mSlicers[i]->GetRenderer()->RemoveActor(mSlicers[i]->GetImageActor());
+  }
 }
+//----------------------------------------------------------------------------
 
+
+//----------------------------------------------------------------------------
 void vvSlicerManager::UpdateInfoOnCursorPosition(int slicer)
 {
-//  int view = mSlicers[slicer]->GetSliceOrientation();
-//  int slice = mSlicers[slicer]->GetSlice();
-    double x = mSlicers[slicer]->GetCursorPosition()[0];
-    double y = mSlicers[slicer]->GetCursorPosition()[1];
-    double z = mSlicers[slicer]->GetCursorPosition()[2];
-    double X = (x - mSlicers[slicer]->GetInput()->GetOrigin()[0])/
-        mSlicers[slicer]->GetInput()->GetSpacing()[0];
-    double Y = (y - mSlicers[slicer]->GetInput()->GetOrigin()[1])/
-        mSlicers[slicer]->GetInput()->GetSpacing()[1];
-    double Z = (z - mSlicers[slicer]->GetInput()->GetOrigin()[2])/
-        mSlicers[slicer]->GetInput()->GetSpacing()[2];
-    double value = -VTK_DOUBLE_MAX;
-    int displayVec = 0;
-    double xVec=0, yVec=0, zVec=0, valueVec=0;
-    int displayOver = 0;
-    int displayFus = 0;
-    double valueOver=0, valueFus=0;
-    if (X >= mSlicers[slicer]->GetInput()->GetWholeExtent()[0] &&
-            X <= mSlicers[slicer]->GetInput()->GetWholeExtent()[1] &&
-            Y >= mSlicers[slicer]->GetInput()->GetWholeExtent()[2] &&
-            Y <= mSlicers[slicer]->GetInput()->GetWholeExtent()[3] &&
-            Z >= mSlicers[slicer]->GetInput()->GetWholeExtent()[4] &&
-            Z <= mSlicers[slicer]->GetInput()->GetWholeExtent()[5])
-    {
-        value = mSlicers[slicer]->GetInput()->GetScalarComponentAsDouble(
-                (int)floor(X),
-                (int)floor(Y),
-                (int)floor(Z),0);
-        if (mSlicers[slicer]->GetVFActor() && mSlicers[slicer]->GetVFActor()->GetVisibility())
-        {
-            displayVec = 1;
-            unsigned int currentTime = mSlicers[slicer]->GetTSlice();
-            vtkImageData *vf = NULL;
-
-            if (mSlicers[slicer]->GetVF()->GetVTKImages().size() > currentTime)
-                vf = mSlicers[slicer]->GetVF()->GetVTKImages()[currentTime];
-            else
-                vf = mSlicers[slicer]->GetVF()->GetVTKImages()[0];
-
-            if (vf)
-            {
-                double Xvf = (x - vf->GetOrigin()[0])/ vf->GetSpacing()[0];
-                double Yvf = (y - vf->GetOrigin()[1])/ vf->GetSpacing()[1];
-                double Zvf = (z - vf->GetOrigin()[2])/ vf->GetSpacing()[2];
-                xVec = vf->GetScalarComponentAsDouble( (int)floor(Xvf), (int)floor(Yvf), (int)floor(Zvf),0);
-                yVec = vf->GetScalarComponentAsDouble( (int)floor(Xvf), (int)floor(Yvf), (int)floor(Zvf),1);
-                zVec = vf->GetScalarComponentAsDouble( (int)floor(Xvf), (int)floor(Yvf), (int)floor(Zvf),2);
-                valueVec = sqrt(xVec*xVec + yVec*yVec + zVec*zVec);
-            }
-        }
-        if (mSlicers[slicer]->GetOverlayActor() && mSlicers[slicer]->GetOverlayActor()->GetVisibility())
-        {
-            displayOver = 1;
-            double Xover = (x - mSlicers[slicer]->GetOverlay()->GetOrigin()[0])
-                /mSlicers[slicer]->GetOverlay()->GetSpacing()[0];
-            double Yover = (y - mSlicers[slicer]->GetOverlay()->GetOrigin()[1])
-                /mSlicers[slicer]->GetOverlay()->GetSpacing()[1];
-            double Zover = (z - mSlicers[slicer]->GetOverlay()->GetOrigin()[2])
-                /mSlicers[slicer]->GetOverlay()->GetSpacing()[2];
-            if (Xover >= mSlicers[slicer]->GetOverlayMapper()->GetInput()->GetWholeExtent()[0] &&
-                    Xover <= mSlicers[slicer]->GetOverlayMapper()->GetInput()->GetWholeExtent()[1] &&
-                    Yover >= mSlicers[slicer]->GetOverlayMapper()->GetInput()->GetWholeExtent()[2] &&
-                    Yover <= mSlicers[slicer]->GetOverlayMapper()->GetInput()->GetWholeExtent()[3] &&
-                    Zover >= mSlicers[slicer]->GetOverlayMapper()->GetInput()->GetWholeExtent()[4] &&
-                    Zover <= mSlicers[slicer]->GetOverlayMapper()->GetInput()->GetWholeExtent()[5])
-            {
-                valueOver = static_cast<vtkImageData*>(mSlicers[slicer]->GetOverlayMapper()->GetInput())->
-                    GetScalarComponentAsDouble(
-                            (int)floor(Xover),
-                            (int)floor(Yover),
-                            (int)floor(Zover),0);
-            }
-        }
-        if (mSlicers[slicer]->GetFusionActor() && mSlicers[slicer]->GetFusionActor()->GetVisibility())
-        {
-            displayFus = 1;
-            double Xfus = (x - mSlicers[slicer]->GetFusion()->GetOrigin()[0])
-                /mSlicers[slicer]->GetFusion()->GetSpacing()[0];
-            double Yfus = (y - mSlicers[slicer]->GetFusion()->GetOrigin()[1])
-                /mSlicers[slicer]->GetFusion()->GetSpacing()[1];
-            double Zfus = (z - mSlicers[slicer]->GetFusion()->GetOrigin()[2])
-                /mSlicers[slicer]->GetFusion()->GetSpacing()[2];
-            if (Xfus >= mSlicers[slicer]->GetFusionMapper()->GetInput()->GetWholeExtent()[0] &&
-                    Xfus <= mSlicers[slicer]->GetFusionMapper()->GetInput()->GetWholeExtent()[1] &&
-                    Yfus >= mSlicers[slicer]->GetFusionMapper()->GetInput()->GetWholeExtent()[2] &&
-                    Yfus <= mSlicers[slicer]->GetFusionMapper()->GetInput()->GetWholeExtent()[3] &&
-                    Zfus >= mSlicers[slicer]->GetFusionMapper()->GetInput()->GetWholeExtent()[4] &&
-                    Zfus <= mSlicers[slicer]->GetFusionMapper()->GetInput()->GetWholeExtent()[5])
-            {
-                valueFus = static_cast<vtkImageData*>(mSlicers[slicer]->GetFusionMapper()->GetInput())->
-                    GetScalarComponentAsDouble(
-                            (int)floor(Xfus),
-                            (int)floor(Yfus),
-                            (int)floor(Zfus),0);
-            }
-        }
-        emit UpdatePosition(mSlicers[slicer]->GetCursorVisibility(),
-                x,y,z,X,Y,Z,value);
-        emit UpdateVector(displayVec,xVec, yVec, zVec, valueVec);
-        emit UpdateOverlay(displayOver,valueOver,value);
-        emit UpdateFusion(displayFus,valueFus);
-        for (unsigned int i = 0; i < mSlicers.size(); i++)
-        {
-            if (mSlicers[i]->GetImageActor()->GetVisibility() == 1)
-                emit UpdateWindows(i,mSlicers[i]->GetSliceOrientation(),mSlicers[i]->GetSlice());
-            else
-                emit UpdateWindows(i,-1,-1);
-        }
+  //  int view = mSlicers[slicer]->GetSliceOrientation();
+  //  int slice = mSlicers[slicer]->GetSlice();
+  double x = mSlicers[slicer]->GetCursorPosition()[0];
+  double y = mSlicers[slicer]->GetCursorPosition()[1];
+  double z = mSlicers[slicer]->GetCursorPosition()[2];
+  double X = (x - mSlicers[slicer]->GetInput()->GetOrigin()[0])/
+    mSlicers[slicer]->GetInput()->GetSpacing()[0];
+  double Y = (y - mSlicers[slicer]->GetInput()->GetOrigin()[1])/
+    mSlicers[slicer]->GetInput()->GetSpacing()[1];
+  double Z = (z - mSlicers[slicer]->GetInput()->GetOrigin()[2])/
+    mSlicers[slicer]->GetInput()->GetSpacing()[2];
+  double value = -VTK_DOUBLE_MAX;
+  int displayVec = 0;
+  double xVec=0, yVec=0, zVec=0, valueVec=0;
+  int displayOver = 0;
+  int displayFus = 0;
+  double valueOver=0, valueFus=0;
+  if (X >= mSlicers[slicer]->GetInput()->GetWholeExtent()[0] &&
+      X <= mSlicers[slicer]->GetInput()->GetWholeExtent()[1] &&
+      Y >= mSlicers[slicer]->GetInput()->GetWholeExtent()[2] &&
+      Y <= mSlicers[slicer]->GetInput()->GetWholeExtent()[3] &&
+      Z >= mSlicers[slicer]->GetInput()->GetWholeExtent()[4] &&
+      Z <= mSlicers[slicer]->GetInput()->GetWholeExtent()[5]) {
+    value = this->GetScalarComponentAsDouble(mSlicers[slicer]->GetInput(), X, Y, Z);
+
+    if (mSlicers[slicer]->GetVFActor() ) {
+      displayVec = 1;
+      unsigned int currentTime = mSlicers[slicer]->GetTSlice();
+      vtkImageData *vf = NULL;
+
+      if (mSlicers[slicer]->GetVF()->GetVTKImages().size() > currentTime)
+        vf = mSlicers[slicer]->GetVF()->GetVTKImages()[currentTime];
+      else
+        vf = mSlicers[slicer]->GetVF()->GetVTKImages()[0];
+
+      if (vf) {
+        double Xvf = (x - vf->GetOrigin()[0])/ vf->GetSpacing()[0];
+        double Yvf = (y - vf->GetOrigin()[1])/ vf->GetSpacing()[1];
+        double Zvf = (z - vf->GetOrigin()[2])/ vf->GetSpacing()[2];
+        xVec = this->GetScalarComponentAsDouble( vf, Xvf, Yvf, Zvf, 0);
+        yVec = this->GetScalarComponentAsDouble( vf, Xvf, Yvf, Zvf, 1);
+        zVec = this->GetScalarComponentAsDouble( vf, Xvf, Yvf, Zvf, 2);
+        valueVec = sqrt(xVec*xVec + yVec*yVec + zVec*zVec);
+      }
+    }
+    if (mSlicers[slicer]->GetOverlayActor() ) {
+      displayOver = 1;
+      vtkImageData *overlay = dynamic_cast<vtkImageData*>(mSlicers[slicer]->GetOverlayMapper()->GetInput());
+      double Xover = (x - overlay->GetOrigin()[0]) / overlay->GetSpacing()[0];
+      double Yover = (y - overlay->GetOrigin()[1]) / overlay->GetSpacing()[1];
+      double Zover = (z - overlay->GetOrigin()[2]) / overlay->GetSpacing()[2];
+      valueOver = this->GetScalarComponentAsDouble(overlay, Xover, Yover, Zover);
+    }
+    if (mSlicers[slicer]->GetFusionActor() ) {
+      displayFus = 1;
+      vtkImageData *fusion = dynamic_cast<vtkImageData*>(mSlicers[slicer]->GetFusionMapper()->GetInput());
+      double Xover = (x - fusion->GetOrigin()[0]) / fusion->GetSpacing()[0];
+      double Yover = (y - fusion->GetOrigin()[1]) / fusion->GetSpacing()[1];
+      double Zover = (z - fusion->GetOrigin()[2]) / fusion->GetSpacing()[2];
+      valueFus = this->GetScalarComponentAsDouble(fusion, Xover, Yover, Zover);
     }
+    emit UpdatePosition(mSlicers[slicer]->GetCursorVisibility(),
+                        x,y,z,X,Y,Z,value);
+    emit UpdateVector(displayVec,xVec, yVec, zVec, valueVec);
+    emit UpdateOverlay(displayOver,valueOver,value);
+    emit UpdateFusion(displayFus,valueFus);
+  }
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::Activated()
 {
-    emit currentImageChanged(mId);
+  emit currentImageChanged(mId);
 }
+//----------------------------------------------------------------------------
+
+
+//----------------------------------------------------------------------------
+void vvSlicerManager::Picked()
+{
+  emit currentPickedImageChanged(mId);
+}
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::UpdateWindowLevel()
 {
-    emit WindowLevelChanged(mSlicers[0]->GetColorWindow(),mSlicers[0]->GetColorLevel(),mPreset,mColorMap);
+  emit WindowLevelChanged();
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::UpdateSlice(int slicer)
 {
-    emit UpdateSlice(slicer, mSlicers[slicer]->GetSlice());
+  if (mPreviousSlice[slicer] == mSlicers[slicer]->GetSlice()) {
+    //DD("============= NOTHING");
+    return;
+  }
+  //std::cout << "vvSlicerManager::UpdateSlice " << slicer << " " << mSlicers[slicer]->GetSlice() << std::endl;
+  emit UpdateSlice(slicer, mSlicers[slicer]->GetSlice());
+  mSlicers[slicer]->Render(); // DS <-- I add this, this could/must be the only Render ...
+  mPreviousSlice[slicer] = mSlicers[slicer]->GetSlice();
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 void vvSlicerManager::UpdateTSlice(int slicer)
 {
-    emit UpdateTSlice(slicer,mSlicers[0]->GetTSlice());
+  int slice = mSlicers[slicer]->GetSlice();
+  int tslice = mSlicers[slicer]->GetTSlice();
+  if (mPreviousSlice[slicer] == slice) {
+    if (mPreviousTSlice[slicer] == tslice) {
+      //      DD("************** NOTHING ***********");
+      return;
+    }
+  }
+  mPreviousSlice[slicer] = slice;
+  mPreviousTSlice[slicer] = tslice;
+  //std::cout << "vvSlicerManager::UpdateTSlice " << slicer << " " << tslice << std::endl;
+  emit UpdateTSlice(slicer, tslice);
 }
+//----------------------------------------------------------------------------
 
+
+//----------------------------------------------------------------------------
 void vvSlicerManager::UpdateSliceRange(int slicer)
 {
-    emit UpdateSliceRange(slicer,
-                          mSlicers[slicer]->GetSliceRange()[0], mSlicers[slicer]->GetSliceRange()[1],
-                          0,mSlicers[slicer]->GetTMax());
+  emit UpdateSliceRange(slicer,
+                        mSlicers[slicer]->GetSliceRange()[0], mSlicers[slicer]->GetSliceRange()[1],
+                        0,mSlicers[slicer]->GetTMax());
 }
+//----------------------------------------------------------------------------
 
+
+//----------------------------------------------------------------------------
 void vvSlicerManager::SetPreset(int preset)
 {
+  //vtkLookupTable* LUT = static_cast<vtkLookupTable*>(mSlicers[0]->GetWindowLevel()->GetLookupTable());
+  double window = mSlicers[0]->GetColorWindow();
+  double level = mSlicers[0]->GetColorLevel();
+
+  std::string component_type=mImage->GetScalarTypeAsITKString();
+  switch (preset) {
+  case 0:
     double range[2];
     mImage->GetScalarRange(range);
-    //vtkLookupTable* LUT = static_cast<vtkLookupTable*>(mSlicers[0]->GetWindowLevel()->GetLookupTable());
-    double window = mSlicers[0]->GetColorWindow();
-    double level = mSlicers[0]->GetColorLevel();
+    window = range[1] - range[0];
+    level = (range[1] + range[0])* 0.5;
+    break;
+  case 1:
+    window = 2000;
+    level = 0;
+    break;
+  case 2:
+    window = 400;
+    level = 20;
+    break;
+  case 3:
+    window = 1500;
+    level = -500;
+    break;
+  case 4:
+    window = 1000;
+    level = 500;
+    break;
+  case 5:
+    window = 1;
+    level = 0.5;
+    break;
+  case 6:
+    break;
+  case 7:
+    window=1.;
+    level=0.;
+    break;
+  }
+  mPreset = preset;
+  this->SetColorWindow(window);
+  this->SetColorLevel(level);
+
+  //if (LUT)
+  //{
+  //    SetColorMap(-1);
+  //}
+}
+//----------------------------------------------------------------------------
 
-    std::string component_type=mImage->GetScalarTypeAsString();
-    switch (preset)
-    {
-    case 0:
-        if (component_type == "unsigned_char")
-        {
-            window = 255;
-            level = 127;
-        }
-        else if (component_type == "short")
-        {
-            window = 2000;
-            level = 0;
-        }
-        else
-        {
-            window = range[1] - range[0];
-            level = (range[1] + range[0])* 0.5;
-        }
-        break;
-    case 1:
-        window = 2000;
-        level = 0;
-        break;
-    case 2:
-        window = 350;
-        level = 60;
-        break;
-    case 3:
-        window = 1500;
-        level = -500;
-        break;
-    case 4:
-        window = 1000;
-        level = 500;
-        break;
-    case 5:
-        window = 1;
-        level = 0.5;
-        break;
-    case 6:
-        break;
-    case 7:
-        window=1.;
-        level=0.;
-        break;
-    }
-    mPreset = preset;
-    this->SetColorWindow(window);
-    this->SetColorLevel(level);
 
-    //if (LUT)
-    //{
-    //    SetColorMap(-1);
-    //}
-}
-void vvSlicerManager::SetColorMap()
+//----------------------------------------------------------------------------
+void vvSlicerManager::SetLocalColorWindowing(const int slicer, const bool bCtrlKey)
 {
-    SetColorMap(mColorMap);
+  double min, max;
+  int t = this->mSlicers[slicer]->GetTSlice();
+  if(bCtrlKey && this->mSlicers[slicer]->GetFusion()) {
+    this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, this->mSlicers[slicer]->GetFusion()->GetVTKImages()[t]);
+    this->SetFusionWindow(max-min);
+    this->SetFusionLevel(0.5*(min+max));
+    this->SetColorMap(mColorMap);
+  }
+  else if(bCtrlKey && this->mSlicers[slicer]->GetOverlay()) {
+    this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, this->mSlicers[slicer]->GetOverlay()->GetVTKImages()[t]);
+    if(this->mSlicers[slicer]->GetLinkOverlayWindowLevel()){
+      this->SetColorWindow(max-min);
+      this->SetColorLevel(0.5*(min+max));
+    } else {
+      this->SetOverlayColorWindow(max-min);
+      this->SetOverlayColorLevel(0.5*(min+max));
+    }
+  }
+  else {
+    this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, this->mSlicers[slicer]->GetInput());
+    this->SetColorWindow(max-min);
+    this->SetColorLevel(0.5*(min+max));
+    this->SetPreset(6);
+  }
+  this->Render();
+  this->UpdateWindowLevel();
 }
+//----------------------------------------------------------------------------
 
+
+//----------------------------------------------------------------------------
 void vvSlicerManager::SetColorMap(int colormap)
 {
-    double range[2];
-    range[0] = mSlicers[0]->GetInput()->GetScalarRange()[0];
-    range[1] = mSlicers[0]->GetInput()->GetScalarRange()[1];
-
-    double window = mSlicers[0]->GetWindowLevel()->GetWindow();
-    double level = mSlicers[0]->GetWindowLevel()->GetLevel();
-
-    vtkLookupTable* LUT = static_cast<vtkLookupTable*>(mSlicers[0]->GetWindowLevel()->GetLookupTable());
-    switch (colormap)
+  double range[2];
+  range[0] = mSlicers[0]->GetInput()->GetScalarRange()[0];
+  range[1] = mSlicers[0]->GetInput()->GetScalarRange()[1];
+
+  double window = mSlicers[0]->GetWindowLevel()->GetWindow();
+  double level = mSlicers[0]->GetWindowLevel()->GetLevel();
+
+  vtkLookupTable* LUT = static_cast<vtkLookupTable*>(mSlicers[0]->GetWindowLevel()->GetLookupTable());
+  switch (colormap) {
+  case -1:
+    break;
+  case 0:
+    LUT = NULL;
+    break;
+  case 1:
+    if (LUT == NULL)
+      LUT = vtkLookupTable::New();
+    LUT->SetValueRange(0,1);
+    LUT->SetSaturationRange(1,1);
+    LUT->SetHueRange(0,0.18);
+    break;
+  case 2:
+    if (LUT == NULL)
+      LUT = vtkLookupTable::New();
+    LUT->SetValueRange(0,1);
+    LUT->SetSaturationRange(1,1);
+    LUT->SetHueRange(0.4,0.80);
+    break;
+  case 3:
+    if (LUT == NULL)
+      LUT = vtkLookupTable::New();
+    LUT->SetValueRange(0.5,1);
+    LUT->SetSaturationRange(1,1);
+    LUT->SetHueRange(0.666,0);
+    break;
+  case 4:
+    if (LUT == NULL)
+      LUT = vtkLookupTable::New();
+    LUT->SetValueRange(0,1);
+    LUT->SetSaturationRange(1,1);
+    LUT->SetHueRange(0,1);
+    break;
+  case 5:
+    if (LUT == NULL)
+      LUT = vtkLookupTable::New();
+    LUT->SetValueRange(0.,1);
+    LUT->SetSaturationRange(1,1);
+    LUT->SetHueRange(1,0.1);
+    //LUT->SetRampToLinear();
+    break;
+  }
+  if (LUT) {
+    LUT->SetTableRange(level-fabs(window)/2,level+fabs(window)/2);
+    LUT->Build();
+  }
+  vtkWindowLevelLookupTable* fusLUT = NULL;
+  if (mSlicers[0]->GetFusion()) { // && mFusionColorMap >= 0) {
+    fusLUT = vtkWindowLevelLookupTable::New();
+    double fusRange [2];
+    fusRange[0] = mFusionLevel - mFusionWindow/2;
+    fusRange[1] = mFusionLevel + mFusionWindow/2;
+    double* frange = mFusionReader->GetOutput()->GetVTKImages()[0]->GetScalarRange();
+    fusLUT->SetTableRange(frange);
+    fusLUT->SetValueRange(1,1);
+    fusLUT->SetSaturationRange(1,1);
+    fusLUT->SetAlphaRange(1, 1);
+    fusLUT->SetWindow(mFusionWindow);
+    fusLUT->SetLevel(mFusionLevel);
+    if (mFusionColorMap == 1)
+      fusLUT->SetHueRange(0,0.18);
+    else if (mFusionColorMap == 2)
+      fusLUT->SetHueRange(0.4,0.80);
+    else if (mFusionColorMap == 3)
     {
-    case -1:
-        break;
-    case 0:
-        LUT = NULL;
-        break;
-    case 1:
-        if (LUT == NULL)
-            LUT = vtkLookupTable::New();
-        LUT->SetValueRange(0,1);
-        LUT->SetSaturationRange(1,1);
-        LUT->SetHueRange(0,0.18);
-        break;
-    case 2:
-        if (LUT == NULL)
-            LUT = vtkLookupTable::New();
-        LUT->SetValueRange(0,1);
-        LUT->SetSaturationRange(1,1);
-        LUT->SetHueRange(0.4,0.80);
-        break;
-    case 3:
-        if (LUT == NULL)
-            LUT = vtkLookupTable::New();
-        LUT->SetValueRange(0,1);
-        LUT->SetSaturationRange(1,1);
-        LUT->SetHueRange(0,1);
-        break;
-    case 5:
-        if (LUT == NULL)
-            LUT = vtkLookupTable::New();
-        LUT->SetValueRange(0.,1);
-        LUT->SetSaturationRange(1,1);
-        LUT->SetHueRange(1,0.1);
-        //LUT->SetRampToLinear();
-        break;
+      fusLUT->SetHueRange(0.666, 0);
+      fusLUT->SetValueRange(0.5, 1);
     }
-    if (LUT)
+    else if (mFusionColorMap == 4)
+      fusLUT->SetHueRange(0,1);
+    else if (mFusionColorMap <= 0)
     {
-        LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
-        LUT->Build();
+      fusLUT->SetValueRange(0,1);
+      fusLUT->SetSaturationRange(0,0);
     }
-    vtkLookupTable* fusLUT = NULL;
-    if (mSlicers[0]->GetFusion())
-    {
-        fusLUT = vtkLookupTable::New();
-        double fusRange [2];
-        fusRange[0] = mFusionLevel - mFusionWindow/2;
-        fusRange[1] = mFusionLevel + mFusionWindow/2;
-        fusLUT->SetTableRange(fusRange[0],fusRange[1]);
-        fusLUT->SetValueRange(1,1);
-        fusLUT->SetSaturationRange(1,1);
-        if (mFusionColorMap == 1)
-            fusLUT->SetHueRange(0,0.18);
-        else if (mFusionColorMap == 2)
-            fusLUT->SetHueRange(0.4,0.80);
-        else if (mFusionColorMap == 3)
-            fusLUT->SetHueRange(0,1);
-        fusLUT->Build();
-        if (mFusionColorMap == 0)
-            fusLUT = NULL;
+    
+    fusLUT->ForceBuild();
+    double v[4];
+    
+    // set color table transparency
+    double range_end = frange[0] + (double)mFusionThresOpacity*(frange[1] - frange[0])/100;
+    double curr_value = frange[0];
+    int nvalues = fusLUT->GetNumberOfTableValues();
+    //for (double i = frange[0]; i <= alpha_range_end; i++) {
+    for (double i = 0; curr_value < range_end; i++) {  
+      fusLUT->GetTableValue(i, v);
+      v[3] = 0;
+      fusLUT->SetTableValue(i, v);
+      curr_value += (frange[1] - frange[0])/nvalues;
     }
-    for ( unsigned int i = 0; i < mSlicers.size(); i++) {
-        if (mSlicers[i]->GetOverlay() && mSlicers[i]->GetOverlayActor()->GetVisibility()) {
-            vtkLookupTable* supLUT = vtkLookupTable::New();
-            supLUT->SetTableRange(range[0],range[1]);
-            supLUT->SetValueRange(1,1);
-            supLUT->SetSaturationRange(1,1);
-            supLUT->SetHueRange(double(mOverlayColor)/360,double(mOverlayColor)/360);
-            supLUT->Build();
-            vtkLookupTable* invLUT = vtkLookupTable::New();
-            invLUT->SetTableRange(range[0],range[1]);
-            invLUT->SetValueRange(1,1);
-            invLUT->SetSaturationRange(1,1);
-            invLUT->SetHueRange(double((mOverlayColor+180)%360)/360,double((mOverlayColor+180)%360)/360);
-            invLUT->Build();
-            dynamic_cast<vvImageMapToWLColors*>(mSlicers[i]->GetWindowLevel())
-                ->SetWindowLevelMode(true);
-            mSlicers[i]->GetWindowLevel()->SetLookupTable(supLUT);
-            mSlicers[i]->GetOverlayMapper()->SetLookupTable(invLUT);
-            invLUT->Delete();
-            supLUT->Delete();
-        }
-        else if (mSlicers[i]->GetOverlay())
-        {
-            //dynamic_cast<vvImageMapToWLColors*>(mSlicers[i]->GetWindowLevel())
-                //->SetWindowLevelMode(false);
-            mSlicers[i]->GetWindowLevel()->SetLookupTable(LUT);
-        }
-        else
-        {
-            mSlicers[i]->GetWindowLevel()->SetLookupTable(LUT);
-        }
-        if (mSlicers[i]->GetFusion() && mSlicers[i]->GetFusionActor()->GetVisibility())
-        {
-            mSlicers[i]->GetFusionActor()->SetOpacity(double(mFusionOpacity)/100);
-            mSlicers[i]->GetFusionMapper()->SetLookupTable(fusLUT);
-        }
+  }
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    
+    if (mSlicers[i]->GetOverlay()) {
+      vtkLookupTable* supLUT = vtkLookupTable::New();
+      supLUT->SetTableRange(range[0],range[1]);
+      supLUT->SetValueRange(1,1);
+      supLUT->SetSaturationRange(1,1);
+      supLUT->SetHueRange(double(mOverlayColor)/360,double(mOverlayColor)/360);
+      supLUT->Build();
+      vtkLookupTable* invLUT = vtkLookupTable::New();
+      invLUT->SetTableRange(range[0],range[1]);
+      invLUT->SetValueRange(1,1);
+      invLUT->SetSaturationRange(1,1);
+      invLUT->SetHueRange(double((mOverlayColor+180)%360)/360,double((mOverlayColor+180)%360)/360);
+      invLUT->Build();
+      dynamic_cast<vvImageMapToWLColors*>(mSlicers[i]->GetWindowLevel())
+        ->SetWindowLevelMode(true);
+      mSlicers[i]->GetWindowLevel()->SetLookupTable(supLUT);
+      mSlicers[i]->GetOverlayMapper()->SetLookupTable(invLUT);
+      invLUT->Delete();
+      supLUT->Delete();
+    } else if (mSlicers[i]->GetOverlay()) {
+      //dynamic_cast<vvImageMapToWLColors*>(mSlicers[i]->GetWindowLevel())
+      //->SetWindowLevelMode(false);
+      mSlicers[i]->GetWindowLevel()->SetLookupTable(LUT);
+    } else {
+      mSlicers[i]->GetWindowLevel()->SetLookupTable(LUT);
+    }
+    
+    if (mSlicers[i]->GetFusion()) {
+      mSlicers[i]->GetFusionMapper()->SetLookupTable(fusLUT);
+      mSlicers[i]->GetFusionActor()->SetOpacity(double(mFusionOpacity)/100);
     }
-    if (fusLUT)
-        fusLUT->Delete();
-    if (colormap >= 0)
-        mColorMap = colormap;
+  }
+  if (fusLUT)
+    fusLUT->Delete();
+  if (colormap >= 0)
+    mColorMap = colormap;
 }
+//----------------------------------------------------------------------------
+
 
+//----------------------------------------------------------------------------
 vvLandmarks* vvSlicerManager::GetLandmarks()
 {
-    if (mLandmarks == NULL)
-    {
-        mLandmarks = new vvLandmarks(mSlicers[0]->GetTMax()+1);
-        for (unsigned int i = 0; i < mSlicers.size(); i++)
-            mSlicers[i]->SetLandmarks(mLandmarks);
-    }
-    return mLandmarks;
+  if (mLandmarks == NULL) {
+    mLandmarks = new vvLandmarks(mSlicers[0]->GetTMax()+1);
+    for (unsigned int i = 0; i < mSlicers.size(); i++)
+      mSlicers[i]->SetLandmarks(mLandmarks);
+  }
+  return mLandmarks;
 }
+//----------------------------------------------------------------------------
 
+
+//----------------------------------------------------------------------------
 void vvSlicerManager::AddLandmark(float x,float y,float z,float t)
 {
-    double x_index = (x - mSlicers[0]->GetInput()->GetOrigin()[0])/mSlicers[0]->GetInput()->GetSpacing()[0];
-    double y_index = (y - mSlicers[0]->GetInput()->GetOrigin()[1])/mSlicers[0]->GetInput()->GetSpacing()[1];
-    double z_index = (z - mSlicers[0]->GetInput()->GetOrigin()[2])/mSlicers[0]->GetInput()->GetSpacing()[2];
-    double value = mSlicers[0]->GetInput()->GetScalarComponentAsDouble(
-            (int)x_index,
-            (int)y_index,
-            (int)z_index,0);
+  double x_index = (x - mSlicers[0]->GetInput()->GetOrigin()[0])/mSlicers[0]->GetInput()->GetSpacing()[0];
+  double y_index = (y - mSlicers[0]->GetInput()->GetOrigin()[1])/mSlicers[0]->GetInput()->GetSpacing()[1];
+  double z_index = (z - mSlicers[0]->GetInput()->GetOrigin()[2])/mSlicers[0]->GetInput()->GetSpacing()[2];
+  if (x_index >= mSlicers[0]->GetInput()->GetWholeExtent()[0] &&
+      x_index <= mSlicers[0]->GetInput()->GetWholeExtent()[1] &&
+      y_index >= mSlicers[0]->GetInput()->GetWholeExtent()[2] &&
+      y_index <= mSlicers[0]->GetInput()->GetWholeExtent()[3] &&
+      z_index >= mSlicers[0]->GetInput()->GetWholeExtent()[4] &&
+      z_index <= mSlicers[0]->GetInput()->GetWholeExtent()[5]) {
+    double value = this->GetScalarComponentAsDouble(mSlicers[0]->GetInput(), x_index, y_index, z_index);
     this->GetLandmarks()->AddLandmark(x,y,z,t,value);
     emit LandmarkAdded();
+  }
 }
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+void vvSlicerManager::PrevImage(int slicer)
+{
+  emit ChangeImageWithIndexOffset(this, slicer, -1);
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+void vvSlicerManager::NextImage(int slicer)
+{
+  emit ChangeImageWithIndexOffset(this, slicer,  1);
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+void vvSlicerManager::VerticalSliderHasChanged(int slicer, int slice)
+{
+  emit AVerticalSliderHasChanged(slicer, slice);
+}
+
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+double vvSlicerManager::GetScalarComponentAsDouble(vtkImageData *image, double X, double Y, double Z, int component)
+{
+  int ix, iy, iz;
+  return mSlicers[0]->GetScalarComponentAsDouble(image, X, Y, Z, ix, iy, iz, component);
+}
+//----------------------------------------------------------------------------