61 #include <OpenMesh/Core/IO/BinaryHelper.hh>
62 #include <OpenMesh/Core/IO/reader/STLReader.hh>
63 #include <OpenMesh/Core/IO/IOManager.hh>
67 #define strnicmp _strnicmp
69 #define strnicmp strncasecmp
108 STL_Type file_type = NONE;
110 if ( check_extension( _filename,
"stla" ) )
115 else if ( check_extension( _filename,
"stlb" ) )
120 else if ( check_extension( _filename,
"stl" ) )
122 file_type = check_stl_type(_filename);
130 result = read_stla(_filename, _bi, _opt);
131 _opt -= Options::Binary;
137 result = read_stlb(_filename, _bi, _opt);
138 _opt += Options::Binary;
154 _STLReader_::read(std::istream& _is,
161 if (_opt & Options::Binary)
162 result = read_stlb(_is, _bi, _opt);
164 result = read_stla(_is, _bi, _opt);
173 #ifndef DOXY_IGNORE_THIS
179 CmpVec(
float _eps=FLT_MIN) : eps_(_eps) {}
181 bool operator()(
const Vec3f& _v0,
const Vec3f& _v1 )
const
183 if (fabs(_v0[0] - _v1[0]) <= eps_)
185 if (fabs(_v0[1] - _v1[1]) <= eps_)
187 return (_v0[2] < _v1[2] - eps_);
189 else return (_v0[1] < _v1[1] - eps_);
191 else return (_v0[0] < _v1[0] - eps_);
203 void trimStdString( std::string& _string) {
206 size_t start = _string.find_first_not_of(
" \t\r\n");
207 size_t end = _string.find_last_not_of(
" \t\r\n");
209 if(( std::string::npos == start ) || ( std::string::npos == end))
212 _string = _string.substr( start, end-start+1 );
219 read_stla(
const std::string& _filename,
BaseImporter& _bi, Options& _opt)
const
221 std::fstream in( _filename.c_str(), std::ios_base::in );
225 omerr() <<
"[STLReader] : cannot not open file "
231 bool res = read_stla(in, _bi, _opt);
243 read_stla(std::istream& _in,
BaseImporter& _bi, Options& _opt)
const
249 BaseImporter::VHandles vhandles;
252 std::map<Vec3f, VertexHandle, CmpVec> vMap(comp);
253 std::map<Vec3f, VertexHandle, CmpVec>::iterator vMapIt;
258 std::stringstream strstream;
260 bool facet_normal(
false);
262 while( _in && !_in.eof() ) {
265 std::getline(_in, line);
267 omerr() <<
" Warning! Could not read stream properly!\n";
275 if (line.find(
"facet normal") != std::string::npos) {
280 strstream >> garbage;
283 strstream >> garbage;
293 if ( (line.find(
"outer") != std::string::npos) || (line.find(
"OUTER") != std::string::npos ) ) {
297 for (i=0; i<3; ++i) {
299 std::getline(_in, line);
305 strstream >> garbage;
312 if ((vMapIt=vMap.find(v)) == vMap.end())
315 VertexHandle handle = _bi.add_vertex(v);
316 vhandles.push_back(handle);
321 vhandles.push_back(vMapIt->second);
326 if ((vhandles[0] != vhandles[1]) &&
327 (vhandles[0] != vhandles[2]) &&
328 (vhandles[1] != vhandles[2])) {
331 FaceHandle fh = _bi.add_face(vhandles);
336 if (fh.is_valid() && _opt.face_has_normal())
337 _bi.set_normal(fh, n);
339 _opt -= Options::FaceNormal;
342 facet_normal =
false;
353 read_stlb(
const std::string& _filename,
BaseImporter& _bi, Options& _opt)
const
355 std::fstream in( _filename.c_str(), std::ios_base::in | std::ios_base::binary);
359 omerr() <<
"[STLReader] : cannot not open file "
365 bool res = read_stlb(in, _bi, _opt);
377 read_stlb(std::istream& _in,
BaseImporter& _bi, Options& _opt)
const
383 BaseImporter::VHandles vhandles;
385 std::map<Vec3f, VertexHandle, CmpVec> vMap;
386 std::map<Vec3f, VertexHandle, CmpVec>::iterator vMapIt;
390 if ((
sizeof(
float) != 4) || (
sizeof(
int) != 4)) {
391 omerr() <<
"[STLReader] : wrong type size\n";
396 union {
unsigned int i;
unsigned char c[4]; } endian_test;
398 swapFlag = (endian_test.c[3] == 1);
422 if ((vMapIt=vMap.find(v)) == vMap.end())
425 VertexHandle handle = _bi.add_vertex(v);
426 vhandles.push_back(handle);
431 vhandles.push_back(vMapIt->second);
436 if ((vhandles[0] != vhandles[1]) &&
437 (vhandles[0] != vhandles[2]) &&
438 (vhandles[1] != vhandles[2])) {
439 FaceHandle fh = _bi.add_face(vhandles);
441 if (fh.is_valid() && _opt.face_has_normal())
442 _bi.set_normal(fh, n);
454 _STLReader_::STL_Type
456 check_stl_type(
const std::string& _filename)
const
460 std::ifstream ifs (_filename.c_str(), std::ifstream::binary);
463 omerr() <<
"could not open file" << _filename << std::endl;
468 std::string line =
"";
469 std::size_t firstChar;
470 while(line.empty() && ifs.good())
472 std::getline(ifs,line);
473 firstChar = line.find_first_not_of(
"\t ");
477 if(strnicmp(
"solid",&line[firstChar],5) == 0)
487 FILE* in = fopen(_filename.c_str(),
"rb");
488 if (!in)
return NONE;
491 union {
unsigned int i;
unsigned char c[4]; } endian_test;
493 bool swapFlag = (endian_test.c[3] == 1);
498 fread(dummy, 1, 80, in);
503 size_t binary_size = 84 + nT*50;
509 file_size += fread(dummy, 1, 100, in);
513 return (binary_size == file_size ? STLB : NONE);
int read_int(FILE *_in, bool _swap=false)
_STLReader_ __STLReaderInstance
Declare the single entity of the STL reader.
_IOManager_ & IOManager()
Set options for reader/writer modules.
DrawMode NONE
not a valid draw mode
float read_float(FILE *_in, bool _swap=false)
bool register_module(BaseReader *_bl)