From 49128e332ac5cb7e076e7ea5eac2f0dae9aaf0a8 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 6 Dec 2017 09:26:30 +0000 Subject: [PATCH 1/3] Also parse headers of binary STL files starting with the keyword 'solid' --- Polyhedron_IO/include/CGAL/IO/STL_reader.h | 109 +++++++++++++++--- .../Polyhedron_IO/data/ascii-tetrahedron.stl | 31 +++++ .../data/binary-tetrahedron-nice-header.stl | Bin 0 -> 284 bytes ...nary-tetrahedron-non-standard-header-1.stl | Bin 0 -> 284 bytes ...nary-tetrahedron-non-standard-header-2.stl | Bin 0 -> 284 bytes ...nary-tetrahedron-non-standard-header-3.stl | Bin 0 -> 284 bytes ...nary-tetrahedron-non-standard-header-4.stl | Bin 0 -> 284 bytes ...nary-tetrahedron-non-standard-header-5.stl | Bin 0 -> 284 bytes Polyhedron_IO/test/Polyhedron_IO/stl2off.cpp | 20 +++- 9 files changed, 139 insertions(+), 21 deletions(-) create mode 100644 Polyhedron_IO/test/Polyhedron_IO/data/ascii-tetrahedron.stl create mode 100644 Polyhedron_IO/test/Polyhedron_IO/data/binary-tetrahedron-nice-header.stl create mode 100644 Polyhedron_IO/test/Polyhedron_IO/data/binary-tetrahedron-non-standard-header-1.stl create mode 100644 Polyhedron_IO/test/Polyhedron_IO/data/binary-tetrahedron-non-standard-header-2.stl create mode 100644 Polyhedron_IO/test/Polyhedron_IO/data/binary-tetrahedron-non-standard-header-3.stl create mode 100644 Polyhedron_IO/test/Polyhedron_IO/data/binary-tetrahedron-non-standard-header-4.stl create mode 100644 Polyhedron_IO/test/Polyhedron_IO/data/binary-tetrahedron-non-standard-header-5.stl diff --git a/Polyhedron_IO/include/CGAL/IO/STL_reader.h b/Polyhedron_IO/include/CGAL/IO/STL_reader.h index 50bc2691f76..f9a4008fc22 100644 --- a/Polyhedron_IO/include/CGAL/IO/STL_reader.h +++ b/Polyhedron_IO/include/CGAL/IO/STL_reader.h @@ -26,6 +26,7 @@ #include #include #include +#include namespace CGAL{ @@ -35,26 +36,97 @@ namespace CGAL{ std::vector< cpp11::array >& facets, bool verbose = false) { - std::string s, solid("solid"); + bool is_binary_file = false; + + std::string s, solid("solid"), facet("facet"); std::map, int> pmap; int index = 0; cpp11::array ijk; cpp11::array p; char line[80]; - for(int i=0;i < 80; i++){ - boost::uint8_t c; - input.read(reinterpret_cast(&c), sizeof(c)); - line[i]=c; - if(i==5){ - s = std::string(line,5); - if(s == solid){ - break; - } - } - } + int i = 0, ni = 0; - if(s!= solid){ + boost::uint8_t c; + for(; i < 5; i++){ + input.read(reinterpret_cast(&c), sizeof(c)); + line[i]=c; + } + + s = std::string(line,5); + if(s == solid){ + // we found the keyword "solid" which is supposed to indicate the file is Ascii + // But it might still be binary, so we have to find out if it is followed + // by an (optional) name and then the keyword "facet" + // When we find "facet" we conclude that it is really Ascii + do { + input.read(reinterpret_cast(&c), sizeof(c)); + line[i++]=c; + }while(isspace(c) && ( i < 80)); + if(i==80){ + is_binary_file = true; + goto done; + } + // now c is not whitespace + ni = i-1; // here starts either the name or the keyword "facet" + do { + input.read(reinterpret_cast(&c), sizeof(c)); + line[i++]=c; + }while(! isspace(c) && ( i < 80)); +# ifdef CGAL_DEBUG_BINARY_HEADER + s = std::string(line+ni, (i-1) - ni); + std::cout << "|" << s << "|" << std::endl; +# endif + if(s == facet){ + goto done; + } else if(i == 80){ + // the entire header is a name + is_binary_file = true; + goto done; + } + + // we continue to read what comes after the name + + // now c is whitespace + do { + input.read(reinterpret_cast(&c), sizeof(c)); + line[i++]=c; + }while(isspace(c) && ( i < 80)); + if(i==80){ + is_binary_file = true; + goto done; + } + + // now c is not whitespace + ni = i-1; // here starts either "facet", or it is really binary + do { + input.read(reinterpret_cast(&c), sizeof(c)); + line[i++]=c; + }while(! isspace(c) && ( i < 80)); +# ifdef CGAL_DEBUG_BINARY_HEADER + s = std::string(line+ni, (i-1) - ni); + std::cout << "|" << s << "|" << std::endl; +# endif + if(s == facet){ + goto done; + } else { + for(; i < 80; i++){ + input.read(reinterpret_cast(&c), sizeof(c)); + } + is_binary_file = true; + goto done; + } + }else{ + // we read the other 75 characters of the header + for(; i < 80; i++){ + input.read(reinterpret_cast(&c), sizeof(c)); + } + is_binary_file = true; + } + + done: + + if(is_binary_file){ boost::uint32_t N32; input.read(reinterpret_cast(&N32), sizeof(N32)); unsigned int N = N32; @@ -96,14 +168,17 @@ namespace CGAL{ } return true; } else { - std::string facet("facet"), - outer("outer"), + + // It is an Ascii file but the first occurence of "facet" has already be parsed + bool first_facet = true; + std::string outer("outer"), loop("loop"), vertex("vertex"), endloop("endloop"), endsolid("endsolid"); - - while(input >> s){ + s = facet; + while(first_facet || (input >> s)){ + first_facet = false; if(s == endsolid){ //std::cerr << "found endsolid" << std::endl; } else if(s == facet){ diff --git a/Polyhedron_IO/test/Polyhedron_IO/data/ascii-tetrahedron.stl b/Polyhedron_IO/test/Polyhedron_IO/data/ascii-tetrahedron.stl new file mode 100644 index 00000000000..ef48cbaea36 --- /dev/null +++ b/Polyhedron_IO/test/Polyhedron_IO/data/ascii-tetrahedron.stl @@ -0,0 +1,31 @@ +solid cube_corner + facet normal 0.0 -1.0 0.0 + outer loop + vertex 0.0 0.0 0.0 + vertex 1.0 0.0 0.0 + vertex 0.0 0.0 1.0 + endloop + endfacet + facet normal 0.0 0.0 -1.0 + outer loop + vertex 0.0 0.0 0.0 + vertex 0.0 1.0 0.0 + vertex 1.0 0.0 0.0 + endloop + endfacet + facet normal -1.0 0.0 0.0 + outer loop + vertex 0.0 0.0 0.0 + vertex 0.0 0.0 1.0 + vertex 0.0 1.0 0.0 + endloop + endfacet + facet normal 0.577 0.577 0.577 + outer loop + vertex 1.0 0.0 0.0 + vertex 0.0 1.0 0.0 + vertex 0.0 0.0 1.0 + endloop + endfacet + endsolid + \ No newline at end of file diff --git a/Polyhedron_IO/test/Polyhedron_IO/data/binary-tetrahedron-nice-header.stl b/Polyhedron_IO/test/Polyhedron_IO/data/binary-tetrahedron-nice-header.stl new file mode 100644 index 0000000000000000000000000000000000000000..6298d8d89b613b2e2eccc123225e4cf3ae0dfd1d GIT binary patch literal 284 zcmZ?v_wf(1t*@_F@O2Dv4f1sK0dqhCAWSk~VSs^#{V*1SZm>tNVJuWJe7Xp$gqaDV VVX9%Y)mdSC7)Hp#bih<0^8vPQA7B6g literal 0 HcmV?d00001 diff --git a/Polyhedron_IO/test/Polyhedron_IO/data/binary-tetrahedron-non-standard-header-1.stl b/Polyhedron_IO/test/Polyhedron_IO/data/binary-tetrahedron-non-standard-header-1.stl new file mode 100644 index 0000000000000000000000000000000000000000..3ef58ac3e48c322f4458dc429662de9a9a5d781a GIT binary patch literal 284 zcmXTU&&fQnO;w-eqG76GwAEQ*dl*K@ K!gRn?A@c!X)*B!I literal 0 HcmV?d00001 diff --git a/Polyhedron_IO/test/Polyhedron_IO/data/binary-tetrahedron-non-standard-header-3.stl b/Polyhedron_IO/test/Polyhedron_IO/data/binary-tetrahedron-non-standard-header-3.stl new file mode 100644 index 0000000000000000000000000000000000000000..733843ff7c73635acde211abf2d0332877606545 GIT binary patch literal 284 zcmaisu?+(;2t`xe23g<_a1*4t1+s*7ra-cdWgzu!b`xZ$CuH5F%7GPLt4YJY~Cy06oRJMMm^ W{*&?Zqd|w>UY9j`ULz6I_xuLS-z>HO literal 0 HcmV?d00001 diff --git a/Polyhedron_IO/test/Polyhedron_IO/data/binary-tetrahedron-non-standard-header-5.stl b/Polyhedron_IO/test/Polyhedron_IO/data/binary-tetrahedron-non-standard-header-5.stl new file mode 100644 index 0000000000000000000000000000000000000000..d1dd7ed0bf4f6ea3164b5e294f9ca74fedf9e807 GIT binary patch literal 284 zcmaisu?+(;2t`xe23h0&0%>l6EMc7~kZfZaNPU~#1lcJ{ft)l668ax_ACBD{Rex?4C U@$;=ghu)soEqY!f5!C1W0@?~J!vFvP literal 0 HcmV?d00001 diff --git a/Polyhedron_IO/test/Polyhedron_IO/stl2off.cpp b/Polyhedron_IO/test/Polyhedron_IO/stl2off.cpp index 2c2c3dae2de..839ca82b839 100644 --- a/Polyhedron_IO/test/Polyhedron_IO/stl2off.cpp +++ b/Polyhedron_IO/test/Polyhedron_IO/stl2off.cpp @@ -5,8 +5,9 @@ #include #include -void read(const char* fname) +void read(const char* fname, int v, int f) { + std::cout << "Reading "<< fname << std::endl; std::ifstream input(fname, std::ios::in | std::ios::binary); std::vector< CGAL::cpp11::array > points; @@ -16,7 +17,10 @@ void read(const char* fname) points, faces, true); - + + assert(points.size() == v); + assert(faces.size() == f); + std::cout << "OFF version of file " << fname << std::endl; std::cout.precision(17); @@ -35,7 +39,15 @@ void read(const char* fname) int main() { - read("data/cube.stl"); - read("data/triangle.stl"); + read("data/cube.stl", 8, 12); + read("data/triangle.stl", 3, 1); + + + read("data/binary-tetrahedron-nice-header.stl", 4, 4); + read("data/binary-tetrahedron-non-standard-header-1.stl", 4, 4); + read("data/binary-tetrahedron-non-standard-header-2.stl", 4, 4); + read("data/binary-tetrahedron-non-standard-header-3.stl", 4, 4); + read("data/binary-tetrahedron-non-standard-header-4.stl", 4, 4); + read("data/binary-tetrahedron-non-standard-header-5.stl", 4, 4); return 0; } From cd7f1af9c4a0de04646c3cda51078c5e388fdbf1 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 11 Dec 2017 16:39:53 +0000 Subject: [PATCH 2/3] bug fix --- Polyhedron_IO/include/CGAL/IO/STL_reader.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Polyhedron_IO/include/CGAL/IO/STL_reader.h b/Polyhedron_IO/include/CGAL/IO/STL_reader.h index f9a4008fc22..490e8ca3b08 100644 --- a/Polyhedron_IO/include/CGAL/IO/STL_reader.h +++ b/Polyhedron_IO/include/CGAL/IO/STL_reader.h @@ -73,8 +73,8 @@ namespace CGAL{ input.read(reinterpret_cast(&c), sizeof(c)); line[i++]=c; }while(! isspace(c) && ( i < 80)); -# ifdef CGAL_DEBUG_BINARY_HEADER - s = std::string(line+ni, (i-1) - ni); + s = std::string(line+ni, (i-1) - ni); +# ifdef CGAL_DEBUG_BINARY_HEADER std::cout << "|" << s << "|" << std::endl; # endif if(s == facet){ @@ -103,7 +103,7 @@ namespace CGAL{ input.read(reinterpret_cast(&c), sizeof(c)); line[i++]=c; }while(! isspace(c) && ( i < 80)); -# ifdef CGAL_DEBUG_BINARY_HEADER +# ifdef CGAL_DEBUG_BINARY_HEADER s = std::string(line+ni, (i-1) - ni); std::cout << "|" << s << "|" << std::endl; # endif From 84be28c0d6b278e4cddcd1713d6581f187607996 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 13 Dec 2017 07:04:58 +0000 Subject: [PATCH 3/3] fix error and warning inside a test file --- Polyhedron_IO/test/Polyhedron_IO/stl2off.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Polyhedron_IO/test/Polyhedron_IO/stl2off.cpp b/Polyhedron_IO/test/Polyhedron_IO/stl2off.cpp index 839ca82b839..91a4cc1a51f 100644 --- a/Polyhedron_IO/test/Polyhedron_IO/stl2off.cpp +++ b/Polyhedron_IO/test/Polyhedron_IO/stl2off.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -5,7 +6,7 @@ #include #include -void read(const char* fname, int v, int f) +void read(const char* fname, std::size_t v, std::size_t f) { std::cout << "Reading "<< fname << std::endl; std::ifstream input(fname, std::ios::in | std::ios::binary);