From 6889a543a32df1b802ffc9c48609310aa72f03d3 Mon Sep 17 00:00:00 2001 From: Mika Salmela Date: Wed, 2 Oct 2013 13:21:58 +0300 Subject: Surface slice view back again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When constructing slice view, x&z coordinates are copied also. Point position set to vertex position, which is more robust. Task-number: QTRD-2363 Change-Id: Ifbee1bbdfa9a7575760116433204d9cea9a908aa Reviewed-by: Tomi Korpipää Reviewed-by: Miikka Heikkinen --- src/datavisualization/engine/surface3drenderer.cpp | 42 +++++------ src/datavisualization/engine/surface3drenderer_p.h | 1 - src/datavisualization/utils/surfaceobject.cpp | 88 +++++++++++++--------- src/datavisualization/utils/surfaceobject_p.h | 10 ++- 4 files changed, 78 insertions(+), 63 deletions(-) (limited to 'src/datavisualization') diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index 4501c126..e794f2a7 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -272,17 +272,26 @@ void Surface3DRenderer::updateSliceDataModel(int selectionId) QSurfaceDataRow *sliceRow; if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow) { - sliceRow = new QSurfaceDataRow(*m_dataArray.at(row)); + QSurfaceDataRow *src = m_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(), -1.0)); } else if (m_cachedSelectionMode == QDataVis::SelectionModeSliceColumn) { - sliceRow = new QSurfaceDataRow(); - sliceRow->resize(m_sampleSpace.height()); - for (int i = 0; i < m_sampleSpace.height(); i++) - (*sliceRow)[i] = m_dataArray.at(i)->at(column); + 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(), + -1.0)); + } } + m_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(), 1.0)); + m_sliceDataArray << duplicateRow; QRect sliceRect(0, 0, sliceRow->size(), 2); @@ -292,8 +301,8 @@ void Surface3DRenderer::updateSliceDataModel(int selectionId) loadSliceSurfaceObj(); if (m_cachedSmoothSurface) { - m_sliceSurfaceObj->setUpSmoothData(m_sliceDataArray, sliceRect, m_axisCacheY.min(), - m_heightNormalizer, true); + m_sliceSurfaceObj->setUpSmoothData(m_sliceDataArray, sliceRect, m_heightNormalizer, + m_axisCacheY.min(), true); } else { m_sliceSurfaceObj->setUpData(m_sliceDataArray, sliceRect, m_heightNormalizer, m_axisCacheY.min(), true); @@ -1895,20 +1904,19 @@ void Surface3DRenderer::surfacePointSelected(int id) QVector3D pos; if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow) { - pos = normalize(column, 0); + 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_sliceViewPort); m_selectionPointer->updateSliceData(true, m_autoScaleAdjustment); } else if (m_cachedSelectionMode == QDataVis::SelectionModeSliceColumn) { - pos = normalize(0, row); - pos.setX(-pos.z()); + 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_sliceViewPort); m_selectionPointer->updateSliceData(true, m_autoScaleAdjustment); } else { - pos = normalize(column, row); + 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_mainViewPort); @@ -1964,18 +1972,6 @@ QString Surface3DRenderer::createSelectionLabel(qreal value, int column, int row return labelText; } -QVector3D Surface3DRenderer::normalize(int x, int z) -{ - float resX = (m_dataArray.at(z)->at(x).x() - m_minVisibleColumnValue) - / (m_visibleColumnRange / 2.0f) - 1.0f; - float resY = (m_dataArray.at(z)->at(x).y() - float(m_axisCacheY.min())) - / (m_heightNormalizer / 2.0f) - 1.0f; - float resZ = (m_dataArray.at(z)->at(x).z() - m_minVisibleRowValue) - / (m_visibleRowRange / -2.0f) + 1.0f; - - return QVector3D(resX, resY, resZ); -} - void Surface3DRenderer::loadMeshFile() { qDebug() << __FUNCTION__ << "should we do something"; diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h index cf0d7e3c..e5a76aac 100644 --- a/src/datavisualization/engine/surface3drenderer_p.h +++ b/src/datavisualization/engine/surface3drenderer_p.h @@ -174,7 +174,6 @@ private: void fillIdCorner(uchar *p, uchar r, uchar g, uchar b, uchar a, int stride); void surfacePointSelected(int id); QString createSelectionLabel(qreal value, int column, int row); - QVector3D normalize(int x, int z); #if !defined(QT_OPENGL_ES_2) void updateDepthBuffer(); #endif diff --git a/src/datavisualization/utils/surfaceobject.cpp b/src/datavisualization/utils/surfaceobject.cpp index 8dd5f21f..f78fcec3 100644 --- a/src/datavisualization/utils/surfaceobject.cpp +++ b/src/datavisualization/utils/surfaceobject.cpp @@ -45,16 +45,18 @@ SurfaceObject::~SurfaceObject() void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange, GLfloat yMin, bool changeGeometry) { - int columns = space.width(); - int rows = space.height(); - int totalSize = rows * columns; + m_columns = space.width(); + m_rows = space.height(); + int totalSize = m_rows * m_columns; 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; - GLfloat uvX = 1.0 / GLfloat(columns - 1); - GLfloat uvY = 1.0 / GLfloat(rows - 1); + GLfloat uvX = 1.0 / GLfloat(m_columns - 1); + GLfloat uvY = 1.0 / GLfloat(m_rows - 1); + + m_surfaceType = SurfaceSmooth; // Create/populate vertice table if (changeGeometry) @@ -64,9 +66,9 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR if (changeGeometry) uvs.resize(totalSize); int totalIndex = 0; - for (int i = 0; i < rows; i++) { + for (int i = 0; i < m_rows; i++) { const QSurfaceDataRow &p = *dataArray.at(i); - for (int j = 0; j < columns; j++) { + 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); @@ -79,34 +81,34 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR } // Create normals - int rowLimit = rows - 1; - int colLimit = columns - 1; - int rowColLimit = rowLimit * columns; + int rowLimit = m_rows - 1; + int colLimit = m_columns - 1; + int rowColLimit = rowLimit * m_columns; int totalLimit = totalSize - 1; if (changeGeometry) m_normals.resize(totalSize); totalIndex = 0; - for (int row = 0; row < rowColLimit; row += columns) { + for (int row = 0; row < rowColLimit; row += m_columns) { for (int j = 0; j < colLimit; j++) { m_normals[totalIndex++] = normal(m_vertices.at(row + j), m_vertices.at(row + j + 1), - m_vertices.at(row + columns + j)); + m_vertices.at(row + m_columns + j)); } int p = row + colLimit; m_normals[totalIndex++] = normal(m_vertices.at(p), - m_vertices.at(p + columns), + m_vertices.at(p + m_columns), m_vertices.at(p - 1)); } for (int j = rowColLimit; j < totalLimit; j++) { m_normals[totalIndex++] = normal(m_vertices.at(j), - m_vertices.at(j - columns), + m_vertices.at(j - m_columns), m_vertices.at(j + 1)); } - int p = rows * colLimit; + int p = m_rows * colLimit; m_normals[totalIndex++] = normal(m_vertices.at(p), m_vertices.at(p - 1), - m_vertices.at(p - columns - 1)); + m_vertices.at(p - m_columns - 1)); // Create indices table GLint *indices = 0; @@ -114,16 +116,16 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR m_indexCount = 6 * colLimit * rowLimit; indices = new GLint[m_indexCount]; p = 0; - for (int row = 0; row < rowLimit * columns; row += columns) { + for (int row = 0; row < rowLimit * m_columns; row += m_columns) { for (int j = 0; j < colLimit; j++) { // Left triangle indices[p++] = row + j + 1; - indices[p++] = row + columns + j; + indices[p++] = row + m_columns + j; indices[p++] = row + j; // Right triangle - indices[p++] = row + columns + j + 1; - indices[p++] = row + columns + j; + indices[p++] = row + m_columns + j + 1; + indices[p++] = row + m_columns + j; indices[p++] = row + j + 1; } } @@ -132,19 +134,19 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR // Create line element indices GLint *gridIndices = 0; if (changeGeometry) { - m_gridIndexCount = 2 * columns * rowLimit + 2 * rows * colLimit; + m_gridIndexCount = 2 * m_columns * rowLimit + 2 * m_rows * colLimit; gridIndices = new GLint[m_gridIndexCount]; p = 0; - for (int i = 0, row = 0; i < rows; i++, row += columns) { + for (int i = 0, row = 0; i < m_rows; i++, row += m_columns) { for (int j = 0; j < colLimit; j++) { gridIndices[p++] = row + j; gridIndices[p++] = row + j + 1; } } - for (int i = 0, row = 0; i < rowLimit; i++, row += columns) { - for (int j = 0; j < columns; j++) { + for (int i = 0, row = 0; i < rowLimit; i++, row += m_columns) { + for (int j = 0; j < m_columns; j++) { gridIndices[p++] = row + j; - gridIndices[p++] = row + j + columns; + gridIndices[p++] = row + j + m_columns; } } } @@ -159,16 +161,18 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange, GLfloat yMin, bool changeGeometry) { - int columns = space.width(); - int rows = space.height(); - int totalSize = rows * columns * 2; + m_columns = space.width(); + m_rows = space.height(); + int totalSize = m_rows * m_columns * 2; 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; - GLfloat uvX = 1.0 / GLfloat(columns - 1); - GLfloat uvY = 1.0 / GLfloat(rows - 1); + GLfloat uvX = 1.0 / GLfloat(m_columns - 1); + GLfloat uvY = 1.0 / GLfloat(m_rows - 1); + + m_surfaceType = SurfaceFlat; // Create vertice table if (changeGeometry) @@ -179,14 +183,14 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s uvs.resize(totalSize); int totalIndex = 0; - int rowLimit = rows - 1; - int colLimit = columns - 1; - int doubleColumns = columns * 2 - 2; + int rowLimit = m_rows - 1; + int colLimit = m_columns - 1; + int doubleColumns = m_columns * 2 - 2; int rowColLimit = rowLimit * doubleColumns; - for (int i = 0; i < rows; i++) { + for (int i = 0; i < m_rows; i++) { const QSurfaceDataRow &row = *dataArray.at(i); - for (int j = 0; j < columns; j++) { + 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); @@ -248,10 +252,10 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s // Create grid line element indices GLint *gridIndices = 0; if (changeGeometry) { - m_gridIndexCount = 2 * columns * rowLimit + 2 * rows * colLimit; + m_gridIndexCount = 2 * m_columns * rowLimit + 2 * m_rows * colLimit; gridIndices = new GLint[m_gridIndexCount]; p = 0; - int fullRowLimit = rows * doubleColumns; + int fullRowLimit = m_rows * doubleColumns; for (int row = 0; row < fullRowLimit; row += doubleColumns) { for (int j = 0; j < doubleColumns; j += 2) { gridIndices[p++] = row + j; @@ -322,6 +326,16 @@ GLuint SurfaceObject::gridIndexCount() return m_gridIndexCount; } +QVector3D SurfaceObject::vertexAt(int column, int row) +{ + int pos = 0; + if (m_surfaceType == SurfaceFlat) + pos = row * (m_columns * 2 - 2) + column * 2 - (column > 0); + else + pos = row * m_columns + column; + return m_vertices.at(pos); +} + 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 ab490960..5100bb2c 100644 --- a/src/datavisualization/utils/surfaceobject_p.h +++ b/src/datavisualization/utils/surfaceobject_p.h @@ -50,6 +50,7 @@ public: GLfloat yMin, bool changeGeometry); GLuint gridElementBuf(); GLuint gridIndexCount(); + QVector3D vertexAt(int column, int row); private: QVector3D normal(const QVector3D &a, const QVector3D &b, const QVector3D &c); @@ -58,8 +59,13 @@ private: const GLint *gridIndices, bool changeGeometry); private: - int m_dataWidth; - int m_dataDepth; + enum SurfaceType { + SurfaceSmooth, + SurfaceFlat + }; + int m_surfaceType; + int m_columns; + int m_rows; GLfloat m_yRange; GLuint m_gridElementbuffer; GLuint m_gridIndexCount; -- cgit v1.2.3