]> git.sur5r.net Git - fstl/blobdiff - src/mesh.cpp
Remove dependancy on eigen
[fstl] / src / mesh.cpp
index d7266e7875274350f22ca75b15bacfae2df841b9..3a971202ce46ba6e7d12d2bc463e6af27562e799 100644 (file)
@@ -1,11 +1,29 @@
 #include <QFile>
 #include <QDataStream>
+#include <QVector3D>
 
 #include <algorithm>
 
 #include "mesh.h"
 
-Mesh::Mesh(const Eigen::Matrix3Xf& v, const Eigen::Matrix3Xi& i)
+struct Vec3
+{
+    GLfloat x, y, z;
+    bool operator!=(const Vec3& rhs) const
+    {
+        return x != rhs.x || y != rhs.y || z != rhs.z;
+    }
+    bool operator<(const Vec3& rhs) const
+    {
+        if      (x != rhs.x)    return x < rhs.x;
+        else if (y != rhs.y)    return y < rhs.y;
+        else if (z != rhs.z)    return z < rhs.z;
+        else                    return false;
+    }
+};
+
+
+Mesh::Mesh(std::vector<GLfloat> v, std::vector<GLuint> i)
     : vertices(v), indices(i)
 {
     // Nothing to do here
@@ -20,67 +38,65 @@ Mesh* Mesh::load_stl(const QString& filename)
     data.setByteOrder(QDataStream::LittleEndian);
     data.setFloatingPointPrecision(QDataStream::SinglePrecision);
 
+    // Skip .stl file header
     data.skipRawData(80);
+
+    // Load the triangle count from the .stl file
     uint32_t tri_count;
     data >> tri_count;
 
-    // Extract vertices into a vector of Vector4d objects
-    std::vector<Eigen::Vector4d> verts(tri_count*3);
-    for (unsigned i=0; i < tri_count; ++i)
+    // Extract vertices into an array of xyz, unsigned pairs
+    QVector<std::pair<Vec3, GLuint>> verts(tri_count*3);
+
+    // Store vertices in the array, processing one triangle at a time.
+    for (auto v=verts.begin(); v != verts.end(); v += 3)
     {
+        // Skip face's normal vector
         data.skipRawData(3*sizeof(float));
-        for (int j=0; j < 3; ++j)
-        {
-            float x, y, z;
-            data >> x >> y >> z;
-            verts[3*i + j] << x, y, z, 3*i + j;
-        }
+
+        // Load vertex data from .stl file into vertices
+        data >> v[0].first.x >> v[0].first.y >> v[0].first.z;
+        data >> v[1].first.x >> v[1].first.y >> v[1].first.z;
+        data >> v[2].first.x >> v[2].first.y >> v[2].first.z;
+
+        // Skip face attribute
         data.skipRawData(sizeof(uint16_t));
     }
 
-    // Sort the set of vertices (to deduplicate)
-    std::sort(verts.begin(), verts.end(),
-              [](const Eigen::Vector4d& lhs, const Eigen::Vector4d& rhs)
-        {
-            if      (lhs[0] != rhs[0])  return lhs[0] < rhs[0];
-            else if (lhs[1] != rhs[1])  return lhs[1] < rhs[1];
-            else if (lhs[2] != rhs[2])  return lhs[2] < rhs[2];
-            else                        return false;
-        }
-    );
+    // Save indicies as the second element in the array
+    // (so that we can reconstruct triangle order after sorting)
+    for (size_t i=0; i < tri_count*3; ++i)
+    {
+        verts[i].second = i;
+    }
 
-    // This list will store unique vertices
-    std::list<Eigen::Vector3f> unique;
+    // Sort the set of vertices (to deduplicate)
+    std::sort(verts.begin(), verts.end());
 
-    // This vector will store triangles as rows of indices
-    Eigen::Matrix3Xi indices;
-    indices.resize(Eigen::NoChange, tri_count);
+    // This vector will store triangles as sets of 3 indices
+    std::vector<GLuint> indices(tri_count*3);
 
     // Go through the sorted vertex list, deduplicating and creating
     // an indexed geometry representation for the triangles.
+    // Unique vertices are moved so that they occupy the first vertex_count
+    // positions in the verts array.
+    size_t vertex_count = 0;
     for (auto v : verts)
     {
-        if (!unique.size() || v[0] != unique.back()[0] ||
-                              v[1] != unique.back()[1] ||
-                              v[2] != unique.back()[2])
+        if (!vertex_count || v.first != verts[vertex_count-1].first)
         {
-            // Switch to a float vector and save in the list.
-            Eigen::Vector3f v_;
-            v_ << v[0], v[1], v[2];
-            unique.push_back(v_);
+            verts[vertex_count++] = v;
         }
-        indices(int(v[3]) % 3, int(v[3]) / 3) = unique.size() - 1;
+        indices[v.second] = vertex_count - 1;
     }
 
-    // Finally, pack unique vertices into a matrix.
-    Eigen::Matrix3Xf unique_verts;
-    unique_verts.resize(Eigen::NoChange, unique.size());
+    // Finally, pack unique vertices into a flat array.
+    std::vector<GLfloat> unique_verts(vertex_count*3);
+    for (size_t i=0; i < vertex_count; ++i)
     {
-        auto v = unique.begin();
-        for (unsigned i=0; i < unique.size(); ++i)
-        {
-            unique_verts.col(i) = *(v++);
-        }
+        unique_verts[3*i]     = verts[i].first.x;
+        unique_verts[3*i + 1] = verts[i].first.y;
+        unique_verts[3*i + 2] = verts[i].first.z;
     }
 
     return new Mesh(unique_verts, indices);