]> Creatis software - clitk.git/commitdiff
Merge branch 'master' of git.creatis.insa-lyon.fr:clitk
authorBenoît Presles <benoit.presles@creatis.insa-lyon.fr>
Thu, 20 Dec 2012 17:30:01 +0000 (18:30 +0100)
committerBenoît Presles <benoit.presles@creatis.insa-lyon.fr>
Thu, 20 Dec 2012 17:30:01 +0000 (18:30 +0100)
vv/qt_ui/vvLandmarksPanel.ui
vv/vv.cxx
vv/vvLandmarks.cxx
vv/vvLandmarks.h
vv/vvLandmarksPanel.cxx
vv/vvLandmarksPanel.h
vv/vvMainWindow.cxx
vv/vvMainWindow.h

index 7a64ea6b9940e946ddb99be2cb72c1d7dd3b726c..8cbe197d9134697bf47c17da6acb55d0c6ad4fd5 100644 (file)
@@ -7,20 +7,14 @@
     <x>0</x>
     <y>0</y>
     <width>325</width>
-    <height>131</height>
+    <height>214</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QGridLayout">
-   <property name="margin">
-    <number>2</number>
-   </property>
-   <property name="spacing">
-    <number>2</number>
-   </property>
-   <item row="0" column="0" colspan="4">
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0" colspan="2">
     <widget class="QLabel" name="nameLabel">
      <property name="text">
       <string>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
@@ -30,7 +24,14 @@ p, li { white-space: pre-wrap; }
      </property>
     </widget>
    </item>
-   <item row="2" column="0" colspan="4">
+   <item row="1" column="0" colspan="2">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Coordinates are in mm</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0" colspan="5">
     <widget class="QTableWidget" name="tableWidget">
      <property name="columnCount">
       <number>7</number>
@@ -84,7 +85,7 @@ p, li { white-space: pre-wrap; }
       <string>remove last landmark.</string>
      </property>
      <property name="text">
-      <string/>
+      <string>1</string>
      </property>
      <property name="icon">
       <iconset resource="../vvIcons.qrc">
@@ -93,19 +94,30 @@ p, li { white-space: pre-wrap; }
     </widget>
    </item>
    <item row="3" column="1">
-    <spacer>
+    <widget class="QPushButton" name="removeAllButton">
+     <property name="text">
+      <string>All</string>
+     </property>
+     <property name="icon">
+      <iconset resource="../vvIcons.qrc">
+       <normaloff>:/common/icons/standardbutton-cancel-16.png</normaloff>:/common/icons/standardbutton-cancel-16.png</iconset>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="2">
+    <spacer name="spacer">
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
-       <width>40</width>
+       <width>39</width>
        <height>20</height>
       </size>
      </property>
     </spacer>
    </item>
-   <item row="3" column="2">
+   <item row="3" column="3">
     <widget class="QPushButton" name="loadButton">
      <property name="text">
       <string>Load</string>
@@ -116,7 +128,7 @@ p, li { white-space: pre-wrap; }
      </property>
     </widget>
    </item>
-   <item row="3" column="3">
+   <item row="3" column="4">
     <widget class="QPushButton" name="saveButton">
      <property name="text">
       <string>Save</string>
@@ -127,13 +139,6 @@ p, li { white-space: pre-wrap; }
      </property>
     </widget>
    </item>
-   <item row="1" column="0">
-    <widget class="QLabel" name="label">
-     <property name="text">
-      <string>Coordinates are in mm</string>
-     </property>
-    </widget>
-   </item>
   </layout>
  </widget>
  <resources>
index 47057e4a0ed335cc3720cec279c5ffcfab6f9c29..2b20ac914e648af30483917d443b4488a217ae7c 100644 (file)
--- a/vv/vv.cxx
+++ b/vv/vv.cxx
@@ -45,7 +45,7 @@
 #include <sys/stat.h>
 #include <errno.h>
 
-typedef enum {O_BASE,O_OVERLAY,O_FUSION,O_VF,O_CONTOUR} OpenModeType;
+typedef enum {O_BASE,O_OVERLAY,O_FUSION,O_VF,O_CONTOUR,O_LANDMARKS} OpenModeType;
 typedef enum {P_NORMAL,P_SEQUENCE,P_WINDOW,P_LEVEL} ParseModeType;
 
 void load_image_first_error()
@@ -79,6 +79,8 @@ void open_sequence(vvMainWindow &window,
     window.LoadImages(sequence_filenames, vvImageReader::MERGEDWITHTIME);
   else if (open_mode==O_OVERLAY)
     window.AddOverlayImage(n_image_loaded-1,sequence_filenames,vvImageReader::MERGEDWITHTIME);
+  else if (open_mode==O_LANDMARKS)
+    window.AddLandmarks(n_image_loaded-1,sequence_filenames);
   else {
     std::cerr << "Sequences are not managed for opening " << open_mode_names[open_mode] << std::endl;
     exit(1);
@@ -181,7 +183,8 @@ int main( int argc, char** argv )
                     << "--overlay file \t Overlay the image in file with complementary colors." << std::endl
                     << "--fusion file  \t Overlay the image in file with alpha blending and colormap." << std::endl
                     //<< "--roi file     \t Overlay binary mask images. Option may be repeated on a single base image." << std::endl
-                    << "--contour file \t Overlay DICOM RT-STRUCT contours." << std::endl;
+                    << "--contour file \t Overlay DICOM RT-STRUCT contours." << std::endl
+                    << "--landmarks [--sequence] file(s)  \t Overlay the landmarks in file(s) (.txt or .pts)." << std::endl;
           exit(0);
         } else if (current=="--vf") {
           if (!n_image_loaded) load_image_first_error();
@@ -195,6 +198,9 @@ int main( int argc, char** argv )
         } else if (current=="--fusion") {
           if (!n_image_loaded) load_image_first_error();
           open_mode = O_FUSION;
+        } else if (current=="--landmarks") {
+          if (!n_image_loaded) load_image_first_error();
+          open_mode = O_LANDMARKS;
         } else if (current == "--sequence") {
           if(open_mode==O_BASE) n_image_loaded++; //count only one for the whole sequence
           parse_mode=P_SEQUENCE;
@@ -273,6 +279,8 @@ int main( int argc, char** argv )
           window.AddDCStructContour(n_image_loaded-1,current.c_str());
         else if (open_mode==O_FUSION)
           window.AddFusionImage(n_image_loaded-1,current.c_str());
+        else if (open_mode==O_LANDMARKS)
+          window.AddLandmarks(n_image_loaded-1,image);
         open_mode = O_BASE;
       }
     }
index 0bab2f4305a8434023ffaa9751fdaf236f5f3fda..fed697ebc2a218943ac125b4676e15ac1f3afd70 100644 (file)
 #include "vtkFloatArray.h"
 #include "vtkPointData.h"
 #include "clitkCommon.h"
+#include <itksys/SystemTools.hxx>
 
 //--------------------------------------------------------------------
 vvLandmarks::vvLandmarks(int size)
 {
-  mLandmarks.resize(0);
-  mFilename = "";
+  mLandmarks.resize(size);
+  mFilenames.resize(0);
+  mTime = 0;
 
   for (int i = 0; i < size; i++) {
+    mLandmarks[i].resize(0);
     vtkPoints *points = vtkPoints::New();
     mPoints.push_back(points);
+    mIds.push_back(vtkFloatArray::New());
+    mLabels.push_back(vtkStringArray::New());
+    mLabels.back()->SetName("labels");
   }
   mPolyData = vtkPolyData::New();
-  mIds = vtkFloatArray::New();
-  mLabels = vtkStringArray::New();
-  mLabels->SetName("labels");
 }
 //--------------------------------------------------------------------
 
@@ -52,16 +55,14 @@ vvLandmarks::~vvLandmarks()
 {
   for (unsigned int i = 0; i < mPoints.size(); i++) {
     mPoints[i]->Delete();
+    mIds[i]->Delete();
+    mLabels[i]->Delete();
   }
   /*for(unsigned int i = 0; i < mText.size(); i++) {
     mText[i]->Delete();
     }*/
-  if (mIds)
-    mIds->Delete();
   if (mPolyData)
     mPolyData->Delete();
-  if (mLabels)
-    mLabels->Delete();
 }
 //--------------------------------------------------------------------
 
@@ -76,14 +77,14 @@ void vvLandmarks::AddLandmark(float x,float y,float z,float t,double value)
   point.coordinates[2] = z;
   point.coordinates[3] = t;
   point.pixel_value=value;
-  mLandmarks.push_back(point);
+  mLandmarks[mTime].push_back(point);
 
   idPoint = mPoints[int(t)]->InsertNextPoint(x,y,z);
   std::string str_vtkIdType;       // string which will contain the result
   std::ostringstream convert;      // stream used for the conversion
   convert << idPoint;                  // insert the textual representation of 'idPoint' in the characters in the stream
   str_vtkIdType = convert.str();    // set 'str_vtkIdType' to the contents of the stream
-  mLabels->InsertNextValue(str_vtkIdType.c_str());
+  mLabels[mTime]->InsertNextValue(str_vtkIdType.c_str());
 
   std::stringstream numberVal;
   numberVal << (mLandmarks.size()-1);
@@ -95,7 +96,7 @@ void vvLandmarks::AddLandmark(float x,float y,float z,float t,double value)
   mText.push_back(number);
   */
 
-  mIds->InsertNextTuple1(0.55);
+  mIds[mTime]->InsertNextTuple1(0.55);
   //mIds->InsertTuple1(mLandmarks.size(),mLandmarks.size());
   SetTime(int(t));
 }
@@ -105,13 +106,12 @@ void vvLandmarks::AddLandmark(float x,float y,float z,float t,double value)
 //--------------------------------------------------------------------
 void vvLandmarks::RemoveLastLandmark()
 {
-  mPoints[mLandmarks.back().coordinates[3]]->SetNumberOfPoints(
-                                                               mPoints[mLandmarks.back().coordinates[3]]->GetNumberOfPoints()-1);
+  mPoints[mTime]->SetNumberOfPoints(mPoints[mTime]->GetNumberOfPoints()-1);
   //  mText.pop_back();
-  mLandmarks.pop_back();
-  mIds->RemoveLastTuple();
-  mLabels->SetNumberOfValues(mLabels->GetNumberOfValues()-1);
-  mLabels->Modified();
+  mLandmarks[mTime].pop_back();
+  mIds[mTime]->RemoveLastTuple();
+  mLabels[mTime]->SetNumberOfValues(mLabels[mTime]->GetNumberOfValues()-1);
+  mLabels[mTime]->Modified();
   mPolyData->Modified();
 }
 //--------------------------------------------------------------------
@@ -123,31 +123,42 @@ void vvLandmarks::RemoveLandmark(int index)
   // erase a vtkPoint by shifiting the array .
   // not a problem here because there are no 
   // pologyons linking the points
-  int npoints = mPoints[mLandmarks[index].coordinates[3]]->GetNumberOfPoints();
-  int t = mLandmarks[index].coordinates[3];
+  int t = mTime;//mLandmarks[index].coordinates[3];
+  int npoints = mPoints[t]->GetNumberOfPoints();
   for (int i = index; i < npoints - 1; i++) {
     mPoints[t]->InsertPoint(i, mPoints[t]->GetPoint(i+1));
        std::string str_i;                   // string which will contain the result
        std::ostringstream convert;      // stream used for the conversion
        convert << i;                        // insert the textual representation of 'i' in the characters in the stream
        str_i = convert.str();           // set 'str_i' to the contents of the stream
-       mLabels->SetValue(i,str_i.c_str());
+       mLabels[t]->SetValue(i,str_i.c_str());
     }
   mPoints[t]->SetNumberOfPoints(npoints-1);
-  mLabels->SetNumberOfValues(npoints-1);
-  mLabels->Modified();
+  mLabels[t]->SetNumberOfValues(npoints-1);
+  mLabels[t]->Modified();
   mPolyData->Modified();
 
-  mLandmarks.erase(mLandmarks.begin() + index);
-  mIds->RemoveLastTuple();
+  mLandmarks[t].erase(mLandmarks[t].begin() + index);
+  mIds[t]->RemoveLastTuple();
 }
 //--------------------------------------------------------------------
 
+//--------------------------------------------------------------------
+void vvLandmarks::RemoveAll()
+{
+  for (unsigned int i = 0; i < mLandmarks.size(); i++) {
+    mLandmarks[i].clear();
+    mPoints[i]->SetNumberOfPoints(0);
+    mLabels[i]->SetNumberOfValues(0);
+    mIds[i]->SetNumberOfValues(0);
+  }
+}
+//--------------------------------------------------------------------
 
 //--------------------------------------------------------------------
 void vvLandmarks::ChangeComments(int index, std::string comments)
 {
-  mLandmarks[index].comments = comments;
+  mLandmarks[mTime][index].comments = comments;
 }
 //--------------------------------------------------------------------
 
@@ -155,7 +166,7 @@ void vvLandmarks::ChangeComments(int index, std::string comments)
 //--------------------------------------------------------------------
 double vvLandmarks::GetPixelValue(int index)
 {
-  return mLandmarks[index].pixel_value;
+  return mLandmarks[mTime][index].pixel_value;
 }
 //--------------------------------------------------------------------
 
@@ -163,7 +174,7 @@ double vvLandmarks::GetPixelValue(int index)
 //--------------------------------------------------------------------
 float* vvLandmarks::GetCoordinates(int index)
 {
-  return mLandmarks[index].coordinates;
+  return mLandmarks[mTime][index].coordinates;
 }
 //--------------------------------------------------------------------
 
@@ -171,116 +182,224 @@ float* vvLandmarks::GetCoordinates(int index)
 //--------------------------------------------------------------------
 std::string vvLandmarks::GetComments(int index)
 {
-  return mLandmarks[index].comments;
+  return mLandmarks[mTime][index].comments;
 }
 //--------------------------------------------------------------------
 
 
 //--------------------------------------------------------------------
-void vvLandmarks::LoadFile(std::string filename)
+bool vvLandmarks::LoadFile(std::vector<std::string> filenames)
 {
-  std::ifstream fp(filename.c_str(), std::ios::in|std::ios::binary);
-  if (!fp.is_open()) {
-    std::cerr <<"Unable to open file " << filename << std::endl;
-    return;
-  }
-  mFilename = filename;
-  mLandmarks.clear();
-  vtkIdType idPoint;
-  char line[255];
-  for (unsigned int i = 0; i < mPoints.size(); i++)
+  // all files in the sequence must be of the same type
+  std::string extension = itksys::SystemTools::GetFilenameExtension(filenames[0]);
+  if (extension == ".txt")
+    return LoadTxtFile(filenames);
+  else if (extension == ".pts")
+    return LoadPtsFile(filenames);
+
+  return false;
+}
+
+//--------------------------------------------------------------------
+bool vvLandmarks::LoadTxtFile(std::vector<std::string> filenames)
+{
+  mFilenames = filenames;
+  for (unsigned int i = 0; i < mPoints.size(); i++) {
+    mLandmarks[i].clear();
     mPoints[i]->SetNumberOfPoints(0);
-  bool first_line=true;
-  while (fp.getline(line,255)) {
-    //    DD(line);
-    std::string stringline = line;
-    if (first_line) {
-      first_line=false;
-      ///New landmark format: first line is "LANDMARKSXX", where XX is the version number
-      if (stringline.size() >= 10 && stringline.compare(0,9,"LANDMARKS")==0) {
-        std::istringstream ss(stringline.c_str()+9);
-        ss >> mFormatVersion;
-        continue; //skip first line
-      } else
-        mFormatVersion=0;
+  }
+
+  int err = 0;
+  for (unsigned int f = 0; f < filenames.size(); f++) {
+    std::ifstream fp(filenames[f].c_str(), std::ios::in|std::ios::binary);
+    if (!fp.is_open()) {
+      std::cerr <<"Unable to open file " << filenames[f] << std::endl;
+      err++;
     }
-    if (stringline.size() > 1) {
-      vvLandmark point;
-      int previousSpace = 0;
-      int space=0;
-      if (mFormatVersion>0) {
+    vtkIdType idPoint;
+    char line[255];
+    bool first_line=true;
+    while (fp.getline(line,255)) {
+      //    DD(line);
+      std::string stringline = line;
+      stringline += "\n";
+      
+      if (first_line) {
+        first_line=false;
+        ///New landmark format: first line is "LANDMARKSXX", where XX is the version number
+        if (stringline.size() >= 10 && stringline.compare(0,9,"LANDMARKS")==0) {
+          std::istringstream ss(stringline.c_str()+9);
+          ss >> mFormatVersion;
+          continue; //skip first line
+        } else
+          mFormatVersion=0;
+      }
+      if (stringline.size() > 1) {
+        vvLandmark point;
+        int previousSpace = 0;
+        int space=0;
+        if (mFormatVersion>0) {
+          space = stringline.find(" ", previousSpace+1);
+          if (space < -1 || space > (int)stringline.size()) {
+            ErrorMsg(mLandmarks.size(),"index");
+            continue;
+          }
+          //int index = atoi(stringline.substr(previousSpace,space - previousSpace).c_str());
+          previousSpace = space;
+        }
         space = stringline.find(" ", previousSpace+1);
         if (space < -1 || space > (int)stringline.size()) {
-          ErrorMsg(mLandmarks.size(),"index");
+          ErrorMsg(mLandmarks.size(),"x position");
           continue;
         }
-        //int index = atoi(stringline.substr(previousSpace,space - previousSpace).c_str());
+        point.coordinates[0] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+        //      DD(point.coordinates[0]);
         previousSpace = space;
-      }
-      space = stringline.find(" ", previousSpace+1);
-      if (space < -1 || space > (int)stringline.size()) {
-        ErrorMsg(mLandmarks.size(),"x position");
-        continue;
-      }
-      point.coordinates[0] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
-      //      DD(point.coordinates[0]);
-      previousSpace = space;
-      space = stringline.find(" ", previousSpace+1);
-      if (space < -1 || space > (int)stringline.size()) {
-        ErrorMsg(mLandmarks.size(),"y position");
-        continue;
-      }
-      point.coordinates[1] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
-      //      DD(point.coordinates[1]);
-      previousSpace = space;
-      space = stringline.find(" ", previousSpace+1);
-      if (space < -1 || space > (int)stringline.size()) {
-        ErrorMsg(mLandmarks.size(),"z position");
-        continue;
-      }
-      point.coordinates[2] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
-      previousSpace = space;
-      if (mFormatVersion>0) {
         space = stringline.find(" ", previousSpace+1);
         if (space < -1 || space > (int)stringline.size()) {
-          ErrorMsg(mLandmarks.size(),"t position");
+          ErrorMsg(mLandmarks.size(),"y position");
           continue;
         }
-        point.coordinates[3] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+        point.coordinates[1] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+        //      DD(point.coordinates[1]);
         previousSpace = space;
         space = stringline.find(" ", previousSpace+1);
         if (space < -1 || space > (int)stringline.size()) {
-          ErrorMsg(mLandmarks.size(),"pixel value");
+          ErrorMsg(mLandmarks.size(),"z position");
           continue;
         }
-        point.pixel_value = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
-        //        DD(point.pixel_value);
-      } else {
-        point.pixel_value=0.; //Not in file
-        point.coordinates[3]=0.;
-      }
-      previousSpace = space;
-      //this is the maximum size of comments
-      space = (stringline.find("\n", previousSpace+1) < 254 ? stringline.find("\n", previousSpace+1) : 254);
-      if (previousSpace != -1) {
-        point.comments = stringline.substr(previousSpace,space - (previousSpace)).c_str();
+        point.coordinates[2] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+        previousSpace = space;
+        if (mFormatVersion>0) {
+          space = stringline.find(" ", previousSpace+1);
+          if (space < -1 || space > (int)stringline.size()) {
+            ErrorMsg(mLandmarks.size(),"t position");
+            continue;
+          }
+          point.coordinates[3] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+          previousSpace = space;
+          space = stringline.find(" ", previousSpace+1);
+          if (space < -1 || space > (int)stringline.size()) {
+            ErrorMsg(mLandmarks.size(),"pixel value");
+            continue;
+          }
+          point.pixel_value = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+          //        DD(point.pixel_value);
+        } else {
+          point.pixel_value=0.; //Not in file
+          point.coordinates[3]=(float)f;
+        }
+        previousSpace = space;
+        //this is the maximum size of comments
+        space = (stringline.find("\n", previousSpace+1) < 254 ? stringline.find("\n", previousSpace+1) : 254);
+        if (previousSpace != -1) {
+          point.comments = stringline.substr(previousSpace,space - (previousSpace)).c_str();
+        }
+        //      DD(point.comments);
+        mLandmarks[int(point.coordinates[3])].push_back(point);
+        mIds[int(point.coordinates[3])]->InsertNextTuple1(0.55);
+        idPoint = mPoints[int(point.coordinates[3])]->InsertNextPoint(
+                                                            point.coordinates[0],point.coordinates[1],point.coordinates[2]);
+        std::string str_vtkIdType;         // string which will contain the result
+        std::ostringstream convert;    // stream used for the conversion
+        convert << idPoint;                // insert the textual representation of 'idPoint' in the characters in the stream
+        str_vtkIdType = convert.str(); // set 'str_vtkIdType' to the contents of the stream
+        mLabels[int(point.coordinates[3])]->InsertNextValue(str_vtkIdType.c_str());
       }
-      //      DD(point.comments);
-      mLandmarks.push_back(point);
-      mIds->InsertNextTuple1(0.55);
-     idPoint = mPoints[int(point.coordinates[3])]->InsertNextPoint(
-                                                          point.coordinates[0],point.coordinates[1],point.coordinates[2]);
-     std::string str_vtkIdType;            // string which will contain the result
-     std::ostringstream convert;       // stream used for the conversion
-     convert << idPoint;                   // insert the textual representation of 'idPoint' in the characters in the stream
-     str_vtkIdType = convert.str(); // set 'str_vtkIdType' to the contents of the stream
-     mLabels->InsertNextValue(str_vtkIdType.c_str());
     }
   }
+
+  if (err > 0 && err == filenames.size())
+    return false;
+  
   SetTime(0);
+  
+  return true;
 }
 //--------------------------------------------------------------------
 
+//--------------------------------------------------------------------
+bool vvLandmarks::LoadPtsFile(std::vector<std::string> filenames)
+{
+  mFilenames = filenames;
+  for (unsigned int i = 0; i < mPoints.size(); i++) {
+    mPoints[i]->SetNumberOfPoints(0);
+    mLandmarks[i].clear();
+  }
+
+  int err = 0;
+  for (unsigned int f = 0; f < filenames.size(); f++) {
+    std::ifstream fp(filenames[f].c_str(), std::ios::in|std::ios::binary);
+    if (!fp.is_open()) {
+      std::cerr <<"Unable to open file " << filenames[f] << std::endl;
+      err++;
+    }
+    vtkIdType idPoint;
+    char line[255];
+    bool first_line=true;
+    while (fp.getline(line,255)) {
+      std::string stringline = line;
+      stringline += "\n";
+      
+      std::string separators = "\t\n\r ";
+      if (stringline.size() > 1) {
+        vvLandmark point;
+        int previousSpace = 0;
+        int space=0;
+
+        if (stringline[0] == '#') // comments
+          continue;
+        
+        space = stringline.find_first_of(separators, previousSpace+1);
+        if (space == std::string::npos) {
+          ErrorMsg(mLandmarks.size(),"x position");
+          continue;
+        }
+        point.coordinates[0] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+        //      DD(point.coordinates[0]);
+        previousSpace = space;
+        space = stringline.find_first_of(separators, previousSpace+1);
+        if (space == std::string::npos) {
+          ErrorMsg(mLandmarks.size(),"y position");
+          continue;
+        }
+        point.coordinates[1] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+        //      DD(point.coordinates[1]);
+        previousSpace = space;
+        space = stringline.find_first_of(separators, previousSpace+1);
+        if (space == std::string::npos) {
+          ErrorMsg(mLandmarks.size(),"z position");
+          continue;
+        }
+        point.coordinates[2] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+        previousSpace = space;
+        point.pixel_value=0.; //Not in file
+        point.coordinates[3]=(float)f;  //Not in file
+        point.comments = "";  //Not in file
+
+        //      DD(point.comments);
+        mLandmarks[int(point.coordinates[3])].push_back(point);
+        mIds[int(point.coordinates[3])]->InsertNextTuple1(0.55);
+        idPoint = mPoints[int(point.coordinates[3])]->InsertNextPoint(
+                                                            point.coordinates[0],point.coordinates[1],point.coordinates[2]);
+        std::string str_vtkIdType;     // string which will contain the result
+        std::ostringstream convert;  // stream used for the conversion
+        convert << idPoint;        // insert the textual representation of 'idPoint' in the characters in the stream
+        str_vtkIdType = convert.str(); // set 'str_vtkIdType' to the contents of the stream
+        mLabels[int(point.coordinates[3])]->InsertNextValue(str_vtkIdType.c_str());
+      }
+    }
+  }
+  
+  SetTime(0);
+  DD("vvLandmarks::LoadPtsFile")
+  if (err > 0 && err == filenames.size())
+    return false;
+
+  
+  return true;
+}
+//--------------------------------------------------------------------
 
 //--------------------------------------------------------------------
 bool vvLandmarks::ErrorMsg(int num,const char * text)
@@ -295,21 +414,23 @@ bool vvLandmarks::ErrorMsg(int num,const char * text)
 void vvLandmarks::SaveFile(std::string filename)
 {
   std::string fileContent = "LANDMARKS1\n"; //File format version identification
-  for (unsigned int i = 0; i < mLandmarks.size(); i++) {
-    std::stringstream out;
-    out.imbue(std::locale("C")); //This is to specify that the dot is to be used as the decimal separator
-    out << i << " "
-        << mLandmarks[i].coordinates[0] << " "
-        << mLandmarks[i].coordinates[1] << " "
-        << mLandmarks[i].coordinates[2] << " "
-        << mLandmarks[i].coordinates[3] << " "
-        << mLandmarks[i].pixel_value << " ";
-    fileContent += out.str();
-    if (mLandmarks[i].comments.size() == 0)
-      fileContent += " ";
-    else
-      fileContent += mLandmarks[i].comments;
-    fileContent += "\n";
+  for (unsigned int t = 0; t < mLandmarks.size(); t++) {
+    for (unsigned int i = 0; i < mLandmarks[t].size(); i++) {
+      std::stringstream out;
+      out.imbue(std::locale("C")); //This is to specify that the dot is to be used as the decimal separator
+      out << i << " "
+          << mLandmarks[t][i].coordinates[0] << " "
+          << mLandmarks[t][i].coordinates[1] << " "
+          << mLandmarks[t][i].coordinates[2] << " "
+          << mLandmarks[t][i].coordinates[3] << " "
+          << mLandmarks[t][i].pixel_value << " ";
+      fileContent += out.str();
+      if (mLandmarks[t][i].comments.size() == 0)
+        fileContent += " ";
+      else
+        fileContent += mLandmarks[t][i].comments;
+      fileContent += "\n";
+    }
   }
   std::ofstream fp(filename.c_str(), std::ios::trunc);
   if ( !fp ) {
@@ -327,10 +448,11 @@ void vvLandmarks::SetTime(int time)
 {
   if (time >= 0 && time <= ((int)mPoints.size() -1)) {
     mPolyData->SetPoints(mPoints[time]);
-    mPolyData->GetPointData()->SetScalars(mIds);
-    mPolyData->GetPointData()->AddArray(mLabels);
+    mPolyData->GetPointData()->SetScalars(mIds[time]);
+    mPolyData->GetPointData()->AddArray(mLabels[time]);
     mPolyData->Modified();
     mPolyData->Update();
+    mTime = time;
   }
 }
 //--------------------------------------------------------------------
index 8f9471729d92462a0145f78e4ee95c92b0aca3c4..7920d6f9357787b3ccea6ff27b2e80214a4932d1 100644 (file)
@@ -39,17 +39,19 @@ public :
     vvLandmarks(int size);
     ~vvLandmarks();
 
-    void LoadFile(std::string filename);
+    bool LoadFile(std::vector<std::string> filename);
     void SaveFile(std::string filename);
 
     void AddLandmark(float x,float y,float z,float t,double value);
     void RemoveLastLandmark();
     void RemoveLandmark(int index);
+    void RemoveAll();
+    
     void ChangeComments(int index, std::string comments);
     float* GetCoordinates(int index);
     double GetPixelValue(int index);
     std::string GetComments(int index);
-    unsigned int GetNumberOfPoints() { return (unsigned int) mLandmarks.size(); }
+    unsigned int GetNumberOfPoints() { return (unsigned int) mLandmarks[mTime].size(); }
     //int GetNumberOfSources(){return mText.size();}
 
     vtkPolyData* GetOutput() {
@@ -57,20 +59,29 @@ public :
     }
     //vtkPolyData* GetSources(int i){return mText[i]->GetOutput();}
     void SetTime(int time);
+    int GetTime() {return mTime; }
 
     bool ErrorMsg(int num,const char * text);
 
 private:
     ///Helper function to tackle the use of the comma as the decimal separator
     std::string replace_dots(std::string input);
-    std::vector<vvLandmark> mLandmarks;
+    
+    typedef std::vector<vvLandmark> LandmarkContainerType;
+    std::vector<LandmarkContainerType> mLandmarks;
+    
     vtkPolyData *mPolyData;
     std::vector<vtkPoints*> mPoints;
-    vtkFloatArray* mIds;
+    std::vector<vtkFloatArray*> mIds;
     //std::vector<vvLandmarksGlyph*> mText;
-    vtkStringArray* mLabels;
-    std::string mFilename;
+    std::vector<vtkStringArray*> mLabels;
+    std::vector<std::string> mFilenames;
     int mFormatVersion;
+    int mTime;
+
+    bool LoadTxtFile(std::vector<std::string> filenames);
+    bool LoadPtsFile(std::vector<std::string> filenames);
+  
 };
 
 #endif
index 7fb80276ad5c8f6bbfb6642b76cdc45f9cc46680..2d3e1a5503ca4f0702e13947935035afd690d16f 100644 (file)
@@ -25,6 +25,7 @@
 #include "vvLandmarks.h"
 
 #include <vtksys/SystemTools.hxx>
+#include <clitkDD.h>
 
 //====================================================================
 vvLandmarksPanel::vvLandmarksPanel(QWidget * parent):QWidget(parent)
@@ -40,17 +41,29 @@ vvLandmarksPanel::vvLandmarksPanel(QWidget * parent):QWidget(parent)
   connect(loadButton, SIGNAL(clicked()),this,SLOT(Load()));
   connect(saveButton, SIGNAL(clicked()),this,SLOT(Save()));
   connect(removeButton, SIGNAL(clicked()),this,SLOT(RemoveSelectedPoints()));
+  connect(removeAllButton, SIGNAL(clicked()),this,SLOT(RemoveAllPoints()));
   connect(tableWidget,SIGNAL(cellChanged(int,int)),this,SLOT(CommentsChanged(int,int)));
+  connect(tableWidget,SIGNAL(doubleClicked(const QModelIndex &)),this,SLOT(SelectPoint()));
 }
 
 void vvLandmarksPanel::Load()
 {
   QString file = QFileDialog::getOpenFileName(this,tr("Load Landmarks"),
-                 mCurrentPath.c_str(),tr("Landmarks ( *.txt)"));
-  if (!file.isEmpty())
-    mCurrentLandmarks->LoadFile(file.toStdString());
+                 mCurrentPath.c_str(),tr("Landmarks ( *.txt *.pts)"));
+  if (!file.isEmpty()) {
+    std::vector<std::string> files(1, file.toStdString());
+    LoadFromFile(files);
+  }
+}
+
+bool vvLandmarksPanel::LoadFromFile(std::vector<std::string> files)
+{
+  if (!mCurrentLandmarks->LoadFile(files))
+    return false;
+  
   SetCurrentLandmarks(mCurrentLandmarks,2);
   emit UpdateRenderWindows();
+  return true;
 }
 
 void vvLandmarksPanel::Save()
@@ -66,6 +79,25 @@ void vvLandmarksPanel::Save()
   }
 }
 
+void vvLandmarksPanel::SelectPoint()
+{
+  if (tableWidget->rowCount() > 0) {
+    QList<QTableWidgetItem *> items = tableWidget->selectedItems();
+    if (!items.empty()) {
+      // we're using single-selection mode
+      int row = items[0]->row();
+      mSelectedPoint[0] = mCurrentLandmarks->GetCoordinates(row)[0];
+      mSelectedPoint[1] = mCurrentLandmarks->GetCoordinates(row)[1];
+      mSelectedPoint[2] = mCurrentLandmarks->GetCoordinates(row)[2];
+      mSelectedPoint[3] = mCurrentLandmarks->GetCoordinates(row)[3];
+        
+      emit SelectedPointChanged();
+    }
+  }
+
+}
+
+
 void vvLandmarksPanel::RemoveSelectedPoints()
 {
   if (tableWidget->rowCount() > 0) {
@@ -90,6 +122,14 @@ void vvLandmarksPanel::RemoveSelectedPoints()
   }
 }
 
+void vvLandmarksPanel::RemoveAllPoints()
+{
+  mCurrentLandmarks->RemoveAll();
+  tableWidget->clearContents();
+  tableWidget->setRowCount(0);
+  emit UpdateRenderWindows();
+}
+
 void vvLandmarksPanel::AddPoint()
 {
   AddPoint(mCurrentLandmarks->GetNumberOfPoints()-1);
@@ -97,10 +137,11 @@ void vvLandmarksPanel::AddPoint()
 
 void vvLandmarksPanel::AddPoint(int landmarksIndex)
 {
-  int rowIndex = landmarksIndex; //tableWidget->rowCount();
+  int rowIndex = tableWidget->rowCount();
+//   DD(rowIndex);
   tableWidget->setRowCount(rowIndex+1);
   tableWidget->setRowHeight(rowIndex,20);
-  QTableWidgetItem* iItem = new QTableWidgetItem(QString::number(landmarksIndex));
+  QTableWidgetItem* iItem = new QTableWidgetItem(QString::number(rowIndex));
   iItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
   tableWidget->setItem(rowIndex,0,iItem);
 
@@ -135,14 +176,18 @@ void vvLandmarksPanel::AddPoint(int landmarksIndex)
 
 void vvLandmarksPanel::SetCurrentLandmarks(vvLandmarks* lm,int time)
 {
+  if (time != lm->GetTime())
+    return;
+  
   loadButton->setEnabled(1);
   saveButton->setEnabled(1);
   removeButton->setEnabled(1);
   mCurrentLandmarks = lm;
   tableWidget->clearContents();
-  tableWidget->setRowCount(mCurrentLandmarks->GetNumberOfPoints());
-  for (unsigned int i = 0; i < mCurrentLandmarks->GetNumberOfPoints(); i++)
-    AddPoint(i);
+  tableWidget->setRowCount(0);
+  for (unsigned int i = 0; i < mCurrentLandmarks->GetNumberOfPoints(); i++) {
+      AddPoint(i);
+  }
   //if (time > 1)
   //tableWidget->setColumnHidden(4,1);
   //else
index 9966d8820f6672802e8e597d5795c03ac1847c6a..01f53994ce67b0c604e8325199a9fca4f21f6f5e 100644 (file)
@@ -38,20 +38,27 @@ public:
         mCurrentPath = path;
     }
     void SetCurrentImage(std::string filename);
+    double* GetSelectedPoint() { return mSelectedPoint; }
 
 public slots:
     void Load();
+    bool LoadFromFile(std::vector<std::string> file);
     void Save();
     void RemoveSelectedPoints();
+    void RemoveAllPoints();
     void AddPoint();
+    void SelectPoint();
     void CommentsChanged(int row, int column);
 signals:
     void UpdateRenderWindows();
+    void SelectedPointChanged();
 
 private:
     void AddPoint(int);
+
     vvLandmarks* mCurrentLandmarks;
     std::string mCurrentPath;
+    double mSelectedPoint[4];
 }; // end class vvLandmarksPanel
 //====================================================================
 
index 1964b7e02335dcb744fd92e3a83d7efa7cfeea90..a44aadfb956311329c5b79e17d5c0076526efe73 100644 (file)
@@ -324,6 +324,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(overlayPanel,SIGNAL(FusionPropertyUpdated(int,int,int,double,double, bool)),
           this,SLOT(SetFusionProperty(int,int,int,double,double, bool)));
   connect(landmarksPanel,SIGNAL(UpdateRenderWindows()),this,SLOT(UpdateRenderWindows()));
+  connect(landmarksPanel,SIGNAL(SelectedPointChanged()),this,SLOT(GoToLandmark()));
 
   playMode = 0;//pause
   mFrameRate = 10;
@@ -704,51 +705,8 @@ void vvMainWindow::MergeImagesWithTime()
   mInputPathName = itksys::SystemTools::GetFilenamePath(files[0].toStdString()).c_str();
   std::vector<std::string> vector;
 
-  unsigned int currentDim = 0;
-  std::vector<double> currentSpacing;
-  std::vector<int> currentSize;
-  std::vector<double> currentOrigin;
-
-  for (int i = 0; i < files.size(); i++) {
-    itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO(
-                                         files[i].toStdString().c_str(), itk::ImageIOFactory::ReadMode);
-    if (reader) {
-      reader->SetFileName(files[i].toStdString().c_str());
-      reader->ReadImageInformation();
-      if (i == 0)
-        currentDim = reader->GetNumberOfDimensions();
-      bool IsOk = true;
-      for (unsigned int j = 0; j < currentDim; j++) {
-        if (i == 0) {
-          if (j == 0) {
-            currentSpacing.resize(currentDim);
-            currentSize.resize(currentDim);
-            currentOrigin.resize(currentDim);
-          }
-          currentOrigin[j] = reader->GetOrigin(j);
-          currentSpacing[j] = reader->GetSpacing(j);
-          currentSize[j] = reader->GetDimensions(j);
-        } else if (currentDim != reader->GetNumberOfDimensions()
-                   || currentSpacing[j] != reader->GetSpacing(j)
-                   || currentSize[j] != (int)reader->GetDimensions(j)
-                   || currentOrigin[j] != reader->GetOrigin(j)) {
-          QString error = "Cannot read file (too different from others ";
-          error += files[i].toStdString().c_str();
-          QMessageBox::information(this,tr("Reading problem"),error);
-          IsOk = false;
-          break;
-        }
-      }
-      if (IsOk)
-        vector.push_back(files[i].toStdString());
-    } else {
-      QString error = "Cannot read file info for ";
-      error += files[i].toStdString().c_str();
-      error += "\n";
-      error += "Maybe you're trying to open an image in an unsupported format?\n";
-      QMessageBox::information(this,tr("Reading problem"),error);
-    }
-  }
+  for (int i = 0; i < files.size(); i++)
+    vector.push_back(files[i].toStdString());
   sort(vector.begin(),vector.end());
   if (vector.size() > 1)
     LoadImages(vector, vvImageReader::MERGEDWITHTIME);
@@ -1022,6 +980,12 @@ void vvMainWindow::CurrentImageChanged(std::string id)
   }
   DataTree->topLevelItem(selected)->setSelected(1);
   mCurrentSelectedImageId = id;
+
+  landmarksPanel->SetCurrentLandmarks(mSlicerManagers[selected]->GetLandmarks(),
+                                      mSlicerManagers[selected]->GetTSlice());
+  landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
+  landmarksPanel->SetCurrentImage(mSlicerManagers[selected]->GetFileName().c_str());
+  
   emit SelectedImageHasChanged(mSlicerManagers[selected]);
 }
 //------------------------------------------------------------------------------
@@ -1154,7 +1118,7 @@ void vvMainWindow::ImageInfoChanged()
     infoPanel->setTransformation(Get4x4MatrixDoubleAsString(transformation));
 
     landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(),
-                                        mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetVTKImages().size());
+                                        mSlicerManagers[index]->GetTSlice());
     landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
     landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str());
 
@@ -1166,26 +1130,26 @@ void vvMainWindow::ImageInfoChanged()
       }
     }
 
-    infoPanel->setFileName(image);
-    infoPanel->setDimension(dim);
-    infoPanel->setSizePixel(GetVectorIntAsString(inputSize));
-    infoPanel->setSizeMM(GetVectorDoubleAsString(sizeMM));
-    infoPanel->setOrigin(GetVectorDoubleAsString(origin));
-    infoPanel->setSpacing(GetVectorDoubleAsString(inputSpacing));
-    infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")");
-
-    landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(),
-                                        mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetVTKImages().size());
-    landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
-    landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str());
-
-    overlayPanel->getCurrentImageName(mSlicerManagers[index]->GetFileName().c_str());
-    for (int i = 0; i < 4; i++) {
-      if (DataTree->selectedItems()[0]->data(i+1,Qt::CheckStateRole).toInt() > 0 || i == 3) {
-        mSlicerManagers[index]->UpdateInfoOnCursorPosition(i);
-        break;
-      }
-    }
+//     infoPanel->setFileName(image);
+//     infoPanel->setDimension(dim);
+//     infoPanel->setSizePixel(GetVectorIntAsString(inputSize));
+//     infoPanel->setSizeMM(GetVectorDoubleAsString(sizeMM));
+//     infoPanel->setOrigin(GetVectorDoubleAsString(origin));
+//     infoPanel->setSpacing(GetVectorDoubleAsString(inputSpacing));
+//     infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")");
+// 
+//     landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(),
+//                                         mSlicerManagers[index]->GetTSlice());
+//     landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
+//     landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str());
+// 
+//     overlayPanel->getCurrentImageName(mSlicerManagers[index]->GetFileName().c_str());
+//     for (int i = 0; i < 4; i++) {
+//       if (DataTree->selectedItems()[0]->data(i+1,Qt::CheckStateRole).toInt() > 0 || i == 3) {
+//         mSlicerManagers[index]->UpdateInfoOnCursorPosition(i);
+//         break;
+//       }
+//     }
     WindowLevelChanged();
     slicingPresetComboBox->setCurrentIndex(mSlicerManagers[index]->GetSlicingPreset());
 
@@ -2159,7 +2123,15 @@ void vvMainWindow::AddFusionImage(int index, QString file)
     QMessageBox::information(this,tr("Problem reading Fusion !"),"File doesn't exist!");
 }
 //------------------------------------------------------------------------------
-
+//------------------------------------------------------------------------------
+void vvMainWindow::AddLandmarks(int index, std::vector<std::string> files)
+{
+    if (!landmarksPanel->LoadFromFile(files))
+      QMessageBox::information(this,tr("Problem reading Landmarks !"),"File doesn't exist!");
+    
+    landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
+    landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str());
+}
 
 //------------------------------------------------------------------------------
 void vvMainWindow::OpenField()
@@ -3019,6 +2991,23 @@ void vvMainWindow::GoToCursor()
 }
 //------------------------------------------------------------------------------
 
+//------------------------------------------------------------------------------
+void vvMainWindow::GoToLandmark()
+{
+  int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
+  for (int column = 1; column < 5; column++) {
+    if (DataTree->selectedItems()[0]->data(column,Qt::CheckStateRole).toInt() > 1) {
+      double* cursorPos = landmarksPanel->GetSelectedPoint();
+      mSlicerManagers[index]->GetSlicer(column-1)->SetCurrentPosition(
+        cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]);
+      mSlicerManagers[index]->UpdateViews(1,column-1);
+      mSlicerManagers[index]->UpdateLinked(column-1);
+      break;
+    }
+  }
+}
+//------------------------------------------------------------------------------
+
 //------------------------------------------------------------------------------
 void vvMainWindow::PlayPause()
 {
index e308314c59620094e59ac7bb778856154089283c..a15ff8b1bb6e26817d2e7a1abe45704bc0299cdf 100644 (file)
@@ -57,7 +57,8 @@ class vvMainWindow: public vvMainWindowBase,
   void AddOverlayImage(int index, std::vector<std::string> fileNames, vvImageReader::LoadedImageType type);
   void AddFusionImage(int index, QString filename);
   void AddROI(int index, QString filename);
-  ///Adds a mesh to a SlicerManager, with optional warping by vector field
+  void AddLandmarks(int index, std::vector<std::string>);
+///Adds a mesh to a SlicerManager, with optional warping by vector field
   void AddContour(int image_index, vvMesh::Pointer contour, bool propagation);
   ///This is used to show an image when opened or computed
   void ShowLastImage();
@@ -160,6 +161,7 @@ public slots:
   void SetFusionProperty(int opacity, int tresOpacity, int colormap,double window,double level, bool showLegend);
 
   void GoToCursor();
+  void GoToLandmark();
   void PlayPause();
   void PlayNext();
   void ChangeFrameRate(int rate) {