12 bool operator!=(const Vec3& rhs) const
14 return x != rhs.x || y != rhs.y || z != rhs.z;
16 bool operator<(const Vec3& rhs) const
18 if (x != rhs.x) return x < rhs.x;
19 else if (y != rhs.y) return y < rhs.y;
20 else if (z != rhs.z) return z < rhs.z;
26 Mesh::Mesh(std::vector<GLfloat> v, std::vector<GLuint> i)
27 : vertices(v), indices(i)
32 Mesh* Mesh::load_stl(const QString& filename)
35 file.open(QIODevice::ReadOnly);
37 QDataStream data(&file);
38 data.setByteOrder(QDataStream::LittleEndian);
39 data.setFloatingPointPrecision(QDataStream::SinglePrecision);
41 // Skip .stl file header
44 // Load the triangle count from the .stl file
48 // Extract vertices into an array of xyz, unsigned pairs
49 QVector<std::pair<Vec3, GLuint>> verts(tri_count*3);
51 // Store vertices in the array, processing one triangle at a time.
52 for (auto v=verts.begin(); v != verts.end(); v += 3)
54 // Skip face's normal vector
55 data.skipRawData(3*sizeof(float));
57 // Load vertex data from .stl file into vertices
58 data >> v[0].first.x >> v[0].first.y >> v[0].first.z;
59 data >> v[1].first.x >> v[1].first.y >> v[1].first.z;
60 data >> v[2].first.x >> v[2].first.y >> v[2].first.z;
62 // Skip face attribute
63 data.skipRawData(sizeof(uint16_t));
66 // Save indicies as the second element in the array
67 // (so that we can reconstruct triangle order after sorting)
68 for (size_t i=0; i < tri_count*3; ++i)
73 // Sort the set of vertices (to deduplicate)
74 std::sort(verts.begin(), verts.end());
76 // This vector will store triangles as sets of 3 indices
77 std::vector<GLuint> indices(tri_count*3);
79 // Go through the sorted vertex list, deduplicating and creating
80 // an indexed geometry representation for the triangles.
81 // Unique vertices are moved so that they occupy the first vertex_count
82 // positions in the verts array.
83 size_t vertex_count = 0;
86 if (!vertex_count || v.first != verts[vertex_count-1].first)
88 verts[vertex_count++] = v;
90 indices[v.second] = vertex_count - 1;
93 // Finally, pack unique vertices into a flat array.
94 std::vector<GLfloat> unique_verts(vertex_count*3);
95 for (size_t i=0; i < vertex_count; ++i)
97 unique_verts[3*i] = verts[i].first.x;
98 unique_verts[3*i + 1] = verts[i].first.y;
99 unique_verts[3*i + 2] = verts[i].first.z;
102 return new Mesh(unique_verts, indices);