Commit efa67fbc authored by Mike Kremer's avatar Mike Kremer

Commit of the debugged version of Alex' improvement to OpenMesh. File i/o is...

Commit of the debugged version of Alex' improvement to OpenMesh. File i/o is now done via istream/ostream instances such that direct buffer writing to files (serialization) will also be possible in future releases.
Code is tested.

git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@221 fdac6126-5c0c-442c-9429-916003d36597
parent 86b53bf9
......@@ -102,6 +102,31 @@ read(const std::string& _filename, BaseImporter& _bi, Options& _opt)
//-----------------------------------------------------------------------------
bool
_IOManager_::
read(std::istream& _is, const std::string& _ext, BaseImporter& _bi, Options& _opt)
{
std::set<BaseReader*>::const_iterator it = reader_modules_.begin();
std::set<BaseReader*>::const_iterator it_end = reader_modules_.end();
// Try all registered modules
for(; it != it_end; ++it)
if ((*it)->BaseReader::can_u_read(_ext)) //Use the extension check only (no file existence)
{
_bi.prepare();
bool ok = (*it)->read(_is, _bi, _opt);
_bi.finish();
return ok;
}
// All modules failed to read
return false;
}
//-----------------------------------------------------------------------------
bool
_IOManager_::
write(const std::string& _filename, BaseExporter& _be, Options _opt)
......@@ -128,6 +153,34 @@ write(const std::string& _filename, BaseExporter& _be, Options _opt)
return false;
}
//-----------------------------------------------------------------------------
bool
_IOManager_::
write(std::ostream& _os,const std::string &_ext, BaseExporter& _be, Options _opt)
{
std::set<BaseWriter*>::const_iterator it = writer_modules_.begin();
std::set<BaseWriter*>::const_iterator it_end = writer_modules_.end();
if ( it == it_end )
{
omerr() << "[OpenMesh::IO::_IOManager_] No writing modules available!\n";
return false;
}
// Try all registered modules
for(; it != it_end; ++it)
{
if ((*it)->BaseWriter::can_u_write(_ext)) //Restrict test to the extension check
{
return (*it)->write(_os, _be, _opt);
}
}
// All modules failed to save
return false;
}
//-----------------------------------------------------------------------------
......
......@@ -118,6 +118,16 @@ public:
BaseImporter& _bi,
Options& _opt);
/**
Read a mesh from open std::istream _is. The target data structure is specified
by the given BaseImporter. The \c sread method consecutively queries all
of its reader modules. True is returned upon success, false if all
reader modules failed to use _is.
*/
bool read(std::istream& _filename,
const std::string& _ext,
BaseImporter& _bi,
Options& _opt);
/** Write a mesh to file _filename. The source data structure is specified
......@@ -129,7 +139,17 @@ public:
bool write(const std::string& _filename,
BaseExporter& _be,
Options _opt=Options::Default);
/** Write a mesh to open std::ostream _os. The source data structure is specified
by the given BaseExporter. The \c save method consecutively queries all
of its writer modules. True is returned upon success, false if all
writer modules failed to write the requested format.
Options is determined by _filename's extension.
*/
bool write(std::ostream& _filename,
const std::string& _ext,
BaseExporter& _be,
Options _opt=Options::Default);
/// Returns true if the format is supported by one of the reader modules.
......
......@@ -107,6 +107,23 @@ read_mesh(Mesh& _mesh,
}
/** Read a mesh from file open std::istream. The file format is determined by
parameter _ext. _ext has to include ".[format]" in order to work properly */
template <class Mesh>
bool
read_mesh(Mesh& _mesh,
std::istream& _is,
const std::string& _ext,
Options& _opt,
bool _clear = true)
{
if (_clear) _mesh.clear();
ImporterT<Mesh> importer(_mesh);
return IOManager().read(_is,_ext, importer, _opt);
}
//-----------------------------------------------------------------------------
......@@ -124,6 +141,22 @@ bool write_mesh(const Mesh& _mesh, const std::string& _filename,
//-----------------------------------------------------------------------------
/** Write a mesh to an open std::ostream. The file format is determined
by _ext. */
template <class Mesh>
bool write_mesh(const Mesh& _mesh,
std::ostream& _os,
const std::string& _ext,
Options _opt = Options::Default)
{
ExporterT<Mesh> exporter(_mesh);
return IOManager().write(_os,_ext, exporter, _opt);
}
//-----------------------------------------------------------------------------
template <class Mesh>
size_t binary_size(const Mesh& _mesh, const std::string& _format,
Options _opt = Options::Default)
......
......@@ -110,6 +110,14 @@ public:
virtual bool read(const std::string& _filename,
BaseImporter& _bi,
Options& _opt) = 0;
/** Reads a mesh given by a std::stream. This method usually uses the same stream reading method
that read uses. Options can be passed via _opt. After execution _opt contains the Options
that were available
*/
virtual bool read(std::istream& _is,
BaseImporter& _bi,
Options& _opt) = 0;
/// Returns true if reader can parse _filename (checks extension)
......
......@@ -4,10 +4,10 @@
* Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
* *
* OpenMesh is free software: you can redistribute it and/or modify *
* OpenMesh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
......@@ -30,10 +30,10 @@
* License along with OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
\*===========================================================================*/
/*===========================================================================*\
* *
* *
* $Revision$ *
* $Date$ *
* *
......@@ -112,7 +112,7 @@ read(const std::string& _filename, BaseImporter& _bi, Options& _opt)
{
std::fstream in( _filename.c_str(), std::ios_base::in );
if (!in)
if (!in.is_open() || !in.good())
{
omerr() << "[OBJReader] : cannot not open file "
<< _filename
......@@ -137,7 +137,6 @@ read(const std::string& _filename, BaseImporter& _bi, Options& _opt)
return result;
}
//-----------------------------------------------------------------------------
bool
......@@ -264,7 +263,7 @@ read_material(std::fstream& _in)
bool
_OBJReader_::
read(std::fstream& _in, BaseImporter& _bi, Options& _opt)
read(std::istream& _in, BaseImporter& _bi, Options& _opt)
{
omlog() << "[OBJReader] : read file\n";
......
......@@ -4,10 +4,10 @@
* Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
* *
* OpenMesh is free software: you can redistribute it and/or modify *
* OpenMesh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
......@@ -30,10 +30,10 @@
* License along with OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
\*===========================================================================*/
/*===========================================================================*\
* *
* *
* $Revision$ *
* $Date$ *
* *
......@@ -94,6 +94,10 @@ public:
BaseImporter& _bi,
Options& _opt);
bool read(std::istream& _in,
BaseImporter& _bi,
Options& _opt);
private:
#ifndef DOXY_IGNORE_THIS
......@@ -163,8 +167,6 @@ private:
private:
bool read(std::fstream& _in, BaseImporter& _bi, Options& _opt);
std::string path_;
};
......
......@@ -4,10 +4,10 @@
* Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
* *
* OpenMesh is free software: you can redistribute it and/or modify *
* OpenMesh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
......@@ -30,10 +30,10 @@
* License along with OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
\*===========================================================================*/
/*===========================================================================*\
* *
* *
* $Revision$ *
* $Date$ *
* *
......@@ -57,6 +57,8 @@
#include <OpenMesh/Core/IO/SR_store.hh>
//STL
#include <iostream>
#include <ios>
#include <fstream>
#include <memory>
......@@ -84,48 +86,55 @@ _OFFReader_& OFFReader() { return __OFFReaderInstance; }
_OFFReader_::_OFFReader_()
{
IOManager().register_module(this);
_OFFReader_::_OFFReader_()
{
IOManager().register_module(this);
}
//-----------------------------------------------------------------------------
bool
_OFFReader_::read(const std::string& _filename, BaseImporter& _bi,
bool
_OFFReader_::read(const std::string& _filename, BaseImporter& _bi,
Options& _opt)
{
std::fstream in(_filename.c_str(), (options_.is_binary() ? std::ios_base::binary | std::ios_base::in
: std::ios_base::in) );
std::ifstream ifile(_filename.c_str(), (options_.is_binary() ? std::ios::binary | std::ios::in
: std::ios::in) );
if (!in)
if (!ifile.is_open() || !ifile.good())
{
omerr() << "[OFFReader] : cannot not open file "
omerr() << "[OFFReader] : cannot not open file "
<< _filename
<< std::endl;
return false;
}
assert(ifile);
bool result = read(in, _bi, _opt);
bool result = read(ifile, _bi, _opt);
in.close();
ifile.close();
return result;
}
//-----------------------------------------------------------------------------
bool
_OFFReader_::read(std::fstream& _in, BaseImporter& _bi, Options& _opt ) const
bool
_OFFReader_::read(std::istream& _in, BaseImporter& _bi, Options& _opt )
{
if (!_in.good())
{
omerr() << "[OMReader] : cannot not use stream "
<< std::endl;
return false;
}
// filter relevant options for reading
bool swap = _opt.check( Options::Swap );
userOptions_ = _opt;
......@@ -152,13 +161,13 @@ _OFFReader_::read(std::fstream& _in, BaseImporter& _bi, Options& _opt ) const
//-----------------------------------------------------------------------------
bool
_OFFReader_::read_ascii(std::fstream& _in, BaseImporter& _bi) const
bool
_OFFReader_::read_ascii(std::istream& _in, BaseImporter& _bi) const
{
omlog() << "[OFFReader] : read ascii file\n";
unsigned int i, j, k, l, idx;
unsigned int nV, nF, dummy;
OpenMesh::Vec3f v, n;
......@@ -186,9 +195,9 @@ omlog() << "[OFFReader] : read ascii file\n";
{
// Always read VERTEX
_in >> v[0]; _in >> v[1]; _in >> v[2];
vh = _bi.add_vertex(v);
//perhaps read NORMAL
if ( options_.vertex_has_normal() ){
......@@ -236,7 +245,7 @@ omlog() << "[OFFReader] : read ascii file\n";
_bi.set_color( vh, color_cast<Vec4uc, Vec4f>(c4f) );
break;
default:
default:
std::cerr << "Error in file format (colorType = " << colorType << ")\n";
}
}
......@@ -266,7 +275,7 @@ omlog() << "[OFFReader] : read ascii file\n";
vhandles[1] = VertexHandle(k);
vhandles[2] = VertexHandle(l);
}
else
else
{
vhandles.clear();
for (j=0; j<nV; ++j)
......@@ -275,7 +284,7 @@ omlog() << "[OFFReader] : read ascii file\n";
vhandles.push_back(VertexHandle(idx));
}
}
FaceHandle fh = _bi.add_face(vhandles);
//perhaps read face COLOR
......@@ -287,7 +296,7 @@ omlog() << "[OFFReader] : read ascii file\n";
int colorType = getColorType(line, false );
std::stringstream stream( line );
std::stringstream stream( line );
std::string trash;
......@@ -316,7 +325,7 @@ omlog() << "[OFFReader] : read ascii file\n";
_bi.set_color( fh, color_cast<Vec4uc, Vec4f>(c4f) );
break;
default:
default:
std::cerr << "Error in file format (colorType = " << colorType << ")\n";
}
}
......@@ -369,7 +378,7 @@ int _OFFReader_::getColorType(std::string& _line, bool _texCoordsAvailable) cons
//get first item
found = _line.find(" ");
std::string c1 = _line.substr (0,found);
if (c1.find(".") != std::string::npos){
if (count == 3)
count = 5;
......@@ -380,32 +389,32 @@ int _OFFReader_::getColorType(std::string& _line, bool _texCoordsAvailable) cons
return count;
}
void _OFFReader_::readValue(std::fstream& _in, float& _value) const{
void _OFFReader_::readValue(std::istream& _in, float& _value) const{
float32_t tmp;
restore( _in , tmp, false ); //assuming LSB byte order
_value = tmp;
}
void _OFFReader_::readValue(std::fstream& _in, int& _value) const{
void _OFFReader_::readValue(std::istream& _in, int& _value) const{
uint32_t tmp;
restore( _in , tmp, false ); //assuming LSB byte order
_value = tmp;
}
void _OFFReader_::readValue(std::fstream& _in, unsigned int& _value) const{
void _OFFReader_::readValue(std::istream& _in, unsigned int& _value) const{
uint32_t tmp;
restore( _in , tmp, false ); //assuming LSB byte order
_value = tmp;
}
bool
_OFFReader_::read_binary(std::fstream& _in, BaseImporter& _bi, bool /*_swap*/) const
bool
_OFFReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap*/) const
{
omlog() << "[OFFReader] : read binary file\n";
unsigned int i, j, k, l, idx;
unsigned int nV, nF, dummy;
OpenMesh::Vec3f v, n;
......@@ -426,16 +435,16 @@ _OFFReader_::read_binary(std::fstream& _in, BaseImporter& _bi, bool /*_swap*/) c
_bi.reserve(nV, 3*nV, nF);
// read vertices: coord [hcoord] [normal] [color] [texcoord]
// read vertices: coord [hcoord] [normal] [color] [texcoord]
for (i=0; i<nV && !_in.eof(); ++i)
{
// Always read Vertex
readValue(_in, v[0]);
readValue(_in, v[1]);
readValue(_in, v[2]);
vh = _bi.add_vertex(v);
if ( options_.vertex_has_normal() ) {
readValue(_in, n[0]);
readValue(_in, n[1]);
......@@ -444,7 +453,7 @@ _OFFReader_::read_binary(std::fstream& _in, BaseImporter& _bi, bool /*_swap*/) c
if ( userOptions_.vertex_has_normal() )
_bi.set_normal(vh, n);
}
if ( options_.vertex_has_color() ) {
//with alpha
if ( options_.color_has_alpha() ){
......@@ -465,7 +474,7 @@ _OFFReader_::read_binary(std::fstream& _in, BaseImporter& _bi, bool /*_swap*/) c
_bi.set_color( vh, Vec3uc( c ) );
}
}
if ( options_.vertex_has_texcoord()) {
readValue(_in, t[0]);
readValue(_in, t[1]);
......@@ -474,7 +483,7 @@ _OFFReader_::read_binary(std::fstream& _in, BaseImporter& _bi, bool /*_swap*/) c
_bi.set_texcoord(vh, t);
}
}
// faces
// #N <v1> <v2> .. <v(n-1)> [color spec]
// So far color spec is unsupported!
......@@ -494,7 +503,7 @@ _OFFReader_::read_binary(std::fstream& _in, BaseImporter& _bi, bool /*_swap*/) c
vhandles[1] = VertexHandle(k);
vhandles[2] = VertexHandle(l);
}
else
else
{
vhandles.clear();
for (j=0; j<nV; ++j)
......@@ -503,7 +512,7 @@ _OFFReader_::read_binary(std::fstream& _in, BaseImporter& _bi, bool /*_swap*/) c
vhandles.push_back(VertexHandle(idx));
}
}
FaceHandle fh = _bi.add_face(vhandles);
//face color
......@@ -550,7 +559,7 @@ bool _OFFReader_::can_u_read(const std::string& _filename) const
{
ifs.close();
return true;
}
}
}
return false;
}
......@@ -558,7 +567,7 @@ bool _OFFReader_::can_u_read(const std::string& _filename) const
//-----------------------------------------------------------------------------
bool _OFFReader_::can_u_read(std::istream& _is) const
{
options_.cleanup();
......@@ -589,7 +598,7 @@ bool _OFFReader_::can_u_read(std::istream& _is) const
if ( ( remainingChars > 0 ) && ( p[0] == 'n') )
{ vertexDimensionTooHigh = true; ++p; --remainingChars; }
if ( ( remainingChars < 3 ) || (!(p[0] == 'O' && p[1] == 'F' && p[2] == 'F') ) )
return false;
......
......@@ -4,10 +4,10 @@
* Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
* *
* OpenMesh is free software: you can redistribute it and/or modify *
* OpenMesh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
......@@ -30,10 +30,10 @@
* License along with OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
\*===========================================================================*/
/*===========================================================================*\
* *
* *
* $Revision$ *
* $Date$ *
* *
......@@ -83,8 +83,8 @@ class BaseImporter;
//== IMPLEMENTATION ===========================================================
/**
Implementation of the OFF format reader. This class is singleton'ed by
/**
Implementation of the OFF format reader. This class is singleton'ed by
SingletonT to OFFReader.
By passing Options to the read function you can manipulate the reading behavoir.
......@@ -123,29 +123,28 @@ public:
std::string get_description() const { return "Object File Format"; }
std::string get_extensions() const { return "off"; }
std::string get_magic() const { return "OFF"; }
bool read(const std::string& _filename,
BaseImporter& _bi,
bool read(const std::string& _filename,
BaseImporter& _bi,
Options& _opt);
bool can_u_read(const std::string& _filename) const;
bool read(std::istream& _in, BaseImporter& _bi, Options& _opt );
private:
bool can_u_read(std::istream& _is) const;
bool read(std::fstream& _in, BaseImporter& _bi, Options& _opt ) const;
bool read_ascii(std::fstream& _in, BaseImporter& _bi) const;
bool read_binary(std::fstream& _in, BaseImporter& _bi, bool swap) const;
void readValue(std::fstream& _in, float& _value) const;
void readValue(std::fstream& _in, int& _value) const;
void readValue(std::fstream& _in, unsigned int& _value) const;
bool read_ascii(std::istream& _in, BaseImporter& _bi) const;
bool read_binary(std::istream& _in, BaseImporter& _bi, bool swap) const;
void readValue(std::istream& _in, float& _value) const;
void readValue(std::istream& _in, int& _value) const;
void readValue(std::istream& _in, unsigned int& _value) const;
int getColorType(std::string & _line, bool _texCoordsAvailable) const;
//available options for reading
mutable Options options_;
//options that the user wants to read
......
This diff is collapsed.
......@@ -95,6 +95,11 @@ public:
BaseImporter& _bi,
Options& _opt );
//! Stream Reader for std::istream input in binary format
bool read(std::istream& _is,
BaseImporter& _bi,
Options& _opt );
virtual bool can_u_read(const std::string& _filename) const;
virtual bool can_u_read(std::istream& _is) const;
......@@ -103,7 +108,6 @@ private:
bool supports( const OMFormat::uint8 version ) const;
bool read(std::istream& _is, BaseImporter& _bi, Options& _opt ) const;
bool read_ascii(std::istream& _is, BaseImporter& _bi, Options& _opt) const;
bool read_binary(std::istream& _is, BaseImporter& _bi, Options& _opt) const;
......
......@@ -87,10 +87,11 @@ _PLYReader_::_PLYReader_() {
bool _PLYReader_::read(const std::string& _filename, BaseImporter& _bi, Options& _opt) {
std::fstream in(_filename.c_str(), (options_.is_binary() ? std::ios_base::binary | std::ios_base::in
: std::ios_base::in));
if (!in) {
if (!in.is_open() || !in.good()) {
omerr() << "[PLYReader] : cannot not open file " << _filename << std::endl;
return false;
}
......@@ -104,7 +105,13 @@ bool _PLYReader_::read(const std::string& _filename, BaseImporter& _bi, Options&
//-----------------------------------------------------------------------------
bool _PLYReader_::read(std::fstream& _in, BaseImporter& _bi, Options& _opt) const {
bool _PLYReader_::read(std::istream& _in, BaseImporter& _bi, Options& _opt) {
if (!_in.good()) {
omerr() << "[PLYReader] : cannot not use stream" << std::endl;
return false;
}
// filter relevant options for reading
bool swap = _opt.check(Options::Swap);
......@@ -137,9 +144,11 @@ bool _PLYReader_::read(std::fstream& _in, BaseImporter& _bi, Options& _opt) cons
}
//-----------------------------------------------------------------------------
bool _PLYReader_::read_ascii(std::fstream& _in, BaseImporter& _bi) const {
bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi) const {
omlog() << "[PLYReader] : read ascii file\n";
......@@ -269,7 +278,7 @@ bool _PLYReader_::read_ascii(std::fstream& _in, BaseImporter& _bi) const {
//-----------------------------------------------------------------------------
bool _PLYReader_::read_binary(std::fstream& _in, BaseImporter& _bi, bool /*_swap*/) const {
bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap*/) const {
omlog() << "[PLYReader] : read binary file format\n";
......@@ -394,7 +403,7 @@ bool _PLYReader_::read_binary(std::fstream& _in, BaseImporter& _bi, bool /*_swap
//-----------------------------------------------------------------------------