1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Data Visualization module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL$
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 General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 or (at your option) any later version
20** approved by the KDE Free Qt Foundation. The licenses are as published by
21** the Free Software Foundation and appearing in the file LICENSE.GPL3
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#include "datasource.h"
31#include <QtCore/qmath.h>
32#include <QtCore/qrandom.h>
33
34using namespace QtDataVisualization;
35
36//! [3]
37Q_DECLARE_METATYPE(QSurface3DSeries *)
38//! [3]
39
40DataSource::DataSource(QObject *parent) :
41 QObject(parent),
42 m_index(-1),
43 m_resetArray(nullptr)
44{
45 //! [4]
46 qRegisterMetaType<QSurface3DSeries *>();
47 //! [4]
48}
49
50DataSource::~DataSource()
51{
52 clearData();
53}
54
55//! [0]
56void DataSource::generateData(int cacheCount, int rowCount, int columnCount,
57 float xMin, float xMax, float yMin, float yMax,
58 float zMin, float zMax)
59{
60 if (!cacheCount || !rowCount || !columnCount)
61 return;
62
63 clearData();
64 // Re-create the cache array
65 m_data.resize(asize: cacheCount);
66 for (int i(0); i < cacheCount; i++) {
67 QSurfaceDataArray &array = m_data[i];
68 array.reserve(alloc: rowCount);
69 for (int j(0); j < rowCount; j++)
70 array.append(t: new QSurfaceDataRow(columnCount));
71 }
72
73 float xRange = xMax - xMin;
74 float yRange = yMax - yMin;
75 float zRange = zMax - zMin;
76 int cacheIndexStep = columnCount / cacheCount;
77 float cacheStep = float(cacheIndexStep) * xRange / float(columnCount);
78
79 // Populate caches
80 for (int i(0); i < cacheCount; i++) {
81 QSurfaceDataArray &cache = m_data[i];
82 float cacheXAdjustment = cacheStep * i;
83 float cacheIndexAdjustment = cacheIndexStep * i;
84 for (int j(0); j < rowCount; j++) {
85 QSurfaceDataRow &row = *(cache[j]);
86 float rowMod = (float(j)) / float(rowCount);
87 float yRangeMod = yRange * rowMod;
88 float zRangeMod = zRange * rowMod;
89 float z = zRangeMod + zMin;
90 qreal rowColWaveAngleMul = M_PI * M_PI * rowMod;
91 float rowColWaveMul = yRangeMod * 0.2f;
92 for (int k(0); k < columnCount; k++) {
93 float colMod = (float(k)) / float(columnCount);
94 float xRangeMod = xRange * colMod;
95 float x = xRangeMod + xMin + cacheXAdjustment;
96 float colWave = float(qSin(v: (2.0 * M_PI * colMod) - (1.0 / 2.0 * M_PI)) + 1.0);
97 float y = (colWave * ((float(qSin(v: rowColWaveAngleMul * colMod) + 1.0))))
98 * rowColWaveMul
99 + QRandomGenerator::global()->bounded(highest: 0.15f) * yRangeMod;
100
101 int index = k + cacheIndexAdjustment;
102 if (index >= columnCount) {
103 // Wrap over
104 index -= columnCount;
105 x -= xRange;
106 }
107 row[index] = QVector3D(x, y, z);
108 }
109 }
110 }
111}
112//! [0]
113
114//! [1]
115void DataSource::update(QSurface3DSeries *series)
116{
117 if (series && m_data.size()) {
118 // Each iteration uses data from a different cached array
119 m_index++;
120 if (m_index > m_data.count() - 1)
121 m_index = 0;
122
123 QSurfaceDataArray array = m_data.at(i: m_index);
124 int newRowCount = array.size();
125 int newColumnCount = array.at(i: 0)->size();
126
127 // If the first time or the dimensions of the cache array have changed,
128 // reconstruct the reset array
129 if (!m_resetArray || series->dataProxy()->rowCount() != newRowCount
130 || series->dataProxy()->columnCount() != newColumnCount) {
131 m_resetArray = new QSurfaceDataArray();
132 m_resetArray->reserve(alloc: newRowCount);
133 for (int i(0); i < newRowCount; i++)
134 m_resetArray->append(t: new QSurfaceDataRow(newColumnCount));
135 }
136
137 // Copy items from our cache to the reset array
138 for (int i(0); i < newRowCount; i++) {
139 const QSurfaceDataRow &sourceRow = *(array.at(i));
140 QSurfaceDataRow &row = *(*m_resetArray)[i];
141 for (int j(0); j < newColumnCount; j++)
142 row[j].setPosition(sourceRow.at(i: j).position());
143 }
144
145 // Notify the proxy that data has changed
146 series->dataProxy()->resetArray(newArray: m_resetArray);
147 }
148}
149//! [1]
150
151void DataSource::clearData()
152{
153 for (int i(0); i < m_data.size(); i++) {
154 QSurfaceDataArray &array = m_data[i];
155 for (int j(0); j < array.size(); j++)
156 delete array[j];
157 array.clear();
158 }
159}
160

source code of qtdatavis3d/examples/datavisualization/qmloscilloscope/datasource.cpp