/* This file is part of the Gudhi Library. The Gudhi library * (Geometric Understanding in Higher Dimensions) is a generic C++ * library for computational topology. * * Author(s): David Salinas * * Copyright (C) 2014 Inria * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SKELETON_BLOCKER_SKELETON_BLOCKER_OFF_IO_H_ #define SKELETON_BLOCKER_SKELETON_BLOCKER_OFF_IO_H_ #include #include #include #include namespace Gudhi { namespace skeleton_blocker { /** *@brief Off reader visitor that can be passed to Off_reader to read a Skeleton_blocker_complex. */ template class Skeleton_blocker_off_flag_visitor_reader { Complex& complex_; typedef typename Complex::Vertex_handle Vertex_handle; typedef typename Complex::Point Point; const bool load_only_points_; public: explicit Skeleton_blocker_off_flag_visitor_reader(Complex& complex, bool load_only_points = false) : complex_(complex), load_only_points_(load_only_points) { } void init(int dim, int num_vertices, int num_faces, int num_edges) { // TODO(DS): do an assert to check that this number are correctly read // TODO(DS): reserve size for vector points } void point(const std::vector& point) { complex_.add_vertex(Point(point.begin(), point.end())); } void maximal_face(const std::vector& face) { if (!load_only_points_) { for (size_t i = 0; i < face.size(); ++i) for (size_t j = i + 1; j < face.size(); ++j) { complex_.add_edge_without_blockers(Vertex_handle(face[i]), Vertex_handle(face[j])); } } } void done() { } }; /** *@brief Off reader visitor that can be passed to Off_reader to read a Skeleton_blocker_complex. */ template class Skeleton_blocker_off_visitor_reader { Complex& complex_; typedef typename Complex::Vertex_handle Vertex_handle; typedef typename Complex::Simplex Simplex; typedef typename Complex::Point Point; const bool load_only_points_; std::vector points_; std::vector maximal_faces_; public: explicit Skeleton_blocker_off_visitor_reader(Complex& complex, bool load_only_points = false) : complex_(complex), load_only_points_(load_only_points) { } void init(int dim, int num_vertices, int num_faces, int num_edges) { maximal_faces_.reserve(num_faces); points_.reserve(num_vertices); } void point(const std::vector& point) { points_.emplace_back(point.begin(), point.end()); } void maximal_face(const std::vector& face) { if (!load_only_points_) { Simplex s; for (auto x : face) s.add_vertex(Vertex_handle(x)); maximal_faces_.emplace_back(s); } } void done() { complex_ = make_complex_from_top_faces(maximal_faces_.begin(), maximal_faces_.end(), points_.begin(), points_.end()); } }; /** *@brief Class that allows to load a Skeleton_blocker_complex from an off file. */ template class Skeleton_blocker_off_reader { public: /** * name_file : file to read * read_complex : complex that will receive the file content * read_only_points : specify true if only the points must be read */ Skeleton_blocker_off_reader(const std::string & name_file, Complex& read_complex, bool read_only_points = false, bool is_flag = false) : valid_(false) { std::ifstream stream(name_file); if (stream.is_open()) { if (is_flag || read_only_points) { Skeleton_blocker_off_flag_visitor_reader off_visitor(read_complex, read_only_points); Off_reader off_reader(stream); valid_ = off_reader.read(off_visitor); } else { Skeleton_blocker_off_visitor_reader off_visitor(read_complex, read_only_points); Off_reader off_reader(stream); valid_ = off_reader.read(off_visitor); } } } /** * return true if reading did not meet problems. */ bool is_valid() const { return valid_; } private: bool valid_; }; template class Skeleton_blocker_off_writer { public: /** * name_file : file where the off will be written * save_complex : complex that be outputted in the file * for now only save triangles. */ Skeleton_blocker_off_writer(const std::string & name_file, const Complex& save_complex) { typedef typename Complex::Vertex_handle Vertex_handle; std::ofstream stream(name_file); if (stream.is_open()) { stream << "OFF\n"; size_t num_triangles = std::distance(save_complex.triangle_range().begin(), save_complex.triangle_range().end()); stream << save_complex.num_vertices() << " " << num_triangles << " 0 \n"; // in case the complex has deactivated some vertices, eg only has vertices 0 2 5 7 for instance // we compute a map from 0 2 5 7 to 0 1 2 3 std::map vertex_num; size_t current_vertex = 0; for (auto v : save_complex.vertex_range()) { vertex_num[v] = current_vertex++; const auto& pt(save_complex.point(v)); for (auto x : pt) stream << x << " "; stream << std::endl; } for (const auto & t : save_complex.triangle_range()) { stream << "3 "; for (auto x : t) stream << vertex_num[x] << " "; stream << std::endl; } stream.close(); } else { std::cerr << "could not open file " << name_file << std::endl; } } }; } // namespace skeleton_blocker namespace skbl = skeleton_blocker; } // namespace Gudhi #endif // SKELETON_BLOCKER_SKELETON_BLOCKER_OFF_IO_H_