diff options
Diffstat (limited to 'src/common/include/gudhi')
-rw-r--r-- | src/common/include/gudhi/Debug_utils.h (renamed from src/common/include/gudhi/Utils.h) | 41 | ||||
-rw-r--r-- | src/common/include/gudhi/Off_reader.h | 49 | ||||
-rw-r--r-- | src/common/include/gudhi/Points_off_io.h | 177 | ||||
-rw-r--r-- | src/common/include/gudhi/distance_functions.h | 4 | ||||
-rw-r--r-- | src/common/include/gudhi/reader_utils.h | 6 |
5 files changed, 231 insertions, 46 deletions
diff --git a/src/common/include/gudhi/Utils.h b/src/common/include/gudhi/Debug_utils.h index 43916f11..7573a9db 100644 --- a/src/common/include/gudhi/Utils.h +++ b/src/common/include/gudhi/Debug_utils.h @@ -19,28 +19,37 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef UTILS_H_ -#define UTILS_H_ +#ifndef DEBUG_UTILS_H_ +#define DEBUG_UTILS_H_ +#include <iostream> + +#ifndef NDEBUG + // GUDHI_DEBUG is the Gudhi official flag for debug mode. + #define GUDHI_DEBUG +#endif + +// GUDHI_CHECK throw an exception if expression is false in debug mode, but does nothing in release mode +// Could assert in release mode, but cmake sets NDEBUG (for "NO DEBUG") in this mode, means assert does nothing. +#ifdef GUDHI_DEBUG + #define GUDHI_CHECK(expression, excpt) if ((expression) == 0) throw excpt +#else + #define GUDHI_CHECK(expression, excpt) (void) 0 +#endif #define PRINT(a) std::cerr << #a << ": " << (a) << " (DISP)" << std::endl // #define DBG_VERBOSE #ifdef DBG_VERBOSE -#define DBG(a) std::cerr << "DBG: " << (a) << std::endl -#define DBGMSG(a, b) std::cerr << "DBG: " << a << b << std::endl -#define DBGVALUE(a) std::cerr << "DBG: " << #a << ": " << a << std::endl -#define DBGCONT(a) std::cerr << "DBG: container " << #a << " -> "; for (auto x : a) std::cerr << x << ","; std::cerr << -std::endl + #define DBG(a) std::cout << "DBG: " << (a) << std::endl + #define DBGMSG(a, b) std::cout << "DBG: " << a << b << std::endl + #define DBGVALUE(a) std::cout << "DBG: " << #a << ": " << a << std::endl + #define DBGCONT(a) std::cout << "DBG: container " << #a << " -> "; for (auto x : a) std::cout << x << ","; std::cout << std::endl #else -// #define DBG(a) a -// #define DBGMSG(a,b) b -// #define DBGVALUE(a) a -// #define DBGCONT(a) a -#define DBG(a) -#define DBGMSG(a, b) -#define DBGVALUE(a) -#define DBGCONT(a) + #define DBG(a) (void) 0 + #define DBGMSG(a, b) (void) 0 + #define DBGVALUE(a) (void) 0 + #define DBGCONT(a) (void) 0 #endif -#endif // UTILS_H_ +#endif // DEBUG_UTILS_H_ diff --git a/src/common/include/gudhi/Off_reader.h b/src/common/include/gudhi/Off_reader.h index 81b9e634..4fcd2af2 100644 --- a/src/common/include/gudhi/Off_reader.h +++ b/src/common/include/gudhi/Off_reader.h @@ -31,40 +31,35 @@ #include <iterator> #include <string> #include <vector> +#include <fstream> namespace Gudhi { -/** - * Read an off file and calls a visitor methods while reading it. - * An off file must have its first/snd line in this format : - * OFF - * num_vert num_faces num_edges - * - * A noff file must have its first/snd line in this format : - * nOFF - * dim num_vert num_faces num_edges - * - * The number of edges num_edges is optional and can be left to zero. +/** \brief OFF file reader top class visitor. + * + * OFF file must be conform to format described here : + * http://www.geomview.org/docs/html/OFF.html */ class Off_reader { public: Off_reader(std::ifstream& stream) : stream_(stream) { } - // Off_reader(const std::string& name):stream_(name){ - // if(!stream_.is_open()) - // std::cerr <<"could not open file \n"; - // } ~Off_reader() { stream_.close(); } - /** - * read an off file and calls the following methods : - * void init(int dim,int num_vertices,int num_faces,int num_edges); //num_edges may not be set - * void point(const std::vector<double>& point); - * void maximal_face(const std::list<int>& face); - * void done(); - * of the visitor when reading a point or a maximal face. + /** \brief + * Read an OFF file and calls the following methods : + * + * <CODE>void init(int dim,int num_vertices,int num_faces,int num_edges); // from file header - num_edges may not be set + * + * void point(const std::vector<double>& point); // for each point read + * + * void maximal_face(const std::list<int>& face); // for each face read + * + * void done(); // upon file read is finished</CODE> + * + * of the visitor when reading a point or a maximal face. Edges are not taken into account. */ template<typename OffVisitor> bool read(OffVisitor& off_visitor) { @@ -118,7 +113,7 @@ class Off_reader { if (!goto_next_uncomment_line(line)) return false; std::istringstream iss(line); - if (is_off_file) { + if ((is_off_file) && (!is_noff_file)) { off_info_.dim = 3; if (!(iss >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) { std::cerr << "incorrect number of vertices/faces/edges\n"; @@ -126,8 +121,8 @@ class Off_reader { } } else { if (!(iss >> off_info_.dim >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) { - std::cerr << "incorrect number of vertices/faces/edges\n"; - return false; + std::cerr << "incorrect number of vertices/faces/edges\n"; + return false; } } off_visitor.init(off_info_.dim, off_info_.num_vertices, off_info_.num_faces, off_info_.num_edges); @@ -138,7 +133,7 @@ class Off_reader { bool goto_next_uncomment_line(std::string& uncomment_line) { uncomment_line.clear(); do - std::getline(stream_, uncomment_line); while (uncomment_line[0] == '%'); // || uncomment_line.empty()); + std::getline(stream_, uncomment_line); while (uncomment_line[0] == '%'); return (uncomment_line.size() > 0 && uncomment_line[0] != '%'); } @@ -166,7 +161,7 @@ class Off_reader { iss >> num_face_vertices; std::vector<int> face; face.assign(std::istream_iterator<int>(iss), std::istream_iterator<int>()); - if (face.size() != off_info_.dim) return false; + // if (face.size() != (off_info_.dim + 1)) return false; visitor.maximal_face(face); } return true; diff --git a/src/common/include/gudhi/Points_off_io.h b/src/common/include/gudhi/Points_off_io.h new file mode 100644 index 00000000..77f36be2 --- /dev/null +++ b/src/common/include/gudhi/Points_off_io.h @@ -0,0 +1,177 @@ +/* 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): Vincent Rouvreau + * + * Copyright (C) 2015 INRIA Saclay (France) + * + * 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 <http://www.gnu.org/licenses/>. + */ +#ifndef POINTS_OFF_IO_H_ +#define POINTS_OFF_IO_H_ + +#include <gudhi/Off_reader.h> + +#include <string> +#include <vector> +#include <fstream> +#include <map> + +namespace Gudhi { + +/** + * \brief OFF file visitor implementation according to Off_reader in order to read points from an OFF file. + */ +template<typename Point_d> +class Points_off_visitor_reader { + private: + std::vector<Point_d> point_cloud; + + public: + /** \brief Off_reader visitor init implementation. + * + * The init parameters are set from OFF file header. + * Dimension value is required in order to construct Alpha complex. + * + * @param[in] dim space dimension of vertices. + * @param[in] num_vertices number of vertices in the OFF file (not used). + * @param[in] num_faces number of faces in the OFF file (not used). + * @param[in] num_edges number of edges in the OFF file (not used). + */ + void init(int dim, int num_vertices, int num_faces, int num_edges) { +#ifdef DEBUG_TRACES + std::cout << "Points_off_visitor_reader::init - dim=" << dim << " - num_vertices=" << + num_vertices << " - num_faces=" << num_faces << " - num_edges=" << num_edges << std::endl; +#endif // DEBUG_TRACES + if (num_faces > 0) { + std::cerr << "Points_off_visitor_reader::init faces are not taken into account from OFF file for Points.\n"; + } + if (num_edges > 0) { + std::cerr << "Points_off_visitor_reader::init edges are not taken into account from OFF file for Points.\n"; + } + } + + /** \brief Off_reader visitor point implementation. + * + * The point function is called on each vertex line from OFF file. + * This function inserts the vertex in the Alpha complex. + * + * @param[in] point vector of vertex coordinates. + */ + void point(const std::vector<double>& point) { +#ifdef DEBUG_TRACES + std::cout << "Points_off_visitor_reader::point "; + for (auto coordinate : point) { + std::cout << coordinate << " | "; + } + std::cout << std::endl; +#endif // DEBUG_TRACES + // Fill the point cloud + point_cloud.push_back(Point_d(point.size(), point.begin(), point.end())); + } + + // Off_reader visitor maximal_face implementation - Only points are read + void maximal_face(const std::vector<int>& face) { } + + // Off_reader visitor done implementation - Only points are read + void done() { } + + /** \brief Point cloud getter. + * + * @return point_cloud. + */ + const std::vector<Point_d>& get_point_cloud() const { + return point_cloud; + } +}; + +/** + * \brief OFF file reader implementation in order to read points from an OFF file. + * + * This class is using the Points_off_visitor_reader to visit the OFF file according to Off_reader. + * + * Point_d must have a constructor with the following form: + * + * \code template<class InputIterator > Point_d::Point_d(int d, InputIterator first, InputIterator last) \endcode + * + * where d is the point dimension. + * + * \section Example + * + * This example loads points from an OFF file and builds a vector of CGAL points in dimension d. + * Then, it is asked to display the points. + * + * \include common/CGAL_points_off_reader.cpp + * + * When launching: + * + * \code $> ./cgaloffreader ../../data/points/alphacomplexdoc.off + * \endcode + * + * the program output is: + * + * \include common/cgaloffreader_result.txt + */ +template<typename Point_d> +class Points_off_reader { + public: + /** \brief Reads the OFF file and constructs the Alpha complex from the points + * that are in the OFF file. + * + * @param[in] name_file OFF file to read. + * + * \post Check with is_valid() function to see if read operation was successful. + */ + Points_off_reader(const std::string& name_file) + : valid_(false) { + std::ifstream stream(name_file); + if (stream.is_open()) { + Off_reader off_reader(stream); + Points_off_visitor_reader<Point_d> off_visitor; + valid_ = off_reader.read(off_visitor); + if (valid_) { + point_cloud = off_visitor.get_point_cloud(); + } + } else { + std::cerr << "Points_off_reader::Points_off_reader could not open file " << name_file << "\n"; + } + } + + /** \brief Returns if the OFF file read operation was successful or not. + * + * @return OFF file read status. + */ + bool is_valid() const { + return valid_; + } + + /** \brief Point cloud getter. + * + * @return point_cloud. + */ + const std::vector<Point_d>& get_point_cloud() const { + return point_cloud; + } + + private: + /** \brief point_cloud.*/ + std::vector<Point_d> point_cloud; + /** \brief OFF file read status.*/ + bool valid_; +}; + +} // namespace Gudhi + +#endif // POINTS_OFF_IO_H_ diff --git a/src/common/include/gudhi/distance_functions.h b/src/common/include/gudhi/distance_functions.h index e5c79ded..cd518581 100644 --- a/src/common/include/gudhi/distance_functions.h +++ b/src/common/include/gudhi/distance_functions.h @@ -23,6 +23,8 @@ #ifndef DISTANCE_FUNCTIONS_H_ #define DISTANCE_FUNCTIONS_H_ +#include <cmath> // for std::sqrt + /* Compute the Euclidean distance between two Points given * by a range of coordinates. The points are assumed to have * the same dimension. */ @@ -35,7 +37,7 @@ double euclidean_distance(Point &p1, Point &p2) { double tmp = *it1 - *it2; dist += tmp*tmp; } - return sqrt(dist); + return std::sqrt(dist); } #endif // DISTANCE_FUNCTIONS_H_ diff --git a/src/common/include/gudhi/reader_utils.h b/src/common/include/gudhi/reader_utils.h index e05714c7..899f9df6 100644 --- a/src/common/include/gudhi/reader_utils.h +++ b/src/common/include/gudhi/reader_utils.h @@ -58,7 +58,9 @@ inline void read_points(std::string file_name, std::vector< std::vector< double while (iss >> x) { point.push_back(x); } - points.push_back(point); + // Check for empty lines + if (!point.empty()) + points.push_back(point); } in_file.close(); } @@ -159,7 +161,7 @@ bool read_simplex(std::istream & in_, std::vector< Vertex_handle > & simplex, Fi simplex.push_back(v); } in_ >> fil; - in_.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); // ignore until the carriage return + in_.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); // ignore until the carriage return return true; } |