QT3D, Lines and AtCore
2017-07-02[ atcore atelier kde qt3d ]
After some time working with Qt3D, now Atelier project is one step closer to have a 3D viewer from the GCode and a realtime draw of printer work.
To know how Qt3D works, you can take a look in this overview. Where, working with 3D lines was a bit problematic, but I hope to help someone with this job.
Rendering
To render, we need our mesh and the material. This simple cube have something more than 1300 lines, and if you are thinking about it, you can can handle big models like this Dragon Head with around 706000 lines in 60fps.
Mesh
It's done with a C++ code, where a 4D vector is used to perform the buffer population, the 4D is because a 3D printer have 4 dimensions in a actuation space, (X, Y, Z and E) where E is the extruder that move the filament to perform the extrusion.
LineMeshGeometry::LineMeshGeometry(QList<QVector4D> vertices, Qt3DCore::QNode *parent) :
Qt3DRender::QGeometry(parent)
, _positionAttribute(new Qt3DRender::QAttribute(this))
, _vertexBuffer(new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, this))
{
QByteArray vertexBufferData;
vertexBufferData.resize(vertices.size() * 3 * sizeof(float));
float *rawVertexArray = reinterpret_cast<float *>(vertexBufferData.data());
int idx = 0;
for (const auto &v : vertices) {
rawVertexArray[idx++] = v.x();
rawVertexArray[idx++] = v.y();
rawVertexArray[idx++] = v.z();
_vertices.append(v.toVector3D());
}
_vertexBuffer->setData(vertexBufferData);
_positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
_positionAttribute->setBuffer(_vertexBuffer);
_positionAttribute->setDataType(Qt3DRender::QAttribute::Float);
_positionAttribute->setDataSize(3);
_positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
addAttribute(_positionAttribute);
}
int LineMeshGeometry::vertexCount()
{
return _vertices.size();
}
With this done, it's possible to easy populate it with a simple class.
LineMesh::LineMesh(Qt3DCore::QNode *parent) :
Qt3DRender::QGeometryRenderer(parent)
, _lineMeshGeo(nullptr)
{
setInstanceCount(1);
setIndexOffset(0);
setFirstInstance(0);
// This will allow the line visualization
setPrimitiveType(Qt3DRender::QGeometryRenderer::LineStrip);
// This will be visualized in qml
qRegisterMetaType<QList<QVector4D> >("QList<QVector4D>");
auto gcode = new GcodeTo3D();
connect(gcode, &GcodeTo3D::posFinished, this, &LineMesh::posUpdate);
}
void LineMesh::posUpdate(QList<QVector4D> pos)
{
_vertices = pos;
_lineMeshGeo = new LineMeshGeometry(_vertices, this);
setVertexCount(_lineMeshGeo->vertexCount());
setGeometry(_lineMeshGeo);
emit finished();
}
Material and Entity
The material used in the first GIF was PhongMaterial, this is simple done with:
PhongMaterial {
id: lineMaterial
ambient: "darkGreen"
}
And in the end, the creation of an Entity.
LineMesh {
id: lineMesh
enabled: true
}
Entity {
id: lineEntity
components: [ lineMesh, lineMaterial ]
}
In the next week we plan to finish our simple 3D viwer and add it in AtCore test GUI.\ For more info about AtCore and Atelier click here !