]> Creatis software - clitk.git/blobdiff - vv/vvImageContour.cxx
Debug RTStruct conversion with empty struc
[clitk.git] / vv / vvImageContour.cxx
index 63df2cb784c3dcc9aa66d7a56cf81d9597f0530a..68dc72059a32d5cf02ac3424720149e6ffd9fc7f 100644 (file)
 /*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
 
-  Program:   vv
-  Module:    $RCSfile: vvImageContour.cxx,v $
-  Language:  C++
-  Date:      $Date: 2010/02/07 12:00:59 $
-  Version:   $Revision: 1.2 $
-  Author :   David Sarrut (david.sarrut@creatis.insa-lyon.fr)
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
 
-  Copyright (C) 2010
-  Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
-  CREATIS                   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.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-  =========================================================================*/
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+  ===========================================================================**/
 
 #include "vvImageContour.h"
+#include "vvImage.h"
+#include <vtkVersion.h>
 #include <vtkImageActor.h>
 #include <vtkCamera.h>
+#include <vtkRenderer.h>
 #include <vtkMarchingSquares.h>
 #include <vtkImageClip.h>
 #include <vtkImageData.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkProperty.h>
+#include <vtkInformation.h>
 
 //------------------------------------------------------------------------------
-vvImageContour::vvImageContour() {
+vvImageContour::vvImageContour()
+{ 
   mTSlice = -1;
   mSlice = 0;
+  mHiddenImageIsUsed = false;
+  mDisplayModeIsPreserveMemory = true;
+  SetPreserveMemoryModeEnabled(true);
+  mPreviousOrientation = -1;
+  mPreviousValue=0;
+  mDepth = 1.0;
+  mSlice = 0;
 }
 //------------------------------------------------------------------------------
 
 
 //------------------------------------------------------------------------------
-vvImageContour::~vvImageContour() {
-  for (unsigned int i = 0; i < mSlicer->GetImage()->GetVTKImages().size(); i++) {
-    mSlicer->GetRenderer()->RemoveActor(mSquaresActorList[i]);
-  }
+vvImageContour::~vvImageContour()
+{ 
   mSquaresActorList.clear();
-  mSquaresList.clear();
-  mClipperList.clear();
 }
 //------------------------------------------------------------------------------
 
 
 //------------------------------------------------------------------------------
-void vvImageContour::setSlicer(vvSlicer * slicer) {
-  mSlicer = slicer;  
+void vvImageContour::RemoveActors()
+{ 
+  for (unsigned int i = 0; i < mSquaresActorList.size(); i++) {
+    if (mSlicer != 0) {
+      if (mSlicer!= NULL) {
+        if (mSlicer->GetRenderer() != NULL) {
+          if (mSquaresActorList[i] != NULL)  {
+            mSlicer->GetRenderer()->RemoveActor(mSquaresActorList[i]);
+          }
+        }
+      }   
+    }
+  }
+}
+//------------------------------------------------------------------------------
+
 
+//------------------------------------------------------------------------------
+void vvImageContour::SetSlicer(vvSlicer * slicer) 
+{ 
+  mSlicer = slicer;  
+  // Create an actor for each time slice
   for (unsigned int numImage = 0; numImage < mSlicer->GetImage()->GetVTKImages().size(); numImage++) {
-    // DD(numImage);
-    vtkImageClip * mClipper = vtkImageClip::New();
-    vtkMarchingSquares * mSquares = vtkMarchingSquares::New();
-    vtkPolyDataMapper * mSquaresMapper = vtkPolyDataMapper::New();
-    vtkActor * mSquaresActor = vtkActor::New();
+    CreateNewActor(numImage);
+  }
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvImageContour::SetImage(vvImage::Pointer image) 
+{ 
+  for (unsigned int numImage = 0; numImage < image->GetVTKImages().size(); numImage++) {
+#if VTK_MAJOR_VERSION <= 5
+    mClipperList[numImage]->SetInput(image->GetVTKImages()[numImage]);
+#else
+    mClipperList[numImage]->SetInputData(image->GetVTKImages()[numImage]);
+#endif
+  }
+  mHiddenImageIsUsed = true;
+  mHiddenImage = image;
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvImageContour::SetPreserveMemoryModeEnabled(bool b) 
+{ 
+  // FastCache mode work only if threshold is always the same
+  if (mDisplayModeIsPreserveMemory == b) return;
+  mDisplayModeIsPreserveMemory = b;
+  if (!b) {
+    clitkExceptionMacro("TODO : not implemented yet");
+    HideActors();
+    InitializeCacheMode();
+  }
+  else {
+    for(unsigned int d=0; d<mListOfCachedContourActors.size(); d++)
+      mListOfCachedContourActors[d].clear();
+    mListOfCachedContourActors.clear();
+    ShowActors();
+  }
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvImageContour::SetColor(double r, double g, double b) 
+{ 
+  for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
+    mSquaresActorList[i]->GetProperty()->SetColor(r,g,b);
+    mSquaresActorList[i]->GetProperty()->SetOpacity(0.995); //in order to get VTK to turn on the alpha-blending in OpenGL
+  }
+}
+//------------------------------------------------------------------------------
 
-    mClipper->SetInput(mSlicer->GetImage()->GetVTKImages()[numImage]);
-    mSquares->SetInput(mClipper->GetOutput());
-    mSquaresMapper->SetInput(mSquares->GetOutput());
-    mSquaresMapper->ScalarVisibilityOff();
-    mSquaresActor->SetMapper(mSquaresMapper);
-    mSquaresActor->GetProperty()->SetColor(1.0,0,0);
-    mSquaresActor->SetPickable(0);
-    mSquaresActor->VisibilityOff();
-    mSlicer->GetRenderer()->AddActor(mSquaresActor);
-    
-    mSquaresActorList.push_back(mSquaresActor);
-    mSquaresList.push_back(mSquares);
-    mClipperList.push_back(mClipper);
 
+//------------------------------------------------------------------------------
+void vvImageContour::SetLineWidth(double w)
+{ 
+  for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
+    mSquaresActorList[i]->GetProperty()->SetLineWidth(w);
   }
-  //mSquares->Update();
 }
 //------------------------------------------------------------------------------
 
 
 //------------------------------------------------------------------------------
-void vvImageContour::update(int value) {
+void vvImageContour::HideActors() 
+{ 
+  if (!mSlicer) return;
   mSlice = mSlicer->GetSlice();
+  for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
+    mSquaresActorList[i]->VisibilityOff();
+  }
+}
+//------------------------------------------------------------------------------
 
-  // Only change actor visibility if tslice change
-  if (mTSlice != mSlicer->GetTSlice()) {
-    if (mTSlice != -1) 
-      mSquaresActorList[mTSlice]->VisibilityOff();
-    mTSlice = mSlicer->GetTSlice();
-    mSquaresActorList[mTSlice]->VisibilityOn();
+
+//------------------------------------------------------------------------------
+void vvImageContour::ShowActors() 
+{ 
+  if (!mSlicer) return;
+  mSlice = mSlicer->GetSlice();
+  mTSlice = mSlicer->GetTSlice();
+  mSquaresActorList[mTSlice]->VisibilityOn();
+  Update(mValue);
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvImageContour::SetDepth(double d) 
+{ 
+  mDepth = d;
+  // Move the actor to be visible
+  double position[3] = {0, 0, 0};
+  int orientation = ComputeCurrentOrientation();
+  position[orientation] = -mDepth;
+
+  for(unsigned int i=0; i<mSquaresActorList.size(); i++)
+    mSquaresActorList[i]->SetPosition(position);
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvImageContour::Update(double value) 
+{ 
+  if (!mSlicer) return;
+  if (mPreviousValue == value) {
+    if (mPreviousSlice == mSlicer->GetSlice()) {
+      if (mPreviousTSlice == mSlicer->GetTSlice()) {
+        if (mPreviousOrientation == ComputeCurrentOrientation()) {
+          return; // Nothing to do
+        }
+      }
+    }
   }
-  
+
+  // Get current threshold value
+  mValue = value;
+
+  // Get current slice
+  mSlice = mSlicer->GetSlice();
+
+  if (mDisplayModeIsPreserveMemory) {
+    UpdateWithPreserveMemoryMode();
+  }
+  else {
+    UpdateWithFastCacheMode();
+  }
+
+  //mSlicer->Render(); //DS ---> REMOVE ??
+
+  mPreviousTSlice = mSlicer->GetTSlice();
+  mPreviousSlice  = mSlicer->GetSlice();
+  mPreviousValue  = value;
+  mPreviousOrientation = ComputeCurrentOrientation();
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvImageContour::UpdateWithPreserveMemoryMode() 
+{ 
+  // Only change actor visibility if tslice change
+  mPreviousTslice = mTSlice;
+  mTSlice = mSlicer->GetTSlice();
+
   vtkMarchingSquares * mSquares = mSquaresList[mTSlice];
+  vtkPolyDataMapper* mapper = mSquaresMapperList[mTSlice];
   vtkImageClip * mClipper = mClipperList[mTSlice];
   vtkActor * mSquaresActor = mSquaresActorList[mTSlice];
+  int orientation = ComputeCurrentOrientation();
 
-  // Do it
-  mSquares->SetValue(0,value);
+  UpdateActor(mSquaresActor, mapper, mSquares, mClipper, mValue, orientation, mSlice);
 
+  if (mPreviousTslice != mTSlice) {
+    if (mPreviousTslice != -1) mSquaresActorList[mPreviousTslice]->VisibilityOff();
+  }
+
+  //mSlicer->Render();
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvImageContour::InitializeCacheMode() 
+{ 
+clitkExceptionMacro("TODO : not implemented yet");
+  mPreviousSlice = mPreviousOrientation = 0;
+  int dim = mSlicer->GetImage()->GetNumberOfDimensions();
+
+  mListOfCachedContourActors.resize(dim);
+  for(int d=0; d<dim; d++) {
+    int size = mSlicer->GetImage()->GetSize()[d];
+    mListOfCachedContourActors[d].resize(size);
+    for(int j=0; j<size; j++) {
+      mListOfCachedContourActors[d][j] = NULL;
+    }
+  }
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+int vvImageContour::ComputeCurrentOrientation() 
+{ 
+  // Get extent of image in the slicer
   int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
-  mClipper->SetOutputWholeExtent(extent[0],extent[1],extent[2],
-                                extent[3],extent[4],extent[5]);
-  int i;
-  for (i = 0; i < 6;i = i+2) {
-    if (extent[i] == extent[i+1]) {
+
+  // Compute orientation
+  int orientation;
+  for (orientation = 0; orientation < 6; orientation = orientation+2) {
+    if (extent[orientation] == extent[orientation+1]) {
       break;
     }
   }
-  
-  switch (i)
-    {
-    case 0:
-      if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0] > mSlice)
-        {
-         mSquaresActor->SetPosition(1,0,0);
-         // mSquaresActor2->SetPosition(1,0,0);
-        }
-      else
-        {
-         mSquaresActor->SetPosition(-1,0,0);
-         // mSquaresActor2->SetPosition(-1,0,0);
-        }
-      break;
-    case 2:
-      if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1] > mSlice)
-        {
-         mSquaresActor->SetPosition(0,1,0);
-          //   mSquaresActor2->SetPosition(0,1,0);
-        }
-      else
-        {
-         mSquaresActor->SetPosition(0,-1,0);
-         // mSquaresActor2->SetPosition(0,-1,0);
-        }
-      break;
-    case 4:
-      if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2] > mSlice)
-        {
-         mSquaresActor->SetPosition(0,0,1);
-         // mSquaresActor2->SetPosition(0,0,1);
-        }
-      else
-        {
-         mSquaresActor->SetPosition(0,0,-1);
-         // mSquaresActor2->SetPosition(0,0,-1);
-        }
-      break;
+  orientation = orientation/2;
+  return orientation;
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvImageContour::UpdateWithFastCacheMode() 
+{ 
+clitkExceptionMacro("TODO : not implemented yet");
+
+  // Compute orientation
+  int orientation = ComputeCurrentOrientation();
+
+  if ((mPreviousSlice == mSlice) && (mPreviousOrientation == orientation)) return;
+
+  vtkActor * actor = mListOfCachedContourActors[orientation][mSlice];
+  if (actor != NULL) {
+    mListOfCachedContourActors[orientation][mSlice]->VisibilityOn();
+  } else {
+    CreateNewActor(0);
+    //SR: commented out, this code is never reached anyway
+    //UpdateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
+    //mListOfCachedContourActors[orientation][mSlice] = mSquaresActor;
+    //mSquaresActor->VisibilityOn();
+  }
+
+  if (mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice] != NULL)
+    mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice]->VisibilityOff();
+  mPreviousSlice = mSlice;
+  mPreviousOrientation = orientation;
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvImageContour::CreateNewActor(int numImage) 
+{ 
+  vtkSmartPointer<vtkActor> squaresActor = vtkSmartPointer<vtkActor>::New();
+  vtkSmartPointer<vtkImageClip> clipper = vtkSmartPointer<vtkImageClip>::New();
+  vtkSmartPointer<vtkMarchingSquares> squares = vtkSmartPointer<vtkMarchingSquares>::New();
+  vtkSmartPointer<vtkPolyDataMapper> squaresMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
+
+  if (mHiddenImageIsUsed) {
+#if VTK_MAJOR_VERSION <= 5
+    clipper->SetInput(mHiddenImage->GetVTKImages()[0]);
+#else
+    clipper->SetInputData(mHiddenImage->GetVTKImages()[0]);
+#endif
+  } else {
+#if VTK_MAJOR_VERSION <= 5
+    clipper->SetInput(mSlicer->GetImage()->GetVTKImages()[numImage]);
+#else
+    clipper->SetInputData(mSlicer->GetImage()->GetVTKImages()[numImage]);
+#endif
+  }
+#if VTK_MAJOR_VERSION <= 5
+  squares->SetInput(clipper->GetOutput());
+  squaresMapper->SetInput(squares->GetOutput());
+#else
+  squares->SetInputConnection(clipper->GetOutputPort(0));
+  squaresMapper->SetInputConnection(squares->GetOutputPort(0));
+#endif
+  squaresMapper->ScalarVisibilityOff();
+  squaresActor->SetMapper(squaresMapper);
+  squaresActor->GetProperty()->SetColor(1.0,0,0);
+  squaresActor->GetProperty()->SetOpacity(0.995); //in order to get VTK to turn on the alpha-blending in OpenGL
+  squaresActor->SetPickable(0);
+  squaresActor->VisibilityOff();
+  mSlicer->GetRenderer()->AddActor(squaresActor);
+
+  mSquaresActorList.push_back(squaresActor);
+  mClipperList.push_back(clipper);
+  mSquaresList.push_back(squares);
+  mSquaresMapperList.push_back(squaresMapper);
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvImageContour::UpdateActor(vtkActor * actor, 
+                                 vtkPolyDataMapper * mapper, 
+                                 vtkMarchingSquares * squares, 
+                                 vtkImageClip * clipper, 
+                                 double threshold, int orientation, int slice) 
+{ 
+  // Set parameter for the MarchigSquare
+  squares->SetValue(0, threshold);
+  squares->Update();
+  // Get image extent
+  int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
+
+  // Change extent if needed
+  int* extent2;
+  if (mHiddenImageIsUsed) {
+    extent2 = new int[6];
+    int * extent3;
+    extent3 = mHiddenImage->GetFirstVTKImageData()->GetExtent();
+
+    for(int i=0; i<6; i++) extent2[i] = extent3[i];
+
+    double s = (double)extent[orientation*2]*(double)mSlicer->GetImage()->GetSpacing()[orientation]; // in mm
+    s = s+mSlicer->GetImage()->GetOrigin()[orientation]; // from origin
+    s = s-mHiddenImage->GetFirstVTKImageData()->GetOrigin()[orientation]; // from corner second image
+    s = s/mHiddenImage->GetFirstVTKImageData()->GetSpacing()[orientation]; // in voxel
+
+    // Rint to the closest slice
+    extent2[orientation*2+1] = extent2[orientation*2] = (int)lrint(s);
+
+    // Do not display a contour if there is no contour on this slice
+    // DD(extent2[orientation*2+1]);
+    // DD(extent3[orientation*2+1]);
+    // DD(extent2[orientation*2]);
+    // DD(extent3[orientation*2]);
+    if ((extent2[orientation*2+1] > extent3[orientation*2+1]) ||
+        (extent2[orientation*2] < extent3[orientation*2])) {
+      actor->VisibilityOff();
+      return;
     }
-  mSquares->Update();
+    else actor->VisibilityOn();
+
+  } else {
+    extent2 = extent;
+    actor->VisibilityOn();
+  }
+  
+  clipper->SetOutputWholeExtent(extent2[0],extent2[1],extent2[2],
+                                extent2[3],extent2[4],extent2[5]);
+                                
+  if (mHiddenImageIsUsed) delete extent2;
+
+  // Move the actor to be visible
+  SetDepth(mDepth);
+  // double position[3] = {0, 0, 0};
+  // DD(mDepth);
+  // position[orientation] = -mDepth;
+  // actor->SetPosition(position);
+  mapper->Update();
 }
 //------------------------------------------------------------------------------
 
+