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
-
@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.
-
@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.
-
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!
-
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: