1/****************************************************************************
2**
3** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt3D module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qgeometry.h"
41#include "qgeometryfactory.h"
42#include "qgeometry_p.h"
43#include <private/qnode_p.h>
44#include <Qt3DRender/qattribute.h>
45#include <Qt3DCore/qpropertyupdatedchange.h>
46
47QT_BEGIN_NAMESPACE
48
49using namespace Qt3DCore;
50
51namespace Qt3DRender {
52
53QGeometryFactory::~QGeometryFactory()
54{
55}
56
57QGeometryPrivate::QGeometryPrivate()
58 : QNodePrivate(),
59 m_boundingVolumePositionAttribute(nullptr)
60{
61}
62
63QGeometryPrivate::~QGeometryPrivate()
64{
65}
66
67/*!
68 \qmltype Geometry
69 \instantiates Qt3DRender::QGeometry
70 \inqmlmodule Qt3D.Render
71 \inherits Node
72 \since 5.7
73 \brief Encapsulates geometry.
74
75 A Geometry type is used to group a list of Attribute objects together
76 to form a geometric shape Qt3D is able to render using GeometryRenderer.
77 Special attribute can be set in order to calculate bounding volume of the shape.
78 */
79
80/*!
81 \class Qt3DRender::QGeometry
82 \inmodule Qt3DRender
83 \since 5.7
84 \brief Encapsulates geometry.
85
86 A Qt3DRender::QGeometry class is used to group a list of Qt3DRender::QAttribute
87 objects together to form a geometric shape Qt3D is able to render using
88 Qt3DRender::QGeometryRenderer. Special attribute can be set in order to calculate
89 bounding volume of the shape.
90 */
91
92/*!
93 \qmlproperty Attribute Geometry::boundingVolumePositionAttribute
94
95 Holds the attribute used to compute the bounding volume. The bounding volume is used internally
96 for picking and view frustum culling.
97
98 If unspecified, the system will look for the attribute using the name returned by
99 QAttribute::defaultPositionAttributeName.
100
101 \sa Attribute
102 */
103/*!
104 \qmlproperty list<Attribute> Geometry::attributes
105
106 Holds the list of attributes the geometry comprises of.
107 */
108
109/*!
110 \property QGeometry::boundingVolumePositionAttribute
111
112 Holds the attribute used to compute the bounding volume. The bounding volume is used internally
113 for picking and view frustum culling.
114
115 If unspecified, the system will look for the attribute using the name returned by
116 QAttribute::defaultPositionAttributeName.
117
118 \sa Qt3DRender::QAttribute
119 */
120
121
122/*!
123 Constructs a new QGeometry with \a parent.
124 */
125QGeometry::QGeometry(QNode *parent)
126 : QGeometry(*new QGeometryPrivate(), parent) {}
127
128/*!
129 \fn Qt3DRender::QGeometryFactory::operator()()
130
131 Returns the generated geometry.
132*/
133/*!
134 \fn bool Qt3DRender::QGeometryFactory::operator==(const QGeometryFactory &other) const = 0
135
136 Compares the factory with the factory specified in \a other.
137 Returns true if they are equal.
138*/
139/*!
140 \internal
141 */
142QGeometry::~QGeometry()
143{
144}
145
146/*!
147 \internal
148 */
149QGeometry::QGeometry(QGeometryPrivate &dd, QNode *parent)
150 : QNode(dd, parent)
151{
152}
153
154void QGeometry::sceneChangeEvent(const QSceneChangePtr &change)
155{
156 Q_D(QGeometry);
157 QPropertyUpdatedChangePtr e = qSharedPointerCast<QPropertyUpdatedChange>(src: change);
158 if (e->type() == PropertyUpdated) {
159 const bool blocked = blockNotifications(block: true);
160 if (e->propertyName() == QByteArrayLiteral("extent")) {
161 const QPair<QVector3D, QVector3D> extent = e->value().value<QPair<QVector3D, QVector3D>>();
162
163 if (extent.first != d->m_minExtent) {
164 d->m_minExtent = extent.first;
165 emit minExtentChanged(minExtent: extent.first);
166 }
167 if (extent.second != d->m_maxExtent) {
168 d->m_maxExtent = extent.second;
169 emit maxExtentChanged(maxExtent: d->m_maxExtent);
170 }
171 }
172 blockNotifications(block: blocked);
173 }
174}
175
176/*!
177 \fn void Qt3DRender::QGeometry::addAttribute(Qt3DRender::QAttribute *attribute)
178 Adds an \a attribute to this geometry.
179 */
180void QGeometry::addAttribute(QAttribute *attribute)
181{
182 Q_ASSERT(attribute);
183 Q_D(QGeometry);
184 if (!d->m_attributes.contains(t: attribute)) {
185 d->m_attributes.append(t: attribute);
186
187 // Ensures proper bookkeeping
188 d->registerDestructionHelper(node: attribute, func: &QGeometry::removeAttribute, d->m_attributes);
189
190 // We need to add it as a child of the current node if it has been declared inline
191 // Or not previously added as a child of the current node so that
192 // 1) The backend gets notified about it's creation
193 // 2) When the current node is destroyed, it gets destroyed as well
194 if (!attribute->parent())
195 attribute->setParent(this);
196
197 d->updateNode(node: attribute, property: "attribute", change: Qt3DCore::PropertyValueAdded);
198 }
199}
200
201/*!
202 \fn void Qt3DRender::QGeometry::removeAttribute(Qt3DRender::QAttribute *attribute)
203 Removes the given \a attribute from this geometry.
204 */
205void QGeometry::removeAttribute(QAttribute *attribute)
206{
207 Q_ASSERT(attribute);
208 Q_D(QGeometry);
209 if (!d->m_attributes.removeOne(t: attribute))
210 return;
211 // Remove bookkeeping connection
212 d->unregisterDestructionHelper(node: attribute);
213 d->updateNode(node: attribute, property: "attribute", change: Qt3DCore::PropertyValueRemoved);
214}
215
216void QGeometry::setBoundingVolumePositionAttribute(QAttribute *boundingVolumePositionAttribute)
217{
218 Q_D(QGeometry);
219 if (d->m_boundingVolumePositionAttribute != boundingVolumePositionAttribute) {
220 d->m_boundingVolumePositionAttribute = boundingVolumePositionAttribute;
221 emit boundingVolumePositionAttributeChanged(boundingVolumePositionAttribute);
222 }
223}
224
225QAttribute *QGeometry::boundingVolumePositionAttribute() const
226{
227 Q_D(const QGeometry);
228 return d->m_boundingVolumePositionAttribute;
229}
230
231/*!
232 \qmlproperty vector3d Geometry::minExtent
233
234 Holds the vertex with the lowest x, y, z position values.
235 */
236
237/*!
238 \property QGeometry::minExtent
239
240 Holds the vertex with the lowest x, y, z position values.
241 */
242QVector3D QGeometry::minExtent() const
243{
244 Q_D(const QGeometry);
245 return d->m_minExtent;
246}
247
248/*!
249 \qmlproperty vector3d Geometry::maxExtent
250
251 Holds the vertex with the highest x, y, z position values.
252 */
253
254/*!
255 \property QGeometry::maxExtent
256
257 Holds the vertex with the highest x, y, z position values.
258 */
259QVector3D QGeometry::maxExtent() const
260{
261 Q_D(const QGeometry);
262 return d->m_maxExtent;
263}
264
265/*!
266 Returns the list of attributes in this geometry.
267 */
268QVector<QAttribute *> QGeometry::attributes() const
269{
270 Q_D(const QGeometry);
271 return d->m_attributes;
272}
273
274Qt3DCore::QNodeCreatedChangeBasePtr QGeometry::createNodeCreationChange() const
275{
276 auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QGeometryData>::create(arguments: this);
277 auto &data = creationChange->data;
278 Q_D(const QGeometry);
279 data.attributeIds = qIdsForNodes(nodes: d->m_attributes);
280 data.boundingVolumePositionAttributeId = qIdForNode(node: d->m_boundingVolumePositionAttribute);
281 return creationChange;
282}
283
284} // namespace Qt3DRender
285
286QT_END_NAMESPACE
287
288#include "moc_qgeometry.cpp"
289

source code of qt3d/src/render/geometry/qgeometry.cpp