Commit 687c4e76 authored by Jan Möbius's avatar Jan Möbius
Browse files

Merge branch 'feature/filemanager-improvements' into 'master'

FileManager improvements

See merge request !37
parents ad214e55 c7ff1cac
Pipeline #7506 failed with stage
in 3 minutes and 39 seconds
......@@ -126,7 +126,9 @@ bool FileManager::getCleanLine(std::istream& _ifs, std::string& _string, bool _s
}
if(_ifs.eof()) {
if (verbosity_level_ >= 2) {
std::cerr << "End of file reached while searching for input!" << std::endl;
}
return false;
}
}
......@@ -141,7 +143,9 @@ bool FileManager::isHexahedralMesh(const std::string& _filename) const {
std::ifstream iff(_filename.c_str(), std::ios::in);
if(!iff.good()) {
if (verbosity_level_ >= 1) {
std::cerr << "Could not open file " << _filename << " for reading!" << std::endl;
}
iff.close();
return false;
}
......@@ -185,7 +189,9 @@ bool FileManager::isTetrahedralMesh(const std::string& _filename) const {
std::ifstream iff(_filename.c_str(), std::ios::in);
if(!iff.good()) {
if (verbosity_level_ >= 1) {
std::cerr << "Could not open file " << _filename << " for reading!" << std::endl;
}
iff.close();
return false;
}
......
......@@ -45,6 +45,8 @@
#include <string>
#include <fstream>
#include <istream>
#include <ostream>
namespace OpenVolumeMesh {
......@@ -66,6 +68,34 @@ public:
/// Default destructor
~FileManager();
/**
* \brief set minimum level for errors that are printed to std::cerr
* @param _level 0: no output; 1: only errors; 2: warnings/info
*/
void setVerbosityLevel(int _level) { verbosity_level_ = _level;}
/**
* \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
*
......@@ -87,6 +117,16 @@ public:
bool _topologyCheck = true,
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
*
......@@ -134,6 +174,9 @@ private:
// Get a whole line from file
bool getCleanLine(std::istream& ifs, std::string& _string, bool _skipEmptyLines = true) const;
int verbosity_level_ = 3;
};
} // Namespace IO
......
......@@ -63,18 +63,10 @@ using namespace OpenVolumeMesh::Geometry;
//==================================================
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;
}
template<class MeshT>
bool FileManager::readStream(std::istream &_istream, MeshT &_mesh,
bool _topologyCheck, bool _computeBottomUpIncidences) const
{
std::stringstream sstr;
std::string line;
std::string s_tmp;
......@@ -95,16 +87,18 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
bool header_found = true;
// Get first line
getCleanLine(iff, line);
getCleanLine(_istream, line);
sstr.str(line);
// Check header
sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp != "OVM") {
//iff.close();
//_istream.close();
header_found = false;
if (verbosity_level_ >= 1) {
std::cerr << "The specified file might not be in OpenVolumeMesh format!" << std::endl;
}
//return false;
}
......@@ -112,8 +106,9 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp == "BINARY") {
iff.close();
if (verbosity_level_ >= 1) {
std::cerr << "Binary files are not supported at the moment!" << std::endl;
}
return false;
}
......@@ -124,7 +119,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
sstr.clear();
sstr.str(line);
} else {
getCleanLine(iff, line);
getCleanLine(_istream, line);
sstr.clear();
sstr.str(line);
}
......@@ -132,13 +127,14 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp != "VERTICES") {
iff.close();
if (verbosity_level_ >= 1) {
std::cerr << "No vertex section defined!" << std::endl;
}
return false;
} else {
// Read in number of vertices
getCleanLine(iff, line);
getCleanLine(_istream, line);
sstr.clear();
sstr.str(line);
sstr >> c;
......@@ -146,7 +142,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
// Read in vertices
for(uint64_t i = 0u; i < c; ++i) {
getCleanLine(iff, line);
getCleanLine(_istream, line);
sstr.clear();
sstr.str(line);
sstr >> v[0];
......@@ -159,19 +155,20 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
/*
* Edges
*/
getCleanLine(iff, line);
getCleanLine(_istream, line);
sstr.clear();
sstr.str(line);
sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp != "EDGES") {
iff.close();
if (verbosity_level_ >= 2) {
std::cerr << "No edge section defined!" << std::endl;
}
return false;
} else {
// Read in number of edges
getCleanLine(iff, line);
getCleanLine(_istream, line);
sstr.clear();
sstr.str(line);
sstr >> c;
......@@ -181,7 +178,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
unsigned int v1 = 0;
unsigned int v2 = 0;
getCleanLine(iff, line);
getCleanLine(_istream, line);
sstr.clear();
sstr.str(line);
sstr >> v1;
......@@ -193,19 +190,20 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
/*
* Faces
*/
getCleanLine(iff, line);
getCleanLine(_istream, line);
sstr.clear();
sstr.str(line);
sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp != "FACES") {
iff.close();
if (verbosity_level_ >= 2) {
std::cerr << "No face section defined!" << std::endl;
}
return false;
} else {
// Read in number of faces
getCleanLine(iff, line);
getCleanLine(_istream, line);
sstr.clear();
sstr.str(line);
sstr >> c;
......@@ -213,7 +211,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
// Read in faces
for(uint64_t i = 0u; i < c; ++i) {
getCleanLine(iff, line);
getCleanLine(_istream, line);
sstr.clear();
sstr.str(line);
......@@ -238,19 +236,20 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
/*
* Cells
*/
getCleanLine(iff, line);
getCleanLine(_istream, line);
sstr.clear();
sstr.str(line);
sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp != "POLYHEDRA") {
iff.close();
if (verbosity_level_ >= 2) {
std::cerr << "No polyhedra section defined!" << std::endl;
}
return false;
} else {
// Read in number of cells
getCleanLine(iff, line);
getCleanLine(_istream, line);
sstr.clear();
sstr.str(line);
sstr >> c;
......@@ -258,7 +257,7 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
// Read in cells
for(uint64_t i = 0u; i < c; ++i) {
getCleanLine(iff, line);
getCleanLine(_istream, line);
sstr.clear();
sstr.str(line);
......@@ -280,31 +279,47 @@ bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
}
}
while(!iff.eof()) {
while(!_istream.eof()) {
// "End of file reached while searching for input!"
// is thrown here. \TODO Fix it!
// Read property
readProperty(iff, _mesh);
readProperty(_istream, _mesh);
}
iff.close();
if(_computeBottomUpIncidences) {
// Compute bottom-up incidences
_mesh.enable_bottom_up_incidences(true);
}
if (verbosity_level_ >= 2) {
std::cerr << "######## openvolumemesh info #########" << std::endl;
std::cerr << "#vertices: " << _mesh.n_vertices() << std::endl;
std::cerr << "#edges: " << _mesh.n_edges() << std::endl;
std::cerr << "#faces: " << _mesh.n_faces() << std::endl;
std::cerr << "#cells: " << _mesh.n_cells() << std::endl;
std::cerr << "######################################" << std::endl;
}
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()) {
if (verbosity_level_ >= 1) {
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>
......@@ -326,7 +341,9 @@ void FileManager::readProperty(std::istream& _iff, MeshT& _mesh) const {
name = line;
extractQuotedText(name);
if (verbosity_level_ >= 2) {
std::cerr << "OVM read property " << name << " of type " << prop_t << std::endl;
}
if(prop_t == typeName<int>()) generateGenericProperty<int, MeshT>(entity_t, name, _iff, _mesh);
else if(prop_t == typeName<unsigned int>()) generateGenericProperty<unsigned int, MeshT>(entity_t, name, _iff, _mesh);
......@@ -403,23 +420,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
off << "OVM ASCII" << std::endl;
_ostream << "OVM ASCII" << std::endl;
uint64_t n_vertices(_mesh.n_vertices());
off << "Vertices" << std::endl;
off << n_vertices << std::endl;
_ostream << "Vertices" << std::endl;
_ostream << n_vertices << std::endl;
typedef typename MeshT::PointT Point;
......@@ -427,84 +437,95 @@ bool FileManager::writeFile(const std::string& _filename, const MeshT& _mesh) co
for(VertexIter v_it = _mesh.v_iter(); v_it; ++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());
off << "Edges" << std::endl;
off << n_edges << std::endl;
_ostream << "Edges" << std::endl;
_ostream << n_edges << std::endl;
// write edges
for(EdgeIter e_it = _mesh.e_iter(); e_it; ++e_it) {
VertexHandle from_vertex = _mesh.edge(*e_it).from_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());
off << "Faces" << std::endl;
off << n_faces << std::endl;
_ostream << "Faces" << std::endl;
_ostream << n_faces << std::endl;
// write faces
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();
for(typename std::vector<HalfEdgeHandle>::const_iterator it = halfedges.begin(); it
!= halfedges.end(); ++it) {
off << it->idx();
_ostream << it->idx();
if((it + 1) != halfedges.end())
off << " ";
_ostream << " ";
}
off << std::endl;
_ostream << std::endl;
}
uint64_t n_cells(_mesh.n_cells());
off << "Polyhedra" << std::endl;
off << n_cells << std::endl;
_ostream << "Polyhedra" << std::endl;
_ostream << n_cells << std::endl;
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();
for(typename std::vector<HalfFaceHandle>::const_iterator it = halffaces.begin(); it
!= halffaces.end(); ++it) {
off << it->idx();
_ostream << it->idx();
if((it + 1) != halffaces.end())
off << " ";
_ostream << " ";
}
off << std::endl;
_ostream << std::endl;
}
// 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
writeProps(off, _mesh.edge_props_begin(), _mesh.edge_props_end());
writeProps(_ostream, _mesh.edge_props_begin(), _mesh.edge_props_end());
// 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
writeProps(off, _mesh.face_props_begin(), _mesh.face_props_end());
writeProps(_ostream, _mesh.face_props_begin(), _mesh.face_props_end());
// 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
writeProps(off, _mesh.cell_props_begin(), _mesh.cell_props_end());
writeProps(_ostream, _mesh.cell_props_begin(), _mesh.cell_props_end());
// 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()) {
if (verbosity_level_ >= 1) {
std::cerr << "Error: Could not open file " << _filename << " for writing!" << std::endl;
}
return false;
}
writeStream(off, _mesh);
return off.good();
}
//==================================================
......@@ -517,7 +538,9 @@ void FileManager::writeProps(std::ostream& _ostr, const IteratorT& _begin, const
p_it != _end; ++p_it) {
if(!(*p_it)->persistent()) continue;
if((*p_it)->anonymous()) {
if (verbosity_level_ >= 2) {
std::cerr << "Serialization of anonymous properties is not supported!" << std::endl;
}
continue;
}
......@@ -525,7 +548,9 @@ void FileManager::writeProps(std::ostream& _ostr, const IteratorT& _begin, const
try {
type_name = (*p_it)->typeNameWrapper();
} catch (std::runtime_error &e) { // type not serializable
std::cerr << "Failed to save property, skipping: " << e.what() << std::endl;
if (verbosity_level_ >= 1) {
std::cerr << "Failed to save property " << (*p_it)->name() << " , skipping: " << e.what() << std::endl;
}
continue;
}
_ostr << (*p_it)->entityType() << " ";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment