Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qquickshapestrokenode.cpp
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6
8
10{
11 setFlag(OwnsGeometry, true);
13 updateMaterial();
14}
15
16void QQuickShapeStrokeNode::QQuickShapeStrokeNode::updateMaterial()
17{
18 m_material.reset(new QQuickShapeStrokeMaterial(this));
19 setMaterial(m_material.data());
20}
21
22// Find the parameters H, G for the depressed cubic
23// t^2+H*t+G=0
24// that results from the equation
25// Q'(s).(p-Q(s)) = 0
26// The last parameter is the static offset between s and t:
27// s = t - b/(3a)
28// use it to get back the parameter t
29QVector3D QQuickShapeStrokeNode::HGforPoint(QVector2D q_a, QVector2D q_b, QVector2D q_c, QVector2D p)
30{
31 // this is a constant for the curve
32 float a = -2. * QVector2D::dotProduct(q_a, q_a);
33 // this is a constant for the curve
34 float b = -3. * QVector2D::dotProduct(q_a, q_b);
35 //this is linear in p so it can be put into the shader with vertex data
36 float c = 2. * QVector2D::dotProduct(q_a, p) - QVector2D::dotProduct(q_b, q_b) - 2. * QVector2D::dotProduct(q_a, q_c);
37 //this is linear in p so it can be put into the shader with vertex data
38 float d = QVector2D::dotProduct(q_b,p) - QVector2D::dotProduct(q_b, q_c);
39 // convert to depressed cubic.
40 // both functions are linear in c and d and thus linear in p
41 // Put in vertex data.
42 float H = (3. * a * c - b * b) / (3. * a * a);
43 float G = (2. * b * b * b - 9. * a * b * c + 27. * a * a * d) / (27. * a * a * a);
44
45 return QVector3D(H, G, b/(3*a));
46}
47
48// Take the start, control and end point of a curve and return the points A, B, C
49// representing the curve as Q(s) = A*s*s + B*s + C
50std::array<QVector2D, 3> QQuickShapeStrokeNode::curveABC(QVector2D p0, QVector2D p1, QVector2D p2)
51{
52 QVector2D a = p0 - 2*p1 + p2;
53 QVector2D b = 2*p1 - 2*p0;
54 QVector2D c = p0;
55
56 return {a, b, c};
57}
58
60 const QVector2D &p0, const QVector2D &p1, const QVector2D &p2)
61{
62 auto abc = curveABC(p0, p1, p2);
63
64 int currentVertex = m_uncookedVertexes.count();
65
66 for (auto p : QList<QVector2D>({v0, v1, v2})) {
67 auto hg = HGforPoint(abc[0], abc[1], abc[2], p);
68
69 m_uncookedVertexes.append( { p.x(), p.y(),
70 abc[0].x(), abc[0].y(), abc[1].x(), abc[1].y(), abc[2].x(), abc[2].y(),
71 hg.x(), hg.y(),
72 hg.z()} );
73 }
74 m_uncookedIndexes << currentVertex << currentVertex + 1 << currentVertex + 2;
75}
76
78 const QVector2D &p0, const QVector2D &p1)
79{
80 // We could reduce this to a linear equation by setting A to (0,0).
81 // However, then we cannot use the cubic solution and need an additional
82 // code path in the shader. The following formulation looks more complicated
83 // but allows to always use the cubic solution.
84 auto A = p1 - p0;
85 auto B = QVector2D(0., 0.);
86 auto C = p0;
87
88 int currentVertex = m_uncookedVertexes.count();
89
90 for (auto p : QList<QVector2D>({v0, v1, v2})) {
91 auto hg = HGforPoint(A, B, C, p);
92 m_uncookedVertexes.append( { p.x(), p.y(),
93 A.x(), A.y(), B.x(), B.y(), C.x(), C.y(),
94 hg.x(), hg.y(),
95 hg.z()} );
96 }
97 m_uncookedIndexes << currentVertex << currentVertex + 1 << currentVertex + 2;
98}
99
101{
103 if (g->indexType() != QSGGeometry::UnsignedIntType) {
104 g = new QSGGeometry(attributes(),
105 m_uncookedVertexes.size(),
106 m_uncookedIndexes.size(),
108 setGeometry(g);
109 } else {
110 g->allocate(m_uncookedVertexes.size(), m_uncookedIndexes.size());
111 }
112
113 g->setDrawingMode(QSGGeometry::DrawTriangles);
114 memcpy(g->vertexData(),
115 m_uncookedVertexes.constData(),
116 g->vertexCount() * g->sizeOfVertex());
117 memcpy(g->indexData(),
118 m_uncookedIndexes.constData(),
119 g->indexCount() * g->sizeOfIndex());
120
121 m_uncookedIndexes.clear();
122 m_uncookedVertexes.clear();
123}
124
126{
127 static QSGGeometry::Attribute data[] = {
134
135 };
136 static QSGGeometry::AttributeSet attrs = { 6, sizeof(StrokeVertex), data };
137 return attrs;
138}
139
Definition qlist.h:74
void appendTriangle(const QVector2D &v0, const QVector2D &v1, const QVector2D &v2, const QVector2D &p0, const QVector2D &p1, const QVector2D &p2)
QVector< StrokeVertex > m_uncookedVertexes
static const QSGGeometry::AttributeSet & attributes()
QVector< quint32 > m_uncookedIndexes
const QSGGeometry * geometry() const
Returns this node's geometry.
Definition qsgnode.h:160
void setGeometry(QSGGeometry *geometry)
Sets the geometry of this node to geometry.
Definition qsgnode.cpp:762
The QSGGeometry class provides low-level storage for graphics primitives in the \l{Qt Quick Scene Gra...
Definition qsggeometry.h:15
@ OwnsGeometry
Definition qsgnode.h:57
void setFlag(Flag, bool=true)
Sets the flag f on this node if enabled is true; otherwise clears the flag.
Definition qsgnode.cpp:584
The QVector2D class represents a vector or vertex in 2D space.
Definition qvectornd.h:31
static constexpr float dotProduct(QVector2D v1, QVector2D v2) noexcept
Returns the dot product of v1 and v2.
Definition qvectornd.h:604
The QVector3D class represents a vector or vertex in 3D space.
Definition qvectornd.h:171
QPixmap p2
QPixmap p1
[0]
Combined button and popup list for selecting options.
static struct AttrInfo attrs[]
n varying highp vec2 A
GLint GLfloat GLfloat GLfloat v2
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLint GLfloat v0
GLint GLfloat GLfloat v1
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLboolean GLboolean g
const GLubyte * c
GLfloat GLfloat p
[1]
#define v1
#define v0
The QSGGeometry::AttributeSet describes how the vertices in a QSGGeometry are built up.
Definition qsggeometry.h:73
The QSGGeometry::Attribute describes a single vertex attribute in a QSGGeometry.
Definition qsggeometry.h:58
static Attribute createWithAttributeType(int pos, int tupleSize, int primitiveType, AttributeType attributeType)
Creates a new QSGGeometry::Attribute for attribute register pos with tupleSize.