Render STL with Qt buffers



  • Hi,

    I want to render a STL file with Qt Buffers. Using Qt version 5.4.2.
    The problem is, this code does not render the STL object but just crashes with a core dump (memory read error)
    Does igl::readSTL returns what I think it does, or did I messed up with the buffers?
    Here is my code:

    #include "movablesphere.h"
    
    #include <QMouseEvent>
    #include <QDebug>
    #include <QMatrix>
    #include <QRect>
    #include <Eigen/Geometry>
    #include <igl/readSTL.h>
    #include <QFile>
    #include <QTemporaryDir>
    #include "mesh.h"
    
    #include <QOpenGLBuffer>
    #include <QOpenGLShaderProgram>
    
    QOpenGLBuffer* verticesBuffer;
    QOpenGLBuffer* trianglesBuffer;
    QOpenGLBuffer* normalsBuffer;
    
    QOpenGLShaderProgram *program;
    int triangleSize;
    
    movableSphere::movableSphere(){
        setWheelSensitivity(0);
        setRotationSensitivity(0);
    
        QTemporaryDir tempDir;
        if(tempDir.isValid()){
    
            QFile::copy(":/halfpipe_gyroscope_noncon.stl", tempDir.path() + QString("/halfpipe_gyroscope_noncon.stl"));
    
            Eigen::MatrixX3d vertices, normals;
            Eigen::MatrixXi triangles;
    
            igl::readSTL(tempDir.path().toStdString() + "/halfpipe_gyroscope_noncon.stl", vertices, triangles, normals);
    
            //compile shaders
            program = new QOpenGLShaderProgram();
            program->addShaderFromSourceCode(QOpenGLShader::Vertex, "attribute highp vec4 vertex;\n"
                "void main()\n"
                "{\n"
                "  gl_Position = vertex;\n"
                "}"
            );
            program->addShaderFromSourceCode(QOpenGLShader::Fragment, "void main()\n"
                "{\n"
                "  gl_FragColor = vec4(0.8,0.4,0.0,1.0);\n"
                "}"
            );
            //program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vertex_shader.glsl");
            //program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/fragment_shader.glsl");
            program->link();
            program->bind();
    
            //cast libigl matrix to opengl matrix
            Eigen::MatrixXf c_vertices, c_normals;
            Eigen::Matrix<uint, Eigen::Dynamic, Eigen::Dynamic> c_triangles;
            c_vertices = vertices.transpose().cast<float>();
            c_triangles = triangles.transpose().cast<uint>();
            c_normals = normals.transpose().cast<float>();
    
            std::cout << "Liquido: Triangle Size: " << c_triangles.cols() << std::endl;
            std::cout << "Liquido: Vertices Size: " << c_vertices.cols() << std::endl;
            triangleSize = c_triangles.size();
    
            //Create Buffers
            QOpenGLBuffer* verticesBuffer = new QOpenGLBuffer();
            QOpenGLBuffer* trianglesBuffer = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
            QOpenGLBuffer* normalsBuffer = new QOpenGLBuffer();
    
            verticesBuffer->create();
            trianglesBuffer->create();
            normalsBuffer->create();
    
            //binding triangles
            trianglesBuffer->bind();
            trianglesBuffer->allocate(c_triangles.data(), static_cast<int>(c_triangles.size()*sizeof(unsigned int)));
            trianglesBuffer->release();
    
            //binding vertices buffer/array
            verticesBuffer->bind();
            verticesBuffer->allocate(c_vertices.data(), static_cast<int>(c_vertices.size()*sizeof(float)));
            verticesBuffer->release();
    
            //binding normals buffer/array
            normalsBuffer->bind();
            normalsBuffer->allocate(c_normals.data(), static_cast<int>(c_normals.size()*sizeof(float)));
            normalsBuffer->release();
    
            program->release();
    
        }else{
            std::cerr << "Cannot create temporary directory! Quitting." << std::endl;
            exit(0);
        }
    }
    
    void movableSphere::draw(QOpenGLFunctions_2_1* gl){
        program->bind();
    
        //Vertex Buffer
        verticesBuffer->bind();
        int vertexLocation = program->attributeLocation("vertex");
        program->enableAttributeArray(vertexLocation);
        program->setAttributeBuffer(vertexLocation, GL_FLOAT, 0, 3);
        trianglesBuffer->bind();
    
        gl->glDrawElements(GL_TRIANGLES, triangleSize, GL_UNSIGNED_INT, 0);
    
        verticesBuffer->release();
        trianglesBuffer->release();
        program->release();
    }
    

    Thank you!


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    The Qt3D module might be of interest for your use case.

    Hope it helps



  • Hi,

    is there a minimal/easy to understand AssimpParser example?
    I just need to render a STL object in a qglviewer::ManipulatedFrame, so I can move it with the mouse.
    Or should I use something else to manipulate the object?

    Thanks!


  • Lifetime Qt Champion

    Do you mean something like the assimp example ?



  • Thanks!
    But how can I render from inside a "plugin" of a main program?
    I got only an QOpenGLFunctions_2_1* gl pointer.


  • Lifetime Qt Champion

    Can you describe your setup ?



  • The program uses Qt5 and libqglviewer.
    The main program creates a QGLViewer (QGLWidget) instance and renders in it with QOpenGLBuffers and glDrawElements.
    This program has plugins, which have a draw function: void draw3D(QOpenGLFunctions_2_1* gl);
    The example plugin just created a new qglviewer::ManipulatedFrame and rendered with gluSphere(foo...);.
    My question is now: What is the easiest way to render STL data in this plugin?

    EDIT: Edited the start post, program crashes with memory read error now


  • Lifetime Qt Champion

    Do you have any control on that main application ?



  • It would be great not to modify it.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.