From 967d178c4343c689c728571bb10d5c94ab8d9d13 Mon Sep 17 00:00:00 2001 From: Jakob Haufe Date: Sun, 13 Mar 2016 23:07:22 +0100 Subject: [PATCH] Imported Upstream version 0.9.2 --- .gitignore | 3 + README.md | 29 +++++++ app/Info.plist | 31 +++++++ app/fstl.icns | Bin 0 -> 66361 bytes app/package.sh | 14 ++++ exe/fstl.ico | Bin 0 -> 370070 bytes exe/fstl.rc | 1 + exe/package.sh | 3 + gl/gl.qrc | 9 +++ gl/mesh.frag | 21 +++++ gl/mesh.vert | 13 +++ gl/quad.frag | 7 ++ gl/quad.vert | 10 +++ gl/sphere.stl | Bin 0 -> 4084 bytes qt/fstl.pro | 46 +++++++++++ qt/qt.qrc | 5 ++ qt/style.qss | 19 +++++ src/app.cpp | 28 +++++++ src/app.h | 20 +++++ src/backdrop.cpp | 44 ++++++++++ src/backdrop.h | 18 +++++ src/canvas.cpp | 205 +++++++++++++++++++++++++++++++++++++++++++++++ src/canvas.h | 60 ++++++++++++++ src/glmesh.cpp | 37 +++++++++ src/glmesh.h | 19 +++++ src/loader.cpp | 129 +++++++++++++++++++++++++++++ src/loader.h | 30 +++++++ src/main.cpp | 9 +++ src/mesh.cpp | 35 ++++++++ src/mesh.h | 31 +++++++ src/window.cpp | 146 +++++++++++++++++++++++++++++++++ src/window.h | 36 +++++++++ 32 files changed, 1058 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 app/Info.plist create mode 100644 app/fstl.icns create mode 100755 app/package.sh create mode 100644 exe/fstl.ico create mode 100644 exe/fstl.rc create mode 100644 exe/package.sh create mode 100644 gl/gl.qrc create mode 100644 gl/mesh.frag create mode 100644 gl/mesh.vert create mode 100644 gl/quad.frag create mode 100644 gl/quad.vert create mode 100644 gl/sphere.stl create mode 100644 qt/fstl.pro create mode 100644 qt/qt.qrc create mode 100644 qt/style.qss create mode 100644 src/app.cpp create mode 100644 src/app.h create mode 100644 src/backdrop.cpp create mode 100644 src/backdrop.h create mode 100644 src/canvas.cpp create mode 100644 src/canvas.h create mode 100644 src/glmesh.cpp create mode 100644 src/glmesh.h create mode 100644 src/loader.cpp create mode 100644 src/loader.h create mode 100644 src/main.cpp create mode 100644 src/mesh.cpp create mode 100644 src/mesh.h create mode 100644 src/window.cpp create mode 100644 src/window.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..deaad71 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build/* +*.pro.user +*.qmake.stash diff --git a/README.md b/README.md new file mode 100644 index 0000000..a9a845f --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +`fstl` is a viewer for [.stl files](http://en.wikipedia.org/wiki/STL_\(file_format\)). + +Here's a screenshot: +![Eiffel tower](http://mattkeeter.com/projects/fstl/eiffel.png) +(credit to [Pranav Panchal](https://grabcad.com/pranav.panchal)) + +It is designed to quickly load and render very high-polygon models; +showing 2 million triangles at 60+ FPS on a mid-range laptop. + +For more details, see the [project page](http://mattkeeter.com/projects/fstl). + +Issues and pull requests are welcome; +the project is under 1K lines of code and should be fairly approachable. + +-------------------------------------------------------------------------------- + +License +------- +(c) 2014 Matt Keeter + +This work may be reproduced, modified, distributed, performed, and displayed for any purpose. Copyright is retained and must be preserved. The work is provided as is; no warranty is provided, and users accept all liability. + +-------------------------------------------------------------------------------- +*p.s.* In my day job, I'm an engineer at [Formlabs](http://formlabs.com). +If you think `fstl` is cool, you should check out our +[jobs page](http://formlabs.com/jobs) -- we're hiring software developers +and engineers of all stripes to work on interesting, hard problems in +consumer-level 3D printing. + diff --git a/app/Info.plist b/app/Info.plist new file mode 100644 index 0000000..ff3047b --- /dev/null +++ b/app/Info.plist @@ -0,0 +1,31 @@ + + + + + NSPrincipalClass + NSApplication + CFBundleIconFile + fstl.icns + CFBundlePackageType + APPL + CFBundleGetInfoString + A minimal fast STL viewer + CFBundleExecutable + fstl + CFBundleIdentifier + com.impraxical.fstl + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + stl + + CFBundleTypeName + Stereolithography file + CFBundleTypeRole + Viewer + + + + diff --git a/app/fstl.icns b/app/fstl.icns new file mode 100644 index 0000000000000000000000000000000000000000..69c011c846414f9b3cad2fa2297e2d34f7fe836d GIT binary patch literal 66361 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 Fe*ifY!b1Q6 literal 0 HcmV?d00001 diff --git a/app/package.sh b/app/package.sh new file mode 100755 index 0000000..d51c470 --- /dev/null +++ b/app/package.sh @@ -0,0 +1,14 @@ +#!/bin/sh +cd ../build +macdeployqt fstl.app +cd fstl.app/Contents/PlugIns +rm -rf accessible audio imageformats mediaservice playlistformats position printsupport qml1tooling sensorgestures sensors +cd ../Frameworks +rm -rf QtDeclarative.framework QtMultimedia.framework QtMultimediaWidgets.framework QtNetwork.framework QtPositioning.framework QtQml.framework QtQuick.framework QtScript.framework QtSensors.framework QtSql.framework QtXmlPatterns.framework +cd ../Resources +rm empty.lproj +cd ../../.. +cp -r fstl.app .. +cd .. +zip -r fstl_mac.zip fstl.app README.md + diff --git a/exe/fstl.ico b/exe/fstl.ico new file mode 100644 index 0000000000000000000000000000000000000000..2e2d891658231eeddcfdeb7f254c3e79536267dc GIT binary patch literal 370070 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 BA_)Kh literal 0 HcmV?d00001 diff --git a/exe/fstl.rc b/exe/fstl.rc new file mode 100644 index 0000000..3620f29 --- /dev/null +++ b/exe/fstl.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "fstl.ico" diff --git a/exe/package.sh b/exe/package.sh new file mode 100644 index 0000000..ef81b62 --- /dev/null +++ b/exe/package.sh @@ -0,0 +1,3 @@ +cd .. +cp build/release/fstl.exe . +/c/Program\ Files/7-Zip/7z.exe a fstl_win.zip fstl.exe README.md diff --git a/gl/gl.qrc b/gl/gl.qrc new file mode 100644 index 0000000..ef93a0e --- /dev/null +++ b/gl/gl.qrc @@ -0,0 +1,9 @@ + + + mesh.frag + mesh.vert + quad.frag + quad.vert + sphere.stl + + diff --git a/gl/mesh.frag b/gl/mesh.frag new file mode 100644 index 0000000..d7a54d5 --- /dev/null +++ b/gl/mesh.frag @@ -0,0 +1,21 @@ +#version 120 + +uniform float zoom; + +varying vec3 ec_pos; + +void main() { + vec3 base3 = vec3(0.99, 0.96, 0.89); + vec3 base2 = vec3(0.92, 0.91, 0.83); + vec3 base00 = vec3(0.40, 0.48, 0.51); + + vec3 ec_normal = normalize(cross(dFdx(ec_pos), dFdy(ec_pos))); + ec_normal.z *= zoom; + ec_normal = normalize(ec_normal); + + float a = dot(ec_normal, vec3(0.0, 0.0, 1.0)); + float b = dot(ec_normal, vec3(-0.57, -0.57, 0.57)); + + gl_FragColor = vec4((a*base2 + (1-a)*base00)*0.5 + + (b*base3 + (1-b)*base00)*0.5, 1.0); +} diff --git a/gl/mesh.vert b/gl/mesh.vert new file mode 100644 index 0000000..e60e76b --- /dev/null +++ b/gl/mesh.vert @@ -0,0 +1,13 @@ +#version 120 +attribute vec3 vertex_position; + +uniform mat4 transform_matrix; +uniform mat4 view_matrix; + +varying vec3 ec_pos; + +void main() { + gl_Position = view_matrix*transform_matrix* + vec4(vertex_position, 1.0); + ec_pos = gl_Position.xyz; +} diff --git a/gl/quad.frag b/gl/quad.frag new file mode 100644 index 0000000..1c02e1b --- /dev/null +++ b/gl/quad.frag @@ -0,0 +1,7 @@ +#version 120 + +varying vec3 frag_color; + +void main() { + gl_FragColor = vec4(frag_color, 1.0); +} diff --git a/gl/quad.vert b/gl/quad.vert new file mode 100644 index 0000000..6698297 --- /dev/null +++ b/gl/quad.vert @@ -0,0 +1,10 @@ +#version 120 +attribute vec2 vertex_position; +attribute vec3 vertex_color; + +varying vec3 frag_color; + +void main() { + gl_Position = vec4(vertex_position, 0.9, 1.0); + frag_color = vertex_color; +} diff --git a/gl/sphere.stl b/gl/sphere.stl new file mode 100644 index 0000000000000000000000000000000000000000..b78c7b49e3cd4b198c0b2b22a29acabea1dfdcd8 GIT binary patch literal 4084 zcmb7`ziSjx5XVy_1Opbf7ILK)iYNpNeWGw+X>BRFz=;|;l}i(_i@oTdaCI7m6h3WY z8w9mT8~h7YY@L~%-Tl11ojbf{_wMHNX1;HJyf@r^wljG#+8S(6cAgCGJ{~>Y8ci-= zyRvy>aPj%ehl8t^R{raAKd^o@Uiox$`XFr_UdUgkC;9W~?Bn_ItNdNwOXT#&VLDpf z&#ym>GKuZ!Nm9$*wfzoJ^Xh}^o^#9DoDUMTayrdNMS@lyVNy-CP4%P>#(w6`?{r;u zp|sX-!@p5?d{FjtlmHv8Pl zCIkDX*M|{|kaS7VifUtm`|f$R=@Vy=gzthyNV<%QR#Y1koNAl~?3>aD3Dy|tlAsmU z#)R^ioI0Je{^tF!=Srt*NwACJNlh#EU`$B7%~|Ag*P;@-nS2^Y`ys)4CEZ%<8?88T zV#5Ei{cwNw?oruvEq#z+y^<~oTCv(=LVOfwYJDzw25o|uK1g)ywWdpgR;+fl>L=WX zWlc0Sr&?TBBt&g<-yvN_MJskuOo$J?u~<~1sX000x+39f?M_9yjEYuN8xzc}bg)II zr*m9aB>ded(q&Y%qS}~n9d^g@*zE=o*A)rhx1_(3*6;0yR#Y1kqC+dg*7ZEwEra=Q z*Vi`^;;-oy(j`$?;T{wdavC&uH94;=x*6^}a<+HwiX>RCeRLHat*AC8$Q)rR-qNEJto|T-8t!RX;enAUi;{36{W5VOLdo3f3qawk2?W2pmvMyq^ X#{_dre{obKSg(C_wF<4++a>W2;Mt%E literal 0 HcmV?d00001 diff --git a/qt/fstl.pro b/qt/fstl.pro new file mode 100644 index 0000000..7a0f449 --- /dev/null +++ b/qt/fstl.pro @@ -0,0 +1,46 @@ +QT += core gui opengl widgets + +TARGET = fstl +TEMPLATE = app + +# Bump optimization up to -O3 in release builds +QMAKE_CXXFLAGS_RELEASE -= -O2 +QMAKE_CXXFLAGS_RELEASE += -O3 + +SOURCES += \ + ../src/app.cpp\ + ../src/main.cpp\ + ../src/canvas.cpp \ + ../src/mesh.cpp \ + ../src/glmesh.cpp \ + ../src/loader.cpp \ + ../src/window.cpp \ + ../src/backdrop.cpp + +HEADERS += \ + ../src/app.h\ + ../src/canvas.h \ + ../src/mesh.h \ + ../src/glmesh.h \ + ../src/loader.h \ + ../src/window.h \ + ../src/backdrop.h + +CONFIG += c++11 + +RESOURCES += \ + qt.qrc \ + ../gl/gl.qrc + +macx { + QMAKE_INFO_PLIST = ../app/Info.plist + ICON = ../app/fstl.icns +} + +win32 { + RC_FILE = ../exe/fstl.rc +} + +static { + CONFIG += static +} diff --git a/qt/qt.qrc b/qt/qt.qrc new file mode 100644 index 0000000..883ac14 --- /dev/null +++ b/qt/qt.qrc @@ -0,0 +1,5 @@ + + + style.qss + + diff --git a/qt/style.qss b/qt/style.qss new file mode 100644 index 0000000..0297148 --- /dev/null +++ b/qt/style.qss @@ -0,0 +1,19 @@ +QWidget { + background-color: #fdf6e3; + color: #839496; +} + +QPushButton { + background-color: #eee8d5; + border-top-width: 5px; + border-bottom-width: 5px; + border-left-width: 30px; + border-right-width: 30px; + border-style: flat; + margin: 0px; + color: #839496; +} + +QPushButton:pressed { + background-color: #ddd7c4; +} diff --git a/src/app.cpp b/src/app.cpp new file mode 100644 index 0000000..b6eb3af --- /dev/null +++ b/src/app.cpp @@ -0,0 +1,28 @@ +#include +#include + +#include "app.h" +#include "window.h" + +App::App(int argc, char *argv[]) : + QApplication(argc, argv), window(new Window()) +{ + window->show(); + if (argc > 1) + window->load_stl(argv[1]); + else + window->load_stl(":gl/sphere.stl"); +} + +bool App::event(QEvent* e) +{ + if (e->type() == QEvent::FileOpen) + { + window->load_stl(static_cast(e)->file()); + return true; + } + else + { + return QApplication::event(e); + } +} diff --git a/src/app.h b/src/app.h new file mode 100644 index 0000000..7a7672e --- /dev/null +++ b/src/app.h @@ -0,0 +1,20 @@ +#ifndef APP_H +#define APP_H + +#include + +class Window; + +class App : public QApplication +{ + Q_OBJECT +public: + explicit App(int argc, char *argv[]); +protected: + bool event(QEvent* e); +private: + Window* const window; + +}; + +#endif // APP_H diff --git a/src/backdrop.cpp b/src/backdrop.cpp new file mode 100644 index 0000000..13d0aa3 --- /dev/null +++ b/src/backdrop.cpp @@ -0,0 +1,44 @@ +#include "backdrop.h" + +Backdrop::Backdrop() +{ + initializeGLFunctions(); + + shader.addShaderFromSourceFile(QGLShader::Vertex, ":/gl/quad.vert"); + shader.addShaderFromSourceFile(QGLShader::Fragment, ":/gl/quad.frag"); + shader.link(); + + float vbuf[] = { + -1, -1, 0.00, 0.10, 0.15, + -1, 1, 0.03, 0.21, 0.26, + 1, -1, 0.00, 0.12, 0.18, + 1, 1, 0.06, 0.26, 0.30}; + + vertices.create(); + vertices.bind(); + vertices.allocate(vbuf, sizeof(vbuf)); + vertices.release(); +} + +void Backdrop::draw() +{ + shader.bind(); + vertices.bind(); + + const GLuint vp = shader.attributeLocation("vertex_position"); + const GLuint vc = shader.attributeLocation("vertex_color"); + + glEnableVertexAttribArray(vp); + glEnableVertexAttribArray(vc); + + glVertexAttribPointer(vp, 2, GL_FLOAT, false, + 5 * sizeof(GLfloat), 0); + glVertexAttribPointer(vc, 3, GL_FLOAT, false, + 5 * sizeof(GLfloat), + (GLvoid*)(2 * sizeof(GLfloat))); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 8); + + vertices.release(); + shader.release(); +} diff --git a/src/backdrop.h b/src/backdrop.h new file mode 100644 index 0000000..a2398c8 --- /dev/null +++ b/src/backdrop.h @@ -0,0 +1,18 @@ +#ifndef BACKDROP_H +#define BACKDROP_H + +#include +#include +#include + +class Backdrop : protected QGLFunctions +{ +public: + Backdrop(); + void draw(); +private: + QGLShaderProgram shader; + QGLBuffer vertices; +}; + +#endif // BACKDROP_H diff --git a/src/canvas.cpp b/src/canvas.cpp new file mode 100644 index 0000000..dd645a5 --- /dev/null +++ b/src/canvas.cpp @@ -0,0 +1,205 @@ +#include +#include + +#include + +#include "canvas.h" +#include "backdrop.h" +#include "glmesh.h" +#include "mesh.h" + +Canvas::Canvas(const QGLFormat& format, QWidget *parent) + : QGLWidget(format, parent), mesh(NULL), + scale(1), zoom(1), tilt(90), yaw(0), status(" ") +{ + // Nothing to do here +} + +Canvas::~Canvas() +{ + delete mesh; +} + +void Canvas::load_mesh(Mesh* m) +{ + mesh = new GLMesh(m); + center = QVector3D(m->xmin() + m->xmax(), + m->ymin() + m->ymax(), + m->zmin() + m->zmax()) / 2; + scale = 2 / sqrt( + pow(m->xmax() - m->xmin(), 2) + + pow(m->ymax() - m->ymin(), 2) + + pow(m->zmax() - m->zmin(), 2)); + + // Reset other camera parameters + zoom = 1; + yaw = 0; + tilt = 90; + + update(); + + delete m; +} + +void Canvas::set_status(const QString &s) +{ + status = s; + update(); +} + +void Canvas::clear_status() +{ + status = ""; + update(); +} + +void Canvas::initializeGL() +{ + initializeGLFunctions(); + + mesh_shader.addShaderFromSourceFile(QGLShader::Vertex, ":/gl/mesh.vert"); + mesh_shader.addShaderFromSourceFile(QGLShader::Fragment, ":/gl/mesh.frag"); + mesh_shader.link(); + + backdrop = new Backdrop(); +} + +void Canvas::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + + backdrop->draw(); + if (mesh) draw_mesh(); + + if (status.isNull()) return; + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.drawText(10, height() - 10, status); +} + + +void Canvas::draw_mesh() +{ + mesh_shader.bind(); + + // Load the transform and view matrices into the shader + glUniformMatrix4fv( + mesh_shader.uniformLocation("transform_matrix"), + 1, GL_FALSE, transform_matrix().data()); + glUniformMatrix4fv( + mesh_shader.uniformLocation("view_matrix"), + 1, GL_FALSE, view_matrix().data()); + + // Compensate for z-flattening when zooming + glUniform1f(mesh_shader.uniformLocation("zoom"), 1/zoom); + + // Find and enable the attribute location for vertex position + const GLuint vp = mesh_shader.attributeLocation("vertex_position"); + glEnableVertexAttribArray(vp); + + // Then draw the mesh with that vertex position + mesh->draw(vp); + + // Clean up state machine + glDisableVertexAttribArray(vp); + mesh_shader.release(); +} + +QMatrix4x4 Canvas::transform_matrix() const +{ + QMatrix4x4 m; + m.rotate(tilt, QVector3D(1, 0, 0)); + m.rotate(yaw, QVector3D(0, 0, 1)); + m.scale(scale); + m.translate(-center); + return m; +} + +QMatrix4x4 Canvas::view_matrix() const +{ + QMatrix4x4 m; + if (width() > height()) + { + m.scale(-height() / float(width()), 1, 0.5); + } + else + { + m.scale(-1, width() / float(height()), 0.5); + } + m.scale(zoom, zoom, 1); + return m; +} + +void Canvas::mousePressEvent(QMouseEvent* event) +{ + if (event->button() == Qt::LeftButton || + event->button() == Qt::RightButton) + { + mouse_pos = event->pos(); + setCursor(Qt::ClosedHandCursor); + } +} + +void Canvas::mouseReleaseEvent(QMouseEvent* event) +{ + if (event->button() == Qt::LeftButton || + event->button() == Qt::RightButton) + { + unsetCursor(); + } +} + +void Canvas::mouseMoveEvent(QMouseEvent* event) +{ + auto p = event->pos(); + auto d = p - mouse_pos; + + if (event->buttons() & Qt::LeftButton) + { + yaw = fmod(yaw - d.x(), 360); + tilt = fmax(0, fmin(180, tilt - d.y())); + update(); + } + else if (event->buttons() & Qt::RightButton) + { + center = transform_matrix().inverted() * + view_matrix().inverted() * + QVector3D(-d.x() / (0.5*width()), + d.y() / (0.5*height()), 0); + update(); + } + mouse_pos = p; +} + +void Canvas::wheelEvent(QWheelEvent *event) +{ + // Find GL position before the zoom operation + // (to zoom about mouse cursor) + auto p = event->pos(); + QVector3D v(1 - p.x() / (0.5*width()), + p.y() / (0.5*height()) - 1, 0); + QVector3D a = transform_matrix().inverted() * + view_matrix().inverted() * v; + + if (event->delta() < 0) + { + for (int i=0; i > event->delta(); --i) + zoom *= 1.001; + } + else if (event->delta() > 0) + { + for (int i=0; i < event->delta(); ++i) + zoom /= 1.001; + } + + // Then find the cursor's GL position post-zoom and adjust center. + QVector3D b = transform_matrix().inverted() * + view_matrix().inverted() * v; + center += b - a; + update(); +} diff --git a/src/canvas.h b/src/canvas.h new file mode 100644 index 0000000..33313cf --- /dev/null +++ b/src/canvas.h @@ -0,0 +1,60 @@ +#ifndef CANVAS_H +#define CANVAS_H + +#include +#include +#include +#include +#include + +class GLMesh; +class Mesh; +class Backdrop; + +class Canvas : public QGLWidget, protected QGLFunctions +{ + Q_OBJECT + +public: + Canvas(const QGLFormat& format, QWidget* parent=0); + + void initializeGL(); + void paintEvent(QPaintEvent* event); + ~Canvas(); + +public slots: + void set_status(const QString& s); + void clear_status(); + void load_mesh(Mesh* m); + + +protected: + void mousePressEvent(QMouseEvent* event); + void mouseReleaseEvent(QMouseEvent* event); + void mouseMoveEvent(QMouseEvent* event); + void wheelEvent(QWheelEvent* event); + + +private: + void draw_mesh(); + + QMatrix4x4 transform_matrix() const; + QMatrix4x4 view_matrix() const; + + QGLShaderProgram mesh_shader; + QGLShaderProgram quad_shader; + + GLMesh* mesh; + Backdrop* backdrop; + + QVector3D center; + float scale; + float zoom; + float tilt; + float yaw; + + QPoint mouse_pos; + QString status; +}; + +#endif // CANVAS_H diff --git a/src/glmesh.cpp b/src/glmesh.cpp new file mode 100644 index 0000000..7053809 --- /dev/null +++ b/src/glmesh.cpp @@ -0,0 +1,37 @@ +#include "glmesh.h" +#include "mesh.h" + +GLMesh::GLMesh(const Mesh* const mesh) + : vertices(QGLBuffer::VertexBuffer), indices(QGLBuffer::IndexBuffer) +{ + initializeGLFunctions(); + + vertices.create(); + indices.create(); + + vertices.setUsagePattern(QGLBuffer::StaticDraw); + indices.setUsagePattern(QGLBuffer::StaticDraw); + + vertices.bind(); + vertices.allocate(mesh->vertices.data(), + mesh->vertices.size() * sizeof(float)); + vertices.release(); + + indices.bind(); + indices.allocate(mesh->indices.data(), + mesh->indices.size() * sizeof(uint32_t)); + indices.release(); +} + +void GLMesh::draw(GLuint vp) +{ + vertices.bind(); + indices.bind(); + + glVertexAttribPointer(vp, 3, GL_FLOAT, false, 3*sizeof(float), NULL); + glDrawElements(GL_TRIANGLES, indices.size() / sizeof(uint32_t), + GL_UNSIGNED_INT, NULL); + + vertices.release(); + indices.release(); +} diff --git a/src/glmesh.h b/src/glmesh.h new file mode 100644 index 0000000..74a193f --- /dev/null +++ b/src/glmesh.h @@ -0,0 +1,19 @@ +#ifndef GLMESH_H +#define GLMESH_H + +#include +#include + +class Mesh; + +class GLMesh : protected QGLFunctions +{ +public: + GLMesh(const Mesh* const mesh); + void draw(GLuint vp); +private: + QGLBuffer vertices; + QGLBuffer indices; +}; + +#endif // GLMESH_H diff --git a/src/loader.cpp b/src/loader.cpp new file mode 100644 index 0000000..0d6b165 --- /dev/null +++ b/src/loader.cpp @@ -0,0 +1,129 @@ +#include "loader.h" + +Loader::Loader(QObject* parent, const QString& filename) + : QThread(parent), filename(filename) +{ + // Nothing to do here +} + +void Loader::run() +{ + Mesh* mesh = load_stl(); + if (mesh) + { + emit got_mesh(mesh); + emit loaded_file(filename); + } +} + + +//////////////////////////////////////////////////////////////////////////////// + +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; + } +}; + +typedef std::pair Vec3i; + +//////////////////////////////////////////////////////////////////////////////// + +Mesh* Loader::load_stl() +{ + QFile file(filename); + file.open(QIODevice::ReadOnly); + if (file.read(5) == "solid") + { + emit error_ascii_stl(); + return NULL; + } + // Skip the rest of the header material + file.read(75); + + QDataStream data(&file); + data.setByteOrder(QDataStream::LittleEndian); + data.setFloatingPointPrecision(QDataStream::SinglePrecision); + + // Load the triangle count from the .stl file + uint32_t tri_count; + data >> tri_count; + + // Verify that the file is the right size + if (file.size() != 84 + tri_count*50) + { + emit error_bad_stl(); + return NULL; + } + + // Extract vertices into an array of xyz, unsigned pairs + QVector verts(tri_count*3); + + // Dummy array, because readRawData is faster than skipRawData + char buffer[sizeof(float)*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.readRawData(buffer, 3*sizeof(float)); + + // 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.readRawData(buffer, sizeof(uint16_t)); + } + + // 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; + } + + // Sort the set of vertices (to deduplicate) + std::sort(verts.begin(), verts.end()); + + // This vector will store triangles as sets of 3 indices + std::vector 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 (!vertex_count || v.first != verts[vertex_count-1].first) + { + verts[vertex_count++] = v; + } + indices[v.second] = vertex_count - 1; + } + verts.resize(vertex_count); + + std::vector flat_verts; + flat_verts.reserve(vertex_count*3); + for (auto v : verts) + { + flat_verts.push_back(v.first.x); + flat_verts.push_back(v.first.y); + flat_verts.push_back(v.first.z); + } + + return new Mesh(flat_verts, indices); +} + diff --git a/src/loader.h b/src/loader.h new file mode 100644 index 0000000..fb0c8d8 --- /dev/null +++ b/src/loader.h @@ -0,0 +1,30 @@ +#ifndef LOADER_H +#define LOADER_H + +#include + +#include "mesh.h" + +class Loader : public QThread +{ + Q_OBJECT +public: + explicit Loader(QObject* parent, const QString& filename); + void run(); + +protected: + Mesh* load_stl(); + +signals: + void loaded_file(QString filename); + void got_mesh(Mesh* m); + + void error_ascii_stl(); + void error_bad_stl(); + +private: + const QString filename; + +}; + +#endif // LOADER_H diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..4b76222 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,9 @@ +#include + +#include "app.h" + +int main(int argc, char *argv[]) +{ + App a(argc, argv); + return a.exec(); +} diff --git a/src/mesh.cpp b/src/mesh.cpp new file mode 100644 index 0000000..cfb4ca4 --- /dev/null +++ b/src/mesh.cpp @@ -0,0 +1,35 @@ +#include +#include +#include + +#include + +#include "mesh.h" + +//////////////////////////////////////////////////////////////////////////////// + +Mesh::Mesh(std::vector v, std::vector i) + : vertices(v), indices(i) +{ + // Nothing to do here +} + +float Mesh::min(size_t start) const +{ + float v = vertices[start]; + for (size_t i=start; i < vertices.size(); i += 3) + { + v = fmin(v, vertices[i]); + } + return v; +} + +float Mesh::max(size_t start) const +{ + float v = vertices[start]; + for (size_t i=start; i < vertices.size(); i += 3) + { + v = fmax(v, vertices[i]); + } + return v; +} diff --git a/src/mesh.h b/src/mesh.h new file mode 100644 index 0000000..e8a02f0 --- /dev/null +++ b/src/mesh.h @@ -0,0 +1,31 @@ +#ifndef MESH_H +#define MESH_H + +#include +#include + +#include + +class Mesh +{ +public: + Mesh(std::vector vertices, std::vector indices); + + float min(size_t start) const; + float max(size_t start) const; + + float xmin() const { return min(0); } + float ymin() const { return min(1); } + float zmin() const { return min(2); } + float xmax() const { return max(0); } + float ymax() const { return max(1); } + float zmax() const { return max(2); } + +private: + std::vector vertices; + std::vector indices; + + friend class GLMesh; +}; + +#endif // MESH_H diff --git a/src/window.cpp b/src/window.cpp new file mode 100644 index 0000000..3002ecc --- /dev/null +++ b/src/window.cpp @@ -0,0 +1,146 @@ +#include +#include +#include + +#include "window.h" +#include "canvas.h" +#include "loader.h" + +Window::Window(QWidget *parent) : + QMainWindow(parent), + open_action(new QAction("Open", this)), + about_action(new QAction("About", this)), + quit_action(new QAction("Quit", this)) + +{ + setWindowTitle("fstl"); + setAcceptDrops(true); + + QFile styleFile(":/qt/style.qss"); + styleFile.open( QFile::ReadOnly ); + setStyleSheet(styleFile.readAll()); + + QGLFormat format; + format.setVersion(2, 1); + format.setSampleBuffers(true); + + canvas = new Canvas(format, this); + setCentralWidget(canvas); + + open_action->setShortcut(QKeySequence::Open); + QObject::connect(open_action, &QAction::triggered, + this, &Window::on_open); + + quit_action->setShortcut(QKeySequence::Quit); + QObject::connect(quit_action, &QAction::triggered, + this, &Window::close); + + QObject::connect(about_action, &QAction::triggered, + this, &Window::on_about); + + auto file_menu = menuBar()->addMenu("File"); + file_menu->addAction(open_action); + file_menu->addAction(quit_action); + + auto help_menu = menuBar()->addMenu("Help"); + help_menu->addAction(about_action); + + resize(600, 400); +} + +void Window::on_open() +{ + QString filename = QFileDialog::getOpenFileName( + this, "Load .stl file", QString(), "*.stl"); + if (not filename.isNull()) + { + load_stl(filename); + } +} + +void Window::on_about() +{ + QMessageBox::about(this, "", + "

fstl

" + "

A fast viewer for .stl files.
" + "https://github.com/mkeeter/fstl

" + "

© 2014 Matthew Keeter
" + "matt.j.keeter@gmail.com

"); +} + +void Window::on_ascii_stl() +{ + QMessageBox::critical(this, "Error", + "Error:
" + "Cannot open ASCII .stl file
" + "Please convert to binary .stl and retry"); +} + +void Window::on_bad_stl() +{ + QMessageBox::critical(this, "Error", + "Error:
" + "This .stl file is invalid or corrupted.
" + "Please export it from the original source, verify, and retry."); +} + +void Window::enable_open() +{ + open_action->setEnabled(true); +} + +void Window::disable_open() +{ + open_action->setEnabled(false); +} + +bool Window::load_stl(const QString& filename) +{ + if (!open_action->isEnabled()) return false; + + canvas->set_status("Loading " + filename); + + Loader* loader = new Loader(this, filename); + connect(loader, &Loader::started, + this, &Window::disable_open); + + connect(loader, &Loader::got_mesh, + canvas, &Canvas::load_mesh); + connect(loader, &Loader::error_ascii_stl, + this, &Window::on_ascii_stl); + connect(loader, &Loader::error_bad_stl, + this, &Window::on_bad_stl); + + connect(loader, &Loader::finished, + loader, &Loader::deleteLater); + connect(loader, &Loader::finished, + this, &Window::enable_open); + connect(loader, &Loader::finished, + canvas, &Canvas::clear_status); + + if (filename[0] != ':') + { + connect(loader, &Loader::loaded_file, + this, &Window::setWindowTitle); + } + + loader->start(); + return true; +} + +void Window::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasUrls()) + { + auto urls = event->mimeData()->urls(); + if (urls.size() == 1 && urls.front().path().endsWith(".stl")) + event->acceptProposedAction(); + } +} + +void Window::dropEvent(QDropEvent *event) +{ + load_stl(event->mimeData()->urls().front().toLocalFile()); +} diff --git a/src/window.h b/src/window.h new file mode 100644 index 0000000..cb92ebb --- /dev/null +++ b/src/window.h @@ -0,0 +1,36 @@ +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class Canvas; + +class Window : public QMainWindow +{ + Q_OBJECT +public: + explicit Window(QWidget* parent=0); + bool load_stl(const QString& filename); + +protected: + void dragEnterEvent(QDragEnterEvent* event); + void dropEvent(QDropEvent* event); + +public slots: + void on_open(); + void on_about(); + void on_ascii_stl(); + void on_bad_stl(); + + void enable_open(); + void disable_open(); + +private: + QAction* const open_action; + QAction* const about_action; + QAction* const quit_action; + + Canvas* canvas; +}; + +#endif // WINDOW_H -- 2.39.5