]> Creatis software - clitk.git/blob - vv/vvLandmarks.cxx
Initial revision
[clitk.git] / vv / vvLandmarks.cxx
1 /*=========================================================================
2
3  Program:   vv
4  Module:    $RCSfile: vvLandmarks.cxx,v $
5  Language:  C++
6  Date:      $Date: 2010/01/06 13:31:57 $
7  Version:   $Revision: 1.1 $
8  Author :   Pierre Seroul (pierre.seroul@gmail.com)
9
10 Copyright (C) 2008
11 Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
12 CREATIS-LRMN http://www.creatis.insa-lyon.fr
13
14 This program is free software: you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation, version 3 of the License.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program.  If not, see <http://www.gnu.org/licenses/>.
25
26 =========================================================================*/
27 #include "vvLandmarks.h"
28
29 #include <ios>
30 #include <fstream>
31 #include <sstream>
32 #include <string>
33 #include <locale.h>
34
35 #include "vtkPolyData.h"
36 #include "vtkPoints.h"
37 #include "vtkFloatArray.h"
38 #include "vtkPointData.h"
39 #include "clitkCommon.h"
40
41 vvLandmarks::vvLandmarks(int size)
42 {
43     mLandmarks.resize(0);
44     mFilename = "";
45
46     for (int i = 0; i < size; i++)
47     {
48         vtkPoints *points = vtkPoints::New();
49         mPoints.push_back(points);
50     }
51     mPolyData = vtkPolyData::New();
52     mIds = vtkFloatArray::New();
53 }
54
55 vvLandmarks::~vvLandmarks()
56 {
57     for (unsigned int i = 0; i < mPoints.size(); i++) {
58         mPoints[i]->Delete();
59     }
60     /*for(unsigned int i = 0; i < mText.size(); i++) {
61       mText[i]->Delete();
62       }*/
63     if (mIds)
64         mIds->Delete();
65     if (mPolyData)
66         mPolyData->Delete();
67 }
68
69 void vvLandmarks::AddLandmark(float x,float y,float z,float t,double value)
70 {
71     vvLandmark point;
72     point.coordinates[0] = x;
73     point.coordinates[1] = y;
74     point.coordinates[2] = z;
75     point.coordinates[3] = t;
76     point.pixel_value=value;
77     mLandmarks.push_back(point);
78     mPoints[int(t)]->InsertNextPoint(x,y,z);
79
80     /*std::stringstream numberVal;
81     numberVal << (mLandmarks.size()-1);
82     vvLandmarksGlyph *number = vvLandmarksGlyph::New();
83     number->SetText(numberVal.str().c_str());
84     number->BackingOff();
85     mText.push_back(number);*/
86     mIds->InsertNextTuple1(0.55);
87     //mIds->InsertTuple1(mLandmarks.size(),mLandmarks.size());
88     SetTime(int(t));
89 }
90
91 void vvLandmarks::RemoveLastLandmark()
92 {
93     mPoints[mLandmarks.back().coordinates[3]]->SetNumberOfPoints(
94         mPoints[mLandmarks.back().coordinates[3]]->GetNumberOfPoints()-1);
95     mPolyData->Modified();
96     //mText.pop_back();
97     mLandmarks.pop_back();
98     mIds->RemoveLastTuple();
99 }
100
101 void vvLandmarks::ChangeComments(int index, std::string comments)
102 {
103     mLandmarks[index].comments = comments;
104 }
105
106 double vvLandmarks::GetPixelValue(int index)
107 {
108     return mLandmarks[index].pixel_value;
109 }
110
111 float* vvLandmarks::GetCoordinates(int index)
112 {
113     return mLandmarks[index].coordinates;
114 }
115
116 std::string vvLandmarks::GetComments(int index)
117 {
118     return mLandmarks[index].comments;
119 }
120
121 void vvLandmarks::LoadFile(std::string filename)
122 {
123     std::ifstream fp(filename.c_str(), std::ios::in|std::ios::binary);
124     if (!fp.is_open())
125     {
126         std::cerr <<"Unable to open file " << filename << std::endl;
127         return;
128     }
129     mFilename = filename;
130     mLandmarks.clear();
131     char line[255];
132     for (unsigned int i = 0; i < mPoints.size();i++)
133         mPoints[i]->SetNumberOfPoints(0);
134     bool first_line=true;
135     while (fp.getline(line,255))
136     {
137         std::string stringline = line;
138         if (first_line)
139         {
140             first_line=false;
141             ///New landmark format: first line is "LANDMARKSXX", where XX is the version number
142             if (stringline.size() >= 10 && stringline.compare(0,9,"LANDMARKS")==0)
143             {
144                 std::istringstream ss(stringline.c_str()+9);
145                 ss >> mFormatVersion;
146                 continue; //skip first line
147             }
148             else 
149                 mFormatVersion=0;
150         }
151         DD(mFormatVersion);
152         if (stringline.size() > 1)
153         {
154             vvLandmark point;
155             int previousSpace = 0;
156             int space=0;
157             if (mFormatVersion>0)
158             {
159                 space = stringline.find(" ", previousSpace+1);
160                 if (space < -1 || space > (int)stringline.size())
161                 {
162                     ErrorMsg(mLandmarks.size(),"index");
163                     continue;
164                 }
165                 //int index = atoi(stringline.substr(previousSpace,space - previousSpace).c_str());
166                 previousSpace = space;
167             }
168             space = stringline.find(" ", previousSpace+1);
169             if (space < -1 || space > (int)stringline.size())
170             {
171                 ErrorMsg(mLandmarks.size(),"x position");
172                 continue;
173             }
174             point.coordinates[0] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
175             previousSpace = space;
176             space = stringline.find(" ", previousSpace+1);
177             if (space < -1 || space > (int)stringline.size())
178             {
179                 ErrorMsg(mLandmarks.size(),"y position");
180                 continue;
181             }
182             point.coordinates[1] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
183             previousSpace = space;
184             space = stringline.find(" ", previousSpace+1);
185             if (space < -1 || space > (int)stringline.size())
186             {
187                 ErrorMsg(mLandmarks.size(),"z position");
188                 continue;
189             }
190             point.coordinates[2] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
191             previousSpace = space;
192             if (mFormatVersion>0)
193             {
194                 space = stringline.find(" ", previousSpace+1);
195                 if (space < -1 || space > (int)stringline.size())
196                 {
197                     ErrorMsg(mLandmarks.size(),"t position");
198                     continue;
199                 }
200                 point.coordinates[3] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
201                 previousSpace = space;
202                 space = stringline.find(" ", previousSpace+1);
203                 if (space < -1 || space > (int)stringline.size())
204                 {
205                     ErrorMsg(mLandmarks.size(),"pixel value");
206                     continue;
207                 }
208                 point.pixel_value = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
209             }
210             else
211             {
212                 point.pixel_value=0.; //Not in file
213                 point.coordinates[3]=0.;
214             }
215             previousSpace = space;
216             //this is the maximum size of comments
217             space = (stringline.find("\n", previousSpace+1) < 254 ? stringline.find("\n", previousSpace+1) : 254);
218             point.comments = stringline.substr(previousSpace,space - (previousSpace)).c_str();
219             mLandmarks.push_back(point);
220             mIds->InsertNextTuple1(0.55);
221             mPoints[int(point.coordinates[3])]->InsertNextPoint(
222                 point.coordinates[0],point.coordinates[1],point.coordinates[2]);
223         }
224     }
225     SetTime(0);
226 }
227
228 bool vvLandmarks::ErrorMsg(int num,const char * text)
229 {
230     std::cerr << "error when loading point " << num << " at " << text << std::endl;
231     return false;
232 }
233
234 void vvLandmarks::SaveFile(std::string filename)
235 {
236     std::string fileContent = "LANDMARKS1\n"; //File format version identification
237     for (unsigned int i = 0; i < mLandmarks.size(); i++) {
238         std::stringstream out;
239         out.imbue(std::locale("C")); //This is to specify that the dot is to be used as the decimal separator
240         out << i << " "
241             << mLandmarks[i].coordinates[0] << " "
242             << mLandmarks[i].coordinates[1] << " "
243             << mLandmarks[i].coordinates[2] << " "
244             << mLandmarks[i].coordinates[3] << " "
245             << mLandmarks[i].pixel_value << " ";
246         fileContent += out.str();
247         if (mLandmarks[i].comments.size() == 0)
248             fileContent += " ";
249         else
250             fileContent += mLandmarks[i].comments;
251         fileContent += "\n";
252     }
253     std::ofstream fp(filename.c_str(), std::ios::trunc);
254     if ( !fp )
255     {
256         std::cerr << "Unable to open file" << std::endl;
257         return;
258     }
259     fp << fileContent.c_str()<< std::endl;
260     fp.close();
261 }
262
263 void vvLandmarks::SetTime(int time)
264 {
265     if (time >= 0 && time <= ((int)mPoints.size() -1))
266     {
267         mPolyData->SetPoints(mPoints[time]);
268         mPolyData->GetPointData()->SetScalars(mIds);
269         mPolyData->Modified();
270         mPolyData->Update();
271     }
272 }
273
274 std::string vvLandmarks::replace_dots(std::string input)
275 {
276     ///Replaces the dots used in the file with the decimal separator in use on the platform
277     lconv * conv=localeconv();
278     unsigned int position = input.find( "." );
279     while ( position < input.size() ) 
280     {
281         input.replace(position, 1, conv->decimal_point);
282         position = input.find( ".", position + 1 );
283     } 
284     return input;
285 }