Off_reader.h
1 /* This file is part of the Gudhi Library. The Gudhi library
2  * (Geometric Understanding in Higher Dimensions) is a generic C++
3  * library for computational topology.
4  *
5  * Author(s): David Salinas
6  *
7  * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (France)
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23 
24 
25 #ifndef OFF_READER_H_
26 #define OFF_READER_H_
27 
28 
29 #include <sstream>
30 #include <iostream>
31 #include <iterator>
32 #include <string>
33 #include <vector>
34 #include <fstream>
35 
36 namespace Gudhi {
37 
43 class Off_reader {
44  public:
45  Off_reader(std::ifstream& stream) : stream_(stream) { }
46 
47  ~Off_reader() {
48  stream_.close();
49  }
50 
64  template<typename OffVisitor>
65  bool read(OffVisitor& off_visitor) {
66  bool success_read_off_preambule = read_off_preambule(off_visitor);
67  if (!success_read_off_preambule) {
68  std::cerr << "could not read off preambule\n";
69  return false;
70  }
71 
72  bool success_read_off_points = read_off_points(off_visitor);
73  if (!success_read_off_points) {
74  std::cerr << "could not read off points\n";
75  return false;
76  }
77 
78  bool success_read_off_faces = read_off_faces(off_visitor);
79  if (!success_read_off_faces) {
80  std::cerr << "could not read off faces\n";
81  return false;
82  }
83 
84  off_visitor.done();
85  return success_read_off_preambule && success_read_off_points && success_read_off_faces;
86  }
87 
88  private:
89  std::ifstream& stream_;
90 
91  struct Off_info {
92  int dim;
93  int num_vertices;
94  int num_edges;
95  int num_faces;
96  };
97 
98  Off_info off_info_;
99 
100  template<typename OffVisitor>
101  bool read_off_preambule(OffVisitor& off_visitor) {
102  std::string line;
103  if (!goto_next_uncomment_line(line)) return false;
104 
105  bool is_off_file = (line.find("OFF") != std::string::npos);
106  bool is_noff_file = (line.find("nOFF") != std::string::npos);
107 
108  if (!is_off_file && !is_noff_file) {
109  std::cerr << line << std::endl;
110  std::cerr << "missing off header\n";
111  return false;
112  }
113 
114  if (!goto_next_uncomment_line(line)) return false;
115  std::istringstream iss(line);
116  if ((is_off_file) && (!is_noff_file)) {
117  off_info_.dim = 3;
118  if (!(iss >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) {
119  std::cerr << "incorrect number of vertices/faces/edges\n";
120  return false;
121  }
122  } else {
123  if (!(iss >> off_info_.dim >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) {
124  std::cerr << "incorrect number of vertices/faces/edges\n";
125  return false;
126  }
127  }
128  off_visitor.init(off_info_.dim, off_info_.num_vertices, off_info_.num_faces, off_info_.num_edges);
129 
130  return true;
131  }
132 
133  bool goto_next_uncomment_line(std::string& uncomment_line) {
134  uncomment_line.clear();
135  do
136  std::getline(stream_, uncomment_line); while (uncomment_line[0] == '%');
137  return (uncomment_line.size() > 0 && uncomment_line[0] != '%');
138  }
139 
140  template<typename OffVisitor>
141  bool read_off_points(OffVisitor& visitor) {
142  int num_vertices_to_read = off_info_.num_vertices;
143  while (num_vertices_to_read--) {
144  std::string line;
145  if (!goto_next_uncomment_line(line)) return false;
146  std::vector<double> point;
147  std::istringstream iss(line);
148  point.assign(std::istream_iterator<double>(iss), std::istream_iterator<double>());
149  // if(point.size() != off_info_.dim) return false;
150  visitor.point(point);
151  }
152  return true;
153  }
154 
155  template<typename OffVisitor>
156  bool read_off_faces(OffVisitor& visitor) {
157  std::string line;
158  while (goto_next_uncomment_line(line)) {
159  std::istringstream iss(line);
160  int num_face_vertices;
161  iss >> num_face_vertices;
162  std::vector<int> face;
163  face.assign(std::istream_iterator<int>(iss), std::istream_iterator<int>());
164  // if (face.size() != (off_info_.dim + 1)) return false;
165  visitor.maximal_face(face);
166  }
167  return true;
168  }
169 };
170 
171 template<typename OFFVisitor>
172 void read_off(const std::string& name_file_off, OFFVisitor& vis) {
173  std::ifstream stream(name_file_off);
174  if (!stream.is_open()) {
175  std::cerr << "could not open file \n";
176  } else {
177  Off_reader off_reader(stream);
178  off_reader.read(vis);
179  }
180 }
181 
182 } // namespace Gudhi
183 
184 #endif // OFF_READER_H_
bool read(OffVisitor &off_visitor)
Read an OFF file and calls the following methods :
Definition: Off_reader.h:65
Definition: SimplicialComplexForAlpha.h:26
OFF file reader top class visitor.
Definition: Off_reader.h:43
GUDHI  Version 2.1.0  - C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding.  - Copyright : GPL v3 Generated on Wed Jan 31 2018 09:40:55 for GUDHI by Doxygen 1.8.11