]> Creatis software - clitk.git/blob - vv/vvLandmarks.cxx
possibility to delete selected landmarks in VV
[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://www.centreleonberard.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 //--------------------------------------------------------------------
33 vvLandmarks::vvLandmarks(int size)
34 {
35   mLandmarks.resize(0);
36   mFilename = "";
37
38   for (int i = 0; i < size; i++) {
39     vtkPoints *points = vtkPoints::New();
40     mPoints.push_back(points);
41   }
42   mPolyData = vtkPolyData::New();
43   mIds = vtkFloatArray::New();
44 }
45 //--------------------------------------------------------------------
46
47
48 //--------------------------------------------------------------------
49 vvLandmarks::~vvLandmarks()
50 {
51   for (unsigned int i = 0; i < mPoints.size(); i++) {
52     mPoints[i]->Delete();
53   }
54   /*for(unsigned int i = 0; i < mText.size(); i++) {
55     mText[i]->Delete();
56     }*/
57   if (mIds)
58     mIds->Delete();
59   if (mPolyData)
60     mPolyData->Delete();
61 }
62 //--------------------------------------------------------------------
63
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   /*
80   vvLandmarksGlyph *number = vvLandmarksGlyph::New();
81   number->SetText(numberVal.str().c_str());
82   number->BackingOff();
83   DD(numberVal.str().c_str());
84   mText.push_back(number);
85   */
86
87   mIds->InsertNextTuple1(0.55);
88   //mIds->InsertTuple1(mLandmarks.size(),mLandmarks.size());
89   SetTime(int(t));
90 }
91 //--------------------------------------------------------------------
92
93
94 //--------------------------------------------------------------------
95 void vvLandmarks::RemoveLastLandmark()
96 {
97   mPoints[mLandmarks.back().coordinates[3]]->SetNumberOfPoints(
98                                                                mPoints[mLandmarks.back().coordinates[3]]->GetNumberOfPoints()-1);
99   mPolyData->Modified();
100   //  mText.pop_back();
101   mLandmarks.pop_back();
102   mIds->RemoveLastTuple();
103 }
104 //--------------------------------------------------------------------
105
106
107 //--------------------------------------------------------------------
108 void vvLandmarks::RemoveLandmark(int index)
109 {
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();
119
120   mLandmarks.erase(mLandmarks.begin() + index);
121   mIds->RemoveLastTuple();
122 }
123 //--------------------------------------------------------------------
124
125
126 //--------------------------------------------------------------------
127 void vvLandmarks::ChangeComments(int index, std::string comments)
128 {
129   mLandmarks[index].comments = comments;
130 }
131 //--------------------------------------------------------------------
132
133
134 //--------------------------------------------------------------------
135 double vvLandmarks::GetPixelValue(int index)
136 {
137   return mLandmarks[index].pixel_value;
138 }
139 //--------------------------------------------------------------------
140
141
142 //--------------------------------------------------------------------
143 float* vvLandmarks::GetCoordinates(int index)
144 {
145   return mLandmarks[index].coordinates;
146 }
147 //--------------------------------------------------------------------
148
149
150 //--------------------------------------------------------------------
151 std::string vvLandmarks::GetComments(int index)
152 {
153   return mLandmarks[index].comments;
154 }
155 //--------------------------------------------------------------------
156
157
158 //--------------------------------------------------------------------
159 void vvLandmarks::LoadFile(std::string filename)
160 {
161   std::ifstream fp(filename.c_str(), std::ios::in|std::ios::binary);
162   if (!fp.is_open()) {
163     std::cerr <<"Unable to open file " << filename << std::endl;
164     return;
165   }
166   mFilename = filename;
167   mLandmarks.clear();
168   char line[255];
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)) {
173     //    DD(line);
174     std::string stringline = line;
175     if (first_line) {
176       first_line=false;
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
182       } else
183         mFormatVersion=0;
184     }
185     if (stringline.size() > 1) {
186       vvLandmark point;
187       int previousSpace = 0;
188       int space=0;
189       if (mFormatVersion>0) {
190         space = stringline.find(" ", previousSpace+1);
191         if (space < -1 || space > (int)stringline.size()) {
192           ErrorMsg(mLandmarks.size(),"index");
193           continue;
194         }
195         //int index = atoi(stringline.substr(previousSpace,space - previousSpace).c_str());
196         previousSpace = space;
197       }
198       space = stringline.find(" ", previousSpace+1);
199       if (space < -1 || space > (int)stringline.size()) {
200         ErrorMsg(mLandmarks.size(),"x position");
201         continue;
202       }
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");
209         continue;
210       }
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");
217         continue;
218       }
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");
225           continue;
226         }
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");
232           continue;
233         }
234         point.pixel_value = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
235         //        DD(point.pixel_value);
236       } else {
237         point.pixel_value=0.; //Not in file
238         point.coordinates[3]=0.;
239       }
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();
245       }
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]);
251     }
252   }
253   SetTime(0);
254 }
255 //--------------------------------------------------------------------
256
257
258 //--------------------------------------------------------------------
259 bool vvLandmarks::ErrorMsg(int num,const char * text)
260 {
261   std::cerr << "error when loading point " << num << " at " << text << std::endl;
262   return false;
263 }
264 //--------------------------------------------------------------------
265
266
267 //--------------------------------------------------------------------
268 void vvLandmarks::SaveFile(std::string filename)
269 {
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
274     out << i << " "
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)
282       fileContent += " ";
283     else
284       fileContent += mLandmarks[i].comments;
285     fileContent += "\n";
286   }
287   std::ofstream fp(filename.c_str(), std::ios::trunc);
288   if ( !fp ) {
289     std::cerr << "Unable to open file" << std::endl;
290     return;
291   }
292   fp << fileContent.c_str()<< std::endl;
293   fp.close();
294 }
295 //--------------------------------------------------------------------
296
297
298 //--------------------------------------------------------------------
299 void vvLandmarks::SetTime(int time)
300 {
301   if (time >= 0 && time <= ((int)mPoints.size() -1)) {
302     mPolyData->SetPoints(mPoints[time]);
303     mPolyData->GetPointData()->SetScalars(mIds);
304     mPolyData->Modified();
305     mPolyData->Update();
306   }
307 }
308 //--------------------------------------------------------------------
309
310
311 //--------------------------------------------------------------------
312 std::string vvLandmarks::replace_dots(std::string input)
313 {
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 );
320   }
321   return input;
322 }
323 //--------------------------------------------------------------------