diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-09-23 13:57:47 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-09-24 09:50:51 +0300 |
commit | f842e21c7fa44d806c06a1463c723632b10e6172 (patch) | |
tree | 544b03ec20521c203a884cf74809972410532730 /src/datavisualization/data | |
parent | ac789c99ad04e5e907365d408d5f94df1685a668 (diff) |
Made surface axis ranges adjustable.
If the surface is partially off the visible range, only grids
that are fully within the visible range will be drawn.
If only one row or column is within visible range, surface is
not drawn.
Task-number: QTRD-2320
Change-Id: If2691577cde61dfd270d79c32b9d6f69984966ba
Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavisualization/data')
-rw-r--r-- | src/datavisualization/data/qheightmapsurfacedataproxy.cpp | 101 | ||||
-rw-r--r-- | src/datavisualization/data/qheightmapsurfacedataproxy_p.h | 4 | ||||
-rw-r--r-- | src/datavisualization/data/qsurfacedataproxy.cpp | 3 |
3 files changed, 62 insertions, 46 deletions
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp index 293eb9eb..f40fa395 100644 --- a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp +++ b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp @@ -82,7 +82,7 @@ QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(QObject *parent) : * \sa heightMap */ QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(const QImage &image, QObject *parent) : - QSurfaceDataProxy(new QHeightMapSurfaceDataProxyPrivate(this, image), parent) + QSurfaceDataProxy(new QHeightMapSurfaceDataProxyPrivate(this), parent) { setHeightMap(image); } @@ -118,50 +118,17 @@ QHeightMapSurfaceDataProxy::~QHeightMapSurfaceDataProxy() * grayscale images may improve data conversion speed for large images. * * Not recommended formats: all mono formats (for example QImage::Format_Mono). + * + * The height map is resolved asynchronously. QSurfaceDataProxy::arrayReset() is emitted when the + * data has been resolved. */ void QHeightMapSurfaceDataProxy::setHeightMap(const QImage &image) { dptr()->m_heightMap = image; - QImage heightImage = image; - // Convert to RGB32 to be sure we're reading the right bytes - if (heightImage.format() != QImage::Format_RGB32) - heightImage = image.convertToFormat(QImage::Format_RGB32); - - uchar *bits = heightImage.bits(); - - int imageHeight = heightImage.height(); - int imageWidth = heightImage.width(); - int bitCount = imageWidth * 4 * (imageHeight - 1); - int widthBits = imageWidth * 4; - qreal height = 0; - - QSurfaceDataArray *dataArray = new QSurfaceDataArray; - dataArray->reserve(imageHeight); - if (heightImage.isGrayscale()) { - // Grayscale, it's enough to read Red byte - for (int i = imageHeight; i > 0; i--, bitCount -= widthBits) { - QSurfaceDataRow *newRow = new QSurfaceDataRow(imageWidth); - for (int j = 0; j < imageWidth; j++) - (*newRow)[j] = qreal(bits[bitCount + (j * 4)]) + 0.1; // Add 0.1 to raise it above ground to avoid glimmering at 0 height - *dataArray << newRow; - } - } else { - // Not grayscale, we'll need to calculate height from RGB - for (int i = imageHeight; i > 0; i--, bitCount -= widthBits) { - QSurfaceDataRow *newRow = new QSurfaceDataRow(imageWidth); - for (int j = 0; j < imageWidth; j++) { - int nextpixel = j * 4; - height = (qreal(bits[bitCount + nextpixel]) - + qreal(bits[1 + bitCount + nextpixel]) - + qreal(bits[2 + bitCount + nextpixel])); - (*newRow)[j] = (height / 3.0) + 0.1; // Add 0.1 to raise it above ground to avoid glimmering at 0 height - } - *dataArray << newRow; - } - } - - resetArray(dataArray, 0.0, imageHeight, 0.0, imageWidth); + // We do resolving asynchronously to make qml onArrayReset handlers actually get the initial reset + if (!dptr()->m_resolveTimer.isActive()) + dptr()->m_resolveTimer.start(0); } QImage QHeightMapSurfaceDataProxy::heightMap() const @@ -210,17 +177,61 @@ const QHeightMapSurfaceDataProxyPrivate *QHeightMapSurfaceDataProxy::dptrc() con QHeightMapSurfaceDataProxyPrivate::QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q) : QSurfaceDataProxyPrivate(q) { + m_resolveTimer.setSingleShot(true); + QObject::connect(&m_resolveTimer, &QTimer::timeout, + this, &QHeightMapSurfaceDataProxyPrivate::handlePendingResolve); } -QHeightMapSurfaceDataProxyPrivate::QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q, - const QImage &image) - : QSurfaceDataProxyPrivate(q), - m_heightMap(image) +QHeightMapSurfaceDataProxyPrivate::~QHeightMapSurfaceDataProxyPrivate() { } -QHeightMapSurfaceDataProxyPrivate::~QHeightMapSurfaceDataProxyPrivate() +QHeightMapSurfaceDataProxy *QHeightMapSurfaceDataProxyPrivate::qptr() { + return static_cast<QHeightMapSurfaceDataProxy *>(q_ptr); +} + +void QHeightMapSurfaceDataProxyPrivate::handlePendingResolve() +{ + QImage heightImage = m_heightMap; + // Convert to RGB32 to be sure we're reading the right bytes + if (heightImage.format() != QImage::Format_RGB32) + heightImage = heightImage.convertToFormat(QImage::Format_RGB32); + + uchar *bits = heightImage.bits(); + + int imageHeight = heightImage.height(); + int imageWidth = heightImage.width(); + int bitCount = imageWidth * 4 * (imageHeight - 1); + int widthBits = imageWidth * 4; + qreal height = 0; + + QSurfaceDataArray *dataArray = new QSurfaceDataArray; + dataArray->reserve(imageHeight); + if (heightImage.isGrayscale()) { + // Grayscale, it's enough to read Red byte + for (int i = imageHeight; i > 0; i--, bitCount -= widthBits) { + QSurfaceDataRow *newRow = new QSurfaceDataRow(imageWidth); + for (int j = 0; j < imageWidth; j++) + (*newRow)[j] = qreal(bits[bitCount + (j * 4)]) + 0.1; // Add 0.1 to raise it above ground to avoid glimmering at 0 height + *dataArray << newRow; + } + } else { + // Not grayscale, we'll need to calculate height from RGB + for (int i = imageHeight; i > 0; i--, bitCount -= widthBits) { + QSurfaceDataRow *newRow = new QSurfaceDataRow(imageWidth); + for (int j = 0; j < imageWidth; j++) { + int nextpixel = j * 4; + height = (qreal(bits[bitCount + nextpixel]) + + qreal(bits[1 + bitCount + nextpixel]) + + qreal(bits[2 + bitCount + nextpixel])); + (*newRow)[j] = (height / 3.0) + 0.1; // Add 0.1 to raise it above ground to avoid glimmering at 0 height + } + *dataArray << newRow; + } + } + + qptr()->resetArray(dataArray, 0.0, imageHeight, 0.0, imageWidth); } QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h index 3cccb4ed..7140c8ef 100644 --- a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h +++ b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h @@ -31,6 +31,7 @@ #include "qheightmapsurfacedataproxy.h" #include "qsurfacedataproxy_p.h" +#include <QTimer> QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -40,14 +41,15 @@ class QHeightMapSurfaceDataProxyPrivate : public QSurfaceDataProxyPrivate public: QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q); - QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q, const QImage &image); virtual ~QHeightMapSurfaceDataProxyPrivate(); private: QHeightMapSurfaceDataProxy *qptr(); + void handlePendingResolve(); QImage m_heightMap; QString m_heightMapFile; + QTimer m_resolveTimer; friend class QHeightMapSurfaceDataProxy; }; diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp index 30cc84f1..bd3688dc 100644 --- a/src/datavisualization/data/qsurfacedataproxy.cpp +++ b/src/datavisualization/data/qsurfacedataproxy.cpp @@ -39,6 +39,9 @@ const qreal defaultMaxValue = 10.0; * * All rows must have same number of values. * + * \note Surfaces with less than two rows or columns are not considered valid surfaces and will + * not get rendered. + * * QSurfaceDataProxy supports the following format tags for QAbstractDataProxy::setItemLabelFormat(): * \table * \row |