Commit ce0d2040 authored by Martin Heistermann's avatar Martin Heistermann
Browse files

New FileManager feature: iostreams instead of filenames.

parent ad214e55
Pipeline #7316 passed with stage
in 5 minutes and 19 seconds
...@@ -45,6 +45,8 @@ ...@@ -45,6 +45,8 @@
#include <string> #include <string>
#include <fstream> #include <fstream>
#include <istream>
#include <ostream>
namespace OpenVolumeMesh { namespace OpenVolumeMesh {
...@@ -66,6 +68,27 @@ public: ...@@ -66,6 +68,27 @@ public:
/// Default destructor /// Default destructor
~FileManager(); ~FileManager();
/**
* \brief Read a mesh from an std::istream
*
* Returns true if the file was successfully read. The mesh
* is stored in parameter _mesh. If something goes wrong,
* this function returns false.
*
* @param _istream The stream to read the mesh from
* @param _mesh A reference to an OpenVolumeMesh instance
* @param _topologyCheck Pass true if you want to perform a topology check
* each time an entity is added (slower performance)
* @param _computeBottomUpIncidences Pass true if you want the file manager
* to directly compute the bottom-up incidences
* for the mesh. (Note: These are needed for
* some iterators to work, see documentation)
*/
template <class MeshT>
bool readStream(std::istream &_istream, MeshT& _mesh,
bool _topologyCheck = true,
bool _computeBottomUpIncidences = true) const;
/** /**
* \brief Read a mesh from a file * \brief Read a mesh from a file
* *
...@@ -87,6 +110,16 @@ public: ...@@ -87,6 +110,16 @@ public:
bool _topologyCheck = true, bool _topologyCheck = true,
bool _computeBottomUpIncidences = true) const; bool _computeBottomUpIncidences = true) const;
/**
* \brief Write a mesh to an std::ostream
*
* @param _ostream The stream to write the mesh to
* @param _mesh A const reference to an OpenVolumeMesh instance
*/
template <class MeshT>
void writeStream(std::ostream &_ostream, const MeshT& _mesh) const;
/** /**
* \brief Write a mesh to a file * \brief Write a mesh to a file
* *
......
...@@ -63,18 +63,10 @@ using namespace OpenVolumeMesh::Geometry; ...@@ -63,18 +63,10 @@ using namespace OpenVolumeMesh::Geometry;
//================================================== //==================================================
template <class MeshT> template<class MeshT>
bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, bool FileManager::readStream(std::istream &_istream, MeshT &_mesh,
bool _topologyCheck, bool _computeBottomUpIncidences) const { bool _topologyCheck, bool _computeBottomUpIncidences) const
{
std::ifstream iff(_filename.c_str(), std::ios::in);
if(!iff.good()) {
std::cerr << "Error: Could not open file " << _filename << " for reading!" << std::endl;
iff.close();
return false;
}
std::stringstream sstr; std::stringstream sstr;
std::string line; std::string line;
std::string s_tmp; std::string s_tmp;
...@@ -95,14 +87,14 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, ...@@ -95,14 +87,14 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
bool header_found = true; bool header_found = true;
// Get first line // Get first line
getCleanLine(iff, line); getCleanLine(_istream, line);
sstr.str(line); sstr.str(line);
// Check header // Check header
sstr >> s_tmp; sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper); std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp != "OVM") { if(s_tmp != "OVM") {
//iff.close(); //_istream.close();
header_found = false; header_found = false;
std::cerr << "The specified file might not be in OpenVolumeMesh format!" << std::endl; std::cerr << "The specified file might not be in OpenVolumeMesh format!" << std::endl;
//return false; //return false;
...@@ -112,7 +104,6 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, ...@@ -112,7 +104,6 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
sstr >> s_tmp; sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper); std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp == "BINARY") { if(s_tmp == "BINARY") {
iff.close();
std::cerr << "Binary files are not supported at the moment!" << std::endl; std::cerr << "Binary files are not supported at the moment!" << std::endl;
return false; return false;
} }
...@@ -124,7 +115,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, ...@@ -124,7 +115,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
sstr.clear(); sstr.clear();
sstr.str(line); sstr.str(line);
} else { } else {
getCleanLine(iff, line); getCleanLine(_istream, line);
sstr.clear(); sstr.clear();
sstr.str(line); sstr.str(line);
} }
...@@ -132,13 +123,12 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, ...@@ -132,13 +123,12 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
sstr >> s_tmp; sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper); std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp != "VERTICES") { if(s_tmp != "VERTICES") {
iff.close();
std::cerr << "No vertex section defined!" << std::endl; std::cerr << "No vertex section defined!" << std::endl;
return false; return false;
} else { } else {
// Read in number of vertices // Read in number of vertices
getCleanLine(iff, line); getCleanLine(_istream, line);
sstr.clear(); sstr.clear();
sstr.str(line); sstr.str(line);
sstr >> c; sstr >> c;
...@@ -146,7 +136,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, ...@@ -146,7 +136,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
// Read in vertices // Read in vertices
for(uint64_t i = 0u; i < c; ++i) { for(uint64_t i = 0u; i < c; ++i) {
getCleanLine(iff, line); getCleanLine(_istream, line);
sstr.clear(); sstr.clear();
sstr.str(line); sstr.str(line);
sstr >> v[0]; sstr >> v[0];
...@@ -159,19 +149,18 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, ...@@ -159,19 +149,18 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
/* /*
* Edges * Edges
*/ */
getCleanLine(iff, line); getCleanLine(_istream, line);
sstr.clear(); sstr.clear();
sstr.str(line); sstr.str(line);
sstr >> s_tmp; sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper); std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp != "EDGES") { if(s_tmp != "EDGES") {
iff.close();
std::cerr << "No edge section defined!" << std::endl; std::cerr << "No edge section defined!" << std::endl;
return false; return false;
} else { } else {
// Read in number of edges // Read in number of edges
getCleanLine(iff, line); getCleanLine(_istream, line);
sstr.clear(); sstr.clear();
sstr.str(line); sstr.str(line);
sstr >> c; sstr >> c;
...@@ -181,7 +170,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, ...@@ -181,7 +170,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
unsigned int v1 = 0; unsigned int v1 = 0;
unsigned int v2 = 0; unsigned int v2 = 0;
getCleanLine(iff, line); getCleanLine(_istream, line);
sstr.clear(); sstr.clear();
sstr.str(line); sstr.str(line);
sstr >> v1; sstr >> v1;
...@@ -193,19 +182,18 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, ...@@ -193,19 +182,18 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
/* /*
* Faces * Faces
*/ */
getCleanLine(iff, line); getCleanLine(_istream, line);
sstr.clear(); sstr.clear();
sstr.str(line); sstr.str(line);
sstr >> s_tmp; sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper); std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp != "FACES") { if(s_tmp != "FACES") {
iff.close();
std::cerr << "No face section defined!" << std::endl; std::cerr << "No face section defined!" << std::endl;
return false; return false;
} else { } else {
// Read in number of faces // Read in number of faces
getCleanLine(iff, line); getCleanLine(_istream, line);
sstr.clear(); sstr.clear();
sstr.str(line); sstr.str(line);
sstr >> c; sstr >> c;
...@@ -213,7 +201,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, ...@@ -213,7 +201,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
// Read in faces // Read in faces
for(uint64_t i = 0u; i < c; ++i) { for(uint64_t i = 0u; i < c; ++i) {
getCleanLine(iff, line); getCleanLine(_istream, line);
sstr.clear(); sstr.clear();
sstr.str(line); sstr.str(line);
...@@ -226,7 +214,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, ...@@ -226,7 +214,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
// Read half-edge indices // Read half-edge indices
for(unsigned int e = 0; e < val; ++e) { for(unsigned int e = 0; e < val; ++e) {
unsigned int v1 = 0; unsigned int v1 = 0;
sstr >> v1; sstr >> v1;
hes.push_back(HalfEdgeHandle(v1)); hes.push_back(HalfEdgeHandle(v1));
} }
...@@ -238,19 +226,18 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, ...@@ -238,19 +226,18 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
/* /*
* Cells * Cells
*/ */
getCleanLine(iff, line); getCleanLine(_istream, line);
sstr.clear(); sstr.clear();
sstr.str(line); sstr.str(line);
sstr >> s_tmp; sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper); std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp != "POLYHEDRA") { if(s_tmp != "POLYHEDRA") {
iff.close();
std::cerr << "No polyhedra section defined!" << std::endl; std::cerr << "No polyhedra section defined!" << std::endl;
return false; return false;
} else { } else {
// Read in number of cells // Read in number of cells
getCleanLine(iff, line); getCleanLine(_istream, line);
sstr.clear(); sstr.clear();
sstr.str(line); sstr.str(line);
sstr >> c; sstr >> c;
...@@ -258,7 +245,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, ...@@ -258,7 +245,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
// Read in cells // Read in cells
for(uint64_t i = 0u; i < c; ++i) { for(uint64_t i = 0u; i < c; ++i) {
getCleanLine(iff, line); getCleanLine(_istream, line);
sstr.clear(); sstr.clear();
sstr.str(line); sstr.str(line);
...@@ -271,7 +258,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, ...@@ -271,7 +258,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
// Read half-face indices // Read half-face indices
for(unsigned int f = 0; f < val; ++f) { for(unsigned int f = 0; f < val; ++f) {
unsigned int v1 = 0; unsigned int v1 = 0;
sstr >> v1; sstr >> v1;
hfs.push_back(HalfFaceHandle(v1)); hfs.push_back(HalfFaceHandle(v1));
} }
...@@ -280,16 +267,14 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, ...@@ -280,16 +267,14 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
} }
} }
while(!iff.eof()) { while(!_istream.eof()) {
// "End of file reached while searching for input!" // "End of file reached while searching for input!"
// is thrown here. \TODO Fix it! // is thrown here. \TODO Fix it!
// Read property // Read property
readProperty(iff, _mesh); readProperty(_istream, _mesh);
} }
iff.close();
if(_computeBottomUpIncidences) { if(_computeBottomUpIncidences) {
// Compute bottom-up incidences // Compute bottom-up incidences
_mesh.enable_bottom_up_incidences(true); _mesh.enable_bottom_up_incidences(true);
...@@ -305,6 +290,20 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh, ...@@ -305,6 +290,20 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
return true; return true;
} }
template <class MeshT>
bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
bool _topologyCheck, bool _computeBottomUpIncidences) const {
std::ifstream iff(_filename.c_str(), std::ios::in);
if(!iff.good()) {
std::cerr << "Error: Could not open file " << _filename << " for reading!" << std::endl;
iff.close();
return false;
}
return readStream(iff, _mesh, _topologyCheck,_computeBottomUpIncidences);
}
//================================================== //==================================================
template <class MeshT> template <class MeshT>
...@@ -403,23 +402,16 @@ void FileManager::generateGenericProperty(const std::string& _entity_t, const st ...@@ -403,23 +402,16 @@ void FileManager::generateGenericProperty(const std::string& _entity_t, const st
//================================================== //==================================================
template<class MeshT>
bool FileManager::writeFile(const std::string& _filename, const MeshT& _mesh) const {
std::ofstream off(_filename.c_str(), std::ios::out);
if(!off.good()) {
std::cerr << "Error: Could not open file " << _filename << " for writing!" << std::endl;
off.close();
return false;
}
template<class MeshT>
void FileManager::writeStream(std::ostream &_ostream, const MeshT &_mesh) const
{
// Write header // Write header
off << "OVM ASCII" << std::endl; _ostream << "OVM ASCII" << std::endl;
uint64_t n_vertices(_mesh.n_vertices()); uint64_t n_vertices(_mesh.n_vertices());
off << "Vertices" << std::endl; _ostream << "Vertices" << std::endl;
off << n_vertices << std::endl; _ostream << n_vertices << std::endl;
typedef typename MeshT::PointT Point; typedef typename MeshT::PointT Point;
...@@ -427,84 +419,93 @@ bool FileManager::writeFile(const std::string& _filename, const MeshT& _mesh) co ...@@ -427,84 +419,93 @@ bool FileManager::writeFile(const std::string& _filename, const MeshT& _mesh) co
for(VertexIter v_it = _mesh.v_iter(); v_it; ++v_it) { for(VertexIter v_it = _mesh.v_iter(); v_it; ++v_it) {
Point v = _mesh.vertex(*v_it); Point v = _mesh.vertex(*v_it);
off << v[0] << " " << v[1] << " " << v[2] << std::endl; _ostream << v[0] << " " << v[1] << " " << v[2] << std::endl;
} }
uint64_t n_edges(_mesh.n_edges()); uint64_t n_edges(_mesh.n_edges());
off << "Edges" << std::endl; _ostream << "Edges" << std::endl;
off << n_edges << std::endl; _ostream << n_edges << std::endl;
// write edges // write edges
for(EdgeIter e_it = _mesh.e_iter(); e_it; ++e_it) { for(EdgeIter e_it = _mesh.e_iter(); e_it; ++e_it) {
VertexHandle from_vertex = _mesh.edge(*e_it).from_vertex(); VertexHandle from_vertex = _mesh.edge(*e_it).from_vertex();
VertexHandle to_vertex = _mesh.edge(*e_it).to_vertex(); VertexHandle to_vertex = _mesh.edge(*e_it).to_vertex();
off << from_vertex << " " << to_vertex << std::endl; _ostream << from_vertex << " " << to_vertex << std::endl;
} }
uint64_t n_faces(_mesh.n_faces()); uint64_t n_faces(_mesh.n_faces());
off << "Faces" << std::endl; _ostream << "Faces" << std::endl;
off << n_faces << std::endl; _ostream << n_faces << std::endl;
// write faces // write faces
for(FaceIter f_it = _mesh.f_iter(); f_it; ++f_it) { for(FaceIter f_it = _mesh.f_iter(); f_it; ++f_it) {
off << static_cast<uint64_t>(_mesh.face(*f_it).halfedges().size()) << " "; _ostream << static_cast<uint64_t>(_mesh.face(*f_it).halfedges().size()) << " ";
std::vector<HalfEdgeHandle> halfedges = _mesh.face(*f_it).halfedges(); std::vector<HalfEdgeHandle> halfedges = _mesh.face(*f_it).halfedges();
for(typename std::vector<HalfEdgeHandle>::const_iterator it = halfedges.begin(); it for(typename std::vector<HalfEdgeHandle>::const_iterator it = halfedges.begin(); it
!= halfedges.end(); ++it) { != halfedges.end(); ++it) {
off << it->idx(); _ostream << it->idx();
if((it + 1) != halfedges.end()) if((it + 1) != halfedges.end())
off << " "; _ostream << " ";
} }
off << std::endl; _ostream << std::endl;
} }
uint64_t n_cells(_mesh.n_cells()); uint64_t n_cells(_mesh.n_cells());
off << "Polyhedra" << std::endl; _ostream << "Polyhedra" << std::endl;
off << n_cells << std::endl; _ostream << n_cells << std::endl;
for(CellIter c_it = _mesh.c_iter(); c_it; ++c_it) { for(CellIter c_it = _mesh.c_iter(); c_it; ++c_it) {
off << static_cast<uint64_t>(_mesh.cell(*c_it).halffaces().size()) << " "; _ostream << static_cast<uint64_t>(_mesh.cell(*c_it).halffaces().size()) << " ";
std::vector<HalfFaceHandle> halffaces = _mesh.cell(*c_it).halffaces(); std::vector<HalfFaceHandle> halffaces = _mesh.cell(*c_it).halffaces();
for(typename std::vector<HalfFaceHandle>::const_iterator it = halffaces.begin(); it for(typename std::vector<HalfFaceHandle>::const_iterator it = halffaces.begin(); it
!= halffaces.end(); ++it) { != halffaces.end(); ++it) {
off << it->idx(); _ostream << it->idx();
if((it + 1) != halffaces.end()) if((it + 1) != halffaces.end())
off << " "; _ostream << " ";
} }
off << std::endl; _ostream << std::endl;
} }
// write vertex props // write vertex props
writeProps(off, _mesh.vertex_props_begin(), _mesh.vertex_props_end()); writeProps(_ostream, _mesh.vertex_props_begin(), _mesh.vertex_props_end());
// write edge props // write edge props
writeProps(off, _mesh.edge_props_begin(), _mesh.edge_props_end()); writeProps(_ostream, _mesh.edge_props_begin(), _mesh.edge_props_end());
// write halfedge props // write halfedge props
writeProps(off, _mesh.halfedge_props_begin(), _mesh.halfedge_props_end()); writeProps(_ostream, _mesh.halfedge_props_begin(), _mesh.halfedge_props_end());
// write face props // write face props
writeProps(off, _mesh.face_props_begin(), _mesh.face_props_end()); writeProps(_ostream, _mesh.face_props_begin(), _mesh.face_props_end());
// write halfface props // write halfface props
writeProps(off, _mesh.halfface_props_begin(), _mesh.halfface_props_end()); writeProps(_ostream, _mesh.halfface_props_begin(), _mesh.halfface_props_end());
// write cell props // write cell props
writeProps(off, _mesh.cell_props_begin(), _mesh.cell_props_end()); writeProps(_ostream, _mesh.cell_props_begin(), _mesh.cell_props_end());
// write mesh props // write mesh props
writeProps(off, _mesh.mesh_props_begin(), _mesh.mesh_props_end()); writeProps(_ostream, _mesh.mesh_props_begin(), _mesh.mesh_props_end());
}
off.close(); template<class MeshT>
bool FileManager::writeFile(const std::string& _filename, const MeshT& _mesh) const {
return true; std::ofstream off(_filename.c_str(), std::ios::out);
if(!off.good()) {
std::cerr << "Error: Could not open file " << _filename << " for writing!" << std::endl;
return false;
}
writeStream(off, _mesh);