-
Notifications
You must be signed in to change notification settings - Fork 92
Description
The purpose of this issue is educational. I am still learning both Qt and QMetaObject-rs.
I studied the Graph example and tried to recreate Qt's BezierCurve example in Rust (https://doc.qt.io/qt-5/qtquick-scenegraph-customgeometry-example.html). The more I look into it, the more I am convinced that at the moment it is not possible to recreate this example without writing C++, I would love to be wrong, however.
In theory, all this example requires is a Rust struct with reimplemented update_paint_node().
The C++ version of this method is as follows:
QSGNode *BezierCurve::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
QSGGeometryNode *node = nullptr;
QSGGeometry *geometry = nullptr;
if (!oldNode) {
node = new QSGGeometryNode;
geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), m_segmentCount);
geometry->setLineWidth(2);
geometry->setDrawingMode(QSGGeometry::DrawLineStrip);
node->setGeometry(geometry);
node->setFlag(QSGNode::OwnsGeometry);
QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
material->setColor(QColor(255, 0, 0));
node->setMaterial(material);
node->setFlag(QSGNode::OwnsMaterial);
} else {
node = static_cast<QSGGeometryNode *>(oldNode);
geometry = node->geometry();
geometry->allocate(m_segmentCount);
}
QSizeF itemSize = size();
QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D();
for (int i = 0; i < m_segmentCount; ++i) {
qreal t = i / qreal(m_segmentCount - 1);
qreal invt = 1 - t;
QPointF pos = invt * invt * invt * m_p1
+ 3 * invt * invt * t * m_p2
+ 3 * invt * t * t * m_p3
+ t * t * t * m_p4;
float x = pos.x() * itemSize.width();
float y = pos.y() * itemSize.height();
vertices[i].set(x, y);
}
node->markDirty(QSGNode::DirtyGeometry);
return node;
}
Upon reviewing the source of SGNode::update_static and SGNode::update_dynamic I understood that both functions take care of the condition when the oldNode is empty or not empty.
If I understand correctly, I could go past the if statement from the code above directly to drawing. To be able to draw, I would need to have access to geometry. This is where things are becoming less clear to me. I see that there is some code regarding Geometry in the scenegraph module, however it is commented out. Therefore I understand that currently there's no way to create custom Geometry in Rust. If that's true, then I need to follow the same structure as in the Graph example - write my own Nodes in C++ and interface them from Rust.
Is my understanding correct?
Essentially, what I am trying to do, after understanding how it all works and what's possible right now, is to create my own Canvas (a QQuickItem), where I can draw shapes (also QQuickItems - children of the Canvas). I would like to define all these elements in Rust, because I don't really know C++ and C++'s build system is beyond my comprehension at the moment...
I would be happy to help out with exposing Geometry nodes from Qt to Rust, if some guidance was offered.
Thank you