1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from math import sin, pi
from PySide6.QtCore import QObject, QRandomGenerator, Slot
from PySide6.QtQml import QmlElement
from PySide6.QtGui import QVector3D
from PySide6.QtDataVisualization import QSurfaceDataItem, QSurface3DSeries
QML_IMPORT_NAME = "SurfaceGallery"
QML_IMPORT_MAJOR_VERSION = 1
@QmlElement
class DataSource(QObject):
def __init__(self, parent=None):
super().__init__(parent)
self.m_index = -1
self.m_resetArray = None
self.m_data = []
@Slot(int, int, int, float, float, float, float, float, float)
def generateData(self, cacheCount, rowCount, columnCount,
xMin, xMax, yMin, yMax, zMin, zMax):
if not cacheCount or not rowCount or not columnCount:
return
self.clearData()
xRange = xMax - xMin
yRange = yMax - yMin
zRange = zMax - zMin
cacheIndexStep = columnCount / cacheCount
cacheStep = float(cacheIndexStep) * xRange / float(columnCount)
# Populate caches
self.m_data = []
rand_gen = QRandomGenerator.global_()
for i in range(0, cacheCount):
cache = []
cacheXAdjustment = cacheStep * i
cacheIndexAdjustment = cacheIndexStep * i
for j in range(0, rowCount):
row = []
rowMod = (float(j)) / float(rowCount)
yRangeMod = yRange * rowMod
zRangeMod = zRange * rowMod
z = zRangeMod + zMin
rowColWaveAngleMul = pi * pi * rowMod
rowColWaveMul = yRangeMod * 0.2
for k in range(0, columnCount):
colMod = (float(k)) / float(columnCount)
xRangeMod = xRange * colMod
x = xRangeMod + xMin + cacheXAdjustment
colWave = sin((2.0 * pi * colMod) - (1.0 / 2.0 * pi)) + 1.0
rand_nr = rand_gen.generateDouble() * 0.15
y = ((colWave * ((sin(rowColWaveAngleMul * colMod) + 1.0)))
* rowColWaveMul + rand_nr * yRangeMod)
index = k + cacheIndexAdjustment
if index >= columnCount:
# Wrap over
index -= columnCount
x -= xRange
row.append(QSurfaceDataItem(QVector3D(x, y, z)))
cache.append(row)
self.m_data.append(cache)
@Slot(QSurface3DSeries)
def update(self, series):
if series and self.m_data:
# Each iteration uses data from a different cached array
self.m_index += 1
if self.m_index > len(self.m_data) - 1:
self.m_index = 0
array = self.m_data[self.m_index]
newRowCount = len(array)
newColumnCount = len(array[0])
# Copy items from our cache to the reset array
self.m_resetArray = []
for i in range(0, newRowCount):
sourceRow = array[i]
row = []
for j in range(0, newColumnCount):
row.append(QSurfaceDataItem(sourceRow[j].position()))
self.m_resetArray.append(row)
# Notify the proxy that data has changed
series.dataProxy().resetArray(self.m_resetArray)
@Slot()
def clearData(self):
self.m_data = []
|