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