diff --git a/src/OpenMesh/Core/IO/BinaryHelper.cc b/src/OpenMesh/Core/IO/BinaryHelper.cc index 1168a336..6162b00c 100644 --- a/src/OpenMesh/Core/IO/BinaryHelper.cc +++ b/src/OpenMesh/Core/IO/BinaryHelper.cc @@ -4,10 +4,10 @@ * Copyright (C) 2001-2011 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 . * * * -\*===========================================================================*/ +\*===========================================================================*/ /*===========================================================================*\ - * * + * * * $Revision$ * * $Date$ * * * @@ -69,7 +69,7 @@ namespace IO { //----------------------------------------------------------------------------- -short int read_short(FILE* _in, bool _swap) +short int read_short(FILE* _in, bool _swap) { union u1 { short int s; unsigned char c[2]; } sc; fread((char*)sc.c, 1, 2, _in); @@ -81,7 +81,7 @@ short int read_short(FILE* _in, bool _swap) //----------------------------------------------------------------------------- -int read_int(FILE* _in, bool _swap) +int read_int(FILE* _in, bool _swap) { union u2 { int i; unsigned char c[4]; } ic; fread((char*)ic.c, 1, 4, _in); @@ -96,7 +96,7 @@ int read_int(FILE* _in, bool _swap) //----------------------------------------------------------------------------- -float read_float(FILE* _in, bool _swap) +float read_float(FILE* _in, bool _swap) { union u3 { float f; unsigned char c[4]; } fc; fread((char*)fc.c, 1, 4, _in); @@ -111,7 +111,7 @@ float read_float(FILE* _in, bool _swap) //----------------------------------------------------------------------------- -double read_double(FILE* _in, bool _swap) +double read_double(FILE* _in, bool _swap) { union u4 { double d; unsigned char c[8]; } dc; fread((char*)dc.c, 1, 8, _in); @@ -124,11 +124,68 @@ double read_double(FILE* _in, bool _swap) return dc.d; } +//----------------------------------------------------------------------------- + +short int read_short(std::istream& _in, bool _swap) +{ + union u1 { short int s; unsigned char c[2]; } sc; + _in.read((char*)sc.c, 2); + if (_swap) std::swap(sc.c[0], sc.c[1]); + return sc.s; +} + + +//----------------------------------------------------------------------------- + + +int read_int(std::istream& _in, bool _swap) +{ + union u2 { int i; unsigned char c[4]; } ic; + _in.read((char*)ic.c, 4); + if (_swap) { + std::swap(ic.c[0], ic.c[3]); + std::swap(ic.c[1], ic.c[2]); + } + return ic.i; +} + + +//----------------------------------------------------------------------------- + + +float read_float(std::istream& _in, bool _swap) +{ + union u3 { float f; unsigned char c[4]; } fc; + _in.read((char*)fc.c, 4); + if (_swap) { + std::swap(fc.c[0], fc.c[3]); + std::swap(fc.c[1], fc.c[2]); + } + return fc.f; +} + + +//----------------------------------------------------------------------------- + + +double read_double(std::istream& _in, bool _swap) +{ + union u4 { double d; unsigned char c[8]; } dc; + _in.read((char*)dc.c, 8); + if (_swap) { + std::swap(dc.c[0], dc.c[7]); + std::swap(dc.c[1], dc.c[6]); + std::swap(dc.c[2], dc.c[5]); + std::swap(dc.c[3], dc.c[4]); + } + return dc.d; +} + //----------------------------------------------------------------------------- -void write_short(short int _i, FILE* _out, bool _swap) +void write_short(short int _i, FILE* _out, bool _swap) { union u1 { short int s; unsigned char c[2]; } sc; sc.s = _i; @@ -140,7 +197,7 @@ void write_short(short int _i, FILE* _out, bool _swap) //----------------------------------------------------------------------------- -void write_int(int _i, FILE* _out, bool _swap) +void write_int(int _i, FILE* _out, bool _swap) { union u2 { int i; unsigned char c[4]; } ic; ic.i = _i; @@ -155,7 +212,7 @@ void write_int(int _i, FILE* _out, bool _swap) //----------------------------------------------------------------------------- -void write_float(float _f, FILE* _out, bool _swap) +void write_float(float _f, FILE* _out, bool _swap) { union u3 { float f; unsigned char c[4]; } fc; fc.f = _f; @@ -170,7 +227,7 @@ void write_float(float _f, FILE* _out, bool _swap) //----------------------------------------------------------------------------- -void write_double(double _d, FILE* _out, bool _swap) +void write_double(double _d, FILE* _out, bool _swap) { union u4 { double d; unsigned char c[8]; } dc; dc.d = _d; diff --git a/src/OpenMesh/Core/IO/BinaryHelper.hh b/src/OpenMesh/Core/IO/BinaryHelper.hh index caee49c4..ef862f11 100644 --- a/src/OpenMesh/Core/IO/BinaryHelper.hh +++ b/src/OpenMesh/Core/IO/BinaryHelper.hh @@ -4,10 +4,10 @@ * Copyright (C) 2001-2011 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 . * * * -\*===========================================================================*/ +\*===========================================================================*/ /*===========================================================================*\ - * * + * * * $Revision$ * * $Date$ * * * @@ -96,6 +96,22 @@ float read_float(FILE* _in, bool _swap=false); \c _swap is true */ double read_double(FILE* _in, bool _swap=false); +/** Binary read a \c short from \c _is and perform byte swapping if + \c _swap is true */ +short int read_short(std::istream& _in, bool _swap=false); + +/** Binary read an \c int from \c _is and perform byte swapping if + \c _swap is true */ +int read_int(std::istream& _in, bool _swap=false); + +/** Binary read a \c float from \c _is and perform byte swapping if + \c _swap is true */ +float read_float(std::istream& _in, bool _swap=false); + +/** Binary read a \c double from \c _is and perform byte swapping if + \c _swap is true */ +double read_double(std::istream& _in, bool _swap=false); + /** Binary write a \c short to \c _os and perform byte swapping if \c _swap is true */ @@ -113,7 +129,7 @@ void write_float(float _f, FILE* _out, bool _swap=false); \c _swap is true */ void write_double(double _d, FILE* _out, bool _swap=false); - + //@} diff --git a/src/OpenMesh/Core/IO/reader/STLReader.cc b/src/OpenMesh/Core/IO/reader/STLReader.cc index 26af0fa2..b66ad11d 100644 --- a/src/OpenMesh/Core/IO/reader/STLReader.cc +++ b/src/OpenMesh/Core/IO/reader/STLReader.cc @@ -144,9 +144,14 @@ _STLReader_::read(std::istream& _is, Options& _opt) { - omerr() << "[OMReader] : STL Streams are not supported " << std::endl; + bool result = false; - return false; + if (_opt & Options::Binary) + result = read_stlb(_is, _bi); + else + result = read_stla(_is, _bi); + + return result; } @@ -313,9 +318,111 @@ read_stla(const std::string& _filename, BaseImporter& _bi) const return true; } - //----------------------------------------------------------------------------- +bool +_STLReader_:: +read_stla(std::istream& _in, BaseImporter& _bi) const +{ + omlog() << "[STLReader] : read ascii stream\n"; + + + unsigned int i; + OpenMesh::Vec3f v; + OpenMesh::Vec3f n; + unsigned int cur_idx(0); + BaseImporter::VHandles vhandles; + + CmpVec comp(eps_); + std::map vMap(comp); + std::map::iterator vMapIt; + + std::string line; + + //bool normal = false; + + while( _in && !_in.eof() ) { + + // Get one line + std::getline(_in, line); + if ( _in.bad() ){ + omerr() << " Warning! Could not read stream properly!\n"; + return false; + } + + // Trim Both leading and trailing spaces + trimStdString(line); + + // Normal found? + if (line.find("facet normal") != std::string::npos) { + std::stringstream strstream(line); + + std::string garbage; + + // facet + strstream >> garbage; + + // normal + strstream >> garbage; + + strstream >> n[0]; + strstream >> n[1]; + strstream >> n[2]; + + //normal = true; + } + + // Detected a triangle + if ( (line.find("outer") != std::string::npos) || (line.find("OUTER") != std::string::npos ) ) { + + vhandles.clear(); + + for (i=0; i<3; ++i) { + // Get one vertex + std::getline(_in, line); + trimStdString(line); + + std::stringstream strstream(line); + + std::string garbage; + strstream >> garbage; + + strstream >> v[0]; + strstream >> v[1]; + strstream >> v[2]; + + // has vector been referenced before? + if ((vMapIt=vMap.find(v)) == vMap.end()) + { + // No : add vertex and remember idx/vector mapping + _bi.add_vertex(v); + vhandles.push_back(VertexHandle(cur_idx)); + vMap[v] = VertexHandle(cur_idx++); + } + else + // Yes : get index from map + vhandles.push_back(vMapIt->second); + + } + + // Add face only if it is not degenerated + if ((vhandles[0] != vhandles[1]) && + (vhandles[0] != vhandles[2]) && + (vhandles[1] != vhandles[2])) { + + + FaceHandle fh = _bi.add_face(vhandles); + + } + + //normal = false; + } + } + + return true; +} + +//----------------------------------------------------------------------------- bool _STLReader_:: @@ -403,9 +510,84 @@ read_stlb(const std::string& _filename, BaseImporter& _bi) const return true; } - //----------------------------------------------------------------------------- +bool +_STLReader_:: +read_stlb(std::istream& _in, BaseImporter& _bi) const +{ + omlog() << "[STLReader] : read binary stream\n"; + + char dummy[100]; + bool swapFlag; + unsigned int i, nT; + OpenMesh::Vec3f v; + unsigned int cur_idx(0); + BaseImporter::VHandles vhandles; + + std::map vMap; + std::map::iterator vMapIt; + + + // check size of types + if ((sizeof(float) != 4) || (sizeof(int) != 4)) { + omerr() << "[STLReader] : wrong type size\n"; + return false; + } + + // determine endian mode + union { unsigned int i; unsigned char c[4]; } endian_test; + endian_test.i = 1; + swapFlag = (endian_test.c[3] == 1); + + // read number of triangles + //fread(dummy, 1, 80, in); + _in.read(dummy, 80); + nT = read_int(_in, swapFlag); + + // read triangles + while (nT) + { + vhandles.clear(); + + // skip triangle normal + _in.read(dummy, 12); + + // triangle's vertices + for (i=0; i<3; ++i) + { + v[0] = read_float(_in, swapFlag); + v[1] = read_float(_in, swapFlag); + v[2] = read_float(_in, swapFlag); + + // has vector been referenced before? + if ((vMapIt=vMap.find(v)) == vMap.end()) + { + // No : add vertex and remember idx/vector mapping + _bi.add_vertex(v); + vhandles.push_back(VertexHandle(cur_idx)); + vMap[v] = VertexHandle(cur_idx++); + } + else + // Yes : get index from map + vhandles.push_back(vMapIt->second); + } + + + // Add face only if it is not degenerated + if ((vhandles[0] != vhandles[1]) && + (vhandles[0] != vhandles[2]) && + (vhandles[1] != vhandles[2])) + _bi.add_face(vhandles); + + _in.read(dummy, 2); + --nT; + } + + return true; +} + +//----------------------------------------------------------------------------- _STLReader_::STL_Type _STLReader_:: diff --git a/src/OpenMesh/Core/IO/reader/STLReader.hh b/src/OpenMesh/Core/IO/reader/STLReader.hh index 885aa74b..c6756b52 100644 --- a/src/OpenMesh/Core/IO/reader/STLReader.hh +++ b/src/OpenMesh/Core/IO/reader/STLReader.hh @@ -121,7 +121,9 @@ private: STL_Type check_stl_type(const std::string& _filename) const; bool read_stla(const std::string& _filename, BaseImporter& _bi) const; + bool read_stla(std::istream& _in, BaseImporter& _bi) const; bool read_stlb(const std::string& _filename, BaseImporter& _bi) const; + bool read_stlb(std::istream& _in, BaseImporter& _bi) const; private: