36#define FILEMANAGERT_CC
48#include <OpenVolumeMesh/Geometry/VectorT.hh>
49#include <OpenVolumeMesh/Mesh/PolyhedralMesh.hh>
51#include <OpenVolumeMesh/FileManager/FileManager.hh>
53namespace OpenVolumeMesh {
57using namespace OpenVolumeMesh::Geometry;
63 bool _topologyCheck,
bool _computeBottomUpIncidences)
const
65 std::stringstream sstr;
68 typedef typename MeshT::PointT Point;
69 Point v = Point(0.0, 0.0, 0.0);
71 _istream.imbue(std::locale::classic());
77 _mesh.enable_bottom_up_incidences(
false);
83 bool header_found =
true;
86 getCleanLine(_istream, line);
91 std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
95 if (verbosity_level_ >= 1) {
96 std::cerr <<
"The specified file might not be in OpenVolumeMesh format!" << std::endl;
103 std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
104 if(s_tmp ==
"BINARY") {
105 if (verbosity_level_ >= 1) {
106 std::cerr <<
"Binary files are not supported at the moment!" << std::endl;
118 getCleanLine(_istream, line);
123 size_t n_vertices = 0;
125 std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
126 if(s_tmp !=
"VERTICES") {
127 if (verbosity_level_ >= 1) {
128 std::cerr <<
"No vertex section defined!" << std::endl;
134 getCleanLine(_istream, line);
139 _mesh.reserve_vertices(
static_cast<size_t>(n_vertices));
142 for(uint64_t i = 0u; i < n_vertices; ++i) {
144 getCleanLine(_istream, line);
158 getCleanLine(_istream, line);
162 std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
163 if(s_tmp !=
"EDGES") {
164 if (verbosity_level_ >= 2) {
165 std::cerr <<
"No edge section defined!" << std::endl;
171 getCleanLine(_istream, line);
176 _mesh.reserve_edges(
static_cast<size_t>(n_edges));
179 for(uint64_t i = 0u; i < n_edges; ++i) {
183 getCleanLine(_istream, line);
188 if (v1 >= n_vertices || v2 >= n_vertices) {
189 std::cerr <<
"OVM file loading error: invalid vertex for edge #" << i
190 <<
" = (" << v1 <<
", " << v2 <<
") - there are only" << n_vertices <<
" vertices." << std::endl;
198 size_t n_halfedges = 2 * n_edges;
203 getCleanLine(_istream, line);
207 std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
208 if(s_tmp !=
"FACES") {
209 if (verbosity_level_ >= 2) {
210 std::cerr <<
"No face section defined!" << std::endl;
216 getCleanLine(_istream, line);
221 _mesh.reserve_faces(
static_cast<size_t>(n_faces));
223 std::vector<HalfEdgeHandle> hes;
226 for(uint64_t i = 0u; i < n_faces; ++i) {
228 getCleanLine(_istream, line);
238 hes.reserve(
static_cast<size_t>(val));
240 for(
unsigned int e = 0; e < val; ++e) {
244 if (v1 >= n_halfedges) {
245 std::cerr <<
"OVM File loading error: invalid halfedge #" << v1 <<
" in face #" << i
246 <<
" - there are only" << n_halfedges <<
" halfedges." << std::endl;
251 hes.emplace_back(v1);
254 _mesh.
add_face(hes, _topologyCheck);
257 size_t n_halffaces = 2 * n_faces;
263 getCleanLine(_istream, line);
267 std::transform(s_tmp.begin(), s_tmp.end(), s_tmp.begin(), ::toupper);
268 if(s_tmp !=
"POLYHEDRA") {
269 if (verbosity_level_ >= 2) {
270 std::cerr <<
"No polyhedra section defined!" << std::endl;
276 getCleanLine(_istream, line);
281 _mesh.reserve_cells(
static_cast<size_t>(n_cells));
283 std::vector<HalfFaceHandle> hfs;
285 for(uint64_t i = 0u; i < n_cells; ++i) {
287 getCleanLine(_istream, line);
297 hfs.reserve(
static_cast<size_t>(val));
300 for(
unsigned int f = 0; f < val; ++f) {
304 if (v1 >= n_halffaces) {
305 std::cerr <<
"OVM File loading error: invalid halfface #" << v1 <<
" in cell #" << i
306 <<
" - there are only" << n_halffaces <<
" halffaces." << std::endl;
311 hfs.emplace_back(v1);
314 _mesh.
add_cell(hfs, _topologyCheck);
318 while(!_istream.eof()) {
323 readProperty(_istream, _mesh);
326 if(_computeBottomUpIncidences) {
328 _mesh.enable_bottom_up_incidences(
true);
331 if (verbosity_level_ >= 2) {
332 std::cerr <<
"######## openvolumemesh info #########" << std::endl;
333 std::cerr <<
"#vertices: " << _mesh.
n_vertices() << std::endl;
334 std::cerr <<
"#edges: " << _mesh.
n_edges() << std::endl;
335 std::cerr <<
"#faces: " << _mesh.
n_faces() << std::endl;
336 std::cerr <<
"#cells: " << _mesh.
n_cells() << std::endl;
337 std::cerr <<
"######################################" << std::endl;
343template <
class MeshT>
345 bool _topologyCheck,
bool _computeBottomUpIncidences)
const {
347 std::ifstream iff(_filename.c_str(), std::ios::in);
349 auto read_buf = std::make_unique<std::array<char, 0x10000>>();
350 iff.rdbuf()->pubsetbuf(read_buf->data(), read_buf->size());
353 if (verbosity_level_ >= 1) {
354 std::cerr <<
"Error: Could not open file " << _filename <<
" for reading!" << std::endl;
359 return readStream(iff, _mesh, _topologyCheck,_computeBottomUpIncidences);
364template <
class MeshT>
365void FileManager::readProperty(std::istream& _iff,
MeshT& _mesh)
const {
367 std::string line, entity_t, prop_t, name;
368 std::stringstream sstr;
370 getCleanLine(_iff, line);
372 if(line.empty())
return;
377 std::transform(entity_t.begin(), entity_t.end(), entity_t.begin(), ::tolower);
379 std::transform(prop_t.begin(), prop_t.end(), prop_t.begin(), ::tolower);
381 extractQuotedText(name);
383 if (verbosity_level_ >= 2) {
384 std::cerr <<
"OVM read property " << name <<
" of type " << prop_t << std::endl;
387 if(prop_t == typeName<int>()) generateGenericProperty<int, MeshT>(entity_t, name, _iff, _mesh);
388 else if(prop_t == typeName<unsigned int>()) generateGenericProperty<unsigned int, MeshT>(entity_t, name, _iff, _mesh);
389 else if(prop_t == typeName<short>()) generateGenericProperty<short, MeshT>(entity_t, name, _iff, _mesh);
390 else if(prop_t == typeName<long>()) generateGenericProperty<long, MeshT>(entity_t, name, _iff, _mesh);
391 else if(prop_t == typeName<unsigned long>()) generateGenericProperty<unsigned long, MeshT>(entity_t, name, _iff, _mesh);
392 else if(prop_t == typeName<char>()) generateGenericProperty<char, MeshT>(entity_t, name, _iff, _mesh);
393 else if(prop_t == typeName<unsigned char>()) generateGenericProperty<unsigned char, MeshT>(entity_t, name, _iff, _mesh);
394 else if(prop_t == typeName<bool>()) generateGenericProperty<bool, MeshT>(entity_t, name, _iff, _mesh);
395 else if(prop_t == typeName<float>()) generateGenericProperty<float, MeshT>(entity_t, name, _iff, _mesh);
396 else if(prop_t == typeName<double>()) generateGenericProperty<double, MeshT>(entity_t, name, _iff, _mesh);
397 else if(prop_t == typeName<std::string>()) generateGenericProperty<std::string, MeshT>(entity_t, name, _iff, _mesh);
398 else if(prop_t == typeName<std::map<HalfEdgeHandle, int> >()) generateGenericProperty<std::map<HalfEdgeHandle, int>,
MeshT>(entity_t, name, _iff, _mesh);
399 else if(prop_t == typeName<std::vector<double> >()) generateGenericProperty<std::vector<double> ,
MeshT>(entity_t, name, _iff, _mesh);
400 else if(prop_t == typeName<std::vector<VertexHandle> >()) generateGenericProperty<std::vector<VertexHandle> ,
MeshT>(entity_t, name, _iff, _mesh);
401 else if(prop_t == typeName<std::vector<HalfFaceHandle> >()) generateGenericProperty<std::vector<HalfFaceHandle> ,
MeshT>(entity_t, name, _iff, _mesh);
402 else if(prop_t == typeName<std::vector<std::vector<HalfFaceHandle> > >()) generateGenericProperty<std::vector<std::vector<HalfFaceHandle> > ,
MeshT>(entity_t, name, _iff, _mesh);
404 else if(prop_t == typeName<Vec2f>()) generateGenericProperty<Vec2f, MeshT>(entity_t, name, _iff, _mesh);
405 else if(prop_t == typeName<Vec2d>()) generateGenericProperty<Vec2d, MeshT>(entity_t, name, _iff, _mesh);
406 else if(prop_t == typeName<Vec2i>()) generateGenericProperty<Vec2i, MeshT>(entity_t, name, _iff, _mesh);
407 else if(prop_t == typeName<Vec2ui>()) generateGenericProperty<Vec2ui, MeshT>(entity_t, name, _iff, _mesh);
409 else if(prop_t == typeName<Vec3f>()) generateGenericProperty<Vec3f, MeshT>(entity_t, name, _iff, _mesh);
410 else if(prop_t == typeName<Vec3d>()) generateGenericProperty<Vec3d, MeshT>(entity_t, name, _iff, _mesh);
411 else if(prop_t == typeName<Vec3i>()) generateGenericProperty<Vec3i, MeshT>(entity_t, name, _iff, _mesh);
412 else if(prop_t == typeName<Vec3ui>()) generateGenericProperty<Vec3ui, MeshT>(entity_t, name, _iff, _mesh);
414 else if(prop_t == typeName<Vec4f>()) generateGenericProperty<Vec4f, MeshT>(entity_t, name, _iff, _mesh);
415 else if(prop_t == typeName<Vec4d>()) generateGenericProperty<Vec4d, MeshT>(entity_t, name, _iff, _mesh);
416 else if(prop_t == typeName<Vec4i>()) generateGenericProperty<Vec4i, MeshT>(entity_t, name, _iff, _mesh);
417 else if(prop_t == typeName<Vec4ui>()) generateGenericProperty<Vec4ui, MeshT>(entity_t, name, _iff, _mesh);
425template <
class PropT,
class MeshT>
426void FileManager::generateGenericProperty(
const std::string& _entity_t,
const std::string& _name,
427 std::istream& _iff,
MeshT& _mesh)
const {
429 if(_entity_t ==
"vprop") {
431 prop.deserialize(_iff);
432 _mesh.set_persistent(prop);
433 }
else if(_entity_t ==
"eprop") {
435 prop.deserialize(_iff);
436 _mesh.set_persistent(prop);
437 }
else if(_entity_t ==
"heprop") {
439 prop.deserialize(_iff);
440 _mesh.set_persistent(prop);
441 }
else if(_entity_t ==
"fprop") {
443 prop.deserialize(_iff);
444 _mesh.set_persistent(prop);
445 }
else if(_entity_t ==
"hfprop") {
447 prop.deserialize(_iff);
448 _mesh.set_persistent(prop);
449 }
else if(_entity_t ==
"cprop") {
451 prop.deserialize(_iff);
452 _mesh.set_persistent(prop);
453 }
else if(_entity_t ==
"mprop") {
455 prop.deserialize(_iff);
456 _mesh.set_persistent(prop);
466 _ostream.imbue(std::locale::classic());
468 _ostream <<
"OVM ASCII" << std::endl;
471 _ostream <<
"Vertices" << std::endl;
472 _ostream << n_vertices << std::endl;
474 typedef typename MeshT::PointT Point;
477 for(
VertexIter v_it = _mesh.v_iter(); v_it; ++v_it) {
479 Point v = _mesh.
vertex(*v_it);
480 _ostream << v[0] <<
" " << v[1] <<
" " << v[2] << std::endl;
483 uint64_t n_edges(_mesh.
n_edges());
484 _ostream <<
"Edges" << std::endl;
485 _ostream << n_edges << std::endl;
488 for(
EdgeIter e_it = _mesh.e_iter(); e_it; ++e_it) {
492 _ostream << from_vertex <<
" " << to_vertex << std::endl;
495 uint64_t n_faces(_mesh.
n_faces());
496 _ostream <<
"Faces" << std::endl;
497 _ostream << n_faces << std::endl;
500 for(
FaceIter f_it = _mesh.f_iter(); f_it; ++f_it) {
502 _ostream << static_cast<uint64_t>(_mesh.
face(*f_it).halfedges().size()) <<
" ";
504 std::vector<HalfEdgeHandle> halfedges = _mesh.
face(*f_it).halfedges();
506 for(
typename std::vector<HalfEdgeHandle>::const_iterator it = halfedges.begin(); it
507 != halfedges.end(); ++it) {
509 _ostream << it->idx();
511 if((it + 1) != halfedges.end())
515 _ostream << std::endl;
518 uint64_t n_cells(_mesh.
n_cells());
519 _ostream <<
"Polyhedra" << std::endl;
520 _ostream << n_cells << std::endl;
522 for(
CellIter c_it = _mesh.c_iter(); c_it; ++c_it) {
524 _ostream << static_cast<uint64_t>(_mesh.
cell(*c_it).halffaces().size()) <<
" ";
526 std::vector<HalfFaceHandle> halffaces = _mesh.
cell(*c_it).halffaces();
528 for(
typename std::vector<HalfFaceHandle>::const_iterator it = halffaces.begin(); it
529 != halffaces.end(); ++it) {
531 _ostream << it->idx();
533 if((it + 1) != halffaces.end())
537 _ostream << std::endl;
540 writeProps<Entity::Vertex> (_ostream, _mesh);
541 writeProps<Entity::Edge> (_ostream, _mesh);
542 writeProps<Entity::HalfEdge>(_ostream, _mesh);
543 writeProps<Entity::Face> (_ostream, _mesh);
544 writeProps<Entity::HalfFace>(_ostream, _mesh);
545 writeProps<Entity::Cell> (_ostream, _mesh);
546 writeProps<Entity::Mesh> (_ostream, _mesh);
552 std::ofstream off(_filename.c_str(), std::ios::out);
555 if (verbosity_level_ >= 1) {
556 std::cerr <<
"Error: Could not open file " << _filename <<
" for writing!" << std::endl;
565template<
typename EntityTag,
class MeshT>
566void FileManager::writeProps(std::ostream &_ostream,
const MeshT& _mesh)
const {
568 _mesh.template persistent_props_begin<EntityTag>(),
569 _mesh.template persistent_props_end<EntityTag>(),
570 entityTypeName<EntityTag>()
575template<
class IteratorT>
576void FileManager::writeProps(
578 const IteratorT& _begin,
const IteratorT& _end,
579 std::string
const &_entityType
583 for(IteratorT p_it = _begin; p_it != _end; ++p_it) {
585 if(!prop->persistent())
continue;
586 if(prop->anonymous()) {
587 if (verbosity_level_ >= 2) {
588 std::cerr <<
"Serialization of anonymous properties is not supported!" << std::endl;
593 std::string type_name;
595 type_name = prop->typeNameWrapper();
596 }
catch (std::runtime_error &e) {
597 if (verbosity_level_ >= 1) {
598 std::cerr <<
"Failed to save property " << prop->name() <<
" , skipping: " << e.what() << std::endl;
602 _ostr << _entityType <<
" ";
603 _ostr << type_name <<
" ";
604 _ostr <<
"\"" << prop->name() <<
"\"" << std::endl;
606 prop->serialize(_ostr);
VertexHandle add_vertex(const VecT &_p)
Add a geometric point to the mesh.
const VecT & vertex(VertexHandle _vh) const
Get point _vh's coordinates.
void writeStream(std::ostream &_ostream, const MeshT &_mesh) const
Write a mesh to an std::ostream.
bool readFile(const std::string &_filename, MeshT &_mesh, bool _topologyCheck=true, bool _computeBottomUpIncidences=true) const
Read a mesh from a file.
bool writeFile(const std::string &_filename, const MeshT &_mesh) const
Write a mesh to a file.
bool readStream(std::istream &_istream, MeshT &_mesh, bool _topologyCheck=true, bool _computeBottomUpIncidences=true) const
Read a mesh from an std::istream.
const Cell & cell(CellHandle _cellHandle) const
Get cell with handle _cellHandle.
size_t n_vertices() const override
Get number of vertices in mesh.
virtual FaceHandle add_face(std::vector< HalfEdgeHandle > _halfedges, bool _topologyCheck=false)
Add face via incident edges.
size_t n_faces() const override
Get number of faces in mesh.
virtual CellHandle add_cell(std::vector< HalfFaceHandle > _halffaces, bool _topologyCheck=false)
Add cell via incident halffaces.
size_t n_cells() const override
Get number of cells in mesh.
virtual void clear(bool _clearProps=true)
Clear whole mesh.
size_t n_edges() const override
Get number of edges in mesh.
const Edge & edge(EdgeHandle _edgeHandle) const
Get edge with handle _edgeHandle.
virtual EdgeHandle add_edge(VertexHandle _fromVertex, VertexHandle _toHandle, bool _allowDuplicates=false)
Add edge.
const Face & face(FaceHandle _faceHandle) const
Get face with handle _faceHandle.