Commit 56351967 authored by Mike Kremer's avatar Mike Kremer

Finished ascii file reader which will be deprecated soon...

git-svn-id: http://www.openvolumemesh.org/svnrepo/OpenVolumeMesh/trunk@57 66977474-1d4b-4f09-8fe9-267525286df2
parent 62ee3e4d
......@@ -94,7 +94,7 @@ void SomeClass::someFunction() {
...
// Our two-dimensional integer vector class
typedef OpenVolumeMesh::Vec2ui Vec2ui;
typedef OpenVolumeMesh::Geometry::Vec2ui Vec2ui;
// Vec2ui stands for "two-dimensional vector of unsigned integers"
......@@ -125,7 +125,7 @@ void SomeClass::someFunction {
...
// Create mesh
typedef OpenVolumeMesh::Vec3d Vec3d;
typedef OpenVolumeMesh::Geometry::Vec3d Vec3d;
OpenVolumeMesh::PolyhedralMesh< Vec3d > myMesh;
// Fill mesh
......
......@@ -2,4 +2,124 @@
\page file_format File Format
%OpenVolumeMesh comes with a file format specification
that is implemented in the OpenVolumeMesh::IO::FileManager class.
As for now, the file format only supports plain text, but a support
for binary files is planned. Also the data type for vertices is restricted
to OpenVolumeMesh::Geometry::Vec3d and the serialization of the
properties is restricted to integral types for the moment.
A full generic support is also planned for the future. Find the
file format specification below.
\section file_spec File Format Specification
\verbatim
OVM ASCII # File header indicating whether data is
# coded as plain text or binary
Vertices # Indicate that all vertices are listed below
n_v # The total number of vertices (>= 0)
x_1 y_1 z_1 # Coordinate of the first vertex
...
x_n y_n z_n # Coordinate of the n_v'th vertex
# == Optional: ========================
Property "name" # A vertex property's name
type # The property's data type: Only integral
# types (bool, int, float, double, string)
p_1 # Property value for the first vertex
...
p_n # Property value for the last vertex
# Other properties may follow using
# the same scheme
# =====================================
Edges # Indicate that edges are specified below
n_e # The total number of edges (>= 0)
vs_1 vt_1 # First edge's source vertex index followed
... # by the first edge's target vertex index
vs_n vt_n # Last edge's source and target vertices
# == Optional: ========================
Property "name" # The same as for vertices
... # =====================================
Faces # Indicate that faces are specified below
n_f # The total number of faces (>= 0)
d he1_1 ... hed_1 # The first face's valence followed by its
... # incident half-edges' indices
d he1_n ... hed_n # Last face's definition
# == Optional: ========================
Property "name" # The same as for vertices
... # =====================================
Polyhedra # Indicates that polyhedra are specified below
n_c # The total number of cells (>= 0)
d hf1_1 ... hfd_1 # The first polyhedron's valence followed
... # by its incident half-faces' indices
d hf1_n ... hfd_n # The last polyhedron's definition
# == Optional: ========================
Property "name" # The same as for vertices
... # =====================================
\endverbatim
\section file_example A Simple Example File
\verbatim
OVM ASCII
Vertices
8
-1.0 -1.0 -1.0
1.0 -1.0 -1.0
1.0 1.0 -1.0
-1.0 1.0 -1.0
-1.0 -1.0 1.0
1.0 -1.0 1.0
1.0 1.0 1.0
-1.0 1.0 1.0
Property "Vertex Weights"
float
1.363
6.334
2.766
8.348
4.214
2.136
7.114
0.651
Edges
12
0 1
1 2
2 3
3 0
4 5
5 6
6 7
7 4
0 4
1 5
2 6
3 7
Property "Edge Tag"
bool
1
1
0
1
1
0
0
1
0
0
1
1
Faces
6
4 0 2 4 6
4 8 10 12 14
4 18 10 21 3
4 16 15 23 6
4 20 12 22 4
4 0 18 9 17
Polyhedra
1
6 1 2 5 6 9 10
\endverbatim
**/
......@@ -44,6 +44,7 @@
#define FILEMANAGER_HH_
#include <string>
#include <fstream>
namespace OpenVolumeMesh {
......@@ -106,6 +107,22 @@ public:
* \brief Test whether given file contains a hexahedral mesh
*/
bool isHexahedralMesh(const std::string& _filename) const;
private:
// Remove leading and trailing whitespaces
void trimString(std::string& _string) const;
// Get quoted text out of a string
void extractQuotedText(std::string& _string) const;
// Get a whole line from file
bool getCleanLine(std::istream& ifs, std::string& _string, bool _skipEmptyLines = true) const;
// Add and initialize property
template<class MeshT, class PropHandleT, typename PropT, typename IterT>
void initializeProperty(std::ifstream& _iff, MeshT& _mesh, const std::string& _s_tmp,
const IterT& _begin, const IterT& _end) const;
};
} // Namespace IO
......
......@@ -42,14 +42,18 @@
#define FILEMANAGERT_CC
#include <vector>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <cctype>
#include <typeinfo>
#include <OpenVolumeMesh/Geometry/VectorT.hh>
#include <OpenVolumeMesh/PolyhedralMesh/PolyhedralMesh.hh>
#include "FileManager.hh"
#include <fstream>
#include <vector>
#include <iostream>
namespace OpenVolumeMesh {
namespace IO {
......@@ -68,134 +72,564 @@ FileManager::~FileManager() {
//==================================================
void FileManager::trimString(std::string& _string) const {
// Trim Both leading and trailing spaces
size_t start = _string.find_first_not_of(" \t\r\n");
size_t end = _string.find_last_not_of(" \t\r\n");
if((std::string::npos == start) || (std::string::npos == end)) {
_string = "";
} else {
_string = _string.substr(start, end - start + 1);
}
}
//==================================================
void FileManager::extractQuotedText(std::string& _string) const {
// Trim Both leading and trailing quote marks
size_t start = _string.find_first_of("\""); ++start;
size_t end = _string.find_last_not_of("\"");
if((std::string::npos == start) || (std::string::npos == end)) {
_string = "";
} else {
_string = _string.substr(start, end - start + 1);
}
}
//==================================================
bool FileManager::getCleanLine(std::istream& _ifs, std::string& _string, bool _skipEmptyLines) const {
// While we are not at the end of the file
while(true) {
// Get the current line:
std::getline(_ifs, _string);
// Remove whitespace at beginning and end
trimString(_string);
// Check if string is not empty ( otherwise we continue
if(_string.size() != 0) {
// Check if string is a comment ( starting with # )
if(_string[0] != '#') {
return true;
}
} else {
if(!_skipEmptyLines)
return true;
}
if(_ifs.eof()) {
std::cerr << "End of file reached while searching for input!" << std::endl;
return false;
}
}
return false;
}
//==================================================
template <class MeshT>
bool FileManager::readFile(const std::string& _filename, MeshT& _mesh,
bool _topologyCheck, bool _computeBottomUpAdjacencies, bool _computeFaceNormals) const {
// found edges in file
bool edges_in_file = false;
std::ifstream iff(_filename.c_str(), std::ios::in);
typedef typename MeshT::Vertex Vertex;
_mesh.clear();
if(!iff.good()) {
std::cerr << "Error: Could not open file " << _filename << " for reading!" << std::endl;
iff.close();
return false;
}
std::ifstream iff(_filename.c_str(), std::ios::in);
std::stringstream sstr;
std::string line;
std::string s_tmp;
unsigned int c = 0u;
typedef OpenVolumeMesh::Geometry::Vec3d Vec3d;
Vec3d v = Vec3d(0.0, 0.0, 0.0);
unsigned int v1 = 0; unsigned int v2 = 0;
/*
* Header
*/
// Get first line
getCleanLine(iff, 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();
std::cerr << "The specified file is not in OpenVolumeMesh format!" << std::endl;
return false;
}
if(!iff.good()) {
std::cerr << "Error: Could not open file " << _filename << " for reading!" << std::endl;
iff.close();
return false;
}
// Get ASCII/BINARY string
sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp == "BINARY") {
iff.close();
std::cerr << "Binary files are not supported at the moment!" << std::endl;
return false;
}
std::string s;
/*
* Vertices
*/
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp != "VERTICES") {
iff.close();
std::cerr << "No vertex section defined!" << std::endl;
return false;
} else {
// Read in number of vertices
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
sstr >> c;
// Read in vertices
for(unsigned int i = 0u; i < c; ++i) {
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
sstr >> v[0];
sstr >> v[1];
sstr >> v[2];
_mesh.add_vertex(v);
}
}
// read header
iff >> s;
if (s != "Vertices") {
std::cerr << "Error reading OpenVolumeMesh file: Vertex section failed!" << std::endl;
iff.close();
return false;
}
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
// Check for properties
sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp == "PROPERTY") {
s_tmp = sstr.str();
extractQuotedText(s_tmp);
std::string type;
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
sstr >> type;
// Add and initialize property
if(type == "int") {
initializeProperty<MeshT, OpenVolumeMesh::VPropHandleT<int>, int, typename MeshT::VertexIter>
(iff, _mesh, s_tmp, _mesh.vertices_begin(), _mesh.vertices_end());
} else if(type == "unsigned int") {
initializeProperty<MeshT, OpenVolumeMesh::VPropHandleT<unsigned int>, unsigned int, typename MeshT::VertexIter>
(iff, _mesh, s_tmp, _mesh.vertices_begin(), _mesh.vertices_end());
} else if(type == "float") {
initializeProperty<MeshT, OpenVolumeMesh::VPropHandleT<float>, float, typename MeshT::VertexIter>
(iff, _mesh, s_tmp, _mesh.vertices_begin(), _mesh.vertices_end());
} else if(type == "double") {
initializeProperty<MeshT, OpenVolumeMesh::VPropHandleT<double>, double, typename MeshT::VertexIter>
(iff, _mesh, s_tmp, _mesh.vertices_begin(), _mesh.vertices_end());
} else if(type == "char") {
initializeProperty<MeshT, OpenVolumeMesh::VPropHandleT<char>, char, typename MeshT::VertexIter>
(iff, _mesh, s_tmp, _mesh.vertices_begin(), _mesh.vertices_end());
} else if(type == "unsigned char") {
initializeProperty<MeshT, OpenVolumeMesh::VPropHandleT<unsigned char>, unsigned char, typename MeshT::VertexIter>
(iff, _mesh, s_tmp, _mesh.vertices_begin(), _mesh.vertices_end());
} else if(type == "bool") {
initializeProperty<MeshT, OpenVolumeMesh::VPropHandleT<bool>, bool, typename MeshT::VertexIter>
(iff, _mesh, s_tmp, _mesh.vertices_begin(), _mesh.vertices_end());
} else if(type == "string") {
initializeProperty<MeshT, OpenVolumeMesh::VPropHandleT<std::string>, std::string, typename MeshT::VertexIter>
(iff, _mesh, s_tmp, _mesh.vertices_begin(), _mesh.vertices_end());
} else {
std::cerr << "Data type '" << type << "' not recognized!" << std::endl;
// Skip number of vertices lines
for(typename MeshT::VertexIter it = _mesh.vertices_begin(); it != _mesh.vertices_end(); ++it) {
getCleanLine(iff, line);
}
}
// Get next line (edge header)
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
} else {
// Reset stream to whole line
sstr.str(line);
}
// read vertices
int nv = 0;
iff >> nv;
for (int i = 0; i < nv; ++i) {
double x, y, z;
iff >> x;
iff >> y;
iff >> z;
Vec3d v(x, y, z);
_mesh.add_vertex(v);
}
/*
* Edges
*/
sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp != "EDGES") {
iff.close();
std::cerr << "No edge section defined!" << std::endl;
return false;
} else {
// Read in number of edges
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
sstr >> c;
// Read in edges
for(unsigned int i = 0u; i < c; ++i) {
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
sstr >> v1;
sstr >> v2;
_mesh.add_edge(typename MeshT::VertexHandle(v1), typename MeshT::VertexHandle(v2));
}
}
iff >> s;
if (s != "Edges") {
std::cerr << "No edges found!" << std::endl;
} else {
edges_in_file = true;
int ne = 0;
iff >> ne;
for (int e = 0; e < ne; ++e) {
int v1 = 0;
int v2 = 0;
iff >> v1;
iff >> v2;
_mesh.add_edge(typename MeshT::VertexHandle(v1), typename MeshT::VertexHandle(v2));
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
// Check for properties
sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp == "PROPERTY") {
s_tmp = sstr.str();
extractQuotedText(s_tmp);
std::string type;
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
sstr >> type;
// Add and initialize property
if(type == "int") {
initializeProperty<MeshT, OpenVolumeMesh::EPropHandleT<int>, int, typename MeshT::EdgeIter>
(iff, _mesh, s_tmp, _mesh.edges_begin(), _mesh.edges_end());
} else if(type == "unsigned int") {
initializeProperty<MeshT, OpenVolumeMesh::EPropHandleT<unsigned int>, unsigned int, typename MeshT::EdgeIter>
(iff, _mesh, s_tmp, _mesh.edges_begin(), _mesh.edges_end());
} else if(type == "float") {
initializeProperty<MeshT, OpenVolumeMesh::EPropHandleT<float>, float, typename MeshT::EdgeIter>
(iff, _mesh, s_tmp, _mesh.edges_begin(), _mesh.edges_end());
} else if(type == "double") {
initializeProperty<MeshT, OpenVolumeMesh::EPropHandleT<double>, double, typename MeshT::EdgeIter>
(iff, _mesh, s_tmp, _mesh.edges_begin(), _mesh.edges_end());
} else if(type == "char") {
initializeProperty<MeshT, OpenVolumeMesh::EPropHandleT<char>, char, typename MeshT::EdgeIter>
(iff, _mesh, s_tmp, _mesh.edges_begin(), _mesh.edges_end());
} else if(type == "unsigned char") {
initializeProperty<MeshT, OpenVolumeMesh::EPropHandleT<unsigned char>, unsigned char, typename MeshT::EdgeIter>
(iff, _mesh, s_tmp, _mesh.edges_begin(), _mesh.edges_end());
} else if(type == "bool") {
initializeProperty<MeshT, OpenVolumeMesh::EPropHandleT<bool>, bool, typename MeshT::EdgeIter>
(iff, _mesh, s_tmp, _mesh.edges_begin(), _mesh.edges_end());
} else if(type == "string") {
initializeProperty<MeshT, OpenVolumeMesh::EPropHandleT<std::string>, std::string, typename MeshT::EdgeIter>
(iff, _mesh, s_tmp, _mesh.edges_begin(), _mesh.edges_end());
} else {
std::cerr << "Data type '" << type << "' not recognized!" << std::endl;
// Skip number of edges lines
for(typename MeshT::EdgeIter it = _mesh.edges_begin(); it != _mesh.edges_end(); ++it) {
getCleanLine(iff, line);
}
}
// Get next line (face header)
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
} else {
// Reset stream to whole line
sstr.str(line);
}
}
if (edges_in_file) {
iff >> s;
}
/*
* Faces
*/
sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp != "FACES") {
iff.close();
std::cerr << "No face section defined!" << std::endl;
return false;
} else {
// Read in number of faces
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
sstr >> c;
// Read in faces
for(unsigned int i = 0u; i < c; ++i) {
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
std::vector<typename MeshT::HalfEdgeHandle> hes;
// Get face valence
unsigned int val = 0u;
sstr >> val;
// Read half-edge indices
for(unsigned int e = 0; e < val; ++e) {
sstr >> v1;
hes.push_back(typename MeshT::HalfEdgeHandle(v1));
}
_mesh.add_face(hes, _topologyCheck);
}
}
if (s != "Faces") {
std::cerr << "Error reading OpenVolumeMesh file: Face section failed!" << std::endl;
iff.close();
return false;
}
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
// Check for properties
sstr >> s_tmp;
std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
if(s_tmp == "PROPERTY") {
s_tmp = sstr.str();
extractQuotedText(s_tmp);
std::string type;
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
sstr >> type;
// Add and initialize property
if(type == "int") {
initializeProperty<MeshT, OpenVolumeMesh::FPropHandleT<int>, int, typename MeshT::FaceIter>
(iff, _mesh, s_tmp, _mesh.faces_begin(), _mesh.faces_end());
} else if(type == "unsigned int") {
initializeProperty<MeshT, OpenVolumeMesh::FPropHandleT<unsigned int>, unsigned int, typename MeshT::FaceIter>
(iff, _mesh, s_tmp, _mesh.faces_begin(), _mesh.faces_end());
} else if(type == "float") {
initializeProperty<MeshT, OpenVolumeMesh::FPropHandleT<float>, float, typename MeshT::FaceIter>
(iff, _mesh, s_tmp, _mesh.faces_begin(), _mesh.faces_end());
} else if(type == "double") {
initializeProperty<MeshT, OpenVolumeMesh::FPropHandleT<double>, double, typename MeshT::FaceIter>
(iff, _mesh, s_tmp, _mesh.faces_begin(), _mesh.faces_end());
} else if(type == "char") {
initializeProperty<MeshT, OpenVolumeMesh::FPropHandleT<char>, char, typename MeshT::FaceIter>
(iff, _mesh, s_tmp, _mesh.faces_begin(), _mesh.faces_end());
} else if(type == "unsigned char") {
initializeProperty<MeshT, OpenVolumeMesh::FPropHandleT<unsigned char>, unsigned char, typename MeshT::FaceIter>
(iff, _mesh, s_tmp, _mesh.faces_begin(), _mesh.faces_end());
} else if(type == "bool") {
initializeProperty<MeshT, OpenVolumeMesh::FPropHandleT<bool>, bool, typename MeshT::FaceIter>
(iff, _mesh, s_tmp, _mesh.faces_begin(), _mesh.faces_end());
} else if(type == "string") {
initializeProperty<MeshT, OpenVolumeMesh::FPropHandleT<std::string>, std::string, typename MeshT::FaceIter>
(iff, _mesh, s_tmp, _mesh.faces_begin(), _mesh.faces_end());
} else {
std::cerr << "Data type '" << type << "' not recognized!" << std::endl;
// Skip number of faces lines
for(typename MeshT::FaceIter it = _mesh.faces_begin(); it != _mesh.faces_end(); ++it) {
getCleanLine(iff, line);
}
}
// Get next line (cell header)
getCleanLine(iff, line);
sstr.clear();
sstr.str(line);
} else {
// Reset stream to whole line
sstr.str(line);
}
// Read halfface indices
int nf = 0;
iff >> nf;