8 Mesh::Mesh(const Eigen::Matrix3Xf& v, const Eigen::Matrix3Xi& i)
9 : vertices(v), indices(i)
14 Mesh* Mesh::load_stl(const QString& filename)
17 file.open(QIODevice::ReadOnly);
19 QDataStream data(&file);
20 data.setByteOrder(QDataStream::LittleEndian);
21 data.setFloatingPointPrecision(QDataStream::SinglePrecision);
27 // Extract vertices into a vector of Vector4d objects
28 std::vector<Eigen::Vector4d> verts(tri_count*3);
29 for (unsigned i=0; i < tri_count; ++i)
31 data.skipRawData(3*sizeof(float));
32 for (int j=0; j < 3; ++j)
36 verts[3*i + j] << x, y, z, 3*i + j;
38 data.skipRawData(sizeof(uint16_t));
41 // Sort the set of vertices (to deduplicate)
42 std::sort(verts.begin(), verts.end(),
43 [](const Eigen::Vector4d& lhs, const Eigen::Vector4d& rhs)
45 if (lhs[0] != rhs[0]) return lhs[0] < rhs[0];
46 else if (lhs[1] != rhs[1]) return lhs[1] < rhs[1];
47 else if (lhs[2] != rhs[2]) return lhs[2] < rhs[2];
52 // This list will store unique vertices
53 std::list<Eigen::Vector3f> unique;
55 // This vector will store triangles as rows of indices
56 Eigen::Matrix3Xi indices;
57 indices.resize(Eigen::NoChange, tri_count);
59 // Go through the sorted vertex list, deduplicating and creating
60 // an indexed geometry representation for the triangles.
63 if (!unique.size() || v[0] != unique.back()[0] ||
64 v[1] != unique.back()[1] ||
65 v[2] != unique.back()[2])
67 // Switch to a float vector and save in the list.
69 v_ << v[0], v[1], v[2];
72 indices(int(v[3]) % 3, int(v[3]) / 3) = unique.size() - 1;
75 // Finally, pack unique vertices into a matrix.
76 Eigen::Matrix3Xf unique_verts;
77 unique_verts.resize(Eigen::NoChange, unique.size());
79 auto v = unique.begin();
80 for (unsigned i=0; i < unique.size(); ++i)
82 unique_verts.col(i) = *(v++);
86 return new Mesh(unique_verts, indices);