Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
IndexLineSetHandler.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS 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 Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #include "IndexLineSetHandler.hh"
26 #include <fstream>
27 #include <bias_config.h>
28 
29 using namespace BIAS;
30 using namespace std;
31 
33 {
34  dNumberOfLinesInSet_ =0;
35 }
36 
38 {
39  dNumberOfLinesInSet_ =0;
40 }
41 
42 
43 /**
44  @returns vector of vector<BIAS::HomgPoint3D> with format:
45  [0]---------[1]---- .....
46  | |
47  startpos .
48  stoppos
49 
50  @param1 Filename of wrlFile with IndexLineSet
51  @param2 here number of found lines is returned
52  @author ischiller
53  @date 03/06
54 */
55 std::vector<std::vector<BIAS::HomgPoint3D> >
56 IndexLineSetHandler::Parse(std::string fileName, int &dNumberOfLines)
57 {
58  char dummy[20];
59  std::vector<double> point;
60  std::vector<int> linePos;
61  std::string tmp;
62  std::ifstream stream;
63  stream.open(fileName.c_str(),ifstream::in);
64 
65  while(!stream.eof()){
66  while(tmp != "point" && !stream.eof()){
67  stream>>dummy;
68  tmp = dummy;
69  if(tmp == "point" || tmp == "Point")
70  {
71  //get rid of the '['
72  stream >> dummy;
73  break;
74  }
75  }
76 
77  int count = 0;
78  // now parse points
79  while(tmp != "]" && !stream.eof() ) {
80  point.clear();//release point vector
81  for(int i=0;i<3;i++){
82  stream>>dummy;
83  tmp = dummy;
84  if(tmp == "]" || (tmp.find(']',0) != string::npos))
85  break;
86  point.push_back(atof(dummy));
87  }
88  if(point.size() == 3){
89 #ifdef BIAS_DEBUG
90  // cout<<"Point : "<<point[0]<<","<<point[1]<<","<<point[2]<<endl;
91 #endif
92  count++;
93  vDetectedPoints_.push_back(point);
94  }
95  }
96 
97  //look for the coordindex section
98  while(tmp != "coordIndex" && !stream.eof()){
99  stream>>dummy;
100  tmp = dummy;
101  if(tmp == "coordIndex" || tmp == "coordIndex")
102  {
103  //get rid of the '['
104  stream >> dummy;
105  break;
106  }
107  }
108  //now parse section with connection assignments
109  //read in "first index"
110  stream>>dummy;
111  tmp = dummy;
112  while(tmp != "]" && !stream.eof() ){
113  linePos.clear(); //clear it
114  //recall last input (which is start)
115  linePos.push_back(atoi(dummy)+vDetectedPoints_.size()-count);
116  stream>>dummy; //get next (stop)
117  tmp = dummy;
118  if(tmp == "]"|| (tmp.find(']',0) != string::npos))
119  break;
120  //if -1 at the end go two steps further, no connection at this position
121  if(tmp == "-1" || tmp == "-1,"){
122  linePos.clear();
123  stream>>dummy;
124  tmp = dummy;
125  if(tmp == "]"|| (tmp.find(']',0) != string::npos))
126  break;
127 
128  linePos.push_back(atoi(dummy)+vDetectedPoints_.size()-count);
129  stream>>dummy;
130  tmp = dummy;
131  if(tmp == "]"|| (tmp.find(']',0) != string::npos))
132  break;
133  }
134 
135  linePos.push_back(atoi(dummy)+vDetectedPoints_.size()-count);
136 
137  if(linePos.size() == 2){
138 #ifdef BIAS_DEBUG
139  // cout<<"Intersection : "<<linePos[0]<<","<<linePos[1]<<endl;
140 #endif
141  vConnectingLines_.push_back(linePos);
142  }
143  }
144 
145  }
146 
147  stream.close();
148 
149  //now build correct vector and deliver HomgPoint3D !!
150  BIAS::HomgPoint3D startPoint3D,stopPoint3D;
151  std::vector<std::vector<BIAS::HomgPoint3D> > output;
152  std::vector<BIAS::HomgPoint3D> line;
153 
154  for(unsigned int k=0;
155  k<vConnectingLines_.size() && k<vDetectedPoints_.size() ;
156  k++) {
157  line.clear();
158 
159  for(int j=0;j<6;j++){
160  if(j<3) { //starting point;
161  startPoint3D[j] = vDetectedPoints_[vConnectingLines_[k][0]][j];
162 
163  }
164  else{//stop point
165  stopPoint3D[j-3] = vDetectedPoints_[vConnectingLines_[k][1]][j-3];
166 
167  }
168  }
169  startPoint3D[3]=1;
170  stopPoint3D[3]=1;
171 
172  //puhs the HomgPoints into vector line
173  line.push_back(startPoint3D);
174  line.push_back(stopPoint3D);
175  //push line into gloab ouput
176  output.push_back(line);
177 
178  dNumberOfLinesInSet_++;
179 #ifdef BIAS_DEBUG
180  // cout<<"Line: ";
181  // for(unsigned int h=0;h<2;h++) cout<<output[k][h]<<",";
182  // cout<<endl;
183 #endif
184  }
185  dNumberOfLines = dNumberOfLinesInSet_;
186  return output;
187 }
188 
190 Write(std::string fileName, std::vector<std::vector<BIAS::HomgPoint3D> > fLines)
191 {
192  //std::map<BIAS::HomgPoint3D, int> mapPoints;
193  //std::map<const double*, int> mapPoints;
194  int a = 0;
195  int linesCount = fLines.size();
196 
197  std::vector<double > pointX, pointY, pointZ;
198  pointX.clear();
199  pointY.clear();
200  pointZ.clear();
201 
202  std::ofstream stream;
203  stream.open(fileName.c_str(),ofstream::out);
204 
205  //VRML HEADER
206  stream << "#VRML V2.0 utf8" << endl;
207  stream << "#Created by BIAS::IndexLineSetWriter amattal/ischiller"
208  <<endl<<endl;
209 
210  //SHAPE DESCRIPTION
211  stream << "Shape{ appearance Appearance { material Material {emissiveColor 1 1 1 }}" << endl;
212  stream << " geometry IndexedLineSet {" << endl;
213  stream << " coord Coordinate {" << endl;
214  stream << " point [" << endl;
215 
216  //Calculate points-array and their indexes
217 
218  //points - array of points with points[i] = a means that point a has index i
219  //mapPoints - correspondences between point values and their indexes
220  for (int i = 0; i < linesCount; i++)
221  {
222  if (FindPoint(fLines[i][0], pointX, pointY, pointZ, a) == -1)
223  {
224  //mapPoints.insert(make_pair(fLines[i][0], a));
225  pointX.push_back(fLines[i][0][0]);
226  pointY.push_back(fLines[i][0][1]);
227  pointZ.push_back(fLines[i][0][2]);
228 
229  //VRML new point description
230  stream << " "
231  << pointX[a] << " "
232  << pointY[a] << " "
233  << pointZ[a] << endl;
234 
235  a++;
236  }
237 
238  if (FindPoint(fLines[i][1], pointX, pointY, pointZ, a) == -1)
239  {
240  //mapPoints.insert(make_pair(fLines[i][1], a));
241 
242  pointX.push_back(fLines[i][1][0]);
243  pointY.push_back(fLines[i][1][1]);
244  pointZ.push_back(fLines[i][1][2]);
245 
246  //VRML new point description
247  stream << " "
248  << pointX[a] << " "
249  << pointY[a] << " "
250  << pointZ[a] << endl;
251 
252  a++;
253  }
254  }
255 
256  //VRML text
257  stream << " ]" << endl;
258  stream << " }" << endl;
259  stream << " coordIndex [" << endl;
260 
261  //Fill the Edge-matrix for all the existing lines from our array
262  int size = a;
263  std::vector< std::vector< bool > > bEdges;
264 
265  bEdges.clear();
266  //bEdges.reserve(size);
267  for (int i = 0; i < size; i++)
268  {
269  std::vector< bool > just;
270  just.clear();
271  for (int j = 0; j < size; j++)
272  {
273  //bEdges[i].reserve(size);
274  just.push_back(false);
275  }
276  bEdges.push_back(just);
277  }
278 
279  //std::map<BIAS::HomgPoint3D, int>::iterator mapIteratorX;
280  //std::map<BIAS::HomgPoint3D, int>::iterator mapIteratorY;
281  for (int i = 0; i < linesCount; i++)
282  {
283  //mapIteratorX = mapPoints.find(fLines[i][0]);
284  //mapIteratorY = mapPoints.find(fLines[i][1]);
285 
286  int indexX = FindPoint(fLines[i][0], pointX, pointY, pointZ, a);
287  int indexY = FindPoint(fLines[i][1], pointX, pointY, pointZ, a);
288 
289  if((indexX != -1) &&
290  (indexY != -1))
291  {
292  //int indexX = (*mapIteratorX).second;
293  //int indexY = (*mapIteratorY).second;
294 
295  bEdges[indexX][indexY] = true;
296  bEdges[indexY][indexX] = true;
297  }
298  }
299 
300  //calculate size of each column
301  vector<int> sizeOfColumns;
302  sizeOfColumns.reserve(size);
303 
304  for (int i = 0; i < size; i++)
305  {
306  sizeOfColumns[i] = 0;
307  for (int j = 0; j < size; j++)
308  {
309  if(bEdges[i][j])
310  {
311  sizeOfColumns[i]++;
312  }
313  }
314  }
315 
316  //And now fill the strings (and make them as long as possible)
317  //with the lines-chains
318 
319  for (int i = 0; i < size; i++)
320  {
321 
322  //calculate chains of lines and them to string tmp
323 
324  while(sizeOfColumns[i] != 0)
325  {
326  stream << " " << i;
327 
328  int begin = 0;
329  int end = i;
330  while(end != -1)
331  {
332  begin = end;
333  end = GetColumnElement(bEdges[begin], size);
334 
335  if(end != -1)
336  {
337  //if the edge exists, delete it from matrix
338  bEdges[begin][end] = false;
339  bEdges[end][begin] = false;
340 
341  //correct the sizes of columns
342  if(end == begin){sizeOfColumns[end]--;}
343  else
344  {
345  sizeOfColumns[begin]--;
346  sizeOfColumns[end]--;
347  }
348 
349  stream << " " << end;
350  }
351  else
352  {
353  //if not, write ", -1" and get out to the next line-chain
354  stream << " " << end;
355 
356  //VRML write the line chain
357  stream << endl;
358  }
359  }
360  }
361  }
362 
363  //VRML endlines
364  stream << " ]" << endl;
365  stream << " colorPerVertex FALSE" << endl;
366  stream << " }" << endl;
367  stream << "}" << endl;
368 
369  stream.close();
370  int success = 0;
371 
372  //Block that writes the lines into stream
373 
374  return success;
375 }
376 
377 //Check if the column is empty and if not, gives the first found element
378 //@param column - our column we're checking
379 //@param size - size of the column (so taht we don't have to calculate it each time
380 
381 //@return -1 if empty, or, if column is not empty, number of the first element
382 int IndexLineSetHandler::
383 GetColumnElement(std::vector< bool > column, int size)
384 {
385  for (int i = 0; i < size; i++)
386  {
387  if (column[i])
388  {
389  return i;
390  }
391  }
392  return -1;
393 }
394 
395 //says if current point is in our array
396 //if yes, give out an index
397 //if no, give out -1
398 int IndexLineSetHandler::
399 FindPoint(BIAS::HomgPoint3D point,
400  std::vector<double > pX,
401  std::vector<double > pY,
402  std::vector<double > pZ,
403  int size)
404 {
405  for (int i = 0; i < size; i++)
406  {
407  if ((pX[i] == point[0]) &&
408  (pY[i] == point[1]) &&
409  (pZ[i] == point[2]))
410  {
411  return i;
412  }
413  }
414  return -1;
415 }
416 
int Write(std::string fileName, std::vector< std::vector< BIAS::HomgPoint3D > > fLines)
Write a set of lines to disk as a IndexedLineSet.
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
std::vector< std::vector< BIAS::HomgPoint3D > > Parse(std::string fileName, int &dNumberOfLines)
Parse a IndexLineSet and return lines in it.