]> Creatis software - clitk.git/blob - vv/vvLandmarks.cxx
Fusion windows level is now 4 decimals
[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     vtkPoints *points = vtkPoints::New();
39     mPoints.push_back(points);
40   }
41   mPolyData = vtkPolyData::New();
42   mIds = vtkFloatArray::New();
43 }
44
45 vvLandmarks::~vvLandmarks()
46 {
47   for (unsigned int i = 0; i < mPoints.size(); i++) {
48     mPoints[i]->Delete();
49   }
50   /*for(unsigned int i = 0; i < mText.size(); i++) {
51     mText[i]->Delete();
52     }*/
53   if (mIds)
54     mIds->Delete();
55   if (mPolyData)
56     mPolyData->Delete();
57 }
58
59 void vvLandmarks::AddLandmark(float x,float y,float z,float t,double value)
60 {
61   vvLandmark point;
62   point.coordinates[0] = x;
63   point.coordinates[1] = y;
64   point.coordinates[2] = z;
65   point.coordinates[3] = t;
66   point.pixel_value=value;
67   mLandmarks.push_back(point);
68   mPoints[int(t)]->InsertNextPoint(x,y,z);
69
70   /*std::stringstream numberVal;
71   numberVal << (mLandmarks.size()-1);
72   vvLandmarksGlyph *number = vvLandmarksGlyph::New();
73   number->SetText(numberVal.str().c_str());
74   number->BackingOff();
75   mText.push_back(number);*/
76   mIds->InsertNextTuple1(0.55);
77   //mIds->InsertTuple1(mLandmarks.size(),mLandmarks.size());
78   SetTime(int(t));
79 }
80
81 void vvLandmarks::RemoveLastLandmark()
82 {
83   mPoints[mLandmarks.back().coordinates[3]]->SetNumberOfPoints(
84     mPoints[mLandmarks.back().coordinates[3]]->GetNumberOfPoints()-1);
85   mPolyData->Modified();
86   //mText.pop_back();
87   mLandmarks.pop_back();
88   mIds->RemoveLastTuple();
89 }
90
91 void vvLandmarks::ChangeComments(int index, std::string comments)
92 {
93   mLandmarks[index].comments = comments;
94 }
95
96 double vvLandmarks::GetPixelValue(int index)
97 {
98   return mLandmarks[index].pixel_value;
99 }
100
101 float* vvLandmarks::GetCoordinates(int index)
102 {
103   return mLandmarks[index].coordinates;
104 }
105
106 std::string vvLandmarks::GetComments(int index)
107 {
108   return mLandmarks[index].comments;
109 }
110
111 void vvLandmarks::LoadFile(std::string filename)
112 {
113   std::ifstream fp(filename.c_str(), std::ios::in|std::ios::binary);
114   if (!fp.is_open()) {
115     std::cerr <<"Unable to open file " << filename << std::endl;
116     return;
117   }
118   mFilename = filename;
119   mLandmarks.clear();
120   char line[255];
121   for (unsigned int i = 0; i < mPoints.size(); i++)
122     mPoints[i]->SetNumberOfPoints(0);
123   bool first_line=true;
124   while (fp.getline(line,255)) {
125     std::string stringline = line;
126     if (first_line) {
127       first_line=false;
128       ///New landmark format: first line is "LANDMARKSXX", where XX is the version number
129       if (stringline.size() >= 10 && stringline.compare(0,9,"LANDMARKS")==0) {
130         std::istringstream ss(stringline.c_str()+9);
131         ss >> mFormatVersion;
132         continue; //skip first line
133       } else
134         mFormatVersion=0;
135     }
136     DD(mFormatVersion);
137     if (stringline.size() > 1) {
138       vvLandmark point;
139       int previousSpace = 0;
140       int space=0;
141       if (mFormatVersion>0) {
142         space = stringline.find(" ", previousSpace+1);
143         if (space < -1 || space > (int)stringline.size()) {
144           ErrorMsg(mLandmarks.size(),"index");
145           continue;
146         }
147         //int index = atoi(stringline.substr(previousSpace,space - previousSpace).c_str());
148         previousSpace = space;
149       }
150       space = stringline.find(" ", previousSpace+1);
151       if (space < -1 || space > (int)stringline.size()) {
152         ErrorMsg(mLandmarks.size(),"x position");
153         continue;
154       }
155       point.coordinates[0] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
156       previousSpace = space;
157       space = stringline.find(" ", previousSpace+1);
158       if (space < -1 || space > (int)stringline.size()) {
159         ErrorMsg(mLandmarks.size(),"y position");
160         continue;
161       }
162       point.coordinates[1] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
163       previousSpace = space;
164       space = stringline.find(" ", previousSpace+1);
165       if (space < -1 || space > (int)stringline.size()) {
166         ErrorMsg(mLandmarks.size(),"z position");
167         continue;
168       }
169       point.coordinates[2] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
170       previousSpace = space;
171       if (mFormatVersion>0) {
172         space = stringline.find(" ", previousSpace+1);
173         if (space < -1 || space > (int)stringline.size()) {
174           ErrorMsg(mLandmarks.size(),"t position");
175           continue;
176         }
177         point.coordinates[3] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
178         previousSpace = space;
179         space = stringline.find(" ", previousSpace+1);
180         if (space < -1 || space > (int)stringline.size()) {
181           ErrorMsg(mLandmarks.size(),"pixel value");
182           continue;
183         }
184         point.pixel_value = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
185       } else {
186         point.pixel_value=0.; //Not in file
187         point.coordinates[3]=0.;
188       }
189       previousSpace = space;
190       //this is the maximum size of comments
191       space = (stringline.find("\n", previousSpace+1) < 254 ? stringline.find("\n", previousSpace+1) : 254);
192       point.comments = stringline.substr(previousSpace,space - (previousSpace)).c_str();
193       mLandmarks.push_back(point);
194       mIds->InsertNextTuple1(0.55);
195       mPoints[int(point.coordinates[3])]->InsertNextPoint(
196         point.coordinates[0],point.coordinates[1],point.coordinates[2]);
197     }
198   }
199   SetTime(0);
200 }
201
202 bool vvLandmarks::ErrorMsg(int num,const char * text)
203 {
204   std::cerr << "error when loading point " << num << " at " << text << std::endl;
205   return false;
206 }
207
208 void vvLandmarks::SaveFile(std::string filename)
209 {
210   std::string fileContent = "LANDMARKS1\n"; //File format version identification
211   for (unsigned int i = 0; i < mLandmarks.size(); i++) {
212     std::stringstream out;
213     out.imbue(std::locale("C")); //This is to specify that the dot is to be used as the decimal separator
214     out << i << " "
215         << mLandmarks[i].coordinates[0] << " "
216         << mLandmarks[i].coordinates[1] << " "
217         << mLandmarks[i].coordinates[2] << " "
218         << mLandmarks[i].coordinates[3] << " "
219         << mLandmarks[i].pixel_value << " ";
220     fileContent += out.str();
221     if (mLandmarks[i].comments.size() == 0)
222       fileContent += " ";
223     else
224       fileContent += mLandmarks[i].comments;
225     fileContent += "\n";
226   }
227   std::ofstream fp(filename.c_str(), std::ios::trunc);
228   if ( !fp ) {
229     std::cerr << "Unable to open file" << std::endl;
230     return;
231   }
232   fp << fileContent.c_str()<< std::endl;
233   fp.close();
234 }
235
236 void vvLandmarks::SetTime(int time)
237 {
238   if (time >= 0 && time <= ((int)mPoints.size() -1)) {
239     mPolyData->SetPoints(mPoints[time]);
240     mPolyData->GetPointData()->SetScalars(mIds);
241     mPolyData->Modified();
242     mPolyData->Update();
243   }
244 }
245
246 std::string vvLandmarks::replace_dots(std::string input)
247 {
248   ///Replaces the dots used in the file with the decimal separator in use on the platform
249   lconv * conv=localeconv();
250   unsigned int position = input.find( "." );
251   while ( position < input.size() ) {
252     input.replace(position, 1, conv->decimal_point);
253     position = input.find( ".", position + 1 );
254   }
255   return input;
256 }