summaryrefslogtreecommitdiffstats
path: root/src/datavisualization
diff options
context:
space:
mode:
Diffstat (limited to 'src/datavisualization')
-rw-r--r--src/datavisualization/axis/qabstract3daxis.cpp2
-rw-r--r--src/datavisualization/axis/qabstract3daxis.h12
-rw-r--r--src/datavisualization/axis/qvalue3daxis.h2
-rw-r--r--src/datavisualization/data/abstractitemmodelhandler.cpp1
-rw-r--r--src/datavisualization/data/abstractitemmodelhandler_p.h6
-rw-r--r--src/datavisualization/data/abstractrenderitem.cpp24
-rw-r--r--src/datavisualization/data/abstractrenderitem_p.h23
-rw-r--r--src/datavisualization/data/baritemmodelhandler.cpp18
-rw-r--r--src/datavisualization/data/barrenderitem.cpp39
-rw-r--r--src/datavisualization/data/barrenderitem_p.h45
-rw-r--r--src/datavisualization/data/labelitem_p.h4
-rw-r--r--src/datavisualization/data/qabstract3dseries.cpp18
-rw-r--r--src/datavisualization/data/qabstract3dseries.h31
-rw-r--r--src/datavisualization/data/qabstract3dseries_p.h1
-rw-r--r--src/datavisualization/data/qabstractdataproxy.h5
-rw-r--r--src/datavisualization/data/qabstractdataproxy_p.h1
-rw-r--r--src/datavisualization/data/qbar3dseries.cpp67
-rw-r--r--src/datavisualization/data/qbar3dseries.h10
-rw-r--r--src/datavisualization/data/qbar3dseries_p.h4
-rw-r--r--src/datavisualization/data/qbardataitem.h2
-rw-r--r--src/datavisualization/data/qbardataproxy.cpp21
-rw-r--r--src/datavisualization/data/qbardataproxy.h8
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy.cpp12
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy.h9
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy_p.h2
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy.cpp91
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy.h27
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy_p.h1
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy.cpp61
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy.h21
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy_p.h1
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy.cpp185
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy.h46
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy_p.h4
-rw-r--r--src/datavisualization/data/qscatterdataitem.cpp10
-rw-r--r--src/datavisualization/data/qscatterdataitem.h7
-rw-r--r--src/datavisualization/data/qscatterdataproxy.cpp2
-rw-r--r--src/datavisualization/data/qscatterdataproxy.h2
-rw-r--r--src/datavisualization/data/qsurface3dseries.cpp2
-rw-r--r--src/datavisualization/data/qsurface3dseries.h2
-rw-r--r--src/datavisualization/data/qsurfacedataitem.h5
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.cpp43
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.h6
-rw-r--r--src/datavisualization/data/qsurfacedataproxy_p.h2
-rw-r--r--src/datavisualization/data/scatteritemmodelhandler.cpp39
-rw-r--r--src/datavisualization/data/scatteritemmodelhandler_p.h1
-rw-r--r--src/datavisualization/data/scatterrenderitem.cpp1
-rw-r--r--src/datavisualization/data/scatterrenderitem_p.h14
-rw-r--r--src/datavisualization/data/surfaceitemmodelhandler.cpp52
-rw-r--r--src/datavisualization/doc/qtdatavisualization.qdocconf33
-rw-r--r--src/datavisualization/doc/snippets/doc_src_qtdatavisualization.cpp2
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc80
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc11
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization-qml-scatter3d.qdoc16
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc18
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization.qdoc24
-rw-r--r--src/datavisualization/engine/abstract3dcontroller.cpp3
-rw-r--r--src/datavisualization/engine/abstract3dcontroller_p.h5
-rw-r--r--src/datavisualization/engine/abstract3drenderer.cpp38
-rw-r--r--src/datavisualization/engine/abstract3drenderer_p.h11
-rw-r--r--src/datavisualization/engine/axisrendercache.cpp5
-rw-r--r--src/datavisualization/engine/bars3dcontroller.cpp34
-rw-r--r--src/datavisualization/engine/bars3dcontroller_p.h8
-rw-r--r--src/datavisualization/engine/bars3drenderer.cpp142
-rw-r--r--src/datavisualization/engine/bars3drenderer_p.h3
-rw-r--r--src/datavisualization/engine/drawer.cpp12
-rw-r--r--src/datavisualization/engine/drawer_p.h4
-rw-r--r--src/datavisualization/engine/engine.pri10
-rw-r--r--src/datavisualization/engine/q3dbars.cpp13
-rw-r--r--src/datavisualization/engine/q3dbars.h15
-rw-r--r--src/datavisualization/engine/q3dbox.cpp485
-rw-r--r--src/datavisualization/engine/q3dbox.h158
-rw-r--r--src/datavisualization/engine/q3dcamera.cpp514
-rw-r--r--src/datavisualization/engine/q3dcamera.h43
-rw-r--r--src/datavisualization/engine/q3dcamera_p.h31
-rw-r--r--src/datavisualization/engine/q3dlight.h1
-rw-r--r--src/datavisualization/engine/q3dobject.h10
-rw-r--r--src/datavisualization/engine/q3dscatter.cpp12
-rw-r--r--src/datavisualization/engine/q3dscatter.h12
-rw-r--r--src/datavisualization/engine/q3dscene.cpp38
-rw-r--r--src/datavisualization/engine/q3dscene.h27
-rw-r--r--src/datavisualization/engine/q3dscene_p.h6
-rw-r--r--src/datavisualization/engine/q3dsurface.cpp23
-rw-r--r--src/datavisualization/engine/q3dsurface.h10
-rw-r--r--src/datavisualization/engine/q3dsurface_p.h2
-rw-r--r--src/datavisualization/engine/qabstract3dgraph.cpp19
-rw-r--r--src/datavisualization/engine/qabstract3dgraph.h16
-rw-r--r--src/datavisualization/engine/qabstract3dgraph_p.h2
-rw-r--r--src/datavisualization/engine/scatter3dcontroller.cpp8
-rw-r--r--src/datavisualization/engine/scatter3dcontroller_p.h5
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp38
-rw-r--r--src/datavisualization/engine/scatter3drenderer_p.h4
-rw-r--r--src/datavisualization/engine/selectionpointer.cpp12
-rw-r--r--src/datavisualization/engine/selectionpointer_p.h2
-rw-r--r--src/datavisualization/engine/seriesrendercache.cpp18
-rw-r--r--src/datavisualization/engine/seriesrendercache_p.h4
-rw-r--r--src/datavisualization/engine/surface3dcontroller.cpp140
-rw-r--r--src/datavisualization/engine/surface3dcontroller_p.h22
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp1316
-rw-r--r--src/datavisualization/engine/surface3drenderer_p.h57
-rw-r--r--src/datavisualization/engine/surfaceseriesrendercache.cpp91
-rw-r--r--src/datavisualization/engine/surfaceseriesrendercache_p.h130
-rw-r--r--src/datavisualization/global/datavisualizationglobal_p.h10
-rw-r--r--src/datavisualization/global/qdatavisualizationglobal.h2
-rw-r--r--src/datavisualization/input/q3dinputhandler.h4
-rw-r--r--src/datavisualization/input/qabstract3dinputhandler.cpp1
-rw-r--r--src/datavisualization/input/qabstract3dinputhandler.h15
-rw-r--r--src/datavisualization/input/qabstract3dinputhandler_p.h2
-rw-r--r--src/datavisualization/input/qtouch3dinputhandler.cpp4
-rw-r--r--src/datavisualization/input/qtouch3dinputhandler_p.h2
-rw-r--r--src/datavisualization/theme/q3dtheme.h41
-rw-r--r--src/datavisualization/utils/abstractobjecthelper.cpp2
-rw-r--r--src/datavisualization/utils/abstractobjecthelper_p.h2
-rw-r--r--src/datavisualization/utils/camerahelper.cpp5
-rw-r--r--src/datavisualization/utils/camerahelper_p.h14
-rw-r--r--src/datavisualization/utils/meshloader.cpp9
-rw-r--r--src/datavisualization/utils/meshloader_p.h4
-rw-r--r--src/datavisualization/utils/objecthelper_p.h2
-rw-r--r--src/datavisualization/utils/shaderhelper.cpp2
-rw-r--r--src/datavisualization/utils/shaderhelper_p.h2
-rw-r--r--src/datavisualization/utils/surfaceobject.cpp17
-rw-r--r--src/datavisualization/utils/surfaceobject_p.h16
-rw-r--r--src/datavisualization/utils/texturehelper.cpp20
-rw-r--r--src/datavisualization/utils/texturehelper_p.h7
-rw-r--r--src/datavisualization/utils/utils.cpp13
-rw-r--r--src/datavisualization/utils/vertexindexer.cpp2
-rw-r--r--src/datavisualization/utils/vertexindexer_p.h5
127 files changed, 2672 insertions, 2266 deletions
diff --git a/src/datavisualization/axis/qabstract3daxis.cpp b/src/datavisualization/axis/qabstract3daxis.cpp
index 2ee7a25d..39b1230e 100644
--- a/src/datavisualization/axis/qabstract3daxis.cpp
+++ b/src/datavisualization/axis/qabstract3daxis.cpp
@@ -151,7 +151,7 @@ QAbstract3DAxis::AxisType QAbstract3DAxis::type() const
*
* Defines the title for the axis.
*/
-void QAbstract3DAxis::setTitle(QString title)
+void QAbstract3DAxis::setTitle(const QString &title)
{
if (d_ptr->m_title != title) {
d_ptr->m_title = title;
diff --git a/src/datavisualization/axis/qabstract3daxis.h b/src/datavisualization/axis/qabstract3daxis.h
index 28b93f36..0d63615a 100644
--- a/src/datavisualization/axis/qabstract3daxis.h
+++ b/src/datavisualization/axis/qabstract3daxis.h
@@ -20,11 +20,9 @@
#define QABSTRACT3DAXIS_H
#include <QtDataVisualization/qdatavisualizationglobal.h>
-
-#include <QObject>
-#include <QScopedPointer>
-#include <QVector>
-#include <QStringList>
+#include <QtCore/QObject>
+#include <QtCore/QScopedPointer>
+#include <QtCore/QStringList>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -63,7 +61,7 @@ protected:
public:
virtual ~QAbstract3DAxis();
- void setTitle(QString title);
+ void setTitle(const QString &title);
QString title() const;
void setLabels(const QStringList &labels);
@@ -84,7 +82,7 @@ public:
void setRange(float min, float max);
signals:
- void titleChanged(QString newTitle);
+ void titleChanged(const QString &newTitle);
void labelsChanged();
void orientationChanged(AxisOrientation orientation);
void minChanged(float value);
diff --git a/src/datavisualization/axis/qvalue3daxis.h b/src/datavisualization/axis/qvalue3daxis.h
index c930c700..f0af759b 100644
--- a/src/datavisualization/axis/qvalue3daxis.h
+++ b/src/datavisualization/axis/qvalue3daxis.h
@@ -48,7 +48,7 @@ public:
signals:
void segmentCountChanged(int count);
void subSegmentCountChanged(int count);
- void labelFormatChanged(QString format);
+ void labelFormatChanged(const QString &format);
protected:
QValue3DAxisPrivate *dptr();
diff --git a/src/datavisualization/data/abstractitemmodelhandler.cpp b/src/datavisualization/data/abstractitemmodelhandler.cpp
index 63eb7e45..9f2ccd86 100644
--- a/src/datavisualization/data/abstractitemmodelhandler.cpp
+++ b/src/datavisualization/data/abstractitemmodelhandler.cpp
@@ -17,7 +17,6 @@
****************************************************************************/
#include "abstractitemmodelhandler_p.h"
-#include <QTimer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/abstractitemmodelhandler_p.h b/src/datavisualization/data/abstractitemmodelhandler_p.h
index c238a63b..ecbfe61c 100644
--- a/src/datavisualization/data/abstractitemmodelhandler_p.h
+++ b/src/datavisualization/data/abstractitemmodelhandler_p.h
@@ -30,9 +30,9 @@
#define ABSTRACTITEMMODELHANDLER_P_H
#include "datavisualizationglobal_p.h"
-#include <QAbstractItemModel>
-#include <QPointer>
-#include <QTimer>
+#include <QtCore/QAbstractItemModel>
+#include <QtCore/QPointer>
+#include <QtCore/QTimer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/abstractrenderitem.cpp b/src/datavisualization/data/abstractrenderitem.cpp
index 522fd144..59ffab22 100644
--- a/src/datavisualization/data/abstractrenderitem.cpp
+++ b/src/datavisualization/data/abstractrenderitem.cpp
@@ -21,39 +21,17 @@
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
AbstractRenderItem::AbstractRenderItem()
- : m_selectionLabelItem(0)
{
}
AbstractRenderItem::AbstractRenderItem(const AbstractRenderItem &other)
{
- m_selectionLabel = other.m_selectionLabel;
m_translation = other.m_translation;
- m_selectionLabelItem = 0;
+ m_rotation = other.m_rotation;
}
AbstractRenderItem::~AbstractRenderItem()
{
- delete m_selectionLabelItem;
-}
-
-LabelItem &AbstractRenderItem::selectionLabelItem()
-{
- if (!m_selectionLabelItem)
- m_selectionLabelItem = new LabelItem;
- return *m_selectionLabelItem;
-}
-
-void AbstractRenderItem::setSelectionLabel(const QString &label)
-{
- if (m_selectionLabelItem)
- m_selectionLabelItem->clear();
- m_selectionLabel = label;
-}
-
-QString &AbstractRenderItem::selectionLabel()
-{
- return m_selectionLabel;
}
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/abstractrenderitem_p.h b/src/datavisualization/data/abstractrenderitem_p.h
index fa06db54..912a09f3 100644
--- a/src/datavisualization/data/abstractrenderitem_p.h
+++ b/src/datavisualization/data/abstractrenderitem_p.h
@@ -32,10 +32,10 @@
#include "datavisualizationglobal_p.h"
#include "labelitem_p.h"
-#include <QOpenGLFunctions>
-#include <QString>
-#include <QVector3D>
-#include <QQuaternion>
+#include <QtCore/QString>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QVector3D>
+#include <QtGui/QQuaternion>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -50,17 +50,16 @@ public:
inline void setTranslation(const QVector3D &translation) { m_translation = translation; }
inline const QVector3D &translation() const {return m_translation; }
- // Selection label item (containing special selection texture, if mode is activated)
- LabelItem &selectionLabelItem();
-
- // Formatted selection label for item.
- void setSelectionLabel(const QString &label);
- QString &selectionLabel(); // Formats selection label if not previously formatted
+ inline QQuaternion rotation() const { return m_rotation; }
+ inline void setRotation(const QQuaternion &rotation)
+ {
+ if (m_rotation != rotation)
+ m_rotation = rotation;
+ }
protected:
- QString m_selectionLabel;
QVector3D m_translation;
- LabelItem *m_selectionLabelItem;
+ QQuaternion m_rotation;
friend class QAbstractDataItem;
};
diff --git a/src/datavisualization/data/baritemmodelhandler.cpp b/src/datavisualization/data/baritemmodelhandler.cpp
index 611fbcb9..4f44fe1d 100644
--- a/src/datavisualization/data/baritemmodelhandler.cpp
+++ b/src/datavisualization/data/baritemmodelhandler.cpp
@@ -20,6 +20,8 @@
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+static const int noRoleIndex = -1;
+
BarItemModelHandler::BarItemModelHandler(QItemModelBarDataProxy *proxy, QObject *parent)
: AbstractItemModelHandler(parent),
m_proxy(proxy),
@@ -51,8 +53,9 @@ void BarItemModelHandler::resolveModel()
QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
- // Default to display role if no mapping
+ // Default value role to display role if no mapping
int valueRole = roleHash.key(m_proxy->valueRole().toLatin1(), Qt::DisplayRole);
+ int rotationRole = roleHash.key(m_proxy->rotationRole().toLatin1(), noRoleIndex);
int rowCount = m_itemModel->rowCount();
int columnCount = m_itemModel->columnCount();
@@ -67,8 +70,11 @@ void BarItemModelHandler::resolveModel()
}
for (int i = 0; i < rowCount; i++) {
QBarDataRow &newProxyRow = *m_proxyArray->at(i);
- for (int j = 0; j < columnCount; j++)
+ for (int j = 0; j < columnCount; j++) {
newProxyRow[j].setValue(m_itemModel->index(i, j).data(valueRole).toReal());
+ if (rotationRole != noRoleIndex)
+ newProxyRow[j].setRotation(m_itemModel->index(i, j).data(rotationRole).toReal());
+ }
}
// Generate labels from headers if using model rows/columns
for (int i = 0; i < rowCount; i++)
@@ -92,12 +98,15 @@ void BarItemModelHandler::resolveModel()
// Sort values into rows and columns
typedef QHash<QString, float> ColumnValueMap;
QHash <QString, ColumnValueMap> itemValueMap;
+ QHash <QString, ColumnValueMap> itemRotationMap;
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < columnCount; j++) {
QModelIndex index = m_itemModel->index(i, j);
QString rowRoleStr = index.data(rowRole).toString();
QString columnRoleStr = index.data(columnRole).toString();
itemValueMap[rowRoleStr][columnRoleStr] = index.data(valueRole).toReal();
+ if (rotationRole != noRoleIndex)
+ itemRotationMap[rowRoleStr][columnRoleStr] = index.data(rotationRole).toReal();
if (generateRows && !rowListHash.value(rowRoleStr, false)) {
rowListHash.insert(rowRoleStr, true);
rowList << rowRoleStr;
@@ -131,8 +140,11 @@ void BarItemModelHandler::resolveModel()
for (int i = 0; i < rowList.size(); i++) {
QString rowKey = rowList.at(i);
QBarDataRow &newProxyRow = *m_proxyArray->at(i);
- for (int j = 0; j < columnList.size(); j++)
+ for (int j = 0; j < columnList.size(); j++) {
newProxyRow[j].setValue(itemValueMap[rowKey][columnList.at(j)]);
+ if (rotationRole != noRoleIndex)
+ newProxyRow[j].setRotation(itemRotationMap[rowKey][columnList.at(j)]);
+ }
}
rowLabels = rowList;
diff --git a/src/datavisualization/data/barrenderitem.cpp b/src/datavisualization/data/barrenderitem.cpp
index 915f3f78..50d2a4b4 100644
--- a/src/datavisualization/data/barrenderitem.cpp
+++ b/src/datavisualization/data/barrenderitem.cpp
@@ -25,7 +25,6 @@ BarRenderItem::BarRenderItem()
: AbstractRenderItem(),
m_value(0),
m_height(0.0f),
- m_sliceLabelItem(0),
m_seriesIndex(0)
{
}
@@ -36,32 +35,58 @@ BarRenderItem::BarRenderItem(const BarRenderItem &other)
m_value = other.m_value;
m_position = other.m_position;
m_height = other.m_height;
- m_sliceLabel = other.m_sliceLabel;
- m_sliceLabelItem = 0;
m_seriesIndex = other.m_seriesIndex;
- m_rotation = other.m_rotation;
}
BarRenderItem::~BarRenderItem()
{
+}
+
+BarRenderSliceItem::BarRenderSliceItem()
+ : BarRenderItem(),
+ m_sliceLabelItem(0)
+{
+}
+
+BarRenderSliceItem::BarRenderSliceItem(const BarRenderSliceItem &other)
+ : BarRenderItem(other)
+{
+ m_sliceLabel = other.m_sliceLabel;
+ m_sliceLabelItem = 0;
+}
+
+BarRenderSliceItem::~BarRenderSliceItem()
+{
delete m_sliceLabelItem;
}
-LabelItem &BarRenderItem::sliceLabelItem()
+void BarRenderSliceItem::setItem(const BarRenderItem &renderItem)
+{
+ m_translation = renderItem.translation();
+ m_rotation = renderItem.rotation();
+ m_value = renderItem.value();
+ m_position = renderItem.position();
+ m_height = renderItem.height();
+ m_seriesIndex = renderItem.seriesIndex();
+ m_sliceLabel = QString();
+ m_sliceLabelItem = 0;
+}
+
+LabelItem &BarRenderSliceItem::sliceLabelItem()
{
if (!m_sliceLabelItem)
m_sliceLabelItem = new LabelItem;
return *m_sliceLabelItem;
}
-void BarRenderItem::setSliceLabel(const QString &label)
+void BarRenderSliceItem::setSliceLabel(const QString &label)
{
if (m_sliceLabelItem)
m_sliceLabelItem->clear();
m_sliceLabel = label;
}
-const QString &BarRenderItem::sliceLabel() const
+const QString &BarRenderSliceItem::sliceLabel() const
{
return m_sliceLabel;
}
diff --git a/src/datavisualization/data/barrenderitem_p.h b/src/datavisualization/data/barrenderitem_p.h
index e1062969..1122053d 100644
--- a/src/datavisualization/data/barrenderitem_p.h
+++ b/src/datavisualization/data/barrenderitem_p.h
@@ -47,48 +47,49 @@ public:
inline const QPoint &position() const { return m_position; }
// Actual cached data value of the bar (needed to trigger label reformats)
- inline void setValue(float value)
- {
- m_value = value;
- // Force reformatting on next access by setting label string to null string
- if (!m_sliceLabel.isNull())
- setSliceLabel(QString());
- if (!m_selectionLabel.isNull())
- setSelectionLabel(QString());
- }
+ inline void setValue(float value) { m_value = value; }
inline float value() const { return m_value; }
// Normalized bar height
inline void setHeight(GLfloat height) { m_height = height; }
inline GLfloat height() const { return m_height; }
- // Label item for formatted label
- LabelItem &sliceLabelItem();
-
- // Formatted label for item.
- void setSliceLabel(const QString &label);
- const QString &sliceLabel() const; // Formats label if not previously formatted
-
// Series index in visual series that this item belongs to.
// This is only utilized by slicing, so it may not be up to date on all items.
inline void setSeriesIndex(int seriesIndex) { m_seriesIndex = seriesIndex; }
inline int seriesIndex() const { return m_seriesIndex; }
- inline void setRotation(const QQuaternion &rotation) { m_rotation = rotation; }
- inline const QQuaternion &rotation() const { return m_rotation; }
-
protected:
float m_value;
QPoint m_position; // x = row, y = column
GLfloat m_height;
- QString m_sliceLabel;
- LabelItem *m_sliceLabelItem;
int m_seriesIndex;
- QQuaternion m_rotation;
friend class QBarDataItem;
};
+class BarRenderSliceItem : public BarRenderItem
+{
+public:
+ BarRenderSliceItem();
+ BarRenderSliceItem(const BarRenderSliceItem &other);
+ virtual ~BarRenderSliceItem();
+
+ void setItem(const BarRenderItem &renderItem);
+
+ // Label item for formatted label
+ LabelItem &sliceLabelItem();
+
+ // Formatted label for item.
+ void setSliceLabel(const QString &label);
+ const QString &sliceLabel() const; // Formats label if not previously formatted
+
+protected:
+ QString m_sliceLabel;
+ LabelItem *m_sliceLabelItem;
+ bool m_isNull;
+};
+
typedef QVector<BarRenderItem> BarRenderItemRow;
typedef QVector<BarRenderItemRow> BarRenderItemArray;
diff --git a/src/datavisualization/data/labelitem_p.h b/src/datavisualization/data/labelitem_p.h
index ca60f742..3a2c1eb1 100644
--- a/src/datavisualization/data/labelitem_p.h
+++ b/src/datavisualization/data/labelitem_p.h
@@ -30,8 +30,8 @@
#define LABELITEM_P_H
#include "datavisualizationglobal_p.h"
-#include <QOpenGLFunctions>
-#include <QSize>
+#include <QtGui/QOpenGLFunctions>
+#include <QtCore/QSize>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qabstract3dseries.cpp b/src/datavisualization/data/qabstract3dseries.cpp
index dc241fdb..4d201c45 100644
--- a/src/datavisualization/data/qabstract3dseries.cpp
+++ b/src/datavisualization/data/qabstract3dseries.cpp
@@ -240,6 +240,14 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \qmlmethod void Abstract3DSeries::setMeshAxisAndAngle(vector3d axis, real angle)
+ *
+ * A convenience function to construct mesh rotation quaternion from axis and angle.
+ *
+ * \sa meshRotation
+ */
+
+/*!
* \internal
*/
QAbstract3DSeries::QAbstract3DSeries(QAbstract3DSeriesPrivate *d, QObject *parent) :
@@ -375,6 +383,16 @@ QQuaternion QAbstract3DSeries::meshRotation() const
}
/*!
+ * A convenience function to construct mesh rotation quaternion from \a axis and \a angle.
+ *
+ * \sa meshRotation
+ */
+void QAbstract3DSeries::setMeshAxisAndAngle(const QVector3D &axis, float angle)
+{
+ setMeshRotation(QQuaternion::fromAxisAndAngle(axis, angle));
+}
+
+/*!
* \property QAbstract3DSeries::userDefinedMesh
*
* Sets the \a fileName for user defined custom mesh for objects that is used when mesh
diff --git a/src/datavisualization/data/qabstract3dseries.h b/src/datavisualization/data/qabstract3dseries.h
index ebb22b7f..9f82901d 100644
--- a/src/datavisualization/data/qabstract3dseries.h
+++ b/src/datavisualization/data/qabstract3dseries.h
@@ -20,10 +20,11 @@
#define QABSTRACT3DSERIES_H
#include <QtDataVisualization/q3dtheme.h>
-#include <QObject>
-#include <QScopedPointer>
-#include <QLinearGradient>
-#include <QQuaternion>
+#include <QtCore/QObject>
+#include <QtCore/QScopedPointer>
+#include <QtCore/QString>
+#include <QtGui/QLinearGradient>
+#include <QtGui/QQuaternion>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -95,6 +96,7 @@ public:
void setMeshRotation(const QQuaternion &rotation);
QQuaternion meshRotation() const;
+ Q_INVOKABLE void setMeshAxisAndAngle(const QVector3D &axis, float angle);
void setUserDefinedMesh(const QString &fileName);
QString userDefinedMesh() const;
@@ -118,20 +120,20 @@ public:
QString name() const;
signals:
- void itemLabelFormatChanged(QString format);
+ void itemLabelFormatChanged(const QString &format);
void visibilityChanged(bool visible);
void meshChanged(Mesh mesh);
void meshSmoothChanged(bool enabled);
- void meshRotationChanged(QQuaternion rotation);
- void userDefinedMeshChanged(QString fileName);
+ void meshRotationChanged(const QQuaternion &rotation);
+ void userDefinedMeshChanged(const QString &fileName);
void colorStyleChanged(Q3DTheme::ColorStyle style);
- void baseColorChanged(QColor color);
- void baseGradientChanged(QLinearGradient gradient);
- void singleHighlightColorChanged(QColor color);
- void singleHighlightGradientChanged(QLinearGradient gradient);
- void multiHighlightColorChanged(QColor color);
- void multiHighlightGradientChanged(QLinearGradient gradient);
- void nameChanged(QString name);
+ void baseColorChanged(const QColor &color);
+ void baseGradientChanged(const QLinearGradient &gradient);
+ void singleHighlightColorChanged(const QColor &color);
+ void singleHighlightGradientChanged(const QLinearGradient &gradient);
+ void multiHighlightColorChanged(const QColor &color);
+ void multiHighlightGradientChanged(const QLinearGradient &gradient);
+ void nameChanged(const QString &name);
protected:
QScopedPointer<QAbstract3DSeriesPrivate> d_ptr;
@@ -142,6 +144,7 @@ private:
friend class Abstract3DController;
friend class Bars3DController;
friend class Surface3DController;
+ friend class Surface3DRenderer;
friend class Scatter3DController;
friend class QBar3DSeries;
friend class SeriesRenderCache;
diff --git a/src/datavisualization/data/qabstract3dseries_p.h b/src/datavisualization/data/qabstract3dseries_p.h
index 6fbabd3d..a803e99b 100644
--- a/src/datavisualization/data/qabstract3dseries_p.h
+++ b/src/datavisualization/data/qabstract3dseries_p.h
@@ -28,7 +28,6 @@
#include "datavisualizationglobal_p.h"
#include "qabstract3dseries.h"
-#include <QString>
#ifndef QABSTRACT3DSERIES_P_H
#define QABSTRACT3DSERIES_P_H
diff --git a/src/datavisualization/data/qabstractdataproxy.h b/src/datavisualization/data/qabstractdataproxy.h
index 52c2e2c6..c643c675 100644
--- a/src/datavisualization/data/qabstractdataproxy.h
+++ b/src/datavisualization/data/qabstractdataproxy.h
@@ -20,9 +20,8 @@
#define QABSTRACTDATAPROXY_H
#include <QtDataVisualization/qdatavisualizationglobal.h>
-
-#include <QObject>
-#include <QScopedPointer>
+#include <QtCore/QObject>
+#include <QtCore/QScopedPointer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qabstractdataproxy_p.h b/src/datavisualization/data/qabstractdataproxy_p.h
index 093629d5..eb901f4c 100644
--- a/src/datavisualization/data/qabstractdataproxy_p.h
+++ b/src/datavisualization/data/qabstractdataproxy_p.h
@@ -28,7 +28,6 @@
#include "datavisualizationglobal_p.h"
#include "qabstractdataproxy.h"
-#include <QString>
#ifndef QABSTRACTDATAPROXY_P_H
#define QABSTRACTDATAPROXY_P_H
diff --git a/src/datavisualization/data/qbar3dseries.cpp b/src/datavisualization/data/qbar3dseries.cpp
index 1440476b..ed4ffaba 100644
--- a/src/datavisualization/data/qbar3dseries.cpp
+++ b/src/datavisualization/data/qbar3dseries.cpp
@@ -18,6 +18,7 @@
#include "qbar3dseries_p.h"
#include "bars3dcontroller_p.h"
+#include <QtCore/qmath.h>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -114,6 +115,17 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \qmlproperty real Bar3DSeries::meshAngle
+ *
+ * A convenience property for defining the series rotation \a angle in degrees.
+ *
+ * \note: When reading this property, it is calculated from Abstract3DSeries::meshRotation value
+ * using floating point precision and always returns a value from zero to 360 degrees.
+ *
+ * \sa Abstract3DSeries::meshRotation
+ */
+
+/*!
* Constructs QBar3DSeries with the given \a parent.
*/
QBar3DSeries::QBar3DSeries(QObject *parent) :
@@ -121,6 +133,7 @@ QBar3DSeries::QBar3DSeries(QObject *parent) :
{
// Default proxy
dptr()->setDataProxy(new QBarDataProxy);
+ dptr()->connectSignals();
}
/*!
@@ -130,14 +143,7 @@ QBar3DSeries::QBar3DSeries(QBarDataProxy *dataProxy, QObject *parent) :
QAbstract3DSeries(new QBar3DSeriesPrivate(this), parent)
{
dptr()->setDataProxy(dataProxy);
-}
-
-/*!
- * \internal
- */
-QBar3DSeries::QBar3DSeries(QBar3DSeriesPrivate *d, QObject *parent) :
- QAbstract3DSeries(d, parent)
-{
+ dptr()->connectSignals();
}
/*!
@@ -183,7 +189,7 @@ void QBar3DSeries::setSelectedBar(const QPoint &position)
{
// Don't do this in private to avoid loops, as that is used for callback from controller.
if (d_ptr->m_controller)
- static_cast<Bars3DController *>(d_ptr->m_controller)->setSelectedBar(position, this);
+ static_cast<Bars3DController *>(d_ptr->m_controller)->setSelectedBar(position, this, true);
else
dptr()->setSelectedBar(position);
}
@@ -204,6 +210,38 @@ QPoint QBar3DSeries::invalidSelectionPosition()
return Bars3DController::invalidSelectionPosition();
}
+static inline float quaternionAngle(const QQuaternion &rotation)
+{
+ return qAcos(rotation.scalar()) * 360.0f / M_PI;
+}
+
+/*!
+ * \property QBar3DSeries::meshAngle
+ *
+ * A convenience property for defining the series rotation \a angle in degrees.
+ * Setting this property is equivalent to the following call:
+ * \code setMeshRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, angle)) \endcode
+ *
+ * \note: When reading this property, it is calculated from QAbstract3DSeries::meshRotation value
+ * using floating point precision and always returns a value from zero to 360 degrees.
+ *
+ * \sa QAbstract3DSeries::meshRotation
+ */
+void QBar3DSeries::setMeshAngle(float angle)
+{
+ setMeshRotation(QQuaternion::fromAxisAndAngle(upVector, angle));
+}
+
+float QBar3DSeries::meshAngle() const
+{
+ QQuaternion rotation = meshRotation();
+
+ if (rotation.isIdentity() || rotation.x() != 0.0f || rotation.z() != 0.0f)
+ return 0.0f;
+ else
+ return quaternionAngle(rotation);
+}
+
/*!
* \internal
*/
@@ -279,6 +317,11 @@ void QBar3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *newCon
}
}
+void QBar3DSeriesPrivate::handleMeshRotationChanged(const QQuaternion &rotation)
+{
+ emit qptr()->meshAngleChanged(quaternionAngle(rotation));
+}
+
void QBar3DSeriesPrivate::setSelectedBar(const QPoint &position)
{
if (position != m_selectedBar) {
@@ -287,4 +330,10 @@ void QBar3DSeriesPrivate::setSelectedBar(const QPoint &position)
}
}
+void QBar3DSeriesPrivate::connectSignals()
+{
+ QObject::connect(q_ptr, &QAbstract3DSeries::meshRotationChanged, this,
+ &QBar3DSeriesPrivate::handleMeshRotationChanged);
+}
+
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qbar3dseries.h b/src/datavisualization/data/qbar3dseries.h
index be748516..c56bc354 100644
--- a/src/datavisualization/data/qbar3dseries.h
+++ b/src/datavisualization/data/qbar3dseries.h
@@ -21,7 +21,7 @@
#include <QtDataVisualization/qabstract3dseries.h>
#include <QtDataVisualization/qbardataproxy.h>
-#include <QPoint>
+#include <QtCore/QPoint>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -32,6 +32,7 @@ class QT_DATAVISUALIZATION_EXPORT QBar3DSeries : public QAbstract3DSeries
Q_OBJECT
Q_PROPERTY(QBarDataProxy *dataProxy READ dataProxy WRITE setDataProxy NOTIFY dataProxyChanged)
Q_PROPERTY(QPoint selectedBar READ selectedBar WRITE setSelectedBar NOTIFY selectedBarChanged)
+ Q_PROPERTY(float meshAngle READ meshAngle WRITE setMeshAngle NOTIFY meshAngleChanged)
public:
explicit QBar3DSeries(QObject *parent = 0);
@@ -45,12 +46,15 @@ public:
QPoint selectedBar() const;
static QPoint invalidSelectionPosition();
+ void setMeshAngle(float angle);
+ float meshAngle() const;
+
signals:
void dataProxyChanged(QBarDataProxy *proxy);
- void selectedBarChanged(QPoint position);
+ void selectedBarChanged(const QPoint &position);
+ void meshAngleChanged(float angle);
protected:
- explicit QBar3DSeries(QBar3DSeriesPrivate *d, QObject *parent = 0);
QBar3DSeriesPrivate *dptr();
const QBar3DSeriesPrivate *dptrc() const;
diff --git a/src/datavisualization/data/qbar3dseries_p.h b/src/datavisualization/data/qbar3dseries_p.h
index 173f1cd9..718f1237 100644
--- a/src/datavisualization/data/qbar3dseries_p.h
+++ b/src/datavisualization/data/qbar3dseries_p.h
@@ -44,8 +44,12 @@ public:
virtual void setDataProxy(QAbstractDataProxy *proxy);
virtual void connectControllerAndProxy(Abstract3DController *newController);
+ void handleMeshRotationChanged(const QQuaternion &rotation);
+
void setSelectedBar(const QPoint &position);
+ void connectSignals();
+
private:
QBar3DSeries *qptr();
diff --git a/src/datavisualization/data/qbardataitem.h b/src/datavisualization/data/qbardataitem.h
index 84e7cd92..e7fce93b 100644
--- a/src/datavisualization/data/qbardataitem.h
+++ b/src/datavisualization/data/qbardataitem.h
@@ -42,7 +42,7 @@ public:
inline float rotation() const { return m_angle; }
protected:
- virtual void createExtraData();
+ void createExtraData();
QBarDataItemPrivate *d_ptr;
diff --git a/src/datavisualization/data/qbardataproxy.cpp b/src/datavisualization/data/qbardataproxy.cpp
index a26e446e..d2553f32 100644
--- a/src/datavisualization/data/qbardataproxy.cpp
+++ b/src/datavisualization/data/qbardataproxy.cpp
@@ -130,7 +130,7 @@ QBarDataProxy::~QBarDataProxy()
*
* The series this proxy is attached to.
*/
-QBar3DSeries *QBarDataProxy::series()
+QBar3DSeries *QBarDataProxy::series() const
{
return static_cast<QBar3DSeries *>(d_ptr->series());
}
@@ -227,6 +227,15 @@ void QBarDataProxy::setItem(int rowIndex, int columnIndex, const QBarDataItem &i
}
/*!
+ * Changes a single item at \a position to the \a item.
+ * The X-value of \a position indicates the row and the Y-value indicates the column.
+ */
+void QBarDataProxy::setItem(const QPoint &position, const QBarDataItem &item)
+{
+ setItem(position.x(), position.y(), item);
+}
+
+/*!
* Adds a new \a row to the end of array.
* Existing row labels are not affected.
*
@@ -427,6 +436,16 @@ const QBarDataItem *QBarDataProxy::itemAt(int rowIndex, int columnIndex) const
}
/*!
+ * \return pointer to the item at \a position. The X-value of \a position indicates the row
+ * and the Y-value indicates the column. The item is guaranteed to be valid only
+ * until the next call that modifies data.
+ */
+const QBarDataItem *QBarDataProxy::itemAt(const QPoint &position) const
+{
+ return itemAt(position.x(), position.y());
+}
+
+/*!
* \internal
*/
QBarDataProxyPrivate *QBarDataProxy::dptr()
diff --git a/src/datavisualization/data/qbardataproxy.h b/src/datavisualization/data/qbardataproxy.h
index 0ad71365..55c11de3 100644
--- a/src/datavisualization/data/qbardataproxy.h
+++ b/src/datavisualization/data/qbardataproxy.h
@@ -21,8 +21,8 @@
#include <QtDataVisualization/qabstractdataproxy.h>
#include <QtDataVisualization/qbardataitem.h>
-#include <QVector>
-#include <QStringList>
+#include <QtCore/QVector>
+#include <QtCore/QStringList>
namespace QtDataVisualization {
// typedefs introduced this way because QDoc doesn't understand namespace macros
@@ -47,7 +47,7 @@ public:
explicit QBarDataProxy(QObject *parent = 0);
virtual ~QBarDataProxy();
- QBar3DSeries *series();
+ QBar3DSeries *series() const;
int rowCount() const;
QStringList rowLabels() const;
@@ -58,6 +58,7 @@ public:
const QBarDataArray *array() const;
const QBarDataRow *rowAt(int rowIndex) const;
const QBarDataItem *itemAt(int rowIndex, int columnIndex) const;
+ const QBarDataItem *itemAt(const QPoint &position) const;
void resetArray();
void resetArray(QBarDataArray *newArray);
@@ -70,6 +71,7 @@ public:
void setRows(int rowIndex, const QBarDataArray &rows, const QStringList &labels);
void setItem(int rowIndex, int columnIndex, const QBarDataItem &item);
+ void setItem(const QPoint &position, const QBarDataItem &item);
int addRow(QBarDataRow *row);
int addRow(QBarDataRow *row, const QString &label);
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
index 9ac5c90f..1aead1d7 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
@@ -134,6 +134,18 @@ QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(const QImage &image, QObj
}
/*!
+ * Constructs QHeightMapSurfaceDataProxy from the given image \a filename and \a parent. Height map is set
+ * by calling setHeightMapFile() with \a filename.
+ *
+ * \sa heightMapFile
+ */
+QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(const QString &filename, QObject *parent) :
+ QSurfaceDataProxy(new QHeightMapSurfaceDataProxyPrivate(this), parent)
+{
+ setHeightMapFile(filename);
+}
+
+/*!
* \internal
*/
QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.h b/src/datavisualization/data/qheightmapsurfacedataproxy.h
index d506d4e8..5b6eb284 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy.h
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy.h
@@ -20,8 +20,8 @@
#define QHEIGHTMAPSURFACEDATAPROXY_H
#include <QtDataVisualization/qsurfacedataproxy.h>
-
-#include <QImage>
+#include <QtGui/QImage>
+#include <QtCore/QString>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -41,6 +41,7 @@ class QT_DATAVISUALIZATION_EXPORT QHeightMapSurfaceDataProxy : public QSurfaceDa
public:
explicit QHeightMapSurfaceDataProxy(QObject *parent = 0);
explicit QHeightMapSurfaceDataProxy(const QImage &image, QObject *parent = 0);
+ explicit QHeightMapSurfaceDataProxy(const QString &filename, QObject *parent = 0);
virtual ~QHeightMapSurfaceDataProxy();
void setHeightMap(const QImage &image);
@@ -59,8 +60,8 @@ public:
float maxZValue() const;
signals:
- void heightMapChanged(QImage image);
- void heightMapFileChanged(QString filename);
+ void heightMapChanged(const QImage &image);
+ void heightMapFileChanged(const QString &filename);
void minXValueChanged(float value);
void maxXValueChanged(float value);
void minZValueChanged(float value);
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
index 0e947666..5cc9993a 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
@@ -31,7 +31,7 @@
#include "qheightmapsurfacedataproxy.h"
#include "qsurfacedataproxy_p.h"
-#include <QTimer>
+#include <QtCore/QTimer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qitemmodelbardataproxy.cpp b/src/datavisualization/data/qitemmodelbardataproxy.cpp
index 97289da1..0e880c77 100644
--- a/src/datavisualization/data/qitemmodelbardataproxy.cpp
+++ b/src/datavisualization/data/qitemmodelbardataproxy.cpp
@@ -18,7 +18,6 @@
#include "qitemmodelbardataproxy_p.h"
#include "baritemmodelhandler_p.h"
-#include <QTimer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -105,6 +104,12 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \qmlproperty string ItemModelBarDataProxy::rotationRole
+ *
+ * Defines the rotation role for the mapping.
+ */
+
+/*!
* \qmlproperty list ItemModelBarDataProxy::rowCategories
* The row categories of the mapping. Only items with row roles that are found in this list are
* included when the data is resolved. The rows are ordered in the same order as they are in this list.
@@ -195,6 +200,27 @@ QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemMod
/*!
* Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
* ownership of the \a itemModel, as typically item models are owned by other controls.
+ * The role mappings are set with \a rowRole, \a columnRole, \a valueRole, and \a rotationRole.
+ */
+QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemModel,
+ const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole,
+ const QString &rotationRole,
+ QObject *parent)
+ : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_valueRole = valueRole;
+ dptr()->m_rotationRole = rotationRole;
+ dptr()->connectItemModelHandler();
+}
+
+/*!
+ * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
+ * ownership of the \a itemModel, as typically item models are owned by other controls.
* The role mappings are set with \a rowRole, \a columnRole, and \a valueRole.
* Row and column categories are set with \a rowCategories and \a columnCategories.
* This constructor also sets autoRowCategories and autoColumnCategories to false.
@@ -220,6 +246,35 @@ QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemMod
}
/*!
+ * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
+ * ownership of the \a itemModel, as typically item models are owned by other controls.
+ * The role mappings are set with \a rowRole, \a columnRole, \a valueRole, and \a rotationRole.
+ * Row and column categories are set with \a rowCategories and \a columnCategories.
+ * This constructor also sets autoRowCategories and autoColumnCategories to false.
+ */
+QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemModel,
+ const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole,
+ const QString &rotationRole,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories,
+ QObject *parent)
+ : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_valueRole = valueRole;
+ dptr()->m_rotationRole = rotationRole;
+ dptr()->m_rowCategories = rowCategories;
+ dptr()->m_columnCategories = columnCategories;
+ dptr()->m_autoRowCategories = false;
+ dptr()->m_autoColumnCategories = false;
+ dptr()->connectItemModelHandler();
+}
+
+/*!
* Destroys QItemModelBarDataProxy.
*/
QItemModelBarDataProxy::~QItemModelBarDataProxy()
@@ -297,6 +352,24 @@ QString QItemModelBarDataProxy::valueRole() const
}
/*!
+ * \property QItemModelBarDataProxy::rotationRole
+ *
+ * Defines the rotation role for the mapping.
+ */
+void QItemModelBarDataProxy::setRotationRole(const QString &role)
+{
+ if (dptr()->m_rotationRole != role) {
+ dptr()->m_rotationRole = role;
+ emit rotationRoleChanged(role);
+ }
+}
+
+QString QItemModelBarDataProxy::rotationRole() const
+{
+ return dptrc()->m_rotationRole;
+}
+
+/*!
* \property QItemModelBarDataProxy::rowCategories
*
* Defines the row categories for the mapping.
@@ -305,7 +378,7 @@ void QItemModelBarDataProxy::setRowCategories(const QStringList &categories)
{
if (dptr()->m_rowCategories != categories) {
dptr()->m_rowCategories = categories;
- emit rowCategoriesChanged(categories);
+ emit rowCategoriesChanged();
}
}
@@ -323,7 +396,7 @@ void QItemModelBarDataProxy::setColumnCategories(const QStringList &categories)
{
if (dptr()->m_columnCategories != categories) {
dptr()->m_columnCategories = categories;
- emit columnCategoriesChanged(categories);
+ emit columnCategoriesChanged();
}
}
@@ -392,24 +465,26 @@ bool QItemModelBarDataProxy::autoColumnCategories() const
}
/*!
- * Changes \a rowRole, \a columnRole, \a valueRole, \a rowCategories and \a columnCategories to the
- * mapping.
+ * Changes \a rowRole, \a columnRole, \a valueRole, \a rotationRole,
+ * \a rowCategories and \a columnCategories to the mapping.
*/
void QItemModelBarDataProxy::remap(const QString &rowRole,
const QString &columnRole,
const QString &valueRole,
+ const QString &rotationRole,
const QStringList &rowCategories,
const QStringList &columnCategories)
{
setRowRole(rowRole);
setColumnRole(columnRole);
setValueRole(valueRole);
+ setRotationRole(rotationRole);
setRowCategories(rowCategories);
setColumnCategories(columnCategories);
}
/*!
- * /return index of the specified \a category in row categories list.
+ * \return index of the specified \a category in row categories list.
* If the row categories list is empty, -1 is returned.
* \note If the automatic row categories generation is in use, this method will
* not return a valid index before the data in the model is resolved for the first time.
@@ -420,7 +495,7 @@ int QItemModelBarDataProxy::rowCategoryIndex(const QString &category)
}
/*!
- * /return index of the specified \a category in column categories list.
+ * \return index of the specified \a category in column categories list.
* If the category is not found, -1 is returned.
* \note If the automatic column categories generation is in use, this method will
* not return a valid index before the data in the model is resolved for the first time.
@@ -477,6 +552,8 @@ void QItemModelBarDataProxyPrivate::connectItemModelHandler()
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
QObject::connect(qptr(), &QItemModelBarDataProxy::valueRoleChanged,
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelBarDataProxy::rotationRoleChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
QObject::connect(qptr(), &QItemModelBarDataProxy::rowCategoriesChanged,
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
QObject::connect(qptr(), &QItemModelBarDataProxy::columnCategoriesChanged,
diff --git a/src/datavisualization/data/qitemmodelbardataproxy.h b/src/datavisualization/data/qitemmodelbardataproxy.h
index 4e62b4c3..f19b4445 100644
--- a/src/datavisualization/data/qitemmodelbardataproxy.h
+++ b/src/datavisualization/data/qitemmodelbardataproxy.h
@@ -20,8 +20,7 @@
#define QITEMMODELBARDATAPROXY_H
#include <QtDataVisualization/qbardataproxy.h>
-#include <QAbstractItemModel>
-#include <QStringList>
+#include <QtCore/QAbstractItemModel>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -34,6 +33,7 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelBarDataProxy : public QBarDataProxy
Q_PROPERTY(QString rowRole READ rowRole WRITE setRowRole NOTIFY rowRoleChanged)
Q_PROPERTY(QString columnRole READ columnRole WRITE setColumnRole NOTIFY columnRoleChanged)
Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole NOTIFY valueRoleChanged)
+ Q_PROPERTY(QString rotationRole READ rotationRole WRITE setRotationRole NOTIFY rotationRoleChanged)
Q_PROPERTY(QStringList rowCategories READ rowCategories WRITE setRowCategories NOTIFY rowCategoriesChanged)
Q_PROPERTY(QStringList columnCategories READ columnCategories WRITE setColumnCategories NOTIFY columnCategoriesChanged)
Q_PROPERTY(bool useModelCategories READ useModelCategories WRITE setUseModelCategories NOTIFY useModelCategoriesChanged)
@@ -50,8 +50,15 @@ public:
QObject *parent = 0);
QItemModelBarDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
const QString &columnRole, const QString &valueRole,
+ const QString &rotationRole, QObject *parent = 0);
+ QItemModelBarDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ const QString &columnRole, const QString &valueRole,
const QStringList &rowCategories, const QStringList &columnCategories,
QObject *parent = 0);
+ QItemModelBarDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ const QString &columnRole, const QString &valueRole,
+ const QString &rotationRole, const QStringList &rowCategories,
+ const QStringList &columnCategories, QObject *parent = 0);
virtual ~QItemModelBarDataProxy();
void setItemModel(const QAbstractItemModel *itemModel);
@@ -63,6 +70,8 @@ public:
QString columnRole() const;
void setValueRole(const QString &role);
QString valueRole() const;
+ void setRotationRole(const QString &role);
+ QString rotationRole() const;
void setRowCategories(const QStringList &categories);
QStringList rowCategories() const;
@@ -77,7 +86,8 @@ public:
bool autoColumnCategories() const;
void remap(const QString &rowRole, const QString &columnRole,
- const QString &valueRole, const QStringList &rowCategories,
+ const QString &valueRole, const QString &rotationRole,
+ const QStringList &rowCategories,
const QStringList &columnCategories);
Q_INVOKABLE int rowCategoryIndex(const QString& category);
@@ -85,11 +95,12 @@ public:
signals:
void itemModelChanged(const QAbstractItemModel* itemModel);
- void rowRoleChanged(QString role);
- void columnRoleChanged(QString role);
- void valueRoleChanged(QString role);
- void rowCategoriesChanged(QStringList categories);
- void columnCategoriesChanged(QStringList categories);
+ void rowRoleChanged(const QString &role);
+ void columnRoleChanged(const QString &role);
+ void valueRoleChanged(const QString &role);
+ void rotationRoleChanged(const QString &role);
+ void rowCategoriesChanged();
+ void columnCategoriesChanged();
void useModelCategoriesChanged(bool enable);
void autoRowCategoriesChanged(bool enable);
void autoColumnCategoriesChanged(bool enable);
diff --git a/src/datavisualization/data/qitemmodelbardataproxy_p.h b/src/datavisualization/data/qitemmodelbardataproxy_p.h
index 0c987a00..2fd74bb2 100644
--- a/src/datavisualization/data/qitemmodelbardataproxy_p.h
+++ b/src/datavisualization/data/qitemmodelbardataproxy_p.h
@@ -53,6 +53,7 @@ private:
QString m_rowRole;
QString m_columnRole;
QString m_valueRole;
+ QString m_rotationRole;
// For row/column items, sort items into these categories. Other categories are ignored.
QStringList m_rowCategories;
diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy.cpp b/src/datavisualization/data/qitemmodelscatterdataproxy.cpp
index 1edee53c..a5287abc 100644
--- a/src/datavisualization/data/qitemmodelscatterdataproxy.cpp
+++ b/src/datavisualization/data/qitemmodelscatterdataproxy.cpp
@@ -18,7 +18,6 @@
#include "qitemmodelscatterdataproxy_p.h"
#include "scatteritemmodelhandler_p.h"
-#include <QTimer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -93,6 +92,16 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \qmlproperty string ItemModelScatterDataProxy::rotationRole
+ *
+ * Defines the rotation role for the mapping.
+ * The model may supply the value for rotation as either variant that is directly convertible
+ * to QQuaternion, or as one of the string representations: \c{"scalar,x,y,z"} or \c{"@angle,x,y,z"}. The first
+ * will construct the quaternion directly with given values, and the second one will construct
+ * the quaternion using QQuaternion::fromAxisAndAngle() method.
+ */
+
+/*!
* Constructs QItemModelScatterDataProxy with optional \a parent.
*/
QItemModelScatterDataProxy::QItemModelScatterDataProxy(QObject *parent)
@@ -134,6 +143,28 @@ QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel
}
/*!
+ * Constructs QItemModelScatterDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
+ * ownership of the \a itemModel, as typically item models are owned by other controls.
+ * The xPosRole property is set to \a xPosRole, yPosRole property to \a yPosRole, zPosRole property
+ * to \a zPosRole, and rotationRole property to \a rotationRole.
+ */
+QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel *itemModel,
+ const QString &xPosRole,
+ const QString &yPosRole,
+ const QString &zPosRole,
+ const QString &rotationRole,
+ QObject *parent)
+ : QScatterDataProxy(new QItemModelScatterDataProxyPrivate(this), parent)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_xPosRole = xPosRole;
+ dptr()->m_yPosRole = yPosRole;
+ dptr()->m_zPosRole = zPosRole;
+ dptr()->m_rotationRole = rotationRole;
+ dptr()->connectItemModelHandler();
+}
+
+/*!
* Destroys QItemModelScatterDataProxy.
*/
QItemModelScatterDataProxy::~QItemModelScatterDataProxy()
@@ -211,14 +242,38 @@ QString QItemModelScatterDataProxy::zPosRole() const
}
/*!
- * Changes \a xPosRole, \a yPosRole and \a zPosRole mapping.
+ * \property QItemModelScatterDataProxy::rotationRole
+ *
+ * Defines the rotation role for the mapping.
+ *
+ * The model may supply the value for rotation as either variant that is directly convertible
+ * to QQuartenion, or as one of the string representations: \c{"scalar,x,y,z"} or \c{"@angle,x,y,z"}. The first
+ * will construct the quaternion directly with given values, and the second one will construct
+ * the quaternion using QQuaternion::fromAxisAndAngle() method.
+ */
+void QItemModelScatterDataProxy::setRotationRole(const QString &role)
+{
+ if (dptr()->m_rotationRole != role) {
+ dptr()->m_rotationRole = role;
+ emit rotationRoleChanged(role);
+ }
+}
+
+QString QItemModelScatterDataProxy::rotationRole() const
+{
+ return dptrc()->m_rotationRole;
+}
+
+/*!
+ * Changes \a xPosRole, \a yPosRole, \a zPosRole, and \a rotationRole mapping.
*/
void QItemModelScatterDataProxy::remap(const QString &xPosRole, const QString &yPosRole,
- const QString &zPosRole)
+ const QString &zPosRole, const QString &rotationRole)
{
setXPosRole(xPosRole);
setYPosRole(yPosRole);
setZPosRole(zPosRole);
+ setRotationRole(rotationRole);
}
/*!
diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy.h b/src/datavisualization/data/qitemmodelscatterdataproxy.h
index 0f69afa7..c6d2245d 100644
--- a/src/datavisualization/data/qitemmodelscatterdataproxy.h
+++ b/src/datavisualization/data/qitemmodelscatterdataproxy.h
@@ -20,8 +20,8 @@
#define QITEMMODELSCATTERDATAPROXY_H
#include <QtDataVisualization/qscatterdataproxy.h>
-#include <QAbstractItemModel>
-#include <QStringList>
+#include <QtCore/QAbstractItemModel>
+#include <QtCore/QString>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -34,6 +34,7 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelScatterDataProxy : public QScatterDa
Q_PROPERTY(QString xPosRole READ xPosRole WRITE setXPosRole NOTIFY xPosRoleChanged)
Q_PROPERTY(QString yPosRole READ yPosRole WRITE setYPosRole NOTIFY yPosRoleChanged)
Q_PROPERTY(QString zPosRole READ zPosRole WRITE setZPosRole NOTIFY zPosRoleChanged)
+ Q_PROPERTY(QString rotationRole READ rotationRole WRITE setRotationRole NOTIFY rotationRoleChanged)
public:
explicit QItemModelScatterDataProxy(QObject *parent = 0);
@@ -41,6 +42,10 @@ public:
QItemModelScatterDataProxy(const QAbstractItemModel *itemModel,
const QString &xPosRole, const QString &yPosRole,
const QString &zPosRole, QObject *parent = 0);
+ QItemModelScatterDataProxy(const QAbstractItemModel *itemModel,
+ const QString &xPosRole, const QString &yPosRole,
+ const QString &zPosRole, const QString &rotationRole,
+ QObject *parent = 0);
virtual ~QItemModelScatterDataProxy();
void setItemModel(const QAbstractItemModel *itemModel);
@@ -52,14 +57,18 @@ public:
QString yPosRole() const;
void setZPosRole(const QString &role);
QString zPosRole() const;
+ void setRotationRole(const QString &role);
+ QString rotationRole() const;
- void remap(const QString &xPosRole, const QString &yPosRole, const QString &zPosRole);
+ void remap(const QString &xPosRole, const QString &yPosRole, const QString &zPosRole,
+ const QString &rotationRole);
signals:
void itemModelChanged(const QAbstractItemModel* itemModel);
- void xPosRoleChanged(QString role);
- void yPosRoleChanged(QString role);
- void zPosRoleChanged(QString role);
+ void xPosRoleChanged(const QString &role);
+ void yPosRoleChanged(const QString &role);
+ void zPosRoleChanged(const QString &role);
+ void rotationRoleChanged(const QString &role);
protected:
QItemModelScatterDataProxyPrivate *dptr();
diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy_p.h b/src/datavisualization/data/qitemmodelscatterdataproxy_p.h
index b8804c5c..4e1f321f 100644
--- a/src/datavisualization/data/qitemmodelscatterdataproxy_p.h
+++ b/src/datavisualization/data/qitemmodelscatterdataproxy_p.h
@@ -52,6 +52,7 @@ private:
QString m_xPosRole;
QString m_yPosRole;
QString m_zPosRole;
+ QString m_rotationRole;
friend class ScatterItemModelHandler;
friend class QItemModelScatterDataProxy;
diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp b/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp
index 0c206b81..f15a8923 100644
--- a/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp
@@ -18,7 +18,6 @@
#include "qitemmodelsurfacedataproxy_p.h"
#include "surfaceitemmodelhandler_p.h"
-#include <QTimer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -30,7 +29,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*
* QItemModelSurfaceDataProxy allows you to use QAbstractItemModel derived models as a data source
* for Q3DSurface. It uses the defined mappings to map data from the model to rows, columns, and
- * values of Q3DSurface graph.
+ * surface points of Q3DSurface graph.
*
* Data is resolved asynchronously whenever the mapping or the model changes.
* QSurfaceDataProxy::arrayReset() is emitted when the data has been resolved.
@@ -39,8 +38,12 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*
* 1) If useModelCategories property is set to true, this proxy will map rows and
* columns of QAbstractItemModel to rows and columns of Q3DSurface, and uses the value returned for
- * Qt::DisplayRole as bar value by default.
- * The value role to be used can be redefined if Qt::DisplayRole is not suitable.
+ * Qt::DisplayRole as Y-position by default. Row and column headers are used for Z-position and
+ * X-position by default, if they can be converted to floats. Otherwise row and column indices
+ * are used.
+ * The Y-position role to be used can be redefined if Qt::DisplayRole is not suitable.
+ * The Z-position and X-position roles to be used can be redefined if the headers or indices
+ * are not suitable.
*
* 2) For models that do not have data already neatly sorted into rows and columns, such as
* QAbstractListModel based models, you can define a role from the model to map for each of row,
@@ -105,10 +108,18 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
- * \qmlproperty string ItemModelSurfaceDataProxy::valueRole
- * The value role of the mapping.
- * The value indicated by value role is set as Y-coodrinate value of the
- * QSurfaceDataItem when model data is resolved.
+ * \qmlproperty string ItemModelSurfaceDataProxy::xPosRole
+ * The X position role of the mapping.
+ */
+
+/*!
+ * \qmlproperty string ItemModelSurfaceDataProxy::yPosRole
+ * The Y position role of the mapping.
+ */
+
+/*!
+ * \qmlproperty string ItemModelSurfaceDataProxy::zPosRole
+ * The Z position role of the mapping.
*/
/*!
@@ -169,17 +180,17 @@ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel
/*!
* Constructs QItemModelSurfaceDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
* ownership of the \a itemModel, as typically item models are owned by other controls.
- * The value role is set to \a valueRole.
+ * The yPosRole role is set to \a yPosRole.
* This constructor is meant to be used with models that have data properly sorted
* in rows and columns already, so it also sets useModelCategories property to true.
*/
QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
- const QString &valueRole,
+ const QString &yPosRole,
QObject *parent)
: QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent)
{
dptr()->m_itemModelHandler->setItemModel(itemModel);
- dptr()->m_valueRole = valueRole;
+ dptr()->m_yPosRole = yPosRole;
dptr()->m_useModelCategories = true;
dptr()->connectItemModelHandler();
}
@@ -187,33 +198,93 @@ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel
/*!
* Constructs QItemModelSurfaceDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
* ownership of the \a itemModel, as typically item models are owned by other controls.
- * The role mappings are set with \a rowRole, \a columnRole, and \a valueRole.
+ * The role mappings are set with \a rowRole, \a columnRole, and \a yPosRole.
+ * The zPosRole and the xPosRole are set to \a rowRole and \a columnRole, respectively.
+ */
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
+ const QString &rowRole,
+ const QString &columnRole,
+ const QString &yPosRole,
+ QObject *parent)
+ : QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_xPosRole = columnRole;
+ dptr()->m_yPosRole = yPosRole;
+ dptr()->m_zPosRole = rowRole;
+ dptr()->connectItemModelHandler();
+}
+
+/*!
+ * Constructs QItemModelSurfaceDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
+ * ownership of the \a itemModel, as typically item models are owned by other controls.
+ * The role mappings are set with \a rowRole, \a columnRole, \a xPosRole, \a yPosRole, and
+ * \a zPosRole.
+ */
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
+ const QString &rowRole,
+ const QString &columnRole,
+ const QString &xPosRole,
+ const QString &yPosRole,
+ const QString &zPosRole,
+ QObject *parent)
+ : QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_xPosRole = xPosRole;
+ dptr()->m_yPosRole = yPosRole;
+ dptr()->m_zPosRole = zPosRole;
+ dptr()->connectItemModelHandler();
+}
+
+/*!
+ * Constructs QItemModelSurfaceDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
+ * ownership of the \a itemModel, as typically item models are owned by other controls.
+ * The role mappings are set with \a rowRole, \a columnRole, and \a yPosRole.
+ * The zPosRole and the xPosRole are set to \a rowRole and \a columnRole, respectively.
+ * Row and column categories are set with \a rowCategories and \a columnCategories.
+ * This constructor also sets autoRowCategories and autoColumnCategories to false.
*/
QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
- const QString &valueRole,
+ const QString &yPosRole,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories,
QObject *parent)
: QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent)
{
dptr()->m_itemModelHandler->setItemModel(itemModel);
dptr()->m_rowRole = rowRole;
dptr()->m_columnRole = columnRole;
- dptr()->m_valueRole = valueRole;
+ dptr()->m_xPosRole = columnRole;
+ dptr()->m_yPosRole = yPosRole;
+ dptr()->m_zPosRole = rowRole;
+ dptr()->m_rowCategories = rowCategories;
+ dptr()->m_columnCategories = columnCategories;
+ dptr()->m_autoRowCategories = false;
+ dptr()->m_autoColumnCategories = false;
dptr()->connectItemModelHandler();
}
/*!
* Constructs QItemModelSurfaceDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
* ownership of the \a itemModel, as typically item models are owned by other controls.
- * The role mappings are set with \a rowRole, \a columnRole, and \a valueRole.
+ * The role mappings are set with \a rowRole, \a columnRole, \a xPosRole, \a yPosRole,
+ * and \a zPosRole.
* Row and column categories are set with \a rowCategories and \a columnCategories.
* This constructor also sets autoRowCategories and autoColumnCategories to false.
*/
QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
- const QString &valueRole,
+ const QString &xPosRole,
+ const QString &yPosRole,
+ const QString &zPosRole,
const QStringList &rowCategories,
const QStringList &columnCategories,
QObject *parent)
@@ -222,7 +293,9 @@ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel
dptr()->m_itemModelHandler->setItemModel(itemModel);
dptr()->m_rowRole = rowRole;
dptr()->m_columnRole = columnRole;
- dptr()->m_valueRole = valueRole;
+ dptr()->m_xPosRole = xPosRole;
+ dptr()->m_yPosRole = yPosRole;
+ dptr()->m_zPosRole = zPosRole;
dptr()->m_rowCategories = rowCategories;
dptr()->m_columnCategories = columnCategories;
dptr()->m_autoRowCategories = false;
@@ -290,21 +363,57 @@ QString QItemModelSurfaceDataProxy::columnRole() const
}
/*!
- * \property QItemModelSurfaceDataProxy::valueRole
+ * \property QItemModelSurfaceDataProxy::xPosRole
+ *
+ * Defines the X position role for the mapping.
+ */
+void QItemModelSurfaceDataProxy::setXPosRole(const QString &role)
+{
+ if (dptr()->m_xPosRole != role) {
+ dptr()->m_xPosRole = role;
+ emit xPosRoleChanged(role);
+ }
+}
+
+QString QItemModelSurfaceDataProxy::xPosRole() const
+{
+ return dptrc()->m_xPosRole;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::yPosRole
*
- * Defines the value role for the mapping.
+ * Defines the Y position role for the mapping.
*/
-void QItemModelSurfaceDataProxy::setValueRole(const QString &role)
+void QItemModelSurfaceDataProxy::setYPosRole(const QString &role)
{
- if (dptr()->m_valueRole != role) {
- dptr()->m_valueRole = role;
- emit valueRoleChanged(role);
+ if (dptr()->m_yPosRole != role) {
+ dptr()->m_yPosRole = role;
+ emit yPosRoleChanged(role);
}
}
-QString QItemModelSurfaceDataProxy::valueRole() const
+QString QItemModelSurfaceDataProxy::yPosRole() const
{
- return dptrc()->m_valueRole;
+ return dptrc()->m_yPosRole;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::zPosRole
+ *
+ * Defines the Z position role for the mapping.
+ */
+void QItemModelSurfaceDataProxy::setZPosRole(const QString &role)
+{
+ if (dptr()->m_zPosRole != role) {
+ dptr()->m_zPosRole = role;
+ emit zPosRoleChanged(role);
+ }
+}
+
+QString QItemModelSurfaceDataProxy::zPosRole() const
+{
+ return dptrc()->m_zPosRole;
}
/*!
@@ -316,7 +425,7 @@ void QItemModelSurfaceDataProxy::setRowCategories(const QStringList &categories)
{
if (dptr()->m_rowCategories != categories) {
dptr()->m_rowCategories = categories;
- emit rowCategoriesChanged(categories);
+ emit rowCategoriesChanged();
}
}
@@ -334,7 +443,7 @@ void QItemModelSurfaceDataProxy::setColumnCategories(const QStringList &categori
{
if (dptr()->m_columnCategories != categories) {
dptr()->m_columnCategories = categories;
- emit columnCategoriesChanged(categories);
+ emit columnCategoriesChanged();
}
}
@@ -403,24 +512,28 @@ bool QItemModelSurfaceDataProxy::autoColumnCategories() const
}
/*!
- * Changes \a rowRole, \a columnRole, \a valueRole, \a rowCategories and \a columnCategories to the
- * mapping.
+ * Changes \a rowRole, \a columnRole, \a xPosRole, \a yPosRole, \a zPosRole,
+ * \a rowCategories and \a columnCategories to the mapping.
*/
void QItemModelSurfaceDataProxy::remap(const QString &rowRole,
const QString &columnRole,
- const QString &valueRole,
+ const QString &xPosRole,
+ const QString &yPosRole,
+ const QString &zPosRole,
const QStringList &rowCategories,
const QStringList &columnCategories)
{
setRowRole(rowRole);
setColumnRole(columnRole);
- setValueRole(valueRole);
+ setXPosRole(xPosRole);
+ setYPosRole(yPosRole);
+ setZPosRole(zPosRole);
setRowCategories(rowCategories);
setColumnCategories(columnCategories);
}
/*!
- * /return index of the specified \a category in row categories list.
+ * \return index of the specified \a category in row categories list.
* If the row categories list is empty, -1 is returned.
* \note If the automatic row categories generation is in use, this method will
* not return a valid index before the data in the model is resolved for the first time.
@@ -431,7 +544,7 @@ int QItemModelSurfaceDataProxy::rowCategoryIndex(const QString &category)
}
/*!
- * /return index of the specified \a category in column categories list.
+ * \return index of the specified \a category in column categories list.
* If the category is not found, -1 is returned.
* \note If the automatic column categories generation is in use, this method will
* not return a valid index before the data in the model is resolved for the first time.
@@ -486,7 +599,11 @@ void QItemModelSurfaceDataProxyPrivate::connectItemModelHandler()
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
QObject::connect(qptr(), &QItemModelSurfaceDataProxy::columnRoleChanged,
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
- QObject::connect(qptr(), &QItemModelSurfaceDataProxy::valueRoleChanged,
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::xPosRoleChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::yPosRoleChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::zPosRoleChanged,
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
QObject::connect(qptr(), &QItemModelSurfaceDataProxy::rowCategoriesChanged,
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy.h b/src/datavisualization/data/qitemmodelsurfacedataproxy.h
index d1e0f2b8..b1ebbeed 100644
--- a/src/datavisualization/data/qitemmodelsurfacedataproxy.h
+++ b/src/datavisualization/data/qitemmodelsurfacedataproxy.h
@@ -20,8 +20,8 @@
#define QITEMMODELSURFACEDATAPROXY_H
#include <QtDataVisualization/qsurfacedataproxy.h>
-#include <QAbstractItemModel>
-#include <QStringList>
+#include <QtCore/QAbstractItemModel>
+#include <QtCore/QStringList>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -33,7 +33,9 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelSurfaceDataProxy : public QSurfaceDa
Q_PROPERTY(const QAbstractItemModel* itemModel READ itemModel WRITE setItemModel NOTIFY itemModelChanged)
Q_PROPERTY(QString rowRole READ rowRole WRITE setRowRole NOTIFY rowRoleChanged)
Q_PROPERTY(QString columnRole READ columnRole WRITE setColumnRole NOTIFY columnRoleChanged)
- Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole NOTIFY valueRoleChanged)
+ Q_PROPERTY(QString xPosRole READ xPosRole WRITE setXPosRole NOTIFY xPosRoleChanged)
+ Q_PROPERTY(QString yPosRole READ yPosRole WRITE setYPosRole NOTIFY yPosRoleChanged)
+ Q_PROPERTY(QString zPosRole READ zPosRole WRITE setZPosRole NOTIFY zPosRoleChanged)
Q_PROPERTY(QStringList rowCategories READ rowCategories WRITE setRowCategories NOTIFY rowCategoriesChanged)
Q_PROPERTY(QStringList columnCategories READ columnCategories WRITE setColumnCategories NOTIFY columnCategoriesChanged)
Q_PROPERTY(bool useModelCategories READ useModelCategories WRITE setUseModelCategories NOTIFY useModelCategoriesChanged)
@@ -43,13 +45,22 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelSurfaceDataProxy : public QSurfaceDa
public:
explicit QItemModelSurfaceDataProxy(QObject *parent = 0);
QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, QObject *parent = 0);
- QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &valueRole,
+ QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &yPosRole,
QObject *parent = 0);
QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
- const QString &columnRole, const QString &valueRole,
+ const QString &columnRole, const QString &yPosRole,
QObject *parent = 0);
QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
- const QString &columnRole, const QString &valueRole,
+ const QString &columnRole, const QString &xPosRole,
+ const QString &yPosRole, const QString &zPosRole,
+ QObject *parent = 0);
+ QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ const QString &columnRole, const QString &yPosRole,
+ const QStringList &rowCategories, const QStringList &columnCategories,
+ QObject *parent = 0);
+ QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ const QString &columnRole, const QString &xPosRole,
+ const QString &yPosRole, const QString &zPosRole,
const QStringList &rowCategories, const QStringList &columnCategories,
QObject *parent = 0);
virtual ~QItemModelSurfaceDataProxy();
@@ -61,8 +72,12 @@ public:
QString rowRole() const;
void setColumnRole(const QString &role);
QString columnRole() const;
- void setValueRole(const QString &role);
- QString valueRole() const;
+ void setXPosRole(const QString &role);
+ QString xPosRole() const;
+ void setYPosRole(const QString &role);
+ QString yPosRole() const;
+ void setZPosRole(const QString &role);
+ QString zPosRole() const;
void setRowCategories(const QStringList &categories);
QStringList rowCategories() const;
@@ -77,7 +92,8 @@ public:
bool autoColumnCategories() const;
void remap(const QString &rowRole, const QString &columnRole,
- const QString &valueRole, const QStringList &rowCategories,
+ const QString &xPosRole, const QString &yPosRole,
+ const QString &zPosRole, const QStringList &rowCategories,
const QStringList &columnCategories);
Q_INVOKABLE int rowCategoryIndex(const QString& category);
@@ -85,11 +101,13 @@ public:
signals:
void itemModelChanged(const QAbstractItemModel* itemModel);
- void rowRoleChanged(QString role);
- void columnRoleChanged(QString role);
- void valueRoleChanged(QString role);
- void rowCategoriesChanged(QStringList categories);
- void columnCategoriesChanged(QStringList categories);
+ void rowRoleChanged(const QString &role);
+ void columnRoleChanged(const QString &role);
+ void xPosRoleChanged(const QString &role);
+ void yPosRoleChanged(const QString &role);
+ void zPosRoleChanged(const QString &role);
+ void rowCategoriesChanged();
+ void columnCategoriesChanged();
void useModelCategoriesChanged(bool enable);
void autoRowCategoriesChanged(bool enable);
void autoColumnCategoriesChanged(bool enable);
diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h b/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h
index 5049a25e..0aaea8fd 100644
--- a/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h
+++ b/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h
@@ -52,7 +52,9 @@ private:
QString m_rowRole;
QString m_columnRole;
- QString m_valueRole;
+ QString m_xPosRole;
+ QString m_yPosRole;
+ QString m_zPosRole;
// For row/column items, sort items into these categories. Other categories are ignored.
QStringList m_rowCategories;
diff --git a/src/datavisualization/data/qscatterdataitem.cpp b/src/datavisualization/data/qscatterdataitem.cpp
index 33f8bed0..9751dfeb 100644
--- a/src/datavisualization/data/qscatterdataitem.cpp
+++ b/src/datavisualization/data/qscatterdataitem.cpp
@@ -52,6 +52,16 @@ QScatterDataItem::QScatterDataItem(const QVector3D &position)
}
/*!
+ * Constructs QScatterDataItem with \a position and \a rotation.
+ */
+QScatterDataItem::QScatterDataItem(const QVector3D &position, const QQuaternion &rotation)
+ : d_ptr(0),
+ m_position(position),
+ m_rotation(rotation)
+{
+}
+
+/*!
* Constructs a copy of \a other.
*/
QScatterDataItem::QScatterDataItem(const QScatterDataItem &other)
diff --git a/src/datavisualization/data/qscatterdataitem.h b/src/datavisualization/data/qscatterdataitem.h
index d2ef3bcc..87cc1fc5 100644
--- a/src/datavisualization/data/qscatterdataitem.h
+++ b/src/datavisualization/data/qscatterdataitem.h
@@ -20,9 +20,7 @@
#define QSCATTERDATAITEM_H
#include <QtDataVisualization/qdatavisualizationglobal.h>
-
-#include <QVector3D>
-#include <QQuaternion>
+#include <QtGui/QQuaternion>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -33,6 +31,7 @@ class QT_DATAVISUALIZATION_EXPORT QScatterDataItem
public:
QScatterDataItem();
QScatterDataItem(const QVector3D &position);
+ QScatterDataItem(const QVector3D &position, const QQuaternion &rotation);
QScatterDataItem(const QScatterDataItem &other);
~QScatterDataItem();
@@ -50,7 +49,7 @@ public:
inline float z() const { return m_position.z(); }
protected:
- virtual void createExtraData();
+ void createExtraData();
QScatterDataItemPrivate *d_ptr;
diff --git a/src/datavisualization/data/qscatterdataproxy.cpp b/src/datavisualization/data/qscatterdataproxy.cpp
index b5e3863d..dbbb4384 100644
--- a/src/datavisualization/data/qscatterdataproxy.cpp
+++ b/src/datavisualization/data/qscatterdataproxy.cpp
@@ -98,7 +98,7 @@ QScatterDataProxy::~QScatterDataProxy()
*
* The series this proxy is attached to.
*/
-QScatter3DSeries *QScatterDataProxy::series()
+QScatter3DSeries *QScatterDataProxy::series() const
{
return static_cast<QScatter3DSeries *>(d_ptr->series());
}
diff --git a/src/datavisualization/data/qscatterdataproxy.h b/src/datavisualization/data/qscatterdataproxy.h
index b8179166..fe561bbd 100644
--- a/src/datavisualization/data/qscatterdataproxy.h
+++ b/src/datavisualization/data/qscatterdataproxy.h
@@ -43,7 +43,7 @@ public:
explicit QScatterDataProxy(QObject *parent = 0);
virtual ~QScatterDataProxy();
- QScatter3DSeries *series();
+ QScatter3DSeries *series() const;
int itemCount() const;
const QScatterDataArray *array() const;
const QScatterDataItem *itemAt(int index) const;
diff --git a/src/datavisualization/data/qsurface3dseries.cpp b/src/datavisualization/data/qsurface3dseries.cpp
index e5f06cc6..b7e15014 100644
--- a/src/datavisualization/data/qsurface3dseries.cpp
+++ b/src/datavisualization/data/qsurface3dseries.cpp
@@ -221,7 +221,7 @@ void QSurface3DSeries::setSelectedPoint(const QPoint &position)
{
// Don't do this in private to avoid loops, as that is used for callback from controller.
if (d_ptr->m_controller)
- static_cast<Surface3DController *>(d_ptr->m_controller)->setSelectedPoint(position, this);
+ static_cast<Surface3DController *>(d_ptr->m_controller)->setSelectedPoint(position, this, true);
else
dptr()->setSelectedPoint(position);
}
diff --git a/src/datavisualization/data/qsurface3dseries.h b/src/datavisualization/data/qsurface3dseries.h
index b8a1a62b..8347104e 100644
--- a/src/datavisualization/data/qsurface3dseries.h
+++ b/src/datavisualization/data/qsurface3dseries.h
@@ -65,7 +65,7 @@ public:
signals:
void dataProxyChanged(QSurfaceDataProxy *proxy);
- void selectedPointChanged(QPoint position);
+ void selectedPointChanged(const QPoint &position);
void flatShadingEnabledChanged(bool enable);
void flatShadingSupportedChanged(bool enable);
void drawModeChanged(QSurface3DSeries::DrawFlags mode);
diff --git a/src/datavisualization/data/qsurfacedataitem.h b/src/datavisualization/data/qsurfacedataitem.h
index f305952b..1e4a384d 100644
--- a/src/datavisualization/data/qsurfacedataitem.h
+++ b/src/datavisualization/data/qsurfacedataitem.h
@@ -20,8 +20,7 @@
#define QSURFACEDATAITEM_H
#include <QtDataVisualization/qdatavisualizationglobal.h>
-
-#include <QVector3D>
+#include <QtGui/QVector3D>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -47,7 +46,7 @@ public:
inline float z() const { return m_position.z(); }
protected:
- virtual void createExtraData();
+ void createExtraData();
QSurfaceDataItemPrivate *d_ptr;
diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp
index 43ce40eb..34cea326 100644
--- a/src/datavisualization/data/qsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qsurfacedataproxy.cpp
@@ -131,7 +131,7 @@ QSurfaceDataProxy::~QSurfaceDataProxy()
*
* The series this proxy is attached to.
*/
-QSurface3DSeries *QSurfaceDataProxy::series()
+QSurface3DSeries *QSurfaceDataProxy::series() const
{
return static_cast<QSurface3DSeries *>(d_ptr->series());
}
@@ -186,6 +186,15 @@ void QSurfaceDataProxy::setItem(int rowIndex, int columnIndex, const QSurfaceDat
}
/*!
+ * Changes a single item at \a position to the \a item.
+ * The X-value of \a position indicates the row and the Y-value indicates the column.
+ */
+void QSurfaceDataProxy::setItem(const QPoint &position, const QSurfaceDataItem &item)
+{
+ setItem(position.x(), position.y(), item);
+}
+
+/*!
* Adds a new \a row to the end of array. The new \a row must have
* the same number of columns as the rows at the initial array.
*
@@ -259,6 +268,29 @@ const QSurfaceDataArray *QSurfaceDataProxy::array() const
}
/*!
+ * \return pointer to the item at \a rowIndex, \a columnIndex. It is guaranteed to be valid only
+ * until the next call that modifies data.
+ */
+const QSurfaceDataItem *QSurfaceDataProxy::itemAt(int rowIndex, int columnIndex) const
+{
+ const QSurfaceDataArray &dataArray = *dptrc()->m_dataArray;
+ Q_ASSERT(rowIndex >= 0 && rowIndex < dataArray.size());
+ const QSurfaceDataRow &dataRow = *dataArray[rowIndex];
+ Q_ASSERT(columnIndex >= 0 && columnIndex < dataRow.size());
+ return &dataRow.at(columnIndex);
+}
+
+/*!
+ * \return pointer to the item at \a position. The X-value of \a position indicates the row
+ * and the Y-value indicates the column. The item is guaranteed to be valid only
+ * until the next call that modifies data.
+ */
+const QSurfaceDataItem *QSurfaceDataProxy::itemAt(const QPoint &position) const
+{
+ return itemAt(position.x(), position.y());
+}
+
+/*!
* \property QSurfaceDataProxy::rowCount
*
* \return number of rows in the data.
@@ -282,15 +314,6 @@ int QSurfaceDataProxy::columnCount() const
}
/*!
- * \return pointer to the item at \a index. It is guaranteed to be valid only until the next call that
- * modifies data.
- */
-const QSurfaceDataItem *QSurfaceDataProxy::itemAt(int index) const
-{
- return &dptrc()->m_dataArray->at(index)->at(2);
-}
-
-/*!
* \internal
*/
QSurfaceDataProxyPrivate *QSurfaceDataProxy::dptr()
diff --git a/src/datavisualization/data/qsurfacedataproxy.h b/src/datavisualization/data/qsurfacedataproxy.h
index 0933faf6..475f1f2d 100644
--- a/src/datavisualization/data/qsurfacedataproxy.h
+++ b/src/datavisualization/data/qsurfacedataproxy.h
@@ -45,11 +45,12 @@ public:
explicit QSurfaceDataProxy(QObject *parent = 0);
virtual ~QSurfaceDataProxy();
- QSurface3DSeries *series();
+ QSurface3DSeries *series() const;
int rowCount() const;
int columnCount() const;
const QSurfaceDataArray *array() const;
- const QSurfaceDataItem *itemAt(int index) const;
+ const QSurfaceDataItem *itemAt(int rowIndex, int columnIndex) const;
+ const QSurfaceDataItem *itemAt(const QPoint &position) const;
void resetArray(QSurfaceDataArray *newArray);
@@ -57,6 +58,7 @@ public:
void setRows(int rowIndex, const QSurfaceDataArray &rows);
void setItem(int rowIndex, int columnIndex, const QSurfaceDataItem &item);
+ void setItem(const QPoint &position, const QSurfaceDataItem &item);
int addRow(QSurfaceDataRow *row);
int addRows(const QSurfaceDataArray &rows);
diff --git a/src/datavisualization/data/qsurfacedataproxy_p.h b/src/datavisualization/data/qsurfacedataproxy_p.h
index 658abe32..7c3486d2 100644
--- a/src/datavisualization/data/qsurfacedataproxy_p.h
+++ b/src/datavisualization/data/qsurfacedataproxy_p.h
@@ -32,8 +32,6 @@
#include "qsurfacedataproxy.h"
#include "qabstractdataproxy_p.h"
-#include <QSize>
-
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class QSurfaceDataProxyPrivate : public QAbstractDataProxyPrivate
diff --git a/src/datavisualization/data/scatteritemmodelhandler.cpp b/src/datavisualization/data/scatteritemmodelhandler.cpp
index 1c936d08..08ed12f3 100644
--- a/src/datavisualization/data/scatteritemmodelhandler.cpp
+++ b/src/datavisualization/data/scatteritemmodelhandler.cpp
@@ -17,7 +17,6 @@
****************************************************************************/
#include "scatteritemmodelhandler_p.h"
-#include <QTimer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -92,6 +91,41 @@ void ScatterItemModelHandler::handleRowsRemoved(const QModelIndex &parent, int s
}
}
+static inline QQuaternion toQuaternion(const QVariant &variant)
+{
+ if (variant.canConvert<QQuaternion>()) {
+ return variant.value<QQuaternion>();
+ } else if (variant.canConvert<QString>()) {
+ QString s = variant.toString();
+ if (!s.isEmpty()) {
+ bool angleAndAxis = false;
+ if (s.startsWith(QLatin1Char('@'))) {
+ angleAndAxis = true;
+ s = s.mid(1);
+ }
+ if (s.count(QLatin1Char(',')) == 3) {
+ int index = s.indexOf(QLatin1Char(','));
+ int index2 = s.indexOf(QLatin1Char(','), index + 1);
+ int index3 = s.indexOf(QLatin1Char(','), index2 + 1);
+
+ bool sGood, xGood, yGood, zGood;
+ float sCoord = s.left(index).toFloat(&sGood);
+ float xCoord = s.mid(index + 1, index2 - index - 1).toFloat(&xGood);
+ float yCoord = s.mid(index2 + 1, index3 - index2 - 1).toFloat(&yGood);
+ float zCoord = s.mid(index3 + 1).toFloat(&zGood);
+
+ if (sGood && xGood && yGood && zGood) {
+ if (angleAndAxis)
+ return QQuaternion::fromAxisAndAngle(xCoord, yCoord, zCoord, sCoord);
+ else
+ return QQuaternion(sCoord, xCoord, yCoord, zCoord);
+ }
+ }
+ }
+ }
+ return QQuaternion();
+}
+
void ScatterItemModelHandler::modelPosToScatterItem(int modelRow, int modelColumn,
QScatterDataItem &item)
{
@@ -105,6 +139,8 @@ void ScatterItemModelHandler::modelPosToScatterItem(int modelRow, int modelColum
yPos = index.data(m_yPosRole).toFloat();
if (m_zPosRole != noRoleIndex)
zPos = index.data(m_zPosRole).toFloat();
+ if (m_rotationRole != noRoleIndex)
+ item.setRotation(toQuaternion(index.data(m_rotationRole)));
item.setPosition(QVector3D(xPos, yPos, zPos));
}
@@ -121,6 +157,7 @@ void ScatterItemModelHandler::resolveModel()
m_xPosRole = roleHash.key(m_proxy->xPosRole().toLatin1(), noRoleIndex);
m_yPosRole = roleHash.key(m_proxy->yPosRole().toLatin1(), noRoleIndex);
m_zPosRole = roleHash.key(m_proxy->zPosRole().toLatin1(), noRoleIndex);
+ m_rotationRole = roleHash.key(m_proxy->rotationRole().toLatin1(), noRoleIndex);
const int columnCount = m_itemModel->columnCount();
const int rowCount = m_itemModel->rowCount();
const int totalCount = rowCount * columnCount;
diff --git a/src/datavisualization/data/scatteritemmodelhandler_p.h b/src/datavisualization/data/scatteritemmodelhandler_p.h
index f0e4fa84..0661d734 100644
--- a/src/datavisualization/data/scatteritemmodelhandler_p.h
+++ b/src/datavisualization/data/scatteritemmodelhandler_p.h
@@ -58,6 +58,7 @@ private:
int m_xPosRole;
int m_yPosRole;
int m_zPosRole;
+ int m_rotationRole;
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/scatterrenderitem.cpp b/src/datavisualization/data/scatterrenderitem.cpp
index d39af816..3b2e64c5 100644
--- a/src/datavisualization/data/scatterrenderitem.cpp
+++ b/src/datavisualization/data/scatterrenderitem.cpp
@@ -33,7 +33,6 @@ ScatterRenderItem::ScatterRenderItem(const ScatterRenderItem &other)
m_visible(false)
{
m_position = other.m_position;
- m_rotation = other.m_rotation;
}
ScatterRenderItem::~ScatterRenderItem()
diff --git a/src/datavisualization/data/scatterrenderitem_p.h b/src/datavisualization/data/scatterrenderitem_p.h
index 45066dd8..eb070682 100644
--- a/src/datavisualization/data/scatterrenderitem_p.h
+++ b/src/datavisualization/data/scatterrenderitem_p.h
@@ -45,19 +45,8 @@ public:
inline const QVector3D &position() const { return m_position; }
inline void setPosition(const QVector3D &pos)
{
- if (m_position != pos) {
+ if (m_position != pos)
m_position = pos;
- // Force reformatting on next access by setting label string to null string
- if (!m_selectionLabel.isNull())
- setSelectionLabel(QString());
- }
- }
-
- inline QQuaternion rotation() const { return m_rotation; }
- inline void setRotation(const QQuaternion &rotation)
- {
- if (m_rotation != rotation)
- m_rotation = rotation;
}
inline bool isVisible() const { return m_visible; }
@@ -65,7 +54,6 @@ public:
protected:
QVector3D m_position;
- QQuaternion m_rotation;
bool m_visible;
friend class QScatterDataItem;
diff --git a/src/datavisualization/data/surfaceitemmodelhandler.cpp b/src/datavisualization/data/surfaceitemmodelhandler.cpp
index 767425e9..f4383dbf 100644
--- a/src/datavisualization/data/surfaceitemmodelhandler.cpp
+++ b/src/datavisualization/data/surfaceitemmodelhandler.cpp
@@ -20,6 +20,8 @@
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+static const int noRoleIndex = -1;
+
SurfaceItemModelHandler::SurfaceItemModelHandler(QItemModelSurfaceDataProxy *proxy, QObject *parent)
: AbstractItemModelHandler(parent),
m_proxy(proxy),
@@ -50,7 +52,9 @@ void SurfaceItemModelHandler::resolveModel()
QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
// Default to display role if no mapping
- int valueRole = roleHash.key(m_proxy->valueRole().toLatin1(), Qt::DisplayRole);
+ int xPosRole = roleHash.key(m_proxy->xPosRole().toLatin1(), noRoleIndex);
+ int yPosRole = roleHash.key(m_proxy->yPosRole().toLatin1(), Qt::DisplayRole);
+ int zPosRole = roleHash.key(m_proxy->zPosRole().toLatin1(), noRoleIndex);
int rowCount = m_itemModel->rowCount();
int columnCount = m_itemModel->columnCount();
@@ -66,15 +70,41 @@ void SurfaceItemModelHandler::resolveModel()
for (int i = 0; i < rowCount; i++) {
QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i);
for (int j = 0; j < columnCount; j++) {
+ float xPos = j;
+ float zPos = i;
+ if (xPosRole != noRoleIndex) {
+ xPos = m_itemModel->index(i, j).data(xPosRole).toFloat();
+ } else {
+ QString header = m_itemModel->headerData(j, Qt::Horizontal).toString();
+ bool ok = false;
+ float headerValue = header.toFloat(&ok);
+ if (ok)
+ xPos = headerValue;
+ }
+
+ if (zPosRole != noRoleIndex) {
+ zPos = m_itemModel->index(i, j).data(zPosRole).toFloat();
+ } else {
+ QString header = m_itemModel->headerData(i, Qt::Vertical).toString();
+ bool ok = false;
+ float headerValue = header.toFloat(&ok);
+ if (ok)
+ zPos = headerValue;
+ }
+
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()));
+ QVector3D(xPos,
+ m_itemModel->index(i, j).data(yPosRole).toFloat(),
+ zPos));
}
}
} else {
int rowRole = roleHash.key(m_proxy->rowRole().toLatin1());
int columnRole = roleHash.key(m_proxy->columnRole().toLatin1());
+ if (xPosRole == noRoleIndex)
+ xPosRole = columnRole;
+ if (zPosRole == noRoleIndex)
+ zPosRole = rowRole;
bool generateRows = m_proxy->autoRowCategories();
bool generateColumns = m_proxy->autoColumnCategories();
@@ -87,14 +117,17 @@ void SurfaceItemModelHandler::resolveModel()
QHash<QString, bool> columnListHash;
// Sort values into rows and columns
- typedef QHash<QString, float> ColumnValueMap;
+ typedef QHash<QString, QVector3D> ColumnValueMap;
QHash <QString, ColumnValueMap> itemValueMap;
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < columnCount; j++) {
QModelIndex index = m_itemModel->index(i, j);
QString rowRoleStr = index.data(rowRole).toString();
QString columnRoleStr = index.data(columnRole).toString();
- itemValueMap[rowRoleStr][columnRoleStr] = index.data(valueRole).toReal();
+ QVector3D itemPos(index.data(xPosRole).toReal(),
+ index.data(yPosRole).toReal(),
+ index.data(zPosRole).toReal());
+ itemValueMap[rowRoleStr][columnRoleStr] = itemPos;
if (generateRows && !rowListHash.value(rowRoleStr, false)) {
rowListHash.insert(rowRoleStr, true);
rowList << rowRoleStr;
@@ -128,11 +161,8 @@ 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].setPosition(QVector3D(columnList.at(j).toFloat(),
- itemValueMap[rowKey][columnList.at(j)],
- rowList.at(i).toFloat()));
- }
+ for (int j = 0; j < columnList.size(); j++)
+ newProxyRow[j].setPosition(itemValueMap[rowKey][columnList.at(j)]);
}
}
diff --git a/src/datavisualization/doc/qtdatavisualization.qdocconf b/src/datavisualization/doc/qtdatavisualization.qdocconf
index 81922313..8bf5a012 100644
--- a/src/datavisualization/doc/qtdatavisualization.qdocconf
+++ b/src/datavisualization/doc/qtdatavisualization.qdocconf
@@ -1,10 +1,14 @@
-include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
+include($QT_INSTALL_DOCS/global/macros.qdocconf)
+include($QT_INSTALL_DOCS/global/qt-cpp-defines.qdocconf)
+include($QT_INSTALL_DOCS/global/compat.qdocconf)
+include($QT_INSTALL_DOCS/global/fileextensions.qdocconf)
+include($QT_INSTALL_DOCS/global/qt-html-templates-offline.qdocconf)
project = QtDataVisualization
description = Qt Data Visualization Reference Documentation
version = 1.0.0
-exampledirs += ../../../examples \
+exampledirs += ../../../examples/datavisualization \
snippets
headerdirs += ..
@@ -12,9 +16,11 @@ imagedirs += ../images \
images
sourcedirs += ..
-depends += qtcore qtgui qtdeclarative
-
-indexes += $QTDIR/doc/html/qt.index
+indexes += $QT_INSTALL_DOCS/qtcore/qtcore.index \
+ $QT_INSTALL_DOCS/qtgui/qtgui.index \
+ $QT_INSTALL_DOCS/qtqml/qtqml.index \
+ $QT_INSTALL_DOCS/qtquick/qtquick.index \
+ $QT_INSTALL_DOCS/qtmultimedia/qtmultimedia.index
qhp.projects = qtdatavisualization
@@ -45,23 +51,6 @@ qhp.qtdatavisualization.subprojects.types.indexTitle = Qt Data Visual
qhp.qtdatavisualization.subprojects.types.selectors = fake:qmlclass
qhp.qtdatavisualization.subprojects.types.sortPages = true
-HTML.footer = \
- "<div class=\"footer\">\n" \
- " <p>\n" \
- " <acronym title=\"Copyright\">&copy;</acronym> 2014 Digia. Qt and Qt logos are\n" \
- " trademarks of of Digia Corporation in Finland and/or other countries worldwide.\n" \
- " </p>\n" \
- " All other trademarks are property of their respective owners.\n" \
- " <br />\n" \
- " <p>\n" \
- " Licensees holding valid Qt Enterprise licenses may use this document in accordance\n" \
- " with the Qt Enterprise License Agreement provided with the Software or,\n" \
- " alternatively, in accordance with the terms contained in a written agreement\n" \
- " between you and Digia.\n" \
- " </p>\n" \
- "</div>\n"
-
-navigation.homepage = Qt Enterprise:
navigation.landingpage = Qt Data Visualization
navigation.cppclassespage = Qt Data Visualization C++ Classes
navigation.qmltypespage = Qt Data Visualization QML Types
diff --git a/src/datavisualization/doc/snippets/doc_src_qtdatavisualization.cpp b/src/datavisualization/doc/snippets/doc_src_qtdatavisualization.cpp
index 458eeb45..6c6e49aa 100644
--- a/src/datavisualization/doc/snippets/doc_src_qtdatavisualization.cpp
+++ b/src/datavisualization/doc/snippets/doc_src_qtdatavisualization.cpp
@@ -72,7 +72,7 @@ QItemModelScatterDataProxy *proxy = new QItemModelScatterDataProxy(customModel,
QItemModelSurfaceDataProxy *proxy = new QItemModelSurfaceDataProxy(customModel,
QStringLiteral("longitude"), // Row role
QStringLiteral("latitude"), // Column role
- QStringLiteral("height")); // value role
+ QStringLiteral("height")); // Y-position role
//! [5]
//! [6]
diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc
index df503eb4..5b251768 100644
--- a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc
+++ b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc
@@ -28,12 +28,6 @@
Note that this type is uncreatable, but contains properties that are shared between
the 3D visualizations.
- \note QML doesn't support the type of anti-aliasing used by Qt Data Visualization graphs
- by default. Setting the \c antialiasing property doesn't affect graphs. To enable
- anti-aliasing for graphs, a custom surface format must be set up for the QQuickView
- before showing it. You can use the convenience function
- \c{QtDataVisualization::qDefaultSurfaceFormat()} to create the custom surface format object.
-
For AbstractGraph3D enums, see \l QAbstract3DGraph::SelectionFlag and
\l QAbstract3DGraph::ShadowQuality
@@ -66,24 +60,62 @@
*/
/*!
- \qmlproperty bool AbstractGraph3D::clearWindowBeforeRendering
-
- Indicates if the graph should also clear the whole window before rendering the graph,
- including the areas outside the graph.
- Since the graphs are drawn first under other QML items, the regular QML window clearing
- before rendering is suppressed when there are any graphs in the window; the graphs
- handle the clearing themselves instead.
- If you have any other items besides graphs that do similar
- custom drawing under other QML items, you need to set this property to false on all graphs
- drawn to same window with the other custom items, or it is likely that the
- other custom items do not render properly.
- Defaults to true.
-
- \note This property should be set to the same value for all graphs in the same window.
- Otherwise some graphs may not show.
-
- \note If window clearing before rendering is suppressed, any areas of the window not fully
- covered with opaque items may not draw properly.
+ \qmlproperty AbstractGraph3D.RenderingMode AbstractGraph3D::renderingMode
+
+ Defaults to \c{RenderIndirect}.
+
+ \table
+ \header
+ \li Render Mode
+ \li Description
+ \row
+ \li RenderDirectToBackground
+ \li Indicates the graph will be rendered directly on the window background.
+ This mode also clears the whole window before rendering the graph, including the areas
+ outside the graph.
+ Since the graphs in this rendering mode are drawn on the window background under other QML
+ items, the regular QML window clearing before rendering is suppressed. The graphs handle the clearing
+ themselves instead.
+ If the surface format of the window supports antialiasing, it will be used (see
+ \c {QtDataVisualization::qDefaultSurfaceFormat()}).
+ This rendering mode offers the best performance at the expense of non-standard QML behavior. For example,
+ the graphs do not obey the Z ordering of QML items and the opacity value has no effect on them.
+ \row
+ \li RenderDirectToBackground_NoClear
+ \li Similar to RenderDirectToBackground mode, except that the graph will not clear the whole
+ window before rendering the graph. This mode is better for windows where you have other custom items
+ besides the graphs that also draw on the window background. In that case you need to either take care
+ of the window clearing yourself or ensure that all areas of the window are fully covered with opaque
+ items.
+ If one graph in the window uses either of the direct rendering modes, then all other graphs in the
+ same window also drawn in direct modes should use the exact same direct rendering mode.
+ Otherwise some graphs may not show up, depending on the drawing order of the graphs.
+ \row
+ \li RenderIndirect
+ \li Indicates the graph will be first rendered to an offscreen surface that
+ is then drawn during normal QML item rendering. The rendered image is
+ antialiased using multisampling method if it is supported in the current environment and the
+ msaaSamples property value is greater than zero.
+ This rendering mode offers good quality and normal QML item behavior at the expense of performance.
+ \endtable
+
+ \note Antialiasing is not supported in OpenGL ES2 environments in any rendering mode.
+
+ \note Setting the \c antialiasing property of the graphs doesn't do anything. However, it is
+ set by the graph itself if the current rendering mode uses antialiasing.
+
+ \sa msaaSamples
+ */
+
+/*!
+ \qmlproperty int AbstractGraph3D::msaaSamples
+ The number of samples used in multisample antialiasing when renderingMode is \c RenderIndirect.
+ When renderingMode is \c RenderDirectToBackground or \c RenderDirectToBackground_NoClear, this
+ property value is read-only and returns the number of samples specified by the window surface
+ format.
+ Defaults to 4.
+
+ \sa renderingMode
*/
/*!
diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc
index aaafe217..6ee51742 100644
--- a/src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc
+++ b/src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc
@@ -36,11 +36,6 @@
*
* See \l{Qt Quick 2 Bars Example} for more thorough usage example.
*
- * \note Qt Data Visualization graphs are rendered behind any other QML elements on screen, including
- * the parent elements of the graph. To make the whole graph show, ensure that no other element
- * draws anything over the area the graph occupies. For example, having a non-transparent \c Rectangle
- * item as the parent of a graph causes the graph to be hidden.
- *
* \sa Bar3DSeries, ItemModelBarDataProxy, Scatter3D, Surface3D, {Qt Data Visualization C++ Classes}
*/
@@ -93,6 +88,12 @@
*/
/*!
+ * \qmlproperty Bar3DSeries Bars3D::selectedSeries
+ * The selected series or \c null. If \l {QAbstract3DGraph::selectionMode}{selectionMode} has
+ * \c SelectionMultiSeries flag set, this property holds the series which owns the selected bar.
+ */
+
+/*!
* \qmlproperty list<Bar3DSeries> Bars3D::seriesList
* \default
* This property holds the series of the graph.
diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-scatter3d.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-scatter3d.qdoc
index b969c536..4ea7888c 100644
--- a/src/datavisualization/doc/src/qtdatavisualization-qml-scatter3d.qdoc
+++ b/src/datavisualization/doc/src/qtdatavisualization-qml-scatter3d.qdoc
@@ -36,11 +36,6 @@
See \l{Qt Quick 2 Scatter Example} for more thorough usage example.
- \note Qt Data Visualization graphs are rendered behind any other QML elements on screen, including
- the parent elements of the graph. To make the whole graph show, ensure that no other element
- draws anything over the area the graph occupies. For example, having a non-transparent \c Rectangle
- item as the parent of a graph causes the graph to be hidden.
-
\sa Scatter3DSeries, ScatterDataProxy, Bars3D, Surface3D, {Qt Data Visualization C++ Classes}
*/
@@ -72,7 +67,12 @@
*/
/*!
- * \qmlproperty list<QScatter3DSeries> Scatter3D::seriesList
+ * \qmlproperty Scatter3DSeries Scatter3D::selectedSeries
+ * The selected series or \c null.
+ */
+
+/*!
+ * \qmlproperty list<Scatter3DSeries> Scatter3D::seriesList
* \default
* This property holds the series of the graph.
* By default, this property contains an empty list.
@@ -80,13 +80,13 @@
*/
/*!
- * \qmlmethod void Scatter3D::addSeries(QScatter3DSeries *series)
+ * \qmlmethod void Scatter3D::addSeries(Scatter3DSeries series)
* Adds the \a series to the graph. A graph can contain multiple series, but has only one set of
* axes. If the newly added series has specified a selected item, it will be highlighted and
* any existing selection will be cleared. Only one added series can have an active selection.
*/
/*!
- * \qmlmethod void Scatter3D::removeSeries(QScatter3DSeries *series)
+ * \qmlmethod void Scatter3D::removeSeries(Scatter3DSeries series)
* Remove the \a series from the graph.
*/
diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc
index 3011336b..23a9a004 100644
--- a/src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc
+++ b/src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc
@@ -36,11 +36,6 @@
See \l{Qt Quick 2 Surface Example} for more thorough usage example.
- \note Qt Data Visualization graphs are rendered behind any other QML elements on screen, including
- the parent elements of the graph. To make the whole graph show, ensure that no other element
- draws anything over the area the graph occupies. For example, having a non-transparent \c Rectangle
- item as the parent of a graph causes the graph to be hidden.
-
\sa Surface3DSeries, ItemModelSurfaceDataProxy, Bars3D, Scatter3D, {Qt Data Visualization C++ Classes}
*/
@@ -72,27 +67,30 @@
*/
/*!
+ * \qmlproperty Surface3DSeries Surface3D::selectedSeries
+ * The selected series or \c null. If \l {QAbstract3DGraph::selectionMode}{selectionMode} has
+ * \c SelectionMultiSeries flag set, this property holds the series which owns the selected point.
+ */
+
/*!
\qmlproperty ColorGradient Surface3D::gradient
The current surface gradient. Setting this property replaces the previous gradient.
*/
/*!
- * \qmlproperty list<QSurface3DSeries> Surface3D::seriesList
+ * \qmlproperty list<Surface3DSeries> Surface3D::seriesList
* \default
* This property holds the series of the graph.
* By default, this property contains an empty list.
* To set the series, either use the addSeries() function or define them as children of the graph.
- * \note The surface graph currently supports only a single series at a time.
*/
/*!
- * \qmlmethod void Surface3D::addSeries(QSurface3DSeries *series)
+ * \qmlmethod void Surface3D::addSeries(Surface3DSeries series)
* Adds the \a series to the graph.
- * \note The surface graph currently supports only a single series at a time.
*/
/*!
- * \qmlmethod void Surface3D::removeSeries(QSurface3DSeries *series)
+ * \qmlmethod void Surface3D::removeSeries(Surface3DSeries series)
* Remove the \a series from the graph.
*/
diff --git a/src/datavisualization/doc/src/qtdatavisualization.qdoc b/src/datavisualization/doc/src/qtdatavisualization.qdoc
index c85b9dbb..e68a1086 100644
--- a/src/datavisualization/doc/src/qtdatavisualization.qdoc
+++ b/src/datavisualization/doc/src/qtdatavisualization.qdoc
@@ -301,24 +301,34 @@
* \fn QSurfaceFormat QtDataVisualization::qDefaultSurfaceFormat(bool antialias = true)
* \relates QAbstract3DGraph
*
- * Anti-aliasing is turned on by default on C++ and turned off on QML, except in OpenGL ES2
- * environments, where anti-aliasing is not supported by Qt Data Visualization.
- * This convenience function can be used to construct a suitable surface format for use by
+ * This convenience function can be used to create a custom surface format suitable for use by
* Qt Data Visualization graphs.
- * The \a{antialias} parameter specifies whether or not anti-aliasing is activated.
+ *
+ * The \a antialias parameter specifies whether or not antialiasing is activated.
+ *
* Give the surface format returned by this function to the graph constructor (C++) or set
* it as the window format for QQuickView (QML) before calling show on it.
*
- * For example, disable anti-aliasing on C++ application:
+ * For example, disable antialiasing on C++ application:
*
* \code
+ * #include <QtDataVisualization/qutils.h>
+ *
+ * // ...
+ *
* Q3DBars *graph = new Q3DBars(QtDataVisualization::qDefaultSurfaceFormat(false));
* \endcode
*
- * For example, enable anti-aliasing on QML application:
+ * For example, enable antialiasing for direct rendering modes on QML application:
*
* \code
- * QtQuick2ApplicationViewer viewer;
+ * #include <QtDataVisualization/qutils.h>
+ *
+ * // ...
+ *
+ * QQuickView viewer;
* viewer.setFormat(QtDataVisualization::qDefaultSurfaceFormat());
* \endcode
+ *
+ * \note Antialiasing is not supported in OpenGL ES2 environments.
*/
diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp
index 4989ddb5..d2b59c58 100644
--- a/src/datavisualization/engine/abstract3dcontroller.cpp
+++ b/src/datavisualization/engine/abstract3dcontroller.cpp
@@ -32,8 +32,7 @@
#include "q3dtheme_p.h"
#include "q3dscene_p.h"
#include "q3dscene.h"
-
-#include <QThread>
+#include <QtCore/QThread>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h
index cac46ddf..f9b6588d 100644
--- a/src/datavisualization/engine/abstract3dcontroller_p.h
+++ b/src/datavisualization/engine/abstract3dcontroller_p.h
@@ -35,10 +35,7 @@
#include "qabstract3dinputhandler.h"
#include "qabstractdataproxy.h"
#include "q3dscene_p.h"
-#include "q3dbox.h"
-
-#include <QObject>
-#include <QLinearGradient>
+#include <QtGui/QLinearGradient>
class QFont;
diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp
index 7824000e..3122cf76 100644
--- a/src/datavisualization/engine/abstract3drenderer.cpp
+++ b/src/datavisualization/engine/abstract3drenderer.cpp
@@ -44,7 +44,8 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
m_devicePixelRatio(1.0f),
m_selectionLabelDirty(true),
m_clickPending(false),
- m_clickedSeries(0)
+ m_clickedSeries(0),
+ m_selectionLabelItem(0)
#ifdef DISPLAY_RENDER_SPEED
, m_isFirstFrame(true),
m_numFrames(0)
@@ -67,6 +68,7 @@ Abstract3DRenderer::~Abstract3DRenderer()
delete m_textureHelper;
delete m_cachedScene;
delete m_cachedTheme;
+ delete m_selectionLabelItem;
}
void Abstract3DRenderer::initializeOpenGL()
@@ -188,7 +190,7 @@ void Abstract3DRenderer::updateScene(Q3DScene *scene)
scene->activeCamera()->d_ptr->updateViewMatrix(m_autoScaleAdjustment);
// Set light position (rotate light with activeCamera, a bit above it (as set in defaultLightPos))
- scene->setLightPositionRelativeToCamera(defaultLightPos);
+ scene->d_ptr->setLightPositionRelativeToCamera(defaultLightPos);
QPoint logicalPixelPosition = scene->selectionQueryPosition();
updateInputPosition(QPoint(logicalPixelPosition.x() * m_devicePixelRatio,
@@ -426,8 +428,17 @@ void Abstract3DRenderer::lowerShadowQuality()
updateShadowQuality(newQuality);
}
-void Abstract3DRenderer::fixGradientAndGenerateTexture(QLinearGradient *gradient,
- GLuint *gradientTexture)
+void Abstract3DRenderer::generateBaseColorTexture(const QColor &color, GLuint *texture)
+{
+ if (*texture) {
+ m_textureHelper->deleteTexture(texture);
+ *texture = 0;
+ }
+
+ *texture = m_textureHelper->createUniformTexture(color);
+}
+
+void Abstract3DRenderer::fixGradientAndGenerateTexture(QLinearGradient *gradient, GLuint *gradientTexture)
{
// Readjust start/stop to match gradient texture size
gradient->setStart(qreal(gradientTextureWidth), qreal(gradientTextureHeight));
@@ -441,4 +452,23 @@ void Abstract3DRenderer::fixGradientAndGenerateTexture(QLinearGradient *gradient
*gradientTexture = m_textureHelper->createGradientTexture(*gradient);
}
+LabelItem &Abstract3DRenderer::selectionLabelItem()
+{
+ if (!m_selectionLabelItem)
+ m_selectionLabelItem = new LabelItem;
+ return *m_selectionLabelItem;
+}
+
+void Abstract3DRenderer::setSelectionLabel(const QString &label)
+{
+ if (m_selectionLabelItem)
+ m_selectionLabelItem->clear();
+ m_selectionLabel = label;
+}
+
+QString &Abstract3DRenderer::selectionLabel()
+{
+ return m_selectionLabel;
+}
+
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h
index e7591a10..4eb8426f 100644
--- a/src/datavisualization/engine/abstract3drenderer_p.h
+++ b/src/datavisualization/engine/abstract3drenderer_p.h
@@ -33,7 +33,7 @@
#include <QtGui/QOpenGLFunctions>
#ifdef DISPLAY_RENDER_SPEED
-#include <QTime>
+#include <QtCore/QTime>
#endif
#include "datavisualizationglobal_p.h"
@@ -94,12 +94,17 @@ public:
virtual void updateAxisLabelFormat(QAbstract3DAxis::AxisOrientation orientation, const QString &format);
virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh);
+ void generateBaseColorTexture(const QColor &color, GLuint *texture);
void fixGradientAndGenerateTexture(QLinearGradient *gradient, GLuint *gradientTexture);
inline bool isClickPending() { return m_clickPending; }
inline void clearClickPending() { m_clickPending = false; }
inline QAbstract3DSeries *clickedSeries() const { return m_clickedSeries; }
+ LabelItem &selectionLabelItem();
+ void setSelectionLabel(const QString &label);
+ QString &selectionLabel();
+
signals:
void needRender(); // Emit this if something in renderer causes need for another render pass.
void requestShadowQuality(QAbstract3DGraph::ShadowQuality quality); // For automatic quality adjustments
@@ -132,7 +137,6 @@ protected:
AxisRenderCache m_axisCacheY;
AxisRenderCache m_axisCacheZ;
TextureHelper *m_textureHelper;
- Q3DBox m_boundingBox;
Q3DScene *m_cachedScene;
bool m_selectionDirty;
@@ -146,6 +150,9 @@ protected:
bool m_clickPending;
QAbstract3DSeries *m_clickedSeries;
+ QString m_selectionLabel;
+ LabelItem *m_selectionLabelItem;
+
#ifdef DISPLAY_RENDER_SPEED
bool m_isFirstFrame;
QTime m_lastFrameTime;
diff --git a/src/datavisualization/engine/axisrendercache.cpp b/src/datavisualization/engine/axisrendercache.cpp
index c1c2d5bd..a107dd23 100644
--- a/src/datavisualization/engine/axisrendercache.cpp
+++ b/src/datavisualization/engine/axisrendercache.cpp
@@ -17,8 +17,9 @@
****************************************************************************/
#include "axisrendercache_p.h"
-#include "qmath.h"
-#include <QFontMetrics>
+
+#include <QtCore/qmath.h>
+#include <QtGui/QFontMetrics>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp
index 5bd37ccf..442601eb 100644
--- a/src/datavisualization/engine/bars3dcontroller.cpp
+++ b/src/datavisualization/engine/bars3dcontroller.cpp
@@ -27,8 +27,8 @@
#include "thememanager_p.h"
#include "q3dtheme_p.h"
-#include <QMatrix4x4>
-#include <qmath.h>
+#include <QtGui/QMatrix4x4>
+#include <QtCore/qmath.h>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -109,7 +109,7 @@ void Bars3DController::handleArrayReset()
m_isDataDirty = true;
}
// Clear selection unless still valid
- setSelectedBar(m_selectedBar, m_selectedBarSeries);
+ setSelectedBar(m_selectedBar, m_selectedBarSeries, false);
emitNeedRender();
}
@@ -152,7 +152,7 @@ void Bars3DController::handleRowsRemoved(int startIndex, int count)
else
selectedRow -= count; // Move selected row down by amount of rows removed
- setSelectedBar(QPoint(selectedRow, m_selectedBar.y()), m_selectedBarSeries);
+ setSelectedBar(QPoint(selectedRow, m_selectedBar.y()), m_selectedBarSeries, false);
}
}
@@ -174,7 +174,7 @@ void Bars3DController::handleRowsInserted(int startIndex, int count)
int selectedRow = m_selectedBar.x();
if (startIndex <= selectedRow) {
selectedRow += count;
- setSelectedBar(QPoint(selectedRow, m_selectedBar.y()), m_selectedBarSeries);
+ setSelectedBar(QPoint(selectedRow, m_selectedBar.y()), m_selectedBarSeries, false);
}
}
@@ -240,9 +240,9 @@ void Bars3DController::handleSeriesVisibilityChangedBySender(QObject *sender)
adjustAxisRanges();
- // Visibility changes may require disabling/enabling slicing,
+ // Visibility changes may require disabling slicing,
// so just reset selection to ensure everything is still valid.
- setSelectedBar(m_selectedBar, m_selectedBarSeries);
+ setSelectedBar(m_selectedBar, m_selectedBarSeries, false);
}
void Bars3DController::handlePendingClick()
@@ -251,7 +251,7 @@ void Bars3DController::handlePendingClick()
QPoint position = m_renderer->clickedPosition();
QBar3DSeries *series = static_cast<QBar3DSeries *>(m_renderer->clickedSeries());
- setSelectedBar(position, series);
+ setSelectedBar(position, series, true);
m_renderer->resetClickedStatus();
}
@@ -309,7 +309,7 @@ void Bars3DController::removeSeries(QAbstract3DSeries *series)
Abstract3DController::removeSeries(series);
if (m_selectedBarSeries == series)
- setSelectedBar(invalidSelectionPosition(), 0);
+ setSelectedBar(invalidSelectionPosition(), 0, false);
if (wasVisible)
adjustAxisRanges();
@@ -348,7 +348,7 @@ void Bars3DController::insertSeries(int index, QAbstract3DSeries *series)
}
if (barSeries->selectedBar() != invalidSelectionPosition())
- setSelectedBar(barSeries->selectedBar(), barSeries);
+ setSelectedBar(barSeries->selectedBar(), barSeries, false);
if (!oldSize)
emit primarySeriesChanged(m_primarySeries);
@@ -381,7 +381,7 @@ void Bars3DController::handleAxisRangeChangedBySender(QObject *sender)
Abstract3DController::handleAxisRangeChangedBySender(sender);
// Update selected bar - may be moved offscreen
- setSelectedBar(m_selectedBar, m_selectedBarSeries);
+ setSelectedBar(m_selectedBar, m_selectedBarSeries, false);
}
void Bars3DController::setMultiSeriesScaling(bool uniform)
@@ -436,7 +436,7 @@ void Bars3DController::setSelectionMode(QAbstract3DGraph::SelectionFlags mode)
if (mode != oldMode) {
// Refresh selection upon mode change to ensure slicing is correctly updated
// according to series the visibility.
- setSelectedBar(m_selectedBar, m_selectedBarSeries);
+ setSelectedBar(m_selectedBar, m_selectedBarSeries, true);
// Special case: Always deactivate slicing when changing away from slice
// automanagement, as this can't be handled in setSelectedBar.
@@ -448,7 +448,7 @@ void Bars3DController::setSelectionMode(QAbstract3DGraph::SelectionFlags mode)
}
}
-void Bars3DController::setSelectedBar(const QPoint &position, QBar3DSeries *series)
+void Bars3DController::setSelectedBar(const QPoint &position, QBar3DSeries *series, bool enterSlice)
{
// If the selection targets non-existent bar, clear selection instead.
QPoint pos = position;
@@ -465,13 +465,14 @@ void Bars3DController::setSelectedBar(const QPoint &position, QBar3DSeries *seri
|| pos.y() < m_axisX->min() || pos.y() > m_axisX->max()
|| !series->isVisible()) {
scene()->setSlicingActive(false);
- } else {
+ } else if (enterSlice) {
scene()->setSlicingActive(true);
}
emitNeedRender();
}
if (pos != m_selectedBar || series != m_selectedBarSeries) {
+ bool seriesChanged = (series != m_selectedBarSeries);
m_selectedBar = pos;
m_selectedBarSeries = series;
m_changeTracker.selectedBarChanged = true;
@@ -485,13 +486,16 @@ void Bars3DController::setSelectedBar(const QPoint &position, QBar3DSeries *seri
if (m_selectedBarSeries)
m_selectedBarSeries->dptr()->setSelectedBar(m_selectedBar);
+ if (seriesChanged)
+ emit selectedSeriesChanged(m_selectedBarSeries);
+
emitNeedRender();
}
}
void Bars3DController::clearSelection()
{
- setSelectedBar(invalidSelectionPosition(), 0);
+ setSelectedBar(invalidSelectionPosition(), 0, false);
}
void Bars3DController::adjustAxisRanges()
diff --git a/src/datavisualization/engine/bars3dcontroller_p.h b/src/datavisualization/engine/bars3dcontroller_p.h
index e704aea1..9ea59c89 100644
--- a/src/datavisualization/engine/bars3dcontroller_p.h
+++ b/src/datavisualization/engine/bars3dcontroller_p.h
@@ -94,11 +94,14 @@ public:
QSizeF barSpacing();
bool isBarSpecRelative();
+ inline QBar3DSeries *selectedSeries() const { return m_selectedBarSeries; }
+
void setSelectionMode(QAbstract3DGraph::SelectionFlags mode);
- void setSelectedBar(const QPoint &position, QBar3DSeries *series);
+ void setSelectedBar(const QPoint &position, QBar3DSeries *series, bool enterSlice);
virtual void clearSelection();
- virtual void handleAxisAutoAdjustRangeChangedInOrientation(QAbstract3DAxis::AxisOrientation orientation, bool autoAdjust);
+ virtual void handleAxisAutoAdjustRangeChangedInOrientation(
+ QAbstract3DAxis::AxisOrientation orientation, bool autoAdjust);
virtual void handleSeriesVisibilityChangedBySender(QObject *sender);
virtual void handlePendingClick();
@@ -128,6 +131,7 @@ public slots:
signals:
void primarySeriesChanged(QBar3DSeries *series);
+ void selectedSeriesChanged(QBar3DSeries *series);
protected:
virtual QAbstract3DAxis *createDefaultAxis(QAbstract3DAxis::AxisOrientation orientation);
diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp
index 664dbabd..be1be0dc 100644
--- a/src/datavisualization/engine/bars3drenderer.cpp
+++ b/src/datavisualization/engine/bars3drenderer.cpp
@@ -28,11 +28,10 @@
#include "q3dlight.h"
#include "qbar3dseries_p.h"
-#include <QMatrix4x4>
-#include <QMouseEvent>
-#include <QThread>
-#include <qmath.h>
-#include <QDebug>
+#include <QtGui/QMatrix4x4>
+#include <QtGui/QMouseEvent>
+#include <QtCore/QThread>
+#include <QtCore/qmath.h>
// You can verify that depth buffer drawing works correctly by uncommenting this.
// You should see the scene from where the light is
@@ -44,7 +43,6 @@ const GLfloat labelMargin = 0.05f;
const GLfloat gridLineWidth = 0.005f;
const bool sliceGridLabels = true;
-const QQuaternion identityQuaternion;
Bars3DRenderer::Bars3DRenderer(Bars3DController *controller)
: Abstract3DRenderer(controller),
@@ -168,7 +166,6 @@ void Bars3DRenderer::updateData()
m_seriesStart = -((float(seriesCount) - 1.0f) / 2.0f) * m_seriesStep;
}
-
if (m_keepSeriesUniform)
m_seriesScaleZ = m_seriesScaleX;
else
@@ -259,30 +256,18 @@ void Bars3DRenderer::updateData()
updateSelectedBar(m_selectedBarPos, m_selectedBarSeries);
}
-void Bars3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList, bool updateVisibility)
-{
- Abstract3DRenderer::updateSeries(seriesList, updateVisibility);
-
- // Fix the series rotations - ignore any rotations that are not along Y-axis
- for (int series = 0; series < m_visibleSeriesList.size(); series++) {
- QVector3D vector = m_visibleSeriesList.at(series).meshRotation().vector();
- if (vector.x() || vector.z())
- m_visibleSeriesList[series].setMeshRotation(identityQuaternion);
- }
-}
-
void Bars3DRenderer::updateScene(Q3DScene *scene)
{
if (m_hasNegativeValues)
- scene->activeCamera()->setMinYRotation(-90.0);
+ scene->activeCamera()->d_ptr->setMinYRotation(-90.0);
else
- scene->activeCamera()->setMinYRotation(0.0f);
+ scene->activeCamera()->d_ptr->setMinYRotation(0.0f);
if (m_hasHeightAdjustmentChanged) {
// Set initial camera position. Also update if height adjustment has changed.
- scene->activeCamera()->setBaseOrientation(cameraDistanceVector,
- zeroVector,
- upVector);
+ scene->activeCamera()->d_ptr->setBaseOrientation(cameraDistanceVector,
+ zeroVector,
+ upVector);
m_hasHeightAdjustmentChanged = false;
}
@@ -499,14 +484,14 @@ void Bars3DRenderer::drawSlicedScene()
int sliceItemCount = m_sliceSelection.size();
for (int bar = 0; bar < sliceItemCount; bar++) {
- BarRenderItem *item = m_sliceSelection.at(bar);
- if (!item)
+ const BarRenderSliceItem &item = m_sliceSelection.at(bar);
+ if (!item.value())
continue;
QQuaternion seriesRotation;
- if (item->seriesIndex() != currentSeriesIndex) {
- currentSeriesIndex = item->seriesIndex();
+ if (item.seriesIndex() != currentSeriesIndex) {
+ currentSeriesIndex = item.seriesIndex();
currentSeries = &(m_visibleSeriesList.at(currentSeriesIndex));
barObj = currentSeries->object();
colorStyle = currentSeries->colorStyle();
@@ -538,7 +523,7 @@ void Bars3DRenderer::drawSlicedScene()
seriesRotation = currentSeries->meshRotation();
}
- if (item->height() < 0)
+ if (item.height() < 0)
glCullFace(GL_FRONT);
else
glCullFace(GL_BACK);
@@ -546,18 +531,18 @@ void Bars3DRenderer::drawSlicedScene()
QMatrix4x4 MVPMatrix;
QMatrix4x4 modelMatrix;
QMatrix4x4 itModelMatrix;
- QQuaternion barRotation = item->rotation();
- GLfloat barPosY = item->translation().y() + barPosYAdjustment - zeroPosAdjustment;
+ QQuaternion barRotation = item.rotation();
+ GLfloat barPosY = item.translation().y() + barPosYAdjustment - zeroPosAdjustment;
if (rowMode) {
- barPosX = item->translation().x();
+ barPosX = item.translation().x();
} else {
- barPosX = -(item->translation().z()); // flip z; frontmost bar to the left
+ barPosX = -(item.translation().z()); // flip z; frontmost bar to the left
barRotation *= ninetyDegreeRotation;
}
modelMatrix.translate(barPosX, barPosY, 0.0f);
- modelMatrixScaler.setY(item->height());
+ modelMatrixScaler.setY(item.height());
if (!seriesRotation.isIdentity())
barRotation *= seriesRotation;
@@ -575,8 +560,8 @@ void Bars3DRenderer::drawSlicedScene()
QVector3D barColor;
GLuint gradientTexture = 0;
- if (itemMode && m_visualSelectedBarPos.x() == item->position().x()
- && m_visualSelectedBarPos.y() == item->position().y()) {
+ if (itemMode && m_visualSelectedBarPos.x() == item.position().x()
+ && m_visualSelectedBarPos.y() == item.position().y()) {
if (colorStyleIsUniform)
barColor = highlightColor;
else
@@ -588,7 +573,7 @@ void Bars3DRenderer::drawSlicedScene()
gradientTexture = baseGradientTexture;
}
- if (item->height() != 0) {
+ if (item.height() != 0) {
// Set shader bindings
barShader->setUniformValue(barShader->model(), modelMatrix);
barShader->setUniformValue(barShader->nModel(),
@@ -598,7 +583,7 @@ void Bars3DRenderer::drawSlicedScene()
barShader->setUniformValue(barShader->color(), barColor);
} else if (colorStyle == Q3DTheme::ColorStyleRangeGradient) {
barShader->setUniformValue(barShader->gradientHeight(),
- (qAbs(item->height()) / m_gradientFraction));
+ (qAbs(item.height()) / m_gradientFraction));
}
// Draw the object
@@ -628,10 +613,10 @@ void Bars3DRenderer::drawSlicedScene()
for (int labelNo = 0; labelNo <= lastLabel; labelNo++) {
// Get labels from first series only
- BarRenderItem *item = m_sliceSelection.at(labelNo);
- m_dummyBarRenderItem.setTranslation(QVector3D(item->translation().x(),
+ const BarRenderSliceItem &item = m_sliceSelection.at(labelNo);
+ m_dummyBarRenderItem.setTranslation(QVector3D(item.translation().x(),
barLabelYPos,
- item->translation().z()));
+ item.translation().z()));
// Draw labels
m_drawer->drawLabel(m_dummyBarRenderItem, *m_sliceCache->labelItems().at(labelNo),
viewMatrix, projectionMatrix, positionComp, sliceLabelRotation,
@@ -641,53 +626,53 @@ void Bars3DRenderer::drawSlicedScene()
}
for (int col = 0; col < sliceItemCount; col++) {
- BarRenderItem *item = m_sliceSelection.at(col);
+ BarRenderSliceItem &item = m_sliceSelection[col];
if (!sliceGridLabels) {
// Draw values
- if (item->height() != 0.0f || (!m_noZeroInRange && item->value() == 0.0f)) {
+ if (item.height() != 0.0f || (!m_noZeroInRange && item.value() == 0.0f)) {
// Create label texture if we need it
- if (item->sliceLabel().isNull() || m_updateLabels) {
- item->setSliceLabel(generateValueLabel(m_axisCacheY.labelFormat(),
- item->value()));
- m_drawer->generateLabelItem(item->sliceLabelItem(), item->sliceLabel());
+ if (item.sliceLabel().isNull() || m_updateLabels) {
+ item.setSliceLabel(generateValueLabel(m_axisCacheY.labelFormat(),
+ item.value()));
+ m_drawer->generateLabelItem(item.sliceLabelItem(), item.sliceLabel());
m_updateLabels = false;
}
- Qt::AlignmentFlag alignment = (item->height() < 0) ? Qt::AlignBottom : Qt::AlignTop;
- Drawer::LabelPosition labelPos = (item->height() < 0) ? Drawer::LabelBelow : Drawer::LabelOver;
- m_dummyBarRenderItem.setTranslation(QVector3D(item->translation().x(),
+ Qt::AlignmentFlag alignment = (item.height() < 0) ? Qt::AlignBottom : Qt::AlignTop;
+ Drawer::LabelPosition labelPos = (item.height() < 0) ? Drawer::LabelBelow : Drawer::LabelOver;
+ m_dummyBarRenderItem.setTranslation(QVector3D(item.translation().x(),
barPosYAdjustment - zeroPosAdjustment
- + item->height(),
- item->translation().z()));
+ + item.height(),
+ item.translation().z()));
- m_drawer->drawLabel(m_dummyBarRenderItem, item->sliceLabelItem(), viewMatrix,
+ m_drawer->drawLabel(m_dummyBarRenderItem, item.sliceLabelItem(), viewMatrix,
projectionMatrix, zeroVector, sliceValueRotation,
- item->height(), m_cachedSelectionMode, m_labelShader,
+ item.height(), m_cachedSelectionMode, m_labelShader,
m_labelObj, activeCamera, false, false, labelPos,
alignment, true);
}
} else {
// Only draw value for selected item when grid labels are on
- if (itemMode && m_visualSelectedBarPos.x() == item->position().x()
- && m_visualSelectedBarPos.y() == item->position().y()
- && item->seriesIndex() == m_visualSelectedBarSeriesIndex) {
+ if (itemMode && m_visualSelectedBarPos.x() == item.position().x()
+ && m_visualSelectedBarPos.y() == item.position().y()
+ && item.seriesIndex() == m_visualSelectedBarSeriesIndex) {
// Create label texture if we need it
- if (item->sliceLabel().isNull() || m_updateLabels) {
- item->setSliceLabel(generateValueLabel(m_axisCacheY.labelFormat(),
- item->value()));
- m_drawer->generateLabelItem(item->sliceLabelItem(), item->sliceLabel());
+ if (item.sliceLabel().isNull() || m_updateLabels) {
+ item.setSliceLabel(generateValueLabel(m_axisCacheY.labelFormat(),
+ item.value()));
+ m_drawer->generateLabelItem(item.sliceLabelItem(), item.sliceLabel());
m_updateLabels = false;
}
- Qt::AlignmentFlag alignment = (item->height() < 0) ? Qt::AlignBottom : Qt::AlignTop;
- Drawer::LabelPosition labelPos = (item->height() < 0) ? Drawer::LabelBelow : Drawer::LabelOver;
- m_dummyBarRenderItem.setTranslation(QVector3D(item->translation().x(),
+ Qt::AlignmentFlag alignment = (item.height() < 0) ? Qt::AlignBottom : Qt::AlignTop;
+ Drawer::LabelPosition labelPos = (item.height() < 0) ? Drawer::LabelBelow : Drawer::LabelOver;
+ m_dummyBarRenderItem.setTranslation(QVector3D(item.translation().x(),
barPosYAdjustment - zeroPosAdjustment
- + item->height(),
- item->translation().z()));
+ + item.height(),
+ item.translation().z()));
- m_drawer->drawLabel(m_dummyBarRenderItem, item->sliceLabelItem(), viewMatrix,
+ m_drawer->drawLabel(m_dummyBarRenderItem, item.sliceLabelItem(), viewMatrix,
projectionMatrix, zeroVector, sliceValueRotation,
- item->height(), m_cachedSelectionMode, m_labelShader,
+ item.height(), m_cachedSelectionMode, m_labelShader,
m_labelObj, activeCamera, false, false, labelPos,
alignment, true);
}
@@ -767,7 +752,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
projectionMatrix.perspective(45.0f, viewPortRatio, 0.1f, 100.0f);
// Get the view matrix
- QMatrix4x4 viewMatrix = activeCamera->viewMatrix();
+ QMatrix4x4 viewMatrix = activeCamera->d_ptr->viewMatrix();
// Calculate drawing order
// Draw order is reversed to optimize amount of drawing (ie. draw front objects first,
@@ -842,7 +827,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
// Get the depth view matrix
// It may be possible to hack lightPos here if we want to make some tweaks to shadow
- QVector3D depthLightPos = activeCamera->calculatePositionRelativeToCamera(
+ QVector3D depthLightPos = activeCamera->d_ptr->calculatePositionRelativeToCamera(
zeroVector, 0.0f, 3.5f / m_autoScaleAdjustment);
depthViewMatrix.lookAt(depthLightPos, zeroVector, upVector);
@@ -1213,9 +1198,9 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
item.setPosition(QPoint(row, bar));
item.setSeriesIndex(series);
if (rowMode)
- m_sliceSelection[sliceSeriesAdjust + bar] = &item;
+ m_sliceSelection[sliceSeriesAdjust + bar].setItem(item);
else
- m_sliceSelection[sliceSeriesAdjust + row] = &item;
+ m_sliceSelection[sliceSeriesAdjust + row].setItem(item);
}
break;
}
@@ -1235,7 +1220,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
item.setSeriesIndex(series);
if (!m_sliceTitleItem && m_axisCacheZ.labelItems().size() > row)
m_sliceTitleItem = m_axisCacheZ.labelItems().at(row);
- m_sliceSelection[sliceSeriesAdjust + bar] = &item;
+ m_sliceSelection[sliceSeriesAdjust + bar].setItem(item);
}
}
break;
@@ -1262,7 +1247,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
item.setSeriesIndex(series);
if (!m_sliceTitleItem && m_axisCacheX.labelItems().size() > bar)
m_sliceTitleItem = m_axisCacheX.labelItems().at(bar);
- m_sliceSelection[sliceSeriesAdjust + row] = &item;
+ m_sliceSelection[sliceSeriesAdjust + row].setItem(item);
}
}
break;
@@ -1304,6 +1289,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
// Draw the object
m_drawer->drawObject(barShader, barObj, gradientTexture, m_depthTexture);
} else
+#else
+ Q_UNUSED(shadowLightStrength);
#endif
{
// Set shadowless shader bindings
@@ -1816,10 +1803,10 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
// Print value of selected bar
glDisable(GL_DEPTH_TEST);
// Draw the selection label
- LabelItem &labelItem = selectedBar->selectionLabelItem();
+ LabelItem &labelItem = selectionLabelItem();
if (m_selectedBar != selectedBar || m_updateLabels || !labelItem.textureId()
|| m_selectionLabelDirty) {
- QString labelText = selectedBar->selectionLabel();
+ QString labelText = selectionLabel();
if (labelText.isNull() || m_selectionLabelDirty) {
static const QString rowIndexTag(QStringLiteral("@rowIdx"));
static const QString rowLabelTag(QStringLiteral("@rowLabel"));
@@ -1863,7 +1850,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
labelText.replace(seriesNameTag,
m_visibleSeriesList[m_visualSelectedBarSeriesIndex].name());
- selectedBar->setSelectionLabel(labelText);
+ setSelectionLabel(labelText);
m_selectionLabelDirty = false;
}
m_drawer->generateLabelItem(labelItem, labelText);
@@ -1954,6 +1941,7 @@ void Bars3DRenderer::updateSelectedBar(const QPoint &position, const QBar3DSerie
m_selectedBarPos = position;
m_selectedBarSeries = series;
m_selectionDirty = true;
+ m_selectionLabelDirty = true;
m_visualSelectedBarSeriesIndex = -1;
if (m_renderingArrays.isEmpty()) {
diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h
index e53f9bc5..37ac2b76 100644
--- a/src/datavisualization/engine/bars3drenderer_p.h
+++ b/src/datavisualization/engine/bars3drenderer_p.h
@@ -60,7 +60,7 @@ private:
// Internal state
BarRenderItem *m_selectedBar; // points to renderitem array
- QVector<BarRenderItem *> m_sliceSelection;
+ QVector<BarRenderSliceItem> m_sliceSelection;
AxisRenderCache *m_sliceCache; // not owned
const LabelItem *m_sliceTitleItem; // not owned
bool m_xFlipped;
@@ -114,7 +114,6 @@ public:
~Bars3DRenderer();
void updateData();
- void updateSeries(const QList<QAbstract3DSeries *> &seriesList, bool updateVisibility);
void updateScene(Q3DScene *scene);
void render(GLuint defaultFboHandle = 0);
diff --git a/src/datavisualization/engine/drawer.cpp b/src/datavisualization/engine/drawer.cpp
index dd82eadc..55a2c2a5 100644
--- a/src/datavisualization/engine/drawer.cpp
+++ b/src/datavisualization/engine/drawer.cpp
@@ -24,8 +24,10 @@
#include "q3dcamera.h"
#include "utils_p.h"
#include "texturehelper_p.h"
-#include <QMatrix4x4>
-#include <qmath.h>
+#include "abstract3drenderer_p.h"
+
+#include <QtGui/QMatrix4x4>
+#include <QtCore/qmath.h>
// Resources need to be explicitly initialized when building as static library
class StaticLibInitializer
@@ -348,10 +350,10 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte
drawObject(shader, object, labelItem.textureId());
}
-void Drawer::generateSelectionLabelTexture(AbstractRenderItem *item)
+void Drawer::generateSelectionLabelTexture(Abstract3DRenderer *renderer)
{
- LabelItem &labelItem = item->selectionLabelItem();
- generateLabelItem(labelItem, item->selectionLabel());
+ LabelItem &labelItem = renderer->selectionLabelItem();
+ generateLabelItem(labelItem, renderer->selectionLabel());
}
void Drawer::generateLabelItem(LabelItem &item, const QString &text, int widestLabel)
diff --git a/src/datavisualization/engine/drawer_p.h b/src/datavisualization/engine/drawer_p.h
index 35a0a7ff..8e98aa3a 100644
--- a/src/datavisualization/engine/drawer_p.h
+++ b/src/datavisualization/engine/drawer_p.h
@@ -34,7 +34,6 @@
#include "q3dtheme.h"
#include "labelitem_p.h"
#include "abstractrenderitem_p.h"
-#include <QFont>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -44,6 +43,7 @@ class AbstractObjectHelper;
class SurfaceObject;
class TextureHelper;
class Q3DCamera;
+class Abstract3DRenderer;
class Drawer : public QObject, public QOpenGLFunctions
{
@@ -84,7 +84,7 @@ public:
LabelPosition position = LabelOver,
Qt::AlignmentFlag alignment = Qt::AlignCenter, bool isSlicing = false);
- void generateSelectionLabelTexture(AbstractRenderItem *item);
+ void generateSelectionLabelTexture(Abstract3DRenderer *item);
void generateLabelItem(LabelItem &item, const QString &text, int widestLabel = 0);
Q_SIGNALS:
diff --git a/src/datavisualization/engine/engine.pri b/src/datavisualization/engine/engine.pri
index e13a9a04..9c2e71e4 100644
--- a/src/datavisualization/engine/engine.pri
+++ b/src/datavisualization/engine/engine.pri
@@ -23,10 +23,10 @@ HEADERS += $$PWD/qabstract3dgraph_p.h \
$$PWD/q3dscene.h \
$$PWD/q3dlight.h \
$$PWD/q3dlight_p.h \
- $$PWD/q3dbox.h \
$$PWD/q3dobject.h \
$$PWD/q3dobject_p.h \
- $$PWD/q3dscene_p.h
+ $$PWD/q3dscene_p.h \
+ $$PWD/surfaceseriesrendercache_p.h
SOURCES += $$PWD/qabstract3dgraph.cpp \
$$PWD/q3dbars.cpp \
@@ -46,8 +46,10 @@ SOURCES += $$PWD/qabstract3dgraph.cpp \
$$PWD/selectionpointer.cpp \
$$PWD/q3dcamera.cpp \
$$PWD/q3dlight.cpp \
- $$PWD/q3dbox.cpp \
$$PWD/q3dobject.cpp \
- $$PWD/q3dscene.cpp
+ $$PWD/q3dscene.cpp \
+ $$PWD/surfaceseriesrendercache.cpp
RESOURCES += engine/engine.qrc
+
+OTHER_FILES += $$PWD/meshes/* $$PWD/shaders/*
diff --git a/src/datavisualization/engine/q3dbars.cpp b/src/datavisualization/engine/q3dbars.cpp
index 787033ad..7b37715f 100644
--- a/src/datavisualization/engine/q3dbars.cpp
+++ b/src/datavisualization/engine/q3dbars.cpp
@@ -104,6 +104,8 @@ Q3DBars::Q3DBars(const QSurfaceFormat *format, QWindow *parent)
dptr()->m_shared->initializeOpenGL();
QObject::connect(dptr()->m_shared, &Bars3DController::primarySeriesChanged,
this, &Q3DBars::primarySeriesChanged);
+ QObject::connect(dptr()->m_shared, &Bars3DController::selectedSeriesChanged,
+ this, &Q3DBars::selectedSeriesChanged);
}
/*!
@@ -328,6 +330,17 @@ QValue3DAxis *Q3DBars::valueAxis() const
}
/*!
+ * \property Q3DBars::selectedSeries
+ *
+ * The selected series or \c null. If selectionMode has \c SelectionMultiSeries flag set, this
+ * property holds the series which owns the selected bar.
+ */
+QBar3DSeries *Q3DBars::selectedSeries() const
+{
+ return dptrc()->m_shared->selectedSeries();
+}
+
+/*!
* Adds \a axis to the graph. The axes added via addAxis are not yet taken to use,
* addAxis is simply used to give the ownership of the \a axis to the graph.
* The \a axis must not be null or added to another graph.
diff --git a/src/datavisualization/engine/q3dbars.h b/src/datavisualization/engine/q3dbars.h
index 06dcfedb..7f9c981f 100644
--- a/src/datavisualization/engine/q3dbars.h
+++ b/src/datavisualization/engine/q3dbars.h
@@ -20,16 +20,13 @@
#define Q3DBARS_H
#include <QtDataVisualization/qabstract3dgraph.h>
-#include <QFont>
-#include <QLinearGradient>
+#include <QtDataVisualization/qvalue3daxis.h>
+#include <QtDataVisualization/qcategory3daxis.h>
+#include <QtDataVisualization/qbar3dseries.h>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class Q3DBarsPrivate;
-class QAbstract3DAxis;
-class QCategory3DAxis;
-class QValue3DAxis;
-class QBar3DSeries;
class QT_DATAVISUALIZATION_EXPORT Q3DBars : public QAbstract3DGraph
{
@@ -42,6 +39,7 @@ class QT_DATAVISUALIZATION_EXPORT Q3DBars : public QAbstract3DGraph
Q_PROPERTY(QCategory3DAxis *columnAxis READ columnAxis WRITE setColumnAxis NOTIFY columnAxisChanged)
Q_PROPERTY(QValue3DAxis *valueAxis READ valueAxis WRITE setValueAxis NOTIFY valueAxisChanged)
Q_PROPERTY(QBar3DSeries *primarySeries READ primarySeries WRITE setPrimarySeries NOTIFY primarySeriesChanged)
+ Q_PROPERTY(QBar3DSeries *selectedSeries READ selectedSeries NOTIFY selectedSeriesChanged)
public:
explicit Q3DBars(const QSurfaceFormat *format = 0, QWindow *parent = 0);
@@ -76,15 +74,18 @@ public:
void releaseAxis(QAbstract3DAxis *axis);
QList<QAbstract3DAxis *> axes() const;
+ QBar3DSeries *selectedSeries() const;
+
signals:
void multiSeriesUniformChanged(bool uniform);
void barThicknessChanged(float thicknessRatio);
- void barSpacingChanged(QSizeF spacing);
+ void barSpacingChanged(const QSizeF &spacing);
void barSpacingRelativeChanged(bool relative);
void rowAxisChanged(QCategory3DAxis *axis);
void columnAxisChanged(QCategory3DAxis *axis);
void valueAxisChanged(QValue3DAxis *axis);
void primarySeriesChanged(QBar3DSeries *series);
+ void selectedSeriesChanged(QBar3DSeries *series);
private:
Q3DBarsPrivate *dptr();
diff --git a/src/datavisualization/engine/q3dbox.cpp b/src/datavisualization/engine/q3dbox.cpp
deleted file mode 100644
index c5caea75..00000000
--- a/src/datavisualization/engine/q3dbox.cpp
+++ /dev/null
@@ -1,485 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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 "datavisualizationglobal_p.h"
-#include "q3dbox.h"
-#include <QtCore/QList>
-
-QT_BEGIN_NAMESPACE_DATAVISUALIZATION
-
-/*!
- \class Q3DBox
- \inmodule QtDataVisualization
- \brief The Q3DBox class represents an axis-aligned box in 3D space.
- \since Qt Data Visualization 1.0
-
- Q3DBox can be used to represent the bounding box of objects in a 3D
- scene so that they can be easily culled if they are out of view.
-
- The sides of the box are always aligned with the x, y, and z axes of
- the world co-ordinate system. Transforming a box with transformed()
- will result in the smallest axis-aligned bounding box that contains
- the transformed box.
-
- Boxes may be null, finite, or infinite. A null box does not occupy
- any space and does not intersect with any other box. A finite
- box consists of a minimum() and maximum() extent in 3D space.
- An infinite box encompasses all points in 3D space.
-
- The extents of a finite box are also included within the box.
- A box with minimum() and maximum() set to the same value
- contains a single point.
-*/
-
-/*!
- \fn Q3DBox::Q3DBox()
-
- Constructs a null box in 3D space.
-
- \sa isNull()
-*/
-
-/*!
- \fn Q3DBox::Q3DBox(const QVector3D& corner1, const QVector3D& corner2)
-
- Constructs a finite box in 3D space from \a corner1 to \a corner2.
- The minimum() and maximum() co-ordinates of the new box are set
- to the minimum and maximum x, y, and z values from \a corner1 and
- \a corner2. The \a corner1 and \a corner2 values can be any two
- opposite corners that define the box.
-
- \sa isFinite(), minimum(), maximum()
-*/
-
-/*!
- \fn bool Q3DBox::isNull() const
-
- Returns true if this box is null; false otherwise.
-
- \sa isFinite(), isInfinite(), setToNull()
-*/
-
-/*!
- \fn bool Q3DBox::isFinite() const
-
- Returns true if this box is finite in size; false otherwise.
-
- \sa isNull(), isInfinite(), setExtents()
-*/
-
-/*!
- \fn bool Q3DBox::isInfinite() const
-
- Returns true if this box is infinite in size; false otherwise.
-
- \sa isNull(), isFinite(), setToInfinite()
-*/
-
-/*!
- \fn QVector3D Q3DBox::minimum() const
-
- Returns the minimum corner of this box.
-
- \sa maximum(), setExtents()
-*/
-
-/*!
- \fn QVector3D Q3DBox::maximum() const
-
- Returns the maximum corner of this box.
-
- \sa minimum(), setExtents()
-*/
-
-/*!
- \fn void Q3DBox::setExtents(const QVector3D& corner1, const QVector3D& corner2)
-
- Sets the extents of this box to a finite region from \a corner1 to
- \a corner2. The minimum() and maximum() co-ordinates of the box are
- set to the minimum and maximum x, y, and z values from \a corner1 and
- \a corner2. The \a corner1 and \a corner2 values can be any two
- opposite corners that define the box.
-
- \sa minimum(), maximum()
-*/
-
-/*!
- \fn void Q3DBox::setToNull()
-
- Sets this box to null.
-
- \sa isNull()
-*/
-
-/*!
- \fn void Q3DBox::setToInfinite()
-
- Sets this box to be infinite in size.
-
- \sa isInfinite()
-*/
-
-/*!
- \fn QVector3D Q3DBox::size() const
-
- Returns the finite size of this box. If this box is null or
- infinite, the returned value will be zero.
-
- \sa center(), isNull(), isInfinite()
-*/
-
-/*!
- \fn QVector3D Q3DBox::center() const
-
- Returns the finite center of this box. If this box is null
- or infinite, the returned value will be zero.
-
- \sa size(), isNull(), isInfinite()
-*/
-
-/*!
- \fn bool Q3DBox::contains(const QVector3D& point) const
-
- Returns true if this box contains \a point; false otherwise.
- Null boxes do not contain any points and infinite boxes contain
- all points.
-
- Containment is not a strict test: the point is contained if it
- lies on one of the faces of the box.
-
- \sa intersects()
-*/
-
-/*!
- \fn bool Q3DBox::contains(const Q3DBox& box) const
-
- Returns true if this box completely contains \a box. If this box
- is null, then it will not contain \a box. If this box is infinite,
- and \a box is not null, then \a box will be contained within this box.
- If \a box is infinite, then this box must also be infinite to contain it.
-
- \sa intersects()
-*/
-
-/*!
- Returns true if \a box intersects this box; false otherwise.
-
- \sa intersect(), intersected(), contains()
-*/
-bool Q3DBox::intersects(const Q3DBox& box) const
-{
- if (boxtype == Null)
- return false;
- else if (boxtype == Infinite)
- return box.boxtype != Null;
- else if (box.boxtype == Null)
- return false;
- else if (box.boxtype == Infinite)
- return true;
-
- if (maxcorner.x() < box.mincorner.x())
- return false;
- if (mincorner.x() > box.maxcorner.x())
- return false;
-
- if (maxcorner.y() < box.mincorner.y())
- return false;
- if (mincorner.y() > box.maxcorner.y())
- return false;
-
- if (maxcorner.z() < box.mincorner.z())
- return false;
- if (mincorner.z() > box.maxcorner.z())
- return false;
-
- return true;
-}
-
-/*!
- Intersects this box with \a box.
-
- \sa intersected(), intersects(), unite()
-*/
-void Q3DBox::intersect(const Q3DBox& box)
-{
- // Handle the simple cases first.
- if (boxtype == Null) {
- // Null intersected with anything is null.
- return;
- } else if (boxtype == Infinite) {
- // Infinity intersected with a box is that box.
- *this = box;
- return;
- } else if (box.boxtype == Null) {
- // Anything intersected with null is null.
- setToNull();
- return;
- } else if (box.boxtype == Infinite) {
- // Box intersected with infinity is the box.
- return;
- }
-
- // Intersect two finite boxes.
- QVector3D min1 = mincorner;
- QVector3D max1 = maxcorner;
- QVector3D min2 = box.mincorner;
- QVector3D max2 = box.maxcorner;
- if (min2.x() > min1.x())
- min1.setX(min2.x());
- if (min2.y() > min1.y())
- min1.setY(min2.y());
- if (min2.z() > min1.z())
- min1.setZ(min2.z());
- if (max2.x() < max1.x())
- max1.setX(max2.x());
- if (max2.y() < max1.y())
- max1.setY(max2.y());
- if (max2.z() < max1.z())
- max1.setZ(max2.z());
- if (min1.x() > max1.x() || min1.y() > max1.y() || min1.z() > max1.z()) {
- setToNull();
- } else {
- mincorner = min1;
- maxcorner = max1;
- }
-}
-
-/*!
- Returns a new box which is the intersection of this box with \a box.
-
- \sa intersect(), intersects(), united()
-*/
-Q3DBox Q3DBox::intersected(const Q3DBox& box) const
-{
- Q3DBox result(*this);
- result.intersect(box);
- return result;
-}
-
-/*!
- Unites this box with \a point by expanding it to encompass \a point.
- If \a point is already contained within this box, then this box
- will be unchanged.
-
- \sa united(), intersect()
-*/
-void Q3DBox::unite(const QVector3D& point)
-{
- if (boxtype == Finite) {
- if (point.x() < mincorner.x())
- mincorner.setX(point.x());
- else if (point.x() > maxcorner.x())
- maxcorner.setX(point.x());
- if (point.y() < mincorner.y())
- mincorner.setY(point.y());
- else if (point.y() > maxcorner.y())
- maxcorner.setY(point.y());
- if (point.z() < mincorner.z())
- mincorner.setZ(point.z());
- else if (point.z() > maxcorner.z())
- maxcorner.setZ(point.z());
- } else if (boxtype == Null) {
- boxtype = Finite;
- mincorner = point;
- maxcorner = point;
- }
-}
-
-/*!
- Unites this box with \a box by expanding this box to encompass the
- region defined by \a box. If \a box is already contained within
- this box, then this box will be unchanged.
-
- \sa united(), intersect()
-*/
-void Q3DBox::unite(const Q3DBox& box)
-{
- if (box.boxtype == Finite) {
- unite(box.minimum());
- unite(box.maximum());
- } else if (box.boxtype == Infinite) {
- setToInfinite();
- }
-}
-
-/*!
- Returns a new box which unites this box with \a point. The returned
- value will be the smallest box that contains both this box and \a point.
-
- \sa unite(), intersected()
-*/
-Q3DBox Q3DBox::united(const QVector3D& point) const
-{
- if (boxtype == Finite) {
- Q3DBox result(*this);
- result.unite(point);
- return result;
- } else if (boxtype == Null) {
- return Q3DBox(point, point);
- } else {
- return *this;
- }
-}
-
-/*!
- Returns a new box which unites this box with \a box. The returned value
- will be the smallest box that contains both this box and \a box.
-
- \sa unite(), intersected()
-*/
-Q3DBox Q3DBox::united(const Q3DBox& box) const
-{
- if (boxtype == Finite) {
- Q3DBox result(*this);
- result.unite(box);
- return result;
- } else if (boxtype == Null) {
- return box;
- } else {
- return *this;
- }
-}
-
-/*!
- Transforms this box according to \a matrix. Each of the 8 box
- corners are transformed and then a new box that encompasses all
- of the transformed corner values is created.
-
- \sa transformed()
-*/
-void Q3DBox::transform(const QMatrix4x4& matrix)
-{
- *this = transformed(matrix);
-}
-
-/*!
- Returns this box transformed by \a matrix. Each of the 8 box
- corners are transformed and then a new box that encompasses all
- of the transformed corner values is returned.
-
- \sa transform()
-*/
-Q3DBox Q3DBox::transformed(const QMatrix4x4& matrix) const
-{
- if (boxtype != Finite)
- return *this;
- Q3DBox result;
- result.unite(matrix * mincorner);
- result.unite(matrix * QVector3D(mincorner.x(), mincorner.y(), maxcorner.z()));
- result.unite(matrix * QVector3D(mincorner.x(), maxcorner.y(), maxcorner.z()));
- result.unite(matrix * QVector3D(mincorner.x(), maxcorner.y(), mincorner.z()));
- result.unite(matrix * QVector3D(maxcorner.x(), mincorner.y(), mincorner.z()));
- result.unite(matrix * QVector3D(maxcorner.x(), maxcorner.y(), mincorner.z()));
- result.unite(matrix * QVector3D(maxcorner.x(), mincorner.y(), maxcorner.z()));
- result.unite(matrix * maxcorner);
- return result;
-}
-
-/*!
- \fn bool Q3DBox::operator==(const Q3DBox& box) const
-
- Returns true if this box is identical to \a box.
-*/
-
-/*!
- \fn bool Q3DBox::operator!=(const Q3DBox& box) const
-
- Returns true if this box is not identical to \a box.
-*/
-
-/*!
- \fn bool qFuzzyCompare(const Q3DBox& box1, const Q3DBox& box2)
- \relates Q3DBox
-
- Returns true if \a box1 and \a box2 are almost equal; false otherwise.
-*/
-
-#ifndef QT_NO_DEBUG_STREAM
-
-/*!
- \fn operator<<(QDebug dbg, const Q3DBox &box)
- \internal
- */
-QDebug operator<<(QDebug dbg, const Q3DBox &box)
-{
- if (box.isFinite()) {
- dbg.nospace() << "Q3DBox(("
- << box.minimum().x() << ", " << box.minimum().y() << ", "
- << box.minimum().z() << ") - ("
- << box.maximum().x() << ", " << box.maximum().y() << ", "
- << box.maximum().z() << "))";
- return dbg.space();
- } else if (box.isNull()) {
- dbg << "Q3DBox(null)";
- return dbg;
- } else {
- dbg << "Q3DBox(infinite)";
- return dbg;
- }
-}
-
-#endif
-
-#ifndef QT_NO_DATASTREAM
-
-/*!
- \relates Q3DBox
-
- Writes the given \a box to the given \a stream and returns a
- reference to the stream.
-*/
-QDataStream &operator<<(QDataStream &stream, const Q3DBox &box)
-{
- if (box.isNull()) {
- stream << int(0);
- } else if (box.isInfinite()) {
- stream << int(2);
- } else {
- stream << int(1);
- stream << box.minimum();
- stream << box.maximum();
- }
- return stream;
-}
-
-/*!
- \relates Q3DBox
-
- Reads a 3D box from the given \a stream into the given \a box
- and returns a reference to the stream.
-*/
-QDataStream &operator>>(QDataStream &stream, Q3DBox &box)
-{
- int type;
- stream >> type;
- if (type == 1) {
- QVector3D minimum, maximum;
- stream >> minimum;
- stream >> maximum;
- box = Q3DBox(minimum, maximum);
- } else if (type == 2) {
- box.setToInfinite();
- } else {
- box.setToNull();
- }
- return stream;
-}
-
-#endif
-
-QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/q3dbox.h b/src/datavisualization/engine/q3dbox.h
deleted file mode 100644
index 6dbaefa1..00000000
--- a/src/datavisualization/engine/q3dbox.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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 Q3DBOX_H
-#define Q3DBOX_H
-
-#include <QtDataVisualization/qdatavisualizationglobal.h>
-#include <QtGui/QMatrix4x4>
-#include <QtGui/QVector3D>
-
-QT_BEGIN_NAMESPACE_DATAVISUALIZATION
-
-class Q3DBox; // Needed to circumvent an issue with qdoc. If this line is removed, make docs will not work for this.
-
-class QT_DATAVISUALIZATION_EXPORT Q3DBox
-{
-public:
- inline Q3DBox() : boxtype(Null), mincorner(0, 0, 0), maxcorner(0, 0, 0) {}
- inline Q3DBox(const QVector3D& corner1, const QVector3D& corner2): boxtype(Finite),
- mincorner(qMin(corner1.x(), corner2.x()),
- qMin(corner1.y(), corner2.y()),
- qMin(corner1.z(), corner2.z())),
- maxcorner(qMax(corner1.x(), corner2.x()),
- qMax(corner1.y(), corner2.y()),
- qMax(corner1.z(), corner2.z())) {}
-
- inline bool isNull() const { return (boxtype == Null); }
- inline bool isFinite() const { return (boxtype == Finite); }
- inline bool isInfinite() const { return (boxtype == Infinite); }
-
- inline QVector3D minimum() const { return mincorner; }
- inline QVector3D maximum() const { return maxcorner; }
- inline void setExtents(const QVector3D& corner1, const QVector3D& corner2)
- {
- boxtype = Finite;
- mincorner = QVector3D(qMin(corner1.x(), corner2.x()),
- qMin(corner1.y(), corner2.y()),
- qMin(corner1.z(), corner2.z()));
- maxcorner = QVector3D(qMax(corner1.x(), corner2.x()),
- qMax(corner1.y(), corner2.y()),
- qMax(corner1.z(), corner2.z()));
- }
-
- inline void setToNull()
- {
- boxtype = Null;
- mincorner = QVector3D(0, 0, 0);
- maxcorner = QVector3D(0, 0, 0);
- }
-
- inline void setToInfinite()
- {
- boxtype = Infinite;
- mincorner = QVector3D(0, 0, 0);
- maxcorner = QVector3D(0, 0, 0);
- }
-
- inline QVector3D size() const { return maxcorner - mincorner; }
- inline QVector3D center() const { return (mincorner + maxcorner) * 0.5f; }
-
- inline bool contains(const QVector3D& point) const
- {
- if (boxtype == Finite) {
- return (point.x() >= mincorner.x() && point.x() <= maxcorner.x() &&
- point.y() >= mincorner.y() && point.y() <= maxcorner.y() &&
- point.z() >= mincorner.z() && point.z() <= maxcorner.z());
- } else if (boxtype == Infinite) {
- return true;
- } else {
- return false;
- }
- }
-
- inline bool contains(const Q3DBox& box) const
- {
- if (box.boxtype == Finite)
- return contains(box.mincorner) && contains(box.maxcorner);
- else if (box.boxtype == Infinite)
- return (boxtype == Infinite);
- else
- return false;
- }
-
- bool intersects(const Q3DBox& box) const;
- void intersect(const Q3DBox& box);
- Q3DBox intersected(const Q3DBox& box) const;
-
- void unite(const QVector3D& point);
- void unite(const Q3DBox& box);
-
- Q3DBox united(const QVector3D& point) const;
- Q3DBox united(const Q3DBox& box) const;
-
- void transform(const QMatrix4x4& matrix);
- Q3DBox transformed(const QMatrix4x4& matrix) const;
-
- inline bool operator==(const Q3DBox& box) const
- {
- return (boxtype == box.boxtype &&
- mincorner == box.mincorner &&
- maxcorner == box.maxcorner);
- }
-
- inline bool operator!=(const Q3DBox& box) const
- {
- return (boxtype != box.boxtype ||
- mincorner != box.mincorner ||
- maxcorner != box.maxcorner);
- }
-
- friend bool qFuzzyCompare(const Q3DBox& box1, const Q3DBox& box2);
-
-private:
- enum Type
- {
- Null,
- Finite,
- Infinite
- };
-
- Q3DBox::Type boxtype;
- QVector3D mincorner, maxcorner;
-};
-
-inline bool qFuzzyCompare(const Q3DBox& box1, const Q3DBox& box2)
-{
- return box1.boxtype == box2.boxtype &&
- qFuzzyCompare(box1.mincorner, box2.mincorner) &&
- qFuzzyCompare(box1.maxcorner, box2.maxcorner);
-}
-
-#ifndef QT_NO_DEBUG_STREAM
-QT_DATAVISUALIZATION_EXPORT QDebug operator<<(QDebug dbg, const Q3DBox &box);
-#endif
-
-#ifndef QT_NO_DATASTREAM
-QT_DATAVISUALIZATION_EXPORT QDataStream &operator<<(QDataStream &stream, const Q3DBox &box);
-QT_DATAVISUALIZATION_EXPORT QDataStream &operator>>(QDataStream &stream, Q3DBox &box);
-#endif
-
-QT_END_NAMESPACE_DATAVISUALIZATION
-
-#endif
diff --git a/src/datavisualization/engine/q3dcamera.cpp b/src/datavisualization/engine/q3dcamera.cpp
index 426fa51d..c7342aa9 100644
--- a/src/datavisualization/engine/q3dcamera.cpp
+++ b/src/datavisualization/engine/q3dcamera.cpp
@@ -19,12 +19,10 @@
#include "q3dcamera.h"
#include "q3dcamera_p.h"
#include "q3dscene.h"
-#include "q3dbox.h"
#include "q3dobject.h"
#include "utils_p.h"
-#include <qmath.h>
-#include <QVector3D>
+#include <QtCore/qmath.h>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -35,9 +33,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \since Qt Data Visualization 1.0
*
* Q3DCamera represents a basic orbit around centerpoint 3D camera that is used when rendering the
- * data visualization. The class offers simple methods for setting the orbit point in rotations,
- * but allows also setting the 4x4 view matrix directly in case a more customized camera behavior is
- * needed.
+ * data visualization. The class offers simple methods for rotating the camera around the origin
+ * and setting zoom level.
*/
/*!
@@ -85,9 +82,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \brief Representation of a camera in 3D space.
*
* Camera3D represents a basic orbit around centerpoint 3D camera that is used when rendering the
- * data visualization. The class offers simple methods for setting the orbit point in rotations,
- * but allows also setting the 4x4 view matrix directly in case a more customized camera behavior is
- * needed.
+ * data visualization. The type offers simple methods for rotating the camera around the origin
+ * and setting zoom level.
*
* For Camera3D enums, see \l Q3DCamera::CameraPreset
*/
@@ -107,74 +103,6 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
- * \qmlproperty float Camera3D::minXRotation
- *
- * This property contains the current minimum X-rotation for the camera.
- * The full circle range is \c{[-180, 180]} and the minimum value is limited to \c -180.
- * Also the value can't be higher than the maximum, and is adjusted if necessary.
- *
- * \sa wrapXRotation, maxXRotation
- */
-
-/*!
- * \qmlproperty float Camera3D::minYRotation
- *
- * This property contains the current minimum Y-rotation for the camera.
- * The full Y angle range is \c{[-90, 90]} and the minimum value is limited to \c -90.
- * Also the value can't be higher than the maximum, and is adjusted if necessary.
- *
- * \sa wrapYRotation, maxYRotation
- */
-
-/*!
- * \qmlproperty float Camera3D::maxXRotation
- *
- * This property contains the current maximum X-rotation for the camera.
- * The full circle range is \c{[-180, 180]} and the maximum value is limited to \c 180.
- * Also the value can't be lower than the minimum, and is adjusted if necessary.
- *
- * \sa wrapXRotation, minXRotation
- */
-
-/*!
- * \qmlproperty float Camera3D::maxYRotation
- *
- * This property contains the current maximum Y-rotation for the camera.
- * The full Y angle range is \c{[-90, 90]} and the maximum value is limited to \c 90.
- * Also the value can't be lower than the minimum, and is adjusted if necessary.
- *
- * \sa wrapYRotation, minYRotation
- */
-
-/*!
- * \qmlmethod void Camera3D::setBaseOrientation(vector3d basePosition, vector3d target, vector3d baseUp)
- *
- * Sets the base values for the camera that are used when calculating the camera position using the
- * rotation values. The base position of the camera is defined by \a basePosition, expectation is
- * that the x and y values are 0. Look at target point is defined by \a target and the camera
- * rotates around it. Up direction for the camera is defined by \a baseUp, normally this is a
- * vector with only y value set to 1.
- */
-
-/*!
- * \qmlproperty matrix4x4 Camera3D::viewMatrix
- *
- * This property contains the view matrix used in the 3D calculations. When the default orbiting
- * camera behavior is sufficient, there is no need to touch this property. If the default
- * behavior is insufficient, the view matrix can be set directly.
- * \note When setting the view matrix directly remember to set viewMatrixAutoUpdateEnabled
- * property to \c false.
- */
-
-/*!
- * \qmlproperty bool Camera3D::viewMatrixAutoUpdateEnabled
- *
- * This property determines if view matrix is automatically updated each render cycle using the
- * current base orientation and rotations. If set to \c false, no automatic recalculation is done and
- * the view matrix can be set using the viewMatrix property.
- */
-
-/*!
* \qmlproperty Camera3D.CameraPreset Camera3D::cameraPreset
*
* This property contains the currently active camera preset, which is one of
@@ -272,8 +200,7 @@ void Q3DCamera::copyValuesFrom(const Q3DObject &source)
/*!
* \property Q3DCamera::xRotation
*
- * This property contains the X-rotation angle of the camera around the target point in degrees
- * starting from the current base position set by the setBaseOrientation() method.
+ * This property contains the X-rotation angle of the camera around the target point in degrees.
*/
float Q3DCamera::xRotation() const {
return d_ptr->m_xRotation;
@@ -300,8 +227,7 @@ void Q3DCamera::setXRotation(float rotation)
/*!
* \property Q3DCamera::yRotation
*
- * This property contains the Y-rotation angle of the camera around the target point in degrees
- * starting from the current base position set by the setBaseOrientation() method.
+ * This property contains the Y-rotation angle of the camera around the target point in degrees.
*/
float Q3DCamera::yRotation() const {
return d_ptr->m_yRotation;
@@ -326,192 +252,10 @@ void Q3DCamera::setYRotation(float rotation)
}
/*!
- * \property Q3DCamera::minXRotation
- *
- * This property contains the current minimum X-rotation for the camera.
- * The full circle range is \c{[-180, 180]} and the minimum value is limited to \c -180.
- * Also the value can't be higher than the maximum, and is adjusted if necessary.
- *
- * \sa wrapXRotation, maxXRotation
- */
-float Q3DCamera::minXRotation() const
-{
- return d_ptr->m_minXRotation;
-}
-
-void Q3DCamera::setMinXRotation(float minRotation)
-{
- minRotation = qBound(-180.0f, minRotation, 180.0f);
- if (minRotation > d_ptr->m_maxXRotation)
- minRotation = d_ptr->m_maxXRotation;
-
- if (d_ptr->m_minXRotation != minRotation) {
- d_ptr->m_minXRotation = minRotation;
- emit minXRotationChanged(minRotation);
-
- if (d_ptr->m_xRotation < d_ptr->m_minXRotation)
- setXRotation(d_ptr->m_xRotation);
- }
-}
-
-/*!
- * \property Q3DCamera::minYRotation
- *
- * This property contains the current minimum Y-rotation for the camera.
- * The full Y angle range is \c{[-90, 90]} and the minimum value is limited to \c -90.
- * Also the value can't be higher than the maximum, and is adjusted if necessary.
- *
- * \sa wrapYRotation, maxYRotation
- */
-float Q3DCamera::minYRotation() const
-{
- return d_ptr->m_minYRotation;
-}
-
-void Q3DCamera::setMinYRotation(float minRotation)
-{
- minRotation = qBound(-90.0f, minRotation, 90.0f);
- if (minRotation > d_ptr->m_maxYRotation)
- minRotation = d_ptr->m_maxYRotation;
-
- if (d_ptr->m_minYRotation != minRotation) {
- d_ptr->m_minYRotation = minRotation;
- emit minYRotationChanged(minRotation);
-
- if (d_ptr->m_yRotation < d_ptr->m_minYRotation)
- setYRotation(d_ptr->m_yRotation);
- }
-}
-
-/*!
- * \property Q3DCamera::maxXRotation
- *
- * This property contains the current maximum X-rotation for the camera.
- * The full circle range is \c{[-180, 180]} and the maximum value is limited to \c 180.
- * Also the value can't be lower than the minimum, and is adjusted if necessary.
- *
- * \sa wrapXRotation, minXRotation
- */
-float Q3DCamera::maxXRotation() const
-{
- return d_ptr->m_maxXRotation;
-}
-
-void Q3DCamera::setMaxXRotation(float maxRotation)
-{
- maxRotation = qBound(-180.0f, maxRotation, 180.0f);
-
- if (maxRotation < d_ptr->m_minXRotation)
- maxRotation = d_ptr->m_minXRotation;
-
- if (d_ptr->m_maxXRotation != maxRotation) {
- d_ptr->m_maxXRotation = maxRotation;
- emit maxXRotationChanged(maxRotation);
-
- if (d_ptr->m_xRotation > d_ptr->m_maxXRotation)
- setXRotation(d_ptr->m_xRotation);
- }
-}
-
-/*!
- * \property Q3DCamera::maxYRotation
- *
- * This property contains the current maximum Y-rotation for the camera.
- * The full Y angle range is \c{[-90, 90]} and the maximum value is limited to \c 90.
- * Also the value can't be lower than the minimum, and is adjusted if necessary.
- *
- * \sa wrapYRotation, minYRotation
- */
-float Q3DCamera::maxYRotation() const
-{
- return d_ptr->m_maxYRotation;
-}
-
-void Q3DCamera::setMaxYRotation(float maxRotation)
-{
- maxRotation = qBound(-90.0f, maxRotation, 90.0f);
-
- if (maxRotation < d_ptr->m_minYRotation)
- maxRotation = d_ptr->m_minYRotation;
-
- if (d_ptr->m_maxYRotation != maxRotation) {
- d_ptr->m_maxYRotation = maxRotation;
- emit maxYRotationChanged(maxRotation);
-
- if (d_ptr->m_yRotation > d_ptr->m_maxYRotation)
- setYRotation(d_ptr->m_yRotation);
- }
-}
-
-/*!
- * Sets the base values for the camera that are used when calculating the camera position using the
- * rotation values. The base position of the camera is defined by \a basePosition, expectation is
- * that the x and y values are 0. Look at target point is defined by \a target and the camera
- * rotates around it. Up direction for the camera is defined by \a baseUp, normally this is a
- * vector with only y value set to 1.
- */
-void Q3DCamera::setBaseOrientation(const QVector3D &basePosition,
- const QVector3D &target,
- const QVector3D &baseUp)
-{
- if (position() != basePosition
- || d_ptr->m_target != target
- || d_ptr->m_up != baseUp) {
- setPosition(basePosition);
- d_ptr->m_target = target;
- d_ptr->m_up = baseUp;
- setDirty(true);
- }
-}
-
-/*!
- * \property Q3DCamera::viewMatrix
- *
- * This property contains the view matrix used in the 3D calculations. When the default orbiting
- * camera behavior is sufficient, there is no need to touch this property. If the default
- * behavior is insufficient, the view matrix can be set directly.
- * \note When setting the view matrix directly remember to set viewMatrixAutoUpdateEnabled to
- * \c false.
- */
-QMatrix4x4 Q3DCamera::viewMatrix() const
-{
- return d_ptr->m_viewMatrix;
-}
-
-void Q3DCamera::setViewMatrix(const QMatrix4x4 &viewMatrix)
-{
- if (d_ptr->m_viewMatrix != viewMatrix) {
- d_ptr->m_viewMatrix = viewMatrix;
- setDirty(true);
- emit viewMatrixChanged(d_ptr->m_viewMatrix);
- }
-}
-
-/*!
- * \property Q3DCamera::viewMatrixAutoUpdateEnabled
- *
- * This property determines if view matrix is automatically updated each render cycle using the
- * current base orientation and rotations. If set to \c false, no automatic recalculation is done
- * and the view matrix can be set using the viewMatrix property.
- */
-bool Q3DCamera::isViewMatrixAutoUpdateEnabled() const
-{
- return d_ptr->m_isViewMatrixUpdateActive;
-}
-
-void Q3DCamera::setViewMatrixAutoUpdateEnabled(bool isEnabled)
-{
- d_ptr->m_isViewMatrixUpdateActive = isEnabled;
- emit viewMatrixAutoUpdateChanged(isEnabled);
-}
-
-/*!
* \property Q3DCamera::cameraPreset
*
* This property contains the currently active camera preset, if no preset is active the value
* is CameraPresetNone.
- * \note The base camera orientation set by setBaseOrientation() will affect
- * the presets as all calculations are based on those values.
*/
Q3DCamera::CameraPreset Q3DCamera::cameraPreset() const
{
@@ -674,42 +418,6 @@ void Q3DCamera::setZoomLevel(int zoomLevel)
}
/*!
- * Calculates and returns a position relative to the camera using the given parameters
- * and the current camera viewMatrix property.
- * The relative 3D offset to the current camera position is defined in \a relativePosition.
- * An optional fixed rotation of the calculated point around the data visualization area can be
- * given in \a fixedRotation. The rotation is given in degrees.
- * An optional \a distanceModifier modifies the distance of the calculated point from the data
- * visualization.
- * \return calculated position relative to this camera's position.
- */
-QVector3D Q3DCamera::calculatePositionRelativeToCamera(const QVector3D &relativePosition,
- float fixedRotation,
- float distanceModifier) const
-{
- // Move the position with camera
- GLfloat radiusFactor = cameraDistance * (1.5f + distanceModifier);
- GLfloat xAngle;
- GLfloat yAngle;
- if (!fixedRotation) {
- xAngle = qDegreesToRadians(d_ptr->m_xRotation);
- yAngle = qDegreesToRadians(d_ptr->m_yRotation);
- } else {
- xAngle = qDegreesToRadians(fixedRotation);
- yAngle = 0;
- }
- GLfloat radius = (radiusFactor + relativePosition.y()); // set radius to match the highest height of the position
- GLfloat zPos = radius * qCos(xAngle) * qCos(yAngle);
- GLfloat xPos = radius * qSin(xAngle) * qCos(yAngle);
- GLfloat yPos = (radiusFactor + relativePosition.y()) * qSin(yAngle);
-
- // Keep in the set position in relation to camera
- return QVector3D(-xPos + relativePosition.x(),
- yPos + relativePosition.y(),
- zPos + relativePosition.z());
-}
-
-/*!
* \property Q3DCamera::wrapXRotation
*
* This property determines the behavior of the minimum and maximum limits in the X-rotation.
@@ -809,34 +517,120 @@ void Q3DCameraPrivate::setYRotation(const float rotation)
}
}
-void Q3DCameraPrivate::setMinXRotation(const float rotation)
+/*!
+ * \internal
+ * This property contains the current minimum X-rotation for the camera.
+ * The full circle range is \c{[-180, 180]} and the minimum value is limited to \c -180.
+ * Also the value can't be higher than the maximum, and is adjusted if necessary.
+ *
+ * \sa wrapXRotation, maxXRotation
+ */
+float Q3DCameraPrivate::minXRotation() const
+{
+ return m_minXRotation;
+}
+
+void Q3DCameraPrivate::setMinXRotation(float minRotation)
{
- if (m_minXRotation != rotation) {
- m_minXRotation = rotation;
+ minRotation = qBound(-180.0f, minRotation, 180.0f);
+ if (minRotation > m_maxXRotation)
+ minRotation = m_maxXRotation;
+
+ if (m_minXRotation != minRotation) {
+ m_minXRotation = minRotation;
+ emit minXRotationChanged(minRotation);
+
+ if (m_xRotation < m_minXRotation)
+ setXRotation(m_xRotation);
q_ptr->setDirty(true);
}
}
-void Q3DCameraPrivate::setMinYRotation(const float rotation)
+/*!
+ * \internal
+ * This property contains the current minimum Y-rotation for the camera.
+ * The full Y angle range is \c{[-90, 90]} and the minimum value is limited to \c -90.
+ * Also the value can't be higher than the maximum, and is adjusted if necessary.
+ *
+ * \sa wrapYRotation, maxYRotation
+ */
+float Q3DCameraPrivate::minYRotation() const
+{
+ return m_minYRotation;
+}
+
+void Q3DCameraPrivate::setMinYRotation(float minRotation)
{
- if (m_minYRotation != rotation) {
- m_minYRotation = rotation;
+ minRotation = qBound(-90.0f, minRotation, 90.0f);
+ if (minRotation > m_maxYRotation)
+ minRotation = m_maxYRotation;
+
+ if (m_minYRotation != minRotation) {
+ m_minYRotation = minRotation;
+ emit minYRotationChanged(minRotation);
+
+ if (m_yRotation < m_minYRotation)
+ setYRotation(m_yRotation);
q_ptr->setDirty(true);
}
}
-void Q3DCameraPrivate::setMaxXRotation(const float rotation)
+/*!
+ * \internal
+ * This property contains the current maximum X-rotation for the camera.
+ * The full circle range is \c{[-180, 180]} and the maximum value is limited to \c 180.
+ * Also the value can't be lower than the minimum, and is adjusted if necessary.
+ *
+ * \sa wrapXRotation, minXRotation
+ */
+float Q3DCameraPrivate::maxXRotation() const
{
- if (m_maxXRotation != rotation) {
- m_maxXRotation = rotation;
+ return m_maxXRotation;
+}
+
+void Q3DCameraPrivate::setMaxXRotation(float maxRotation)
+{
+ maxRotation = qBound(-180.0f, maxRotation, 180.0f);
+
+ if (maxRotation < m_minXRotation)
+ maxRotation = m_minXRotation;
+
+ if (m_maxXRotation != maxRotation) {
+ m_maxXRotation = maxRotation;
+ emit maxXRotationChanged(maxRotation);
+
+ if (m_xRotation > m_maxXRotation)
+ setXRotation(m_xRotation);
q_ptr->setDirty(true);
}
}
-void Q3DCameraPrivate::setMaxYRotation(const float rotation)
+/*!
+ * \internal
+ * This property contains the current maximum Y-rotation for the camera.
+ * The full Y angle range is \c{[-90, 90]} and the maximum value is limited to \c 90.
+ * Also the value can't be lower than the minimum, and is adjusted if necessary.
+ *
+ * \sa wrapYRotation, minYRotation
+ */
+float Q3DCameraPrivate::maxYRotation() const
+{
+ return m_maxYRotation;
+}
+
+void Q3DCameraPrivate::setMaxYRotation(float maxRotation)
{
- if (m_maxYRotation != rotation) {
- m_maxYRotation = rotation;
+ maxRotation = qBound(-90.0f, maxRotation, 90.0f);
+
+ if (maxRotation < m_minYRotation)
+ maxRotation = m_minYRotation;
+
+ if (m_maxYRotation != maxRotation) {
+ m_maxYRotation = maxRotation;
+ emit maxYRotationChanged(maxRotation);
+
+ if (m_yRotation > m_maxYRotation)
+ setYRotation(m_yRotation);
q_ptr->setDirty(true);
}
}
@@ -866,7 +660,103 @@ void Q3DCameraPrivate::updateViewMatrix(float zoomAdjustment)
// Compensate for translation (if d_ptr->m_target is off origin)
viewMatrix.translate(-m_target.x(), -m_target.y(), -m_target.z());
- q_ptr->setViewMatrix(viewMatrix);
+ setViewMatrix(viewMatrix);
+}
+
+/*!
+ * \internal
+ * This property contains the view matrix used in the 3D calculations. When the default orbiting
+ * camera behavior is sufficient, there is no need to touch this property. If the default
+ * behavior is insufficient, the view matrix can be set directly.
+ * \note When setting the view matrix directly remember to set viewMatrixAutoUpdateEnabled to
+ * \c false.
+ */
+QMatrix4x4 Q3DCameraPrivate::viewMatrix() const
+{
+ return m_viewMatrix;
+}
+
+void Q3DCameraPrivate::setViewMatrix(const QMatrix4x4 &viewMatrix)
+{
+ if (m_viewMatrix != viewMatrix) {
+ m_viewMatrix = viewMatrix;
+ q_ptr->setDirty(true);
+ emit viewMatrixChanged(m_viewMatrix);
+ }
+}
+
+/*!
+ * \internal
+ * This property determines if view matrix is automatically updated each render cycle using the
+ * current base orientation and rotations. If set to \c false, no automatic recalculation is done
+ * and the view matrix can be set using the viewMatrix property.
+ */
+bool Q3DCameraPrivate::isViewMatrixAutoUpdateEnabled() const
+{
+ return m_isViewMatrixUpdateActive;
+}
+
+void Q3DCameraPrivate::setViewMatrixAutoUpdateEnabled(bool isEnabled)
+{
+ m_isViewMatrixUpdateActive = isEnabled;
+ emit viewMatrixAutoUpdateChanged(isEnabled);
+}
+
+/*!
+ * \internal
+ * Sets the base values for the camera that are used when calculating the camera position using the
+ * rotation values. The base position of the camera is defined by \a basePosition, expectation is
+ * that the x and y values are 0. Look at target point is defined by \a target and the camera
+ * rotates around it. Up direction for the camera is defined by \a baseUp, normally this is a
+ * vector with only y value set to 1.
+ */
+void Q3DCameraPrivate::setBaseOrientation(const QVector3D &basePosition,
+ const QVector3D &target,
+ const QVector3D &baseUp)
+{
+ if (q_ptr->position() != basePosition || m_target != target || m_up != baseUp) {
+ q_ptr->setPosition(basePosition);
+ m_target = target;
+ m_up = baseUp;
+ q_ptr->setDirty(true);
+ }
+}
+
+/*!
+ * \internal
+ * Calculates and returns a position relative to the camera using the given parameters
+ * and the current camera viewMatrix property.
+ * The relative 3D offset to the current camera position is defined in \a relativePosition.
+ * An optional fixed rotation of the calculated point around the data visualization area can be
+ * given in \a fixedRotation. The rotation is given in degrees.
+ * An optional \a distanceModifier modifies the distance of the calculated point from the data
+ * visualization.
+ * \return calculated position relative to this camera's position.
+ */
+QVector3D Q3DCameraPrivate::calculatePositionRelativeToCamera(const QVector3D &relativePosition,
+ float fixedRotation,
+ float distanceModifier) const
+{
+ // Move the position with camera
+ GLfloat radiusFactor = cameraDistance * (1.5f + distanceModifier);
+ GLfloat xAngle;
+ GLfloat yAngle;
+ if (!fixedRotation) {
+ xAngle = qDegreesToRadians(m_xRotation);
+ yAngle = qDegreesToRadians(m_yRotation);
+ } else {
+ xAngle = qDegreesToRadians(fixedRotation);
+ yAngle = 0;
+ }
+ GLfloat radius = (radiusFactor + relativePosition.y()); // set radius to match the highest height of the position
+ GLfloat zPos = radius * qCos(xAngle) * qCos(yAngle);
+ GLfloat xPos = radius * qSin(xAngle) * qCos(yAngle);
+ GLfloat yPos = (radiusFactor + relativePosition.y()) * qSin(yAngle);
+
+ // Keep in the set position in relation to camera
+ return QVector3D(-xPos + relativePosition.x(),
+ yPos + relativePosition.y(),
+ zPos + relativePosition.z());
}
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/q3dcamera.h b/src/datavisualization/engine/q3dcamera.h
index 1a3a3284..87602e5c 100644
--- a/src/datavisualization/engine/q3dcamera.h
+++ b/src/datavisualization/engine/q3dcamera.h
@@ -20,10 +20,6 @@
#define Q3DCAMERA_H
#include <QtDataVisualization/q3dobject.h>
-#include <QMatrix4x4>
-
-class QVector3D;
-class QPoint;
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -35,14 +31,8 @@ class QT_DATAVISUALIZATION_EXPORT Q3DCamera : public Q3DObject
Q_ENUMS(CameraPreset)
Q_PROPERTY(float xRotation READ xRotation WRITE setXRotation NOTIFY xRotationChanged)
Q_PROPERTY(float yRotation READ yRotation WRITE setYRotation NOTIFY yRotationChanged)
- Q_PROPERTY(float minXRotation READ minXRotation NOTIFY minXRotationChanged)
- Q_PROPERTY(float minYRotation READ minYRotation NOTIFY minYRotationChanged)
- Q_PROPERTY(float maxXRotation READ maxXRotation NOTIFY maxXRotationChanged)
- Q_PROPERTY(float maxYRotation READ maxYRotation NOTIFY maxYRotationChanged)
Q_PROPERTY(int zoomLevel READ zoomLevel WRITE setZoomLevel NOTIFY zoomLevelChanged)
- Q_PROPERTY(QMatrix4x4 viewMatrix READ viewMatrix WRITE setViewMatrix NOTIFY viewMatrixChanged)
Q_PROPERTY(CameraPreset cameraPreset READ cameraPreset WRITE setCameraPreset NOTIFY cameraPresetChanged)
- Q_PROPERTY(bool viewMatrixAutoUpdateEnabled READ isViewMatrixAutoUpdateEnabled WRITE setViewMatrixAutoUpdateEnabled NOTIFY viewMatrixAutoUpdateChanged)
Q_PROPERTY(bool wrapXRotation READ wrapXRotation WRITE setWrapXRotation NOTIFY wrapXRotationChanged)
Q_PROPERTY(bool wrapYRotation READ wrapYRotation WRITE setWrapYRotation NOTIFY wrapYRotationChanged)
@@ -75,7 +65,6 @@ public:
CameraPresetDirectlyBelow
};
-public:
Q3DCamera(QObject *parent = 0);
virtual ~Q3DCamera();
@@ -84,12 +73,6 @@ public:
float yRotation() const;
void setYRotation(float rotation);
- float minXRotation() const;
- float maxXRotation() const;
-
- float minYRotation() const;
- float maxYRotation() const;
-
bool wrapXRotation() const;
void setWrapXRotation(bool isEnabled);
@@ -98,48 +81,23 @@ public:
virtual void copyValuesFrom(const Q3DObject &source);
- QMatrix4x4 viewMatrix() const;
- void setViewMatrix(const QMatrix4x4 &viewMatrix);
-
- bool isViewMatrixAutoUpdateEnabled() const;
- void setViewMatrixAutoUpdateEnabled(bool isEnabled);
-
CameraPreset cameraPreset() const;
void setCameraPreset(CameraPreset preset);
int zoomLevel() const;
void setZoomLevel(int zoomLevel);
- Q_INVOKABLE void setBaseOrientation(const QVector3D &defaultPosition,
- const QVector3D &defaultTarget,
- const QVector3D &defaultUp);
-
- QVector3D calculatePositionRelativeToCamera(const QVector3D &relativePosition,
- float fixedRotation,
- float distanceModifier) const;
void setCameraPosition(float horizontal, float vertical, float distance = 100.0f);
signals:
void xRotationChanged(float rotation);
void yRotationChanged(float rotation);
- void minXRotationChanged(float rotation);
- void minYRotationChanged(float rotation);
- void maxXRotationChanged(float rotation);
- void maxYRotationChanged(float rotation);
void zoomLevelChanged(int zoomLevel);
- void viewMatrixChanged(QMatrix4x4 viewMatrix);
void cameraPresetChanged(CameraPreset preset);
- void viewMatrixAutoUpdateChanged(bool enabled);
void wrapXRotationChanged(bool isEnabled);
void wrapYRotationChanged(bool isEnabled);
private:
- void setMinXRotation(float rotation);
- void setMinYRotation(float rotation);
- void setMaxXRotation(float rotation);
- void setMaxYRotation(float rotation);
-
-private:
QScopedPointer<Q3DCameraPrivate> d_ptr;
Q_DISABLE_COPY(Q3DCamera)
@@ -153,7 +111,6 @@ private:
friend class SelectionPointer;
friend class Q3DInputHandler;
friend class QTouch3DInputHandlerPrivate;
- friend class QMac3DInputHandler;
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/q3dcamera_p.h b/src/datavisualization/engine/q3dcamera_p.h
index b55010c8..884229e3 100644
--- a/src/datavisualization/engine/q3dcamera_p.h
+++ b/src/datavisualization/engine/q3dcamera_p.h
@@ -31,13 +31,15 @@
#include "datavisualizationglobal_p.h"
#include "q3dcamera.h"
+#include <QtGui/QMatrix4x4>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class Q3DCamera;
-class Q3DCameraPrivate
+class Q3DCameraPrivate : public QObject
{
+ Q_OBJECT
public:
Q3DCameraPrivate(Q3DCamera *q);
~Q3DCameraPrivate();
@@ -47,12 +49,38 @@ public:
void setXRotation(float rotation);
void setYRotation(float rotation);
void setMinXRotation(float rotation);
+ float minXRotation() const;
void setMinYRotation(float rotation);
+ float minYRotation() const;
void setMaxXRotation(float rotation);
+ float maxXRotation() const;
void setMaxYRotation(float rotation);
+ float maxYRotation() const;
void updateViewMatrix(float zoomAdjustment);
+ QMatrix4x4 viewMatrix() const;
+ void setViewMatrix(const QMatrix4x4 &viewMatrix);
+
+ bool isViewMatrixAutoUpdateEnabled() const;
+ void setViewMatrixAutoUpdateEnabled(bool isEnabled);
+
+ void setBaseOrientation(const QVector3D &defaultPosition,
+ const QVector3D &defaultTarget,
+ const QVector3D &defaultUp);
+
+ QVector3D calculatePositionRelativeToCamera(const QVector3D &relativePosition,
+ float fixedRotation,
+ float distanceModifier) const;
+
+signals:
+ void minXRotationChanged(float rotation);
+ void minYRotationChanged(float rotation);
+ void maxXRotationChanged(float rotation);
+ void maxYRotationChanged(float rotation);
+ void viewMatrixChanged(QMatrix4x4 viewMatrix);
+ void viewMatrixAutoUpdateChanged(bool enabled);
+
public:
Q3DCamera *q_ptr;
@@ -79,7 +107,6 @@ public:
friend class SelectionPointer;
friend class Q3DInputHandler;
friend class QTouch3DInputHandler;
- friend class QMac3DInputHandler;
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/q3dlight.h b/src/datavisualization/engine/q3dlight.h
index 876601a7..6d51b90f 100644
--- a/src/datavisualization/engine/q3dlight.h
+++ b/src/datavisualization/engine/q3dlight.h
@@ -24,7 +24,6 @@
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class Q3DLightPrivate;
-class Q3DScene;
class QT_DATAVISUALIZATION_EXPORT Q3DLight : public Q3DObject
{
diff --git a/src/datavisualization/engine/q3dobject.h b/src/datavisualization/engine/q3dobject.h
index 07506f63..4ea505bb 100644
--- a/src/datavisualization/engine/q3dobject.h
+++ b/src/datavisualization/engine/q3dobject.h
@@ -19,14 +19,14 @@
#ifndef Q3DOBJECT_H
#define Q3DOBJECT_H
-#include <QtDataVisualization/q3dscene.h>
-
-#include <QObject>
-#include <QVector3D>
+#include <QtDataVisualization/qdatavisualizationglobal.h>
+#include <QtCore/QObject>
+#include <QtGui/QVector3D>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class Q3DObjectPrivate;
+class Q3DScene;
class QT_DATAVISUALIZATION_EXPORT Q3DObject : public QObject
{
@@ -46,7 +46,7 @@ public:
void setPosition(const QVector3D &position);
signals:
- void positionChanged(QVector3D position);
+ void positionChanged(const QVector3D &position);
protected:
void setDirty(bool dirty);
diff --git a/src/datavisualization/engine/q3dscatter.cpp b/src/datavisualization/engine/q3dscatter.cpp
index db7d2491..7c7809f3 100644
--- a/src/datavisualization/engine/q3dscatter.cpp
+++ b/src/datavisualization/engine/q3dscatter.cpp
@@ -87,6 +87,8 @@ Q3DScatter::Q3DScatter(const QSurfaceFormat *format, QWindow *parent)
dptr()->m_shared = new Scatter3DController(geometry());
d_ptr->setVisualController(dptr()->m_shared);
dptr()->m_shared->initializeOpenGL();
+ QObject::connect(dptr()->m_shared, &Scatter3DController::selectedSeriesChanged,
+ this, &Q3DScatter::selectedSeriesChanged);
}
/*!
@@ -202,6 +204,16 @@ QValue3DAxis *Q3DScatter::axisZ() const
}
/*!
+ * \property Q3DScatter::selectedSeries
+ *
+ * The selected series or \c null.
+ */
+QScatter3DSeries *Q3DScatter::selectedSeries() const
+{
+ return dptrc()->m_shared->selectedSeries();
+}
+
+/*!
* Adds \a axis to the graph. The axes added via addAxis are not yet taken to use,
* addAxis is simply used to give the ownership of the \a axis to the graph.
* The \a axis must not be null or added to another graph.
diff --git a/src/datavisualization/engine/q3dscatter.h b/src/datavisualization/engine/q3dscatter.h
index 55158537..016431af 100644
--- a/src/datavisualization/engine/q3dscatter.h
+++ b/src/datavisualization/engine/q3dscatter.h
@@ -20,16 +20,12 @@
#define Q3DSCATTER_H
#include <QtDataVisualization/qabstract3dgraph.h>
-#include <QtDataVisualization/q3dscene.h>
-#include <QFont>
-#include <QLinearGradient>
+#include <QtDataVisualization/qvalue3daxis.h>
+#include <QtDataVisualization/qscatter3dseries.h>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class Q3DScatterPrivate;
-class QValue3DAxis;
-class QCategory3DAxis;
-class QScatter3DSeries;
class QT_DATAVISUALIZATION_EXPORT Q3DScatter : public QAbstract3DGraph
{
@@ -37,6 +33,7 @@ class QT_DATAVISUALIZATION_EXPORT Q3DScatter : public QAbstract3DGraph
Q_PROPERTY(QValue3DAxis *axisX READ axisX WRITE setAxisX NOTIFY axisXChanged)
Q_PROPERTY(QValue3DAxis *axisY READ axisY WRITE setAxisY NOTIFY axisYChanged)
Q_PROPERTY(QValue3DAxis *axisZ READ axisZ WRITE setAxisZ NOTIFY axisZChanged)
+ Q_PROPERTY(QScatter3DSeries *selectedSeries READ selectedSeries NOTIFY selectedSeriesChanged)
public:
explicit Q3DScatter(const QSurfaceFormat *format = 0, QWindow *parent = 0);
@@ -56,10 +53,13 @@ public:
void releaseAxis(QValue3DAxis *axis);
QList<QValue3DAxis *> axes() const;
+ QScatter3DSeries *selectedSeries() const;
+
signals:
void axisXChanged(QValue3DAxis *axis);
void axisYChanged(QValue3DAxis *axis);
void axisZChanged(QValue3DAxis *axis);
+ void selectedSeriesChanged(QScatter3DSeries *series);
private:
Q3DScatterPrivate *dptr();
diff --git a/src/datavisualization/engine/q3dscene.cpp b/src/datavisualization/engine/q3dscene.cpp
index 6ee4e275..be64b928 100644
--- a/src/datavisualization/engine/q3dscene.cpp
+++ b/src/datavisualization/engine/q3dscene.cpp
@@ -16,8 +16,6 @@
**
****************************************************************************/
-#include <qmath.h>
-
#include "datavisualizationglobal_p.h"
#include "q3dscene.h"
@@ -25,6 +23,8 @@
#include "q3dcamera_p.h"
#include "q3dlight_p.h"
+#include <QtCore/qmath.h>
+
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
/*!
@@ -438,23 +438,6 @@ void Q3DScene::setDevicePixelRatio(float pixelRatio)
}
}
-/*!
- * Calculates and sets the light position relative to the currently active camera using the given
- * parameters.
- * The relative 3D offset to the current camera position is defined in \a relativePosition.
- * Optional \a fixedRotation fixes the light rotation around the data visualization area to the
- * given value in degrees.
- * Optional \a distanceModifier modifies the distance of the light from the data visualization.
- */
-void Q3DScene::setLightPositionRelativeToCamera(const QVector3D &relativePosition,
- float fixedRotation, float distanceModifier)
-{
- d_ptr->m_light->setPosition(
- d_ptr->m_camera->calculatePositionRelativeToCamera(relativePosition,
- fixedRotation,
- distanceModifier));
-}
-
Q3DScenePrivate::Q3DScenePrivate(Q3DScene *q) :
QObject(0),
q_ptr(q),
@@ -650,4 +633,21 @@ QRect Q3DScenePrivate::glSecondarySubViewport()
return m_glSecondarySubViewport;
}
+/*!
+ * \internal
+ * Calculates and sets the light position relative to the currently active camera using the given
+ * parameters.
+ * The relative 3D offset to the current camera position is defined in \a relativePosition.
+ * Optional \a fixedRotation fixes the light rotation around the data visualization area to the
+ * given value in degrees.
+ * Optional \a distanceModifier modifies the distance of the light from the data visualization.
+ */
+void Q3DScenePrivate::setLightPositionRelativeToCamera(const QVector3D &relativePosition,
+ float fixedRotation, float distanceModifier)
+{
+ m_light->setPosition(m_camera->d_ptr->calculatePositionRelativeToCamera(relativePosition,
+ fixedRotation,
+ distanceModifier));
+}
+
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/q3dscene.h b/src/datavisualization/engine/q3dscene.h
index 61a18c9d..d663744e 100644
--- a/src/datavisualization/engine/q3dscene.h
+++ b/src/datavisualization/engine/q3dscene.h
@@ -20,15 +20,13 @@
#define Q3DSCENE_H
#include <QtDataVisualization/qdatavisualizationglobal.h>
-
-#include <QObject>
-#include <QRect>
+#include <QtDataVisualization/q3dcamera.h>
+#include <QtDataVisualization/q3dlight.h>
+#include <QtCore/QObject>
+#include <QtCore/QRect>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
-class Q3DCamera;
-class Q3DBox;
-class Q3DLight;
class Q3DScenePrivate;
class QT_DATAVISUALIZATION_EXPORT Q3DScene : public QObject
@@ -46,7 +44,7 @@ class QT_DATAVISUALIZATION_EXPORT Q3DScene : public QObject
public:
Q3DScene(QObject *parent = 0);
- ~Q3DScene();
+ virtual ~Q3DScene();
QRect viewport() const;
@@ -77,19 +75,16 @@ public:
float devicePixelRatio() const;
void setDevicePixelRatio(float pixelRatio);
- Q_INVOKABLE void setLightPositionRelativeToCamera(const QVector3D &relativePosition,
- float fixedRotation = 0.0f,
- float distanceModifier = 0.0f);
signals:
- void viewportChanged(QRect viewport);
- void primarySubViewportChanged(QRect subViewport);
- void secondarySubViewportChanged(QRect subViewport);
+ void viewportChanged(const QRect &viewport);
+ void primarySubViewportChanged(const QRect &subViewport);
+ void secondarySubViewportChanged(const QRect &subViewport);
void secondarySubviewOnTopChanged(bool isSecondaryOnTop);
void slicingActiveChanged(bool isSlicingActive);
- void activeCameraChanged(const Q3DCamera *camera);
- void activeLightChanged(const Q3DLight *light);
+ void activeCameraChanged(Q3DCamera *camera);
+ void activeLightChanged(Q3DLight *light);
void devicePixelRatioChanged(float pixelRatio);
- void selectionQueryPositionChanged(const QPoint position);
+ void selectionQueryPositionChanged(const QPoint &position);
private:
QScopedPointer<Q3DScenePrivate> d_ptr;
diff --git a/src/datavisualization/engine/q3dscene_p.h b/src/datavisualization/engine/q3dscene_p.h
index be0d3dc5..bc6a7223 100644
--- a/src/datavisualization/engine/q3dscene_p.h
+++ b/src/datavisualization/engine/q3dscene_p.h
@@ -30,7 +30,7 @@
#define Q3DSCENE_P_H
#include "datavisualizationglobal_p.h"
-#include <QRect>
+#include "q3dscene.h"
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -86,6 +86,10 @@ public:
QRect glPrimarySubViewport();
QRect glSecondarySubViewport();
+ void setLightPositionRelativeToCamera(const QVector3D &relativePosition,
+ float fixedRotation = 0.0f,
+ float distanceModifier = 0.0f);
+
signals:
void needRender();
diff --git a/src/datavisualization/engine/q3dsurface.cpp b/src/datavisualization/engine/q3dsurface.cpp
index a8a8235e..7724cb24 100644
--- a/src/datavisualization/engine/q3dsurface.cpp
+++ b/src/datavisualization/engine/q3dsurface.cpp
@@ -32,8 +32,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* \since Qt Data Visualization 1.0
*
* This class enables developers to render 3D surface plots and to view them by rotating the scene
- * freely. The surface plotting includes also gridline that can be set on or off.
- * The visual appearance of the surface can be changed by controlling the smooth status.
+ * freely. The visual properties of the surface such as draw mode and shading can be controlled
+ * via QSurface3DSeries.
*
* The Q3DSurface supports selection by showing a highlighted ball on the data point where the user has clicked
* with left mouse button (when default input handler is in use) or selected via QSurface3DSeries.
@@ -49,8 +49,6 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
* These default axes can be modified via axis accessors, but as soon any axis is set explicitly
* for the orientation, the default axis for that orientation is destroyed.
*
- * Q3DSurface supports only single series at a time.
- *
* \section1 How to construct a minimal Q3DSurface graph
*
* First, construct Q3DSurface. Since we are running the graph as top level window
@@ -100,6 +98,8 @@ Q3DSurface::Q3DSurface(const QSurfaceFormat *format, QWindow *parent)
dptr()->m_shared = new Surface3DController(geometry());
d_ptr->setVisualController(dptr()->m_shared);
dptr()->m_shared->initializeOpenGL();
+ QObject::connect(dptr()->m_shared, &Surface3DController::selectedSeriesChanged,
+ this, &Q3DSurface::selectedSeriesChanged);
}
/*!
@@ -111,8 +111,6 @@ Q3DSurface::~Q3DSurface()
/*!
* Adds the \a series to the graph.
- *
- * \note The surface graph currently supports only a single series at a time.
*/
void Q3DSurface::addSeries(QSurface3DSeries *series)
{
@@ -129,8 +127,6 @@ void Q3DSurface::removeSeries(QSurface3DSeries *series)
/*!
* \return list of series added to this graph.
- *
- * \note The surface graph currently supports only a single series at a time.
*/
QList<QSurface3DSeries *> Q3DSurface::seriesList() const
{
@@ -223,6 +219,17 @@ QValue3DAxis *Q3DSurface::axisZ() const
}
/*!
+ * \property Q3DSurface::selectedSeries
+ *
+ * The selected series or \c null. If selectionMode has \c SelectionMultiSeries flag set, this
+ * property holds the series which owns the selected point.
+ */
+QSurface3DSeries *Q3DSurface::selectedSeries() const
+{
+ return dptrc()->m_shared->selectedSeries();
+}
+
+/*!
* Adds \a axis to the graph. The axes added via addAxis are not yet taken to use,
* addAxis is simply used to give the ownership of the \a axis to the graph.
* The \a axis must not be null or added to another graph.
diff --git a/src/datavisualization/engine/q3dsurface.h b/src/datavisualization/engine/q3dsurface.h
index 7fb6e58a..9868c844 100644
--- a/src/datavisualization/engine/q3dsurface.h
+++ b/src/datavisualization/engine/q3dsurface.h
@@ -20,14 +20,12 @@
#define Q3DSURFACE_H
#include <QtDataVisualization/qabstract3dgraph.h>
-#include <QtDataVisualization/q3dscene.h>
-#include <QFont>
+#include <QtDataVisualization/qvalue3daxis.h>
+#include <QtDataVisualization/qsurface3dseries.h>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class Q3DSurfacePrivate;
-class QValue3DAxis;
-class QSurface3DSeries;
class QT_DATAVISUALIZATION_EXPORT Q3DSurface : public QAbstract3DGraph
{
@@ -35,6 +33,7 @@ class QT_DATAVISUALIZATION_EXPORT Q3DSurface : public QAbstract3DGraph
Q_PROPERTY(QValue3DAxis *axisX READ axisX WRITE setAxisX NOTIFY axisXChanged)
Q_PROPERTY(QValue3DAxis *axisY READ axisY WRITE setAxisY NOTIFY axisYChanged)
Q_PROPERTY(QValue3DAxis *axisZ READ axisZ WRITE setAxisZ NOTIFY axisZChanged)
+ Q_PROPERTY(QSurface3DSeries *selectedSeries READ selectedSeries NOTIFY selectedSeriesChanged)
public:
explicit Q3DSurface(const QSurfaceFormat *format = 0, QWindow *parent = 0);
@@ -55,10 +54,13 @@ public:
void releaseAxis(QValue3DAxis *axis);
QList<QValue3DAxis *> axes() const;
+ QSurface3DSeries *selectedSeries() const;
+
signals:
void axisXChanged(QValue3DAxis *axis);
void axisYChanged(QValue3DAxis *axis);
void axisZChanged(QValue3DAxis *axis);
+ void selectedSeriesChanged(QSurface3DSeries *series);
private:
Q3DSurfacePrivate *dptr();
diff --git a/src/datavisualization/engine/q3dsurface_p.h b/src/datavisualization/engine/q3dsurface_p.h
index 540956b6..0e5a5121 100644
--- a/src/datavisualization/engine/q3dsurface_p.h
+++ b/src/datavisualization/engine/q3dsurface_p.h
@@ -32,8 +32,6 @@
#include "surface3dcontroller_p.h"
#include "qabstract3dgraph_p.h"
-#include <QList>
-
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class Q3DSurface;
diff --git a/src/datavisualization/engine/qabstract3dgraph.cpp b/src/datavisualization/engine/qabstract3dgraph.cpp
index d8146149..f2102b29 100644
--- a/src/datavisualization/engine/qabstract3dgraph.cpp
+++ b/src/datavisualization/engine/qabstract3dgraph.cpp
@@ -23,11 +23,10 @@
#include "q3dscene_p.h"
#include "qutils.h"
-#include <QGuiApplication>
-#include <QOpenGLContext>
-#include <QOpenGLPaintDevice>
-#include <QPainter>
-
+#include <QtGui/QGuiApplication>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLPaintDevice>
+#include <QtGui/QPainter>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -85,10 +84,16 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
automatically. If you wish to control the slice view yourself via Q3DScene, do not set this
flag. When setting this mode flag, either \c SelectionRow or \c SelectionColumn must also
be set, but not both. Slicing is supported by Q3DBars and Q3DSurface only.
+ When this flag is set, slice mode is entered in the following situations:
+ \list
+ \li When selection is changed explicitly via series API to a visible item
+ \li When selection is changed by clicking on the graph
+ \li When the selection mode changes and the selected item is visible
+ \endlist
\value SelectionMultiSeries
Setting this mode means that items for all series at same position are highlighted, instead
of just the selected item. The actual selection in the other series doesn't change.
- Multi-series selection is only supported for Q3DBars.
+ Multi-series selection is not supported for Q3DScatter.
*/
/*!
@@ -216,7 +221,7 @@ void QAbstract3DGraph::setActiveInputHandler(QAbstract3DInputHandler *inputHandl
d_ptr->m_visualController->setActiveInputHandler(inputHandler);
}
-QAbstract3DInputHandler *QAbstract3DGraph::activeInputHandler()
+QAbstract3DInputHandler *QAbstract3DGraph::activeInputHandler() const
{
return d_ptr->m_visualController->activeInputHandler();
}
diff --git a/src/datavisualization/engine/qabstract3dgraph.h b/src/datavisualization/engine/qabstract3dgraph.h
index 9534ce5c..adf67912 100644
--- a/src/datavisualization/engine/qabstract3dgraph.h
+++ b/src/datavisualization/engine/qabstract3dgraph.h
@@ -20,18 +20,15 @@
#define QABSTRACT3DGRAPH_H
#include <QtDataVisualization/qdatavisualizationglobal.h>
-
-#include <QWindow>
-#include <QOpenGLFunctions>
-#include <QScreen>
+#include <QtDataVisualization/q3dtheme.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QtDataVisualization/qabstract3dinputhandler.h>
+#include <QtGui/QWindow>
+#include <QtGui/QOpenGLFunctions>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class QAbstract3DGraphPrivate;
-class Abstract3DController;
-class QAbstract3DInputHandler;
-class Q3DTheme;
-class Q3DScene;
class QT_DATAVISUALIZATION_EXPORT QAbstract3DGraph : public QWindow, protected QOpenGLFunctions
{
@@ -78,7 +75,7 @@ public:
void addInputHandler(QAbstract3DInputHandler *inputHandler);
void releaseInputHandler(QAbstract3DInputHandler *inputHandler);
void setActiveInputHandler(QAbstract3DInputHandler *inputHandler);
- QAbstract3DInputHandler *activeInputHandler();
+ QAbstract3DInputHandler *activeInputHandler() const;
QList<QAbstract3DInputHandler *> inputHandlers() const;
void addTheme(Q3DTheme *theme);
@@ -117,6 +114,7 @@ signals:
void shadowQualityChanged(ShadowQuality quality);
private:
+ Q_DISABLE_COPY(QAbstract3DGraph)
QScopedPointer<QAbstract3DGraphPrivate> d_ptr;
friend class Q3DBars;
diff --git a/src/datavisualization/engine/qabstract3dgraph_p.h b/src/datavisualization/engine/qabstract3dgraph_p.h
index a353797b..d28495ab 100644
--- a/src/datavisualization/engine/qabstract3dgraph_p.h
+++ b/src/datavisualization/engine/qabstract3dgraph_p.h
@@ -31,8 +31,6 @@
#include "datavisualizationglobal_p.h"
-#include <QObject>
-
class QOpenGLContext;
class QOpenGLPaintDevice;
diff --git a/src/datavisualization/engine/scatter3dcontroller.cpp b/src/datavisualization/engine/scatter3dcontroller.cpp
index a1850a3c..54292ac0 100644
--- a/src/datavisualization/engine/scatter3dcontroller.cpp
+++ b/src/datavisualization/engine/scatter3dcontroller.cpp
@@ -24,8 +24,8 @@
#include "qscatterdataproxy_p.h"
#include "qscatter3dseries_p.h"
-#include <QMatrix4x4>
-#include <qmath.h>
+#include <QtGui/QMatrix4x4>
+#include <QtCore/qmath.h>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -303,6 +303,7 @@ void Scatter3DController::setSelectedItem(int index, QScatter3DSeries *series)
index = invalidSelectionIndex();
if (index != m_selectedItem || series != m_selectedItemSeries) {
+ bool seriesChanged = (series != m_selectedItemSeries);
m_selectedItem = index;
m_selectedItemSeries = series;
m_changeTracker.selectedItemChanged = true;
@@ -316,6 +317,9 @@ void Scatter3DController::setSelectedItem(int index, QScatter3DSeries *series)
if (m_selectedItemSeries)
m_selectedItemSeries->dptr()->setSelectedItem(m_selectedItem);
+ if (seriesChanged)
+ emit selectedSeriesChanged(m_selectedItemSeries);
+
emitNeedRender();
}
}
diff --git a/src/datavisualization/engine/scatter3dcontroller_p.h b/src/datavisualization/engine/scatter3dcontroller_p.h
index 173d4e05..53d24549 100644
--- a/src/datavisualization/engine/scatter3dcontroller_p.h
+++ b/src/datavisualization/engine/scatter3dcontroller_p.h
@@ -93,6 +93,8 @@ public:
// Change selection mode
void setSelectionMode(QAbstract3DGraph::SelectionFlags mode);
+ inline QScatter3DSeries *selectedSeries() const { return m_selectedItemSeries; }
+
void setSelectedItem(int index, QScatter3DSeries *series);
static inline int invalidSelectionIndex() { return -1; }
virtual void clearSelection();
@@ -116,6 +118,9 @@ public slots:
void handleItemsRemoved(int startIndex, int count);
void handleItemsInserted(int startIndex, int count);
+signals:
+ void selectedSeriesChanged(QScatter3DSeries *series);
+
protected:
virtual void startRecordingRemovesAndInserts();
diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp
index cf9dbefe..de1a769a 100644
--- a/src/datavisualization/engine/scatter3drenderer.cpp
+++ b/src/datavisualization/engine/scatter3drenderer.cpp
@@ -27,11 +27,10 @@
#include "q3dlight.h"
#include "qscatter3dseries_p.h"
-#include <QMatrix4x4>
-#include <QMouseEvent>
-#include <QThread>
-#include <qmath.h>
-#include <QDebug>
+#include <QtGui/QMatrix4x4>
+#include <QtGui/QMouseEvent>
+#include <QtCore/QThread>
+#include <QtCore/qmath.h>
// Commenting this draws the shadow map with perspective projection. Otherwise it's drawn in
// orthographic projection.
@@ -210,7 +209,10 @@ void Scatter3DRenderer::updateData()
&& (dotPos.z() >= minZ && dotPos.z() <= maxZ)) {
renderItem.setPosition(dotPos);
renderItem.setVisible(true);
- renderItem.setRotation(dataArray.at(i).rotation());
+ if (!dataArray.at(i).rotation().isIdentity())
+ renderItem.setRotation(dataArray.at(i).rotation().normalized());
+ else
+ renderItem.setRotation(identityQuaternion);
calculateTranslation(renderItem);
} else {
renderItem.setVisible(false);
@@ -225,11 +227,11 @@ void Scatter3DRenderer::updateData()
void Scatter3DRenderer::updateScene(Q3DScene *scene)
{
- scene->activeCamera()->setMinYRotation(-90.0f);
+ scene->activeCamera()->d_ptr->setMinYRotation(-90.0f);
if (m_hasHeightAdjustmentChanged) {
// Set initial camera position. Also update if height adjustment has changed.
- scene->activeCamera()->setBaseOrientation(cameraDistanceVector, zeroVector, upVector);
+ scene->activeCamera()->d_ptr->setBaseOrientation(cameraDistanceVector, zeroVector, upVector);
m_hasHeightAdjustmentChanged = false;
}
@@ -273,7 +275,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
projectionMatrix.perspective(45.0f, viewPortRatio, 0.1f, 100.0f);
// Calculate view matrix
- QMatrix4x4 viewMatrix = activeCamera->viewMatrix();
+ QMatrix4x4 viewMatrix = activeCamera->d_ptr->viewMatrix();
QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix;
int seriesCount = m_visibleSeriesList.size();
@@ -354,7 +356,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
// Get the depth view matrix
// It may be possible to hack lightPos here if we want to make some tweaks to shadow
- QVector3D depthLightPos = activeCamera->calculatePositionRelativeToCamera(
+ QVector3D depthLightPos = activeCamera->d_ptr->calculatePositionRelativeToCamera(
zeroVector, 0.0f, 2.5f / m_autoScaleAdjustment);
depthViewMatrix.lookAt(depthLightPos, zeroVector, upVector);
// Set the depth projection matrix
@@ -444,6 +446,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
ShaderHelper *pointSelectionShader = m_selectionShader;
#else
+ Q_UNUSED(havePointSeries);
ShaderHelper *pointSelectionShader = m_pointShader;
#endif
ShaderHelper *selectionShader = m_selectionShader;
@@ -714,7 +717,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
dotShader->setUniformValue(dotShader->color(), dotColor);
} else if (colorStyle == Q3DTheme::ColorStyleRangeGradient) {
dotShader->setUniformValue(dotShader->gradientMin(),
- (item.position().y() + 1.0f) / 2.0f);
+ (item.translation().y() + 1.0f) / 2.0f);
}
#if !defined(QT_OPENGL_ES_2)
if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
@@ -1457,10 +1460,10 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
} else {
glDisable(GL_DEPTH_TEST);
// Draw the selection label
- LabelItem &labelItem = selectedItem->selectionLabelItem();
+ LabelItem &labelItem = selectionLabelItem();
if (m_selectedItem != selectedItem || m_updateLabels
|| !labelItem.textureId() || m_selectionLabelDirty) {
- QString labelText = selectedItem->selectionLabel();
+ QString labelText = selectionLabel();
if (labelText.isNull() || m_selectionLabelDirty) {
static const QString xTitleTag(QStringLiteral("@xTitle"));
static const QString yTitleTag(QStringLiteral("@yTitle"));
@@ -1502,7 +1505,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
}
labelText.replace(seriesNameTag, m_visibleSeriesList[m_selectedItemSeriesIndex].name());
- selectedItem->setSelectionLabel(labelText);
+ setSelectionLabel(labelText);
m_selectionLabelDirty = false;
}
m_drawer->generateLabelItem(labelItem, labelText);
@@ -1531,6 +1534,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
void Scatter3DRenderer::updateSelectedItem(int index, const QScatter3DSeries *series)
{
m_selectionDirty = true;
+ m_selectionLabelDirty = true;
m_selectedSeries = series;
m_selectedItemIndex = Scatter3DController::invalidSelectionIndex();
m_selectedItemTotalIndex = Scatter3DController::invalidSelectionIndex();
@@ -1633,12 +1637,6 @@ void Scatter3DRenderer::fixMeshFileName(QString &fileName, QAbstract3DSeries::Me
}
}
-void Scatter3DRenderer::updateAxisRange(QAbstract3DAxis::AxisOrientation orientation,
- float min, float max)
-{
- Abstract3DRenderer::updateAxisRange(orientation, min, max);
-}
-
void Scatter3DRenderer::calculateTranslation(ScatterRenderItem &item)
{
// We need to normalize translations
diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h
index d7a880f9..5591a362 100644
--- a/src/datavisualization/engine/scatter3drenderer_p.h
+++ b/src/datavisualization/engine/scatter3drenderer_p.h
@@ -141,10 +141,6 @@ private:
friend class ScatterRenderItem;
public slots:
- // Overloaded from abstract renderer
- virtual void updateAxisRange(QAbstract3DAxis::AxisOrientation orientation, float min,
- float max);
-
void updateSelectedItem(int index, const QScatter3DSeries *series);
private:
diff --git a/src/datavisualization/engine/selectionpointer.cpp b/src/datavisualization/engine/selectionpointer.cpp
index 4f5e2114..d4e635bc 100644
--- a/src/datavisualization/engine/selectionpointer.cpp
+++ b/src/datavisualization/engine/selectionpointer.cpp
@@ -21,12 +21,12 @@
#include "shaderhelper_p.h"
#include "objecthelper_p.h"
#include "texturehelper_p.h"
-#include "q3dcamera.h"
+#include "q3dcamera_p.h"
#include "drawer_p.h"
#include "utils_p.h"
#include "q3dlight.h"
-#include <QMatrix4x4>
+#include <QtGui/QMatrix4x4>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -91,11 +91,13 @@ void SelectionPointer::render(GLuint defaultFboHandle)
QMatrix4x4 projectionMatrix;
if (m_cachedIsSlicingActivated) {
GLfloat aspect = (GLfloat)m_mainViewPort.width() / (GLfloat)m_mainViewPort.height();
+ GLfloat sliceUnitsScaled = sliceUnits / m_autoScaleAdjustment;
viewMatrix.lookAt(QVector3D(0.0f, 0.0f, 1.0f), zeroVector, upVector);
- projectionMatrix.ortho(-sliceUnits * aspect, sliceUnits * aspect,
- -sliceUnits, sliceUnits, -1.0f, 4.0f);
+ projectionMatrix.ortho(-sliceUnitsScaled * aspect, sliceUnitsScaled * aspect,
+ -sliceUnitsScaled, sliceUnitsScaled,
+ -1.0f, 4.0f);
} else {
- viewMatrix = camera->viewMatrix();
+ viewMatrix = camera->d_ptr->viewMatrix();
projectionMatrix.perspective(45.0f, (GLfloat)m_mainViewPort.width()
/ (GLfloat)m_mainViewPort.height(), 0.1f, 100.0f);
}
diff --git a/src/datavisualization/engine/selectionpointer_p.h b/src/datavisualization/engine/selectionpointer_p.h
index c72b3510..1eac22be 100644
--- a/src/datavisualization/engine/selectionpointer_p.h
+++ b/src/datavisualization/engine/selectionpointer_p.h
@@ -29,8 +29,6 @@
#ifndef SELECTIONPOINTER_P_H
#define SELECTIONPOINTER_P_H
-#include <QVector3D>
-
#include "q3dscene.h"
#include "datavisualizationglobal_p.h"
#include "surface3dcontroller_p.h"
diff --git a/src/datavisualization/engine/seriesrendercache.cpp b/src/datavisualization/engine/seriesrendercache.cpp
index fe2db319..896b3b28 100644
--- a/src/datavisualization/engine/seriesrendercache.cpp
+++ b/src/datavisualization/engine/seriesrendercache.cpp
@@ -30,6 +30,7 @@ SeriesRenderCache::SeriesRenderCache()
: m_series(0),
m_object(0),
m_mesh(QAbstract3DSeries::MeshCube),
+ m_baseUniformTexture(0),
m_baseGradientTexture(0),
m_singleHighlightGradientTexture(0),
m_multiHighlightGradientTexture(0)
@@ -127,7 +128,11 @@ void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer *
}
if (seriesChanged || changeTracker.meshRotationChanged) {
- m_meshRotation = series->meshRotation();
+ m_meshRotation = series->meshRotation().normalized();
+ if (m_series->type() == QAbstract3DSeries::SeriesTypeBar
+ && (m_meshRotation.x() || m_meshRotation.z())) {
+ m_meshRotation = identityQuaternion;
+ }
changeTracker.meshRotationChanged = false;
}
@@ -138,6 +143,8 @@ void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer *
if (seriesChanged || changeTracker.baseColorChanged) {
m_baseColor = Utils::vectorFromColor(series->baseColor());
+ if (m_series->type() == QAbstract3DSeries::SeriesTypeSurface)
+ renderer->generateBaseColorTexture(series->baseColor(), &m_baseUniformTexture);
changeTracker.baseColorChanged = false;
}
@@ -178,9 +185,12 @@ void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer *
void SeriesRenderCache::cleanup(TextureHelper *texHelper)
{
delete m_object;
- texHelper->deleteTexture(&m_baseGradientTexture);
- texHelper->deleteTexture(&m_singleHighlightGradientTexture);
- texHelper->deleteTexture(&m_multiHighlightGradientTexture);
+ if (QOpenGLContext::currentContext()) {
+ texHelper->deleteTexture(&m_baseUniformTexture);
+ texHelper->deleteTexture(&m_baseGradientTexture);
+ texHelper->deleteTexture(&m_singleHighlightGradientTexture);
+ texHelper->deleteTexture(&m_multiHighlightGradientTexture);
+ }
}
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/seriesrendercache_p.h b/src/datavisualization/engine/seriesrendercache_p.h
index 82f69ccd..77e050b0 100644
--- a/src/datavisualization/engine/seriesrendercache_p.h
+++ b/src/datavisualization/engine/seriesrendercache_p.h
@@ -45,7 +45,7 @@ public:
virtual ~SeriesRenderCache();
void populate(QAbstract3DSeries *series, Abstract3DRenderer *renderer);
- void cleanup(TextureHelper *texHelper);
+ virtual void cleanup(TextureHelper *texHelper);
// NOTE: Series pointer can only be used to access the series when syncing with controller.
// It is not guaranteed to be valid while rendering and should only be used as an identifier.
@@ -58,6 +58,7 @@ public:
inline ObjectHelper *object() const { return m_object; }
inline const Q3DTheme::ColorStyle &colorStyle() const { return m_colorStyle; }
inline const QVector3D &baseColor() const { return m_baseColor; }
+ inline const GLuint &baseUniformTexture() const { return m_baseUniformTexture; }
inline const GLuint &baseGradientTexture() const { return m_baseGradientTexture; }
inline const QVector3D &singleHighlightColor() const { return m_singleHighlightColor; }
inline const GLuint &singleHighlightGradientTexture() const { return m_singleHighlightGradientTexture; }
@@ -74,6 +75,7 @@ protected:
Q3DTheme::ColorStyle m_colorStyle;
QVector3D m_baseColor;
+ GLuint m_baseUniformTexture;
GLuint m_baseGradientTexture;
QVector3D m_singleHighlightColor;
GLuint m_singleHighlightGradientTexture;
diff --git a/src/datavisualization/engine/surface3dcontroller.cpp b/src/datavisualization/engine/surface3dcontroller.cpp
index 0eb66d0e..991a1ce8 100644
--- a/src/datavisualization/engine/surface3dcontroller.cpp
+++ b/src/datavisualization/engine/surface3dcontroller.cpp
@@ -26,9 +26,7 @@
#include "qsurface3dseries_p.h"
#include "shaderhelper_p.h"
-#include <QMatrix4x4>
-
-#include <QDebug>
+#include <QtGui/QMatrix4x4>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -68,6 +66,11 @@ void Surface3DController::synchDataToRenderer()
if (!isInitialized())
return;
+ if (m_changedSeriesList.size()) {
+ m_renderer->modifiedSeriesList(m_changedSeriesList);
+ m_changedSeriesList.clear();
+ }
+
Abstract3DController::synchDataToRenderer();
// Notify changes to renderer
@@ -103,7 +106,7 @@ void Surface3DController::handleAxisRangeChangedBySender(QObject *sender)
Abstract3DController::handleAxisRangeChangedBySender(sender);
// Update selected point - may be moved offscreen
- setSelectedPoint(m_selectedPoint, m_selectedSeries);
+ setSelectedPoint(m_selectedPoint, m_selectedSeries, false);
}
void Surface3DController::handleSeriesVisibilityChangedBySender(QObject *sender)
@@ -112,9 +115,9 @@ void Surface3DController::handleSeriesVisibilityChangedBySender(QObject *sender)
adjustValueAxisRange();
- // Visibility changes may require disabling/enabling slicing,
+ // Visibility changes may require disabling slicing,
// so just reset selection to ensure everything is still valid.
- setSelectedPoint(m_selectedPoint, m_selectedSeries);
+ setSelectedPoint(m_selectedPoint, m_selectedSeries, false);
}
void Surface3DController::handlePendingClick()
@@ -123,7 +126,7 @@ void Surface3DController::handlePendingClick()
QPoint position = m_renderer->clickedPosition();
QSurface3DSeries *series = static_cast<QSurface3DSeries *>(m_renderer->clickedSeries());
- setSelectedPoint(position, series);
+ setSelectedPoint(position, series, true);
m_renderer->resetClickedStatus();
}
@@ -143,18 +146,14 @@ void Surface3DController::addSeries(QAbstract3DSeries *series)
{
Q_ASSERT(series && series->type() == QAbstract3DSeries::SeriesTypeSurface);
- if (!m_seriesList.size()) {
- Abstract3DController::addSeries(series);
+ Abstract3DController::addSeries(series);
- if (series->isVisible())
- adjustValueAxisRange();
- } else {
- qWarning("Surface graph only supports a single series.");
- }
+ if (series->isVisible())
+ adjustValueAxisRange();
QSurface3DSeries *surfaceSeries = static_cast<QSurface3DSeries *>(series);
if (surfaceSeries->selectedPoint() != invalidSelectionPosition())
- setSelectedPoint(surfaceSeries->selectedPoint(), surfaceSeries);
+ setSelectedPoint(surfaceSeries->selectedPoint(), surfaceSeries, false);
}
void Surface3DController::removeSeries(QAbstract3DSeries *series)
@@ -164,7 +163,7 @@ void Surface3DController::removeSeries(QAbstract3DSeries *series)
Abstract3DController::removeSeries(series);
if (m_selectedSeries == series)
- setSelectedPoint(invalidSelectionPosition(), 0);
+ setSelectedPoint(invalidSelectionPosition(), 0, false);
if (wasVisible)
adjustValueAxisRange();
@@ -203,7 +202,7 @@ void Surface3DController::setSelectionMode(QAbstract3DGraph::SelectionFlags mode
if (mode != oldMode) {
// Refresh selection upon mode change to ensure slicing is correctly updated
// according to series the visibility.
- setSelectedPoint(m_selectedPoint, m_selectedSeries);
+ setSelectedPoint(m_selectedPoint, m_selectedSeries, true);
// Special case: Always deactivate slicing when changing away from slice
// automanagement, as this can't be handled in setSelectedBar.
@@ -215,7 +214,7 @@ void Surface3DController::setSelectionMode(QAbstract3DGraph::SelectionFlags mode
}
}
-void Surface3DController::setSelectedPoint(const QPoint &position, QSurface3DSeries *series)
+void Surface3DController::setSelectedPoint(const QPoint &position, QSurface3DSeries *series, bool enterSlice)
{
// If the selection targets non-existent point, clear selection instead.
QPoint pos = position;
@@ -253,14 +252,15 @@ void Surface3DController::setSelectedPoint(const QPoint &position, QSurface3DSer
if (item.x() < axisMinX || item.x() > axisMaxX
|| item.z() < axisMinZ || item.z() > axisMaxZ) {
scene()->setSlicingActive(false);
- } else {
+ } else if (enterSlice) {
scene()->setSlicingActive(true);
}
}
emitNeedRender();
}
- if (pos != m_selectedPoint) {
+ if (pos != m_selectedPoint || series != m_selectedSeries) {
+ bool seriesChanged = (series != m_selectedSeries);
m_selectedPoint = pos;
m_selectedSeries = series;
m_changeTracker.selectedPointChanged = true;
@@ -274,13 +274,16 @@ void Surface3DController::setSelectedPoint(const QPoint &position, QSurface3DSer
if (m_selectedSeries)
m_selectedSeries->dptr()->setSelectedPoint(m_selectedPoint);
+ if (seriesChanged)
+ emit selectedSeriesChanged(m_selectedSeries);
+
emitNeedRender();
}
}
void Surface3DController::clearSelection()
{
- setSelectedPoint(invalidSelectionPosition(), 0);
+ setSelectedPoint(invalidSelectionPosition(), 0, false);
}
void Surface3DController::handleArrayReset()
@@ -288,10 +291,12 @@ void Surface3DController::handleArrayReset()
QSurface3DSeries *series = static_cast<QSurfaceDataProxy *>(sender())->series();
if (series->isVisible()) {
adjustValueAxisRange();
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
m_isDataDirty = true;
}
// Clear selection unless still valid
- setSelectedPoint(m_selectedPoint, m_selectedSeries);
+ setSelectedPoint(m_selectedPoint, m_selectedSeries, false);
emitNeedRender();
}
@@ -315,56 +320,55 @@ void Surface3DController::handleRowsChanged(int startIndex, int count)
m_changedRows.reserve(sender->rowCount());
QSurface3DSeries *series = sender->series();
- if (series->isVisible()) {
- // Change is for the visible series, put the change to queue
- int oldChangeCount = m_changedRows.size();
- for (int i = 0; i < count; i++) {
- bool newItem = true;
- int candidate = startIndex + i;
- for (int i = 0; i < oldChangeCount; i++) {
- if (m_changedRows.at(i) == candidate) {
- newItem = false;
- break;
- }
+ int oldChangeCount = m_changedRows.size();
+ for (int i = 0; i < count; i++) {
+ bool newItem = true;
+ int candidate = startIndex + i;
+ for (int i = 0; i < oldChangeCount; i++) {
+ if (m_changedRows.at(i).row == candidate &&
+ series == m_changedRows.at(i).series) {
+ newItem = false;
+ break;
}
- if (newItem)
- m_changedRows.append(candidate);
}
- if (m_changedRows.size()) {
- m_changeTracker.rowsChanged = true;
-
- adjustValueAxisRange();
- // Clear selection unless still valid
- setSelectedPoint(m_selectedPoint, m_selectedSeries);
- emitNeedRender();
+ if (newItem) {
+ ChangeRow newItem = {series, candidate};
+ m_changedRows.append(newItem);
}
}
+ if (m_changedRows.size()) {
+ m_changeTracker.rowsChanged = true;
+
+ adjustValueAxisRange();
+ // Clear selection unless still valid
+ setSelectedPoint(m_selectedPoint, m_selectedSeries, false);
+ emitNeedRender();
+ }
}
void Surface3DController::handleItemChanged(int rowIndex, int columnIndex)
{
QSurfaceDataProxy *sender = static_cast<QSurfaceDataProxy *>(QObject::sender());
QSurface3DSeries *series = sender->series();
- if (series->isVisible()) {
- // Change is for the visible series, put the change to queue
- bool newItem = true;
- QPoint candidate(columnIndex, rowIndex);
- foreach (QPoint item, m_changedItems) {
- if (item == candidate) {
- newItem = false;
- break;
- }
- }
- if (newItem) {
- m_changedItems.append(candidate);
- m_changeTracker.itemChanged = true;
- adjustValueAxisRange();
- // Clear selection unless still valid
- setSelectedPoint(m_selectedPoint, m_selectedSeries);
- emitNeedRender();
+ bool newItem = true;
+ QPoint candidate(columnIndex, rowIndex);
+ foreach (ChangeItem item, m_changedItems) {
+ if (item.point == candidate && item.series == series) {
+ newItem = false;
+ break;
}
}
+ if (newItem) {
+ ChangeItem newItem = {series, candidate};
+ m_changedItems.append(newItem);
+ m_changeTracker.itemChanged = true;
+
+ adjustValueAxisRange();
+ // Clear selection unless still valid
+ setSelectedPoint(m_selectedPoint, m_selectedSeries, false);
+ emitNeedRender();
+ }
}
void Surface3DController::handleRowsAdded(int startIndex, int count)
@@ -375,6 +379,8 @@ void Surface3DController::handleRowsAdded(int startIndex, int count)
if (series->isVisible()) {
adjustValueAxisRange();
m_isDataDirty = true;
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
}
emitNeedRender();
}
@@ -389,13 +395,15 @@ void Surface3DController::handleRowsInserted(int startIndex, int count)
int selectedRow = m_selectedPoint.x();
if (startIndex <= selectedRow) {
selectedRow += count;
- setSelectedPoint(QPoint(selectedRow, m_selectedPoint.y()), m_selectedSeries);
+ setSelectedPoint(QPoint(selectedRow, m_selectedPoint.y()), m_selectedSeries, false);
}
}
if (series->isVisible()) {
adjustValueAxisRange();
m_isDataDirty = true;
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
}
emitNeedRender();
@@ -415,13 +423,15 @@ void Surface3DController::handleRowsRemoved(int startIndex, int count)
else
selectedRow -= count; // Move selected row down by amount of rows removed
- setSelectedPoint(QPoint(selectedRow, m_selectedPoint.y()), m_selectedSeries);
+ setSelectedPoint(QPoint(selectedRow, m_selectedPoint.y()), m_selectedSeries, false);
}
}
if (series->isVisible()) {
adjustValueAxisRange();
m_isDataDirty = true;
+ if (!m_changedSeriesList.contains(series))
+ m_changedSeriesList.append(series);
}
emitNeedRender();
@@ -435,6 +445,7 @@ void Surface3DController::adjustValueAxisRange()
bool adjustX = (valueAxisX && valueAxisX->isAutoAdjustRange());
bool adjustY = (valueAxisY && valueAxisY->isAutoAdjustRange());
bool adjustZ = (valueAxisZ && valueAxisZ->isAutoAdjustRange());
+ bool first = true;
if (adjustX || adjustY || adjustZ) {
float minValueX = 0.0f;
@@ -453,7 +464,7 @@ void Surface3DController::adjustValueAxisRange()
QVector3D maxLimits;
proxy->dptrc()->limitValues(minLimits, maxLimits);
if (adjustX) {
- if (!series) {
+ if (first) {
// First series initializes the values
minValueX = minLimits.x();
maxValueX = maxLimits.x();
@@ -463,7 +474,7 @@ void Surface3DController::adjustValueAxisRange()
}
}
if (adjustY) {
- if (!series) {
+ if (first) {
// First series initializes the values
minValueY = minLimits.y();
maxValueY = maxLimits.y();
@@ -473,7 +484,7 @@ void Surface3DController::adjustValueAxisRange()
}
}
if (adjustZ) {
- if (!series) {
+ if (first) {
// First series initializes the values
minValueZ = minLimits.z();
maxValueZ = maxLimits.z();
@@ -482,6 +493,7 @@ void Surface3DController::adjustValueAxisRange()
maxValueZ = qMax(maxValueZ, maxLimits.z());
}
}
+ first = false;
}
}
diff --git a/src/datavisualization/engine/surface3dcontroller_p.h b/src/datavisualization/engine/surface3dcontroller_p.h
index 624bea47..14c0dd40 100644
--- a/src/datavisualization/engine/surface3dcontroller_p.h
+++ b/src/datavisualization/engine/surface3dcontroller_p.h
@@ -58,6 +58,16 @@ class QT_DATAVISUALIZATION_EXPORT Surface3DController : public Abstract3DControl
{
Q_OBJECT
+public:
+ struct ChangeItem {
+ QSurface3DSeries *series;
+ QPoint point;
+ };
+ struct ChangeRow {
+ QSurface3DSeries *series;
+ int row;
+ };
+
private:
Surface3DChangeBitField m_changeTracker;
Surface3DRenderer *m_renderer;
@@ -65,8 +75,9 @@ private:
QSurface3DSeries *m_selectedSeries; // Points to the series for which the point is selected in
// single series selection cases.
bool m_flatShadingSupported;
- QVector<QPoint> m_changedItems;
- QVector<int> m_changedRows;
+ QVector<ChangeItem> m_changedItems;
+ QVector<ChangeRow> m_changedRows;
+ QVector<QSurface3DSeries *> m_changedSeriesList;
public:
explicit Surface3DController(QRect rect, Q3DScene *scene = 0);
@@ -76,9 +87,11 @@ public:
virtual void synchDataToRenderer();
void setSelectionMode(QAbstract3DGraph::SelectionFlags mode);
- void setSelectedPoint(const QPoint &position, QSurface3DSeries *series);
+ void setSelectedPoint(const QPoint &position, QSurface3DSeries *series, bool enterSlice);
virtual void clearSelection();
+ inline QSurface3DSeries *selectedSeries() const { return m_selectedSeries; }
+
virtual void handleAxisAutoAdjustRangeChangedInOrientation(
QAbstract3DAxis::AxisOrientation orientation, bool autoAdjust);
virtual void handleAxisRangeChangedBySender(QObject *sender);
@@ -102,6 +115,9 @@ public slots:
void handleFlatShadingSupportedChange(bool supported);
+signals:
+ void selectedSeriesChanged(QSurface3DSeries *series);
+
private:
void adjustValueAxisRange();
diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp
index 82f9eae1..ffcdeb7a 100644
--- a/src/datavisualization/engine/surface3drenderer.cpp
+++ b/src/datavisualization/engine/surface3drenderer.cpp
@@ -30,11 +30,9 @@
#include "q3dlight.h"
#include "qsurface3dseries_p.h"
-#include <QMatrix4x4>
-#include <QMouseEvent>
-#include <qmath.h>
-
-#include <QDebug>
+#include <QtGui/QMatrix4x4>
+#include <QtGui/QMouseEvent>
+#include <QtCore/qmath.h>
static const int ID_TO_RGBA_MASK = 0xff;
@@ -45,22 +43,17 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
const GLfloat aspectRatio = 2.0f; // Forced ratio of x and z to y. Dynamic will make it look odd.
const GLfloat backgroundMargin = 1.1f; // Margin for background (1.1f = make it 10% larger to avoid items being drawn inside background)
const GLfloat labelMargin = 0.05f;
-const GLfloat backgroundBottom = 1.0f;
const GLfloat gridLineWidth = 0.005f;
const GLfloat sliceZScale = 0.1f;
const GLfloat sliceUnits = 2.5f;
-const int subViewDivider = 5;
-const uint invalidSelectionId = uint(-1);
Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
: Abstract3DRenderer(controller),
- m_labelBackground(false),
- m_font(QFont(QStringLiteral("Arial"))),
- m_isGridEnabled(true),
m_cachedIsSlicingActivated(false),
m_depthShader(0),
m_backgroundShader(0),
- m_surfaceShader(0),
+ m_surfaceFlatShader(0),
+ m_surfaceSmoothShader(0),
m_surfaceGridShader(0),
m_selectionShader(0),
m_labelShader(0),
@@ -70,10 +63,6 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
m_scaleZ(0.0f),
m_scaleXWithBackground(0.0f),
m_scaleZWithBackground(0.0f),
- m_surfaceScaleX(0.0f),
- m_surfaceScaleZ(0.0f),
- m_surfaceOffsetX(0.0f),
- m_surfaceOffsetZ(0.0f),
m_minVisibleColumnValue(0.0f),
m_maxVisibleColumnValue(0.0f),
m_minVisibleRowValue(0.0f),
@@ -83,33 +72,25 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
m_backgroundObj(0),
m_gridLineObj(0),
m_labelObj(0),
- m_surfaceObj(0),
- m_sliceSurfaceObj(0),
m_depthTexture(0),
m_depthModelTexture(0),
m_depthFrameBuffer(0),
m_selectionFrameBuffer(0),
m_selectionDepthBuffer(0),
- m_selectionTexture(0),
m_selectionResultTexture(0),
m_shadowQualityToShader(33.3f),
- m_cachedFlatShading(false),
m_flatSupported(true),
- m_cachedSurfaceVisible(true),
- m_cachedSurfaceGridOn(true),
- m_selectionPointer(0),
m_selectionActive(false),
m_xFlipped(false),
m_zFlipped(false),
m_yFlipped(false),
- m_sampleSpace(QRect(0, 0, 0, 0)),
m_shadowQualityMultiplier(3),
- m_clickedPointId(invalidSelectionId),
m_hasHeightAdjustmentChanged(true),
m_selectedPoint(Surface3DController::invalidSelectionPosition()),
m_selectedSeries(0),
- m_uniformGradientTexture(0),
- m_clickedPosition(Surface3DController::invalidSelectionPosition())
+ m_clickedPosition(Surface3DController::invalidSelectionPosition()),
+ m_selectionTexturesDirty(false),
+ m_noShadowTexture(0)
{
// Check if flat feature is supported
ShaderHelper tester(this, QStringLiteral(":/shaders/vertexSurfaceFlat"),
@@ -125,9 +106,6 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
initializeOpenGLFunctions();
initializeOpenGL();
-
- // Create initial uniform gradient
- generateUniformGradient(m_uniformGradientTextureColor);
}
Surface3DRenderer::~Surface3DRenderer()
@@ -137,34 +115,28 @@ Surface3DRenderer::~Surface3DRenderer()
m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
+ m_textureHelper->deleteTexture(&m_noShadowTexture);
m_textureHelper->deleteTexture(&m_depthTexture);
m_textureHelper->deleteTexture(&m_depthModelTexture);
- m_textureHelper->deleteTexture(&m_selectionTexture);
m_textureHelper->deleteTexture(&m_selectionResultTexture);
- m_textureHelper->deleteTexture(&m_uniformGradientTexture);
}
delete m_depthShader;
delete m_backgroundShader;
delete m_selectionShader;
- delete m_surfaceShader;
+ delete m_surfaceFlatShader;
+ delete m_surfaceSmoothShader;
delete m_surfaceGridShader;
delete m_labelShader;
delete m_backgroundObj;
- delete m_surfaceObj;
- delete m_sliceSurfaceObj;
delete m_gridLineObj;
delete m_labelObj;
- delete m_selectionPointer;
-
- for (int i = 0; i < m_dataArray.size(); i++)
- delete m_dataArray.at(i);
- m_dataArray.clear();
-
- for (int i = 0; i < m_sliceDataArray.size(); i++)
- delete m_sliceDataArray.at(i);
- m_sliceDataArray.clear();
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ cache->cleanup(m_textureHelper);
+ delete cache;
+ }
+ m_renderCacheList.clear();
}
void Surface3DRenderer::initializeOpenGL()
@@ -196,81 +168,65 @@ void Surface3DRenderer::initializeOpenGL()
// Load background mesh (we need to be initialized first)
loadBackgroundMesh();
+
+ // Create texture for no shadows
+ QImage image(2, 2, QImage::Format_RGB32);
+ image.fill(Qt::white);
+ m_noShadowTexture = m_textureHelper->create2DTexture(image, false, true, false, true);
}
void Surface3DRenderer::updateData()
{
- // Surface only supports single series for now, so we are only interested in the first series
- const QSurfaceDataArray *array = 0;
- if (m_visibleSeriesList.size()) {
- QSurface3DSeries *firstSeries = static_cast<QSurface3DSeries *>(m_visibleSeriesList.at(0).series());
- QSurfaceDataProxy *dataProxy = firstSeries->dataProxy();
- if (dataProxy)
- array = dataProxy->array();
- }
-
calculateSceneScalingFactors();
- // Need minimum of 2x2 array to draw a surface
- if (array && array->size() >= 2 && array->at(0)->size() >= 2) {
- QRect sampleSpace = calculateSampleRect(*array);
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ const QSurface3DSeries *currentSeries = cache->series();
+ QSurfaceDataProxy *dataProxy = currentSeries->dataProxy();
+ const QSurfaceDataArray &array = *dataProxy->array();
- bool dimensionChanged = false;
- if (m_sampleSpace != sampleSpace) {
- dimensionChanged = true;
- m_sampleSpace = sampleSpace;
+ // Need minimum of 2x2 array to draw a surface
+ if (array.size() >= 2 && array.at(0)->size() >= 2) {
+ QRect sampleSpace = calculateSampleRect(cache, array);
- for (int i = 0; i < m_dataArray.size(); i++)
- delete m_dataArray.at(i);
- m_dataArray.clear();
- }
+ QSurfaceDataArray &dataArray = cache->dataArray();
+ bool dimensionChanged = false;
+ if (cache->sampleSpace() != sampleSpace) {
+ if (sampleSpace.width() >= 2)
+ m_selectionTexturesDirty = true;
- if (sampleSpace.width() >= 2 && sampleSpace.height() >= 2) {
- if (dimensionChanged) {
- m_dataArray.reserve(sampleSpace.height());
- for (int i = 0; i < sampleSpace.height(); i++)
- m_dataArray << new QSurfaceDataRow(sampleSpace.width());
- }
- 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());
- }
+ dimensionChanged = true;
+ cache->setSampleSpace(sampleSpace);
- if (m_dataArray.size() > 0) {
- if (!m_surfaceObj)
- loadSurfaceObj();
+ for (int i = 0; i < dataArray.size(); i++)
+ delete dataArray.at(i);
+ dataArray.clear();
+ }
- // Note: Data setup can change sample space (as min width/height is 1)
- if (!m_cachedFlatShading) {
- m_surfaceObj->setUpSmoothData(m_dataArray, m_sampleSpace, m_heightNormalizer,
- m_axisCacheY.min(), dimensionChanged);
- } else {
- m_surfaceObj->setUpData(m_dataArray, m_sampleSpace, m_heightNormalizer,
- m_axisCacheY.min(), dimensionChanged);
+ if (sampleSpace.width() >= 2 && sampleSpace.height() >= 2) {
+ if (dimensionChanged) {
+ dataArray.reserve(sampleSpace.height());
+ for (int i = 0; i < sampleSpace.height(); i++)
+ dataArray << new QSurfaceDataRow(sampleSpace.width());
+ }
+ for (int i = 0; i < sampleSpace.height(); i++) {
+ for (int j = 0; j < sampleSpace.width(); j++) {
+ (*(dataArray.at(i)))[j] = array.at(i + sampleSpace.y())->at(
+ j + sampleSpace.x());
+ }
}
- if (dimensionChanged)
- updateSelectionTexture();
+ if (dataArray.size() > 0 && (cache->objectDirty() || dimensionChanged)) {
+ checkFlatSupport(cache);
+ updateObjects(cache, dimensionChanged);
+ cache->setObjectDirty(false);
+ cache->setFlatStatusDirty(false);
+ }
}
}
- } else {
- for (int i = 0; i < m_dataArray.size(); i++)
- delete m_dataArray.at(i);
- m_dataArray.clear();
- m_sampleSpace = QRect();
-
- delete m_surfaceObj;
- m_surfaceObj = 0;
-#if !defined(QT_OPENGL_ES_2)
- m_textureHelper->fillDepthTexture(m_depthTexture, m_primarySubViewport.size(),
- m_shadowQualityMultiplier, 1.0f);
-#endif
}
- for (int i = 0; i < m_sliceDataArray.size(); i++)
- delete m_sliceDataArray.at(i);
- m_sliceDataArray.clear();
+ if (m_selectionTexturesDirty && m_cachedSelectionMode > QAbstract3DGraph::SelectionNone)
+ updateSelectionTextures();
updateSelectedPoint(m_selectedPoint, m_selectedSeries);
}
@@ -278,171 +234,360 @@ void Surface3DRenderer::updateData()
void Surface3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList,
bool updateVisibility)
{
- Abstract3DRenderer::updateSeries(seriesList, updateVisibility);
+ Q_UNUSED(updateVisibility);
- if (m_visibleSeriesList.size()) {
- QSurface3DSeries *series = static_cast<QSurface3DSeries *>(m_visibleSeriesList.at(0).series());
- updateFlatStatus(series->isFlatShadingEnabled());
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList)
+ cache->setValid(false);
- QSurface3DSeries::DrawFlags drawMode = series->drawMode();
- m_cachedSurfaceVisible = drawMode.testFlag(QSurface3DSeries::DrawSurface);
-#if !defined(QT_OPENGL_ES_2)
- if (!m_cachedSurfaceVisible) {
- m_textureHelper->fillDepthTexture(m_depthTexture, m_primarySubViewport.size(),
- m_shadowQualityMultiplier, 1.0f);
+ foreach (QAbstract3DSeries *series, seriesList) {
+ // Item selection label may need update
+ if (series->d_ptr->m_changeTracker.nameChanged
+ || series->d_ptr->m_changeTracker.itemLabelFormatChanged) {
+ m_selectionLabelDirty = true;
}
-#endif
- m_cachedSurfaceGridOn = drawMode.testFlag(QSurface3DSeries::DrawWireframe);
-
- QVector3D seriesColor = Utils::vectorFromColor(series->baseColor());
- if (m_uniformGradientTextureColor != seriesColor)
- generateUniformGradient(seriesColor);
- if (m_selectionPointer) {
- m_selectionPointer->setHighlightColor(
- Utils::vectorFromColor(series->singleHighlightColor()));
- // Make sure selection pointer object reference is still good
- m_selectionPointer->setPointerObject(m_visibleSeriesList.at(0).object());
- m_selectionPointer->setRotation(m_visibleSeriesList.at(0).meshRotation());
+
+ QSurface3DSeries *surfaceSeries = static_cast<QSurface3DSeries *>(series);
+ SurfaceSeriesRenderCache *cache = m_renderCacheList.value(surfaceSeries);
+ if (!cache) {
+ cache = new SurfaceSeriesRenderCache;
+ m_renderCacheList[surfaceSeries] = cache;
+
+ m_selectionTexturesDirty = true;
+ }
+ cache->setValid(true);
+ cache->populate(surfaceSeries, this);
+ if (cache->isFlatStatusDirty() && cache->sampleSpace().width()) {
+ checkFlatSupport(cache);
+ updateObjects(cache, true);
+ cache->setFlatStatusDirty(false);
+ }
+ }
+
+ // Remove non-valid objects from the cache list
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (!cache->isValid()) {
+ if (cache->series() == m_selectedSeries)
+ updateSelectedPoint(Surface3DController::invalidSelectionPosition(), 0);
+
+ m_renderCacheList.remove(cache->series());
+ cache->cleanup(m_textureHelper);
+ delete cache;
+
+ m_selectionTexturesDirty = true;
+ }
+ }
+
+ // Selection pointer issues
+ if (m_selectedSeries) {
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ QVector3D highlightColor =
+ Utils::vectorFromColor(cache->series()->singleHighlightColor());
+ SelectionPointer *slicePointer = cache->sliceSelectionPointer();
+ if (slicePointer) {
+ slicePointer->setHighlightColor(highlightColor);
+ slicePointer->setPointerObject(cache->object());
+ slicePointer->setRotation(cache->meshRotation());
+ }
+ SelectionPointer *mainPointer = cache->mainSelectionPointer();
+ if (mainPointer) {
+ mainPointer->setHighlightColor(highlightColor);
+ mainPointer->setPointerObject(cache->object());
+ mainPointer->setRotation(cache->meshRotation());
+ }
}
}
}
-void Surface3DRenderer::updateRows(const QVector<int> &rows)
+void Surface3DRenderer::modifiedSeriesList(const QVector<QSurface3DSeries *> &seriesList)
{
- // Surface only supports single series for now, so we are only interested in the first series
- const QSurfaceDataArray *array = 0;
- if (m_visibleSeriesList.size()) {
- QSurface3DSeries *firstSeries = static_cast<QSurface3DSeries *>(m_visibleSeriesList.at(0).series());
- QSurfaceDataProxy *dataProxy = firstSeries->dataProxy();
- if (dataProxy)
- array = dataProxy->array();
+ foreach (QSurface3DSeries *series, seriesList) {
+ SurfaceSeriesRenderCache *cache = m_renderCacheList.value(series);
+ if (cache)
+ cache->setObjectDirty(true);
}
+}
+
+void Surface3DRenderer::updateRows(const QVector<Surface3DController::ChangeRow> &rows)
+{
+ foreach (Surface3DController::ChangeRow item, rows) {
+ SurfaceSeriesRenderCache *cache = m_renderCacheList.value(item.series);
+ QSurfaceDataArray &dstArray = cache->dataArray();
+ const QRect &sampleSpace = cache->sampleSpace();
- if (array && array->size() >= 2 && array->at(0)->size() >= 2
- && m_sampleSpace.width() >= 2 && m_sampleSpace.height() >= 2) {
- bool updateBuffers = false;
- int sampleSpaceTop = m_sampleSpace.y() + m_sampleSpace.height();
- foreach (int row, rows) {
- if (row >= m_sampleSpace.y() && row <= sampleSpaceTop) {
+ const QSurfaceDataArray *srcArray = 0;
+ QSurfaceDataProxy *dataProxy = item.series->dataProxy();
+ if (dataProxy)
+ srcArray = dataProxy->array();
+
+ if (cache && srcArray->size() >= 2 && srcArray->at(0)->size() >= 2 &&
+ sampleSpace.width() >= 2 && sampleSpace.height() >= 2) {
+ bool updateBuffers = false;
+ int sampleSpaceTop = sampleSpace.y() + sampleSpace.height();
+ int row = item.row;
+ if (row >= sampleSpace.y() && row <= sampleSpaceTop) {
updateBuffers = true;
- for (int j = 0; j < m_sampleSpace.width(); j++)
- (*(m_dataArray.at(row - m_sampleSpace.y())))[j] =
- array->at(row)->at(j + m_sampleSpace.x());
-
- if (m_cachedFlatShading) {
- m_surfaceObj->updateCoarseRow(m_dataArray, row - m_sampleSpace.y(),
- m_heightNormalizer,
- m_axisCacheY.min());
+ for (int j = 0; j < sampleSpace.width(); j++) {
+ (*(dstArray.at(row - sampleSpace.y())))[j] =
+ srcArray->at(row)->at(j + sampleSpace.x());
+ }
+
+ if (cache->isFlatShadingEnabled()) {
+ cache->surfaceObject()->updateCoarseRow(dstArray, row - sampleSpace.y(),
+ m_heightNormalizer,
+ m_axisCacheY.min());
} else {
- m_surfaceObj->updateSmoothRow(m_dataArray, row - m_sampleSpace.y(),
- m_heightNormalizer,
- m_axisCacheY.min());
+ cache->surfaceObject()->updateSmoothRow(dstArray, row - sampleSpace.y(),
+ m_heightNormalizer,
+ m_axisCacheY.min());
}
}
+ if (updateBuffers)
+ cache->surfaceObject()->uploadBuffers();
}
- if (updateBuffers)
- m_surfaceObj->uploadBuffers();
}
updateSelectedPoint(m_selectedPoint, m_selectedSeries);
}
-void Surface3DRenderer::updateItem(const QVector<QPoint> &points)
+void Surface3DRenderer::updateItem(const QVector<Surface3DController::ChangeItem> &points)
{
- // Surface only supports single series for now, so we are only interested in the first series
- const QSurfaceDataArray *array = 0;
- if (m_visibleSeriesList.size()) {
- QSurface3DSeries *firstSeries = static_cast<QSurface3DSeries *>(m_visibleSeriesList.at(0).series());
- QSurfaceDataProxy *dataProxy = firstSeries->dataProxy();
+ foreach (Surface3DController::ChangeItem item, points) {
+ SurfaceSeriesRenderCache *cache = m_renderCacheList.value(item.series);
+ QSurfaceDataArray &dstArray = cache->dataArray();
+ const QRect &sampleSpace = cache->sampleSpace();
+
+ const QSurfaceDataArray *srcArray = 0;
+ QSurfaceDataProxy *dataProxy = item.series->dataProxy();
if (dataProxy)
- array = dataProxy->array();
- }
+ srcArray = dataProxy->array();
- if (array && array->size() >= 2 && array->at(0)->size() >= 2
- && m_sampleSpace.width() >= 2 && m_sampleSpace.height() >= 2) {
- int sampleSpaceTop = m_sampleSpace.y() + m_sampleSpace.height();
- int sampleSpaceRight = m_sampleSpace.x() + m_sampleSpace.width();
- bool updateBuffers = false;
- foreach (QPoint item, points) {
- if (item.y() <= sampleSpaceTop && item.y() >= m_sampleSpace.y() &&
- item.x() <= sampleSpaceRight && item.x() >= m_sampleSpace.x()) {
+ if (cache && srcArray->size() >= 2 && srcArray->at(0)->size() >= 2 &&
+ sampleSpace.width() >= 2 && sampleSpace.height() >= 2) {
+ int sampleSpaceTop = sampleSpace.y() + sampleSpace.height();
+ int sampleSpaceRight = sampleSpace.x() + sampleSpace.width();
+ bool updateBuffers = false;
+ QPoint point = item.point;
+
+ if (point.y() <= sampleSpaceTop && point.y() >= sampleSpace.y() &&
+ point.x() <= sampleSpaceRight && point.x() >= sampleSpace.x()) {
updateBuffers = true;
- int x = item.x() - m_sampleSpace.x();
- int y = item.y() - m_sampleSpace.y();
- (*(m_dataArray.at(y)))[x] = array->at(item.y())->at(item.x());
+ int x = point.x() - sampleSpace.x();
+ int y = point.y() - sampleSpace.y();
+ (*(dstArray.at(y)))[x] = srcArray->at(point.y())->at(point.x());
- if (m_cachedFlatShading) {
- m_surfaceObj->updateCoarseItem(m_dataArray, y, x, m_heightNormalizer,
- m_axisCacheY.min());
+ if (cache->isFlatShadingEnabled()) {
+ cache->surfaceObject()->updateCoarseItem(dstArray, y, x, m_heightNormalizer,
+ m_axisCacheY.min());
} else {
- m_surfaceObj->updateSmoothItem(m_dataArray, y, x, m_heightNormalizer,
- m_axisCacheY.min());
+ cache->surfaceObject()->updateSmoothItem(dstArray, y, x, m_heightNormalizer,
+ m_axisCacheY.min());
}
}
+ if (updateBuffers)
+ cache->surfaceObject()->uploadBuffers();
}
- if (updateBuffers)
- m_surfaceObj->uploadBuffers();
+
}
updateSelectedPoint(m_selectedPoint, m_selectedSeries);
}
+void Surface3DRenderer::updateAxisRange(QAbstract3DAxis::AxisOrientation orientation, float min,
+ float max)
+{
+ Abstract3DRenderer::updateAxisRange(orientation, min, max);
+
+ if (orientation == QAbstract3DAxis::AxisOrientationY) {
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList)
+ cache->setObjectDirty(true);
+ }
+}
+
void Surface3DRenderer::updateSliceDataModel(const QPoint &point)
{
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList)
+ cache->sliceSurfaceObject()->clear();
+
+ if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionMultiSeries)) {
+ // Find axis coordinates for the selected point
+ SurfaceSeriesRenderCache *selectedCache =
+ m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries));
+ QSurfaceDataArray &dataArray = selectedCache->dataArray();
+ QSurfaceDataItem item = dataArray.at(point.x())->at(point.y());
+ QPointF coords(item.x(), item.z());
+
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (cache->series() != m_selectedSeries) {
+ QPoint mappedPoint = mapCoordsToSampleSpace(cache, coords);
+ updateSliceObject(cache, mappedPoint);
+ } else {
+ updateSliceObject(cache, point);
+ }
+ }
+ } else {
+ if (m_selectedSeries) {
+ SurfaceSeriesRenderCache *cache =
+ m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries));
+ if (cache)
+ updateSliceObject(cache, point);
+ }
+ }
+}
+
+QPoint Surface3DRenderer::mapCoordsToSampleSpace(SurfaceSeriesRenderCache *cache,
+ const QPointF &coords)
+{
+ QPoint point(-1, -1);
+
+ QSurfaceDataArray &dataArray = cache->dataArray();
+ int top = dataArray.size() - 1;
+ int right = dataArray.at(top)->size() - 1;
+ QSurfaceDataItem itemBottomLeft = dataArray.at(0)->at(0);
+ QSurfaceDataItem itemTopRight = dataArray.at(top)->at(right);
+
+ if (itemBottomLeft.x() <= coords.x() && itemTopRight.x() >= coords.x()) {
+ float modelX = coords.x() - itemBottomLeft.x();
+ float spanX = itemTopRight.x() - itemBottomLeft.x();
+ float stepX = spanX / float(right);
+ int sampleX = int((modelX + (stepX / 2.0f)) / stepX);
+
+ QSurfaceDataItem item = dataArray.at(0)->at(sampleX);
+ if (!::qFuzzyCompare(float(coords.x()), item.x())) {
+ int direction = 1;
+ if (item.x() > coords.x())
+ direction = -1;
+
+ findMatchingColumn(coords.x(), sampleX, direction, dataArray);
+ }
+
+ if (sampleX >= 0 && sampleX <= right)
+ point.setY(sampleX);
+ }
+
+ if (itemBottomLeft.z() <= coords.y() && itemTopRight.z() >= coords.y()) {
+ float modelY = coords.y() - itemBottomLeft.z();
+ float spanY = itemTopRight.z() - itemBottomLeft.z();
+ float stepY = spanY / float(top);
+ int sampleY = int((modelY + (stepY / 2.0f)) / stepY);
+
+ QSurfaceDataItem item = dataArray.at(sampleY)->at(0);
+ if (!::qFuzzyCompare(float(coords.y()), item.z())) {
+ int direction = 1;
+ if (item.z() > coords.y())
+ direction = -1;
+
+ findMatchingRow(coords.y(), sampleY, direction, dataArray);
+ }
+
+ if (sampleY >= 0 && sampleY <= top)
+ point.setX(sampleY);
+ }
+
+ return point;
+}
+
+void Surface3DRenderer::findMatchingRow(float z, int &sample, int direction,
+ QSurfaceDataArray &dataArray)
+{
+ int maxZ = dataArray.size() - 1;
+ QSurfaceDataItem item = dataArray.at(sample)->at(0);
+ float distance = qAbs(z - item.z());
+ int newSample = sample + direction;
+ while (newSample >= 0 && newSample <= maxZ) {
+ item = dataArray.at(newSample)->at(0);
+ float newDist = qAbs(z - item.z());
+ if (newDist < distance) {
+ sample = newSample;
+ distance = newDist;
+ } else {
+ break;
+ }
+ newSample = sample + direction;
+ }
+}
+
+void Surface3DRenderer::findMatchingColumn(float x, int &sample, int direction,
+ QSurfaceDataArray &dataArray)
+{
+ int maxX = dataArray.at(0)->size() - 1;
+ QSurfaceDataItem item = dataArray.at(0)->at(sample);
+ float distance = qAbs(x - item.x());
+ int newSample = sample + direction;
+ while (newSample >= 0 && newSample <= maxX) {
+ item = dataArray.at(0)->at(newSample);
+ float newDist = qAbs(x - item.x());
+ if (newDist < distance) {
+ sample = newSample;
+ distance = newDist;
+ } else {
+ break;
+ }
+ newSample = sample + direction;
+ }
+}
+
+void Surface3DRenderer::updateSliceObject(SurfaceSeriesRenderCache *cache, const QPoint &point)
+{
int column = point.y();
int row = point.x();
- for (int i = 0; i < m_sliceDataArray.size(); i++)
- delete m_sliceDataArray.at(i);
- m_sliceDataArray.clear();
+ if ((m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow) && row == -1) ||
+ (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionColumn) && column == -1)) {
+ cache->sliceSurfaceObject()->clear();
+ return;
+ }
- m_sliceDataArray.reserve(2);
- QSurfaceDataRow *sliceRow;
+ QSurfaceDataArray &sliceDataArray = cache->sliceDataArray();
+ for (int i = 0; i < sliceDataArray.size(); i++)
+ delete sliceDataArray.at(i);
+ sliceDataArray.clear();
+ sliceDataArray.reserve(2);
+ QSurfaceDataRow *sliceRow;
+ QSurfaceDataArray &dataArray = cache->dataArray();
float adjust = (0.025f * m_heightNormalizer) / 2.0f;
float stepDown = 2.0f * adjust;
if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow)) {
- QSurfaceDataRow *src = m_dataArray.at(row);
+ QSurfaceDataRow *src = dataArray.at(row);
sliceRow = new QSurfaceDataRow(src->size());
for (int i = 0; i < sliceRow->size(); i++)
(*sliceRow)[i].setPosition(QVector3D(src->at(i).x(), src->at(i).y() + adjust, -1.0f));
} else {
- sliceRow = new QSurfaceDataRow(m_sampleSpace.height());
- for (int i = 0; i < m_sampleSpace.height(); i++) {
- (*sliceRow)[i].setPosition(QVector3D(m_dataArray.at(i)->at(column).z(),
- m_dataArray.at(i)->at(column).y() + adjust,
+ const QRect &sampleSpace = cache->sampleSpace();
+ sliceRow = new QSurfaceDataRow(sampleSpace.height());
+ for (int i = 0; i < sampleSpace.height(); i++) {
+ (*sliceRow)[i].setPosition(QVector3D(dataArray.at(i)->at(column).z(),
+ dataArray.at(i)->at(column).y() + adjust,
-1.0f));
}
}
-
- m_sliceDataArray << sliceRow;
+ sliceDataArray << sliceRow;
// Make a duplicate, so that we get a little bit depth
QSurfaceDataRow *duplicateRow = new QSurfaceDataRow(*sliceRow);
for (int i = 0; i < sliceRow->size(); i++) {
- (*sliceRow)[i].setPosition(QVector3D(sliceRow->at(i).x(), sliceRow->at(i).y() - stepDown,
+ (*sliceRow)[i].setPosition(QVector3D(sliceRow->at(i).x(),
+ sliceRow->at(i).y() - stepDown,
1.0f));
}
-
- m_sliceDataArray << duplicateRow;
+ sliceDataArray << duplicateRow;
QRect sliceRect(0, 0, sliceRow->size(), 2);
-
if (sliceRow->size() > 0) {
- if (!m_sliceSurfaceObj)
- loadSliceSurfaceObj();
-
- if (!m_cachedFlatShading) {
- m_sliceSurfaceObj->setUpSmoothData(m_sliceDataArray, sliceRect, m_heightNormalizer,
- m_axisCacheY.min(), true);
+ if (cache->isFlatShadingEnabled()) {
+ cache->sliceSurfaceObject()->setUpData(sliceDataArray, sliceRect,
+ m_heightNormalizer,
+ m_axisCacheY.min(), true);
} else {
- m_sliceSurfaceObj->setUpData(m_sliceDataArray, sliceRect, m_heightNormalizer,
- m_axisCacheY.min(), true);
+ cache->sliceSurfaceObject()->setUpSmoothData(sliceDataArray, sliceRect,
+ m_heightNormalizer,
+ m_axisCacheY.min(), true);
}
}
}
-QRect Surface3DRenderer::calculateSampleRect(const QSurfaceDataArray &array)
+QRect Surface3DRenderer::calculateSampleRect(SurfaceSeriesRenderCache *cache,
+ const QSurfaceDataArray &array)
{
QRect sampleSpace;
@@ -518,14 +663,17 @@ QRect Surface3DRenderer::calculateSampleRect(const QSurfaceDataArray &array)
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 surfaceScaleX = m_scaleX * m_visibleColumnRange / m_areaSize.width();
+ GLfloat 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();
+ GLfloat surfaceOffsetX = m_scaleX * (data2XCenterX - axis2XCenterX) / m_areaSize.width();
+ GLfloat surfaceOffsetZ = -m_scaleZ * (data2XCenterZ - axis2XCenterZ) / m_areaSize.height();
+
+ cache->setScale(QVector3D(surfaceScaleX, 1.0f, surfaceScaleZ));
+ cache->setOffset(QVector3D(surfaceOffsetX, 0.0f, surfaceOffsetZ));
return sampleSpace;
}
@@ -535,14 +683,15 @@ void Surface3DRenderer::updateScene(Q3DScene *scene)
// Set initial camera position
// X must be 0 for rotation to work - we can use "setCameraRotation" for setting it later
if (m_hasHeightAdjustmentChanged) {
- scene->activeCamera()->setBaseOrientation(cameraDistanceVector, zeroVector, upVector);
+ scene->activeCamera()->d_ptr->setBaseOrientation(cameraDistanceVector, zeroVector,
+ upVector);
// For now this is used just to make things once. Proper use will come
m_hasHeightAdjustmentChanged = false;
}
Abstract3DRenderer::updateScene(scene);
- if (m_selectionPointer && m_selectionActive
+ if (m_selectionActive
&& m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionItem)) {
m_selectionDirty = true; // Ball may need repositioning if scene changes
}
@@ -560,9 +709,16 @@ void Surface3DRenderer::render(GLuint defaultFboHandle)
drawSlicedScene();
// Render selection ball
- if (m_selectionPointer && m_selectionActive
+ if (m_selectionActive
&& m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionItem)) {
- m_selectionPointer->render(defaultFboHandle);
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (cache->slicePointerActive() && cache->renderable() &&
+ m_cachedIsSlicingActivated ) {
+ cache->sliceSelectionPointer()->render(defaultFboHandle);
+ }
+ if (cache->mainPointerActive() && cache->renderable())
+ cache->mainSelectionPointer()->render(defaultFboHandle);
+ }
}
}
@@ -583,8 +739,10 @@ void Surface3DRenderer::drawSlicedScene()
GLfloat aspect = (GLfloat)m_secondarySubViewport.width()
/ (GLfloat)m_secondarySubViewport.height();
- projectionMatrix.ortho(-sliceUnits * aspect, sliceUnits * aspect,
- -sliceUnits, sliceUnits, -1.0f, 4.0f);
+ GLfloat sliceUnitsScaled = sliceUnits / m_autoScaleAdjustment;
+ projectionMatrix.ortho(-sliceUnitsScaled * aspect, sliceUnitsScaled * aspect,
+ -sliceUnitsScaled, sliceUnitsScaled,
+ -1.0f, 4.0f);
// Set view matrix
QMatrix4x4 viewMatrix;
@@ -595,72 +753,85 @@ void Surface3DRenderer::drawSlicedScene()
QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix;
+ const Q3DCamera *activeCamera = m_cachedScene->activeCamera();
+
bool rowMode = m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow);
- GLfloat scaleX = 0.0f;
GLfloat scaleXBackground = 0.0f;
- GLfloat offset = 0.0f;
- if (rowMode) {
- scaleX = m_surfaceScaleX;
- scaleXBackground = m_scaleXWithBackground;
- offset = m_surfaceOffsetX;
- } else {
- scaleX = m_surfaceScaleZ;
- scaleXBackground = m_scaleZWithBackground;
- offset = -m_surfaceOffsetZ;
- }
- if (m_surfaceObj) {
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 modelMatrix;
- QMatrix4x4 itModelMatrix;
+ if (m_renderCacheList.size()) {
+ bool drawGrid = false;
- const SeriesRenderCache &series = m_visibleSeriesList.at(0);
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (cache->sliceSurfaceObject()->indexCount() && cache->renderable()) {
+ if (!drawGrid && cache->surfaceGridVisible()) {
+ glEnable(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(0.5f, 1.0f);
+ drawGrid = true;
+ }
- modelMatrix.translate(offset, 0.0f, 0.0f);
- QVector3D scaling(scaleX, 1.0f, sliceZScale);
- modelMatrix.scale(scaling);
- itModelMatrix.scale(scaling);
+ GLfloat scaleX = 0.0f;
+ GLfloat offset = 0.0f;
+ if (rowMode) {
+ scaleX = cache->scale().x();
+ scaleXBackground = m_scaleXWithBackground;
+ offset = cache->offset().x();
+ } else {
+ scaleX = cache->scale().z();
+ scaleXBackground = m_scaleZWithBackground;
+ offset = -cache->offset().z();
+ }
- MVPMatrix = projectionViewMatrix * modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 itModelMatrix;
- if (m_cachedSurfaceVisible) {
- if (m_cachedSurfaceGridOn) {
- glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(0.5f, 1.0f);
- }
+ modelMatrix.translate(offset, 0.0f, 0.0f);
+ QVector3D scaling(scaleX, 1.0f, sliceZScale);
+ modelMatrix.scale(scaling);
+ itModelMatrix.scale(scaling);
- ShaderHelper *surfaceShader = m_surfaceShader;
- surfaceShader->bind();
-
- GLuint baseGradientTexture = m_uniformGradientTexture;
- if (series.colorStyle() != Q3DTheme::ColorStyleUniform)
- baseGradientTexture = series.baseGradientTexture();
-
- // Set shader bindings
- surfaceShader->setUniformValue(surfaceShader->lightP(), lightPos);
- surfaceShader->setUniformValue(surfaceShader->view(), viewMatrix);
- surfaceShader->setUniformValue(surfaceShader->model(), modelMatrix);
- surfaceShader->setUniformValue(surfaceShader->nModel(),
- itModelMatrix.inverted().transposed());
- surfaceShader->setUniformValue(surfaceShader->MVP(), MVPMatrix);
- surfaceShader->setUniformValue(surfaceShader->lightS(), 0.15f);
- surfaceShader->setUniformValue(surfaceShader->ambientS(),
- m_cachedTheme->ambientLightStrength() * 2.3f);
- surfaceShader->setUniformValue(surfaceShader->lightColor(), lightColor);
-
- m_drawer->drawObject(surfaceShader, m_sliceSurfaceObj, baseGradientTexture);
+ MVPMatrix = projectionViewMatrix * modelMatrix;
+ cache->setMVPMatrix(MVPMatrix);
+
+ if (cache->surfaceVisible()) {
+ ShaderHelper *surfaceShader = m_surfaceFlatShader;
+ surfaceShader->bind();
+
+ GLuint colorTexture = cache->baseUniformTexture();;
+ if (cache->colorStyle() != Q3DTheme::ColorStyleUniform)
+ colorTexture = cache->baseGradientTexture();
+
+ // Set shader bindings
+ surfaceShader->setUniformValue(surfaceShader->lightP(), lightPos);
+ surfaceShader->setUniformValue(surfaceShader->view(), viewMatrix);
+ surfaceShader->setUniformValue(surfaceShader->model(), modelMatrix);
+ surfaceShader->setUniformValue(surfaceShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ surfaceShader->setUniformValue(surfaceShader->MVP(), MVPMatrix);
+ surfaceShader->setUniformValue(surfaceShader->lightS(), 0.15f);
+ surfaceShader->setUniformValue(surfaceShader->ambientS(),
+ m_cachedTheme->ambientLightStrength() * 2.3f);
+ surfaceShader->setUniformValue(surfaceShader->lightColor(), lightColor);
+
+ m_drawer->drawObject(surfaceShader, cache->sliceSurfaceObject(), colorTexture);
+ }
+ }
}
// Draw surface grid
- if (m_cachedSurfaceGridOn) {
+ if (drawGrid) {
+ glDisable(GL_POLYGON_OFFSET_FILL);
m_surfaceGridShader->bind();
m_surfaceGridShader->setUniformValue(m_surfaceGridShader->color(),
Utils::vectorFromColor(m_cachedTheme->gridLineColor()));
- m_surfaceGridShader->setUniformValue(m_surfaceGridShader->MVP(), MVPMatrix);
- m_drawer->drawSurfaceGrid(m_surfaceGridShader, m_sliceSurfaceObj);
-
- glDisable(GL_POLYGON_OFFSET_FILL);
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (cache->sliceSurfaceObject()->indexCount() && cache->isSeriesVisible() &&
+ cache->surfaceGridVisible()) {
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->MVP(), cache->MVPMatrix());
+ m_drawer->drawSurfaceGrid(m_surfaceGridShader, cache->sliceSurfaceObject());
+ }
+ }
}
}
@@ -756,7 +927,7 @@ void Surface3DRenderer::drawSlicedScene()
}
}
- // Draw axis labels
+ // Draw labels
m_labelShader->bind();
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
@@ -781,7 +952,7 @@ void Surface3DRenderer::drawSlicedScene()
m_dummyRenderItem.setTranslation(labelTrans);
m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
positionComp, rotation, 0, m_cachedSelectionMode, m_labelShader,
- m_labelObj, m_cachedScene->activeCamera(),
+ m_labelObj, activeCamera,
true, true, Drawer::LabelMid, Qt::AlignRight, true);
}
labelNbr++;
@@ -822,13 +993,35 @@ void Surface3DRenderer::drawSlicedScene()
m_drawer->drawLabel(m_dummyRenderItem, *axisLabelItem, viewMatrix, projectionMatrix,
positionComp, rotation, 0, QAbstract3DGraph::SelectionRow,
- m_labelShader, m_labelObj, m_cachedScene->activeCamera(),
+ m_labelShader, m_labelObj, activeCamera,
false, false, Drawer::LabelBelow, Qt::AlignBottom, true);
}
labelNbr++;
labelPos += posStep;
}
+ // Draw labels for axes
+ AbstractRenderItem *dummyItem(0);
+ positionComp.setY(m_autoScaleAdjustment);
+ if (rowMode) {
+ m_drawer->drawLabel(*dummyItem, m_axisCacheX.titleItem(), viewMatrix, projectionMatrix,
+ positionComp, zeroVector, 0, m_cachedSelectionMode, m_labelShader,
+ m_labelObj, activeCamera, false, false, Drawer::LabelBottom,
+ Qt::AlignCenter, true);
+ } else {
+ m_drawer->drawLabel(*dummyItem, m_axisCacheZ.titleItem(), viewMatrix, projectionMatrix,
+ positionComp, zeroVector, 0, m_cachedSelectionMode, m_labelShader,
+ m_labelObj, activeCamera, false, false, Drawer::LabelBottom,
+ Qt::AlignCenter, true);
+ }
+ // Y-axis label
+ labelTrans = QVector3D(-scaleXBackground - labelMargin, 0.0f, 0.0f);
+ m_dummyRenderItem.setTranslation(labelTrans);
+ m_drawer->drawLabel(m_dummyRenderItem, m_axisCacheY.titleItem(), viewMatrix,
+ projectionMatrix, zeroVector, QVector3D(0.0f, 0.0f, 90.0f), 0,
+ m_cachedSelectionMode, m_labelShader, m_labelObj, activeCamera,
+ false, false, Drawer::LabelMid, Qt::AlignHCenter);
+
glDisable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
@@ -839,6 +1032,8 @@ void Surface3DRenderer::drawSlicedScene()
void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
{
+ bool noShadows = true;
+
GLfloat backgroundRotation = 0;
QVector3D lightColor = Utils::vectorFromColor(m_cachedTheme->lightColor());
@@ -847,15 +1042,15 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
m_primarySubViewport.width(),
m_primarySubViewport.height());
- // Specify viewport
-
// Set up projection matrix
QMatrix4x4 projectionMatrix;
projectionMatrix.perspective(45.0f, (GLfloat)m_primarySubViewport.width()
/ (GLfloat)m_primarySubViewport.height(), 0.1f, 100.0f);
+ const Q3DCamera *activeCamera = m_cachedScene->activeCamera();
+
// Calculate view matrix
- QMatrix4x4 viewMatrix = m_cachedScene->activeCamera()->viewMatrix();
+ QMatrix4x4 viewMatrix = activeCamera->d_ptr->viewMatrix();
QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix;
@@ -885,14 +1080,10 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
QMatrix4x4 depthProjectionMatrix;
QMatrix4x4 depthProjectionViewMatrix;
- QVector3D surfaceScaler(m_surfaceScaleX, 1.0f, m_surfaceScaleZ);
- QVector3D surfaceOffset(m_surfaceOffsetX, 0.0f, m_surfaceOffsetZ);
-
// Draw depth buffer
#if !defined(QT_OPENGL_ES_2)
GLfloat adjustedLightStrength = m_cachedTheme->lightStrength() / 10.0f;
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone && m_surfaceObj
- && m_cachedSurfaceVisible) {
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone && m_renderCacheList.size()) {
// Render scene into a depth texture for using with shadow mapping
// Enable drawing to depth framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, m_depthFrameBuffer);
@@ -912,47 +1103,44 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
// Get the depth view matrix
// It may be possible to hack lightPos here if we want to make some tweaks to shadow
- QVector3D depthLightPos = m_cachedScene->activeCamera()->calculatePositionRelativeToCamera(
- zeroVector, 0.0f, 3.5f / m_autoScaleAdjustment);
+ QVector3D depthLightPos = activeCamera->d_ptr->calculatePositionRelativeToCamera(
+ zeroVector, 0.0f, 4.0f / m_autoScaleAdjustment);
depthViewMatrix.lookAt(depthLightPos, zeroVector, upVector);
// Set the depth projection matrix
-#ifndef USE_WIDER_SHADOWS
- // Use this for perspective shadows
depthProjectionMatrix.perspective(10.0f, (GLfloat)m_primarySubViewport.width()
/ (GLfloat)m_primarySubViewport.height(), 3.0f, 100.0f);
-#else
- // Use these for orthographic shadows
- depthProjectionMatrix.ortho(-2.0f * 2.0f, 2.0f * 2.0f,
- -2.0f, 2.0f,
- 0.0f, 100.0f);
-#endif
depthProjectionViewMatrix = depthProjectionMatrix * depthViewMatrix;
glDisable(GL_CULL_FACE);
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
-
- modelMatrix.translate(surfaceOffset);
- modelMatrix.scale(surfaceScaler);
-
- MVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ SurfaceObject *object = cache->surfaceObject();
+ if (object->indexCount() && cache->surfaceVisible() && cache->isSeriesVisible()
+ && cache->sampleSpace().width() >= 2 && cache->sampleSpace().height() >= 2) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
- m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix);
+ modelMatrix.translate(cache->offset());
+ modelMatrix.scale(cache->scale());
+ MVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ cache->setMVPMatrix(MVPMatrix);
+ m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix);
- // 1st attribute buffer : vertices
- glEnableVertexAttribArray(m_depthShader->posAtt());
- glBindBuffer(GL_ARRAY_BUFFER, m_surfaceObj->vertexBuf());
- glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0,
- (void *)0);
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_depthShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, object->vertexBuf());
+ glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0,
+ (void *)0);
- // Index buffer
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_surfaceObj->elementBuf());
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object->elementBuf());
- // Draw the triangles
- glDrawElements(GL_TRIANGLES, m_surfaceObj->indexCount(), m_surfaceObj->indicesType(),
- (void *)0);
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, object->indexCount(),
+ object->indicesType(), (void *)0);
+ }
+ }
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
@@ -961,9 +1149,26 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
m_depthModelTexture, 0);
glClear(GL_DEPTH_BUFFER_BIT);
- // Draw the triangles
- glDrawElements(GL_TRIANGLES, m_surfaceObj->indexCount(), m_surfaceObj->indicesType(),
- (void *)0);
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ SurfaceObject *object = cache->surfaceObject();
+ if (object->indexCount() && cache->surfaceVisible() && cache->isSeriesVisible()
+ && cache->sampleSpace().width() >= 2 && cache->sampleSpace().height() >= 2) {
+ m_depthShader->setUniformValue(m_depthShader->MVP(), cache->MVPMatrix());
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_depthShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, object->vertexBuf());
+ glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0,
+ (void *)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object->elementBuf());
+
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, object->indexCount(),
+ object->indicesType(), (void *)0);
+ }
+ }
// Free buffers
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@@ -989,10 +1194,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
glEnable(GL_TEXTURE_2D);
// Draw selection buffer
- if (!m_cachedIsSlicingActivated && m_surfaceObj && m_selectionState == SelectOnScene
- && m_cachedSelectionMode > QAbstract3DGraph::SelectionNone
- && (m_cachedSurfaceVisible || m_cachedSurfaceGridOn)
- && m_visibleSeriesList.size() > 0) {
+ if (!m_cachedIsSlicingActivated && m_renderCacheList.size() && m_selectionState == SelectOnScene
+ && m_cachedSelectionMode > QAbstract3DGraph::SelectionNone) {
m_selectionShader->bind();
glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer);
glViewport(0,
@@ -1007,17 +1210,21 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
glDisable(GL_CULL_FACE);
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
-
- modelMatrix.translate(surfaceOffset);
- modelMatrix.scale(surfaceScaler);
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (cache->surfaceObject()->indexCount() && cache->renderable()) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
- MVPMatrix = projectionViewMatrix * modelMatrix;
+ modelMatrix.translate(cache->offset());
+ modelMatrix.scale(cache->scale());
- m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix);
+ MVPMatrix = projectionViewMatrix * modelMatrix;
+ m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix);
- m_drawer->drawObject(m_selectionShader, m_surfaceObj, m_selectionTexture);
+ m_drawer->drawObject(m_selectionShader, cache->surfaceObject(),
+ cache->selectionTexture());
+ }
+ }
glEnable(GL_DITHER);
@@ -1035,7 +1242,6 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
#endif
m_clickedPosition = selectionIdToSurfacePoint(selectionId);
- m_clickedSeries = m_visibleSeriesList.at(0).series();
emit needRender();
@@ -1047,81 +1253,102 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
}
// Draw the surface
- if (m_surfaceObj && m_sampleSpace.width() >= 2 && m_sampleSpace.height() >= 2) {
- m_surfaceShader->bind();
+ if (m_renderCacheList.size()) {
// For surface we can see climpses from underneath
glDisable(GL_CULL_FACE);
- if (m_cachedSurfaceGridOn) {
- glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(0.5f, 1.0f);
- }
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 itModelMatrix;
+ bool drawGrid = false;
+
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 itModelMatrix;
- modelMatrix.translate(surfaceOffset);
- modelMatrix.scale(surfaceScaler);
- itModelMatrix.scale(surfaceScaler);
+ modelMatrix.translate(cache->offset());
+ modelMatrix.scale(cache->scale());
+ itModelMatrix.scale(cache->scale());
#ifdef SHOW_DEPTH_TEXTURE_SCENE
- MVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ MVPMatrix = depthProjectionViewMatrix * modelMatrix;
#else
- MVPMatrix = projectionViewMatrix * modelMatrix;
+ MVPMatrix = projectionViewMatrix * modelMatrix;
#endif
+ cache->setMVPMatrix(MVPMatrix);
+
+ const QRect &sampleSpace = cache->sampleSpace();
+ if (cache->surfaceObject()->indexCount() && cache->isSeriesVisible() &&
+ sampleSpace.width() >= 2 && sampleSpace.height() >= 2) {
+ noShadows = false;
+ if (!drawGrid && cache->surfaceGridVisible()) {
+ glEnable(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(0.5f, 1.0f);
+ drawGrid = true;
+ }
- if (m_cachedSurfaceVisible) {
- // Set shader bindings
- m_surfaceShader->setUniformValue(m_surfaceShader->lightP(), lightPos);
- m_surfaceShader->setUniformValue(m_surfaceShader->view(), viewMatrix);
- m_surfaceShader->setUniformValue(m_surfaceShader->model(), modelMatrix);
- m_surfaceShader->setUniformValue(m_surfaceShader->nModel(),
- itModelMatrix.inverted().transposed());
- m_surfaceShader->setUniformValue(m_surfaceShader->MVP(), MVPMatrix);
- m_surfaceShader->setUniformValue(m_surfaceShader->ambientS(),
- m_cachedTheme->ambientLightStrength());
- m_surfaceShader->setUniformValue(m_surfaceShader->lightColor(), lightColor);
-
- GLuint gradientTexture;
- if (m_visibleSeriesList.at(0).colorStyle() == Q3DTheme::ColorStyleUniform)
- gradientTexture = m_uniformGradientTexture;
- else
- gradientTexture = m_visibleSeriesList.at(0).baseGradientTexture();
+ if (cache->surfaceVisible()) {
+ ShaderHelper *shader = m_surfaceFlatShader;
+ if (!cache->isFlatShadingEnabled())
+ shader = m_surfaceSmoothShader;
+ shader->bind();
+
+ // Set shader bindings
+ shader->setUniformValue(shader->lightP(), lightPos);
+ shader->setUniformValue(shader->view(), viewMatrix);
+ shader->setUniformValue(shader->model(), modelMatrix);
+ shader->setUniformValue(shader->nModel(),
+ itModelMatrix.inverted().transposed());
+ shader->setUniformValue(shader->MVP(), MVPMatrix);
+ shader->setUniformValue(shader->ambientS(),
+ m_cachedTheme->ambientLightStrength());
+ shader->setUniformValue(shader->lightColor(), lightColor);
-#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
- // Set shadow shader bindings
- QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
- m_surfaceShader->setUniformValue(m_surfaceShader->shadowQ(),
- m_shadowQualityToShader);
- m_surfaceShader->setUniformValue(m_surfaceShader->depth(), depthMVPMatrix);
- m_surfaceShader->setUniformValue(m_surfaceShader->lightS(), adjustedLightStrength);
+ GLuint gradientTexture;
+ if (cache->colorStyle() == Q3DTheme::ColorStyleUniform)
+ gradientTexture = cache->baseUniformTexture();
+ else
+ gradientTexture = cache->baseGradientTexture();
- // Draw the object
- m_drawer->drawObject(m_surfaceShader, m_surfaceObj, gradientTexture,
- m_depthModelTexture);
- } else
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ // Set shadow shader bindings
+ QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ shader->setUniformValue(shader->shadowQ(), m_shadowQualityToShader);
+ shader->setUniformValue(shader->depth(), depthMVPMatrix);
+ shader->setUniformValue(shader->lightS(), adjustedLightStrength);
+
+ // Draw the objects
+ m_drawer->drawObject(shader, cache->surfaceObject(), gradientTexture,
+ m_depthModelTexture);
+ } else
#endif
- {
- // Set shadowless shader bindings
- m_surfaceShader->setUniformValue(m_surfaceShader->lightS(),
- m_cachedTheme->lightStrength());
+ {
+ // Set shadowless shader bindings
+ shader->setUniformValue(shader->lightS(),
+ m_cachedTheme->lightStrength());
- // Draw the object
- m_drawer->drawObject(m_surfaceShader, m_surfaceObj, gradientTexture);
+ // Draw the objects
+ m_drawer->drawObject(shader, cache->surfaceObject(), gradientTexture);
+ }
+ }
}
- glEnable(GL_CULL_FACE);
}
+ glEnable(GL_CULL_FACE);
// Draw surface grid
- if (m_cachedSurfaceGridOn) {
+ if (drawGrid) {
+ glDisable(GL_POLYGON_OFFSET_FILL);
m_surfaceGridShader->bind();
m_surfaceGridShader->setUniformValue(m_surfaceGridShader->color(),
Utils::vectorFromColor(m_cachedTheme->gridLineColor()));
- m_surfaceGridShader->setUniformValue(m_surfaceGridShader->MVP(), MVPMatrix);
- m_drawer->drawSurfaceGrid(m_surfaceGridShader, m_surfaceObj);
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->MVP(), cache->MVPMatrix());
- glDisable(GL_POLYGON_OFFSET_FILL);
+ const QRect &sampleSpace = cache->sampleSpace();
+ if (cache->surfaceObject()->indexCount() && cache->surfaceGridVisible() &&
+ cache->isSeriesVisible() && sampleSpace.width() >= 2 && sampleSpace.height() >= 2) {
+ m_drawer->drawSurfaceGrid(m_surfaceGridShader, cache->surfaceObject());
+ }
+ }
}
}
@@ -1177,10 +1404,14 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
m_backgroundShader->setUniformValue(m_backgroundShader->depth(), depthMVPMatrix);
m_backgroundShader->setUniformValue(m_backgroundShader->lightS(),
adjustedLightStrength);
-
// Draw the object
- m_drawer->drawObject(m_backgroundShader, m_backgroundObj, 0, m_depthTexture);
+ if (noShadows)
+ m_drawer->drawObject(m_backgroundShader, m_backgroundObj, 0, m_noShadowTexture);
+ else
+ m_drawer->drawObject(m_backgroundShader, m_backgroundObj, 0, m_depthTexture);
} else
+#else
+ Q_UNUSED(noShadows);
#endif
{
// Set shadowless shader bindings
@@ -1565,7 +1796,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
positionZComp, rotation, 0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, m_cachedScene->activeCamera(),
+ m_labelShader, m_labelObj, activeCamera,
true, true, Drawer::LabelMid, alignment);
}
labelNbr++;
@@ -1611,7 +1842,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
positionZComp, rotation, 0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, m_cachedScene->activeCamera(),
+ m_labelShader, m_labelObj, activeCamera,
true, true, Drawer::LabelMid, alignment);
}
labelNbr++;
@@ -1671,7 +1902,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
m_dummyRenderItem.setTranslation(labelTransBack);
m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
positionZComp, labelRotateVectorBack, 0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, m_cachedScene->activeCamera(),
+ m_labelShader, m_labelObj, activeCamera,
true, true, Drawer::LabelMid, alignmentBack);
// Side wall
@@ -1679,7 +1910,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
m_dummyRenderItem.setTranslation(labelTransSide);
m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
positionZComp, labelRotateVectorSide, 0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, m_cachedScene->activeCamera(),
+ m_labelShader, m_labelObj, activeCamera,
true, true, Drawer::LabelMid, alignmentSide);
}
labelNbr++;
@@ -1697,12 +1928,17 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
// Selection handling
if (m_selectionDirty || m_selectionLabelDirty) {
QPoint visiblePoint = Surface3DController::invalidSelectionPosition();
- if (m_selectedPoint != Surface3DController::invalidSelectionPosition()) {
- int x = m_selectedPoint.x() - m_sampleSpace.y();
- int y = m_selectedPoint.y() - m_sampleSpace.x();
- if (x >= 0 && y >= 0 && x < m_sampleSpace.height() && y < m_sampleSpace.width()
- && m_dataArray.size()) {
- visiblePoint = QPoint(x, y);
+ if (m_selectedSeries) {
+ SurfaceSeriesRenderCache *cache =
+ m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries));
+ if (cache && m_selectedPoint != Surface3DController::invalidSelectionPosition()) {
+ const QRect &sampleSpace = cache->sampleSpace();
+ int x = m_selectedPoint.x() - sampleSpace.y();
+ int y = m_selectedPoint.y() - sampleSpace.x();
+ if (x >= 0 && y >= 0 && x < sampleSpace.height() && y < sampleSpace.width()
+ && cache->dataArray().size()) {
+ visiblePoint = QPoint(x, y);
+ }
}
}
@@ -1721,47 +1957,65 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
}
}
-// This one needs to be called when the data size changes
-void Surface3DRenderer::updateSelectionTexture()
+void Surface3DRenderer::updateSelectionMode(QAbstract3DGraph::SelectionFlags mode)
+{
+ Abstract3DRenderer::updateSelectionMode(mode);
+
+ if (m_cachedSelectionMode > QAbstract3DGraph::SelectionNone)
+ updateSelectionTextures();
+}
+
+void Surface3DRenderer::updateSelectionTextures()
+{
+ uint lastSelectionId = 1;
+
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ GLuint texture = cache->selectionTexture();
+ m_textureHelper->deleteTexture(&texture);
+ createSelectionTexture(cache, lastSelectionId);
+ }
+ m_selectionTexturesDirty = false;
+}
+
+void Surface3DRenderer::createSelectionTexture(SurfaceSeriesRenderCache *cache,
+ uint &lastSelectionId)
{
// Create the selection ID image. Each grid corner gets 2x2 pixel area of
// ID color so that each vertex (data point) has 4x4 pixel area of ID color
- int idImageWidth = (m_sampleSpace.width() - 1) * 4;
- int idImageHeight = (m_sampleSpace.height() - 1) * 4;
+ const QRect &sampleSpace = cache->sampleSpace();
+ int idImageWidth = (sampleSpace.width() - 1) * 4;
+ int idImageHeight = (sampleSpace.height() - 1) * 4;
int stride = idImageWidth * 4 * sizeof(uchar); // 4 = number of color components (rgba)
+ uint idStart = lastSelectionId;
uchar *bits = new uchar[idImageWidth * idImageHeight * 4 * sizeof(uchar)];
- uint id = 1;
for (int i = 0; i < idImageHeight; i += 4) {
for (int j = 0; j < idImageWidth; j += 4) {
int p = (i * idImageWidth + j) * 4;
uchar r, g, b, a;
- idToRGBA(id, &r, &g, &b, &a);
+ idToRGBA(lastSelectionId, &r, &g, &b, &a);
fillIdCorner(&bits[p], r, g, b, a, stride);
- idToRGBA(id + 1, &r, &g, &b, &a);
+ idToRGBA(lastSelectionId + 1, &r, &g, &b, &a);
fillIdCorner(&bits[p + 8], r, g, b, a, stride);
- idToRGBA(id + m_sampleSpace.width(), &r, &g, &b, &a);
+ idToRGBA(lastSelectionId + sampleSpace.width(), &r, &g, &b, &a);
fillIdCorner(&bits[p + 2 * stride], r, g, b, a, stride);
- idToRGBA(id + m_sampleSpace.width() + 1, &r, &g, &b, &a);
+ idToRGBA(lastSelectionId + sampleSpace.width() + 1, &r, &g, &b, &a);
fillIdCorner(&bits[p + 2 * stride + 8], r, g, b, a, stride);
- id++;
+ lastSelectionId++;
}
- id++;
- }
-
- // If old texture exists, delete it
- if (m_selectionTexture) {
- m_textureHelper->deleteTexture(&m_selectionTexture);
- m_selectionTexture = 0;
+ lastSelectionId++;
}
+ lastSelectionId += sampleSpace.width();
+ cache->setSelectionIdRange(idStart, lastSelectionId - 1);
// Move the ID image (bits) to the texture
QImage image = QImage(bits, idImageWidth, idImageHeight, QImage::Format_RGB32);
- m_selectionTexture = m_textureHelper->create2DTexture(image, false, false, false);
+ GLuint selectionTexture = m_textureHelper->create2DTexture(image, false, false, false);
+ cache->setSelectionTexture(selectionTexture);
// Release the temp bits allocation
delete[] bits;
@@ -1821,33 +2075,30 @@ void Surface3DRenderer::calculateSceneScalingFactors()
m_scaleZWithBackground = m_scaleZ * backgroundMargin;
}
-bool Surface3DRenderer::updateFlatStatus(bool enable)
+void Surface3DRenderer::checkFlatSupport(SurfaceSeriesRenderCache *cache)
{
- if (enable && !m_flatSupported) {
+ bool flatEnable = cache->isFlatShadingEnabled();
+ if (flatEnable && !m_flatSupported) {
qWarning() << "Warning: Flat qualifier not supported on your platform's GLSL language."
" Requires at least GLSL version 1.2 with GL_EXT_gpu_shader4 extension.";
- enable = false;
+ cache->setFlatShadingEnabled(false);
+ cache->setFlatChangeAllowed(false);
}
+}
- bool changed = false;
- if (enable != m_cachedFlatShading) {
- m_cachedFlatShading = enable;
- changed = true;
- initSurfaceShaders();
- }
+void Surface3DRenderer::updateObjects(SurfaceSeriesRenderCache *cache, bool dimensionChanged)
+{
+ QSurfaceDataArray &dataArray = cache->dataArray();
+ const QRect &sampleSpace = cache->sampleSpace();
- // 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_cachedFlatShading) {
- m_surfaceObj->setUpSmoothData(m_dataArray, m_sampleSpace, m_heightNormalizer,
- m_axisCacheY.min(), true);
- } else {
- m_surfaceObj->setUpData(m_dataArray, m_sampleSpace, m_heightNormalizer,
- m_axisCacheY.min(), true);
- }
- }
- return m_cachedFlatShading;
+ if (cache->isFlatShadingEnabled()) {
+ cache->surfaceObject()->setUpData(dataArray, sampleSpace, m_heightNormalizer,
+ m_axisCacheY.min(), dimensionChanged);
+ } else {
+ cache->surfaceObject()->setUpSmoothData(dataArray, sampleSpace, m_heightNormalizer,
+ m_axisCacheY.min(), dimensionChanged);
+ }
}
void Surface3DRenderer::updateSelectedPoint(const QPoint &position, const QSurface3DSeries *series)
@@ -1863,11 +2114,6 @@ void Surface3DRenderer::resetClickedStatus()
m_clickedSeries = 0;
}
-void Surface3DRenderer::updateSurfaceGridStatus(bool enable)
-{
- m_cachedSurfaceGridOn = enable;
-}
-
void Surface3DRenderer::loadBackgroundMesh()
{
if (m_backgroundObj)
@@ -1876,20 +2122,6 @@ void Surface3DRenderer::loadBackgroundMesh()
m_backgroundObj->load();
}
-void Surface3DRenderer::loadSurfaceObj()
-{
- if (m_surfaceObj)
- delete m_surfaceObj;
- m_surfaceObj = new SurfaceObject();
-}
-
-void Surface3DRenderer::loadSliceSurfaceObj()
-{
- if (m_sliceSurfaceObj)
- delete m_sliceSurfaceObj;
- m_sliceSurfaceObj = new SurfaceObject();
-}
-
void Surface3DRenderer::loadGridLineMesh()
{
if (m_gridLineObj)
@@ -1900,56 +2132,132 @@ void Surface3DRenderer::loadGridLineMesh()
void Surface3DRenderer::surfacePointSelected(const QPoint &point)
{
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ cache->setSlicePointerActivity(false);
+ cache->setMainPointerActivity(false);
+ }
+
+ if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionMultiSeries)) {
+ // Find axis coordinates for the selected point
+ SurfaceSeriesRenderCache *selectedCache =
+ m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries));
+ QSurfaceDataArray &dataArray = selectedCache->dataArray();
+ QSurfaceDataItem item = dataArray.at(point.x())->at(point.y());
+ QPointF coords(item.x(), item.z());
+
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (cache->series() != m_selectedSeries) {
+ QPoint mappedPoint = mapCoordsToSampleSpace(cache, coords);
+ updateSelectionPoint(cache, mappedPoint, false);
+ } else {
+ updateSelectionPoint(cache, point, true);
+ }
+ }
+ } else {
+ if (m_selectedSeries) {
+ SurfaceSeriesRenderCache *cache =
+ m_renderCacheList.value(const_cast<QSurface3DSeries *>(m_selectedSeries));
+ if (cache)
+ updateSelectionPoint(cache, point, true);
+ }
+ }
+}
+
+void Surface3DRenderer::updateSelectionPoint(SurfaceSeriesRenderCache *cache, const QPoint &point,
+ bool label)
+{
int row = point.x();
int column = point.y();
- float value = m_dataArray.at(row)->at(column).y();
+ if (column < 0 || row < 0)
+ return;
+
+ QSurfaceDataArray &dataArray = cache->dataArray();
+ float value = dataArray.at(row)->at(column).y();
+
+ SelectionPointer *slicePointer = cache->sliceSelectionPointer();
+ if (!slicePointer && m_cachedIsSlicingActivated) {
+ slicePointer = new SelectionPointer(m_drawer);
+ cache->setSliceSelectionPointer(slicePointer);
+ }
+ SelectionPointer *mainPointer = cache->mainSelectionPointer();
+ if (!mainPointer) {
+ mainPointer = new SelectionPointer(m_drawer);
+ cache->setMainSelectionPointer(mainPointer);
+ }
- if (!m_selectionPointer)
- m_selectionPointer = new SelectionPointer(m_drawer);
+ const QVector3D &scale = cache->scale();
+ const QVector3D &offset = cache->offset();
+ QString selectionLabel;
+ if (label)
+ selectionLabel = createSelectionLabel(cache, value, column, row);
- QVector3D pos;
if (m_cachedIsSlicingActivated) {
+ QVector3D subPos;
if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow)) {
- pos = m_sliceSurfaceObj->vertexAt(column, 0);
- pos *= QVector3D(m_surfaceScaleX, 1.0f, 0.0f);
- pos += QVector3D(m_surfaceOffsetX, 0.0f, 0.0f);
- m_selectionPointer->updateBoundingRect(m_secondarySubViewport);
- m_selectionPointer->updateSliceData(true, m_autoScaleAdjustment);
+ subPos = cache->sliceSurfaceObject()->vertexAt(column, 0);
+ subPos *= QVector3D(scale.x(), 1.0f, 0.0f);
+ subPos += QVector3D(offset.x(), 0.0f, 0.0f);
} else if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionColumn)) {
- pos = m_sliceSurfaceObj->vertexAt(row, 0);
- pos *= QVector3D(m_surfaceScaleZ, 1.0f, 0.0f);
- pos += QVector3D(-m_surfaceOffsetZ, 0.0f, 0.0f);
- m_selectionPointer->updateBoundingRect(m_secondarySubViewport);
- m_selectionPointer->updateSliceData(true, m_autoScaleAdjustment);
+ subPos = cache->sliceSurfaceObject()->vertexAt(row, 0);
+ subPos *= QVector3D(scale.z(), 1.0f, 0.0f);
+ subPos += QVector3D(-offset.z(), 0.0f, 0.0f);
}
- } else {
- pos = m_surfaceObj->vertexAt(column, row);
- pos *= QVector3D(m_surfaceScaleX, 1.0f, m_surfaceScaleZ);;
- pos += QVector3D(m_surfaceOffsetX, 0.0f, m_surfaceOffsetZ);
- m_selectionPointer->updateBoundingRect(m_primarySubViewport);
- m_selectionPointer->updateSliceData(false, m_autoScaleAdjustment);
- }
-
- m_selectionPointer->setPosition(pos);
- m_selectionPointer->setLabel(createSelectionLabel(value, column, row));
- m_selectionPointer->setPointerObject(m_visibleSeriesList.at(0).object());
- m_selectionPointer->setHighlightColor(m_visibleSeriesList.at(0).singleHighlightColor());
- m_selectionPointer->updateScene(m_cachedScene);
- m_selectionPointer->setRotation(m_visibleSeriesList.at(0).meshRotation());
+ slicePointer->updateBoundingRect(m_secondarySubViewport);
+ slicePointer->updateSliceData(true, m_autoScaleAdjustment);
+ slicePointer->setPosition(subPos);
+ slicePointer->setLabel(selectionLabel);
+ slicePointer->setPointerObject(cache->object());
+ slicePointer->setHighlightColor(cache->singleHighlightColor());
+ slicePointer->updateScene(m_cachedScene);
+ slicePointer->setRotation(cache->meshRotation());
+ cache->setSlicePointerActivity(true);
+ }
+
+ QVector3D mainPos;
+ mainPos = cache->surfaceObject()->vertexAt(column, row);
+ mainPos *= scale;
+ mainPos += offset;
+ mainPointer->updateBoundingRect(m_primarySubViewport);
+ mainPointer->updateSliceData(false, m_autoScaleAdjustment);
+ mainPointer->setPosition(mainPos);
+ mainPointer->setLabel(selectionLabel);
+ mainPointer->setPointerObject(cache->object());
+ mainPointer->setHighlightColor(cache->singleHighlightColor());
+ mainPointer->updateScene(m_cachedScene);
+ mainPointer->setRotation(cache->meshRotation());
+ cache->setMainPointerActivity(true);
}
// Maps selection Id to surface point in data array
QPoint Surface3DRenderer::selectionIdToSurfacePoint(uint id)
{
- int column = ((id - 1) % m_sampleSpace.width()) + m_sampleSpace.x();
- int row = ((id - 1) / m_sampleSpace.width()) + m_sampleSpace.y();
+ SurfaceSeriesRenderCache *selectedCache = 0;
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (cache->isWithinIdRange(id)) {
+ selectedCache = cache;
+ break;
+ }
+ }
+ if (!selectedCache) {
+ m_clickedSeries = 0;
+ return Surface3DController::invalidSelectionPosition();
+ }
+
+ uint idInSeries = id - selectedCache->selectionIdStart() + 1;
+ const QRect &sampleSpace = selectedCache->sampleSpace();
+ int column = ((idInSeries - 1) % sampleSpace.width()) + sampleSpace.x();
+ int row = ((idInSeries - 1) / sampleSpace.width()) + sampleSpace.y();
+
+ m_clickedSeries = selectedCache->series();
return QPoint(row, column);
}
-QString Surface3DRenderer::createSelectionLabel(float value, int column, int row)
+QString Surface3DRenderer::createSelectionLabel(SurfaceSeriesRenderCache *cache, float value,
+ int column, int row)
{
- QString labelText = m_visibleSeriesList[0].itemLabelFormat();
+ QSurfaceDataArray &dataArray = cache->dataArray();
+ QString labelText = cache->itemLabelFormat();
static const QString xTitleTag(QStringLiteral("@xTitle"));
static const QString yTitleTag(QStringLiteral("@yTitle"));
static const QString zTitleTag(QStringLiteral("@zTitle"));
@@ -1967,7 +2275,7 @@ QString Surface3DRenderer::createSelectionLabel(float value, int column, int row
if (labelFormat.isEmpty())
labelFormat = Utils::defaultLabelFormat();
QString valueLabelText = generateValueLabel(labelFormat,
- m_dataArray.at(row)->at(column).x());
+ dataArray.at(row)->at(column).x());
labelText.replace(xLabelTag, valueLabelText);
}
if (labelText.contains(yLabelTag)) {
@@ -1982,11 +2290,11 @@ QString Surface3DRenderer::createSelectionLabel(float value, int column, int row
if (labelFormat.isEmpty())
labelFormat = Utils::defaultLabelFormat();
QString valueLabelText = generateValueLabel(labelFormat,
- m_dataArray.at(row)->at(column).z());
+ dataArray.at(row)->at(column).z());
labelText.replace(zLabelTag, valueLabelText);
}
- labelText.replace(seriesNameTag, m_visibleSeriesList[0].name());
+ labelText.replace(seriesNameTag, cache->name());
m_selectionLabelDirty = false;
@@ -2055,6 +2363,11 @@ void Surface3DRenderer::updateSlicingActive(bool isSlicing)
#endif
m_selectionDirty = true;
+
+ foreach (SurfaceSeriesRenderCache *cache, m_renderCacheList) {
+ if (cache->mainSelectionPointer())
+ cache->mainSelectionPointer()->updateBoundingRect(m_primarySubViewport);
+ }
}
void Surface3DRenderer::loadLabelMesh()
@@ -2071,31 +2384,34 @@ void Surface3DRenderer::initShaders(const QString &vertexShader, const QString &
Q_UNUSED(fragmentShader);
// draw the shader for the surface according to smooth status, shadow and uniform color
- if (m_surfaceShader)
- delete m_surfaceShader;
+ if (m_surfaceFlatShader)
+ delete m_surfaceFlatShader;
+ if (m_surfaceSmoothShader)
+ delete m_surfaceSmoothShader;
+
#if !defined(QT_OPENGL_ES_2)
- if (!m_cachedFlatShading) {
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
- m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentSurfaceShadowNoTex"));
- } else {
- m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragmentSurface"));
- }
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ m_surfaceSmoothShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentSurfaceShadowNoTex"));
} else {
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
- m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceShadowFlat"),
+ m_surfaceSmoothShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentSurface"));
+ }
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ m_surfaceFlatShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceShadowFlat"),
QStringLiteral(":/shaders/fragmentSurfaceShadowFlat"));
- } else {
- m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceFlat"),
+ } else {
+ m_surfaceFlatShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceFlat"),
QStringLiteral(":/shaders/fragmentSurfaceFlat"));
- }
}
#else
- m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragmentSurfaceES2"));
+ m_surfaceSmoothShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentSurfaceES2"));
+ m_surfaceFlatShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentSurfaceES2"));
#endif
- m_surfaceShader->initialize();
+ m_surfaceSmoothShader->initialize();
+ m_surfaceFlatShader->initialize();
}
void Surface3DRenderer::initBackgroundShaders(const QString &vertexShader,
@@ -2175,16 +2491,4 @@ void Surface3DRenderer::updateDepthBuffer()
}
#endif
-void Surface3DRenderer::generateUniformGradient(const QVector3D newColor)
-{
- if (m_visibleSeriesList.size()) {
- QColor newQColor = Utils::colorFromVector(newColor);
- m_uniformGradientTextureColor = newColor;
- QLinearGradient newGradient;
- newGradient.setColorAt(0.0, newQColor);
- newGradient.setColorAt(1.0, newQColor);
- fixGradientAndGenerateTexture(&newGradient, &m_uniformGradientTexture);
- }
-}
-
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h
index 06973f43..7a4422e4 100644
--- a/src/datavisualization/engine/surface3drenderer_p.h
+++ b/src/datavisualization/engine/surface3drenderer_p.h
@@ -34,6 +34,7 @@
#include "abstract3drenderer_p.h"
#include "scatterrenderitem_p.h"
#include "qsurfacedataproxy.h"
+#include "surfaceseriesrendercache_p.h"
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -47,20 +48,14 @@ class QT_DATAVISUALIZATION_EXPORT Surface3DRenderer : public Abstract3DRenderer
{
Q_OBJECT
-public:
- // Visual parameters
- QRect m_boundingRect;
- bool m_labelBackground;
- QFont m_font;
- bool m_isGridEnabled;
-
private:
bool m_cachedIsSlicingActivated;
// Internal attributes purely related to how the scene is drawn with GL.
ShaderHelper *m_depthShader;
ShaderHelper *m_backgroundShader;
- ShaderHelper *m_surfaceShader;
+ ShaderHelper *m_surfaceFlatShader;
+ ShaderHelper *m_surfaceSmoothShader;
ShaderHelper *m_surfaceGridShader;
ShaderHelper *m_selectionShader;
ShaderHelper *m_labelShader;
@@ -70,10 +65,6 @@ private:
GLfloat m_scaleZ;
GLfloat m_scaleXWithBackground;
GLfloat m_scaleZWithBackground;
- GLfloat m_surfaceScaleX;
- GLfloat m_surfaceScaleZ;
- GLfloat m_surfaceOffsetX;
- GLfloat m_surfaceOffsetZ;
GLfloat m_minVisibleColumnValue;
GLfloat m_maxVisibleColumnValue;
GLfloat m_minVisibleRowValue;
@@ -83,38 +74,28 @@ private:
ObjectHelper *m_backgroundObj;
ObjectHelper *m_gridLineObj;
ObjectHelper *m_labelObj;
- SurfaceObject *m_surfaceObj;
- SurfaceObject *m_sliceSurfaceObj;
GLuint m_depthTexture;
GLuint m_depthModelTexture;
GLuint m_depthFrameBuffer;
GLuint m_selectionFrameBuffer;
GLuint m_selectionDepthBuffer;
- GLuint m_selectionTexture;
GLuint m_selectionResultTexture;
GLfloat m_shadowQualityToShader;
- bool m_cachedFlatShading;
bool m_flatSupported;
- bool m_cachedSurfaceVisible;
- bool m_cachedSurfaceGridOn;
- SelectionPointer *m_selectionPointer;
bool m_selectionActive;
bool m_xFlipped;
bool m_zFlipped;
bool m_yFlipped;
AbstractRenderItem m_dummyRenderItem;
- QSurfaceDataArray m_dataArray;
- QSurfaceDataArray m_sliceDataArray;
- QRect m_sampleSpace;
GLint m_shadowQualityMultiplier;
QSizeF m_areaSize;
- uint m_clickedPointId;
bool m_hasHeightAdjustmentChanged;
QPoint m_selectedPoint;
const QSurface3DSeries *m_selectedSeries;
- GLuint m_uniformGradientTexture;
- QVector3D m_uniformGradientTextureColor;
QPoint m_clickedPosition;
+ QHash<QSurface3DSeries *, SurfaceSeriesRenderCache *> m_renderCacheList;
+ bool m_selectionTexturesDirty;
+ GLuint m_noShadowTexture;
public:
explicit Surface3DRenderer(Surface3DController *controller);
@@ -122,11 +103,12 @@ public:
void updateData();
void updateSeries(const QList<QAbstract3DSeries *> &seriesList, bool updateVisibility);
- void updateRows(const QVector<int> &rows);
- void updateItem(const QVector<QPoint> &points);
+ void updateSelectionMode(QAbstract3DGraph::SelectionFlags mode);
+ void modifiedSeriesList(const QVector<QSurface3DSeries *> &seriesList);
+ void updateRows(const QVector<Surface3DController::ChangeRow> &rows);
+ void updateItem(const QVector<Surface3DController::ChangeItem> &points);
+ void updateAxisRange(QAbstract3DAxis::AxisOrientation orientation, float min, float max);
void updateScene(Q3DScene *scene);
- bool updateFlatStatus(bool enable);
- void updateSurfaceGridStatus(bool enable);
void updateSlicingActive(bool isSlicing);
void updateSelectedPoint(const QPoint &position, const QSurface3DSeries *series);
inline QPoint clickedPosition() const { return m_clickedPosition; }
@@ -142,16 +124,20 @@ signals:
void flatShadingSupportedChanged(bool supported);
private:
+ void checkFlatSupport(SurfaceSeriesRenderCache *cache);
+ void updateObjects(SurfaceSeriesRenderCache *cache, bool dimensionChanged);
void updateSliceDataModel(const QPoint &point);
+ QPoint mapCoordsToSampleSpace(SurfaceSeriesRenderCache *cache, const QPointF &coords);
+ void findMatchingRow(float z, int &sample, int direction, QSurfaceDataArray &dataArray);
+ void findMatchingColumn(float x, int &sample, int direction, QSurfaceDataArray &dataArray);
+ void updateSliceObject(SurfaceSeriesRenderCache *cache, const QPoint &point);
void updateShadowQuality(QAbstract3DGraph::ShadowQuality quality);
void updateTextures();
void initShaders(const QString &vertexShader, const QString &fragmentShader);
- QRect calculateSampleRect(const QSurfaceDataArray &array);
+ QRect calculateSampleRect(SurfaceSeriesRenderCache *cache, const QSurfaceDataArray &array);
void loadBackgroundMesh();
void loadGridLineMesh();
void loadLabelMesh();
- void loadSurfaceObj();
- void loadSliceSurfaceObj();
void drawScene(GLuint defaultFboHandle);
void calculateSceneScalingFactors();
void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader);
@@ -160,17 +146,18 @@ private:
void initSurfaceShaders();
void initSelectionBuffer();
void initDepthShader();
- void updateSelectionTexture();
+ void updateSelectionTextures();
+ void createSelectionTexture(SurfaceSeriesRenderCache *cache, uint &lastSelectionId);
void idToRGBA(uint id, uchar *r, uchar *g, uchar *b, uchar *a);
void fillIdCorner(uchar *p, uchar r, uchar g, uchar b, uchar a, int stride);
void surfacePointSelected(const QPoint &point);
+ void updateSelectionPoint(SurfaceSeriesRenderCache *cache, const QPoint &point, bool label);
QPoint selectionIdToSurfacePoint(uint id);
- QString createSelectionLabel(float value, int column, int row);
+ QString createSelectionLabel(SurfaceSeriesRenderCache *cache, float value, int column, int row);
#if !defined(QT_OPENGL_ES_2)
void updateDepthBuffer();
#endif
void emitSelectedPointChanged(QPoint position);
- void generateUniformGradient(const QVector3D newColor);
Q_DISABLE_COPY(Surface3DRenderer)
};
diff --git a/src/datavisualization/engine/surfaceseriesrendercache.cpp b/src/datavisualization/engine/surfaceseriesrendercache.cpp
new file mode 100644
index 00000000..ba25d71d
--- /dev/null
+++ b/src/datavisualization/engine/surfaceseriesrendercache.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 "seriesrendercache_p.h"
+#include "surfaceseriesrendercache_p.h"
+#include "objecthelper_p.h"
+#include "abstract3drenderer_p.h"
+#include "texturehelper_p.h"
+#include "utils_p.h"
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+SurfaceSeriesRenderCache::SurfaceSeriesRenderCache()
+ : m_surfaceVisible(false),
+ m_surfaceGridVisible(false),
+ m_surfaceFlatShading(true),
+ m_surfaceObj(new SurfaceObject),
+ m_sliceSurfaceObj(new SurfaceObject),
+ m_sampleSpace(QRect(0, 0, 0 , 0)),
+ m_selectionTexture(0),
+ m_selectionIdStart(0),
+ m_selectionIdEnd(0),
+ m_flatChangeAllowed(true),
+ m_flatStatusDirty(false),
+ m_scale(QVector3D(1.0f, 1.0f, 1.0f)),
+ m_offset(QVector3D(0.0f, 0.0f, 0.0f)),
+ m_sliceSelectionPointer(0),
+ m_mainSelectionPointer(0),
+ m_slicePointerActive(false),
+ m_mainPointerActive(false),
+ m_valid(false),
+ m_objectDirty(true)
+{
+}
+
+SurfaceSeriesRenderCache::~SurfaceSeriesRenderCache()
+{
+}
+
+void SurfaceSeriesRenderCache::populate(QSurface3DSeries *series, Abstract3DRenderer *renderer)
+{
+ Q_ASSERT(series);
+
+ SeriesRenderCache::populate(series, renderer);
+
+ QSurface3DSeries::DrawFlags drawMode = series->drawMode();
+ m_surfaceVisible = drawMode.testFlag(QSurface3DSeries::DrawSurface);
+ m_surfaceGridVisible = drawMode.testFlag(QSurface3DSeries::DrawWireframe);
+ if (m_flatChangeAllowed && m_surfaceFlatShading != series->isFlatShadingEnabled()) {
+ m_surfaceFlatShading = series->isFlatShadingEnabled();
+ m_flatStatusDirty = true;
+ }
+}
+
+void SurfaceSeriesRenderCache::cleanup(TextureHelper *texHelper)
+{
+ if (QOpenGLContext::currentContext())
+ texHelper->deleteTexture(&m_selectionTexture);
+
+ delete m_surfaceObj;
+ delete m_sliceSurfaceObj;
+ for (int i = 0; i < m_dataArray.size(); i++)
+ delete m_dataArray.at(i);
+ m_dataArray.clear();
+
+ for (int i = 0; i < m_sliceDataArray.size(); i++)
+ delete m_sliceDataArray.at(i);
+ m_sliceDataArray.clear();
+
+ delete m_sliceSelectionPointer;
+ delete m_mainSelectionPointer;
+
+ SeriesRenderCache::cleanup(texHelper);
+}
+
+QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/surfaceseriesrendercache_p.h b/src/datavisualization/engine/surfaceseriesrendercache_p.h
new file mode 100644
index 00000000..2dda0670
--- /dev/null
+++ b/src/datavisualization/engine/surfaceseriesrendercache_p.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 SURFACESERIESRENDERCACHE_P_H
+#define SURFACESERIESRENDERCACHE_P_H
+
+#include "datavisualizationglobal_p.h"
+#include "seriesrendercache_p.h"
+#include "qabstract3dseries_p.h"
+#include "qsurface3dseries_p.h"
+#include "surfaceobject_p.h"
+#include "selectionpointer_p.h"
+
+#include <QtGui/QMatrix4x4>
+
+QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+
+class Abstract3DRenderer;
+class ObjectHelper;
+class TextureHelper;
+
+class SurfaceSeriesRenderCache : public SeriesRenderCache
+{
+public:
+ SurfaceSeriesRenderCache();
+ virtual ~SurfaceSeriesRenderCache();
+
+ void populate(QSurface3DSeries *series, Abstract3DRenderer *renderer);
+ virtual void cleanup(TextureHelper *texHelper);
+
+ inline bool surfaceVisible() const { return m_surfaceVisible; }
+ inline bool surfaceGridVisible() const { return m_surfaceGridVisible; }
+ inline bool isFlatShadingEnabled() const { return m_surfaceFlatShading; }
+ inline void setFlatShadingEnabled(bool enabled) { m_surfaceFlatShading = enabled; }
+ inline void setFlatChangeAllowed(bool allowed) { m_flatChangeAllowed = allowed; }
+ inline void setValid(bool valid) { m_valid = valid; }
+ inline bool isValid() const { return m_valid; }
+ inline SurfaceObject *surfaceObject() { return m_surfaceObj; }
+ inline SurfaceObject *sliceSurfaceObject() { return m_sliceSurfaceObj; }
+ inline const QRect &sampleSpace() const { return m_sampleSpace; }
+ inline void setSampleSpace(const QRect &sampleSpace) { m_sampleSpace = sampleSpace; }
+ inline QSurface3DSeries *series() const { return static_cast<QSurface3DSeries *>(m_series); }
+ inline QSurfaceDataArray &dataArray() { return m_dataArray; }
+ inline QSurfaceDataArray &sliceDataArray() { return m_sliceDataArray; }
+ inline bool isSeriesVisible() const { return m_series->isVisible(); }
+ inline bool renderable() const { return m_series->isVisible() && (m_surfaceVisible ||
+ m_surfaceGridVisible); }
+ inline void setObjectDirty(bool state) { m_objectDirty = state; }
+ inline bool objectDirty() const { return m_objectDirty; }
+ inline void setSelectionTexture(GLuint texture) { m_selectionTexture = texture; }
+ inline GLuint selectionTexture() const { return m_selectionTexture; }
+ inline void setSelectionIdRange(uint start, uint end) { m_selectionIdStart = start;
+ m_selectionIdEnd = end; }
+ inline uint selectionIdStart() const { return m_selectionIdStart; }
+ inline bool isWithinIdRange(uint selection) const { return selection >= m_selectionIdStart &&
+ selection <= m_selectionIdEnd; }
+ inline bool isFlatStatusDirty() const { return m_flatStatusDirty; }
+ inline void setFlatStatusDirty(bool status) { m_flatStatusDirty = status; }
+ inline void setScale(const QVector3D &scale) { m_scale = scale; }
+ inline const QVector3D &scale() const { return m_scale; }
+ inline void setOffset(const QVector3D &offset) { m_offset = offset; }
+ inline const QVector3D &offset() const { return m_offset; }
+ // m_MVPMatrix is volatile, used only for optimizing rendering a bit
+ inline void setMVPMatrix(const QMatrix4x4 &matrix) { m_MVPMatrix = matrix; }
+ inline const QMatrix4x4 &MVPMatrix() { return m_MVPMatrix; }
+
+ inline void setSliceSelectionPointer(SelectionPointer *pointer) { m_sliceSelectionPointer = pointer; }
+ inline SelectionPointer *sliceSelectionPointer() const { return m_sliceSelectionPointer; }
+ inline void setMainSelectionPointer(SelectionPointer *pointer) { m_mainSelectionPointer = pointer; }
+ inline SelectionPointer *mainSelectionPointer() const { return m_mainSelectionPointer; }
+
+ inline void setSlicePointerActivity(bool activity) { m_slicePointerActive = activity; }
+ inline bool slicePointerActive() const { return m_slicePointerActive; }
+ inline void setMainPointerActivity(bool activity) { m_mainPointerActive = activity; }
+ inline bool mainPointerActive() const { return m_mainPointerActive; }
+
+protected:
+ bool m_surfaceVisible;
+ bool m_surfaceGridVisible;
+ bool m_surfaceFlatShading;
+ SurfaceObject *m_surfaceObj;
+ SurfaceObject *m_sliceSurfaceObj;
+ QRect m_sampleSpace;
+ QSurfaceDataArray m_dataArray;
+ QSurfaceDataArray m_sliceDataArray;
+ GLuint m_selectionTexture;
+ uint m_selectionIdStart;
+ uint m_selectionIdEnd;
+ bool m_flatChangeAllowed;
+ bool m_flatStatusDirty;
+ QVector3D m_scale;
+ QVector3D m_offset;
+ QMatrix4x4 m_MVPMatrix;
+ SelectionPointer *m_sliceSelectionPointer;
+ SelectionPointer *m_mainSelectionPointer;
+ bool m_slicePointerActive;
+ bool m_mainPointerActive;
+
+ bool m_valid;
+ bool m_objectDirty;
+};
+
+QT_END_NAMESPACE_DATAVISUALIZATION
+
+#endif
diff --git a/src/datavisualization/global/datavisualizationglobal_p.h b/src/datavisualization/global/datavisualizationglobal_p.h
index 83af408a..e448c1cb 100644
--- a/src/datavisualization/global/datavisualizationglobal_p.h
+++ b/src/datavisualization/global/datavisualizationglobal_p.h
@@ -30,9 +30,10 @@
#define DATAVISUALIZATIONGLOBAL_P_H
#include "qdatavisualizationglobal.h"
-#include <QOpenGLFunctions>
-#include <QVector3D>
-#include <QDebug>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QVector3D>
+#include <QtGui/QQuaternion>
+#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -49,12 +50,15 @@ static const QVector3D defaultLightPos = QVector3D(0.0f, 0.5f, 0.0f);
static const QVector3D zeroVector = QVector3D(0.0f, 0.0f, 0.0f);
static const QVector3D upVector = QVector3D(0.0f, 1.0f, 0.0f);
static const QVector3D cameraDistanceVector = QVector3D(0.0f, 0.0f, cameraDistance);
+static const QQuaternion identityQuaternion;
// Skip color == selection texture's background color
static const QVector3D selectionSkipColor = QVector3D(255.0f, 255.0f, 255.0f);
static const QVector3D invalidColorVector = QVector3D(-1.0f, -1.0f, -1.0f);
static const GLfloat gradientTextureHeight = 1024.0f;
static const GLfloat gradientTextureWidth = 2.0f;
+static const GLfloat uniformTextureHeight = 64.0f;
+static const GLfloat uniformTextureWidth = 2.0f;
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/global/qdatavisualizationglobal.h b/src/datavisualization/global/qdatavisualizationglobal.h
index d7e71265..186db94c 100644
--- a/src/datavisualization/global/qdatavisualizationglobal.h
+++ b/src/datavisualization/global/qdatavisualizationglobal.h
@@ -19,7 +19,7 @@
#ifndef QDATAVISUALIZATIONGLOBAL_H
#define QDATAVISUALIZATIONGLOBAL_H
-#include <qglobal.h>
+#include <QtCore/qglobal.h>
#define QT_DATAVISUALIZATION_VERSION_STR "1.0.0"
/*
diff --git a/src/datavisualization/input/q3dinputhandler.h b/src/datavisualization/input/q3dinputhandler.h
index 49471d72..118bd829 100644
--- a/src/datavisualization/input/q3dinputhandler.h
+++ b/src/datavisualization/input/q3dinputhandler.h
@@ -16,8 +16,8 @@
**
****************************************************************************/
-#ifndef QDEFAULT3DINPUTHANDLER_H
-#define QDEFAULT3DINPUTHANDLER_H
+#ifndef Q3DINPUTHANDLER_H
+#define Q3DINPUTHANDLER_H
#include <QtDataVisualization/qabstract3dinputhandler.h>
diff --git a/src/datavisualization/input/qabstract3dinputhandler.cpp b/src/datavisualization/input/qabstract3dinputhandler.cpp
index f786d466..5360eb38 100644
--- a/src/datavisualization/input/qabstract3dinputhandler.cpp
+++ b/src/datavisualization/input/qabstract3dinputhandler.cpp
@@ -17,6 +17,7 @@
****************************************************************************/
#include "qabstract3dinputhandler_p.h"
+#include "q3dscene.h"
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/input/qabstract3dinputhandler.h b/src/datavisualization/input/qabstract3dinputhandler.h
index 803517ed..75ec8c1b 100644
--- a/src/datavisualization/input/qabstract3dinputhandler.h
+++ b/src/datavisualization/input/qabstract3dinputhandler.h
@@ -19,8 +19,13 @@
#ifndef QABSTRACT3DINPUTHANDLER_H
#define QABSTRACT3DINPUTHANDLER_H
+#include <QtDataVisualization/qdatavisualizationglobal.h>
#include <QtDataVisualization/q3dscene.h>
-#include <QMouseEvent>
+#include <QtCore/QObject>
+#include <QtCore/QPoint>
+#include <QtGui/QWheelEvent>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QTouchEvent>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -41,8 +46,9 @@ public:
InputViewOnSecondary
};
-public:
+protected:
explicit QAbstract3DInputHandler(QObject *parent = 0);
+public:
virtual ~QAbstract3DInputHandler();
// Input event listeners
@@ -53,7 +59,6 @@ public:
virtual void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos);
virtual void wheelEvent(QWheelEvent *event);
-public:
InputView inputView() const;
void setInputView(InputView inputView);
@@ -64,9 +69,9 @@ public:
void setScene(Q3DScene *scene);
signals:
- void positionChanged(QPoint position);
+ void positionChanged(const QPoint &position);
void inputViewChanged(InputView view);
- void sceneChanged(const Q3DScene *scene);
+ void sceneChanged(Q3DScene *scene);
protected:
void setPrevDistance(int distance);
diff --git a/src/datavisualization/input/qabstract3dinputhandler_p.h b/src/datavisualization/input/qabstract3dinputhandler_p.h
index 52b1a5f6..fa5a2315 100644
--- a/src/datavisualization/input/qabstract3dinputhandler_p.h
+++ b/src/datavisualization/input/qabstract3dinputhandler_p.h
@@ -31,7 +31,6 @@
#include "datavisualizationglobal_p.h"
#include "qabstract3dinputhandler.h"
-#include <QRect>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -62,7 +61,6 @@ public:
private:
QAbstract3DInputHandler::InputView m_inputView;
QPoint m_inputPosition;
- QRect m_mainViewPort;
Q3DScene *m_scene;
bool m_isDefaultHandler;
diff --git a/src/datavisualization/input/qtouch3dinputhandler.cpp b/src/datavisualization/input/qtouch3dinputhandler.cpp
index 76b5721b..da84b33f 100644
--- a/src/datavisualization/input/qtouch3dinputhandler.cpp
+++ b/src/datavisualization/input/qtouch3dinputhandler.cpp
@@ -18,8 +18,8 @@
#include "qtouch3dinputhandler_p.h"
#include "q3dcamera_p.h"
-#include <QTimer>
-#include <qmath.h>
+#include <QtCore/QTimer>
+#include <QtCore/qmath.h>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/input/qtouch3dinputhandler_p.h b/src/datavisualization/input/qtouch3dinputhandler_p.h
index 19c30142..613b5f28 100644
--- a/src/datavisualization/input/qtouch3dinputhandler_p.h
+++ b/src/datavisualization/input/qtouch3dinputhandler_p.h
@@ -22,6 +22,8 @@
#include "qabstract3dinputhandler_p.h"
#include "qtouch3dinputhandler.h"
+class QTimer;
+
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class QAbstract3DInputHandler;
diff --git a/src/datavisualization/theme/q3dtheme.h b/src/datavisualization/theme/q3dtheme.h
index 91c5bb6f..43278c79 100644
--- a/src/datavisualization/theme/q3dtheme.h
+++ b/src/datavisualization/theme/q3dtheme.h
@@ -20,10 +20,10 @@
#define Q3DTHEME_H
#include <QtDataVisualization/qdatavisualizationglobal.h>
-
-#include <QLinearGradient>
-#include <QFont>
-#include <QColor>
+#include <QtCore/QObject>
+#include <QtGui/QLinearGradient>
+#include <QtGui/QFont>
+#include <QtGui/QColor>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -149,23 +149,23 @@ public:
signals:
void typeChanged(Theme themeType);
- void baseColorsChanged(QList<QColor> colors);
- void backgroundColorChanged(QColor color);
- void windowColorChanged(QColor color);
- void labelTextColorChanged(QColor color);
- void labelBackgroundColorChanged(QColor color);
- void gridLineColorChanged(QColor color);
- void singleHighlightColorChanged(QColor color);
- void multiHighlightColorChanged(QColor color);
- void lightColorChanged(QColor color);
- void baseGradientsChanged(QList<QLinearGradient> gradients);
- void singleHighlightGradientChanged(QLinearGradient gradient);
- void multiHighlightGradientChanged(QLinearGradient gradient);
+ void baseColorsChanged(const QList<QColor> &colors);
+ void backgroundColorChanged(const QColor &color);
+ void windowColorChanged(const QColor &color);
+ void labelTextColorChanged(const QColor &color);
+ void labelBackgroundColorChanged(const QColor &color);
+ void gridLineColorChanged(const QColor &color);
+ void singleHighlightColorChanged(const QColor &color);
+ void multiHighlightColorChanged(const QColor &color);
+ void lightColorChanged(const QColor &color);
+ void baseGradientsChanged(const QList<QLinearGradient> &gradients);
+ void singleHighlightGradientChanged(const QLinearGradient &gradient);
+ void multiHighlightGradientChanged(const QLinearGradient &gradient);
void lightStrengthChanged(float strength);
void ambientLightStrengthChanged(float strength);
void highlightLightStrengthChanged(float strength);
void labelBorderEnabledChanged(bool enabled);
- void fontChanged(QFont font);
+ void fontChanged(const QFont &font);
void backgroundEnabledChanged(bool enabled);
void gridEnabledChanged(bool enabled);
void labelBackgroundEnabledChanged(bool enabled);
@@ -173,16 +173,17 @@ signals:
protected:
explicit Q3DTheme(Q3DThemePrivate *d, Theme themeType, QObject *parent = 0);
+
QScopedPointer<Q3DThemePrivate> d_ptr;
+private:
+ Q_DISABLE_COPY(Q3DTheme)
+
friend class ThemeManager;
friend class Abstract3DRenderer;
friend class Bars3DController;
friend class AbstractDeclarative;
friend class Abstract3DController;
-
-private:
- Q_DISABLE_COPY(Q3DTheme)
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/utils/abstractobjecthelper.cpp b/src/datavisualization/utils/abstractobjecthelper.cpp
index 9ced43a1..c350d096 100644
--- a/src/datavisualization/utils/abstractobjecthelper.cpp
+++ b/src/datavisualization/utils/abstractobjecthelper.cpp
@@ -18,8 +18,6 @@
#include "abstractobjecthelper_p.h"
-#include <QDebug>
-
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
AbstractObjectHelper::AbstractObjectHelper()
diff --git a/src/datavisualization/utils/abstractobjecthelper_p.h b/src/datavisualization/utils/abstractobjecthelper_p.h
index 5ec34318..3220b37d 100644
--- a/src/datavisualization/utils/abstractobjecthelper_p.h
+++ b/src/datavisualization/utils/abstractobjecthelper_p.h
@@ -30,7 +30,7 @@
#define ABSTRACTOBJECTHELPER_H
#include "datavisualizationglobal_p.h"
-#include <QOpenGLFunctions>
+#include <QtGui/QOpenGLFunctions>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/utils/camerahelper.cpp b/src/datavisualization/utils/camerahelper.cpp
index 220c49db..ee4c27e0 100644
--- a/src/datavisualization/utils/camerahelper.cpp
+++ b/src/datavisualization/utils/camerahelper.cpp
@@ -18,9 +18,8 @@
#include "camerahelper_p.h"
-#include <qmath.h>
-#include <QMatrix4x4>
-#include <QVector3D>
+#include <QtCore/qmath.h>
+#include <QtGui/QMatrix4x4>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/utils/camerahelper_p.h b/src/datavisualization/utils/camerahelper_p.h
index e78bc24c..f410ceb5 100644
--- a/src/datavisualization/utils/camerahelper_p.h
+++ b/src/datavisualization/utils/camerahelper_p.h
@@ -31,8 +31,6 @@
#include "datavisualizationglobal_p.h"
#include "q3dcamera.h"
-#include "q3dbars.h"
-#include <QObject>
class QMatrix4x4;
class QVector3D;
@@ -71,17 +69,17 @@ public:
QPointF getCameraRotations();
// Set default camera orientation. Position's x and y should be 0.
void setDefaultCameraOrientation(const QVector3D &defaultPosition,
- const QVector3D &defaultTarget,
- const QVector3D &defaultUp);
+ const QVector3D &defaultTarget,
+ const QVector3D &defaultUp);
// Calculate view matrix based on rotation and zoom
QMatrix4x4 calculateViewMatrix(const QPoint &mousePos, int zoom,
- int screenWidth, int screenHeight,
- bool showUnder = false);
+ int screenWidth, int screenHeight,
+ bool showUnder = false);
// Calcluate light position based on rotation. Call after calling calculateViewMatrix to get
// up-to-date position
QVector3D calculateLightPosition(const QVector3D &lightPosition,
- GLfloat fixedRotation = 0.0f,
- GLfloat distanceModifier = 0.0f);
+ GLfloat fixedRotation = 0.0f,
+ GLfloat distanceModifier = 0.0f);
void updateMousePos(const QPoint &mousePos);
void setCameraPreset(Q3DCamera::CameraPreset preset);
};
diff --git a/src/datavisualization/utils/meshloader.cpp b/src/datavisualization/utils/meshloader.cpp
index 49bdf710..615a7909 100644
--- a/src/datavisualization/utils/meshloader.cpp
+++ b/src/datavisualization/utils/meshloader.cpp
@@ -18,11 +18,10 @@
#include "meshloader_p.h"
-#include <QFile>
-#include <QStringList>
-#include <QVector>
-#include <QVector2D>
-#include <QVector3D>
+#include <QtCore/QFile>
+#include <QtCore/QStringList>
+#include <QtCore/QVector>
+#include <QtGui/QVector2D>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/utils/meshloader_p.h b/src/datavisualization/utils/meshloader_p.h
index e7425ae6..16ddaf6d 100644
--- a/src/datavisualization/utils/meshloader_p.h
+++ b/src/datavisualization/utils/meshloader_p.h
@@ -30,9 +30,7 @@
#define MESHLOADER_P_H
#include "datavisualizationglobal_p.h"
-
-class QVector2D;
-class QVector3D;
+#include <QtGui/QVector2D>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/utils/objecthelper_p.h b/src/datavisualization/utils/objecthelper_p.h
index f96fc87d..0260dd05 100644
--- a/src/datavisualization/utils/objecthelper_p.h
+++ b/src/datavisualization/utils/objecthelper_p.h
@@ -31,7 +31,7 @@
#include "datavisualizationglobal_p.h"
#include "abstractobjecthelper_p.h"
-#include <QOpenGLFunctions>
+#include <QtGui/QOpenGLFunctions>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/utils/shaderhelper.cpp b/src/datavisualization/utils/shaderhelper.cpp
index d4df11b4..7fb237c6 100644
--- a/src/datavisualization/utils/shaderhelper.cpp
+++ b/src/datavisualization/utils/shaderhelper.cpp
@@ -18,7 +18,7 @@
#include "shaderhelper_p.h"
-#include <QOpenGLShader>
+#include <QtGui/QOpenGLShader>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/utils/shaderhelper_p.h b/src/datavisualization/utils/shaderhelper_p.h
index 34bbf39e..ced27572 100644
--- a/src/datavisualization/utils/shaderhelper_p.h
+++ b/src/datavisualization/utils/shaderhelper_p.h
@@ -30,7 +30,7 @@
#define SHADERHELPER_P_H
#include "datavisualizationglobal_p.h"
-#include <QOpenGLFunctions>
+#include <QtGui/QOpenGLFunctions>
class QOpenGLShaderProgram;
diff --git a/src/datavisualization/utils/surfaceobject.cpp b/src/datavisualization/utils/surfaceobject.cpp
index b0cd6c82..9bcdfee2 100644
--- a/src/datavisualization/utils/surfaceobject.cpp
+++ b/src/datavisualization/utils/surfaceobject.cpp
@@ -19,12 +19,15 @@
#include "surfaceobject_p.h"
#include "abstractobjecthelper_p.h"
-#include <QVector3D>
-#include <QVector2D>
+#include <QtGui/QVector2D>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
SurfaceObject::SurfaceObject()
+ : m_surfaceType(Undefined),
+ m_columns(0),
+ m_rows(0),
+ m_gridIndexCount(0)
{
m_indicesType = GL_UNSIGNED_INT;
initializeOpenGLFunctions();
@@ -668,6 +671,9 @@ GLuint SurfaceObject::gridIndexCount()
QVector3D SurfaceObject::vertexAt(int column, int row)
{
int pos = 0;
+ if (m_surfaceType == Undefined || !m_vertices.size())
+ return zeroVector;
+
if (m_surfaceType == SurfaceFlat)
pos = row * (m_columns * 2 - 2) + column * 2 - (column > 0);
else
@@ -675,6 +681,13 @@ QVector3D SurfaceObject::vertexAt(int column, int row)
return m_vertices.at(pos);
}
+void SurfaceObject::clear()
+{
+ m_gridIndexCount = 0;
+ m_indexCount = 0;
+ m_surfaceType = Undefined;
+}
+
QVector3D SurfaceObject::normal(const QVector3D &a, const QVector3D &b, const QVector3D &c)
{
QVector3D v1 = b - a;
diff --git a/src/datavisualization/utils/surfaceobject_p.h b/src/datavisualization/utils/surfaceobject_p.h
index ec1a30bd..69cb7e5d 100644
--- a/src/datavisualization/utils/surfaceobject_p.h
+++ b/src/datavisualization/utils/surfaceobject_p.h
@@ -33,13 +33,20 @@
#include "abstractobjecthelper_p.h"
#include "qsurfacedataproxy.h"
-#include <QRect>
+#include <QtCore/QRect>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class SurfaceObject : public AbstractObjectHelper
{
public:
+ enum SurfaceType {
+ SurfaceSmooth,
+ SurfaceFlat,
+ Undefined
+ };
+
+public:
SurfaceObject();
~SurfaceObject();
@@ -63,6 +70,7 @@ public:
GLuint gridElementBuf();
GLuint gridIndexCount();
QVector3D vertexAt(int column, int row);
+ void clear();
private:
QVector3D normal(const QVector3D &a, const QVector3D &b, const QVector3D &c);
@@ -71,11 +79,7 @@ private:
bool changeGeometry);
private:
- enum SurfaceType {
- SurfaceSmooth,
- SurfaceFlat
- };
- int m_surfaceType;
+ SurfaceType m_surfaceType;
int m_columns;
int m_rows;
GLuint m_gridElementbuffer;
diff --git a/src/datavisualization/utils/texturehelper.cpp b/src/datavisualization/utils/texturehelper.cpp
index b5079f1b..52c673dc 100644
--- a/src/datavisualization/utils/texturehelper.cpp
+++ b/src/datavisualization/utils/texturehelper.cpp
@@ -19,10 +19,8 @@
#include "texturehelper_p.h"
#include "utils_p.h"
-#include <QImage>
-#include <QPainter>
-
-#include <QDebug>
+#include <QtGui/QImage>
+#include <QtGui/QPainter>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -45,7 +43,6 @@ GLuint TextureHelper::create2DTexture(const QImage &image, bool useTrilinearFilt
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
GLuint temp;
- //qDebug() << "old size" << image.size();
GLuint imageWidth = Utils::getNearestPowerOfTwo(image.width(), temp);
GLuint imageHeight = Utils::getNearestPowerOfTwo(image.height(), temp);
if (smoothScale) {
@@ -54,7 +51,6 @@ GLuint TextureHelper::create2DTexture(const QImage &image, bool useTrilinearFilt
} else {
texImage = image.scaled(imageWidth, imageHeight, Qt::IgnoreAspectRatio);
}
- //qDebug() << "new size" << texImage.size();
#endif
GLuint textureId;
@@ -155,6 +151,18 @@ GLuint TextureHelper::createSelectionTexture(const QSize &size, GLuint &frameBuf
return textureid;
}
+GLuint TextureHelper::createUniformTexture(const QColor &color)
+{
+ QImage image(QSize(int(uniformTextureWidth), int(uniformTextureHeight)),
+ QImage::Format_RGB32);
+ QPainter pmp(&image);
+ pmp.setBrush(QBrush(color));
+ pmp.setPen(Qt::NoPen);
+ pmp.drawRect(0, 0, int(uniformTextureWidth), int(uniformTextureHeight));
+
+ return create2DTexture(image, false, true, false, true);
+}
+
GLuint TextureHelper::createGradientTexture(const QLinearGradient &gradient)
{
QImage image(QSize(int(gradientTextureWidth), int(gradientTextureHeight)),
diff --git a/src/datavisualization/utils/texturehelper_p.h b/src/datavisualization/utils/texturehelper_p.h
index 17553f30..ebfaa042 100644
--- a/src/datavisualization/utils/texturehelper_p.h
+++ b/src/datavisualization/utils/texturehelper_p.h
@@ -30,9 +30,9 @@
#define TEXTUREHELPER_P_H
#include "datavisualizationglobal_p.h"
-#include <QOpenGLFunctions>
-#include <QRgb>
-#include <QLinearGradient>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QRgb>
+#include <QtGui/QLinearGradient>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -48,6 +48,7 @@ class TextureHelper : protected QOpenGLFunctions
GLuint createCubeMapTexture(const QImage &image, bool useTrilinearFiltering = false);
// Returns selection texture and inserts generated framebuffers to framebuffer parameters
GLuint createSelectionTexture(const QSize &size, GLuint &frameBuffer, GLuint &depthBuffer);
+ GLuint createUniformTexture(const QColor &color);
GLuint createGradientTexture(const QLinearGradient &gradient);
#if !defined(QT_OPENGL_ES_2)
GLuint createDepthTexture(const QSize &size, GLuint textureSize);
diff --git a/src/datavisualization/utils/utils.cpp b/src/datavisualization/utils/utils.cpp
index 482fc831..e0b1370e 100644
--- a/src/datavisualization/utils/utils.cpp
+++ b/src/datavisualization/utils/utils.cpp
@@ -18,13 +18,12 @@
#include "utils_p.h"
-#include <QVector3D>
-#include <QColor>
-#include <QPainter>
-#include <QPoint>
-#include <QImage>
-#include <QRegExp>
-#include <qmath.h>
+#include <QtGui/QColor>
+#include <QtGui/QPainter>
+#include <QtCore/QPoint>
+#include <QtGui/QImage>
+#include <QtCore/QRegExp>
+#include <QtCore/qmath.h>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/utils/vertexindexer.cpp b/src/datavisualization/utils/vertexindexer.cpp
index f089ce6e..2a496ebc 100644
--- a/src/datavisualization/utils/vertexindexer.cpp
+++ b/src/datavisualization/utils/vertexindexer.cpp
@@ -18,7 +18,7 @@
#include "vertexindexer_p.h"
-#include <qmath.h>
+#include <QtCore/qmath.h>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/utils/vertexindexer_p.h b/src/datavisualization/utils/vertexindexer_p.h
index fe100e21..260afad4 100644
--- a/src/datavisualization/utils/vertexindexer_p.h
+++ b/src/datavisualization/utils/vertexindexer_p.h
@@ -31,9 +31,8 @@
#include "datavisualizationglobal_p.h"
-#include <QVector>
-#include <QVector2D>
-#include <QVector3D>
+#include <QtCore/QVector>
+#include <QtGui/QVector2D>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION