diff --git a/src/polymesh/formats/stl.cc b/src/polymesh/formats/stl.cc index 1d2cf6f1339c0e7465f09bbb4e5d621b77390bfd..1f384c190509376a07884337645e40ac1f7c48f3 100644 --- a/src/polymesh/formats/stl.cc +++ b/src/polymesh/formats/stl.cc @@ -70,7 +70,17 @@ bool read_stl(const std::string& filename, Mesh& mesh, vertex_attribute<std::arr if (!file.good()) return false; - return read_stl(file, mesh, position, normals); + if (is_ascii_stl(file)) + { + return read_stl_ascii(file, mesh, position, normals); + } + else + { + // Windows interprets binary files differently from ascii which messes with the parsing. + // Therefore we create a new stream in binary mode. + file = std::ifstream(filename, std::ios::binary); + return read_stl_binary(file, mesh, position, normals); + } } template <class ScalarT> @@ -99,9 +109,10 @@ bool read_stl_binary(std::istream& input, Mesh& mesh, vertex_attribute<std::arra // } uint32_t n_triangles; - input.read((char*)&n_triangles, sizeof(n_triangles)); + input.read(reinterpret_cast<char*>(&n_triangles), sizeof(n_triangles)); - size_t fs_expect = 80 + sizeof(n_triangles) + n_triangles * (sizeof(std::array<ScalarT, 3>) * 4 + sizeof(uint16_t)); + // note: binary stl always stores 32bit floats + size_t fs_expect = 80 + sizeof(n_triangles) + n_triangles * (sizeof(std::array<float, 3>) * 4 + sizeof(uint16_t)); if (fs_expect != fs_real) { std::cerr << "Expected file size mismatch: " << fs_expect << " vs " << fs_real << " bytes (file corrupt or wrong format?)" << std::endl; @@ -125,12 +136,25 @@ bool read_stl_binary(std::istream& input, Mesh& mesh, vertex_attribute<std::arra auto v2 = mesh.vertices().add(); auto f = mesh.faces().add(v0, v1, v2); - input.read((char*)&f[normals], sizeof(std::array<ScalarT, 3>)); - input.read((char*)&position[v0], sizeof(std::array<ScalarT, 3>)); - input.read((char*)&position[v1], sizeof(std::array<ScalarT, 3>)); - input.read((char*)&position[v2], sizeof(std::array<ScalarT, 3>)); + std::array<float, 3> n; + input.read(reinterpret_cast<char*>(&n), sizeof(n)); + + if (normals) + f[normals] = {n[0], n[1], n[2]}; + + std::array<float, 3> p0; + std::array<float, 3> p1; + std::array<float, 3> p2; + input.read(reinterpret_cast<char*>(&p0), sizeof(p0)); + input.read(reinterpret_cast<char*>(&p1), sizeof(p1)); + input.read(reinterpret_cast<char*>(&p2), sizeof(p2)); + // convert float to ScalarT + position[v0] = {ScalarT(p0[0]), ScalarT(p0[1]), ScalarT(p0[2])}; + position[v1] = {ScalarT(p1[0]), ScalarT(p1[1]), ScalarT(p1[2])}; + position[v2] = {ScalarT(p2[0]), ScalarT(p2[1]), ScalarT(p2[2])}; + uint16_t attr_cnt; - input.read((char*)&attr_cnt, sizeof(attr_cnt)); + input.read(reinterpret_cast<char*>(&attr_cnt), sizeof(attr_cnt)); } return true;