diff options
Diffstat (limited to 'src/datavisualization')
-rw-r--r-- | src/datavisualization/data/customrenderitem.cpp | 3 | ||||
-rw-r--r-- | src/datavisualization/data/customrenderitem_p.h | 2 | ||||
-rw-r--r-- | src/datavisualization/data/qcustom3ditem.cpp | 7 | ||||
-rw-r--r-- | src/datavisualization/data/qsurfacedataproxy.cpp | 80 | ||||
-rw-r--r-- | src/datavisualization/doc/qtdatavis3d.qdocconf | 60 | ||||
-rw-r--r-- | src/datavisualization/doc/src/qtdatavisualization.qdoc | 2 | ||||
-rw-r--r-- | src/datavisualization/engine/abstract3drenderer.cpp | 11 | ||||
-rw-r--r-- | src/datavisualization/engine/q3dcamera_p.h | 2 | ||||
-rw-r--r-- | src/datavisualization/engine/qabstract3dgraph.cpp | 5 | ||||
-rw-r--r-- | src/datavisualization/utils/meshloader.cpp | 4 | ||||
-rw-r--r-- | src/datavisualization/utils/objecthelper.cpp | 86 | ||||
-rw-r--r-- | src/datavisualization/utils/qutils.h | 4 |
12 files changed, 158 insertions, 108 deletions
diff --git a/src/datavisualization/data/customrenderitem.cpp b/src/datavisualization/data/customrenderitem.cpp index 68e84c44..6279921d 100644 --- a/src/datavisualization/data/customrenderitem.cpp +++ b/src/datavisualization/data/customrenderitem.cpp @@ -68,9 +68,10 @@ CustomRenderItem::~CustomRenderItem() ObjectHelper::releaseObjectHelper(m_renderer, m_object); } -void CustomRenderItem::setMesh(const QString &meshFile) +bool CustomRenderItem::setMesh(const QString &meshFile) { ObjectHelper::resetObjectHelper(m_renderer, m_object, meshFile); + return m_object ? true : false; } void CustomRenderItem::setColorTable(const QList<QRgb> &colors) diff --git a/src/datavisualization/data/customrenderitem_p.h b/src/datavisualization/data/customrenderitem_p.h index 196e6aa0..e14b1de4 100644 --- a/src/datavisualization/data/customrenderitem_p.h +++ b/src/datavisualization/data/customrenderitem_p.h @@ -59,7 +59,7 @@ public: inline void setTexture(GLuint texture) { m_texture = texture; } inline GLuint texture() const { return m_texture; } - void setMesh(const QString &meshFile); + bool setMesh(const QString &meshFile); inline ObjectHelper *mesh() const { return m_object; } inline void setScaling(const QVector3D &scaling) { m_scaling = scaling; } inline const QVector3D &scaling() const { return m_scaling; } diff --git a/src/datavisualization/data/qcustom3ditem.cpp b/src/datavisualization/data/qcustom3ditem.cpp index 07e3c809..63ba2b20 100644 --- a/src/datavisualization/data/qcustom3ditem.cpp +++ b/src/datavisualization/data/qcustom3ditem.cpp @@ -58,7 +58,9 @@ QT_BEGIN_NAMESPACE /*! \qmlproperty string Custom3DItem::meshFile * * The item mesh file name. The item in the file must be in Wavefront OBJ format and include - * vertices, normals, and UVs. It also needs to be in triangles. + * vertices, normals, and UVs. It also needs to be in triangles. If the file is missing either + * normals or UVs, loading will fail with an error message to the console output and the item will + * not be rendered. */ /*! \qmlproperty string Custom3DItem::textureFile @@ -203,6 +205,9 @@ QCustom3DItem::~QCustom3DItem() * * The item in the file must be in Wavefront OBJ format and include * vertices, normals, and UVs. It also needs to be in triangles. + * If the file is missing either normals or UVs, loading will fail + * with an error message to the console output and the item will + * not be rendered. */ void QCustom3DItem::setMeshFile(const QString &meshFile) { diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp index 7601d021..c9c6425d 100644 --- a/src/datavisualization/data/qsurfacedataproxy.cpp +++ b/src/datavisualization/data/qsurfacedataproxy.cpp @@ -552,9 +552,11 @@ void QSurfaceDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxV float itemValue = m_dataArray->at(i)->at(j).y(); if (qIsNaN(itemValue) || qIsInf(itemValue)) continue; - if (min > itemValue && isValidValue(itemValue, axisY)) + if ((min > itemValue || (qIsNaN(min) || qIsInf(min))) + && isValidValue(itemValue, axisY)) { min = itemValue; - if (max < itemValue) + } + if (max < itemValue || (qIsNaN(max) || qIsInf(max))) max = itemValue; } } @@ -569,33 +571,59 @@ void QSurfaceDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxV float xHigh = m_dataArray->at(0)->last().x(); float zLow = m_dataArray->at(0)->at(0).z(); float zHigh = m_dataArray->last()->at(0).z(); - for (int i = 0; i < columns; i++) { - float zItemValue = m_dataArray->at(0)->at(i).z(); - if (qIsNaN(zItemValue) || qIsInf(zItemValue)) - continue; - else if (isValidValue(zItemValue, axisZ)) - zLow = qMin(zLow,zItemValue); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < columns; j++) { + float zItemValue = m_dataArray->at(i)->at(j).z(); + if (qIsNaN(zItemValue) || qIsInf(zItemValue)) + continue; + else if (isValidValue(zItemValue, axisZ)) + zLow = qMin(zLow,zItemValue); + } + if (!qIsNaN(zLow) && !qIsInf(zLow)) + break; } - for (int i = 0; i < columns; i++) { - float zItemValue = m_dataArray->last()->at(i).z(); - if (qIsNaN(zItemValue) || qIsInf(zItemValue)) - continue; - else if (isValidValue(zItemValue, axisZ)) - zHigh = qMax(zHigh, zItemValue); + for (int i = rows - 1; i >= 0; i--) { + for (int j = 0; j < columns; j++) { + float zItemValue = m_dataArray->at(i)->at(j).z(); + if (qIsNaN(zItemValue) || qIsInf(zItemValue)) + continue; + else if (isValidValue(zItemValue, axisZ)) + { + if (!qIsNaN(zHigh) && !qIsInf(zHigh)) + zHigh = qMax(zHigh, zItemValue); + else + zHigh = zItemValue; + } + } + if (!qIsNaN(zHigh) && !qIsInf(zHigh)) + break; } - for (int i = 0; i < rows; i++) { - float xItemValue = m_dataArray->at(i)->at(0).x(); - if (qIsNaN(xItemValue) || qIsInf(xItemValue)) - continue; - else if (isValidValue(xItemValue, axisX)) - xLow = qMin(xLow, xItemValue); + for (int j = 0; j<columns; j++){ + for (int i = 0; i < rows; i++) { + float xItemValue = m_dataArray->at(i)->at(j).x(); + if (qIsNaN(xItemValue) || qIsInf(xItemValue)) + continue; + else if (isValidValue(xItemValue, axisX)) + xLow = qMin(xLow, xItemValue); + } + if (!qIsNaN(xLow) && !qIsInf(xLow)) + break; } - for (int i = 0; i < rows; i++) { - float xItemValue = m_dataArray->at(i)->last().x(); - if (qIsNaN(xItemValue) || qIsInf(xItemValue)) - continue; - else if (isValidValue(xItemValue, axisX)) - xHigh = qMax(xHigh, xItemValue); + for (int j = columns-1; j >= 0; j--){ + for (int i = 0; i < rows; i++) { + float xItemValue = m_dataArray->at(i)->at(j).x(); + if (qIsNaN(xItemValue) || qIsInf(xItemValue)) + continue; + else if (isValidValue(xItemValue, axisX)) + { + if (!qIsNaN(xHigh) && !qIsInf(xHigh)) + xHigh = qMax(xHigh, xItemValue); + else + xHigh = xItemValue; + } + } + if (!qIsNaN(xHigh) && !qIsInf(xHigh)) + break; } minValues.setX(xLow); minValues.setZ(zLow); diff --git a/src/datavisualization/doc/qtdatavis3d.qdocconf b/src/datavisualization/doc/qtdatavis3d.qdocconf index bc4690ad..1f689dfa 100644 --- a/src/datavisualization/doc/qtdatavis3d.qdocconf +++ b/src/datavisualization/doc/qtdatavis3d.qdocconf @@ -1,7 +1,7 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) include($QT_INSTALL_DOCS/config/exampleurl-qtdatavis3d.qdocconf) -project = QtDataVisualization +project = QtDataVis3D description = Qt Data Visualization Reference Documentation version = $QT_VERSION buildversion = Qt Data Visualization | Commercial or GPLv3 @@ -17,37 +17,37 @@ imagedirs += ../images \ depends = qtcore qtgui qtqml qtquick qtdoc qtcmake qtwidgets -qhp.projects = QtDataVisualization - -qhp.QtDataVisualization.file = qtdatavis3d.qhp -qhp.QtDataVisualization.namespace = org.qt-project.qtdatavisualization.$QT_VERSION_TAG -qhp.QtDataVisualization.virtualFolder = qtdatavisualization -qhp.QtDataVisualization.indexTitle = Qt Data Visualization -qhp.QtDataVisualization.indexRoot = - -qhp.QtDataVisualization.filterAttributes = qtdatavisualization $QT_VERSION qtrefdoc -qhp.QtDataVisualization.customFilters.Qt.name = QtDataVisualization $QT_VERSION -qhp.QtDataVisualization.customFilters.Qt.filterAttributes = qtdatavisualization $QT_VERSION -qhp.QtDataVisualization.subprojects = gettingstarted examples classes types -qhp.QtDataVisualization.subprojects.gettingstarted.title = Getting Started -qhp.QtDataVisualization.subprojects.gettingstarted.indexTitle = Qt Data Visualization Getting Started -qhp.QtDataVisualization.subprojects.gettingstarted.selectors = doc:page -qhp.QtDataVisualization.subprojects.gettingstarted.sortPages = true -qhp.QtDataVisualization.subprojects.examples.title = Examples -qhp.QtDataVisualization.subprojects.examples.indexTitle = Qt Data Visualization Examples -qhp.QtDataVisualization.subprojects.examples.selectors = doc:example -qhp.QtDataVisualization.subprojects.examples.sortPages = true -qhp.QtDataVisualization.subprojects.classes.title = C++ Classes -qhp.QtDataVisualization.subprojects.classes.indexTitle = Qt Data Visualization C++ Classes -qhp.QtDataVisualization.subprojects.classes.selectors = class -qhp.QtDataVisualization.subprojects.classes.sortPages = true -qhp.QtDataVisualization.subprojects.types.title = QML Types -qhp.QtDataVisualization.subprojects.types.indexTitle = Qt Data Visualization QML Types -qhp.QtDataVisualization.subprojects.types.selectors = qmlclass -qhp.QtDataVisualization.subprojects.types.sortPages = true +qhp.projects = QtDataVis3D + +qhp.QtDataVis3D.file = qtdatavis3d.qhp +qhp.QtDataVis3D.namespace = org.qt-project.qtdatavisualization.$QT_VERSION_TAG +qhp.QtDataVis3D.virtualFolder = qtdatavisualization +qhp.QtDataVis3D.indexTitle = Qt Data Visualization +qhp.QtDataVis3D.indexRoot = + +qhp.QtDataVis3D.filterAttributes = qtdatavisualization $QT_VERSION qtrefdoc +qhp.QtDataVis3D.customFilters.Qt.name = QtDataVisualization $QT_VERSION +qhp.QtDataVis3D.customFilters.Qt.filterAttributes = qtdatavisualization $QT_VERSION +qhp.QtDataVis3D.subprojects = gettingstarted examples classes types +qhp.QtDataVis3D.subprojects.gettingstarted.title = Getting Started +qhp.QtDataVis3D.subprojects.gettingstarted.indexTitle = Qt Data Visualization Getting Started +qhp.QtDataVis3D.subprojects.gettingstarted.selectors = doc:page +qhp.QtDataVis3D.subprojects.gettingstarted.sortPages = true +qhp.QtDataVis3D.subprojects.examples.title = Examples +qhp.QtDataVis3D.subprojects.examples.indexTitle = Qt Data Visualization Examples +qhp.QtDataVis3D.subprojects.examples.selectors = doc:example +qhp.QtDataVis3D.subprojects.examples.sortPages = true +qhp.QtDataVis3D.subprojects.classes.title = C++ Classes +qhp.QtDataVis3D.subprojects.classes.indexTitle = Qt Data Visualization C++ Classes +qhp.QtDataVis3D.subprojects.classes.selectors = class +qhp.QtDataVis3D.subprojects.classes.sortPages = true +qhp.QtDataVis3D.subprojects.types.title = QML Types +qhp.QtDataVis3D.subprojects.types.indexTitle = Qt Data Visualization QML Types +qhp.QtDataVis3D.subprojects.types.selectors = qmlclass +qhp.QtDataVis3D.subprojects.types.sortPages = true navigation.landingpage = Qt Data Visualization navigation.cppclassespage = Qt Data Visualization C++ Classes navigation.qmltypespage = Qt Data Visualization QML Types -manifestmeta.highlighted.names = "QtDataVisualization/Textured Surface Example" +manifestmeta.highlighted.names = "QtDataVis3D/Textured Surface Example" diff --git a/src/datavisualization/doc/src/qtdatavisualization.qdoc b/src/datavisualization/doc/src/qtdatavisualization.qdoc index 33448065..1f9cb60c 100644 --- a/src/datavisualization/doc/src/qtdatavisualization.qdoc +++ b/src/datavisualization/doc/src/qtdatavisualization.qdoc @@ -29,6 +29,8 @@ \module QtDataVisualization \title Qt Data Visualization C++ Classes \ingroup modules + \qtcmakepackage DataVisualization + \qtvariable datavisualization \brief C++ classes for the Qt Data Visualization API. diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index 54487ba1..4a0b1c8f 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -749,8 +749,10 @@ void Abstract3DRenderer::updateCustomData(const QList<QCustom3DItem *> &customIt CustomRenderItem *renderItem = m_customRenderCache.value(item); if (!renderItem) renderItem = addCustomItem(item); - renderItem->setValid(true); - renderItem->setIndex(i); // always update index, as it must match the custom item index + if (renderItem) { + renderItem->setValid(true); + renderItem->setIndex(i); // always update index, as it must match the custom item index + } } // Check render item cache and remove items that are not in customItems list anymore @@ -1133,7 +1135,10 @@ CustomRenderItem *Abstract3DRenderer::addCustomItem(QCustom3DItem *item) CustomRenderItem *newItem = new CustomRenderItem(); newItem->setRenderer(this); newItem->setItemPointer(item); // Store pointer for render item updates - newItem->setMesh(item->meshFile()); + if (!newItem->setMesh(item->meshFile())) { + delete newItem; + return nullptr; + } newItem->setOrigPosition(item->position()); newItem->setOrigScaling(item->scaling()); newItem->setScalingAbsolute(item->isScalingAbsolute()); diff --git a/src/datavisualization/engine/q3dcamera_p.h b/src/datavisualization/engine/q3dcamera_p.h index 944e408e..27685a43 100644 --- a/src/datavisualization/engine/q3dcamera_p.h +++ b/src/datavisualization/engine/q3dcamera_p.h @@ -89,7 +89,7 @@ Q_SIGNALS: void minYRotationChanged(float rotation); void maxXRotationChanged(float rotation); void maxYRotationChanged(float rotation); - void viewMatrixChanged(QMatrix4x4 viewMatrix); + void viewMatrixChanged(const QMatrix4x4 &viewMatrix); void viewMatrixAutoUpdateChanged(bool enabled); public: diff --git a/src/datavisualization/engine/qabstract3dgraph.cpp b/src/datavisualization/engine/qabstract3dgraph.cpp index 6e17937e..957004f4 100644 --- a/src/datavisualization/engine/qabstract3dgraph.cpp +++ b/src/datavisualization/engine/qabstract3dgraph.cpp @@ -656,11 +656,6 @@ qreal QAbstract3DGraph::currentFps() const * * \brief Whether orthographic projection is used for displaying the graph. * - * If \c {true}, ortographic projection is used to create 2D graphs by replacing - * the default input handler with one that does not allow rotating the graph and - * by setting the camera to view the graph - * directly from the side or from the top. Also, axis labels typically need to be rotated when - * viewing the graph from the sides. * Defaults to \c{false}. * \note Shadows will be disabled when set to \c{true}. * diff --git a/src/datavisualization/utils/meshloader.cpp b/src/datavisualization/utils/meshloader.cpp index 274d4a13..fa071a96 100644 --- a/src/datavisualization/utils/meshloader.cpp +++ b/src/datavisualization/utils/meshloader.cpp @@ -81,6 +81,10 @@ bool MeshLoader::loadOBJ(const QString &path, QList<QVector3D> &out_vertices, QStringList set1 = lineContents.at(1).split(slashTag); QStringList set2 = lineContents.at(2).split(slashTag); QStringList set3 = lineContents.at(3).split(slashTag); + if (set1.length() < 3 || set2.length() < 3 || set3.length() < 3) { + qWarning("The file being loaded is missing UVs and/or normals"); + return false; + } vertexIndex[0] = set1.at(0).toUInt(); vertexIndex[1] = set2.at(0).toUInt(); vertexIndex[2] = set3.at(0).toUInt(); diff --git a/src/datavisualization/utils/objecthelper.cpp b/src/datavisualization/utils/objecthelper.cpp index f8fa01de..87875a98 100644 --- a/src/datavisualization/utils/objecthelper.cpp +++ b/src/datavisualization/utils/objecthelper.cpp @@ -113,10 +113,19 @@ ObjectHelper *ObjectHelper::getObjectHelper(const Abstract3DRenderer *cacheId, objRef = new ObjectHelperRef; objRef->refCount = 0; objRef->obj = new ObjectHelper(objectFile); - objectTable->insert(objectFile, objRef); + if (objRef->obj->m_meshDataLoaded) { + objectTable->insert(objectFile, objRef); + } else { + delete objRef->obj; + delete objRef; + objRef = nullptr; + } + } + if (objRef) { + objRef->refCount++; + return objRef->obj; } - objRef->refCount++; - return objRef->obj; + return nullptr; } void ObjectHelper::load() @@ -140,41 +149,44 @@ void ObjectHelper::load() QList<QVector2D> uvs; QList<QVector3D> normals; bool loadOk = MeshLoader::loadOBJ(m_objectFile, vertices, uvs, normals); - if (!loadOk) - qFatal("loading failed"); - - // Index vertices - VertexIndexer::indexVBO(vertices, uvs, normals, m_indices, m_indexedVertices, m_indexedUVs, - m_indexedNormals); - - m_indexCount = m_indices.size(); - - glGenBuffers(1, &m_vertexbuffer); - glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer); - glBufferData(GL_ARRAY_BUFFER, m_indexedVertices.size() * sizeof(QVector3D), - &m_indexedVertices.at(0), - GL_STATIC_DRAW); - glGenBuffers(1, &m_normalbuffer); - glBindBuffer(GL_ARRAY_BUFFER, m_normalbuffer); - glBufferData(GL_ARRAY_BUFFER, m_indexedNormals.size() * sizeof(QVector3D), - &m_indexedNormals.at(0), - GL_STATIC_DRAW); - - glGenBuffers(1, &m_uvbuffer); - glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer); - glBufferData(GL_ARRAY_BUFFER, m_indexedUVs.size() * sizeof(QVector2D), - &m_indexedUVs.at(0), GL_STATIC_DRAW); - - glGenBuffers(1, &m_elementbuffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof(GLuint), - &m_indices.at(0), GL_STATIC_DRAW); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - m_meshDataLoaded = true; + if (!loadOk) { + qCritical() << "Loading" << m_objectFile << "failed"; + m_meshDataLoaded = false; + } else { + // Index vertices + VertexIndexer::indexVBO(vertices, uvs, normals, m_indices, m_indexedVertices, m_indexedUVs, + m_indexedNormals); + + m_indexCount = m_indices.size(); + + glGenBuffers(1, &m_vertexbuffer); + glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer); + glBufferData(GL_ARRAY_BUFFER, m_indexedVertices.size() * sizeof(QVector3D), + &m_indexedVertices.at(0), + GL_STATIC_DRAW); + + glGenBuffers(1, &m_normalbuffer); + glBindBuffer(GL_ARRAY_BUFFER, m_normalbuffer); + glBufferData(GL_ARRAY_BUFFER, m_indexedNormals.size() * sizeof(QVector3D), + &m_indexedNormals.at(0), + GL_STATIC_DRAW); + + glGenBuffers(1, &m_uvbuffer); + glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer); + glBufferData(GL_ARRAY_BUFFER, m_indexedUVs.size() * sizeof(QVector2D), + &m_indexedUVs.at(0), GL_STATIC_DRAW); + + glGenBuffers(1, &m_elementbuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof(GLuint), + &m_indices.at(0), GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + m_meshDataLoaded = true; + } } QT_END_NAMESPACE diff --git a/src/datavisualization/utils/qutils.h b/src/datavisualization/utils/qutils.h index dc72835e..6a35ff34 100644 --- a/src/datavisualization/utils/qutils.h +++ b/src/datavisualization/utils/qutils.h @@ -38,9 +38,7 @@ QT_BEGIN_NAMESPACE -#ifdef Q_OS_MACOS -#pragma clang diagnostic ignored "-Wunused-function" -#endif +[[maybe_unused]] static inline QSurfaceFormat qDefaultSurfaceFormat(bool antialias) { bool isES = false; |