]> Creatis software - clitk.git/commitdiff
- correct crop 2D bug
authordsarrut <dsarrut>
Fri, 2 Apr 2010 09:46:58 +0000 (09:46 +0000)
committerdsarrut <dsarrut>
Fri, 2 Apr 2010 09:46:58 +0000 (09:46 +0000)
- prepare for DicomRT Struct

17 files changed:
common/CMakeLists.txt
common/clitkCommonGenericFilter.h
common/clitkDicomRT_Contour.cxx [new file with mode: 0644]
common/clitkDicomRT_Contour.h [new file with mode: 0644]
common/clitkDicomRT_ROI.cxx [new file with mode: 0644]
common/clitkDicomRT_ROI.h [new file with mode: 0644]
common/clitkDicomRT_ROI_ConvertToImageFilter.cxx [new file with mode: 0644]
common/clitkDicomRT_ROI_ConvertToImageFilter.h [new file with mode: 0644]
common/clitkDicomRT_StructureSet.cxx [new file with mode: 0644]
common/clitkDicomRT_StructureSet.h [new file with mode: 0644]
vv/CMakeLists.txt
vv/vvImageContour.cxx
vv/vvImageContour.h
vv/vvMainWindow.cxx
vv/vvSlicerManager.cxx
vv/vvToolCropImage.cxx
vv/vvToolImageArithm.cxx

index e40a81fe673de3a40c4053b86f1d40947ea7b71c..ef102d989974be4e57900a47f23a7986d0295c61 100644 (file)
@@ -32,5 +32,13 @@ SET(clitkCommon_SRC
 
 ADD_LIBRARY(clitkCommon STATIC ${clitkCommon_SRC})
 
+
+ADD_LIBRARY(clitkDicomRTStruct STATIC
+  clitkDicomRT_Contour.cxx
+  clitkDicomRT_ROI.cxx
+  clitkDicomRT_StructureSet.cxx
+  clitkDicomRT_ROI_ConvertToImageFilter.cxx
+)
+
 #ADD_LIBRARY(clitkCommonShared SHARED ${clitkCommon_SRC})
 #SET_TARGET_PROPERTIES(clitkCommonShared PROPERTIES COMPILE_FLAGS -fPIC)
index 55d2f94019f3fd83cead0fefe9e97469841d582a..3f9d63cfca556525dbfa40c4ef4cb443ec09c35e 100644 (file)
   - BSD        See included LICENSE.txt file
   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
 ======================================================================-====*/
+
 #ifndef CLITKCOMMONGENERICFILTER_H
 #define CLITKCOMMONGENERICFILTER_H
+
 #include "clitkCommon.h"
 
 /*--------------------------------------------------------------------
@@ -32,6 +34,7 @@ namespace clitk {
   class GenericFilterFunctorBase {
   public:
     GenericFilterFunctorBase(FilterType * f) { mFilter = f; }
+    virtual ~GenericFilterFunctorBase() { delete mFilter; }
     virtual void Execute()= 0;
     FilterType * mFilter;
   };
diff --git a/common/clitkDicomRT_Contour.cxx b/common/clitkDicomRT_Contour.cxx
new file mode 100644 (file)
index 0000000..ac6d441
--- /dev/null
@@ -0,0 +1,121 @@
+/*=========================================================================
+  Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
+  Main authors :   XX XX XX
+
+  Authors belongs 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
+
+  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.
+
+  It is distributed under dual licence
+  - BSD       http://www.opensource.org/licenses/bsd-license.php
+  - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+
+  =========================================================================*/
+
+#include "clitkDicomRT_Contour.h" 
+#include <vtkCellArray.h>
+
+//--------------------------------------------------------------------
+clitk::DicomRT_Contour::DicomRT_Contour() {
+  mMeshIsUpToDate = false;
+  mNbOfPoints = 0;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+clitk::DicomRT_Contour::~DicomRT_Contour() {
+  
+}
+//--------------------------------------------------------------------
+
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_Contour::Print(std::ostream & os) const {
+  DD("TODO : print Contours");
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+bool clitk::DicomRT_Contour::Read(gdcm::SQItem * item) {
+  
+  // Contour type [Contour Geometric Type]
+  mType = item->GetEntryValue(0x3006,0x0042);
+  // DD(mType);
+  if (mType != "CLOSED_PLANAR ") { ///WARNING to the space after the name ...
+    std::cerr << "Skip this contour : type=" << mType << std::endl;
+    return false;
+  }
+  
+  // Number of points [Number of Contour Points]
+  mNbOfPoints = parse_value<int>(item->GetEntryValue(0x3006,0x0046));
+  // DD(mNbOfPoints);
+  
+  // Read values [Contour Data]
+  std::vector<float> points = parse_string<float>(item->GetEntryValue(0x3006,0x0050),'\\');
+  assert(points.size() == static_cast<unsigned int>(mNbOfPoints)*3);
+  
+  // Organize values
+  mData = vtkPoints::New();
+  mData->SetDataTypeToDouble();
+  mData->SetNumberOfPoints(mNbOfPoints);
+  double z = -1;
+  for(unsigned int i=0; i<mNbOfPoints; i++) {
+    double p[3];
+    p[0] = points[i*3];
+    p[1] = points[i*3+1];
+    p[2] = points[i*3+2];
+    mData->SetPoint(i, p);
+    if (z == -1) z = p[2];
+    if (p[2] != z) {
+      DD(i);
+      DD(p[2]);
+      DD(z);
+      std::cout << "ERROR ! contour not in the same slice" << std::endl;
+      assert(p[2] == z);
+    }
+  }
+
+  return true;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+vtkPolyData * clitk::DicomRT_Contour::GetMesh() {
+  if (!mMeshIsUpToDate) {
+    ComputeMesh();
+  }
+  return mMesh;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_Contour::ComputeMesh() {  
+ //  DD("ComputeMesh Contour");
+  mMesh = vtkPolyData::New();
+  mMesh->Allocate(); //for cell structures
+  mMesh->SetPoints(vtkPoints::New());
+  vtkIdType ids[2];
+  for (unsigned int idx=0 ; idx<mNbOfPoints ; idx++) {
+    mMesh->GetPoints()->InsertNextPoint(mData->GetPoint(idx)[0], 
+                                        mData->GetPoint(idx)[1], 
+                                        mData->GetPoint(idx)[2]);
+    ids[0]=idx; 
+    ids[1]=(ids[0]+1) % mNbOfPoints; //0-1,1-2,...,n-1-0
+    // DD(ids[0]);
+//     DD(ids[1]);
+    mMesh->GetLines()->InsertNextCell(2,ids);
+  }
+  // DD(mMesh->GetNumberOfCells());
+  mMeshIsUpToDate = true;
+}
+//--------------------------------------------------------------------
diff --git a/common/clitkDicomRT_Contour.h b/common/clitkDicomRT_Contour.h
new file mode 100644 (file)
index 0000000..b599769
--- /dev/null
@@ -0,0 +1,85 @@
+/*=========================================================================
+  Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
+  Main authors :   XX XX XX
+
+  Authors belongs 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
+
+  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.
+
+  It is distributed under dual licence
+  - BSD       http://www.opensource.org/licenses/bsd-license.php
+  - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+
+  =========================================================================*/
+
+#ifndef CLITKDICOMRT_CONTOUR_H
+#define CLITKDICOMRT_CONTOUR_H
+
+#include "clitkCommon.h" 
+#include "clitkDicomRT_Contour.h"
+#include <gdcm.h>
+#include <gdcmSQItem.h>
+#include <vtkPoints.h>
+#include <vtkPolyData.h>
+
+namespace clitk {
+
+  //--------------------------------------------------------------------
+  class DicomRT_Contour {
+    
+  public:
+    DicomRT_Contour();
+    ~DicomRT_Contour();
+
+    void Print(std::ostream & os = std::cout) const;
+    bool Read(gdcm::SQItem * item);
+    vtkPolyData * GetMesh();
+    
+  protected:
+    void ComputeMesh();
+    unsigned int mNbOfPoints;
+    std::string mType;
+    vtkPoints * mData;
+    vtkPolyData * mMesh;
+    bool mMeshIsUpToDate;
+
+  };
+  //--------------------------------------------------------------------
+
+  //--------------------------------------------------------------------
+  template<class ElementType>
+  ElementType parse_value(std::string str)
+  {
+    std::istringstream parser(str);
+    ElementType value;
+    parser >> value;
+    if (parser.fail()) {
+      DD(str);
+      DD(value);
+    }
+    assert(!parser.fail());
+    return value;
+  }
+
+  template<class ElementType>
+  std::vector<ElementType> parse_string(std::string str,char delim) {
+    std::istringstream ss(str);
+    std::string token;
+    std::vector<ElementType> result;
+    while (getline(ss,token,delim))
+      {
+        result.push_back(parse_value<ElementType>(token));
+      }
+    return result;
+  }
+  //--------------------------------------------------------------------
+
+
+} // end namespace clitk
+#endif // CLITKDICOMRT_CONTOUR_H
+
diff --git a/common/clitkDicomRT_ROI.cxx b/common/clitkDicomRT_ROI.cxx
new file mode 100644 (file)
index 0000000..f65dc62
--- /dev/null
@@ -0,0 +1,150 @@
+/*=========================================================================
+  Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
+  Main authors :   XX XX XX
+
+  Authors belongs 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
+
+  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.
+
+  It is distributed under dual licence
+  - BSD       http://www.opensource.org/licenses/bsd-license.php
+  - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+
+  =========================================================================*/
+
+#include "clitkDicomRT_ROI.h" 
+#include <vtkSmartPointer.h>
+#include <vtkAppendPolyData.h>
+
+//--------------------------------------------------------------------
+clitk::DicomRT_ROI::DicomRT_ROI() {
+  mName = "NoName";
+  mNumber = -1;
+  mColor.resize(3);
+  mColor[0] = mColor[1] = mColor[2] = 0;
+  mMeshIsUpToDate = false;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+clitk::DicomRT_ROI::~DicomRT_ROI() {
+  
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+int clitk::DicomRT_ROI::GetROINumber() const {
+  return mNumber;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+const std::string & clitk::DicomRT_ROI::GetName() const {
+  return mName;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+const std::vector<double> & clitk::DicomRT_ROI::GetDisplayColor() const {
+  return mColor;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI::Print(std::ostream & os) const {
+  os << "ROI " << mNumber << "\t" << mName 
+     << "\t(" << mColor[0] << " " << mColor[1] << " " << mColor[2] << ")"
+     << "\t Contours = " << mListOfContours.size() << std::endl;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI::Read(std::map<int, std::string> & rois, gdcm::SQItem * item) {
+  
+  // Change number if needed
+  
+  // TODO
+
+  // ROI number [Referenced ROI Number]
+  mNumber = atoi(item->GetEntryValue(0x3006,0x0084).c_str());
+  
+  // Retrieve ROI Name
+  mName = rois[mNumber];
+
+  // ROI Color [ROI Display Color]
+  mColor = clitk::parse_string<double>(item->GetEntryValue(0x3006,0x002a),'\\');
+
+  // Read contours [Contour Sequence]
+  gdcm::SeqEntry * contours=item->GetSeqEntry(0x3006,0x0040);
+  for(gdcm::SQItem* j=contours->GetFirstSQItem();j!=0;j=contours->GetNextSQItem()) {
+    DicomRT_Contour * c = new DicomRT_Contour;    
+    bool b = c->Read(j);
+    if (b) mListOfContours.push_back(c);
+  }
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+vtkPolyData * clitk::DicomRT_ROI::GetMesh() {
+  if (!mMeshIsUpToDate) {
+    ComputeMesh();
+  }
+  return mMesh;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI::ComputeMesh() {
+  vtkAppendPolyData * append = vtkAppendPolyData::New();
+  for(unsigned int i=0; i<mListOfContours.size(); i++) {
+    append->AddInput(mListOfContours[i]->GetMesh());
+  }
+  append->Update();
+  mMesh = append->GetOutput();
+  mMeshIsUpToDate = true;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI::SetFromBinaryImage(vvImage::Pointer image, int n, 
+                                           std::string name, 
+                                           std::vector<double> color) {
+  
+  // ROI number [Referenced ROI Number]
+  mNumber = n;
+  
+  // ROI Name
+  mName = name;
+    
+  // ROI Color [ROI Display Color]
+  mColor = color;
+
+  // No contours [Contour Sequence]
+  mListOfContours.clear();
+
+  // Set image
+  mImage = image;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+const vvImage::Pointer clitk::DicomRT_ROI::GetImage() const {
+  return mImage;
+}
+//--------------------------------------------------------------------
diff --git a/common/clitkDicomRT_ROI.h b/common/clitkDicomRT_ROI.h
new file mode 100644 (file)
index 0000000..fe95208
--- /dev/null
@@ -0,0 +1,61 @@
+/*=========================================================================
+  Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
+  Main authors :   XX XX XX
+
+  Authors belongs 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
+
+  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.
+
+  It is distributed under dual licence
+  - BSD       http://www.opensource.org/licenses/bsd-license.php
+  - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+
+  =========================================================================*/
+
+#ifndef CLITKDICOMRT_ROI_H
+#define CLITKDICOMRT_ROI_H
+
+#include "clitkDicomRT_Contour.h"
+#include "vvImage.h"
+
+namespace clitk {
+
+  //--------------------------------------------------------------------
+  class DicomRT_ROI {
+    
+  public:
+    DicomRT_ROI();
+    ~DicomRT_ROI();
+
+    void Print(std::ostream & os = std::cout) const;
+    void Read(std::map<int, std::string> & rois, gdcm::SQItem * item);
+    void SetFromBinaryImage(vvImage::Pointer image, int n, 
+                           std::string name, 
+                           std::vector<double> color);
+
+    int GetROINumber() const;
+    const std::string & GetName() const;
+    const std::vector<double> & GetDisplayColor() const;
+    vtkPolyData * GetMesh();
+    const vvImage::Pointer GetImage() const;
+    
+  protected:
+    void ComputeMesh();
+    std::string mName;
+    int mNumber;
+    std::vector<double> mColor;
+    std::vector<DicomRT_Contour*> mListOfContours;
+    vtkPolyData * mMesh;
+    bool mMeshIsUpToDate;
+    vvImage::Pointer mImage;
+  };
+  //--------------------------------------------------------------------
+
+} // end namespace clitk
+#endif // CLITKDICOMRT_ROI_H
+
diff --git a/common/clitkDicomRT_ROI_ConvertToImageFilter.cxx b/common/clitkDicomRT_ROI_ConvertToImageFilter.cxx
new file mode 100644 (file)
index 0000000..ef5ecb4
--- /dev/null
@@ -0,0 +1,191 @@
+/*=========================================================================
+  Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
+  Main authors :   XX XX XX
+
+  Authors belongs 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
+
+  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.
+
+  It is distributed under dual licence
+  - BSD       http://www.opensource.org/licenses/bsd-license.php
+  - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+
+  =========================================================================*/
+
+#include "clitkDicomRT_ROI_ConvertToImageFilter.h" 
+#include <vtkPolyDataToImageStencil.h>
+#include <vtkSmartPointer.h>
+#include <vtkImageStencil.h>
+#include <vtkLinearExtrusionFilter.h>
+#include <itkVTKImageToImageFilter.h>
+#include "clitkImageCommon.h"
+
+//--------------------------------------------------------------------
+clitk::DicomRT_ROI_ConvertToImageFilter::DicomRT_ROI_ConvertToImageFilter() {
+  mROI = NULL;
+  mImageInfoIsSet = false;
+  mWriteOutput = false;
+  mCropMask = true;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+clitk::DicomRT_ROI_ConvertToImageFilter::~DicomRT_ROI_ConvertToImageFilter() {
+  
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI_ConvertToImageFilter::SetROI(clitk::DicomRT_ROI * roi) {
+  mROI = roi;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI_ConvertToImageFilter::SetCropMaskEnabled(bool b) {
+  mCropMask = b;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI_ConvertToImageFilter::SetOutputImageFilename(std::string s) {
+  mOutputFilename = s;
+  mWriteOutput = true;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI_ConvertToImageFilter::SetImageFilename(std::string f) {
+  itk::ImageIOBase::Pointer header = clitk::readImageHeader(f);
+  if (header->GetNumberOfDimensions() < 3) {
+    std::cerr << "Error. Please provide a 3D image instead of " << f << std::endl;
+    exit(0);
+  }
+  if (header->GetNumberOfDimensions() > 3) {
+    std::cerr << "Warning dimension > 3 are ignored" << std::endl;
+  }
+  mSpacing.resize(3);
+  mOrigin.resize(3);
+  mSize.resize(3);
+  for(unsigned int i=0; i<3; i++) {
+    mSpacing[i] = header->GetSpacing(i);
+    mOrigin[i] = header->GetOrigin(i);
+    mSize[i] = header->GetDimensions(i);
+  }
+  mImageInfoIsSet = true;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_ROI_ConvertToImageFilter::Update() {
+  if (!mROI) {
+    std::cerr << "Error. No ROI set, please use SetROI." << std::endl;
+    exit(0);
+  }
+  if (!mImageInfoIsSet) {
+    std::cerr << "Error. Please provide image info (spacing/origin) with SetImageFilename" << std::endl;
+    exit(0);
+  }
+  // DD("Update");
+  
+  // Get Mesh
+  vtkPolyData * mesh = mROI->GetMesh();
+  DD(mesh->GetNumberOfCells());
+  
+  // Get bounds
+  double *bounds=mesh->GetBounds(); 
+  // for(int i=0; i<6; i++){
+//     DD(bounds[i]);
+//   }
+
+  // Compute origin
+  std::vector<double> origin; 
+  origin.resize(3);
+  origin[0] = floor((bounds[0]-mOrigin[0])/mSpacing[0]-2)*mSpacing[0]+mOrigin[0];
+  origin[1] = floor((bounds[2]-mOrigin[1])/mSpacing[1]-2)*mSpacing[1]+mOrigin[1];
+  origin[2] = floor((bounds[4]-mOrigin[2])/mSpacing[2]-2)*mSpacing[2]+mOrigin[2];
+  
+  // Compute extend
+  std::vector<double> extend; 
+  extend.resize(3);
+  extend[0] = ceil((bounds[1]-origin[0])/mSpacing[0]+4);
+  extend[1] = ceil((bounds[3]-origin[1])/mSpacing[1]+4);
+  extend[2] = ceil((bounds[5]-origin[2])/mSpacing[2]+4);
+  
+  // If no crop, set initial image size/origin
+  if (!mCropMask) {
+    for(int i=0; i<3; i++) {
+      origin[i] = mOrigin[i];
+      extend[i] = mSize[i]-1;
+    }
+  }
+  
+  // Create new output image
+  mBinaryImage = vtkImageData::New();
+  mBinaryImage->SetScalarTypeToUnsignedChar();
+  mBinaryImage->SetOrigin(&origin[0]);
+  mBinaryImage->SetSpacing(&mSpacing[0]);
+  mBinaryImage->SetExtent(0, extend[0], 
+                          0, extend[1], 
+                          0, extend[2]);
+  mBinaryImage->AllocateScalars();
+
+  // for(int i=0; i<3; i++){
+  //     DD(origin[i]);
+  //     DD(extend[i]);
+  //     DD(mBinaryImage->GetDimensions()[i]);
+  //   }
+  memset(mBinaryImage->GetScalarPointer(), 0,
+         mBinaryImage->GetDimensions()[0]*mBinaryImage->GetDimensions()[1]*mBinaryImage->GetDimensions()[2]*sizeof(unsigned char));
+  
+  // Extrude
+  vtkSmartPointer<vtkLinearExtrusionFilter> extrude=vtkSmartPointer<vtkLinearExtrusionFilter>::New();
+  extrude->SetInput(mesh);
+  ///We extrude in the -slice_spacing direction to respect the FOCAL convention // ?????????????
+  extrude->SetVector(0, 0, -mSpacing[2]);
+
+  // Binarization  
+  vtkSmartPointer<vtkPolyDataToImageStencil> sts=vtkSmartPointer<vtkPolyDataToImageStencil>::New();
+  //The following line is extremely important
+  //http://www.nabble.com/Bug-in-vtkPolyDataToImageStencil--td23368312.html#a23370933
+  sts->SetTolerance(0);
+  sts->SetInformationInput(mBinaryImage);
+  sts->SetInput(extrude->GetOutput());
+  //sts->SetInput(mesh);
+
+  vtkSmartPointer<vtkImageStencil> stencil=vtkSmartPointer<vtkImageStencil>::New();
+  stencil->SetStencil(sts->GetOutput());  
+  stencil->SetInput(mBinaryImage);
+  stencil->ReverseStencilOn();
+  stencil->Update();
+  mBinaryImage->ShallowCopy(stencil->GetOutput());
+  
+  if (mWriteOutput) {
+     typedef itk::Image<unsigned char, 3> ImageType;
+     typedef itk::VTKImageToImageFilter<ImageType> ConnectorType;
+     ConnectorType::Pointer connector = ConnectorType::New();
+     connector->SetInput(GetOutput());
+     connector->Update();
+     clitk::writeImage<ImageType>(connector->GetOutput(), mOutputFilename);  
+  }
+}
+//--------------------------------------------------------------------
+
+
+    
+//--------------------------------------------------------------------
+vtkImageData * clitk::DicomRT_ROI_ConvertToImageFilter::GetOutput() {
+  return mBinaryImage;
+}
+//--------------------------------------------------------------------
diff --git a/common/clitkDicomRT_ROI_ConvertToImageFilter.h b/common/clitkDicomRT_ROI_ConvertToImageFilter.h
new file mode 100644 (file)
index 0000000..d5d27b3
--- /dev/null
@@ -0,0 +1,58 @@
+/*=========================================================================
+  Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
+  Main authors :   XX XX XX
+
+  Authors belongs 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
+
+  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.
+
+  It is distributed under dual licence
+  - BSD       http://www.opensource.org/licenses/bsd-license.php
+  - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+
+  =========================================================================*/
+
+#ifndef CLITKDICOMRT_ROI_CONVERTTOIMAGEFILTER_H
+#define CLITKDICOMRT_ROI_CONVERTTOIMAGEFILTER_H
+
+#include "clitkDicomRT_ROI.h"
+#include "clitkImageCommon.h"
+#include <vtkImageData.h>
+
+namespace clitk {
+
+  //--------------------------------------------------------------------
+  class DicomRT_ROI_ConvertToImageFilter {
+    
+  public:
+    DicomRT_ROI_ConvertToImageFilter();
+    ~DicomRT_ROI_ConvertToImageFilter();
+
+    void SetROI(clitk::DicomRT_ROI * roi);
+    void SetImageFilename(std::string s);
+    void SetOutputImageFilename(std::string s);
+    void Update();    
+    vtkImageData * GetOutput();
+    void SetCropMaskEnabled(bool b);
+
+  protected:
+    bool mImageInfoIsSet;
+    bool mWriteOutput;
+    bool mCropMask;
+    std::string mOutputFilename;
+    std::vector<double> mSpacing;
+    std::vector<double> mOrigin;
+    std::vector<int> mSize;
+    clitk::DicomRT_ROI * mROI;
+    vtkImageData * mBinaryImage;
+  };
+  //--------------------------------------------------------------------
+
+} // end namespace clitk
+#endif // CLITKDICOMRT_ROI_CONVERTTOIMAGEFILTER_H
+
diff --git a/common/clitkDicomRT_StructureSet.cxx b/common/clitkDicomRT_StructureSet.cxx
new file mode 100644 (file)
index 0000000..d7c4e79
--- /dev/null
@@ -0,0 +1,239 @@
+/*=========================================================================
+  Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
+  Main authors :   XX XX XX
+
+  Authors belongs 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
+
+  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.
+
+  It is distributed under dual licence
+  - BSD       http://www.opensource.org/licenses/bsd-license.php
+  - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+
+  =========================================================================*/
+
+#include "clitkDicomRT_StructureSet.h" 
+#include <vtksys/SystemTools.hxx>
+
+//--------------------------------------------------------------------
+clitk::DicomRT_StructureSet::DicomRT_StructureSet() {
+  mStudyID = "NoStudyID";
+  mStudyTime = "NoStudyTime";
+  mStudyDate = "NoStudyDate";
+  mLabel = "NoLabel";
+  mName = "NoName";
+  mDate = "NoDate";
+  mTime = "NoTime";
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+clitk::DicomRT_StructureSet::~DicomRT_StructureSet() {
+  
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+const std::string & clitk::DicomRT_StructureSet::GetStudyID() const {
+  return mStudyID;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+const std::string & clitk::DicomRT_StructureSet::GetStudyTime() const{
+  return mStudyTime;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+const std::string & clitk::DicomRT_StructureSet::GetStudyDate() const {
+  return mStudyDate;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+const std::string & clitk::DicomRT_StructureSet::GetLabel() const {
+  return mLabel;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+const std::string & clitk::DicomRT_StructureSet::GetName() const {
+  return mName;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+const std::string & clitk::DicomRT_StructureSet::GetDate() const {
+  return mDate;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+const std::string & clitk::DicomRT_StructureSet::GetTime() const {
+  return mTime;
+}
+//--------------------------------------------------------------------
+    
+//--------------------------------------------------------------------
+const std::vector<clitk::DicomRT_ROI*> & clitk::DicomRT_StructureSet::GetListOfROI() const {
+  return mListOfROI;
+}
+//--------------------------------------------------------------------
+    
+//--------------------------------------------------------------------
+clitk::DicomRT_ROI* clitk::DicomRT_StructureSet::GetROI(int n) {
+  if (mMapOfROIIndex.find(n) == mMapOfROIIndex.end()) {
+    std::cerr << "No ROI number " << n << std::endl;
+    return NULL;
+  }
+  DD(mListOfROI[mMapOfROIIndex[n]]->GetName());
+  DD(mListOfROI[mMapOfROIIndex[n]]->GetROINumber());  
+  return mListOfROI[mMapOfROIIndex[n]];
+}
+//--------------------------------------------------------------------
+    
+//--------------------------------------------------------------------
+void clitk::DicomRT_StructureSet::Print(std::ostream & os) const {
+  os << "Study ID      = " << mStudyID << std::endl
+     << "Study Date    = " << mStudyDate << std::endl
+     << "Study Time    = " << mStudyTime << std::endl
+     << "Struct Label  = " << mLabel << std::endl
+     << "Struct Name   = " << mName << std::endl
+     << "Struct Time   = " << mTime << std::endl
+     << "Number of ROI = " << mListOfROI.size() << std::endl;
+  for(unsigned int i=0; i<mListOfROI.size(); i++) {
+    mListOfROI[i]->Print(os);
+  }
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::DicomRT_StructureSet::Read(const std::string & filename) {
+  // Open DICOM
+  gdcm::File reader;
+  reader.SetFileName(filename.c_str());
+  reader.SetMaxSizeLoadEntry(16384); // Needed ...
+  reader.SetLoadMode(gdcm::LD_NOSHADOW); // don't load shadow tags (in order to save memory)
+  reader.Load();
+
+  // Check file type
+  //Verify if the file is a RT-Structure-Set dicom file
+  if (!gdcm::Util::DicomStringEqual(reader.GetEntryValue(0x0008,0x0016),"1.2.840.10008.5.1.4.1.1.481.3")) {  //SOP clas UID
+    std::cerr << "Error. the file " << filename 
+              << " is not a Dicom Struct ? (must have a SOP Class UID [0008|0016] = 1.2.840.10008.5.1.4.1.1.481.3 ==> [RT Structure Set Storage])"
+              << std::endl;
+    exit(0);
+  }    
+  if (!gdcm::Util::DicomStringEqual(reader.GetEntryValue(0x0008,0x0060),"RTSTRUCT")) {  //SOP clas UID
+    std::cerr << "Error. the file " << filename 
+              << " is not a Dicom Struct ? (must have 0x0008,0x0060 = RTSTRUCT [RT Structure Set Storage])"
+              << std::endl;
+    exit(0);
+  }    
+
+  // Read global info
+  mStudyID   = reader.GetValEntry(0x0020,0x0010)->GetValue();
+  mStudyTime = reader.GetValEntry(0x008,0x0020)->GetValue();
+  mStudyDate = reader.GetValEntry(0x008,0x0030)->GetValue();
+  mLabel     = reader.GetValEntry(0x3006,0x002)->GetValue();
+  mName      = reader.GetValEntry(0x3006,0x004)->GetValue();
+  mTime      = reader.GetValEntry(0x3006,0x009)->GetValue();
+  
+  //----------------------------------
+  // Read all ROI Names and number
+  // 0x3006,0x0020 = [ Structure Set ROI Sequence ]
+  gdcm::SeqEntry * roi_seq=reader.GetSeqEntry(0x3006,0x0020);
+  assert(roi_seq); // TODO error message
+  for (gdcm::SQItem* r=roi_seq->GetFirstSQItem();r!=0;r=roi_seq->GetNextSQItem()) {
+    std::string name = r->GetEntryValue(0x3006,0x0026);      // 0x3006,0x0026 = [ROI Name] 
+    int nb = atoi(r->GetEntryValue(0x3006,0x0022).c_str());  // 0x3006,0x0022 = [ROI Number]
+    // Change number if needed
+    
+    //TODO
+
+    // Check if such a number already exist
+    if (mMapOfROIName.find(nb) != mMapOfROIName.end()) {
+      std::cerr << "WARNING. A Roi already exist with the number " 
+               << nb << ". I replace." << std::endl;
+    }
+    // Add in map
+    mMapOfROIName[nb] = name;
+  }
+  // DD(mMapOfROIName.size());
+  
+  //----------------------------------
+  // Read all ROI   
+  // 0x3006,0x0039 = [ ROI Contour Sequence ]
+  gdcm::SeqEntry * roi_contour_seq=reader.GetSeqEntry(0x3006,0x0039);
+  assert(roi_contour_seq); // TODO error message
+  int n=0;
+  for (gdcm::SQItem* r=roi_contour_seq->GetFirstSQItem();r!=0;r=roi_contour_seq->GetNextSQItem()) {
+    DicomRT_ROI * roi = new DicomRT_ROI;
+    roi->Read(mMapOfROIName, r);
+    mListOfROI.push_back(roi);
+    mMapOfROIIndex[roi->GetROINumber()] = n;
+    n++;
+  }
+
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+int clitk::DicomRT_StructureSet::AddBinaryImageAsNewROI(vvImage::Pointer im, std::string n) {
+  DD("AddBinaryImageAsNewROI");
+  // Search max ROI number
+  int max = -1;
+  for(unsigned int i=0; i<mListOfROI.size(); i++) {
+    if (mListOfROI[i]->GetROINumber() > max) 
+      max = mListOfROI[i]->GetROINumber();
+  }
+  DD(max);
+  ++max;
+  DD(max);
+
+  // Compute name
+  std::ostringstream oss;
+  oss << vtksys::SystemTools::GetFilenameName(vtksys::SystemTools::GetFilenameWithoutLastExtension(n))
+      << "_roi_" << max << vtksys::SystemTools::GetFilenameLastExtension(n);
+  DD(oss.str());
+  mMapOfROIName[max] = oss.str();
+
+  // Set color
+  std::vector<double> color;
+  color.push_back(1);
+  color.push_back(0);
+  color.push_back(0);
+  
+  // Create ROI
+  DicomRT_ROI * roi = new DicomRT_ROI;
+  roi->SetFromBinaryImage(im, 
+                         max, 
+                         oss.str(), 
+                         color);
+  mListOfROI.push_back(roi);
+  mMapOfROIIndex[mListOfROI.size()-1] = max;
+  DD(mMapOfROIIndex[mListOfROI.size()-1]);
+  return max;
+}
+//--------------------------------------------------------------------
+
+
diff --git a/common/clitkDicomRT_StructureSet.h b/common/clitkDicomRT_StructureSet.h
new file mode 100644 (file)
index 0000000..77d164d
--- /dev/null
@@ -0,0 +1,68 @@
+/*=========================================================================
+  Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
+  Main authors :   XX XX XX
+
+  Authors belongs 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
+
+  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.
+
+  It is distributed under dual licence
+  - BSD       http://www.opensource.org/licenses/bsd-license.php
+  - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+
+  =========================================================================*/
+
+#ifndef CLITKDICOMRT_STRUCTURESET_H
+#define CLITKDICOMRT_STRUCTURESET_H
+
+#include "clitkCommon.h" 
+#include "clitkDicomRT_ROI.h"
+#include "vvImage.h"
+
+namespace clitk {
+
+  //--------------------------------------------------------------------
+  class DicomRT_StructureSet {
+    
+  public:
+    DicomRT_StructureSet();
+    ~DicomRT_StructureSet();
+
+    void Print(std::ostream & os = std::cout) const;
+    void Read(const std::string & filename);
+
+    const std::vector<clitk::DicomRT_ROI*> & GetListOfROI() const;
+    clitk::DicomRT_ROI * GetROI(int n);
+    const std::string & GetStudyID() const;
+    const std::string & GetStudyTime() const;
+    const std::string & GetStudyDate() const;
+    const std::string & GetLabel() const;
+    const std::string & GetName() const;
+    const std::string & GetDate() const;
+    const std::string & GetTime() const;
+
+    int AddBinaryImageAsNewROI(vvImage::Pointer i, std::string name);
+    
+  protected:
+    std::string mStudyID;
+    std::string mStudyTime;
+    std::string mStudyDate;
+    std::string mLabel;
+    std::string mName;
+    std::string mDate;
+    std::string mTime;
+    std::map<int, std::string> mMapOfROIName;
+    std::map<int, int> mMapOfROIIndex;
+    std::vector<clitk::DicomRT_ROI*> mListOfROI;
+
+  };
+  //--------------------------------------------------------------------
+
+} // end namespace clitk
+#endif // CLITKDICOMRT_STRUCTURESET_H
+
index e8a5cd8881f0b24750b9f1fe32553ab4fd3b5bb1..160fe69849d54451fa99d8702f08b1dc9aa5e37f 100644 (file)
@@ -42,6 +42,7 @@ endif(COMMAND cmake_policy)
 LINK_LIBRARIES (
   #ITKIO
   clitkCommon
+  clitkDicomRTStruct
   #clitkGGO
   clitkFilters
   ${QT_QTCORE_LIBRARY}
@@ -112,7 +113,9 @@ SET(vv_SRCS
   vvImageContour.cxx
   vvToolImageArithm.cxx
   vvToolConvert.cxx
-#  vvToolStructureSetManager.cxx
+  # vvToolStructureSetManager.cxx
+#   vvStructureSetActor.cxx
+#   vvROIActor.cxx
   )
 
 QT4_WRAP_CPP(vv_SRCS 
@@ -144,7 +147,9 @@ QT4_WRAP_CPP(vv_SRCS
   vvToolCropImage.h
   vvToolImageArithm.h
   vvToolConvert.h
-#  vvToolStructureSetManager.h
+  # vvToolStructureSetManager.h
+ #  vvStructureSetActor.h
+#   vvROIActor.h
   )
 
 QT4_WRAP_UI(vv_UI_CXX 
@@ -171,7 +176,7 @@ QT4_WRAP_UI(vv_UI_CXX
   qt_ui/vvToolCropImage.ui
   qt_ui/vvToolBinarize.ui
   qt_ui/vvToolImageArithm.ui
- qt_ui/vvToolStructureSetManager.ui
+  # qt_ui/vvToolStructureSetManager.ui
   )
 
 SET(vvUI_RCCS vvIcons.qrc)
index a98247c5123f3e4c2b69d992a88686d026155efd..fa22d45e98d60c234aa825f10e36979967dfa837 100644 (file)
 
   - 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 <vtkImageActor.h>
 #include <vtkCamera.h>
 #include <vtkRenderer.h>
@@ -30,6 +31,8 @@
 vvImageContour::vvImageContour() {
   mTSlice = -1;
   mSlice = 0;
+  mHiddenImageIsUsed = false;
+  mDisplayModeIsPreserveMemory = true;
 }
 //------------------------------------------------------------------------------
 
@@ -53,9 +56,11 @@ void vvImageContour::setSlicer(vvSlicer * slicer) {
   for (unsigned int numImage = 0; numImage < mSlicer->GetImage()->GetVTKImages().size(); numImage++) {
     vtkImageClip * mClipper = vtkImageClip::New();
     vtkMarchingSquares * mSquares = vtkMarchingSquares::New();
-    vtkPolyDataMapper * mSquaresMapper = vtkPolyDataMapper::New();
+    //    vtkPolyDataMapper * mSquaresMapper = vtkPolyDataMapper::New();
     vtkActor * mSquaresActor = vtkActor::New();
 
+    createNewActor(&mSquaresActor, &mSquares, &mClipper);
+    /*
     mClipper->SetInput(mSlicer->GetImage()->GetVTKImages()[numImage]);
     mSquares->SetInput(mClipper->GetOutput());
     mSquaresMapper->SetInput(mSquares->GetOutput());
@@ -65,7 +70,7 @@ void vvImageContour::setSlicer(vvSlicer * slicer) {
     mSquaresActor->SetPickable(0);
     mSquaresActor->VisibilityOff();
     mSlicer->GetRenderer()->AddActor(mSquaresActor);
-    
+    */
     mSquaresActorList.push_back(mSquaresActor);
     mSquaresList.push_back(mSquares);
     mClipperList.push_back(mClipper);
@@ -74,6 +79,37 @@ void vvImageContour::setSlicer(vvSlicer * slicer) {
 //------------------------------------------------------------------------------
 
 
+//------------------------------------------------------------------------------
+void vvImageContour::setImage(vvImage::Pointer image) {
+  DD("vvImageContour::setImage");
+  for (unsigned int numImage = 0; numImage < image->GetVTKImages().size(); numImage++) {
+    mClipperList[numImage]->SetInput(image->GetVTKImages()[numImage]);
+  }
+  mHiddenImageIsUsed = true;
+  mHiddenImage = image;
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvImageContour::setPreserveModeEnabled(bool b) {
+  DD("setPreserveModeEnabled");
+  DD(b);
+  DD(mDisplayModeIsPreserveMemory);
+  if (mDisplayModeIsPreserveMemory == b) return;
+  mDisplayModeIsPreserveMemory = b;
+  if (!b) {
+    initializeCacheMode();
+  }
+  else {
+    for(unsigned int d=0; d<mListOfCachedContourActors.size(); d++)
+      mListOfCachedContourActors[d].clear();
+    mListOfCachedContourActors.clear();
+  }
+}
+//------------------------------------------------------------------------------
+
+
 //------------------------------------------------------------------------------
 void vvImageContour::setColor(double r, double g, double b) {
   for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
@@ -109,12 +145,25 @@ void vvImageContour::showActors() {
   
 //------------------------------------------------------------------------------
 void vvImageContour::update(double value) {
-  mValue= value;
   if (!mSlicer) return;
+  // Get current threshold value
+  mValue= value;
+  // Get current slice
+  mSlice = mSlicer->GetSlice();
 
-  // how to not update if not visible ?
+  if (mDisplayModeIsPreserveMemory) {
+    updateWithPreserveMemoryMode();
+  }
+  else {
+    updateWithFastCacheMode();
+  }
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvImageContour::updateWithPreserveMemoryMode() {
 
-  mSlice = mSlicer->GetSlice();
   // Only change actor visibility if tslice change
   if (mTSlice != mSlicer->GetTSlice()) {
     if (mTSlice != -1) 
@@ -126,13 +175,78 @@ void vvImageContour::update(double value) {
   vtkMarchingSquares * mSquares = mSquaresList[mTSlice];
   vtkImageClip * mClipper = mClipperList[mTSlice];
   vtkActor * mSquaresActor = mSquaresActorList[mTSlice];
+  int orientation = computeCurrentOrientation();
+  // DD(orientation);
+
+  updateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
 
+  return;
+  
   // Do it
-  mSquares->SetValue(0,value);
+  mSquares->SetValue(0, mValue );
 
   int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
-  mClipper->SetOutputWholeExtent(extent[0],extent[1],extent[2],
-                                extent[3],extent[4],extent[5]);
+  // DD(extent[0]);
+  // DD(extent[1]);
+  // DD(extent[2]);
+  // DD(extent[3]);
+  // DD(extent[4]);
+  // DD(extent[5]);
+
+  // int* extent2 = mClipper->GetInput()->GetDisplayExtent();
+  // DD(extent2[0]);
+  // DD(extent2[1]);
+  int* extent2 = new int[6];
+  if (mHiddenImageIsUsed) {
+    int * extent3;
+    extent3 = mHiddenImage->GetFirstVTKImageData()->GetExtent();
+    for(int i=0; i<6; i++) extent2[i] = extent3[i];
+    // DD(extent2[0]);
+    // DD(extent2[1]);
+    // DD(extent2[2]);
+    // DD(extent2[3]);
+    // DD(extent2[4]);
+    // DD(extent2[5]);
+    for(int i=0; i<6; i+=2) {
+      if (extent[i] != extent[i+1]) { 
+        // extent[i] = extent2[i]; 
+        // extent[i+1] = extent2[i+1]; 
+      }
+      else {
+        // DD(extent[i]);
+        // DD(mSlicer->GetImage()->GetSpacing()[i/2]);
+        // DD(mHiddenImage->GetFirstVTKImageData()->GetSpacing()[i/2]);
+
+        double s = (double)extent[i]*(double)mSlicer->GetImage()->GetSpacing()[i/2]; // in mm
+        // DD(s);
+        s = s+mSlicer->GetImage()->GetOrigin()[i/2]; // from origin
+        // DD(s);
+        s = s-mHiddenImage->GetFirstVTKImageData()->GetOrigin()[i/2]; // from corner second image
+        s = s/mHiddenImage->GetFirstVTKImageData()->GetSpacing()[i/2]; // in voxel
+        // DD(s);
+
+        if (s == floor(s)) { 
+          extent2[i] = extent2[i+1] = (int)floor(s);
+        }
+        else {
+          extent2[i] = (int)floor(s);
+          extent2[i+1] = extent2[i];
+        }
+        // DD(extent2[i]);
+      }
+    }
+  }
+  else extent2 = extent;
+  // DD(extent2[0]);
+  // DD(extent2[1]);
+  // DD(extent2[2]);
+  // DD(extent2[3]);
+  // DD(extent2[4]);
+  // DD(extent2[5]);
+  
+
+  mClipper->SetOutputWholeExtent(extent2[0],extent2[1],extent2[2],
+                                extent2[3],extent2[4],extent2[5]);
   int i;
   for (i = 0; i < 6;i = i+2) {
     if (extent[i] == extent[i+1]) {
@@ -177,3 +291,151 @@ void vvImageContour::update(double value) {
 }
 //------------------------------------------------------------------------------
 
+
+//------------------------------------------------------------------------------
+void vvImageContour::initializeCacheMode() {
+  DD("vvImageContour::initializeCacheMode");
+    
+  mPreviousSlice = mPreviousOrientation = 0;
+  int dim;
+  if (mHiddenImageIsUsed) dim = mHiddenImage->GetNumberOfDimensions();
+  else dim = mSlicer->GetImage()->GetNumberOfDimensions();
+  DD(dim);
+
+  mListOfCachedContourActors.resize(dim);
+  for(int d=0; d<dim; d++) {
+    DD(d);
+    int size;
+    if (mHiddenImageIsUsed) size = mHiddenImage->GetSize()[d];
+    else size = mSlicer->GetImage()->GetSize()[d];
+    DD(size);
+    mListOfCachedContourActors[d].resize(size);
+    for(int j=0; j<size; j++) {
+      mListOfCachedContourActors[d][j] = NULL;
+      DD(mListOfCachedContourActors.size());
+      DD(mListOfCachedContourActors[d].size());
+    }
+  }
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+int vvImageContour::computeCurrentOrientation() {
+  // Get extent of image in the slicer
+  int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
+  
+  // Compute orientation
+  int orientation;
+  for (orientation = 0; orientation < 6;orientation = orientation+2) {
+    if (extent[orientation] == extent[orientation+1]) {
+      break;
+    }
+  }
+  orientation = orientation/2;
+  // DD(orientation);
+  return orientation;
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvImageContour::updateWithFastCacheMode() {
+  DD("vvImageContour::updateWithFastCacheMode");
+
+  // Compute orientation
+  int orientation = computeCurrentOrientation();
+
+  // Turn off previous actor
+  DD(mPreviousOrientation);
+  DD(mPreviousSlice);
+  if (mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice] != NULL)
+    mListOfCachedContourActors[mPreviousOrientation][mPreviousSlice]->VisibilityOff();
+  mPreviousSlice = mSlice;
+  mPreviousOrientation = orientation;
+
+  // Display actor if it exist
+  vtkActor * actor = mListOfCachedContourActors[orientation][mSlice];
+  if (actor != NULL) {
+    DD("Actor exist");
+    mListOfCachedContourActors[orientation][mSlice]->VisibilityOn();
+  }
+  else {
+    vtkImageClip * mClipper;
+    vtkMarchingSquares * mSquares;
+    vtkActor * mSquaresActor;
+    createNewActor(&mSquaresActor, &mSquares, &mClipper);
+    updateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
+    mListOfCachedContourActors[orientation][mSlice] = mSquaresActor;
+    mSquaresActor->VisibilityOn();
+  }
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvImageContour::createNewActor(vtkActor ** actor, 
+                                   vtkMarchingSquares ** squares, 
+                                   vtkImageClip ** clipper) {
+  // DD("vvImageContour::CreateNewActor");
+  vtkActor * mSquaresActor = (*actor = vtkActor::New());
+  vtkImageClip * mClipper = (*clipper = vtkImageClip::New());
+  vtkMarchingSquares * mSquares = (*squares = vtkMarchingSquares::New());
+  vtkPolyDataMapper * mSquaresMapper = vtkPolyDataMapper::New();
+  
+  if (mHiddenImageIsUsed) 
+    mClipper->SetInput(mHiddenImage->GetVTKImages()[0]);
+  else 
+    mClipper->SetInput(mSlicer->GetImage()->GetVTKImages()[0]);
+  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);  
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvImageContour::updateActor(vtkActor * actor, 
+                                vtkMarchingSquares * squares, 
+                                vtkImageClip * clipper, 
+                                int threshold, int orientation, int slice) {
+  // DD("Update Actor according to extend/threshold");
+  
+  int* extent = mSlicer->GetImageActor()->GetDisplayExtent();
+  clipper->SetOutputWholeExtent(extent[0],extent[1],extent[2],
+                                extent[3],extent[4],extent[5]);
+  squares->SetValue(0, threshold);
+
+  switch (orientation)  {
+  case 0: if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0] > slice) {
+      actor->SetPosition(1,0,0);
+    }
+    else {
+      actor->SetPosition(-1,0,0);
+    }
+    break;
+  case 1: if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1] > slice) {
+      actor->SetPosition(0,1,0);
+    }
+    else {
+      actor->SetPosition(0,-1,0);
+    }
+    break;
+  case 2: if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2] > slice) {
+      actor->SetPosition(0,0,1);
+    }
+    else {
+      actor->SetPosition(0,0,-1);
+    }
+    break;
+  }
+  squares->Update();
+}
+//------------------------------------------------------------------------------
+
+
index 5b16d3541387385fa91e20eaf49716095def2bed..ad1143dd963399ca01319dbc382e78da529fe1e2 100644 (file)
 ======================================================================-====*/
 #ifndef VVIMAGECONTOUR_H
 #define VVIMAGECONTOUR_H
+
 #include "clitkCommon.h"
 #include "vvSlicer.h"
+
 class vtkImageClip;
 class vtkMarchingSquares;
 class vtkActor;
+class vvImage;
 
 //------------------------------------------------------------------------------
 class vvImageContour
@@ -36,17 +39,42 @@ class vvImageContour
   void hideActors();
   void showActors();
   void setColor(double r, double g, double b);
+  void setImage(vvImage::Pointer image);
+  void setPreserveModeEnabled(bool b);
 
  protected:
   vvSlicer * mSlicer;
   int mSlice;
   int mTSlice;
   double mValue;
+  bool mHiddenImageIsUsed;
+  vvImage::Pointer mHiddenImage;
+  bool mDisplayModeIsPreserveMemory;
 
+  // For preserveMemory mode
   std::vector<vtkImageClip*> mClipperList;
   std::vector<vtkMarchingSquares*> mSquaresList;
   std::vector<vtkActor*> mSquaresActorList;
 
+  // For fast cache mode
+  int mPreviousSlice;
+  int mPreviousOrientation;
+  std::vector<std::vector<vtkActor*> > mListOfCachedContourActors;
+
+  // Functions
+  void initializeCacheMode();
+  void updateWithPreserveMemoryMode();
+  void updateWithFastCacheMode();
+  void createNewActor(vtkActor ** actor, 
+                     vtkMarchingSquares ** squares, 
+                     vtkImageClip ** clipper);
+  void updateActor(vtkActor * actor, 
+                  vtkMarchingSquares * squares,
+                  vtkImageClip * clipper, 
+                  int threshold, int orientation, int slice);
+  void createActor(int orientation, int slice);
+  int computeCurrentOrientation();
+  
 }; // end class vvImageContour
 //------------------------------------------------------------------------------
 
index 422f3ef977cc3c3ed2db42e7718e288f390d14ee..c7d05c65d333f75cc61d5c0019670991fd347f84 100644 (file)
@@ -2378,7 +2378,8 @@ void vvMainWindow::NOVerticalSliderChanged() {
       if (DataTree->topLevelItem(i)->data(COLUMN_UL_VIEW,Qt::CheckStateRole).toInt() > 1)
         {
           mSlicerManagers[i]->GetSlicer(0)->SetSlice(value);
-          mSlicerManagers[i]->UpdateSlice(0); // <-- DS add this. Not too much update ? 
+          // mSlicerManagers[i]->UpdateSlice(0);
+          // <-- DS add this. Not too much update ? YES.
           break;
         }
     }
index 53801929f8df7a51b7011483ee2f6b2f1f837b25..85356864018f5746f50146707a734dd7b2c3abbc 100644 (file)
@@ -635,6 +635,8 @@ void vvSlicerManager::UpdateViews(int current,int slicer)
                    mSlicers[i]->SetSlice((int)floor(x));
                  break;
                 }
+              // DD("UpdateViews::");
+              // DD(i);
              UpdateSlice(i);
              UpdateTSlice(i);
             }
@@ -932,6 +934,9 @@ void vvSlicerManager::UpdateWindowLevel()
 //----------------------------------------------------------------------------
 void vvSlicerManager::UpdateSlice(int slicer)
 {
+  // DD("vvSlicerManager::UpdateSlice emit UpdateSlice");
+  // DD(slicer);
+  // DD(mSlicers[slicer]->GetSlice());
   emit UpdateSlice(slicer, mSlicers[slicer]->GetSlice());
 }
 //----------------------------------------------------------------------------
index 0b1b5407078411b9a7584140f75c3ac42fa103ad..74c1e4c43c53207ca6a281c0f594f3fa0a97203b 100644 (file)
@@ -56,7 +56,7 @@ vvToolCropImage::~vvToolCropImage() {
 
 //------------------------------------------------------------------------------
 bool vvToolCropImage::close() { 
-  for(int i=0; i<6; i++) mReducedExtent[i] = mInitialExtent[i];
+  for(int i=0; i<mExtentSize; i++) mReducedExtent[i] = mInitialExtent[i];
   UpdateExtent();
   return vvToolWidgetBase::close(); 
 }
@@ -65,7 +65,7 @@ bool vvToolCropImage::close() {
 
 //------------------------------------------------------------------------------
 void vvToolCropImage::reject() { 
-  for(int i=0; i<6; i++) mReducedExtent[i] = mInitialExtent[i];
+  for(int i=0; i<mExtentSize; i++) mReducedExtent[i] = mInitialExtent[i];
   UpdateExtent();
   return vvToolWidgetBase::reject(); 
 }
@@ -181,7 +181,7 @@ void vvToolCropImage::InputIsSelected(vvSlicerManager * slicer) {
   mReducedExtent = new int[mExtentSize];
   mInitialExtent = new int[mExtentSize];
   mReducedExtent = mCurrentSlicerManager->GetImage()->GetFirstVTKImageData()->GetWholeExtent();
-  for(int i=0; i<6; i++) mInitialExtent[i] = mReducedExtent[i];
+  for(int i=0; i<mExtentSize; i++) mInitialExtent[i] = mReducedExtent[i];
   for(int i=0; i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
     //DD(i);
     //DD(mReducedExtent[i]);
index f7077a8f6b4ffb8e122efdf01011f8503f7e638a..3ab39650afecd133ff2408eaffaef5df1c6a639c 100644 (file)
@@ -57,7 +57,7 @@ void vvToolImageArithm::Initialize() {
   SetToolMenuName("ImageArithm");
   SetToolIconFilename(":/common/icons/arithm.png");
   SetToolTip("Perform simple arithmetic operations on one or two images.");
-  SetToolExperimental(true);
+  SetToolExperimental(false);
 }
 //------------------------------------------------------------------------------