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
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 
109 
110  if (!is_off_file && !is_noff_file) {
111  std::cerr << line << std::endl;
112  std::cerr << "missing off header\n";
113  return false;
114  }
115 
116  if (is_noff_file) {
117  // Should be on a separate line, but we accept it on the same line as the number of vertices
118  stream_ >> off_info_.dim;
119  } else {
120  off_info_.dim = 3;
121  }
122 
123  if (!goto_next_uncomment_line(line)) return false;
124  std::istringstream iss(line);
125  if (!(iss >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) {
126  std::cerr << "incorrect number of vertices/faces/edges\n";
127  return false;
128  }
129  off_visitor.init(off_info_.dim, off_info_.num_vertices, off_info_.num_faces, off_info_.num_edges);
130 
131  return true;
132  }
133 
134  bool goto_next_uncomment_line(std::string& uncomment_line) {
135  do {
136  // skip whitespace, including empty lines
137  if (!std::ifstream::sentry(stream_)) return false;
138  std::getline(stream_, uncomment_line);
139  } while (uncomment_line[0] == '#');
140  return static_cast<bool>(stream_);
141  }
142 
143  template<typename OffVisitor>
144  bool read_off_points(OffVisitor& visitor) {
145  int num_vertices_to_read = off_info_.num_vertices;
146  while (num_vertices_to_read--) {
147  std::string line;
148  if (!goto_next_uncomment_line(line)) return false;
149  std::vector<double> point;
150  std::istringstream iss(line);
151  point.assign(std::istream_iterator<double>(iss), std::istream_iterator<double>());
152  // if(point.size() != off_info_.dim) return false;
153  visitor.point(point);
154  }
155  return true;
156  }
157 
158  template<typename OffVisitor>
159  bool read_off_faces(OffVisitor& visitor) {
160  std::string line;
161  while (goto_next_uncomment_line(line)) {
162  std::istringstream iss(line);
163  int num_face_vertices;
164  iss >> num_face_vertices;
165  std::vector<int> face;
166  face.assign(std::istream_iterator<int>(iss), std::istream_iterator<int>());
167  // if (face.size() != (off_info_.dim + 1)) return false;
168  visitor.maximal_face(face);
169  }
170  return true;
171  }
172 };
173 
174 template<typename OFFVisitor>
175 void read_off(const std::string& name_file_off, OFFVisitor& vis) {
176  std::ifstream stream(name_file_off);
177  if (!stream.is_open()) {
178  std::cerr << "could not open file \n";
179  } else {
180  Off_reader off_reader(stream);
181  off_reader.read(vis);
182  }
183 }
184 
185 } // namespace Gudhi
186 
187 #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.3.0  - C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding.  - Copyright : GPL v3 Generated on Tue Sep 4 2018 14:32:59 for GUDHI by Doxygen 1.8.13