summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
diff options
context:
space:
mode:
authorTomi Korpipää <tomi.korpipaa@digia.com>2013-09-20 09:58:22 +0300
committerTomi Korpipää <tomi.korpipaa@digia.com>2013-09-20 10:01:25 +0300
commitd8662133def955c4aedf83e9b035fbece35a6710 (patch)
tree17400fb99e06ff5fef1029e1a47c5bbfc58da2cc /src/datavisualization/data/qheightmapsurfacedataproxy.cpp
parent61f323fde93cf105fb2c70c74cf756211e5aba4f (diff)
Surface: Implemented giving a height map via API
Task-number: QTRD-2273 Change-Id: Ib0c540d52711ced38421b744664de7eddd97b585 Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Diffstat (limited to 'src/datavisualization/data/qheightmapsurfacedataproxy.cpp')
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy.cpp226
1 files changed, 226 insertions, 0 deletions
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
new file mode 100644
index 00000000..293eb9eb
--- /dev/null
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qheightmapsurfacedataproxy_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class QHeightMapSurfaceDataProxy
+ * \inmodule QtDataVisualization
+ * \brief Proxy class for Q3DSurface.
+ * \since 1.0.0
+ *
+ * QHeightMapSurfaceDataProxy takes care of surface related height map data handling. It provides a
+ * way for giving the surface plot a height map to be visualized.
+ *
+ * \sa QSurfaceDataProxy
+ */
+
+/*!
+ * \qmltype HeightMapSurfaceDataProxy
+ * \instantiates QHeightMapSurfaceDataProxy
+ * \inherits SurfaceDataProxy
+ *
+ * HeightMapSurfaceDataProxy takes care of surface related height map data handling. It provides a
+ * way for giving the surface plot a height map to be visualized.
+ */
+
+/*!
+ * \qmlproperty image HeightMapSurfaceDataProxy::heightMap
+ *
+ * A height map to be visualized. Setting this property replaces current data with height map data.
+ *
+ * There are several formats the image can be given in, but if it is not in a directly usable
+ * format, a conversion is made. \note If the result seems wrong, the automatic conversion failed
+ * and you should try converting the image yourself before setting it. Preferred format is
+ * QImage::Format_RGB32 in grayscale.
+ *
+ * The height of the image is read from the red component of the pixels if the image is in grayscale,
+ * otherwise it is an average calculated from red, green and blue components of the pixels. Using
+ * grayscale images may improve data conversion speed for large images.
+ *
+ * Not recommended formats: all mono formats (for example QImage::Format_Mono).
+ */
+
+/*!
+ * \qmlproperty string HeightMapSurfaceDataProxy::heightMapFile
+ *
+ * A file with a height map image to be visualized. Setting this property replaces current data
+ * with height map data.
+ *
+ * \sa heightMap
+ */
+
+/*!
+ * Constructs QHeightMapSurfaceDataProxy with the given \a parent.
+ */
+QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(QObject *parent) :
+ QSurfaceDataProxy(new QHeightMapSurfaceDataProxyPrivate(this), parent)
+{
+}
+
+/*!
+ * Constructs QHeightMapSurfaceDataProxy with the given \a image and \a parent. Height map is set
+ * by calling setHeighMap() with \a image.
+ *
+ * \sa heightMap
+ */
+QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(const QImage &image, QObject *parent) :
+ QSurfaceDataProxy(new QHeightMapSurfaceDataProxyPrivate(this, image), parent)
+{
+ setHeightMap(image);
+}
+
+/*!
+ * \internal
+ */
+QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(
+ QHeightMapSurfaceDataProxyPrivate *d, QObject *parent) :
+ QSurfaceDataProxy(d, parent)
+{
+}
+
+/*!
+ * Destroys QHeightMapSurfaceDataProxy.
+ */
+QHeightMapSurfaceDataProxy::~QHeightMapSurfaceDataProxy()
+{
+}
+
+/*!
+ * \property QHeightMapSurfaceDataProxy::heightMap
+ *
+ * A height map to be visualized. Setting this property replaces current data with height map data.
+ *
+ * There are several formats the image can be given in, but if it is not in a directly usable
+ * format, a conversion is made. \note If the result seems wrong, the automatic conversion failed
+ * and you should try converting the image yourself before setting it. Preferred format is
+ * QImage::Format_RGB32 in grayscale.
+ *
+ * The height of the image is read from the red component of the pixels if the image is in grayscale,
+ * otherwise it is an average calculated from red, green and blue components of the pixels. Using
+ * grayscale images may improve data conversion speed for large images.
+ *
+ * Not recommended formats: all mono formats (for example QImage::Format_Mono).
+ */
+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);
+}
+
+QImage QHeightMapSurfaceDataProxy::heightMap() const
+{
+ return dptrc()->m_heightMap;
+}
+
+/*!
+ * \property QHeightMapSurfaceDataProxy::heightMapFile
+ *
+ * A file with a height map image to be visualized. Setting this property replaces current data
+ * with height map data.
+ *
+ * \sa heightMap
+ */
+void QHeightMapSurfaceDataProxy::setHeightMapFile(const QString &filename)
+{
+ dptr()->m_heightMapFile = filename;
+ setHeightMap(QImage(filename));
+}
+
+QString QHeightMapSurfaceDataProxy::heightMapFile() const
+{
+ return dptrc()->m_heightMapFile;
+}
+/*!
+ * \internal
+ */
+QHeightMapSurfaceDataProxyPrivate *QHeightMapSurfaceDataProxy::dptr()
+{
+ return static_cast<QHeightMapSurfaceDataProxyPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \internal
+ */
+const QHeightMapSurfaceDataProxyPrivate *QHeightMapSurfaceDataProxy::dptrc() const
+{
+ return static_cast<const QHeightMapSurfaceDataProxyPrivate *>(d_ptr.data());
+}
+
+//
+// QHeightMapSurfaceDataProxyPrivate
+//
+
+QHeightMapSurfaceDataProxyPrivate::QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q)
+ : QSurfaceDataProxyPrivate(q)
+{
+}
+
+QHeightMapSurfaceDataProxyPrivate::QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q,
+ const QImage &image)
+ : QSurfaceDataProxyPrivate(q),
+ m_heightMap(image)
+{
+}
+
+QHeightMapSurfaceDataProxyPrivate::~QHeightMapSurfaceDataProxyPrivate()
+{
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE