summaryrefslogtreecommitdiffstats
path: root/src/datavisualization
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2013-09-30 11:06:58 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2013-10-01 09:03:24 +0300
commit822a19d3e2650c7a9326b69ff4621ccd556e16cc (patch)
tree064fba99ba0e4ec7a3113c5fb051d3cd50972360 /src/datavisualization
parent52fcca463e63500bea81b0ac3615d4779bc7682c (diff)
Refactor surface data item to have X, Y, and Z values.
Task-number: QTRD-2332 Change-Id: I086d3a422ff444cbcede1aa238107ebcbce68729 Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Diffstat (limited to 'src/datavisualization')
-rw-r--r--src/datavisualization/data/data.pri7
-rw-r--r--src/datavisualization/data/qbardataitem.cpp10
-rw-r--r--src/datavisualization/data/qbardataitem.h4
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy.cpp253
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy.h14
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy_p.h10
-rw-r--r--src/datavisualization/data/qscatterdataitem.cpp10
-rw-r--r--src/datavisualization/data/qscatterdataitem.h10
-rw-r--r--src/datavisualization/data/qsurfacedataitem.cpp113
-rw-r--r--src/datavisualization/data/qsurfacedataitem.h59
-rw-r--r--src/datavisualization/data/qsurfacedataitem_p.h51
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.cpp307
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.h20
-rw-r--r--src/datavisualization/data/qsurfacedataproxy_p.h18
-rw-r--r--src/datavisualization/data/surfaceitemmodelhandler.cpp40
-rw-r--r--src/datavisualization/engine/bars3drenderer.cpp2
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp194
-rw-r--r--src/datavisualization/engine/surface3drenderer_p.h18
-rw-r--r--src/datavisualization/utils/surfaceobject.cpp57
-rw-r--r--src/datavisualization/utils/surfaceobject_p.h4
20 files changed, 705 insertions, 496 deletions
diff --git a/src/datavisualization/data/data.pri b/src/datavisualization/data/data.pri
index f5a283e7..770d2bd1 100644
--- a/src/datavisualization/data/data.pri
+++ b/src/datavisualization/data/data.pri
@@ -34,7 +34,9 @@ HEADERS += \
$$PWD/qitemmodelsurfacedatamapping_p.h \
$$PWD/qitemmodelsurfacedataproxy.h \
$$PWD/qitemmodelsurfacedataproxy_p.h \
- $$PWD/surfaceitemmodelhandler_p.h
+ $$PWD/surfaceitemmodelhandler_p.h \
+ $$PWD/qsurfacedataitem.h \
+ $$PWD/qsurfacedataitem_p.h
SOURCES += \
$$PWD/labelitem.cpp \
@@ -58,4 +60,5 @@ SOURCES += \
$$PWD/qheightmapsurfacedataproxy.cpp \
$$PWD/qitemmodelsurfacedatamapping.cpp \
$$PWD/qitemmodelsurfacedataproxy.cpp \
- $$PWD/surfaceitemmodelhandler.cpp
+ $$PWD/surfaceitemmodelhandler.cpp \
+ $$PWD/qsurfacedataitem.cpp
diff --git a/src/datavisualization/data/qbardataitem.cpp b/src/datavisualization/data/qbardataitem.cpp
index 01bcfd1c..2803c01a 100644
--- a/src/datavisualization/data/qbardataitem.cpp
+++ b/src/datavisualization/data/qbardataitem.cpp
@@ -81,20 +81,14 @@ QBarDataItem &QBarDataItem::operator=(const QBarDataItem &other)
}
/*!
+ * \fn void QBarDataItem::setValue(qreal value)
* Sets \a value to this data item.
*/
-void QBarDataItem::setValue(qreal value)
-{
- m_value = value;
-}
/*!
+ * \fn qreal QBarDataItem::value() const
* \return value of this data item.
*/
-qreal QBarDataItem::value() const
-{
- return m_value;
-}
/*!
* \internal
diff --git a/src/datavisualization/data/qbardataitem.h b/src/datavisualization/data/qbardataitem.h
index 683120b2..68bbcedf 100644
--- a/src/datavisualization/data/qbardataitem.h
+++ b/src/datavisualization/data/qbardataitem.h
@@ -35,8 +35,8 @@ public:
QBarDataItem &operator=(const QBarDataItem &other);
- void setValue(qreal value);
- qreal value() const;
+ void setValue(qreal value) { m_value = value; }
+ qreal value() const { return m_value; }
// TODO Set color, label format, ...?
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
index c0b0723c..05b44a17 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
@@ -20,6 +20,10 @@
QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+// Default ranges correspond value axis defaults
+const float defaultMinValue = 0.0f;
+const float defaultMaxValue = 10.0f;
+
/*!
* \class QHeightMapSurfaceDataProxy
* \inmodule QtDataVisualization
@@ -29,6 +33,11 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
* 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.
*
+ * Since height maps do not contain values for X or Z axes, those values need to be given
+ * separately using minXValue, maxXValue, minZValue, and maxZValue properties. X-value corresponds
+ * to image horizontal direction and Z-value to the vertical. Setting any of these
+ * properties triggers asynchronous re-resolving of any existing height map.
+ *
* \sa QSurfaceDataProxy
*/
@@ -55,6 +64,11 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
* 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.
*
+ * Since height maps do not contain values for X or Z axes, those values need to be given
+ * separately using minXValue, maxXValue, minZValue, and maxZValue properties. X-value corresponds
+ * to image horizontal direction and Z-value to the vertical. Setting any of these
+ * properties triggers asynchronous re-resolving of any existing height map.
+ *
* Not recommended formats: all mono formats (for example QImage::Format_Mono).
*/
@@ -68,6 +82,38 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
*/
/*!
+ * \qmlproperty qreal HeightMapSurfaceDataProxy::minXValue
+ *
+ * The minimum X value for the generated surface points.
+ * When setting this property the corresponding maximum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+
+/*!
+ * \qmlproperty qreal HeightMapSurfaceDataProxy::maxXValue
+ *
+ * The maximum X value for the generated surface points.
+ * When setting this property the corresponding minimum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+
+/*!
+ * \qmlproperty qreal HeightMapSurfaceDataProxy::minZValue
+ *
+ * The minimum Z value for the generated surface points.
+ * When setting this property the corresponding maximum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+
+/*!
+ * \qmlproperty qreal HeightMapSurfaceDataProxy::maxZValue
+ *
+ * The maximum Z value for the generated surface points.
+ * When setting this property the corresponding minimum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+
+/*!
* Constructs QHeightMapSurfaceDataProxy with the given \a parent.
*/
QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(QObject *parent) :
@@ -154,6 +200,85 @@ QString QHeightMapSurfaceDataProxy::heightMapFile() const
{
return dptrc()->m_heightMapFile;
}
+
+/*!
+ * A convenience function for setting all minimum and maximum values at the same time
+ * The minimum values must be smaller than the corresponding maximum value. Otherwise
+ * the values get adjusted so that they are valid.
+ */
+void QHeightMapSurfaceDataProxy::setValueRanges(float minX, float maxX, float minZ, float maxZ)
+{
+ dptr()->setValueRanges(minX, maxX, minZ, maxZ);
+}
+
+/*!
+ * \property QHeightMapSurfaceDataProxy::minXValue
+ *
+ * The minimum X value for the generated surface points.
+ * When setting this property the corresponding maximum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+void QHeightMapSurfaceDataProxy::setMinXValue(float min)
+{
+ dptr()->setMinXValue(min);
+}
+
+float QHeightMapSurfaceDataProxy::minXValue() const
+{
+ return dptrc()->m_minXValue;
+}
+
+/*!
+ * \property QHeightMapSurfaceDataProxy::maxXValue
+ *
+ * The maximum X value for the generated surface points.
+ * When setting this property the corresponding minimum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+void QHeightMapSurfaceDataProxy::setMaxXValue(float max)
+{
+ dptr()->setMaxXValue(max);
+}
+
+float QHeightMapSurfaceDataProxy::maxXValue() const
+{
+ return dptrc()->m_maxXValue;
+}
+
+/*!
+ * \property QHeightMapSurfaceDataProxy::minZValue
+ *
+ * The minimum Z value for the generated surface points.
+ * When setting this property the corresponding maximum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+void QHeightMapSurfaceDataProxy::setMinZValue(float min)
+{
+ dptr()->setMinZValue(min);
+}
+
+float QHeightMapSurfaceDataProxy::minZValue() const
+{
+ return dptrc()->m_minZValue;
+}
+
+/*!
+ * \property QHeightMapSurfaceDataProxy::maxZValue
+ *
+ * The maximum Z value for the generated surface points.
+ * When setting this property the corresponding minimum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+void QHeightMapSurfaceDataProxy::setMaxZValue(float max)
+{
+ dptr()->setMaxZValue(max);
+}
+
+float QHeightMapSurfaceDataProxy::maxZValue() const
+{
+ return dptrc()->m_maxZValue;
+}
+
/*!
* \internal
*/
@@ -175,7 +300,11 @@ const QHeightMapSurfaceDataProxyPrivate *QHeightMapSurfaceDataProxy::dptrc() con
//
QHeightMapSurfaceDataProxyPrivate::QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q)
- : QSurfaceDataProxyPrivate(q)
+ : QSurfaceDataProxyPrivate(q),
+ m_minXValue(defaultMinValue),
+ m_maxXValue(defaultMaxValue),
+ m_minZValue(defaultMinValue),
+ m_maxZValue(defaultMaxValue)
{
m_resolveTimer.setSingleShot(true);
QObject::connect(&m_resolveTimer, &QTimer::timeout,
@@ -191,6 +320,109 @@ QHeightMapSurfaceDataProxy *QHeightMapSurfaceDataProxyPrivate::qptr()
return static_cast<QHeightMapSurfaceDataProxy *>(q_ptr);
}
+void QHeightMapSurfaceDataProxyPrivate::setValueRanges(float minX, float maxX, float minZ, float maxZ)
+{
+ bool changed = false;
+ if (m_minXValue != minX || m_minZValue != minZ) {
+ m_minXValue = minX;
+ m_minZValue = minZ;
+ changed = true;
+ }
+ if (m_maxXValue != maxX || minX >= maxX) {
+ if (minX >= maxX) {
+ m_maxXValue = minX + 1.0;
+ qWarning() << "Warning: Tried to set invalid range for X value range."
+ " Range automatically adjusted to a valid one:"
+ << minX << "-" << maxX << "-->" << m_minXValue << "-" << m_maxXValue;
+ } else {
+ m_maxXValue = maxX;
+ }
+ changed = true;
+ }
+ if (m_maxZValue != maxZ || minZ >= maxZ) {
+ if (minZ >= maxZ) {
+ m_maxZValue = minZ + 1.0;
+ qWarning() << "Warning: Tried to set invalid range for Z value range."
+ " Range automatically adjusted to a valid one:"
+ << minZ << "-" << maxZ << "-->" << m_minZValue << "-" << m_maxZValue;
+ } else {
+ m_maxZValue = maxZ;
+ }
+ changed = true;
+ }
+
+ if (changed && !m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+}
+
+void QHeightMapSurfaceDataProxyPrivate::setMinXValue(float min)
+{
+ if (min != m_minXValue) {
+ if (min >= m_maxXValue) {
+ qreal oldMax = m_maxXValue;
+ m_maxXValue = min + 1.0;
+ qWarning() << "Warning: Tried to set minimum X to equal or larger than maximum X for"
+ " value range. Maximum automatically adjusted to a valid one:"
+ << oldMax << "-->" << m_maxXValue;
+ }
+ m_minXValue = min;
+
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+ }
+}
+
+void QHeightMapSurfaceDataProxyPrivate::setMaxXValue(float max)
+{
+ if (m_maxXValue != max) {
+ if (max <= m_minXValue) {
+ qreal oldMin = m_minXValue;
+ m_minXValue = max - 1.0;
+ qWarning() << "Warning: Tried to set maximum X to equal or smaller than minimum X for"
+ " value range. Minimum automatically adjusted to a valid one:"
+ << oldMin << "-->" << m_minXValue;
+ }
+ m_maxXValue = max;
+
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+ }
+}
+
+void QHeightMapSurfaceDataProxyPrivate::setMinZValue(float min)
+{
+ if (min != m_minZValue) {
+ if (min >= m_maxZValue) {
+ qreal oldMax = m_maxZValue;
+ m_maxZValue = min + 1.0;
+ qWarning() << "Warning: Tried to set minimum Z to equal or larger than maximum Z for"
+ " value range. Maximum automatically adjusted to a valid one:"
+ << oldMax << "-->" << m_maxZValue;
+ }
+ m_minZValue = min;
+
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+ }
+}
+
+void QHeightMapSurfaceDataProxyPrivate::setMaxZValue(float max)
+{
+ if (m_maxZValue != max) {
+ if (max <= m_minZValue) {
+ qreal oldMin = m_minZValue;
+ m_minZValue = max - 1.0;
+ qWarning() << "Warning: Tried to set maximum Z to equal or smaller than minimum Z for"
+ " value range. Minimum automatically adjusted to a valid one:"
+ << oldMin << "-->" << m_minZValue;
+ }
+ m_maxZValue = max;
+
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+ }
+}
+
void QHeightMapSurfaceDataProxyPrivate::handlePendingResolve()
{
QImage heightImage = m_heightMap;
@@ -204,7 +436,7 @@ void QHeightMapSurfaceDataProxyPrivate::handlePendingResolve()
int imageWidth = heightImage.width();
int bitCount = imageWidth * 4 * (imageHeight - 1);
int widthBits = imageWidth * 4;
- qreal height = 0;
+ float height = 0;
// Do not recreate array if dimensions have not changed
QSurfaceDataArray *dataArray = m_dataArray;
@@ -217,12 +449,16 @@ void QHeightMapSurfaceDataProxyPrivate::handlePendingResolve()
}
}
+ float xMul = (m_maxXValue - m_minXValue) / float(imageWidth - 1);
+ float zMul = (m_maxZValue - m_minZValue) / float(imageHeight - 1);
+
if (heightImage.isGrayscale()) {
// Grayscale, it's enough to read Red byte
for (int i = 0; i < imageHeight; i++, bitCount -= widthBits) {
QSurfaceDataRow &newRow = *dataArray->at(i);
for (int j = 0; j < imageWidth; j++)
- newRow[j] = qreal(bits[bitCount + (j * 4)]);
+ newRow[j].setPosition(QVector3D((float(j) * xMul) + m_minXValue, float(bits[bitCount + (j * 4)]),
+ (float(i) * zMul) + m_minZValue));
}
} else {
// Not grayscale, we'll need to calculate height from RGB
@@ -230,15 +466,16 @@ void QHeightMapSurfaceDataProxyPrivate::handlePendingResolve()
QSurfaceDataRow &newRow = *dataArray->at(i);
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;
+ height = (float(bits[bitCount + nextpixel])
+ + float(bits[1 + bitCount + nextpixel])
+ + float(bits[2 + bitCount + nextpixel]));
+ newRow[j].setPosition(QVector3D((float(j) * xMul) + m_minXValue, height / 3.0f,
+ (float(i) * zMul) + m_minZValue));
}
}
}
- qptr()->resetArray(dataArray, 0.0, imageHeight, 0.0, imageWidth);
+ qptr()->resetArray(dataArray);
}
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.h b/src/datavisualization/data/qheightmapsurfacedataproxy.h
index 8ca9f502..3306059f 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy.h
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy.h
@@ -33,6 +33,10 @@ class QT_DATAVISUALIZATION_EXPORT QHeightMapSurfaceDataProxy : public QSurfaceDa
Q_PROPERTY(QImage heightMap READ heightMap WRITE setHeightMap)
Q_PROPERTY(QString heightMapFile READ heightMapFile WRITE setHeightMapFile)
+ Q_PROPERTY(float minXValue READ minXValue WRITE setMinXValue)
+ Q_PROPERTY(float maxXValue READ maxXValue WRITE setMaxXValue)
+ Q_PROPERTY(float minZValue READ minZValue WRITE setMinZValue)
+ Q_PROPERTY(float maxZValue READ maxZValue WRITE setMaxZValue)
public:
explicit QHeightMapSurfaceDataProxy(QObject *parent = 0);
@@ -45,6 +49,16 @@ public:
void setHeightMapFile(const QString &filename);
QString heightMapFile() const;
+ void setValueRanges(float minX, float maxX, float minZ, float maxZ);
+ void setMinXValue(float min);
+ float minXValue() const;
+ void setMaxXValue(float max);
+ float maxXValue() const;
+ void setMinZValue(float min);
+ float minZValue() const;
+ void setMaxZValue(float max);
+ float maxZValue() const;
+
protected:
explicit QHeightMapSurfaceDataProxy(QHeightMapSurfaceDataProxyPrivate *d, QObject *parent = 0);
QHeightMapSurfaceDataProxyPrivate *dptr();
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
index 7140c8ef..2d773344 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
@@ -43,6 +43,11 @@ public:
QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q);
virtual ~QHeightMapSurfaceDataProxyPrivate();
+ void setValueRanges(float minX, float maxX, float minZ, float maxZ);
+ void setMinXValue(float min);
+ void setMaxXValue(float max);
+ void setMinZValue(float min);
+ void setMaxZValue(float max);
private:
QHeightMapSurfaceDataProxy *qptr();
void handlePendingResolve();
@@ -51,6 +56,11 @@ private:
QString m_heightMapFile;
QTimer m_resolveTimer;
+ float m_minXValue;
+ float m_maxXValue;
+ float m_minZValue;
+ float m_maxZValue;
+
friend class QHeightMapSurfaceDataProxy;
};
diff --git a/src/datavisualization/data/qscatterdataitem.cpp b/src/datavisualization/data/qscatterdataitem.cpp
index b331e03b..3de5bbd7 100644
--- a/src/datavisualization/data/qscatterdataitem.cpp
+++ b/src/datavisualization/data/qscatterdataitem.cpp
@@ -84,20 +84,14 @@ QScatterDataItem &QScatterDataItem::operator=(const QScatterDataItem &other)
}
/*!
+ * \fn void QScatterDataItem::setPosition(const QVector3D &position)
* Sets \a position to this data item.
*/
-void QScatterDataItem::setPosition(const QVector3D &position)
-{
- m_position = position;
-}
/*!
+ * \fn QVector3D QScatterDataItem::position() const
* \return position of this data item.
*/
-QVector3D QScatterDataItem::position() const
-{
- return m_position;
-}
//void QScatterDataItem::setSize(qreal size)
//{
diff --git a/src/datavisualization/data/qscatterdataitem.h b/src/datavisualization/data/qscatterdataitem.h
index 42a27e92..29154259 100644
--- a/src/datavisualization/data/qscatterdataitem.h
+++ b/src/datavisualization/data/qscatterdataitem.h
@@ -36,8 +36,14 @@ public:
QScatterDataItem &operator=(const QScatterDataItem &other);
- void setPosition(const QVector3D &position);
- QVector3D position() const;
+ inline void setPosition(const QVector3D &position) { m_position = position; }
+ inline QVector3D position() const { return m_position; }
+ inline void setX(float value) { m_position.setX(value); }
+ inline void setY(float value) { m_position.setY(value); }
+ inline void setZ(float value) { m_position.setZ(value); }
+ inline float x() const { return m_position.x(); }
+ inline float y() const { return m_position.y(); }
+ inline float z() const { return m_position.z(); }
//void setSize(qreal size);
//qreal size() const;
diff --git a/src/datavisualization/data/qsurfacedataitem.cpp b/src/datavisualization/data/qsurfacedataitem.cpp
new file mode 100644
index 00000000..3fb21c95
--- /dev/null
+++ b/src/datavisualization/data/qsurfacedataitem.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** 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 "qsurfacedataitem_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class QSurfaceDataItem
+ * \inmodule QtDataVisualization
+ * \brief The QSurfaceDataItem class provides a container for resolved data to be added to surface
+ * graphs.
+ * \since 1.0.0
+ *
+ * A QSurfaceDataItem holds data for a single vertex in surface graph.
+ * Surface data proxies parse data into QSurfaceDataItem instances for visualizing.
+ *
+ * \sa QSurfaceDataProxy, {Qt Data Visualization C++ Classes}
+ */
+
+/*!
+ * Constructs QSurfaceDataItem.
+ */
+QSurfaceDataItem::QSurfaceDataItem()
+ : d_ptr(0) // private data doesn't exist by default (optimization)
+
+{
+}
+
+/*!
+ * Constructs QSurfaceDataItem with \a position.
+ */
+QSurfaceDataItem::QSurfaceDataItem(const QVector3D &position)
+ : d_ptr(0),
+ m_position(position)
+{
+}
+
+/*!
+ * Constructs a copy of \a other.
+ */
+QSurfaceDataItem::QSurfaceDataItem(const QSurfaceDataItem &other)
+{
+ operator=(other);
+}
+
+/*!
+ * Destroys QSurfaceDataItem.
+ */
+QSurfaceDataItem::~QSurfaceDataItem()
+{
+}
+
+/*!
+ * Assigns a copy of \a other to this object.
+ */
+QSurfaceDataItem &QSurfaceDataItem::operator=(const QSurfaceDataItem &other)
+{
+ m_position = other.m_position;
+ //m_size = other.m_size;
+
+ if (other.d_ptr)
+ createExtraData();
+ else
+ d_ptr = 0;
+ // TODO set extra data
+
+ return *this;
+}
+
+/*!
+ * \fn void QSurfaceDataItem::setPosition(const QVector3D &position)
+ * Sets \a position to this data item.
+ */
+
+/*!
+ * \fn QVector3D QSurfaceDataItem::position() const
+ * \return position of this data item.
+ */
+
+/*!
+ * \internal
+ */
+void QSurfaceDataItem::createExtraData()
+{
+ if (!d_ptr)
+ d_ptr = new QSurfaceDataItemPrivate;
+}
+
+QSurfaceDataItemPrivate::QSurfaceDataItemPrivate()
+{
+}
+
+QSurfaceDataItemPrivate::~QSurfaceDataItemPrivate()
+{
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/qsurfacedataitem.h b/src/datavisualization/data/qsurfacedataitem.h
new file mode 100644
index 00000000..dbc849d3
--- /dev/null
+++ b/src/datavisualization/data/qsurfacedataitem.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** 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 QSURFACEDATAITEM_H
+#define QSURFACEDATAITEM_H
+
+#include <QtDataVisualization/qdatavisualizationenums.h>
+#include <QVector3D>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QSurfaceDataItemPrivate;
+
+class QT_DATAVISUALIZATION_EXPORT QSurfaceDataItem
+{
+public:
+ QSurfaceDataItem();
+ QSurfaceDataItem(const QVector3D &position);
+ QSurfaceDataItem(const QSurfaceDataItem &other);
+ ~QSurfaceDataItem();
+
+ QSurfaceDataItem &operator=(const QSurfaceDataItem &other);
+
+ inline void setPosition(const QVector3D &position) { m_position = position; }
+ inline QVector3D position() const { return m_position; }
+ inline void setX(float value) { m_position.setX(value); }
+ inline void setY(float value) { m_position.setY(value); }
+ inline void setZ(float value) { m_position.setZ(value); }
+ inline float x() const { return m_position.x(); }
+ inline float y() const { return m_position.y(); }
+ inline float z() const { return m_position.z(); }
+
+protected:
+ virtual void createExtraData();
+
+ QSurfaceDataItemPrivate *d_ptr;
+
+private:
+ QVector3D m_position;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualization/data/qsurfacedataitem_p.h b/src/datavisualization/data/qsurfacedataitem_p.h
new file mode 100644
index 00000000..d13679a8
--- /dev/null
+++ b/src/datavisualization/data/qsurfacedataitem_p.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** 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 QSURFACEDATAITEM_P_H
+#define QSURFACEDATAITEM_P_H
+
+#include "datavisualizationglobal_p.h"
+#include "qsurfacedataitem.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QSurfaceDataItemPrivate
+{
+public:
+ QSurfaceDataItemPrivate();
+ virtual ~QSurfaceDataItemPrivate();
+
+ // TODO stores other data for surface items besides position
+
+protected:
+ friend class QSurfaceDataItem;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp
index 3b683bbc..f1351521 100644
--- a/src/datavisualization/data/qsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qsurfacedataproxy.cpp
@@ -21,10 +21,6 @@
QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-// Default ranges correspond value axis defaults
-const qreal defaultMinValue = 0.0;
-const qreal defaultMaxValue = 10.0;
-
/*!
* \class QSurfaceDataProxy
* \inmodule QtDataVisualization
@@ -33,17 +29,19 @@ const qreal defaultMaxValue = 10.0;
*
* QSurfaceDataProxy takes care of surface related data handling. The QSurfaceDataProxy handles the data
* in rows and for this it provides two auxiliary typedefs. QSurfaceDataArray is a QList for
- * controlling the rows. For rows there is a QVector typedef QSurfaceDataRow which takes in qreal
- * values. See Q3DSurface documentation and basic sample code there how to feed the data for the
+ * controlling the rows. For rows there is a QVector QSurfaceDataRow which contains QSurfaceDataItem
+ * objects. See Q3DSurface documentation and basic sample code there how to feed the data for the
* QSurfaceDataProxy.
*
- * All rows must have same number of values.
+ * All rows must have same number of items.
+ *
+ * When determining what rows and columns are visible, the first item in each row and the first item in
+ * each column determine if the whole row or column is visible, even if other items in the row or column
+ * individually have different X- or Z-coordinates.
*
* \note Surfaces with less than two rows or columns are not considered valid surfaces and will
* not get rendered.
*
- * \note The way row and column values are handled is subject to change after technology preview.
- *
* QSurfaceDataProxy supports the following format tags for QAbstractDataProxy::setItemLabelFormat():
* \table
* \row
@@ -84,42 +82,6 @@ const qreal defaultMaxValue = 10.0;
*/
/*!
- * \qmlproperty qreal QSurfaceDataProxy::minValueRows
- *
- * The minimum value of the range in rows. For instance if function z value varies between -8.0
- * and 8.0 set this property to -8.0.
- *
- * \note The way row and column values are handled is subject to change after technology preview.
- */
-
-/*!
- * \qmlproperty qreal QSurfaceDataProxy::maxValueRows
- *
- * The maximum value of the range in rows. For instance if function z value varies between -8.0
- * and 8.0 set this property to 8.0.
- *
- * \note The way row and column values are handled is subject to change after technology preview.
- */
-
-/*!
- * \qmlproperty qreal QSurfaceDataProxy::minValueColumns
- *
- * The minimum value of the range in columns. For instance if function x value varies between -8.0
- * and 8.0 set this property to -8.0.
- *
- * \note The way row and column values are handled is subject to change after technology preview.
- */
-
-/*!
- * \qmlproperty qreal QSurfaceDataProxy::maxValueColumns
- *
- * The maximum value of the range in columns. For instance if function x value varies between -8.0
- * and 8.0 set this property to 8.0.
- *
- * \note The way row and column values are handled is subject to change after technology preview.
- */
-
-/*!
* Constructs QSurfaceDataProxy with the given \a parent.
*/
QSurfaceDataProxy::QSurfaceDataProxy(QObject *parent) :
@@ -148,36 +110,16 @@ QSurfaceDataProxy::~QSurfaceDataProxy()
* signal.
* Passing null array deletes the old array and creates a new empty array.
* All rows in \a newArray must be of same length.
- * Row and column ranges are reset to defaults, unless \a newArray is the same as the old array.
- * In that case, old row and column ranges are kept.
*/
void QSurfaceDataProxy::resetArray(QSurfaceDataArray *newArray)
{
if (dptr()->m_dataArray != newArray) {
- dptr()->resetArray(newArray, defaultMinValue, defaultMaxValue, defaultMinValue,
- defaultMaxValue);
+ dptr()->resetArray(newArray);
}
emit arrayReset();
}
/*!
- * Takes ownership of the \a newArray. Clears the existing array and if the \a newArray is
- * different than the existing array. If it's the same array, this just triggers arrayReset()
- * signal and updates row/column values.
- * Passing null array deletes the old array and creates a new empty array.
- * All rows in \a newArray must be of same length.
- * Row and column ranges are set to values defined by the rest of the parameters: \a minValueRows,
- * \a maxValueRows, \a minValueColumns, and \a maxValueColumns.
- */
-void QSurfaceDataProxy::resetArray(QSurfaceDataArray *newArray, qreal minValueRows,
- qreal maxValueRows, qreal minValueColumns,
- qreal maxValueColumns)
-{
- dptr()->resetArray(newArray, minValueRows, maxValueRows, minValueColumns, maxValueColumns);
- emit arrayReset();
-}
-
-/*!
* \return pointer to the data array.
*/
const QSurfaceDataArray *QSurfaceDataProxy::array() const
@@ -241,110 +183,13 @@ const QSurfaceDataProxyPrivate *QSurfaceDataProxy::dptrc() const
* emit this signal yourself or the graph won't get updated.
*/
-/*!
- * Sets the value range for rows from \a min to \a max. For instance if function z value varies between -8.0
- * and 8.0 set \a min to -8.0 and \a max to 8.0.
- * When setting the range, the max is adjusted if necessary, to ensure that the range remains valid.
- */
-void QSurfaceDataProxy::setValueRangeRows(qreal min, qreal max)
-{
- dptr()->setValueRangeRows(min, max);
-}
-
-/*!
- * Sets the value range for columns from \a min to \a max. For instance if function x value varies between -8.0
- * and 8.0 set \a min to -8.0 and \a max to 8.0.
- * When setting the range, the max is adjusted if necessary, to ensure that the range remains valid.
- */
-void QSurfaceDataProxy::setValueRangeColumns(qreal min, qreal max)
-{
- dptr()->setValueRangeColumns(min, max);
-}
-
-/*!
- * \property QSurfaceDataProxy::minValueRows
- *
- * Defines the minimum value of the range for rows. For instance if function z value varies between -8.0
- * and 8.0 set this property to -8.0.
- * When setting this property the max is adjusted if necessary, to ensure that the range remains
- * valid.
- */
-void QSurfaceDataProxy::setMinValueRows(qreal min)
-{
- dptr()->setMinValueRows(min);
-}
-
-qreal QSurfaceDataProxy::minValueRows() const
-{
- return dptrc()->m_minValueRows;
-}
-
-/*!
- * \property QSurfaceDataProxy::maxValueRows
- *
- * Defines the maximum value of the range for rows. For instance if function z value varies between -8.0
- * and 8.0 set this property to 8.0.
- * When setting this property the min is adjusted if necessary, to ensure that the range remains
- * valid.
- */
-void QSurfaceDataProxy::setMaxValueRows(qreal max)
-{
- dptr()->setMaxValueRows(max);
-}
-
-qreal QSurfaceDataProxy::maxValueRows() const
-{
- return dptrc()->m_maxValueRows;
-}
-
-/*!
- * \property QSurfaceDataProxy::minValueColumns
- *
- * Defines the minimum value of the range for columns. For instance if function x value varies between -8.0
- * and 8.0 set this property to -8.0.
- * When setting this property the min is adjusted if necessary, to ensure that the range remains
- * valid.
- */
-void QSurfaceDataProxy::setMinValueColumns(qreal min)
-{
- dptr()->setMinValueColumns(min);
-}
-
-qreal QSurfaceDataProxy::minValueColumns() const
-{
- return dptrc()->m_minValueColumns;
-}
-
-/*!
- * \property QSurfaceDataProxy::maxValueColumns
- *
- * Defines the maximum value of the range for columns. For instance if function x value varies between -8.0
- * and 8.0 set this property to 8.0.
- * When setting this property the min is adjusted if necessary, to ensure that the range remains
- * valid.
- */
-void QSurfaceDataProxy::setMaxValueColumns(qreal max)
-{
- dptr()->setMaxValueColumns(max);
-}
-
-qreal QSurfaceDataProxy::maxValueColumns() const
-{
- return dptrc()->m_maxValueColumns;
-}
-
-
//
// QSurfaceDataProxyPrivate
//
QSurfaceDataProxyPrivate::QSurfaceDataProxyPrivate(QSurfaceDataProxy *q)
: QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeSurface),
- m_dataArray(new QSurfaceDataArray),
- m_minValueRows(defaultMinValue),
- m_maxValueRows(defaultMaxValue),
- m_minValueColumns(defaultMinValue),
- m_maxValueColumns(defaultMaxValue)
+ m_dataArray(new QSurfaceDataArray)
{
m_itemLabelFormat = QStringLiteral("@yLabel (@xLabel, @zLabel)");
}
@@ -354,9 +199,7 @@ QSurfaceDataProxyPrivate::~QSurfaceDataProxyPrivate()
clearArray();
}
-void QSurfaceDataProxyPrivate::resetArray(QSurfaceDataArray *newArray, qreal minValueRows,
- qreal maxValueRows, qreal minValueColumns,
- qreal maxValueColumns)
+void QSurfaceDataProxyPrivate::resetArray(QSurfaceDataArray *newArray)
{
if (!newArray)
newArray = new QSurfaceDataArray;
@@ -365,115 +208,6 @@ void QSurfaceDataProxyPrivate::resetArray(QSurfaceDataArray *newArray, qreal min
clearArray();
m_dataArray = newArray;
}
-
- setValueRangeRows(minValueRows, maxValueRows);
- setValueRangeColumns(minValueColumns, maxValueColumns);
-}
-
-void QSurfaceDataProxyPrivate::setValueRangeRows(qreal min, qreal max)
-{
- bool changed = false;
- if (m_minValueRows != min) {
- m_minValueRows = min;
- changed = true;
- }
- if (m_maxValueRows != max || min >= max) {
- if (min >= max) {
- m_maxValueRows = min + 1.0;
- qWarning() << "Warning: Tried to set invalid range for value range."
- " Range automatically adjusted to a valid one:"
- << min << "-" << max << "-->" << m_minValueRows << "-" << m_maxValueRows;
- } else {
- m_maxValueRows = max;
- }
- changed = true;
- }
-
- if (changed)
- emit qptr()->valueRangeRowsChanged(min, max);
-}
-
-void QSurfaceDataProxyPrivate::setValueRangeColumns(qreal min, qreal max)
-{
- bool changed = false;
- if (m_minValueColumns != min) {
- m_minValueColumns = min;
- changed = true;
- }
- if (m_maxValueColumns != max || min >= max) {
- if (min >= max) {
- m_maxValueColumns = min + 1.0;
- qWarning() << "Warning: Tried to set invalid range for value range."
- " Range automatically adjusted to a valid one:"
- << min << "-" << max << "-->" << m_minValueColumns << "-" << m_maxValueColumns;
- } else {
- m_maxValueColumns = max;
- }
- changed = true;
- }
-
- if (changed)
- emit qptr()->valueRangeColumnsChanged(min, max);
-}
-
-void QSurfaceDataProxyPrivate::setMinValueRows(qreal min)
-{
- if (min != m_minValueRows) {
- if (min >= m_maxValueRows) {
- qreal oldMax = m_maxValueRows;
- m_maxValueRows = min + 1.0;
- qWarning() << "Warning: Tried to set minimum to equal or larger than maximum for"
- " value range. Maximum automatically adjusted to a valid one:"
- << oldMax << "-->" << m_maxValueRows;
- }
- m_minValueRows = min;
- emit qptr()->valueRangeRowsChanged(m_minValueRows, m_maxValueRows);
- }
-}
-
-void QSurfaceDataProxyPrivate::setMaxValueRows(qreal max)
-{
- if (m_maxValueRows != max) {
- if (max <= m_minValueRows) {
- qreal oldMin = m_minValueRows;
- m_minValueRows = max - 1.0;
- qWarning() << "Warning: Tried to set maximum to equal or smaller than minimum for"
- " value range. Minimum automatically adjusted to a valid one:"
- << oldMin << "-->" << m_minValueRows;
- }
- m_maxValueRows = max;
- emit qptr()->valueRangeRowsChanged(m_minValueRows, m_maxValueRows);
- }
-}
-
-void QSurfaceDataProxyPrivate::setMinValueColumns(qreal min)
-{
- if (min != m_minValueColumns) {
- if (min >= m_maxValueColumns) {
- qreal oldMax = m_maxValueColumns;
- m_maxValueColumns = min + 1.0;
- qWarning() << "Warning: Tried to set minimum to equal or larger than maximum for"
- " value range. Maximum automatically adjusted to a valid one:"
- << oldMax << "-->" << m_maxValueColumns;
- }
- m_minValueColumns = min;
- emit qptr()->valueRangeColumnsChanged(m_minValueColumns, m_maxValueRows);
- }
-}
-
-void QSurfaceDataProxyPrivate::setMaxValueColumns(qreal max)
-{
- if (m_maxValueColumns != max) {
- if (max <= m_minValueColumns) {
- qreal oldMin = m_minValueColumns;
- m_minValueColumns = max - 1.0;
- qWarning() << "Warning: Tried to set maximum to equal or smaller than minimum for"
- " value range. Minimum automatically adjusted to a valid one:"
- << oldMin << "-->" << m_minValueColumns;
- }
- m_maxValueColumns = max;
- emit qptr()->valueRangeColumnsChanged(m_minValueColumns, m_maxValueColumns);
- }
}
QSurfaceDataProxy *QSurfaceDataProxyPrivate::qptr()
@@ -492,15 +226,15 @@ void QSurfaceDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxV
columns = m_dataArray->at(0)->size();
if (rows && columns) {
- min = m_dataArray->at(0)->at(0);
- max = m_dataArray->at(0)->at(0);
+ min = m_dataArray->at(0)->at(0).y();
+ max = m_dataArray->at(0)->at(0).y();
}
for (int i = 0; i < rows; i++) {
QSurfaceDataRow *row = m_dataArray->at(i);
if (row) {
for (int j = 0; j < columns; j++) {
- qreal itemValue = m_dataArray->at(i)->at(j);
+ qreal itemValue = m_dataArray->at(i)->at(j).y();
if (min > itemValue)
min = itemValue;
if (max < itemValue)
@@ -509,12 +243,19 @@ void QSurfaceDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxV
}
}
- minValues.setX(m_minValueColumns);
minValues.setY(min);
- minValues.setZ(m_minValueRows);
- maxValues.setX(m_maxValueColumns);
maxValues.setY(max);
- maxValues.setZ(m_maxValueRows);
+ if (columns) {
+ minValues.setX(m_dataArray->at(0)->at(0).x());
+ minValues.setZ(m_dataArray->at(0)->at(0).z());
+ maxValues.setX(m_dataArray->at(0)->last().x());
+ maxValues.setZ(m_dataArray->last()->at(0).z());
+ } else {
+ minValues.setX(0.0f);
+ minValues.setZ(0.0f);
+ maxValues.setX(0.0f);
+ maxValues.setZ(0.0f);
+ }
}
void QSurfaceDataProxyPrivate::clearRow(int rowIndex)
diff --git a/src/datavisualization/data/qsurfacedataproxy.h b/src/datavisualization/data/qsurfacedataproxy.h
index de31f188..2aeda80e 100644
--- a/src/datavisualization/data/qsurfacedataproxy.h
+++ b/src/datavisualization/data/qsurfacedataproxy.h
@@ -19,12 +19,11 @@
#ifndef QSURFACEDATAPROXY_H
#define QSURFACEDATAPROXY_H
-#include <QtDataVisualization/qdatavisualizationglobal.h>
#include <QtDataVisualization/qabstractdataproxy.h>
+#include <QtDataVisualization/qsurfacedataitem.h>
QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-typedef qreal QSurfaceDataItem; // Let's stick to this for now, expand if needed
typedef QVector<QSurfaceDataItem> QSurfaceDataRow;
typedef QList<QSurfaceDataRow *> QSurfaceDataArray;
@@ -36,10 +35,6 @@ class QT_DATAVISUALIZATION_EXPORT QSurfaceDataProxy : public QAbstractDataProxy
Q_PROPERTY(int rowCount READ rowCount)
Q_PROPERTY(int columnCount READ columnCount)
- Q_PROPERTY(qreal minValueRows READ minValueRows WRITE setMinValueRows NOTIFY valueRangeRowsChanged)
- Q_PROPERTY(qreal maxValueRows READ maxValueRows WRITE setMaxValueRows NOTIFY valueRangeRowsChanged)
- Q_PROPERTY(qreal minValueColumns READ minValueColumns WRITE setMinValueColumns NOTIFY valueRangeColumnsChanged)
- Q_PROPERTY(qreal maxValueColumns READ maxValueColumns WRITE setMaxValueColumns NOTIFY valueRangeColumnsChanged)
public:
explicit QSurfaceDataProxy(QObject *parent = 0);
@@ -50,20 +45,7 @@ public:
const QSurfaceDataArray *array() const;
const QSurfaceDataItem *itemAt(int index) const;
- void setValueRangeRows(qreal min, qreal max);
- void setValueRangeColumns(qreal min, qreal max);
- void setMinValueRows(qreal min);
- qreal minValueRows() const;
- void setMaxValueRows(qreal max);
- qreal maxValueRows() const;
- void setMinValueColumns(qreal min);
- qreal minValueColumns() const;
- void setMaxValueColumns(qreal max);
- qreal maxValueColumns() const;
-
void resetArray(QSurfaceDataArray *newArray);
- void resetArray(QSurfaceDataArray *newArray, qreal minValueRows, qreal maxValueRows,
- qreal minValueColumns, qreal maxValueColumns);
signals:
void arrayReset();
diff --git a/src/datavisualization/data/qsurfacedataproxy_p.h b/src/datavisualization/data/qsurfacedataproxy_p.h
index a40e8d65..4c8c2820 100644
--- a/src/datavisualization/data/qsurfacedataproxy_p.h
+++ b/src/datavisualization/data/qsurfacedataproxy_p.h
@@ -43,18 +43,7 @@ public:
QSurfaceDataProxyPrivate(QSurfaceDataProxy *q);
virtual ~QSurfaceDataProxyPrivate();
- void resetArray(QSurfaceDataArray *newArray, qreal minValueRows, qreal maxValueRows,
- qreal minValueColumns, qreal maxValueColumns);
-
- void setValueRangeRows(qreal min, qreal max);
- void setValueRangeColumns(qreal min, qreal max);
- void setMinValueRows(qreal min);
- void setMaxValueRows(qreal max);
- void setMinValueColumns(qreal min);
- void setMaxValueColumns(qreal max);
-
- qreal rowValue(int segment, int segmentCount);
- qreal columnValue(int segment, int segmentCount);
+ void resetArray(QSurfaceDataArray *newArray);
void limitValues(QVector3D &minValues, QVector3D &maxValues);
@@ -66,11 +55,6 @@ private:
void clearRow(int rowIndex);
void clearArray();
- qreal m_minValueRows;
- qreal m_maxValueRows;
- qreal m_minValueColumns;
- qreal m_maxValueColumns;
-
friend class QSurfaceDataProxy;
};
diff --git a/src/datavisualization/data/surfaceitemmodelhandler.cpp b/src/datavisualization/data/surfaceitemmodelhandler.cpp
index a9882040..70482162 100644
--- a/src/datavisualization/data/surfaceitemmodelhandler.cpp
+++ b/src/datavisualization/data/surfaceitemmodelhandler.cpp
@@ -49,11 +49,6 @@ void SurfaceItemModelHandler::resolveModel()
return;
}
- float minRowValue = 0.0f;
- float maxRowValue = 1.0f;
- float minColumnValue = 0.0f;
- float maxColumnValue = 1.0f;
-
QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
// Default to display role if no mapping
@@ -72,16 +67,12 @@ void SurfaceItemModelHandler::resolveModel()
}
for (int i = 0; i < rowCount; i++) {
QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i);
- for (int j = 0; j < columnCount; j++)
- newProxyRow[j] = m_itemModel->index(i, j).data(valueRole).toReal();
- }
- if (rowCount) {
- minRowValue = m_itemModel->headerData(0, Qt::Vertical).toFloat();
- maxRowValue = m_itemModel->headerData(rowCount - 1, Qt::Vertical).toFloat();
- }
- if (columnCount) {
- minColumnValue = m_itemModel->headerData(0, Qt::Horizontal).toFloat();
- maxColumnValue = m_itemModel->headerData(columnCount - 1, Qt::Horizontal).toFloat();
+ for (int j = 0; j < columnCount; j++) {
+ newProxyRow[j].setPosition(
+ QVector3D(m_itemModel->headerData(j, Qt::Horizontal).toFloat(),
+ m_itemModel->index(i, j).data(valueRole).toFloat(),
+ m_itemModel->headerData(i, Qt::Vertical).toFloat()));
+ }
}
} else {
int rowRole = roleHash.key(mapping->rowRole().toLatin1());
@@ -139,22 +130,15 @@ void SurfaceItemModelHandler::resolveModel()
for (int i = 0; i < rowList.size(); i++) {
QString rowKey = rowList.at(i);
QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i);
- for (int j = 0; j < columnList.size(); j++)
- newProxyRow[j] = itemValueMap[rowKey][columnList.at(j)];
- }
-
- // Use first and last roles converted to values for limits
- if (rowList.size()) {
- minRowValue = rowList.first().toFloat();
- maxRowValue = rowList.last().toFloat();
- }
- if (columnList.size()) {
- minColumnValue = columnList.first().toFloat();
- maxColumnValue = columnList.last().toFloat();
+ for (int j = 0; j < columnList.size(); j++) {
+ newProxyRow[j].setPosition(QVector3D(columnList.at(j).toFloat(),
+ itemValueMap[rowKey][columnList.at(j)],
+ rowList.at(i).toFloat()));
+ }
}
}
- m_proxy->resetArray(m_proxyArray, minRowValue, maxRowValue, minColumnValue, maxColumnValue);
+ m_proxy->resetArray(m_proxyArray);
}
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp
index 0009098e..b0e07d70 100644
--- a/src/datavisualization/engine/bars3drenderer.cpp
+++ b/src/datavisualization/engine/bars3drenderer.cpp
@@ -189,7 +189,7 @@ void Bars3DRenderer::updateDataModel(QBarDataProxy *dataProxy)
for (; j < updateSize ; j++) {
qreal value = dataRow->at(dataColIndex).value();
m_renderItemArray[i][j].setValue(value);
- m_renderItemArray[i][j].setHeight(value / m_heightNormalizer);
+ m_renderItemArray[i][j].setHeight(GLfloat(value) / m_heightNormalizer);
dataColIndex++;
}
}
diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp
index bd85ceee..64ceb47e 100644
--- a/src/datavisualization/engine/surface3drenderer.cpp
+++ b/src/datavisualization/engine/surface3drenderer.cpp
@@ -86,8 +86,8 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
m_maxVisibleColumnValue(0.0f),
m_minVisibleRowValue(0.0f),
m_maxVisibleRowValue(0.0f),
- m_dataStepX(0.0f),
- m_dataStepZ(0.0f),
+ m_visibleColumnRange(0.0f),
+ m_visibleRowRange(0.0f),
m_backgroundObj(0),
m_gridLineObj(0),
m_labelObj(0),
@@ -207,11 +207,11 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy)
{
calculateSceneScalingFactors();
- const QSurfaceDataArray *array = dataProxy->array();
+ const QSurfaceDataArray &array = *dataProxy->array();
// Need minimum of 2x2 array to draw a surface
- if (array->size() >= 2 && array->at(0)->size() >= 2) {
- QRect sampleSpace = calculateSampleRect(dataProxy);
+ if (array.size() >= 2 && array.at(0)->size() >= 2) {
+ QRect sampleSpace = calculateSampleRect(array);
bool dimensionChanged = false;
if (m_sampleSpace != sampleSpace) {
@@ -232,7 +232,7 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy)
}
for (int i = 0; i < sampleSpace.height(); i++) {
for (int j = 0; j < sampleSpace.width(); j++)
- (*(m_dataArray.at(i)))[j] = array->at(i + sampleSpace.y())->at(j + sampleSpace.x());
+ (*(m_dataArray.at(i)))[j] = array.at(i + sampleSpace.y())->at(j + sampleSpace.x());
}
if (m_dataArray.size() > 0) {
@@ -242,11 +242,11 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy)
// Note: Data setup can change samplespace (as min width/height is 1)
if (m_cachedSmoothSurface) {
m_surfaceObj->setUpSmoothData(m_dataArray, m_sampleSpace, m_heightNormalizer,
- dimensionChanged,
+ m_axisCacheY.min(), dimensionChanged,
m_cachedSelectionMode != QDataVis::ModeNone);
} else {
m_surfaceObj->setUpData(m_dataArray, m_sampleSpace, m_heightNormalizer,
- dimensionChanged,
+ m_axisCacheY.min(), dimensionChanged,
m_cachedSelectionMode != QDataVis::ModeNone);
}
@@ -294,65 +294,107 @@ void Surface3DRenderer::updateSliceDataModel(int selectionId)
loadSliceSurfaceObj();
if (m_cachedSmoothSurface) {
- m_sliceSurfaceObj->setUpSmoothData(m_sliceDataArray, sliceRect, m_heightNormalizer,
- true, true);
+ m_sliceSurfaceObj->setUpSmoothData(m_sliceDataArray, sliceRect, m_axisCacheY.min(),
+ m_heightNormalizer, true, true);
} else {
- m_sliceSurfaceObj->setUpData(m_sliceDataArray, sliceRect, m_heightNormalizer, true,
- true);
+ m_sliceSurfaceObj->setUpData(m_sliceDataArray, sliceRect, m_heightNormalizer,
+ m_axisCacheY.min(), true, true);
}
}
}
-QRect Surface3DRenderer::calculateSampleRect(QSurfaceDataProxy *dataProxy)
+QRect Surface3DRenderer::calculateSampleRect(const QSurfaceDataArray &array)
{
QRect sampleSpace;
- m_minVisibleColumnValue = dataProxy->minValueColumns();
- m_maxVisibleColumnValue = dataProxy->maxValueColumns();
- m_minVisibleRowValue = dataProxy->minValueRows();
- m_maxVisibleRowValue = dataProxy->maxValueRows();
- m_dataStepX = (m_maxVisibleColumnValue - m_minVisibleColumnValue) / (dataProxy->columnCount() - 1);
- m_dataStepZ = (m_maxVisibleRowValue - m_minVisibleRowValue) / (dataProxy->rowCount() - 1);
-
- if (m_minVisibleColumnValue > m_axisCacheX.max() || m_maxVisibleColumnValue < m_axisCacheX.min()
- || m_minVisibleRowValue > m_axisCacheZ.max() || m_maxVisibleRowValue < m_axisCacheZ.min()) {
+ int rowCount = array.size();
+ int columnCount = array.at(0)->size();
+
+ int i;
+ bool found;
+ float axisMinX = float(m_axisCacheX.min());
+ float axisMaxX = float(m_axisCacheX.max());
+ float axisMinZ = float(m_axisCacheZ.min());
+ float axisMaxZ = float(m_axisCacheZ.max());
+
+ // Comparisons between float and double are not accurate, so fudge our comparison values
+ //a little to get all rows and columns into view that need to be visible.
+ const float fudgeFactor = 0.00001f;
+ float fudgedAxisXRange = (axisMaxX - axisMinX) * fudgeFactor;
+ float fudgedAxisZRange = (axisMaxZ - axisMinZ) * fudgeFactor;
+ axisMinX -= fudgedAxisXRange;
+ axisMinZ -= fudgedAxisZRange;
+ axisMaxX += fudgedAxisXRange;
+ axisMaxZ += fudgedAxisZRange;
+
+ // m_minVisibleColumnValue
+ for (i = 0, found = false; i < columnCount; i++) {
+ if (array.at(0)->at(i).x() >= axisMinX) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ m_minVisibleColumnValue = array.at(0)->at(i).x();
+ sampleSpace.setLeft(i);
+ } else {
sampleSpace.setWidth(-1); // to indicate nothing needs to be shown
+ return sampleSpace;
}
- int index = 0;
- while (m_minVisibleColumnValue < m_axisCacheX.min()) {
- m_minVisibleColumnValue += m_dataStepX;
- index++;
+ // m_maxVisibleColumnValue
+ for (i = columnCount - 1, found = false; i >= 0; i--) {
+ if (array.at(0)->at(i).x() <= axisMaxX) {
+ found = true;
+ break;
+ }
}
- sampleSpace.setLeft(index);
-
- index = dataProxy->columnCount() - 1;
- while (m_maxVisibleColumnValue > m_axisCacheX.max()) {
- m_maxVisibleColumnValue -= m_dataStepX;
- index--;
+ if (found) {
+ m_maxVisibleColumnValue = array.at(0)->at(i).x();
+ sampleSpace.setRight(i);
+ } else {
+ sampleSpace.setWidth(-1); // to indicate nothing needs to be shown
+ return sampleSpace;
}
- sampleSpace.setRight(index);
- index = 0;
- while (m_minVisibleRowValue < m_axisCacheZ.min()) {
- m_minVisibleRowValue += m_dataStepZ;
- index++;
+ // m_minVisibleRowValue
+ for (i = 0, found = false; i < rowCount; i++) {
+ if (array.at(i)->at(0).z() >= axisMinZ) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ m_minVisibleRowValue = array.at(i)->at(0).z();
+ sampleSpace.setTop(i);
+ } else {
+ sampleSpace.setWidth(-1); // to indicate nothing needs to be shown
+ return sampleSpace;
}
- sampleSpace.setTop(index);
- index = dataProxy->rowCount() - 1;
- while (m_maxVisibleRowValue > m_axisCacheZ.max()) {
- m_maxVisibleRowValue -= m_dataStepZ;
- index--;
+ // m_maxVisibleRowValue
+ for (i = rowCount - 1, found = false; i >= 0; i--) {
+ if (array.at(i)->at(0).z() <= axisMaxZ) {
+ found = true;
+ break;
+ }
}
- sampleSpace.setBottom(index);
-
- m_surfaceScaleX = m_scaleX * (m_maxVisibleColumnValue - m_minVisibleColumnValue) / m_areaSize.width();
- m_surfaceScaleZ = m_scaleZ * (m_maxVisibleRowValue - m_minVisibleRowValue) / m_areaSize.height();
- GLfloat axis2XCenterX = (m_axisCacheX.min() + m_axisCacheX.max());
- GLfloat axis2XCenterZ = (m_axisCacheZ.min() + m_axisCacheZ.max());
- GLfloat data2XCenterX = (m_minVisibleColumnValue + m_maxVisibleColumnValue);
- GLfloat data2XCenterZ = (m_minVisibleRowValue + m_maxVisibleRowValue);
+ if (found) {
+ m_maxVisibleRowValue = array.at(i)->at(0).z();
+ sampleSpace.setBottom(i);
+ } else {
+ sampleSpace.setWidth(-1); // to indicate nothing needs to be shown
+ return sampleSpace;
+ }
+
+ m_visibleColumnRange = m_maxVisibleColumnValue - m_minVisibleColumnValue;
+ m_visibleRowRange = m_maxVisibleRowValue - m_minVisibleRowValue;
+ m_surfaceScaleX = m_scaleX * m_visibleColumnRange / m_areaSize.width();
+ m_surfaceScaleZ = m_scaleZ * m_visibleRowRange / m_areaSize.height();
+ GLfloat axis2XCenterX = axisMinX + axisMaxX;
+ GLfloat axis2XCenterZ = axisMinZ + axisMaxZ;
+ GLfloat data2XCenterX = GLfloat(m_minVisibleColumnValue + m_maxVisibleColumnValue);
+ GLfloat data2XCenterZ = GLfloat(m_minVisibleRowValue + m_maxVisibleRowValue);
m_surfaceOffsetX = m_scaleX * (data2XCenterX - axis2XCenterX) / m_areaSize.width();
m_surfaceOffsetZ = -m_scaleZ * (data2XCenterZ - axis2XCenterZ) / m_areaSize.height();
@@ -1759,20 +1801,18 @@ bool Surface3DRenderer::updateSmoothStatus(bool enable)
if (enable != m_cachedSmoothSurface) {
m_cachedSmoothSurface = enable;
changed = true;
- }
-
- if (changed)
initSurfaceShaders();
+ }
- // If no surface object created yet, don't try to update the object, instead return
- if (!m_surfaceObj || !changed) {
- return m_cachedSmoothSurface;
- } else {
+ // If no surface object created yet, don't try to update the object
+ if (m_surfaceObj && changed && m_sampleSpace.width() >= 2 && m_sampleSpace.height() >= 2) {
if (m_cachedSmoothSurface) {
- m_surfaceObj->setUpSmoothData(m_dataArray, m_sampleSpace, m_heightNormalizer, true,
+ m_surfaceObj->setUpSmoothData(m_dataArray, m_sampleSpace, m_heightNormalizer,
+ m_axisCacheY.min(), true,
m_cachedSelectionMode != QDataVis::ModeNone);
} else {
- m_surfaceObj->setUpData(m_dataArray, m_sampleSpace, m_heightNormalizer, true,
+ m_surfaceObj->setUpData(m_dataArray, m_sampleSpace, m_heightNormalizer,
+ m_axisCacheY.min(), true,
m_cachedSelectionMode != QDataVis::ModeNone);
}
}
@@ -1853,27 +1893,27 @@ void Surface3DRenderer::surfacePointSelected(int id)
{
int column = (id - 1) % m_sampleSpace.width();
int row = (id - 1) / m_sampleSpace.width();
- qreal value = m_dataArray.at(row)->at(column);
+ qreal value = qreal(m_dataArray.at(row)->at(column).y());
if (!m_selectionPointer)
m_selectionPointer = new SelectionPointer(m_controller, m_drawer);
QVector3D pos;
if (m_cachedSelectionMode == QDataVis::ModeSliceRow) {
- pos = normalize(float(column), value, 0.0f);
+ pos = normalize(column, 0);
pos *= QVector3D(m_surfaceScaleX, 1.0f, 0.0f);
pos += QVector3D(m_surfaceOffsetX, 0.0f, 0.0f);
m_selectionPointer->updateBoundingRect(m_sliceViewPort);
m_selectionPointer->updateSliceData(true, m_autoScaleAdjustment);
} else if (m_cachedSelectionMode == QDataVis::ModeSliceColumn) {
- pos = normalize(0.0f, value, float(row));
+ pos = normalize(0, row);
pos.setX(-pos.z());
pos *= QVector3D(m_surfaceScaleZ, 1.0f, 0.0f);
pos += QVector3D(-m_surfaceOffsetZ, 0.0f, 0.0f);
m_selectionPointer->updateBoundingRect(m_sliceViewPort);
m_selectionPointer->updateSliceData(true, m_autoScaleAdjustment);
} else {
- pos = normalize(float(column), value, float(row));
+ pos = normalize(column, row);
pos *= QVector3D(m_surfaceScaleX, 1.0f, m_surfaceScaleZ);;
pos += QVector3D(m_surfaceOffsetX, 0.0f, m_surfaceOffsetZ);
m_selectionPointer->updateBoundingRect(m_mainViewPort);
@@ -1906,7 +1946,8 @@ QString Surface3DRenderer::createSelectionLabel(qreal value, int column, int row
QString labelFormat = m_axisCacheX.labelFormat();
if (labelFormat.isEmpty())
labelFormat = Utils::defaultLabelFormat();
- QString valueLabelText = generateValueLabel(labelFormat, columnInRange(column));
+ QString valueLabelText = generateValueLabel(labelFormat,
+ m_dataArray.at(row)->at(column).x());
labelText.replace(xLabelTag, valueLabelText);
}
if (labelText.contains(yLabelTag)) {
@@ -1920,30 +1961,21 @@ QString Surface3DRenderer::createSelectionLabel(qreal value, int column, int row
QString labelFormat = m_axisCacheZ.labelFormat();
if (labelFormat.isEmpty())
labelFormat = Utils::defaultLabelFormat();
- QString valueLabelText = generateValueLabel(labelFormat, rowInRange(row));
+ QString valueLabelText = generateValueLabel(labelFormat,
+ m_dataArray.at(row)->at(column).z());
labelText.replace(zLabelTag, valueLabelText);
}
return labelText;
}
-// Transforms the model column coordinate to axis coordinate
-qreal Surface3DRenderer::columnInRange(int column)
-{
- return m_dataStepX * qreal(column) + m_minVisibleColumnValue;
-}
-
-// Transforms the model row coordinate to axis coordinate
-qreal Surface3DRenderer::rowInRange(int row)
-{
- return m_dataStepZ * qreal(row) + m_minVisibleRowValue;
-}
-
-QVector3D Surface3DRenderer::normalize(float x, float y, float z)
+QVector3D Surface3DRenderer::normalize(int x, int z)
{
- float resX = x / ((float(m_sampleSpace.width()) - 1.0f) / 2.0f) - 1.0f;
- float resY = y / (m_heightNormalizer / 2.0f) - 1.0f;
- float resZ = z / ((float(m_sampleSpace.height()) - 1.0f) / -2.0f) + 1.0f;
+ float resX = (m_dataArray.at(z)->at(x).x() - m_minVisibleColumnValue)
+ / (m_visibleColumnRange / 2.0f) - 1.0f;
+ float resY = m_dataArray.at(z)->at(x).y() / (m_heightNormalizer / 2.0f) - 1.0f; // TODO min
+ float resZ = (m_dataArray.at(z)->at(x).z() - m_minVisibleRowValue)
+ / (m_visibleRowRange / -2.0f) + 1.0f;
return QVector3D(resX, resY, resZ);
}
diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h
index 10336f06..9ab36214 100644
--- a/src/datavisualization/engine/surface3drenderer_p.h
+++ b/src/datavisualization/engine/surface3drenderer_p.h
@@ -91,12 +91,12 @@ private:
GLfloat m_surfaceScaleZ;
GLfloat m_surfaceOffsetX;
GLfloat m_surfaceOffsetZ;
- qreal m_minVisibleColumnValue;
- qreal m_maxVisibleColumnValue;
- qreal m_minVisibleRowValue;
- qreal m_maxVisibleRowValue;
- qreal m_dataStepX;
- qreal m_dataStepZ;
+ GLfloat m_minVisibleColumnValue;
+ GLfloat m_maxVisibleColumnValue;
+ GLfloat m_minVisibleRowValue;
+ GLfloat m_maxVisibleRowValue;
+ GLfloat m_visibleColumnRange;
+ GLfloat m_visibleRowRange;
ObjectHelper *m_backgroundObj;
ObjectHelper *m_gridLineObj;
ObjectHelper *m_labelObj;
@@ -154,7 +154,7 @@ private:
virtual void updateShadowQuality(QDataVis::ShadowQuality quality);
virtual void updateTextures();
virtual void initShaders(const QString &vertexShader, const QString &fragmentShader);
- QRect calculateSampleRect(QSurfaceDataProxy *dataProxy);
+ QRect calculateSampleRect(const QSurfaceDataArray &array);
void loadBackgroundMesh();
void loadGridLineMesh();
void loadLabelMesh();
@@ -174,9 +174,7 @@ private:
void fillIdCorner(uchar *p, uchar r, uchar g, uchar b, uchar a, int stride);
void surfacePointSelected(int id);
QString createSelectionLabel(qreal value, int column, int row);
- qreal columnInRange(int column);
- qreal rowInRange(int row);
- QVector3D normalize(float x, float y, float z);
+ QVector3D normalize(int x, int z);
#if !defined(QT_OPENGL_ES_2)
void updateDepthBuffer();
#endif
diff --git a/src/datavisualization/utils/surfaceobject.cpp b/src/datavisualization/utils/surfaceobject.cpp
index 0f9bb7e0..3b58e781 100644
--- a/src/datavisualization/utils/surfaceobject.cpp
+++ b/src/datavisualization/utils/surfaceobject.cpp
@@ -43,14 +43,17 @@ SurfaceObject::~SurfaceObject()
}
void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space,
- GLfloat yRange, bool changeGeometry, bool needTexture)
+ GLfloat yRange, GLfloat yMin, bool changeGeometry,
+ bool needTexture)
{
int columns = space.width();
int rows = space.height();
int totalSize = rows * columns;
- GLfloat width = (GLfloat(columns) - 1.0f) / 2.0f;
- GLfloat depth = (GLfloat(rows) - 1.0f) / -2.0f;
- GLfloat height = yRange / 2.0f;
+ GLfloat xMin = dataArray.at(0)->at(0).x();
+ GLfloat zMin = dataArray.at(0)->at(0).z();
+ GLfloat xNormalizer = (dataArray.at(0)->last().x() - xMin) / 2.0f;
+ GLfloat yNormalizer = yRange / 2.0f;
+ GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f;
// Create/populate vertice table
if (changeGeometry)
@@ -59,16 +62,17 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR
QVector<QVector2D> uvs;
if (needTexture)
uvs.resize(totalSize);
- float uvX = 1.0 / float(columns - 1);
- float uvY = 1.0 / float(rows - 1);
int totalIndex = 0;
for (int i = 0; i < rows; i++) {
+ const QSurfaceDataRow &p = *dataArray.at(i);
for (int j = 0; j < columns; j++) {
- m_vertices[totalIndex] = QVector3D(float(j) / width - 1.0f,
- float(dataArray.at(i)->at(j)) / height - 1.0f,
- float(i) / depth + 1.0f);
+ const QSurfaceDataItem &data = p.at(j);
+ float normalizedX = ((data.x() - xMin) / xNormalizer);
+ float normalizedY = ((data.y() - yMin) / yNormalizer);
+ float normalizedZ = ((data.z() - zMin) / zNormalizer);
+ m_vertices[totalIndex] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f);
if (needTexture)
- uvs[totalIndex] = QVector2D(float(j) * uvX, float(i) * uvY);
+ uvs[totalIndex] = QVector2D(normalizedX / 2.0f, normalizedZ / -2.0f);
totalIndex++;
}
}
@@ -152,16 +156,16 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR
void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &space,
- GLfloat yRange, bool changeGeometry, bool needTexture)
+ GLfloat yRange, GLfloat yMin, bool changeGeometry, bool needTexture)
{
int columns = space.width();
int rows = space.height();
int totalSize = rows * columns * 2;
- GLfloat width = (GLfloat(columns) - 1.0f) / 2.0f;
- GLfloat depth = (GLfloat(rows) - 1.0f) / -2.0f;
- GLfloat height = yRange / 2.0f;
- float uvX = 1.0 / float(columns - 1);
- float uvY = 1.0 / float(rows - 1);
+ GLfloat xMin = dataArray.at(0)->at(0).x();
+ GLfloat zMin = dataArray.at(0)->at(0).z();
+ GLfloat xNormalizer = (dataArray.at(0)->last().x() - xMin) / 2.0f;
+ GLfloat yNormalizer = yRange / 2.0f;
+ GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f;
// Create vertice table
if (changeGeometry)
@@ -178,13 +182,15 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s
int rowColLimit = rowLimit * doubleColumns;
for (int i = 0; i < rows; i++) {
+ const QSurfaceDataRow &row = *dataArray.at(i);
for (int j = 0; j < columns; j++) {
- m_vertices[totalIndex] = QVector3D(float(j) / width - 1.0f,
- float(dataArray.at(i)->at(j)) / height - 1.0f,
- float(i) / depth + 1.0f);
-
+ const QSurfaceDataItem &data = row.at(j);
+ float normalizedX = ((data.x() - xMin) / xNormalizer);
+ float normalizedY = ((data.y() - yMin) / yNormalizer);
+ float normalizedZ = ((data.z() - zMin) / zNormalizer);
+ m_vertices[totalIndex] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f);
if (needTexture)
- uvs[totalIndex] = QVector2D(float(j) * uvX, float(i) * uvY);
+ uvs[totalIndex] = QVector2D(normalizedX / 2.0f, normalizedZ / -2.0f);
totalIndex++;
@@ -280,10 +286,11 @@ void SurfaceObject::createBuffers(const QVector<QVector3D> &vertices, const QVec
&normals.at(0), GL_DYNAMIC_DRAW);
if (changeGeometry) {
- glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer);
- glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(QVector2D),
- &uvs.at(0), GL_STATIC_DRAW);
-
+ if (uvs.size()) {
+ glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer);
+ glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(QVector2D),
+ &uvs.at(0), GL_STATIC_DRAW);
+ }
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indexCount * sizeof(GLint),
indices, GL_STATIC_DRAW);
diff --git a/src/datavisualization/utils/surfaceobject_p.h b/src/datavisualization/utils/surfaceobject_p.h
index 0a52ca7c..c8273b1b 100644
--- a/src/datavisualization/utils/surfaceobject_p.h
+++ b/src/datavisualization/utils/surfaceobject_p.h
@@ -45,9 +45,9 @@ public:
~SurfaceObject();
void setUpData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange,
- bool changeGeometry, bool needTexture);
+ GLfloat yMin, bool changeGeometry, bool needTexture);
void setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange,
- bool changeGeometry, bool needTexture);
+ GLfloat yMin, bool changeGeometry, bool needTexture);
GLuint gridElementBuf();
GLuint gridIndexCount();