summaryrefslogtreecommitdiffstats
path: root/src/datavisualization
diff options
context:
space:
mode:
authorMika Salmela <mika.salmela@digia.com>2013-12-03 14:00:23 +0200
committerMika Salmela <mika.salmela@digia.com>2013-12-03 14:06:59 +0200
commit344870fb79e647b87aa79b9433eef8237c901e10 (patch)
treef0ccaa5991d9f0304bc6f6f91ce3ffd45232384d /src/datavisualization
parent2af35db1a112c49991a80f48e3cd8d8814deb321 (diff)
Better proxy API for surface
Part 2, item change. More is on the way. Change-Id: Ic41f3a90b5a47502b741391ace990117ef2eaf80 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
Diffstat (limited to 'src/datavisualization')
-rw-r--r--src/datavisualization/data/qsurface3dseries.cpp2
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.cpp17
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.h3
-rw-r--r--src/datavisualization/data/qsurfacedataproxy_p.h1
-rw-r--r--src/datavisualization/engine/surface3dcontroller.cpp66
-rw-r--r--src/datavisualization/engine/surface3dcontroller_p.h9
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp78
-rw-r--r--src/datavisualization/engine/surface3drenderer_p.h3
-rw-r--r--src/datavisualization/utils/surfaceobject.cpp248
-rw-r--r--src/datavisualization/utils/surfaceobject_p.h13
10 files changed, 331 insertions, 109 deletions
diff --git a/src/datavisualization/data/qsurface3dseries.cpp b/src/datavisualization/data/qsurface3dseries.cpp
index 5a47a6e4..deb12f44 100644
--- a/src/datavisualization/data/qsurface3dseries.cpp
+++ b/src/datavisualization/data/qsurface3dseries.cpp
@@ -332,6 +332,8 @@ void QSurface3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *ne
&Surface3DController::handleArrayReset);
QObject::connect(surfaceDataProxy, &QSurfaceDataProxy::rowsChanged, controller,
&Surface3DController::handleRowsChanged);
+ QObject::connect(surfaceDataProxy, &QSurfaceDataProxy::itemChanged, controller,
+ &Surface3DController::handleItemChanged);
}
}
diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp
index aba2e288..4c6c85f7 100644
--- a/src/datavisualization/data/qsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qsurfacedataproxy.cpp
@@ -158,6 +158,15 @@ void QSurfaceDataProxy::setRows(int rowIndex, const QSurfaceDataArray &rows)
}
/*!
+ * Changes a single item at \a rowIndex, \a columnIndex to the \a item.
+ */
+void QSurfaceDataProxy::setItem(int rowIndex, int columnIndex, const QSurfaceDataItem &item)
+{
+ dptr()->setItem(rowIndex, columnIndex, item);
+ emit itemChanged(rowIndex, columnIndex);
+}
+
+/*!
* \return pointer to the data array.
*/
const QSurfaceDataArray *QSurfaceDataProxy::array() const
@@ -273,6 +282,14 @@ void QSurfaceDataProxyPrivate::setRows(int rowIndex, const QSurfaceDataArray &ro
}
}
+void QSurfaceDataProxyPrivate::setItem(int rowIndex, int columnIndex, const QSurfaceDataItem &item)
+{
+ Q_ASSERT(rowIndex >= 0 && rowIndex < m_dataArray->size());
+ QSurfaceDataRow &row = *(*m_dataArray)[rowIndex];
+ Q_ASSERT(columnIndex < row.size());
+ row[columnIndex] = item;
+}
+
QSurfaceDataProxy *QSurfaceDataProxyPrivate::qptr()
{
return static_cast<QSurfaceDataProxy *>(q_ptr);
diff --git a/src/datavisualization/data/qsurfacedataproxy.h b/src/datavisualization/data/qsurfacedataproxy.h
index d8808ded..4533f4c5 100644
--- a/src/datavisualization/data/qsurfacedataproxy.h
+++ b/src/datavisualization/data/qsurfacedataproxy.h
@@ -53,9 +53,12 @@ public:
void setRow(int rowIndex, QSurfaceDataRow *row);
void setRows(int rowIndex, const QSurfaceDataArray &rows);
+ void setItem(int rowIndex, int columnIndex, const QSurfaceDataItem &item);
+
signals:
void arrayReset();
void rowsChanged(int startIndex, int count);
+ void itemChanged(int rowIndex, int columnIndex);
void seriesChanged(QSurface3DSeries *series);
protected:
diff --git a/src/datavisualization/data/qsurfacedataproxy_p.h b/src/datavisualization/data/qsurfacedataproxy_p.h
index 38d92be1..3125a40a 100644
--- a/src/datavisualization/data/qsurfacedataproxy_p.h
+++ b/src/datavisualization/data/qsurfacedataproxy_p.h
@@ -46,6 +46,7 @@ public:
void resetArray(QSurfaceDataArray *newArray);
void setRow(int rowIndex, QSurfaceDataRow *row);
void setRows(int rowIndex, const QSurfaceDataArray &rows);
+ void setItem(int rowIndex, int columnIndex, const QSurfaceDataItem &item);
void limitValues(QVector3D &minValues, QVector3D &maxValues) const;
virtual void setSeries(QAbstract3DSeries *series);
diff --git a/src/datavisualization/engine/surface3dcontroller.cpp b/src/datavisualization/engine/surface3dcontroller.cpp
index b1586a78..a9c5f508 100644
--- a/src/datavisualization/engine/surface3dcontroller.cpp
+++ b/src/datavisualization/engine/surface3dcontroller.cpp
@@ -37,8 +37,6 @@ Surface3DController::Surface3DController(QRect rect)
m_renderer(0),
m_selectedPoint(invalidSelectionPosition()),
m_selectedSeries(0),
- m_rowsChangeStartId(0),
- m_rowsChangeCount(0),
m_flatShadingSupported(true)
{
// Setting a null axis creates a new default axis according to orientation and graph type.
@@ -84,8 +82,15 @@ void Surface3DController::synchDataToRenderer()
}
if (m_changeTracker.rowsChanged) {
- m_renderer->updateRows(m_rowsChangeStartId, m_rowsChangeCount);
+ m_renderer->updateRows(m_changedRows);
m_changeTracker.rowsChanged = false;
+ m_changedRows.clear();
+ }
+
+ if (m_changeTracker.itemChanged) {
+ m_renderer->updateItem(m_changedItems);
+ m_changeTracker.itemChanged = false;
+ m_changedItems.clear();
}
if (m_changeTracker.selectedPointChanged) {
@@ -320,16 +325,57 @@ void Surface3DController::handleFlatShadingSupportedChange(bool supported)
void Surface3DController::handleRowsChanged(int startIndex, int count)
{
QSurfaceDataProxy *sender = static_cast<QSurfaceDataProxy *>(QObject::sender());
+ if (m_changedRows.size() == 0)
+ m_changedRows.reserve(sender->rowCount());
+
if (static_cast<QSurface3DSeries *>(m_seriesList.at(0)) == sender->series()) {
// Change is for the visible series, put the change to queue
- m_rowsChangeStartId = startIndex;
- m_rowsChangeCount = count;
- m_changeTracker.rowsChanged = true;
+ 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;
+ }
+ }
+ 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();
+ adjustValueAxisRange();
+ // Clear selection unless still valid
+ setSelectedPoint(m_selectedPoint, m_selectedSeries);
+ emitNeedRender();
+ }
+ }
+}
+
+void Surface3DController::handleItemChanged(int rowIndex, int columnIndex)
+{
+ QSurfaceDataProxy *sender = static_cast<QSurfaceDataProxy *>(QObject::sender());
+ if (static_cast<QSurface3DSeries *>(m_seriesList.at(0)) == sender->series()) {
+ // 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();
+ }
}
}
diff --git a/src/datavisualization/engine/surface3dcontroller_p.h b/src/datavisualization/engine/surface3dcontroller_p.h
index b9bd60a1..c7496c18 100644
--- a/src/datavisualization/engine/surface3dcontroller_p.h
+++ b/src/datavisualization/engine/surface3dcontroller_p.h
@@ -45,13 +45,15 @@ struct Surface3DChangeBitField {
bool surfaceGridChanged : 1;
bool selectedPointChanged : 1;
bool rowsChanged : 1;
+ bool itemChanged : 1;
Surface3DChangeBitField() :
gradientColorChanged(false), // Set to false, as it is initially set in theme
smoothStatusChanged(true),
surfaceGridChanged(true),
selectedPointChanged(true),
- rowsChanged(true)
+ rowsChanged(false),
+ itemChanged(false)
{
}
};
@@ -67,9 +69,9 @@ private:
QPoint m_selectedPoint;
QSurface3DSeries *m_selectedSeries; // Points to the series for which the point is selected in
// single series selection cases.
- int m_rowsChangeStartId;
- int m_rowsChangeCount;
bool m_flatShadingSupported;
+ QVector<QPoint> m_changedItems;
+ QVector<int> m_changedRows;
public:
explicit Surface3DController(QRect rect);
@@ -100,6 +102,7 @@ public:
public slots:
void handleArrayReset();
void handleRowsChanged(int startIndex, int count);
+ void handleItemChanged(int rowIndex, int columnIndex);
// Renderer callback handlers
void handlePointClicked(const QPoint &position, QSurface3DSeries *series);
diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp
index 4942c4ae..81da15da 100644
--- a/src/datavisualization/engine/surface3drenderer.cpp
+++ b/src/datavisualization/engine/surface3drenderer.cpp
@@ -285,14 +285,8 @@ void Surface3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesLis
}
}
-void Surface3DRenderer::updateRows(int startIndex, int count)
+void Surface3DRenderer::updateRows(const QVector<int> &rows)
{
- // TODO: Properly support non-straight rows and columns (QTRD-2643)
- if (startIndex > m_sampleSpace.height()) {
- // No changes on visible area
- return;
- }
-
// Surface only supports single series for now, so we are only interested in the first series
const QSurfaceDataArray *array = 0;
if (m_visibleSeriesList.size()) {
@@ -306,22 +300,68 @@ void Surface3DRenderer::updateRows(int startIndex, int count)
if (array && array->size() >= 2 && array->at(0)->size() >= 2 &&
m_sampleSpace.width() >= 2 && m_sampleSpace.height() >= 2) {
- int endRow = startIndex + count;
- if (endRow > m_sampleSpace.height())
- endRow = m_sampleSpace.height();
+ bool updateBuffers = false;
+ int sampleSpaceTop = m_sampleSpace.y() + m_sampleSpace.height();
+ foreach (int row, rows) {
+ if (row >= m_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());
+ } else {
+ m_surfaceObj->updateSmoothRow(m_dataArray, row - m_sampleSpace.y(), m_heightNormalizer,
+ m_axisCacheY.min());
+ }
+ }
+ }
+ if (updateBuffers)
+ m_surfaceObj->uploadBuffers();
+ }
+
+ updateSelectedPoint(m_selectedPoint, m_selectedSeries);
+}
- for (int i = startIndex; i < endRow; i++) {
- for (int j = 0; j < m_sampleSpace.width(); j++)
- (*(m_dataArray.at(i)))[j] = array->at(i + m_sampleSpace.y())->at(j + m_sampleSpace.x());
+void Surface3DRenderer::updateItem(const QVector<QPoint> &points)
+{
+ // TODO: Properly support non-straight rows and columns (QTRD-2643)
+
+ // 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());
+ if (m_cachedSurfaceGridOn || m_cachedSurfaceVisible) {
+ QSurfaceDataProxy *dataProxy = firstSeries->dataProxy();
+ if (dataProxy)
+ array = dataProxy->array();
}
+ }
- if (!m_cachedFlatShading) {
- m_surfaceObj->updateSmoothRows(m_dataArray, startIndex, endRow, m_heightNormalizer,
- m_axisCacheY.min());
- } else {
- m_surfaceObj->updateCoarseRows(m_dataArray, startIndex, endRow, m_heightNormalizer,
- m_axisCacheY.min());
+ 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()) {
+ 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());
+
+ if (m_cachedFlatShading) {
+ m_surfaceObj->updateCoarseItem(m_dataArray, y, x, m_heightNormalizer, m_axisCacheY.min());
+ } else {
+ m_surfaceObj->updateSmoothItem(m_dataArray, y, x, m_heightNormalizer, m_axisCacheY.min());
+ }
+ }
}
+ if (updateBuffers)
+ m_surfaceObj->uploadBuffers();
}
updateSelectedPoint(m_selectedPoint, m_selectedSeries);
diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h
index 476ef78e..37adb0b9 100644
--- a/src/datavisualization/engine/surface3drenderer_p.h
+++ b/src/datavisualization/engine/surface3drenderer_p.h
@@ -135,7 +135,8 @@ public:
void updateData();
void updateSeries(const QList<QAbstract3DSeries *> &seriesList, bool updateVisibility);
- void updateRows(int startIndex, int count);
+ void updateRows(const QVector<int> &rows);
+ void updateItem(const QVector<QPoint> &points);
void updateScene(Q3DScene *scene);
bool updateFlatStatus(bool enable);
void updateSurfaceGridStatus(bool enable);
diff --git a/src/datavisualization/utils/surfaceobject.cpp b/src/datavisualization/utils/surfaceobject.cpp
index 81945900..ca23482a 100644
--- a/src/datavisualization/utils/surfaceobject.cpp
+++ b/src/datavisualization/utils/surfaceobject.cpp
@@ -120,8 +120,8 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR
createBuffers(m_vertices, uvs, m_normals, 0, changeGeometry);
}
-void SurfaceObject::updateSmoothRows(const QSurfaceDataArray &dataArray, int startRow,
- int endRow, GLfloat yRange, GLfloat yMin)
+void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowIndex,
+ GLfloat yRange, GLfloat yMin)
{
GLfloat xMin = dataArray.at(0)->at(0).x();
GLfloat zMin = dataArray.at(0)->at(0).z();
@@ -130,64 +130,114 @@ void SurfaceObject::updateSmoothRows(const QSurfaceDataArray &dataArray, int sta
GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f;
// Update vertices
- int totalIndex = startRow * m_columns;
- for (int i = startRow; i < endRow; i++) {
- const QSurfaceDataRow &p = *dataArray.at(i);
- for (int j = 0; j < m_columns; j++) {
- const QSurfaceDataItem &data = p.at(j);
- float normalizedX = ((data.x() - xMin) / xNormalizer);
- float normalizedY = ((data.y() - yMin) / yNormalizer);
- float normalizedZ = ((data.z() - zMin) / zNormalizer);
- m_vertices[totalIndex++] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f);
- }
+ int p = rowIndex * m_columns;
+ const QSurfaceDataRow &dataRow = *dataArray.at(rowIndex);
+ for (int j = 0; j < m_columns; j++) {
+ const QSurfaceDataItem &data = dataRow.at(j);
+ float normalizedX = ((data.x() - xMin) / xNormalizer);
+ float normalizedY = ((data.y() - yMin) / yNormalizer);
+ float normalizedZ = ((data.z() - zMin) / zNormalizer);
+ m_vertices[p++] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f);
}
// Create normals
int colLimit = m_columns - 1;
- int rowColLimit = endRow * m_columns;
- if (endRow == m_rows)
- rowColLimit = (endRow - 1) * m_columns;
- int totalLimit = endRow * m_columns - 1;
-
- totalIndex = startRow * m_columns;
- if (startRow > 0) {
- // Change the normals for the previous row also
- totalIndex -= m_columns;
- }
- if (totalIndex < (m_rows - 1) * m_columns) {
- for (int row = totalIndex; row < rowColLimit; row += m_columns) {
- for (int j = 0; j < colLimit; j++) {
- // One right and one up
- m_normals[totalIndex++] = normal(m_vertices.at(row + j),
- m_vertices.at(row + j + 1),
- m_vertices.at(row + m_columns + j));
- }
- int p = row + colLimit;
- // One up and one left
- m_normals[totalIndex++] = normal(m_vertices.at(p),
- m_vertices.at(p + m_columns),
- m_vertices.at(p - 1));
+ int startRow = rowIndex;
+ if (startRow > 0)
+ startRow--;
+ int totalIndex = startRow * m_columns;
+ int rowLimit = (rowIndex + 1) * m_columns;
+ if (rowIndex == m_rows - 1)
+ rowLimit = rowIndex * m_columns; // The rowIndex is top most row, special handling
+
+ for (int row = totalIndex; row < rowLimit; row += m_columns) {
+ for (int j = 0; j < colLimit; j++) {
+ // One right and one up
+ m_normals[totalIndex++] = normal(m_vertices.at(row + j),
+ m_vertices.at(row + j + 1),
+ m_vertices.at(row + m_columns + j));
}
+ int p = row + colLimit;
+ // One up and one left
+ m_normals[totalIndex++] = normal(m_vertices.at(p),
+ m_vertices.at(p + m_columns),
+ m_vertices.at(p - 1));
}
- if (endRow == m_rows) {
+ if (rowIndex == m_rows - 1) {
// Top most line, nothing above, must have different handling.
// Take from one down and one right. Read till second-to-last
- for (int j = rowColLimit; j < totalLimit; j++) {
+ rowLimit = (rowIndex + 1) * m_columns - 1;
+ for (int j = rowIndex * m_columns; j < rowLimit; j++) {
m_normals[totalIndex++] = normal(m_vertices.at(j),
m_vertices.at(j - m_columns),
m_vertices.at(j + 1));
}
// Top left corner. Take from one left and one down
- m_normals[totalIndex++] = normal(m_vertices.at(totalLimit),
- m_vertices.at(totalLimit - 1),
- m_vertices.at(totalLimit - m_columns));
+ m_normals[totalIndex++] = normal(m_vertices.at(rowLimit),
+ m_vertices.at(rowLimit - 1),
+ m_vertices.at(rowLimit - m_columns));
}
+}
- QVector<QVector2D> uvs; // Empty dummy
- createBuffers(m_vertices, uvs, m_normals, 0, false);
+void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row,
+ int column, GLfloat yRange, GLfloat yMin)
+{
+ GLfloat xMin = dataArray.at(0)->at(0).x();
+ GLfloat zMin = dataArray.at(0)->at(0).z();
+ GLfloat xNormalizer = (dataArray.at(0)->last().x() - xMin) / 2.0f;
+ GLfloat yNormalizer = yRange / 2.0f;
+ GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f;
+
+ // Update a vertice
+ const QSurfaceDataItem &data = dataArray.at(row)->at(column);
+ float normalizedX = ((data.x() - xMin) / xNormalizer);
+ float normalizedY = ((data.y() - yMin) / yNormalizer);
+ float normalizedZ = ((data.z() - zMin) / zNormalizer);
+ m_vertices[row * m_columns + column] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f);
+
+ // Create normals
+ int startRow = row;
+ if (startRow > 0)
+ startRow--; // Change the normal for previous row also
+ int startCol = column;
+ if (startCol > 0)
+ startCol--;
+
+ for (int i = startRow; i <= row; i++) {
+ for (int j = startCol; j <= column; j++) {
+ int p = i * m_columns + j;
+ if (i < m_rows) {
+ if (j < m_columns) {
+ // One right and one up
+ m_normals[p] = normal(m_vertices.at(p),
+ m_vertices.at(p + 1),
+ m_vertices.at(p + m_columns));
+ } else {
+ // Last item, nothing on the right. One up and one left
+ m_normals[p] = normal(m_vertices.at(p),
+ m_vertices.at(p + m_columns),
+ m_vertices.at(p - 1));
+ }
+ } else {
+ // Top most line, nothing above, must have different handling.
+ if (j < m_columns) {
+ // Take from one down and one right. Read till second-to-last
+ m_normals[p] = normal(m_vertices.at(p),
+ m_vertices.at(j - m_columns),
+ m_vertices.at(j + 1));
+ } else {
+ // Top left corner. Take from one left and one down
+ m_normals[p] = normal(m_vertices.at(p),
+ m_vertices.at(p - 1),
+ m_vertices.at(p - m_columns));
+ }
+ }
+ }
+ }
}
+
void SurfaceObject::createSmoothIndices(int x, int y, int endX, int endY)
{
if (endX >= m_columns)
@@ -364,8 +414,8 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s
delete[] indices;
}
-void SurfaceObject::updateCoarseRows(const QSurfaceDataArray &dataArray, int startRow,
- int endRow, GLfloat yRange, GLfloat yMin)
+void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex,
+ GLfloat yRange, GLfloat yMin)
{
GLfloat xMin = dataArray.at(0)->at(0).x();
GLfloat zMin = dataArray.at(0)->at(0).z();
@@ -375,47 +425,95 @@ void SurfaceObject::updateCoarseRows(const QSurfaceDataArray &dataArray, int sta
int colLimit = m_columns - 1;
int doubleColumns = m_columns * 2 - 2;
- int totalIndex = startRow * doubleColumns;
- for (int i = startRow; i < endRow; i++) {
- const QSurfaceDataRow &row = *dataArray.at(i);
- for (int j = 0; j < m_columns; j++) {
- const QSurfaceDataItem &data = row.at(j);
- float normalizedX = ((data.x() - xMin) / xNormalizer);
- float normalizedY = ((data.y() - yMin) / yNormalizer);
- float normalizedZ = ((data.z() - zMin) / zNormalizer);
- m_vertices[totalIndex++] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f);
-
- if (j > 0 && j < colLimit) {
- m_vertices[totalIndex] = m_vertices[totalIndex - 1];
- totalIndex++;
- }
+ int p = rowIndex * doubleColumns;
+ const QSurfaceDataRow &dataRow = *dataArray.at(rowIndex);
+ for (int j = 0; j < m_columns; j++) {
+ const QSurfaceDataItem &data = dataRow.at(j);
+ float normalizedX = ((data.x() - xMin) / xNormalizer);
+ float normalizedY = ((data.y() - yMin) / yNormalizer);
+ float normalizedZ = ((data.z() - zMin) / zNormalizer);
+ m_vertices[p++] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f);
+
+ if (j > 0 && j < colLimit) {
+ m_vertices[p] = m_vertices[p - 1];
+ p++;
}
}
// Create normals
- if (startRow > 0)
- startRow--;
- totalIndex = startRow * doubleColumns;
- int rowColLimit = startRow * doubleColumns;
- for (int row = totalIndex, upperRow = totalIndex + doubleColumns;
- row <= rowColLimit;
+ p = rowIndex * doubleColumns;
+ if (p > 0)
+ p -= doubleColumns;
+ int rowLimit = (rowIndex + 1) * doubleColumns;
+ for (int row = p, upperRow = p + doubleColumns;
+ row < rowLimit;
row += doubleColumns, upperRow += doubleColumns) {
for (int j = 0; j < doubleColumns; j += 2) {
// Normal for the left triangle
- m_normals[totalIndex++] = normal(m_vertices.at(row + j),
- m_vertices.at(row + j + 1),
- m_vertices.at(upperRow + j));
+ m_normals[p++] = normal(m_vertices.at(row + j),
+ m_vertices.at(row + j + 1),
+ m_vertices.at(upperRow + j));
// Normal for the right triangle
- m_normals[totalIndex++] = normal(m_vertices.at(row + j + 1),
- m_vertices.at(upperRow + j + 1),
- m_vertices.at(upperRow + j));
+ m_normals[p++] = normal(m_vertices.at(row + j + 1),
+ m_vertices.at(upperRow + j + 1),
+ m_vertices.at(upperRow + j));
}
}
+}
- QVector<QVector2D> uvs; // Empty dummy
- createBuffers(m_vertices, uvs, m_normals, 0, false);
+void SurfaceObject::updateCoarseItem(const QSurfaceDataArray &dataArray, int row,
+ int column, GLfloat yRange, GLfloat yMin)
+{
+ GLfloat xMin = dataArray.at(0)->at(0).x();
+ GLfloat zMin = dataArray.at(0)->at(0).z();
+ GLfloat xNormalizer = (dataArray.at(0)->last().x() - xMin) / 2.0f;
+ GLfloat yNormalizer = yRange / 2.0f;
+ GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f;
+
+ int colLimit = m_columns - 1;
+ int doubleColumns = m_columns * 2 - 2;
+
+ // Update a vertice
+ int p = row * doubleColumns + column * 2 - (column > 0);
+ const QSurfaceDataItem &data = dataArray.at(row)->at(column);
+ float normalizedX = ((data.x() - xMin) / xNormalizer);
+ float normalizedY = ((data.y() - yMin) / yNormalizer);
+ float normalizedZ = ((data.z() - zMin) / zNormalizer);
+ m_vertices[p] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f);
+ p++;
+
+ if (column > 0 && column < colLimit)
+ m_vertices[p] = m_vertices[p - 1];
+
+ // Create normals
+ int startRow = row;
+ if (startRow > 0)
+ startRow--; // Change the normal for previous row also
+ int startCol = column;
+ if (startCol > 0)
+ startCol--;
+ if (row == m_rows - 1)
+ row--;
+ if (column == m_columns - 1)
+ column--;
+
+ for (int i = startRow; i <= row; i++) {
+ for (int j = startCol; j <= column; j++) {
+ p = i * doubleColumns + j * 2;
+ // Normal for the left triangle
+ m_normals[p] = normal(m_vertices.at(p),
+ m_vertices.at(p + 1),
+ m_vertices.at(p + doubleColumns));
+ p++;
+
+ // Normal for the right triangle
+ m_normals[p] = normal(m_vertices.at(p),
+ m_vertices.at(p + doubleColumns),
+ m_vertices.at(p + doubleColumns - 1));
+ }
+ }
}
void SurfaceObject::createCoarseIndices(int x, int y, int columns, int rows)
@@ -511,6 +609,12 @@ void SurfaceObject::createCoarseGridlineIndices(int x, int y, int endX, int endY
delete[] gridIndices;
}
+void SurfaceObject::uploadBuffers()
+{
+ QVector<QVector2D> uvs; // Empty dummy
+ createBuffers(m_vertices, uvs, m_normals, 0, false);
+}
+
void SurfaceObject::createBuffers(const QVector<QVector3D> &vertices, const QVector<QVector2D> &uvs,
const QVector<QVector3D> &normals, const GLint *indices,
bool changeGeometry)
diff --git a/src/datavisualization/utils/surfaceobject_p.h b/src/datavisualization/utils/surfaceobject_p.h
index 895fd3eb..e035d905 100644
--- a/src/datavisualization/utils/surfaceobject_p.h
+++ b/src/datavisualization/utils/surfaceobject_p.h
@@ -48,14 +48,19 @@ public:
GLfloat yMin, bool changeGeometry);
void setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange,
GLfloat yMin, bool changeGeometry);
- void updateCoarseRows(const QSurfaceDataArray &dataArray, int startRow,
- int endRow, GLfloat yRange, GLfloat yMin);
- void updateSmoothRows(const QSurfaceDataArray &dataArray, int startRow,
- int endRow, GLfloat yRange, GLfloat yMin);
+ void updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex,
+ GLfloat yRange, GLfloat yMin);
+ void updateSmoothRow(const QSurfaceDataArray &dataArray, int startRow,
+ GLfloat yRange, GLfloat yMin);
+ void updateSmoothItem(const QSurfaceDataArray &dataArray, int row,
+ int column, GLfloat yRange, GLfloat yMin);
+ void updateCoarseItem(const QSurfaceDataArray &dataArray, int row,
+ int column, GLfloat yRange, GLfloat yMin);
void createSmoothIndices(int x, int y, int endX, int endY);
void createCoarseIndices(int x, int y, int columns, int rows);
void createSmoothGridlineIndices(int x, int y, int endX, int endY);
void createCoarseGridlineIndices(int x, int y, int endX, int endY);
+ void uploadBuffers();
GLuint gridElementBuf();
GLuint gridIndexCount();
QVector3D vertexAt(int column, int row);