From fc04bac1a1da6a0eca404c5f5e4c2d91d5548a35 Mon Sep 17 00:00:00 2001 From: Martin Schultz Date: Mon, 15 Aug 2016 17:14:25 +0200 Subject: [PATCH 1/4] made the stl reader check for ascii file keyword instead of computing binary size --- src/OpenMesh/Core/IO/reader/STLReader.cc | 58 ++++++++++++------------ 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/src/OpenMesh/Core/IO/reader/STLReader.cc b/src/OpenMesh/Core/IO/reader/STLReader.cc index 8e4b9b63..9ed41bc7 100644 --- a/src/OpenMesh/Core/IO/reader/STLReader.cc +++ b/src/OpenMesh/Core/IO/reader/STLReader.cc @@ -61,6 +61,13 @@ #include #include +//comppare strings crossplatform ignorign case +#ifdef _WIN32 + #define strnicmp _strnicmp +#else + #define strnicmp strncasecmp +#endif + //=== NAMESPACES ============================================================== @@ -447,41 +454,32 @@ _STLReader_::STL_Type _STLReader_:: check_stl_type(const std::string& _filename) const { - // assume it's binary stl, then file size is known from #triangles - // if size matches, it's really binary - // open file - FILE* in = fopen(_filename.c_str(), "rb"); - if (!in) return NONE; + std::ifstream ifs (_filename.c_str(), std::ifstream::binary); + if(!ifs.good()) + { + omerr() << "could not open file" << _filename << std::endl; + return NONE; + } + //find first non whitespace character + std::string line = ""; + std::size_t firstChar; + while(line.empty() && ifs.good()) + { + std::getline(ifs,line); + firstChar = line.find_first_not_of("\t "); + } - // determine endian mode - union { unsigned int i; unsigned char c[4]; } endian_test; - endian_test.i = 1; - bool swapFlag = (endian_test.c[3] == 1); + //check for ascii keyword solid + if(strnicmp("solid",&line[firstChar],5) == 0) + { + return STLA; + } - - // read number of triangles - char dummy[100]; - fread(dummy, 1, 80, in); - size_t nT = read_int(in, swapFlag); - - - // compute file size from nT - size_t binary_size = 84 + nT*50; - - - // get actual file size - size_t file_size(0); - rewind(in); - while (!feof(in)) - file_size += fread(dummy, 1, 100, in); - fclose(in); - - - // if sizes match -> it's STLB - return (binary_size == file_size ? STLB : STLA); + //if the file does not start with solid it is STLB + return STLB; } From cc37345556e92130827f4dec25544a81819183f0 Mon Sep 17 00:00:00 2001 From: Martin Schultz Date: Mon, 15 Aug 2016 17:27:55 +0200 Subject: [PATCH 2/4] added include for cstring which should fix compile errors with c++11 and clang --- src/OpenMesh/Core/IO/reader/STLReader.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OpenMesh/Core/IO/reader/STLReader.cc b/src/OpenMesh/Core/IO/reader/STLReader.cc index 9ed41bc7..f804be65 100644 --- a/src/OpenMesh/Core/IO/reader/STLReader.cc +++ b/src/OpenMesh/Core/IO/reader/STLReader.cc @@ -55,6 +55,7 @@ #include #include +#include // OpenMesh #include From 2e6820a16bf43f822223bbcdcbba0b4c62e9135a Mon Sep 17 00:00:00 2001 From: Martin Schultz Date: Tue, 16 Aug 2016 15:06:19 +0200 Subject: [PATCH 3/4] added binary stl file size check after ascii check --- src/OpenMesh/Core/IO/reader/STLReader.cc | 74 +++++++++++++++++------- 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/src/OpenMesh/Core/IO/reader/STLReader.cc b/src/OpenMesh/Core/IO/reader/STLReader.cc index f804be65..6dd8569b 100644 --- a/src/OpenMesh/Core/IO/reader/STLReader.cc +++ b/src/OpenMesh/Core/IO/reader/STLReader.cc @@ -456,31 +456,61 @@ _STLReader_:: check_stl_type(const std::string& _filename) const { - // open file - std::ifstream ifs (_filename.c_str(), std::ifstream::binary); - if(!ifs.good()) - { - omerr() << "could not open file" << _filename << std::endl; - return NONE; - } + // open file + std::ifstream ifs (_filename.c_str(), std::ifstream::binary); + if(!ifs.good()) + { + omerr() << "could not open file" << _filename << std::endl; + return NONE; + } - //find first non whitespace character - std::string line = ""; - std::size_t firstChar; - while(line.empty() && ifs.good()) - { - std::getline(ifs,line); - firstChar = line.find_first_not_of("\t "); - } + //find first non whitespace character + std::string line = ""; + std::size_t firstChar; + while(line.empty() && ifs.good()) + { + std::getline(ifs,line); + firstChar = line.find_first_not_of("\t "); + } - //check for ascii keyword solid - if(strnicmp("solid",&line[firstChar],5) == 0) - { - return STLA; - } + //check for ascii keyword solid + if(strnicmp("solid",&line[firstChar],5) == 0) + { + return STLA; + } + ifs.close(); - //if the file does not start with solid it is STLB - return STLB; + //if the file does not start with solid it is probably STLB + //check the file size to verify it. + + //open the file + FILE* in = fopen(_filename.c_str(), "rb"); + if (!in) return NONE; + + // determine endian mode + union { unsigned int i; unsigned char c[4]; } endian_test; + endian_test.i = 1; + bool swapFlag = (endian_test.c[3] == 1); + + + // read number of triangles + char dummy[100]; + fread(dummy, 1, 80, in); + size_t nT = read_int(in, swapFlag); + + + // compute file size from nT + size_t binary_size = 84 + nT*50; + + // get actual file size + size_t file_size(0); + rewind(in); + while (!feof(in)) + file_size += fread(dummy, 1, 100, in); + fclose(in); + + // if sizes match -> it's STLB + return (binary_size == file_size ? STLB : NONE); } From 9cdd56d90e36becb7e4b3de6eb7630c7025285c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20M=C3=B6bius?= Date: Tue, 16 Aug 2016 16:03:01 +0200 Subject: [PATCH 4/4] Added changelog entry --- Doc/changelog.docu | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Doc/changelog.docu b/Doc/changelog.docu index 39bead27..d940fae4 100644 --- a/Doc/changelog.docu +++ b/Doc/changelog.docu @@ -13,13 +13,18 @@
  • Fixed type pun warning with gcc-6
  • Fixed incorrect type of hash function for boost causing a warning with clang
  • - +
+ +IO +
    +
  • STL Reader: Identify stl files containing solid keyword as ASCII type
  • +
General
  • Fixed undefined MSVC macro warning (Thanks to Xan for the patch)
  • - +
Build System