diff options
author | Tomi Korpipää <tomi.korpipaa@digia.com> | 2013-09-20 09:58:22 +0300 |
---|---|---|
committer | Tomi Korpipää <tomi.korpipaa@digia.com> | 2013-09-20 10:01:25 +0300 |
commit | d8662133def955c4aedf83e9b035fbece35a6710 (patch) | |
tree | 17400fb99e06ff5fef1029e1a47c5bbfc58da2cc /src | |
parent | 61f323fde93cf105fb2c70c74cf756211e5aba4f (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')
7 files changed, 352 insertions, 1 deletions
diff --git a/src/datavisualization/data/data.pri b/src/datavisualization/data/data.pri index 6571aacc..f5a283e7 100644 --- a/src/datavisualization/data/data.pri +++ b/src/datavisualization/data/data.pri @@ -28,6 +28,8 @@ HEADERS += \ $$PWD/scatteritemmodelhandler_p.h \ $$PWD/qsurfacedataproxy.h \ $$PWD/qsurfacedataproxy_p.h \ + $$PWD/qheightmapsurfacedataproxy.h \ + $$PWD/qheightmapsurfacedataproxy_p.h \ $$PWD/qitemmodelsurfacedatamapping.h \ $$PWD/qitemmodelsurfacedatamapping_p.h \ $$PWD/qitemmodelsurfacedataproxy.h \ @@ -53,6 +55,7 @@ SOURCES += \ $$PWD/qabstractdatamapping.cpp \ $$PWD/scatteritemmodelhandler.cpp \ $$PWD/qsurfacedataproxy.cpp \ + $$PWD/qheightmapsurfacedataproxy.cpp \ $$PWD/qitemmodelsurfacedatamapping.cpp \ $$PWD/qitemmodelsurfacedataproxy.cpp \ $$PWD/surfaceitemmodelhandler.cpp 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 diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.h b/src/datavisualization/data/qheightmapsurfacedataproxy.h new file mode 100644 index 00000000..8ca9f502 --- /dev/null +++ b/src/datavisualization/data/qheightmapsurfacedataproxy.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** 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 +** +****************************************************************************/ + +#ifndef QHEIGHTMAPSURFACEDATAPROXY_H +#define QHEIGHTMAPSURFACEDATAPROXY_H + +#include <QtDataVisualization/qsurfacedataproxy.h> + +#include <QImage> + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +class QHeightMapSurfaceDataProxyPrivate; + +class QT_DATAVISUALIZATION_EXPORT QHeightMapSurfaceDataProxy : public QSurfaceDataProxy +{ + Q_OBJECT + + Q_PROPERTY(QImage heightMap READ heightMap WRITE setHeightMap) + Q_PROPERTY(QString heightMapFile READ heightMapFile WRITE setHeightMapFile) + +public: + explicit QHeightMapSurfaceDataProxy(QObject *parent = 0); + explicit QHeightMapSurfaceDataProxy(const QImage &image, QObject *parent = 0); + virtual ~QHeightMapSurfaceDataProxy(); + + void setHeightMap(const QImage &image); + QImage heightMap() const; + + void setHeightMapFile(const QString &filename); + QString heightMapFile() const; + +protected: + explicit QHeightMapSurfaceDataProxy(QHeightMapSurfaceDataProxyPrivate *d, QObject *parent = 0); + QHeightMapSurfaceDataProxyPrivate *dptr(); + const QHeightMapSurfaceDataProxyPrivate *dptrc() const; + +private: + Q_DISABLE_COPY(QHeightMapSurfaceDataProxy) + + friend class Surface3DController; +}; + +QT_DATAVISUALIZATION_END_NAMESPACE + +#endif diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h new file mode 100644 index 00000000..3cccb4ed --- /dev/null +++ b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** 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 +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVisualization API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QHEIGHTMAPSURFACEDATAPROXY_P_H +#define QHEIGHTMAPSURFACEDATAPROXY_P_H + +#include "qheightmapsurfacedataproxy.h" +#include "qsurfacedataproxy_p.h" + +QT_DATAVISUALIZATION_BEGIN_NAMESPACE + +class QHeightMapSurfaceDataProxyPrivate : public QSurfaceDataProxyPrivate +{ + Q_OBJECT + +public: + QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q); + QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q, const QImage &image); + virtual ~QHeightMapSurfaceDataProxyPrivate(); + +private: + QHeightMapSurfaceDataProxy *qptr(); + + QImage m_heightMap; + QString m_heightMapFile; + + friend class QHeightMapSurfaceDataProxy; +}; + +QT_DATAVISUALIZATION_END_NAMESPACE + +#endif diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index e93b3a2c..e64928eb 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -242,6 +242,7 @@ QRect Surface3DRenderer::calculateSampleRect(QSurfaceDataProxy *dataProxy) QRect sampleSpace(0, 0, dataProxy->columnCount(), dataProxy->rowCount()); // TODO: Calculate the actual sample rect, for now it is required data and axis ranges are the same +#if 0 if (m_axisCacheX.min() != dataProxy->minValueColumns() || m_axisCacheX.max() != dataProxy->maxValueColumns() || m_axisCacheZ.min() != dataProxy->minValueRows() || m_axisCacheZ.max() != dataProxy->maxValueRows()) { qWarning() << "Warning: Technology preview doesn't support axis ranges that are different from data ranges -" @@ -250,7 +251,7 @@ QRect Surface3DRenderer::calculateSampleRect(QSurfaceDataProxy *dataProxy) << m_axisCacheZ.min() << dataProxy->minValueRows() << "-" << m_axisCacheZ.max() << dataProxy->maxValueRows(); } - +#endif return sampleSpace; } diff --git a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp index 83c9eaf8..3a700d1d 100644 --- a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp +++ b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp @@ -54,6 +54,7 @@ void Datavis3Dqml2Plugin::registerTypes(const char *uri) qmlRegisterType<QItemModelBarDataProxy>(uri, 1, 0, "ItemModelBarDataProxy"); qmlRegisterType<QItemModelScatterDataProxy>(uri, 1, 0, "ItemModelScatterDataProxy"); qmlRegisterType<QItemModelSurfaceDataProxy>(uri, 1, 0, "ItemModelSurfaceDataProxy"); + qmlRegisterType<QHeightMapSurfaceDataProxy>(uri, 1, 0, "HeightMapSurfaceDataProxy"); } QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualizationqml2/datavisualizationqml2_plugin.h b/src/datavisualizationqml2/datavisualizationqml2_plugin.h index 543afb9c..530b8fd2 100644 --- a/src/datavisualizationqml2/datavisualizationqml2_plugin.h +++ b/src/datavisualizationqml2/datavisualizationqml2_plugin.h @@ -29,6 +29,7 @@ #include "qitemmodelbardataproxy.h" #include "qitemmodelscatterdataproxy.h" #include "qitemmodelsurfacedataproxy.h" +#include "qheightmapsurfacedataproxy.h" #include "q3dvalueaxis.h" #include "q3dcategoryaxis.h" @@ -59,6 +60,7 @@ Q_DECLARE_METATYPE(QScatterDataProxy *) Q_DECLARE_METATYPE(QItemModelScatterDataProxy *) Q_DECLARE_METATYPE(QSurfaceDataProxy *) Q_DECLARE_METATYPE(QItemModelSurfaceDataProxy *) +Q_DECLARE_METATYPE(QHeightMapSurfaceDataProxy *) QT_DATAVISUALIZATION_BEGIN_NAMESPACE |