Rendering an already-loaded mesh using qt3d



  • I have code which generates a mesh, i.e., as a N x 3 array of doubles V of the 3D points and another M x 3 array of integers F of the triangles. How can I render this mesh via qt3d (note the mesh is generated and hence not loaded from a file)? As far as I understand I need to create my own QGeometryRenderer, QGeometry, QBuffer, QAttribute.
    Also - I've googled near and far but couldn't find any example showing how to do this, nor proper documentation of, e.g., the QGeometryRenderer class, explaining how to use it. Am I missing some resource?



  • My attempt to post a reply to your question was unfortunately misunderstood as a hijacking of your thread.

    You decide if it is relevant: https://forum.qt.io/topic/63457/qt3d-vs-matplotlib


  • Qt Champions 2016

    @no-name
    Hello,
    I don't think there's a proper documentation. Qt3D is still a tech-preview, so you'll probably need to ask your question in the interest mail group. The developers are pretty quick to respond, so hopefully they'll be able to provide assistance.

    Kind regards.


  • Moderators

    @eureka Sorry if I misunderstood you. To me the OP's question is that she wants to know how to solve a particular problem with Qt3D. The Python library, matplotlib, you mentioned is something completly different. Matplotlib is for data plotting. Qt3D is a general purpose 3D graphics rendering framework. Like you said you had your own question: "... when to use Qt native classes vs. external python classes for data visualisation?" I split up the topics so that both questions could receive proper answers.


  • Moderators

    Hi @no-name! I was able to create a QGeometryRenderer derived class that generates a single triangle. The code is based on the tesselation modes example. Starting from this it should be easy to let it generate more complex geometries. A single word of warning: I made this with Qt 5.6.0 beta and the API has changed slightly compared to Qt 5.5.1. It's basically only about renaming some classes/namespaces but I'd recommend to use Qt 5.6.0 beta, too. The class I present here is called "QuadMesh" but it is actually a triangle! Sorry for the confusion ^_^. I'll only post the most important pieces but I can post a complete example if you want.

    main.cpp

    #include <QGuiApplication>
    #include <QtQml>
    
    #include "quadmesh.h"
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        qmlRegisterType<QuadMesh>("de.wplm.mesh", 1, 0, "QuadMesh");
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        return app.exec();
    }
    

    quadmesh.h

    #ifndef QUADMESH_H
    #define QUADMESH_H
    
    #include <Qt3DRender/qgeometryrenderer.h>
    
    class QuadMesh : public Qt3DRender::QGeometryRenderer
    {
        Q_OBJECT
    public:
        explicit QuadMesh(Qt3DCore::QNode *parent = 0);
        ~QuadMesh();
    };
    
    #endif // QUADMESH_H
    

    quadmesh.cpp

    #include "quadmesh.h"
    
    #include <Qt3DRender/qattribute.h>
    #include <Qt3DRender/qbuffer.h>
    #include <Qt3DRender/qgeometry.h>
    
    // begin: geometry class
    
    class QuadMeshGeometry : public Qt3DRender::QGeometry
    {
        Q_OBJECT
    public:
        QuadMeshGeometry(Qt3DCore::QNode *parent = Q_NULLPTR)
            : Qt3DRender::QGeometry(parent)
            , m_positionAttribute(new Qt3DRender::QAttribute(this))
            , m_vertexBuffer(new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, this))
        {
            const float positionData[] = {
                -0.8f, -0.8f, 0.0f,
                 0.8f, -0.8f, 0.0f,
                 0.8f,  0.8f, 0.0f //,
               // -0.8f,  0.8f, 0.0f
            };
    
            const int nVerts = 3;
            const int size = nVerts * 3 * sizeof(float);
            QByteArray positionBytes;
            positionBytes.resize(size);
            memcpy(positionBytes.data(), positionData, size);
    
            m_vertexBuffer->setData(positionBytes);
    
            m_positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
            m_positionAttribute->setDataType(Qt3DRender::QAttribute::Float);
            m_positionAttribute->setDataSize(3);
            m_positionAttribute->setCount(nVerts);
            m_positionAttribute->setByteStride(3 * sizeof(float));
            m_positionAttribute->setBuffer(m_vertexBuffer);
    
            //setVerticesPerPatch(3);
            addAttribute(m_positionAttribute);
        }
    
    private:
        Qt3DRender::QAttribute *m_positionAttribute;
        Qt3DRender::QBuffer *m_vertexBuffer;
    };
    
    // end: geometry class
    
    QuadMesh::QuadMesh(QNode *parent)
        : Qt3DRender::QGeometryRenderer(parent)
    {
        setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles); // !!!
        setGeometry(new QuadMeshGeometry(this));
    }
    
    QuadMesh::~QuadMesh()
    {
        QNode::cleanup();
    }
    
    #include "quadmesh.moc"
    

    In your qml files

    import de.wplm.mesh 1.0 // import QuadMesh
    // Scene3D, entity, etc...
    QuadMesh { //  QuadMesh instance
            id: mesh
    }
    

    Hope this helps!


  • Moderators

    Here are some more vertices that make up a small shell with 8 triangles:

            const float positionData[] = {
                0.0f, 0.0f, 0.3f,
                0.0f, 1.0f, 0.0f,
                1.0f, 0.0f, 0.0f,
    
                1.0f, 0.0f, 0.0f,
                1.0f, 1.0f, -0.3f,
                2.0f, 0.0f, 0.3f,
    
                0.0f, 1.0f, 0.0f,
                0.0f, 2.0f, 0.3f,
                1.0f, 1.0f, -0.3f,
    
                1.0f, 1.0f, -0.3f,
                1.0f, 2.0f, 0.0f,
                2.0f, 1.0f, 0.0f,
    
                1.0f, 0.0f, 0.0f,
                0.0f, 1.0f, 0.0f,
                1.0f, 1.0f, -0.3f,
    
                2.0f, 0.0f, 0.3f,
                1.0f, 1.0f, -0.3f,
                2.0f, 1.0f, 0.0f,
    
                1.0f, 1.0f, -0.3f,
                0.0f, 2.0f, 0.3f,
                1.0f, 2.0f, 0.0f,
    
                2.0f, 1.0f, 0.0f,
                1.0f, 2.0f, 0.0f,
                2.0f, 2.0f, 0.3f
            };
    
            const int nVerts = 8*3;
    

    The result looks like this:

    screenshot


Log in to reply
 

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