mirror of https://github.com/qt/qtdatavis3d.git
Multiseries support for surface
Multiseries support for item and row changes. Task-number: QTRD-2767 Change-Id: I5702989e7f59913481a2ca888e402effa22a4221 Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
This commit is contained in:
parent
61c84e2d9c
commit
51ad2b7e53
|
|
@ -322,29 +322,29 @@ 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;
|
||||
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();
|
||||
}
|
||||
adjustValueAxisRange();
|
||||
// Clear selection unless still valid
|
||||
setSelectedPoint(m_selectedPoint, m_selectedSeries, false);
|
||||
emitNeedRender();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -352,26 +352,25 @@ 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, false);
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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,8 @@ 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:
|
||||
|
|
|
|||
|
|
@ -45,18 +45,12 @@ 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),
|
||||
|
|
@ -84,7 +78,6 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
|
|||
m_backgroundObj(0),
|
||||
m_gridLineObj(0),
|
||||
m_labelObj(0),
|
||||
m_surfaceObj(0),
|
||||
m_depthTexture(0),
|
||||
m_depthModelTexture(0),
|
||||
m_depthFrameBuffer(0),
|
||||
|
|
@ -92,16 +85,13 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
|
|||
m_selectionDepthBuffer(0),
|
||||
m_selectionResultTexture(0),
|
||||
m_shadowQualityToShader(33.3f),
|
||||
m_cachedFlatShading(false),
|
||||
m_flatSupported(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),
|
||||
|
|
@ -318,81 +308,86 @@ void Surface3DRenderer::modifiedSeriesList(const QVector<QSurface3DSeries *> &se
|
|||
}
|
||||
}
|
||||
|
||||
void Surface3DRenderer::updateRows(const QVector<int> &rows)
|
||||
void Surface3DRenderer::updateRows(const QVector<Surface3DController::ChangeRow> &rows)
|
||||
{
|
||||
// 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::ChangeRow item, rows) {
|
||||
SurfaceSeriesRenderCache *cache = m_renderCacheList.value(item.series);
|
||||
QSurfaceDataArray &dstArray = cache->dataArray();
|
||||
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) {
|
||||
bool updateBuffers = false;
|
||||
int sampleSpaceTop = m_sampleSpace.y() + m_sampleSpace.height();
|
||||
foreach (int row, rows) {
|
||||
if (row >= m_sampleSpace.y() && row <= sampleSpaceTop) {
|
||||
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());
|
||||
for (int j = 0; j < sampleSpace.width(); j++) {
|
||||
(*(dstArray.at(row - sampleSpace.y())))[j] =
|
||||
srcArray->at(row)->at(j + sampleSpace.x());
|
||||
}
|
||||
|
||||
if (m_cachedFlatShading) {
|
||||
m_surfaceObj->updateCoarseRow(m_dataArray, row - m_sampleSpace.y(),
|
||||
m_heightNormalizer,
|
||||
m_axisCacheY.min());
|
||||
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();
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -48,13 +48,6 @@ 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;
|
||||
|
||||
|
|
@ -85,7 +78,6 @@ private:
|
|||
ObjectHelper *m_backgroundObj;
|
||||
ObjectHelper *m_gridLineObj;
|
||||
ObjectHelper *m_labelObj;
|
||||
SurfaceObject *m_surfaceObj;
|
||||
GLuint m_depthTexture;
|
||||
GLuint m_depthModelTexture;
|
||||
GLuint m_depthFrameBuffer;
|
||||
|
|
@ -93,7 +85,6 @@ private:
|
|||
GLuint m_selectionDepthBuffer;
|
||||
GLuint m_selectionResultTexture;
|
||||
GLfloat m_shadowQualityToShader;
|
||||
bool m_cachedFlatShading;
|
||||
bool m_flatSupported;
|
||||
SelectionPointer *m_selectionPointer;
|
||||
bool m_selectionActive;
|
||||
|
|
@ -101,15 +92,11 @@ private:
|
|||
bool m_zFlipped;
|
||||
bool m_yFlipped;
|
||||
AbstractRenderItem m_dummyRenderItem;
|
||||
QSurfaceDataArray m_dataArray;
|
||||
QRect m_sampleSpace;
|
||||
GLint m_shadowQualityMultiplier;
|
||||
QSizeF m_areaSize;
|
||||
uint m_clickedPointId;
|
||||
bool m_hasHeightAdjustmentChanged;
|
||||
QPoint m_selectedPoint;
|
||||
const QSurface3DSeries *m_selectedSeries;
|
||||
QVector3D m_uniformGradientTextureColor;
|
||||
QPoint m_clickedPosition;
|
||||
QHash<QSurface3DSeries *, SurfaceSeriesRenderCache *> m_renderCacheList;
|
||||
bool m_selectionTexturesDirty;
|
||||
|
|
@ -123,8 +110,8 @@ public:
|
|||
void updateSeries(const QList<QAbstract3DSeries *> &seriesList, bool updateVisibility);
|
||||
void updateSelectionMode(QAbstract3DGraph::SelectionFlags mode);
|
||||
void modifiedSeriesList(const QVector<QSurface3DSeries *> &seriesList);
|
||||
void updateRows(const QVector<int> &rows);
|
||||
void updateItem(const QVector<QPoint> &points);
|
||||
void updateRows(const QVector<Surface3DController::ChangeRow> &rows);
|
||||
void updateItem(const QVector<Surface3DController::ChangeItem> &points);
|
||||
void updateScene(Q3DScene *scene);
|
||||
void updateSlicingActive(bool isSlicing);
|
||||
void updateSelectedPoint(const QPoint &position, const QSurface3DSeries *series);
|
||||
|
|
|
|||
|
|
@ -122,9 +122,9 @@ void GraphModifier::fillSeries()
|
|||
QSurfaceDataRow *newRow3 = new QSurfaceDataRow(m_xCount);
|
||||
QSurfaceDataRow *newRow4 = new QSurfaceDataRow(m_xCount);
|
||||
|
||||
float z = float(i) - m_limitZ + 0.5f;
|
||||
for (int j = 0; j < m_xCount; j++) {
|
||||
float x = float(j) - m_limitX + 0.5f;
|
||||
float z = float(i) - m_limitZ + 0.5f;
|
||||
float angle = (z * x) / float(full) * 1.57f;
|
||||
(*newRow1)[j].setPosition(QVector3D(x, qSin(angle), z));
|
||||
angle *= 1.3f;
|
||||
|
|
@ -701,10 +701,39 @@ void GraphModifier::changeRow()
|
|||
|
||||
m_theSeries->dataProxy()->setRow(int(i), newRow);
|
||||
} else {
|
||||
#ifdef MULTI_SERIES
|
||||
static int changeRowSeries = 0;
|
||||
qDebug() << "Generating new values to a row at random pos for series " << changeRowSeries;
|
||||
|
||||
int row = rand() % m_zCount;
|
||||
QSurfaceDataRow *newRow = createMultiRow(row, changeRowSeries);
|
||||
m_multiseries[changeRowSeries]->dataProxy()->setRow(row, newRow);
|
||||
|
||||
changeRowSeries++;
|
||||
if (changeRowSeries > 3)
|
||||
changeRowSeries = 0;
|
||||
#else
|
||||
qDebug() << "Change row function active only for SqrtSin";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
QSurfaceDataRow *GraphModifier::createMultiRow(int row, int series)
|
||||
{
|
||||
int full = m_limitX * m_limitZ;
|
||||
float i = float(row);
|
||||
QSurfaceDataRow *newRow = new QSurfaceDataRow(m_xCount);
|
||||
float z = float(i) - m_limitZ + 0.5f;
|
||||
for (int j = 0; j < m_xCount; j++) {
|
||||
float x = float(j) - m_limitX + 0.5f;
|
||||
float angle = (z * x) / float(full) * 1.57f;
|
||||
float y = qSin(angle * float(qPow(1.3f, series))) + 0.2f + 1.1f *series;
|
||||
(*newRow)[j].setPosition(QVector3D(x, y, z));
|
||||
}
|
||||
|
||||
return newRow;
|
||||
}
|
||||
|
||||
void GraphModifier::changeRows()
|
||||
{
|
||||
if (m_activeSample == GraphModifier::SqrtSin) {
|
||||
|
|
@ -734,7 +763,24 @@ void GraphModifier::changeRows()
|
|||
|
||||
m_theSeries->dataProxy()->setRows(int(start), dataArray);
|
||||
} else {
|
||||
#ifdef MULTI_SERIES
|
||||
static int changeRowSeries = 0;
|
||||
qDebug() << "Generating new values for 3 rows at random pos for series " << changeRowSeries;
|
||||
|
||||
int row = rand() % (m_zCount - 3);
|
||||
QSurfaceDataArray dataArray;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
QSurfaceDataRow *newRow = createMultiRow(row + i, changeRowSeries);
|
||||
dataArray.append(newRow);
|
||||
}
|
||||
m_multiseries[changeRowSeries]->dataProxy()->setRows(row, dataArray);
|
||||
|
||||
changeRowSeries++;
|
||||
if (changeRowSeries > 3)
|
||||
changeRowSeries = 0;
|
||||
#else
|
||||
qDebug() << "Change row function active only for SqrtSin";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -759,7 +805,23 @@ void GraphModifier::changeItem()
|
|||
|
||||
m_theSeries->dataProxy()->setItem(int(i), int(j), newItem);
|
||||
} else {
|
||||
qDebug() << "Change row function active only for SqrtSin";
|
||||
#ifdef MULTI_SERIES
|
||||
static int changeItemSeries = 0;
|
||||
int full = m_limitX * m_limitZ;
|
||||
float i = float(rand() % m_zCount);
|
||||
float j = float(rand() % m_xCount);
|
||||
float x = float(j) - m_limitX + 0.5f;
|
||||
float z = float(i) - m_limitZ + 0.5f;
|
||||
float angle = (z * x) / float(full) * 1.57f;
|
||||
float y = qSin(angle * float(qPow(1.3f, changeItemSeries))) + 0.2f + 1.1f *changeItemSeries;
|
||||
QSurfaceDataItem newItem(QVector3D(x, y, z));
|
||||
m_multiseries[changeItemSeries]->dataProxy()->setItem(int(i), int(j), newItem);
|
||||
changeItemSeries++;
|
||||
if (changeItemSeries > 3)
|
||||
changeItemSeries = 0;
|
||||
#else
|
||||
qDebug() << "Change item function active only for SqrtSin";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ private:
|
|||
void fillSeries();
|
||||
void resetArrayAndSliders(QSurfaceDataArray *array, float minZ, float maxZ, float minX,
|
||||
float maxX);
|
||||
QSurfaceDataRow *createMultiRow(int row, int series);
|
||||
|
||||
Q3DSurface *m_graph;
|
||||
QSurface3DSeries *m_multiseries[4];
|
||||
|
|
|
|||
Loading…
Reference in New Issue