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