diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/datavisualization/engine/bars3dcontroller.cpp | 81 | ||||
-rw-r--r-- | src/datavisualization/engine/bars3dcontroller_p.h | 18 | ||||
-rw-r--r-- | src/datavisualization/engine/bars3drenderer.cpp | 168 | ||||
-rw-r--r-- | src/datavisualization/engine/bars3drenderer_p.h | 6 | ||||
-rw-r--r-- | src/datavisualization/engine/scatter3drenderer.cpp | 6 | ||||
-rw-r--r-- | src/datavisualization/engine/surface3dcontroller.cpp | 35 | ||||
-rw-r--r-- | src/datavisualization/engine/surface3drenderer.cpp | 19 | ||||
-rw-r--r-- | src/datavisualization/engine/surface3drenderer_p.h | 2 |
8 files changed, 235 insertions, 100 deletions
diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp index 38870115..99fa8223 100644 --- a/src/datavisualization/engine/bars3dcontroller.cpp +++ b/src/datavisualization/engine/bars3dcontroller.cpp @@ -83,6 +83,18 @@ void Bars3DController::synchDataToRenderer() Abstract3DController::synchDataToRenderer(); // Notify changes to renderer + if (m_changeTracker.rowsChanged) { + m_renderer->updateRows(m_changedRows); + m_changeTracker.rowsChanged = false; + m_changedRows.clear(); + } + + if (m_changeTracker.itemChanged) { + m_renderer->updateItems(m_changedItems); + m_changeTracker.itemChanged = false; + m_changedItems.clear(); + } + if (m_changeTracker.multiSeriesScalingChanged) { m_renderer->updateMultiSeriesScaling(m_isMultiSeriesUniform); m_changeTracker.multiSeriesScalingChanged = false; @@ -131,17 +143,39 @@ void Bars3DController::handleRowsAdded(int startIndex, int count) void Bars3DController::handleRowsChanged(int startIndex, int count) { - Q_UNUSED(startIndex) - Q_UNUSED(count) QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series(); - if (series->isVisible()) { - adjustAxisRanges(); - m_isDataDirty = true; - series->d_ptr->markItemLabelDirty(); + int oldChangeCount = m_changedRows.size(); + if (!oldChangeCount) + m_changedRows.reserve(count); + + int selectedRow = m_selectedBar.x(); + for (int i = 0; i < count; i++) { + bool newItem = true; + int candidate = startIndex + i; + for (int j = 0; j < oldChangeCount; j++) { + const ChangeRow &oldChangeItem = m_changedRows.at(j); + if (oldChangeItem.row == candidate && series == oldChangeItem.series) { + newItem = false; + break; + } + } + if (newItem) { + ChangeRow newChangeItem = {series, candidate}; + m_changedRows.append(newChangeItem); + if (series == m_selectedBarSeries && selectedRow == candidate) + series->d_ptr->markItemLabelDirty(); + } + } + if (count) { + m_changeTracker.rowsChanged = true; + + if (series->isVisible()) + adjustAxisRanges(); + + // Clear selection unless still valid (row length might have changed) + setSelectedBar(m_selectedBar, m_selectedBarSeries, false); + emitNeedRender(); } - if (!m_changedSeriesList.contains(series)) - m_changedSeriesList.append(series); - emitNeedRender(); } void Bars3DController::handleRowsRemoved(int startIndex, int count) @@ -199,17 +233,28 @@ void Bars3DController::handleRowsInserted(int startIndex, int count) void Bars3DController::handleItemChanged(int rowIndex, int columnIndex) { - Q_UNUSED(rowIndex) - Q_UNUSED(columnIndex) QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series(); - if (series->isVisible()) { - adjustAxisRanges(); - m_isDataDirty = true; - series->d_ptr->markItemLabelDirty(); + + bool newItem = true; + QPoint candidate(rowIndex, columnIndex); + 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; + + if (series == m_selectedBarSeries && m_selectedBar == candidate) + series->d_ptr->markItemLabelDirty(); + if (series->isVisible()) + adjustAxisRanges(); + emitNeedRender(); } - if (!m_changedSeriesList.contains(series)) - m_changedSeriesList.append(series); - emitNeedRender(); } void Bars3DController::handleDataRowLabelsChanged() diff --git a/src/datavisualization/engine/bars3dcontroller_p.h b/src/datavisualization/engine/bars3dcontroller_p.h index 33928306..00eda402 100644 --- a/src/datavisualization/engine/bars3dcontroller_p.h +++ b/src/datavisualization/engine/bars3dcontroller_p.h @@ -42,12 +42,16 @@ struct Bars3DChangeBitField { bool multiSeriesScalingChanged : 1; bool barSpecsChanged : 1; bool selectedBarChanged : 1; + bool rowsChanged : 1; + bool itemChanged : 1; Bars3DChangeBitField() : slicingActiveChanged(true), multiSeriesScalingChanged(true), barSpecsChanged(true), - selectedBarChanged(true) + selectedBarChanged(true), + rowsChanged(false), + itemChanged(false) { } }; @@ -56,8 +60,20 @@ class QT_DATAVISUALIZATION_EXPORT Bars3DController : public Abstract3DController { Q_OBJECT +public: + struct ChangeItem { + QBar3DSeries *series; + QPoint point; + }; + struct ChangeRow { + QBar3DSeries *series; + int row; + }; + private: Bars3DChangeBitField m_changeTracker; + QVector<ChangeItem> m_changedItems; + QVector<ChangeRow> m_changedRows; // Interaction QPoint m_selectedBar; // Points to row & column in data window. diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index 01fcebb2..ec1f0c7e 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -95,7 +95,8 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) m_clickedPosition(Bars3DController::invalidSelectionPosition()), m_keepSeriesUniform(false), m_haveUniformColorSeries(false), - m_haveGradientSeries(false) + m_haveGradientSeries(false), + m_zeroPosition(0.0f) { m_axisCacheY.setScale(2.0f); m_axisCacheY.setTranslate(-1.0f); @@ -159,7 +160,6 @@ void Bars3DRenderer::updateData() int maxCol = m_axisCacheX.max(); int newRows = maxRow - minRow + 1; int newColumns = maxCol - minCol + 1; - int updateSize = 0; int dataRowCount = 0; int maxDataRowCount = 0; @@ -187,8 +187,7 @@ void Bars3DRenderer::updateData() calculateSceneScalingFactors(); } - const QValue3DAxisFormatter *axisFormatter = m_axisCacheY.formatter(); - float zeroPosition = axisFormatter->positionAt(0.0f); + m_zeroPosition = m_axisCacheY.formatter()->positionAt(0.0f); foreach (SeriesRenderCache *baseCache, m_renderCacheList) { BarSeriesRenderCache *cache = static_cast<BarSeriesRenderCache *>(baseCache); @@ -212,50 +211,12 @@ void Bars3DRenderer::updateData() if (maxDataRowCount < dataRowCount) maxDataRowCount = qMin(dataRowCount, newRows); int dataRowIndex = minRow; - GLfloat heightValue = 0.0f; for (int i = 0; i < newRows; i++) { - int j = 0; BarRenderItemRow &renderRow = renderArray[i]; - if (dataRowIndex < dataRowCount) { - const QBarDataRow *dataRow = dataProxy->rowAt(dataRowIndex); - updateSize = qMin((dataRow->size() - minCol), renderRow.size()); - if (dataRow) { - int dataColIndex = minCol; - for (; j < updateSize ; j++) { - float value = dataRow->at(dataColIndex).value(); - heightValue = axisFormatter->positionAt(value); - if (m_noZeroInRange) { - if (m_hasNegativeValues) { - heightValue = -1.0f + heightValue; - if (heightValue > 0.0f) - heightValue = 0.0f; - } else { - if (heightValue < 0.0f) - heightValue = 0.0f; - } - } else { - heightValue -= zeroPosition; - } - renderRow[j].setValue(value); - renderRow[j].setHeight(heightValue); - - float angle = dataRow->at(dataColIndex).rotation(); - if (angle) { - renderRow[j].setRotation( - QQuaternion::fromAxisAndAngle( - upVector, angle)); - } else { - renderRow[j].setRotation(identityQuaternion); - } - dataColIndex++; - } - } - } - for (; j < newColumns; j++) { - renderRow[j].setValue(0.0f); - renderRow[j].setHeight(0.0f); - renderRow[j].setRotation(identityQuaternion); - } + const QBarDataRow *dataRow = 0; + if (dataRowIndex < dataRowCount) + dataRow = dataProxy->rowAt(dataRowIndex); + updateRenderRow(dataRow, renderRow); dataRowIndex++; } cache->setDataDirty(false); @@ -268,6 +229,56 @@ void Bars3DRenderer::updateData() m_selectedSeriesCache ? m_selectedSeriesCache->series() : 0); } +void Bars3DRenderer::updateRenderRow(const QBarDataRow *dataRow, BarRenderItemRow &renderRow) +{ + int j = 0; + int renderRowSize = renderRow.size(); + int startIndex = m_axisCacheX.min(); + + if (dataRow) { + int updateSize = qMin((dataRow->size() - startIndex), renderRowSize); + int dataColIndex = startIndex; + for (; j < updateSize ; j++) { + updateRenderItem(dataRow->at(dataColIndex), renderRow[j]); + dataColIndex++; + } + } + for (; j < renderRowSize; j++) { + renderRow[j].setValue(0.0f); + renderRow[j].setHeight(0.0f); + renderRow[j].setRotation(identityQuaternion); + } +} + +void Bars3DRenderer::updateRenderItem(const QBarDataItem &dataItem, BarRenderItem &renderItem) +{ + float value = dataItem.value(); + float heightValue = m_axisCacheY.formatter()->positionAt(value); + if (m_noZeroInRange) { + if (m_hasNegativeValues) { + heightValue = -1.0f + heightValue; + if (heightValue > 0.0f) + heightValue = 0.0f; + } else { + if (heightValue < 0.0f) + heightValue = 0.0f; + } + } else { + heightValue -= m_zeroPosition; + } + renderItem.setValue(value); + renderItem.setHeight(heightValue); + + float angle = dataItem.rotation(); + if (angle) { + renderItem.setRotation( + QQuaternion::fromAxisAndAngle( + upVector, angle)); + } else { + renderItem.setRotation(identityQuaternion); + } +} + void Bars3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList) { Abstract3DRenderer::updateSeries(seriesList); @@ -283,9 +294,9 @@ void Bars3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList) BarSeriesRenderCache *cache = static_cast<BarSeriesRenderCache *>(m_renderCacheList.value(barSeries)); if (noSelection - && barSeries->selectedBar() != QBar3DSeries::invalidSelectionPosition() - && selectionLabel() != cache->itemLabel()) { - m_selectionLabelDirty = true; + && barSeries->selectedBar() != QBar3DSeries::invalidSelectionPosition()) { + if (selectionLabel() != cache->itemLabel()) + m_selectionLabelDirty = true; noSelection = false; } cache->setVisualIndex(visualIndex++); @@ -304,6 +315,65 @@ SeriesRenderCache *Bars3DRenderer::createNewCache(QAbstract3DSeries *series) return new BarSeriesRenderCache(series, this); } +void Bars3DRenderer::updateRows(const QVector<Bars3DController::ChangeRow> &rows) +{ + int minRow = m_axisCacheZ.min(); + int maxRow = m_axisCacheZ.max(); + BarSeriesRenderCache *cache = 0; + const QBar3DSeries *prevSeries = 0; + const QBarDataArray *dataArray = 0; + + foreach (Bars3DController::ChangeRow item, rows) { + const int row = item.row; + if (row < minRow || row > maxRow) + continue; + QBar3DSeries *currentSeries = item.series; + if (currentSeries != prevSeries) { + cache = static_cast<BarSeriesRenderCache *>(m_renderCacheList.value(currentSeries)); + prevSeries = currentSeries; + dataArray = item.series->dataProxy()->array(); + // Invisible series render caches are not updated, but instead just marked dirty, so that + // they can be completely recalculated when they are turned visible. + if (!cache->isVisible() && !cache->dataDirty()) + cache->setDataDirty(true); + } + if (cache->isVisible()) + updateRenderRow(dataArray->at(row), cache->renderArray()[row - minRow]); + } +} + +void Bars3DRenderer::updateItems(const QVector<Bars3DController::ChangeItem> &points) +{ + int minRow = m_axisCacheZ.min(); + int maxRow = m_axisCacheZ.max(); + int minCol = m_axisCacheX.min(); + int maxCol = m_axisCacheX.max(); + BarSeriesRenderCache *cache = 0; + const QBar3DSeries *prevSeries = 0; + const QBarDataArray *dataArray = 0; + + foreach (Bars3DController::ChangeItem item, points) { + const int row = item.point.x(); + const int col = item.point.y(); + if (row < minRow || row > maxRow || col < minCol || col > maxCol) + continue; + QBar3DSeries *currentSeries = item.series; + if (currentSeries != prevSeries) { + cache = static_cast<BarSeriesRenderCache *>(m_renderCacheList.value(currentSeries)); + prevSeries = currentSeries; + dataArray = item.series->dataProxy()->array(); + // Invisible series render caches are not updated, but instead just marked dirty, so that + // they can be completely recalculated when they are turned visible. + if (!cache->isVisible() && !cache->dataDirty()) + cache->setDataDirty(true); + } + if (cache->isVisible()) { + updateRenderItem(dataArray->at(row)->at(col), + cache->renderArray()[row - minRow][col - minCol]); + } + } +} + void Bars3DRenderer::updateScene(Q3DScene *scene) { if (m_hasNegativeValues) diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h index ca0e690e..ddea546e 100644 --- a/src/datavisualization/engine/bars3drenderer_p.h +++ b/src/datavisualization/engine/bars3drenderer_p.h @@ -108,6 +108,7 @@ private: bool m_keepSeriesUniform; bool m_haveUniformColorSeries; bool m_haveGradientSeries; + float m_zeroPosition; public: explicit Bars3DRenderer(Bars3DController *controller); @@ -116,6 +117,8 @@ public: void updateData(); void updateSeries(const QList<QAbstract3DSeries *> &seriesList); SeriesRenderCache *createNewCache(QAbstract3DSeries *series); + void updateRows(const QVector<Bars3DController::ChangeRow> &rows); + void updateItems(const QVector<Bars3DController::ChangeItem> &points); void updateScene(Q3DScene *scene); void render(GLuint defaultFboHandle = 0); @@ -169,6 +172,9 @@ private: QPoint selectionColorToArrayPosition(const QVector4D &selectionColor); QBar3DSeries *selectionColorToSeries(const QVector4D &selectionColor); + inline void updateRenderRow(const QBarDataRow *dataRow, BarRenderItemRow &renderRow); + inline void updateRenderItem(const QBarDataItem &dataItem, BarRenderItem &renderItem); + Q_DISABLE_COPY(Bars3DRenderer) friend class BarRenderItem; diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index 5d37e6e1..3f91e9c3 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -240,9 +240,9 @@ void Scatter3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesLis if (cache->itemSize() != itemSize) cache->setItemSize(itemSize); if (noSelection - && scatterSeries->selectedItem() != QScatter3DSeries::invalidSelectionIndex() - && m_selectionLabel != cache->itemLabel()) { - m_selectionLabelDirty = true; + && scatterSeries->selectedItem() != QScatter3DSeries::invalidSelectionIndex()) { + if (m_selectionLabel != cache->itemLabel()) + m_selectionLabelDirty = true; noSelection = false; } diff --git a/src/datavisualization/engine/surface3dcontroller.cpp b/src/datavisualization/engine/surface3dcontroller.cpp index 591cbdda..6f27c7df 100644 --- a/src/datavisualization/engine/surface3dcontroller.cpp +++ b/src/datavisualization/engine/surface3dcontroller.cpp @@ -76,7 +76,7 @@ void Surface3DController::synchDataToRenderer() } if (m_changeTracker.itemChanged) { - m_renderer->updateItem(m_changedItems); + m_renderer->updateItems(m_changedItems); m_changeTracker.itemChanged = false; m_changedItems.clear(); } @@ -309,36 +309,34 @@ 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()); - - QSurface3DSeries *series = sender->series(); + QSurface3DSeries *series = static_cast<QSurfaceDataProxy *>(QObject::sender())->series(); int oldChangeCount = m_changedRows.size(); + if (!oldChangeCount) + m_changedRows.reserve(count); + int selectedRow = m_selectedPoint.x(); 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) { + for (int j = 0; j < oldChangeCount; j++) { + const ChangeRow &oldChangeItem = m_changedRows.at(j); + if (oldChangeItem.row == candidate && series == oldChangeItem.series) { newItem = false; break; } } if (newItem) { - ChangeRow newItem = {series, candidate}; - m_changedRows.append(newItem); + ChangeRow newChangeItem = {series, candidate}; + m_changedRows.append(newChangeItem); if (series == m_selectedSeries && selectedRow == candidate) series->d_ptr->markItemLabelDirty(); } } - if (m_changedRows.size()) { + if (count) { m_changeTracker.rowsChanged = true; - adjustAxisRanges(); - // Clear selection unless still valid - setSelectedPoint(m_selectedPoint, m_selectedSeries, false); + if (series->isVisible()) + adjustAxisRanges(); emitNeedRender(); } } @@ -349,7 +347,7 @@ void Surface3DController::handleItemChanged(int rowIndex, int columnIndex) QSurface3DSeries *series = sender->series(); bool newItem = true; - QPoint candidate(columnIndex, rowIndex); + QPoint candidate(rowIndex, columnIndex); foreach (ChangeItem item, m_changedItems) { if (item.point == candidate && item.series == series) { newItem = false; @@ -364,9 +362,8 @@ void Surface3DController::handleItemChanged(int rowIndex, int columnIndex) if (series == m_selectedSeries && m_selectedPoint == candidate) series->d_ptr->markItemLabelDirty(); - adjustAxisRanges(); - // Clear selection unless still valid - setSelectedPoint(m_selectedPoint, m_selectedSeries, false); + if (series->isVisible()) + adjustAxisRanges(); emitNeedRender(); } } diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index f04277f7..198a034d 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -256,9 +256,9 @@ void Surface3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesLis SurfaceSeriesRenderCache *cache = static_cast<SurfaceSeriesRenderCache *>( m_renderCacheList.value(series)); if (noSelection - && surfaceSeries->selectedPoint() != QSurface3DSeries::invalidSelectionPosition() - && selectionLabel() != cache->itemLabel()) { - m_selectionLabelDirty = true; + && surfaceSeries->selectedPoint() != QSurface3DSeries::invalidSelectionPosition()) { + if (selectionLabel() != cache->itemLabel()) + m_selectionLabelDirty = true; noSelection = false; } @@ -346,7 +346,7 @@ void Surface3DRenderer::updateRows(const QVector<Surface3DController::ChangeRow> updateSelectedPoint(m_selectedPoint, m_selectedSeries); } -void Surface3DRenderer::updateItem(const QVector<Surface3DController::ChangeItem> &points) +void Surface3DRenderer::updateItems(const QVector<Surface3DController::ChangeItem> &points) { foreach (Surface3DController::ChangeItem item, points) { SurfaceSeriesRenderCache *cache = @@ -364,14 +364,15 @@ void Surface3DRenderer::updateItem(const QVector<Surface3DController::ChangeItem int sampleSpaceTop = sampleSpace.y() + sampleSpace.height(); int sampleSpaceRight = sampleSpace.x() + sampleSpace.width(); bool updateBuffers = false; + // Note: Point is (row, column), samplespace is (columns x rows) QPoint point = item.point; - if (point.y() <= sampleSpaceTop && point.y() >= sampleSpace.y() && - point.x() <= sampleSpaceRight && point.x() >= sampleSpace.x()) { + if (point.x() <= sampleSpaceTop && point.x() >= sampleSpace.y() && + point.y() <= sampleSpaceRight && point.y() >= sampleSpace.x()) { updateBuffers = true; - int x = point.x() - sampleSpace.x(); - int y = point.y() - sampleSpace.y(); - (*(dstArray.at(y)))[x] = srcArray->at(point.y())->at(point.x()); + int x = point.y() - sampleSpace.x(); + int y = point.x() - sampleSpace.y(); + (*(dstArray.at(y)))[x] = srcArray->at(point.x())->at(point.y()); if (cache->isFlatShadingEnabled()) cache->surfaceObject()->updateCoarseItem(dstArray, y, x); diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h index 0cd4502a..db46a17b 100644 --- a/src/datavisualization/engine/surface3drenderer_p.h +++ b/src/datavisualization/engine/surface3drenderer_p.h @@ -110,7 +110,7 @@ public: void cleanCache(SeriesRenderCache *cache); void updateSelectionMode(QAbstract3DGraph::SelectionFlags mode); void updateRows(const QVector<Surface3DController::ChangeRow> &rows); - void updateItem(const QVector<Surface3DController::ChangeItem> &points); + void updateItems(const QVector<Surface3DController::ChangeItem> &points); void updateScene(Q3DScene *scene); void updateSlicingActive(bool isSlicing); void updateSelectedPoint(const QPoint &position, QSurface3DSeries *series); |