1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://www.centreleonberard.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
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.
13 It is distributed under dual licence
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"
26 #include "vtkPolyData.h"
27 #include "vtkPoints.h"
28 #include "vtkFloatArray.h"
29 #include "vtkPointData.h"
30 #include "clitkCommon.h"
32 //--------------------------------------------------------------------
33 vvLandmarks::vvLandmarks(int size)
38 for (int i = 0; i < size; i++) {
39 vtkPoints *points = vtkPoints::New();
40 mPoints.push_back(points);
42 mPolyData = vtkPolyData::New();
43 mIds = vtkFloatArray::New();
45 //--------------------------------------------------------------------
48 //--------------------------------------------------------------------
49 vvLandmarks::~vvLandmarks()
51 for (unsigned int i = 0; i < mPoints.size(); i++) {
54 /*for(unsigned int i = 0; i < mText.size(); i++) {
62 //--------------------------------------------------------------------
65 //--------------------------------------------------------------------
66 void vvLandmarks::AddLandmark(float x,float y,float z,float t,double value)
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);
77 std::stringstream numberVal;
78 numberVal << (mLandmarks.size()-1);
80 vvLandmarksGlyph *number = vvLandmarksGlyph::New();
81 number->SetText(numberVal.str().c_str());
83 DD(numberVal.str().c_str());
84 mText.push_back(number);
87 mIds->InsertNextTuple1(0.55);
88 //mIds->InsertTuple1(mLandmarks.size(),mLandmarks.size());
91 //--------------------------------------------------------------------
94 //--------------------------------------------------------------------
95 void vvLandmarks::RemoveLastLandmark()
97 mPoints[mLandmarks.back().coordinates[3]]->SetNumberOfPoints(
98 mPoints[mLandmarks.back().coordinates[3]]->GetNumberOfPoints()-1);
99 mPolyData->Modified();
101 mLandmarks.pop_back();
102 mIds->RemoveLastTuple();
104 //--------------------------------------------------------------------
107 //--------------------------------------------------------------------
108 void vvLandmarks::RemoveLandmark(int index)
110 // erase a vtkPoint by shifiting the array .
111 // not a problem here because there are no
112 // pologyons linking the points
113 int npoints = mPoints[mLandmarks[index].coordinates[3]]->GetNumberOfPoints();
114 int t = mLandmarks[index].coordinates[3];
115 for (int i = index; i < npoints - 1; i++)
116 mPoints[t]->InsertPoint(i, mPoints[t]->GetPoint(i+1));
117 mPoints[t]->SetNumberOfPoints(npoints-1);
118 mPolyData->Modified();
120 mLandmarks.erase(mLandmarks.begin() + index);
121 mIds->RemoveLastTuple();
123 //--------------------------------------------------------------------
126 //--------------------------------------------------------------------
127 void vvLandmarks::ChangeComments(int index, std::string comments)
129 mLandmarks[index].comments = comments;
131 //--------------------------------------------------------------------
134 //--------------------------------------------------------------------
135 double vvLandmarks::GetPixelValue(int index)
137 return mLandmarks[index].pixel_value;
139 //--------------------------------------------------------------------
142 //--------------------------------------------------------------------
143 float* vvLandmarks::GetCoordinates(int index)
145 return mLandmarks[index].coordinates;
147 //--------------------------------------------------------------------
150 //--------------------------------------------------------------------
151 std::string vvLandmarks::GetComments(int index)
153 return mLandmarks[index].comments;
155 //--------------------------------------------------------------------
158 //--------------------------------------------------------------------
159 void vvLandmarks::LoadFile(std::string filename)
161 std::ifstream fp(filename.c_str(), std::ios::in|std::ios::binary);
163 std::cerr <<"Unable to open file " << filename << std::endl;
166 mFilename = filename;
169 for (unsigned int i = 0; i < mPoints.size(); i++)
170 mPoints[i]->SetNumberOfPoints(0);
171 bool first_line=true;
172 while (fp.getline(line,255)) {
174 std::string stringline = line;
177 ///New landmark format: first line is "LANDMARKSXX", where XX is the version number
178 if (stringline.size() >= 10 && stringline.compare(0,9,"LANDMARKS")==0) {
179 std::istringstream ss(stringline.c_str()+9);
180 ss >> mFormatVersion;
181 continue; //skip first line
185 if (stringline.size() > 1) {
187 int previousSpace = 0;
189 if (mFormatVersion>0) {
190 space = stringline.find(" ", previousSpace+1);
191 if (space < -1 || space > (int)stringline.size()) {
192 ErrorMsg(mLandmarks.size(),"index");
195 //int index = atoi(stringline.substr(previousSpace,space - previousSpace).c_str());
196 previousSpace = space;
198 space = stringline.find(" ", previousSpace+1);
199 if (space < -1 || space > (int)stringline.size()) {
200 ErrorMsg(mLandmarks.size(),"x position");
203 point.coordinates[0] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
204 // DD(point.coordinates[0]);
205 previousSpace = space;
206 space = stringline.find(" ", previousSpace+1);
207 if (space < -1 || space > (int)stringline.size()) {
208 ErrorMsg(mLandmarks.size(),"y position");
211 point.coordinates[1] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
212 // DD(point.coordinates[1]);
213 previousSpace = space;
214 space = stringline.find(" ", previousSpace+1);
215 if (space < -1 || space > (int)stringline.size()) {
216 ErrorMsg(mLandmarks.size(),"z position");
219 point.coordinates[2] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
220 previousSpace = space;
221 if (mFormatVersion>0) {
222 space = stringline.find(" ", previousSpace+1);
223 if (space < -1 || space > (int)stringline.size()) {
224 ErrorMsg(mLandmarks.size(),"t position");
227 point.coordinates[3] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
228 previousSpace = space;
229 space = stringline.find(" ", previousSpace+1);
230 if (space < -1 || space > (int)stringline.size()) {
231 ErrorMsg(mLandmarks.size(),"pixel value");
234 point.pixel_value = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
235 // DD(point.pixel_value);
237 point.pixel_value=0.; //Not in file
238 point.coordinates[3]=0.;
240 previousSpace = space;
241 //this is the maximum size of comments
242 space = (stringline.find("\n", previousSpace+1) < 254 ? stringline.find("\n", previousSpace+1) : 254);
243 if (previousSpace != -1) {
244 point.comments = stringline.substr(previousSpace,space - (previousSpace)).c_str();
246 // DD(point.comments);
247 mLandmarks.push_back(point);
248 mIds->InsertNextTuple1(0.55);
249 mPoints[int(point.coordinates[3])]->InsertNextPoint(
250 point.coordinates[0],point.coordinates[1],point.coordinates[2]);
255 //--------------------------------------------------------------------
258 //--------------------------------------------------------------------
259 bool vvLandmarks::ErrorMsg(int num,const char * text)
261 std::cerr << "error when loading point " << num << " at " << text << std::endl;
264 //--------------------------------------------------------------------
267 //--------------------------------------------------------------------
268 void vvLandmarks::SaveFile(std::string filename)
270 std::string fileContent = "LANDMARKS1\n"; //File format version identification
271 for (unsigned int i = 0; i < mLandmarks.size(); i++) {
272 std::stringstream out;
273 out.imbue(std::locale("C")); //This is to specify that the dot is to be used as the decimal separator
275 << mLandmarks[i].coordinates[0] << " "
276 << mLandmarks[i].coordinates[1] << " "
277 << mLandmarks[i].coordinates[2] << " "
278 << mLandmarks[i].coordinates[3] << " "
279 << mLandmarks[i].pixel_value << " ";
280 fileContent += out.str();
281 if (mLandmarks[i].comments.size() == 0)
284 fileContent += mLandmarks[i].comments;
287 std::ofstream fp(filename.c_str(), std::ios::trunc);
289 std::cerr << "Unable to open file" << std::endl;
292 fp << fileContent.c_str()<< std::endl;
295 //--------------------------------------------------------------------
298 //--------------------------------------------------------------------
299 void vvLandmarks::SetTime(int time)
301 if (time >= 0 && time <= ((int)mPoints.size() -1)) {
302 mPolyData->SetPoints(mPoints[time]);
303 mPolyData->GetPointData()->SetScalars(mIds);
304 mPolyData->Modified();
308 //--------------------------------------------------------------------
311 //--------------------------------------------------------------------
312 std::string vvLandmarks::replace_dots(std::string input)
314 ///Replaces the dots used in the file with the decimal separator in use on the platform
315 lconv * conv=localeconv();
316 unsigned int position = input.find( "." );
317 while ( position < input.size() ) {
318 input.replace(position, 1, conv->decimal_point);
319 position = input.find( ".", position + 1 );
323 //--------------------------------------------------------------------