Off_reader.h
1 /* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2  * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3  * Author(s): David Salinas
4  *
5  * Copyright (C) 2014 Inria
6  *
7  * Modification(s):
8  * - YYYY/MM Author: Description of the modification
9  */
10 
11 
12 #ifndef OFF_READER_H_
13 #define OFF_READER_H_
14 
15 
16 #include <sstream>
17 #include <iostream>
18 #include <iterator>
19 #include <string>
20 #include <vector>
21 #include <fstream>
22 
23 namespace Gudhi {
24 
29 class Off_reader {
30  public:
31  Off_reader(std::ifstream& stream) : stream_(stream) { }
32 
33  ~Off_reader() {
34  stream_.close();
35  }
36 
50  template<typename OffVisitor>
51  bool read(OffVisitor& off_visitor) {
52  bool success_read_off_preambule = read_off_preambule(off_visitor);
53  if (!success_read_off_preambule) {
54  std::cerr << "could not read off preambule\n";
55  return false;
56  }
57 
58  bool success_read_off_points = read_off_points(off_visitor);
59  if (!success_read_off_points) {
60  std::cerr << "could not read off points\n";
61  return false;
62  }
63 
64  bool success_read_off_faces = read_off_faces(off_visitor);
65  if (!success_read_off_faces) {
66  std::cerr << "could not read off faces\n";
67  return false;
68  }
69 
70  off_visitor.done();
71  return success_read_off_preambule && success_read_off_points && success_read_off_faces;
72  }
73 
74  private:
75  std::ifstream& stream_;
76 
77  struct Off_info {
78  int dim;
79  int num_vertices;
80  int num_edges;
81  int num_faces;
82  };
83 
84  Off_info off_info_;
85 
86  template<typename OffVisitor>
87  bool read_off_preambule(OffVisitor& off_visitor) {
88  std::string line;
89  if (!goto_next_uncomment_line(line)) return false;
90 
91  bool is_off_file = (line.find("OFF") != std::string::npos);
92  bool is_noff_file = (line.find("nOFF") != std::string::npos);
93 
94 
95 
96  if (!is_off_file && !is_noff_file) {
97  std::cerr << line << std::endl;
98  std::cerr << "missing off header\n";
99  return false;
100  }
101 
102  if (is_noff_file) {
103  // Should be on a separate line, but we accept it on the same line as the number of vertices
104  stream_ >> off_info_.dim;
105  } else {
106  off_info_.dim = 3;
107  }
108 
109  if (!goto_next_uncomment_line(line)) return false;
110  std::istringstream iss(line);
111  if (!(iss >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) {
112  std::cerr << "incorrect number of vertices/faces/edges\n";
113  return false;
114  }
115  off_visitor.init(off_info_.dim, off_info_.num_vertices, off_info_.num_faces, off_info_.num_edges);
116 
117  return true;
118  }
119 
120  bool goto_next_uncomment_line(std::string& uncomment_line) {
121  do {
122  // skip whitespace, including empty lines
123  if (!std::ifstream::sentry(stream_)) return false;
124  std::getline(stream_, uncomment_line);
125  } while (uncomment_line[0] == '#');
126  return static_cast<bool>(stream_);
127  }
128 
129  template<typename OffVisitor>
130  bool read_off_points(OffVisitor& visitor) {
131  int num_vertices_to_read = off_info_.num_vertices;
132  while (num_vertices_to_read--) {
133  std::string line;
134  if (!goto_next_uncomment_line(line)) return false;
135  std::vector<double> point;
136  std::istringstream iss(line);
137  point.assign(std::istream_iterator<double>(iss), std::istream_iterator<double>());
138  // if(point.size() != off_info_.dim) return false;
139  visitor.point(point);
140  }
141  return true;
142  }
143 
144  template<typename OffVisitor>
145  bool read_off_faces(OffVisitor& visitor) {
146  std::string line;
147  while (goto_next_uncomment_line(line)) {
148  std::istringstream iss(line);
149  int num_face_vertices;
150  iss >> num_face_vertices;
151  std::vector<int> face;
152  face.assign(std::istream_iterator<int>(iss), std::istream_iterator<int>());
153  // if (face.size() != (off_info_.dim + 1)) return false;
154  visitor.maximal_face(face);
155  }
156  return true;
157  }
158 };
159 
160 template<typename OFFVisitor>
161 void read_off(const std::string& name_file_off, OFFVisitor& vis) {
162  std::ifstream stream(name_file_off);
163  if (!stream.is_open()) {
164  std::cerr << "could not open file \n";
165  } else {
166  Off_reader off_reader(stream);
167  off_reader.read(vis);
168  }
169 }
170 
171 } // namespace Gudhi
172 
173 #endif // OFF_READER_H_
bool read(OffVisitor &off_visitor)
Read an OFF file and calls the following methods :
Definition: Off_reader.h:51
Definition: SimplicialComplexForAlpha.h:14
OFF file reader top class visitor.
Definition: Off_reader.h:29
GUDHI  Version 3.1.1  - C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding.  - Copyright : MIT Generated on Fri Feb 7 2020 16:35:36 for GUDHI by Doxygen 1.8.13