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
23namespace Gudhi {
24
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
160template<typename OFFVisitor>
161void 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_
OFF file reader top class visitor.
Definition: Off_reader.h:29
bool read(OffVisitor &off_visitor)
Read an OFF file and calls the following methods :
Definition: Off_reader.h:51