From 8410a88a08678a4b2e026b5bc2c61adaef763c05 Mon Sep 17 00:00:00 2001 From: Romulo Pinho Date: Thu, 13 Dec 2012 16:11:43 +0100 Subject: [PATCH] (more) robust handling of landmarks in time-sequences - --landmarks [--sequence] cmd line option (including help message!) - landmark display follows time-frame - landmark addition/removal also matches time-frame --- vv/vv.cxx | 6 +- vv/vvLandmarks.cxx | 411 ++++++++++++++++++++-------------------- vv/vvLandmarks.h | 21 +- vv/vvLandmarksPanel.cxx | 29 ++- vv/vvLandmarksPanel.h | 2 +- vv/vvMainWindow.cxx | 59 +++--- vv/vvMainWindow.h | 2 +- 7 files changed, 278 insertions(+), 252 deletions(-) diff --git a/vv/vv.cxx b/vv/vv.cxx index 7e7e18e..2b20ac9 100644 --- a/vv/vv.cxx +++ b/vv/vv.cxx @@ -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); @@ -182,7 +184,7 @@ int main( int argc, char** argv ) << "--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 - << "--landmarks file \t Overlay the landmarks in file (.txt or .pts)." << 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(); @@ -278,7 +280,7 @@ int main( int argc, char** argv ) 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,current.c_str()); + window.AddLandmarks(n_image_loaded-1,image); open_mode = O_BASE; } } diff --git a/vv/vvLandmarks.cxx b/vv/vvLandmarks.cxx index 94fb975..0b5f98a 100644 --- a/vv/vvLandmarks.cxx +++ b/vv/vvLandmarks.cxx @@ -33,17 +33,19 @@ //-------------------------------------------------------------------- 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"); } //-------------------------------------------------------------------- @@ -53,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(); } //-------------------------------------------------------------------- @@ -77,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); @@ -96,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)); } @@ -106,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(); } //-------------------------------------------------------------------- @@ -124,23 +123,23 @@ 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(); } //-------------------------------------------------------------------- @@ -148,7 +147,7 @@ void vvLandmarks::RemoveLandmark(int index) //-------------------------------------------------------------------- void vvLandmarks::ChangeComments(int index, std::string comments) { - mLandmarks[index].comments = comments; + mLandmarks[mTime][index].comments = comments; } //-------------------------------------------------------------------- @@ -156,7 +155,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; } //-------------------------------------------------------------------- @@ -164,7 +163,7 @@ double vvLandmarks::GetPixelValue(int index) //-------------------------------------------------------------------- float* vvLandmarks::GetCoordinates(int index) { - return mLandmarks[index].coordinates; + return mLandmarks[mTime][index].coordinates; } //-------------------------------------------------------------------- @@ -172,124 +171,136 @@ float* vvLandmarks::GetCoordinates(int index) //-------------------------------------------------------------------- std::string vvLandmarks::GetComments(int index) { - return mLandmarks[index].comments; + return mLandmarks[mTime][index].comments; } //-------------------------------------------------------------------- //-------------------------------------------------------------------- -bool vvLandmarks::LoadFile(std::string filename) +bool vvLandmarks::LoadFile(std::vector filenames) { - std::string extension = itksys::SystemTools::GetFilenameExtension(filename); + // all files in the sequence must be of the same type + std::string extension = itksys::SystemTools::GetFilenameExtension(filenames[0]); if (extension == ".txt") - return LoadTxtFile(filename); + return LoadTxtFile(filenames); else if (extension == ".pts") - return LoadPtsFile(filename); + return LoadPtsFile(filenames); return false; } //-------------------------------------------------------------------- -bool vvLandmarks::LoadTxtFile(std::string filename) +bool vvLandmarks::LoadTxtFile(std::vector 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 false; - } - mFilename = filename; - mLandmarks.clear(); - vtkIdType idPoint; - char line[255]; - for (unsigned int i = 0; i < mPoints.size(); i++) + 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; @@ -297,92 +308,83 @@ bool vvLandmarks::LoadTxtFile(std::string filename) //-------------------------------------------------------------------- //-------------------------------------------------------------------- -bool vvLandmarks::LoadPtsFile(std::string filename) +bool vvLandmarks::LoadPtsFile(std::vector 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 false; - } - mFilename = filename; - mLandmarks.clear(); - vtkIdType idPoint; - char line[255]; - for (unsigned int i = 0; i < mPoints.size(); i++) + mFilenames = filenames; + for (unsigned int i = 0; i < mPoints.size(); i++) { mPoints[i]->SetNumberOfPoints(0); - bool first_line=true; - while (fp.getline(line,255)) { - // DD(line); - std::string stringline = line; - if (stringline.size() > 1) { - vvLandmark point; - int previousSpace = 0; - int space=0; - - if (stringline[0] == '#') // comments - continue; + 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"; - space = stringline.find("\t", 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("\t", 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("\t", 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("\t", previousSpace+1); - if (space < -1 || space > (int)stringline.size()) { - ErrorMsg(mLandmarks.size(),"t position"); + 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[3] = atof(replace_dots(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("\t", previousSpace+1); - if (space < -1 || space > (int)stringline.size()) { - ErrorMsg(mLandmarks.size(),"pixel value"); + 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.pixel_value = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str()); - // DD(point.pixel_value); - } else { + 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]=0.; + 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()); } - 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.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()); } } + SetTime(0); + DD("vvLandmarks::LoadPtsFile") + if (err > 0 && err == filenames.size()) + return false; + return true; } @@ -401,21 +403,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 ) { @@ -433,10 +437,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; } } //-------------------------------------------------------------------- diff --git a/vv/vvLandmarks.h b/vv/vvLandmarks.h index 0abaf61..cd564dc 100644 --- a/vv/vvLandmarks.h +++ b/vv/vvLandmarks.h @@ -39,7 +39,7 @@ public : vvLandmarks(int size); ~vvLandmarks(); - bool LoadFile(std::string filename); + bool LoadFile(std::vector filename); void SaveFile(std::string filename); void AddLandmark(float x,float y,float z,float t,double value); @@ -49,7 +49,7 @@ public : 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,23 +57,28 @@ 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 mLandmarks; + + typedef std::vector LandmarkContainerType; + std::vector mLandmarks; + vtkPolyData *mPolyData; std::vector mPoints; - vtkFloatArray* mIds; + std::vector mIds; //std::vector mText; - vtkStringArray* mLabels; - std::string mFilename; + std::vector mLabels; + std::vector mFilenames; int mFormatVersion; + int mTime; - bool LoadTxtFile(std::string filename); - bool LoadPtsFile(std::string filename); + bool LoadTxtFile(std::vector filenames); + bool LoadPtsFile(std::vector filenames); }; diff --git a/vv/vvLandmarksPanel.cxx b/vv/vvLandmarksPanel.cxx index 46c7c0e..a90ea5b 100644 --- a/vv/vvLandmarksPanel.cxx +++ b/vv/vvLandmarksPanel.cxx @@ -25,6 +25,7 @@ #include "vvLandmarks.h" #include +#include //==================================================================== vvLandmarksPanel::vvLandmarksPanel(QWidget * parent):QWidget(parent) @@ -47,15 +48,20 @@ void vvLandmarksPanel::Load() { QString file = QFileDialog::getOpenFileName(this,tr("Load Landmarks"), mCurrentPath.c_str(),tr("Landmarks ( *.txt *.pts)")); - if (!file.isEmpty()) - LoadFromFile(file.toStdString()); + if (!file.isEmpty()) { + std::vector files(1, file.toStdString()); + LoadFromFile(files); + } } -void vvLandmarksPanel::LoadFromFile(std::string file) +bool vvLandmarksPanel::LoadFromFile(std::vector files) { - mCurrentLandmarks->LoadFile(file); + if (!mCurrentLandmarks->LoadFile(files)) + return false; + SetCurrentLandmarks(mCurrentLandmarks,2); emit UpdateRenderWindows(); + return true; } void vvLandmarksPanel::Save() @@ -102,10 +108,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); @@ -140,14 +147,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 diff --git a/vv/vvLandmarksPanel.h b/vv/vvLandmarksPanel.h index d352a9a..41307d4 100644 --- a/vv/vvLandmarksPanel.h +++ b/vv/vvLandmarksPanel.h @@ -41,7 +41,7 @@ public: public slots: void Load(); - void LoadFromFile(std::string file); + bool LoadFromFile(std::vector file); void Save(); void RemoveSelectedPoints(); void AddPoint(); diff --git a/vv/vvMainWindow.cxx b/vv/vvMainWindow.cxx index 3add36d..8ca4866 100644 --- a/vv/vvMainWindow.cxx +++ b/vv/vvMainWindow.cxx @@ -979,6 +979,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]); } //------------------------------------------------------------------------------ @@ -1111,7 +1117,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()); @@ -1123,26 +1129,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()); @@ -2117,16 +2123,13 @@ void vvMainWindow::AddFusionImage(int index, QString file) } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -void vvMainWindow::AddLandmarks(int index, QString file) +void vvMainWindow::AddLandmarks(int index, std::vector files) { - if (QFile::exists(file)) - { - landmarksPanel->LoadFromFile(file.toStdString()); + 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()); - } - else - QMessageBox::information(this,tr("Problem reading Landmarks !"),"File doesn't exist!"); } //------------------------------------------------------------------------------ diff --git a/vv/vvMainWindow.h b/vv/vvMainWindow.h index efcd6a2..6e5b041 100644 --- a/vv/vvMainWindow.h +++ b/vv/vvMainWindow.h @@ -57,7 +57,7 @@ class vvMainWindow: public vvMainWindowBase, void AddOverlayImage(int index, std::vector fileNames, vvImageReader::LoadedImageType type); void AddFusionImage(int index, QString filename); void AddROI(int index, QString filename); - void AddLandmarks(int index, QString file); + void AddLandmarks(int index, std::vector); ///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 -- 2.45.1