diff options
author | Tomi Korpipaa <tomi.korpipaa@qt.io> | 2023-02-15 13:31:16 +0200 |
---|---|---|
committer | Tomi Korpipaa <tomi.korpipaa@qt.io> | 2023-02-27 13:53:21 +0200 |
commit | 279ed99a5f1fe06c250cec197609e819ea28a38f (patch) | |
tree | afa6109832ccef5594b46b12aebc3921c22f013a /examples/datavisualization | |
parent | cbaa2eaaf73ffa0d2b4ba999c993199fc22110ea (diff) |
Combine 3 more widget examples into graph gallery
Combine the remaining 3 surface graph examples into graph gallery
example.
Pick-to: 6.5
Task-number: QTBUG-110698
Change-Id: Ia324189e10f781f9822db220def72b7b15d37a49
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Diffstat (limited to 'examples/datavisualization')
52 files changed, 1501 insertions, 1841 deletions
diff --git a/examples/datavisualization/CMakeLists.txt b/examples/datavisualization/CMakeLists.txt index c7be4a7a..cff70280 100644 --- a/examples/datavisualization/CMakeLists.txt +++ b/examples/datavisualization/CMakeLists.txt @@ -9,8 +9,5 @@ if(TARGET Qt::Quick) endif() if(NOT ANDROID AND NOT IOS AND NOT WINRT) qt_internal_add_example(graphgallery) - qt_internal_add_example(surface) - qt_internal_add_example(customitems) - qt_internal_add_example(texturesurface) qt_internal_add_example(volumetric) endif() diff --git a/examples/datavisualization/customitems/CMakeLists.txt b/examples/datavisualization/customitems/CMakeLists.txt deleted file mode 100644 index a3e8a99f..00000000 --- a/examples/datavisualization/customitems/CMakeLists.txt +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (C) 2022 The Qt Company Ltd. -# SPDX-License-Identifier: BSD-3-Clause - -cmake_minimum_required(VERSION 3.16) -project(customitems LANGUAGES CXX) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}") - -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Widgets) -find_package(Qt6 COMPONENTS DataVisualization) - -qt_add_executable(customitems - customitemgraph.cpp customitemgraph.h - main.cpp -) -set_target_properties(customitems PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(customitems PUBLIC - Qt::Core - Qt::Gui - Qt::Widgets - Qt::DataVisualization -) - -set(customitems_resource_files - "layer_1.png" - "layer_2.png" - "layer_3.png" -) - -qt6_add_resources(customitems "customitems" - PREFIX - "/maps" - FILES - ${customitems_resource_files} -) -set(customitems1_resource_files - "oilrig.obj" - "pipe.obj" - "refinery.obj" -) - -qt6_add_resources(customitems "customitems1" - PREFIX - "/items" - FILES - ${customitems1_resource_files} -) - -install(TARGETS customitems - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) diff --git a/examples/datavisualization/customitems/customitemgraph.cpp b/examples/datavisualization/customitems/customitemgraph.cpp deleted file mode 100644 index d35edb38..00000000 --- a/examples/datavisualization/customitems/customitemgraph.cpp +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -#include "customitemgraph.h" - -#include <QtDataVisualization/Q3DTheme> -#include <QtDataVisualization/QCustom3DItem> -#include <QtDataVisualization/QCustom3DLabel> -#include <QtGui/QImage> - -CustomItemGraph::CustomItemGraph(Q3DSurface *surface, QLabel *label) - : m_graph(surface), - m_textField(label), - m_previouslyAnimatedItem(0) -{ - QImage layerOneHMap(":/maps/layer_1.png"); - QHeightMapSurfaceDataProxy *layerOneProxy = new QHeightMapSurfaceDataProxy(layerOneHMap); - QSurface3DSeries *layerOneSeries = new QSurface3DSeries(layerOneProxy); - layerOneSeries->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel")); - layerOneProxy->setValueRanges(34.0f, 40.0f, 18.0f, 24.0f); - layerOneSeries->setDrawMode(QSurface3DSeries::DrawSurface); - layerOneSeries->setFlatShadingEnabled(false); - - QImage layerTwoHMap(":/maps/layer_2.png"); - QHeightMapSurfaceDataProxy *layerTwoProxy = new QHeightMapSurfaceDataProxy(layerTwoHMap); - QSurface3DSeries *layerTwoSeries = new QSurface3DSeries(layerTwoProxy); - layerTwoSeries->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel")); - layerTwoProxy->setValueRanges(34.0f, 40.0f, 18.0f, 24.0f); - layerTwoSeries->setDrawMode(QSurface3DSeries::DrawSurface); - layerTwoSeries->setFlatShadingEnabled(false); - - QImage layerThreeHMap(":/maps/layer_3.png"); - QHeightMapSurfaceDataProxy *layerThreeProxy = new QHeightMapSurfaceDataProxy(layerThreeHMap); - QSurface3DSeries *layerThreeSeries = new QSurface3DSeries(layerThreeProxy); - layerThreeSeries->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel")); - layerThreeProxy->setValueRanges(34.0f, 40.0f, 18.0f, 24.0f); - layerThreeSeries->setDrawMode(QSurface3DSeries::DrawSurface); - layerThreeSeries->setFlatShadingEnabled(false); - - m_graph->axisX()->setLabelFormat("%.1f N"); - m_graph->axisZ()->setLabelFormat("%.1f E"); - m_graph->axisX()->setRange(34.0f, 40.0f); - m_graph->axisY()->setRange(0.0f, 200.0f); - m_graph->axisZ()->setRange(18.0f, 24.0f); - - m_graph->axisX()->setTitle(QStringLiteral("Latitude")); - m_graph->axisY()->setTitle(QStringLiteral("Height")); - m_graph->axisZ()->setTitle(QStringLiteral("Longitude")); - - m_graph->addSeries(layerOneSeries); - m_graph->addSeries(layerTwoSeries); - m_graph->addSeries(layerThreeSeries); - - QLinearGradient grOne; - grOne.setColorAt(0.0, Qt::black); - grOne.setColorAt(0.38, Qt::darkYellow); - grOne.setColorAt(0.39, Qt::darkGreen); - grOne.setColorAt(0.5, Qt::darkGray); - grOne.setColorAt(1.0, Qt::gray); - m_graph->seriesList().at(0)->setBaseGradient(grOne); - m_graph->seriesList().at(0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient); - - QLinearGradient grTwo; - grTwo.setColorAt(0.385, Qt::blue); - grTwo.setColorAt(0.395, Qt::white); - m_graph->seriesList().at(1)->setBaseGradient(grTwo); - m_graph->seriesList().at(1)->setColorStyle(Q3DTheme::ColorStyleRangeGradient); - - QLinearGradient grThree; - grThree.setColorAt(0.0, Qt::white); - grThree.setColorAt(0.05, Qt::black); - m_graph->seriesList().at(2)->setBaseGradient(grThree); - m_graph->seriesList().at(2)->setColorStyle(Q3DTheme::ColorStyleRangeGradient); - - m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront); - - connect(m_graph, &QAbstract3DGraph::selectedElementChanged, - this, &CustomItemGraph::handleElementSelected); - - m_selectionAnimation = new QPropertyAnimation(this); - m_selectionAnimation->setPropertyName("scaling"); - m_selectionAnimation->setDuration(500); - m_selectionAnimation->setLoopCount(-1); - - QFont titleFont = QFont("Century Gothic", 30); - titleFont.setBold(true); - QCustom3DLabel *titleLabel = new QCustom3DLabel("Oil Rigs on Imaginary Sea", titleFont, - QVector3D(0.0f, 1.2f, 0.0f), - QVector3D(1.0f, 1.0f, 0.0f), - QQuaternion()); - titleLabel->setPositionAbsolute(true); - titleLabel->setFacingCamera(true); - titleLabel->setBackgroundColor(QColor(0x66cdaa)); - m_graph->addCustomItem(titleLabel); - - toggleItemOne(true); - toggleItemTwo(true); -} - -CustomItemGraph::~CustomItemGraph() -{ - delete m_graph; -} - -void CustomItemGraph::toggleItemOne(bool show) -{ - //! [1] - QVector3D positionOne = QVector3D(39.0f, 77.0f, 19.2f); - //! [1] - QVector3D positionOnePipe = QVector3D(39.0f, 45.0f, 19.2f); - QVector3D positionOneLabel = QVector3D(39.0f, 107.0f, 19.2f); - if (show) { - //! [0] - QImage color = QImage(2, 2, QImage::Format_RGB32); - color.fill(Qt::red); - //! [0] - //! [2] - QCustom3DItem *item = new QCustom3DItem(":/items/oilrig.obj", positionOne, - QVector3D(0.025f, 0.025f, 0.025f), - QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 45.0f), - color); - //! [2] - //! [3] - m_graph->addCustomItem(item); - //! [3] - item = new QCustom3DItem(":/items/pipe.obj", positionOnePipe, - QVector3D(0.005f, 0.5f, 0.005f), - QQuaternion(), - color); - item->setShadowCasting(false); - m_graph->addCustomItem(item); - - QCustom3DLabel *label = new QCustom3DLabel(); - label->setText("Oil Rig One"); - label->setPosition(positionOneLabel); - label->setScaling(QVector3D(1.0f, 1.0f, 1.0f)); - m_graph->addCustomItem(label); - } else { - resetSelection(); - //! [4] - m_graph->removeCustomItemAt(positionOne); - //! [4] - m_graph->removeCustomItemAt(positionOnePipe); - m_graph->removeCustomItemAt(positionOneLabel); - } -} - -void CustomItemGraph::toggleItemTwo(bool show) -{ - QVector3D positionTwo = QVector3D(34.5f, 77.0f, 23.4f); - QVector3D positionTwoPipe = QVector3D(34.5f, 45.0f, 23.4f); - QVector3D positionTwoLabel = QVector3D(34.5f, 107.0f, 23.4f); - if (show) { - QImage color = QImage(2, 2, QImage::Format_RGB32); - color.fill(Qt::red); - QCustom3DItem *item = new QCustom3DItem(); - item->setMeshFile(":/items/oilrig.obj"); - item->setPosition(positionTwo); - item->setScaling(QVector3D(0.025f, 0.025f, 0.025f)); - item->setRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 25.0f)); - item->setTextureImage(color); - m_graph->addCustomItem(item); - item = new QCustom3DItem(":/items/pipe.obj", positionTwoPipe, - QVector3D(0.005f, 0.5f, 0.005f), - QQuaternion(), - color); - item->setShadowCasting(false); - m_graph->addCustomItem(item); - - QCustom3DLabel *label = new QCustom3DLabel(); - label->setText("Oil Rig Two"); - label->setPosition(positionTwoLabel); - label->setScaling(QVector3D(1.0f, 1.0f, 1.0f)); - m_graph->addCustomItem(label); - } else { - resetSelection(); - m_graph->removeCustomItemAt(positionTwo); - m_graph->removeCustomItemAt(positionTwoPipe); - m_graph->removeCustomItemAt(positionTwoLabel); - } -} - -void CustomItemGraph::toggleItemThree(bool show) -{ - QVector3D positionThree = QVector3D(34.5f, 86.0f, 19.1f); - QVector3D positionThreeLabel = QVector3D(34.5f, 116.0f, 19.1f); - if (show) { - QImage color = QImage(2, 2, QImage::Format_RGB32); - color.fill(Qt::darkMagenta); - QCustom3DItem *item = new QCustom3DItem(); - item->setMeshFile(":/items/refinery.obj"); - item->setPosition(positionThree); - item->setScaling(QVector3D(0.04f, 0.04f, 0.04f)); - item->setRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 75.0f)); - item->setTextureImage(color); - m_graph->addCustomItem(item); - - QCustom3DLabel *label = new QCustom3DLabel(); - label->setText("Refinery"); - label->setPosition(positionThreeLabel); - label->setScaling(QVector3D(1.0f, 1.0f, 1.0f)); - m_graph->addCustomItem(label); - } else { - resetSelection(); - m_graph->removeCustomItemAt(positionThree); - m_graph->removeCustomItemAt(positionThreeLabel); - } -} - -void CustomItemGraph::toggleSeeThrough(bool seethrough) -{ - if (seethrough) { - m_graph->seriesList().at(0)->setDrawMode(QSurface3DSeries::DrawWireframe); - m_graph->seriesList().at(1)->setDrawMode(QSurface3DSeries::DrawWireframe); - } else { - m_graph->seriesList().at(0)->setDrawMode(QSurface3DSeries::DrawSurface); - m_graph->seriesList().at(1)->setDrawMode(QSurface3DSeries::DrawSurface); - } -} - -void CustomItemGraph::toggleOilHighlight(bool highlight) -{ - if (highlight) { - QLinearGradient grThree; - grThree.setColorAt(0.0, Qt::black); - grThree.setColorAt(0.05, Qt::red); - m_graph->seriesList().at(2)->setBaseGradient(grThree); - } else { - QLinearGradient grThree; - grThree.setColorAt(0.0, Qt::white); - grThree.setColorAt(0.05, Qt::black); - m_graph->seriesList().at(2)->setBaseGradient(grThree); - } -} - -void CustomItemGraph::toggleShadows(bool shadows) -{ - if (shadows) - m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualityMedium); - else - m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualityNone); -} - -void CustomItemGraph::handleElementSelected(QAbstract3DGraph::ElementType type) -{ - resetSelection(); - if (type == QAbstract3DGraph::ElementCustomItem) { - QCustom3DItem *item = m_graph->selectedCustomItem(); - QString text; - if (qobject_cast<QCustom3DLabel *>(item) != 0) { - text.append("Custom label: "); - } else { - QStringList split = item->meshFile().split("/"); - text.append(split.last()); - text.append(": "); - } - int index = m_graph->selectedCustomItemIndex(); - text.append(QString::number(index)); - m_textField->setText(text); - m_previouslyAnimatedItem = item; - m_previousScaling = item->scaling(); - m_selectionAnimation->setTargetObject(item); - m_selectionAnimation->setStartValue(item->scaling()); - m_selectionAnimation->setEndValue(item->scaling() * 1.5f); - m_selectionAnimation->start(); - } else if (type == QAbstract3DGraph::ElementSeries) { - QString text = "Surface ("; - QSurface3DSeries *series = m_graph->selectedSeries(); - if (series) { - QPoint point = series->selectedPoint(); - QString posStr; - posStr.setNum(point.x()); - text.append(posStr); - text.append(", "); - posStr.setNum(point.y()); - text.append(posStr); - } - text.append(")"); - m_textField->setText(text); - } else if (type > QAbstract3DGraph::ElementSeries - && type < QAbstract3DGraph::ElementCustomItem) { - int index = m_graph->selectedLabelIndex(); - QString text; - if (type == QAbstract3DGraph::ElementAxisXLabel) - text.append("Axis X label: "); - else if (type == QAbstract3DGraph::ElementAxisYLabel) - text.append("Axis Y label: "); - else - text.append("Axis Z label: "); - text.append(QString::number(index)); - m_textField->setText(text); - } else { - m_textField->setText("Nothing"); - } -} - -void CustomItemGraph::resetSelection() -{ - m_selectionAnimation->stop(); - if (m_previouslyAnimatedItem) - m_previouslyAnimatedItem->setScaling(m_previousScaling); - m_previouslyAnimatedItem = 0; -} diff --git a/examples/datavisualization/customitems/customitemgraph.h b/examples/datavisualization/customitems/customitemgraph.h deleted file mode 100644 index 4a3585d4..00000000 --- a/examples/datavisualization/customitems/customitemgraph.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -#ifndef CUSTOMITEMGRAPH_H -#define CUSTOMITEMGRAPH_H - -#include <QtDataVisualization/Q3DSurface> -#include <QtDataVisualization/QSurfaceDataProxy> -#include <QtDataVisualization/QHeightMapSurfaceDataProxy> -#include <QtDataVisualization/QSurface3DSeries> -#include <QtWidgets/QSlider> -#include <QtWidgets/QLabel> -#include <QtCore/QPropertyAnimation> - -class CustomItemGraph : public QObject -{ - Q_OBJECT -public: - explicit CustomItemGraph(Q3DSurface *surface, QLabel *label); - ~CustomItemGraph(); - - void toggleItemOne(bool show); - void toggleItemTwo(bool show); - void toggleItemThree(bool show); - void toggleSeeThrough(bool seethrough); - void toggleOilHighlight(bool highlight); - void toggleShadows(bool shadows); - -private: - void handleElementSelected(QAbstract3DGraph::ElementType type); - void resetSelection(); - -private: - Q3DSurface *m_graph; - QLabel *m_textField; - QPropertyAnimation *m_selectionAnimation; - QCustom3DItem *m_previouslyAnimatedItem; - QVector3D m_previousScaling; -}; - -#endif diff --git a/examples/datavisualization/customitems/customitems.pro b/examples/datavisualization/customitems/customitems.pro deleted file mode 100644 index d366e349..00000000 --- a/examples/datavisualization/customitems/customitems.pro +++ /dev/null @@ -1,19 +0,0 @@ -android|ios|winrt { - error( "This example is not supported for android, ios, or winrt." ) -} - -!include( ../examples.pri ) { - error( "Couldn't find the examples.pri file!" ) -} - -SOURCES += main.cpp \ - customitemgraph.cpp - -HEADERS += customitemgraph.h - -QT += widgets - -RESOURCES += customitems.qrc - -OTHER_FILES += doc/src/* \ - doc/images/* diff --git a/examples/datavisualization/customitems/customitems.qrc b/examples/datavisualization/customitems/customitems.qrc deleted file mode 100644 index 1337c9fc..00000000 --- a/examples/datavisualization/customitems/customitems.qrc +++ /dev/null @@ -1,12 +0,0 @@ -<RCC> - <qresource prefix="/maps"> - <file>layer_1.png</file> - <file>layer_2.png</file> - <file>layer_3.png</file> - </qresource> - <qresource prefix="/items"> - <file>refinery.obj</file> - <file>oilrig.obj</file> - <file>pipe.obj</file> - </qresource> -</RCC> diff --git a/examples/datavisualization/customitems/doc/images/customitems-example.png b/examples/datavisualization/customitems/doc/images/customitems-example.png Binary files differdeleted file mode 100644 index 2732638e..00000000 --- a/examples/datavisualization/customitems/doc/images/customitems-example.png +++ /dev/null diff --git a/examples/datavisualization/customitems/doc/src/customitems.qdoc b/examples/datavisualization/customitems/doc/src/customitems.qdoc deleted file mode 100644 index 3ff39332..00000000 --- a/examples/datavisualization/customitems/doc/src/customitems.qdoc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only - -/*! - \example customitems - \meta tags {DataVisualization, Q3DSurface, QCustom3DItem, Surface Graph} - \meta category {Graphics} - \title Custom Items in Graph - \ingroup qtdatavisualization_examples - \brief Adding custom items to a surface graph. - \since QtDataVisualization 1.1 - - The custom items example shows how to add your own custom meshes as items to a graph, and how - to remove them. - - \image customitems-example.png - - \include examples-run.qdocinc - - \section1 Adding Custom Meshes to the Application - - We'll add the meshes in a resource file: - - \code - <RCC> - ... - <qresource prefix="/items"> - <file>refinery.obj</file> - <file>oilrig.obj</file> - </qresource> - </RCC> - \endcode - - \section1 Adding Custom Item to a Graph - - In this example we do not have specific textures for our meshes, so we'll just create a small - QImage and fill it with a single color: - - \snippet customitems/customitemgraph.cpp 0 - - Then we'll specify the position for the item in a variable. This way we'll be able to use it - later for removing the correct item: - - \snippet customitems/customitemgraph.cpp 1 - - Then we'll create a new QCustom3DItem with all the parameters: - - \snippet customitems/customitemgraph.cpp 2 - - And finally we'll just add the item: - - \snippet customitems/customitemgraph.cpp 3 - - \section1 Removing Custom Item from a Graph - - We'll just call \c removeCustomItemAt() with the position of the item: - - \snippet customitems/customitemgraph.cpp 4 - - \note Removing a custom item from the graph also deletes it. If you want to preserve the item, - you need to use \c releaseCustomItem() method instead. - - \section1 Example Contents -*/ diff --git a/examples/datavisualization/customitems/main.cpp b/examples/datavisualization/customitems/main.cpp deleted file mode 100644 index c71d093a..00000000 --- a/examples/datavisualization/customitems/main.cpp +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -#include "customitemgraph.h" - -#include <QtWidgets/QApplication> -#include <QtWidgets/QWidget> -#include <QtWidgets/QHBoxLayout> -#include <QtWidgets/QVBoxLayout> -#include <QtWidgets/QCheckBox> -#include <QtWidgets/QLabel> -#include <QtWidgets/QMessageBox> - -int main(int argc, char **argv) -{ - qputenv("QSG_RHI_BACKEND", "opengl"); - QApplication app(argc, argv); - Q3DSurface *graph = new Q3DSurface(); - QWidget *container = QWidget::createWindowContainer(graph); - - if (!graph->hasContext()) { - QMessageBox msgBox; - msgBox.setText("Couldn't initialize the OpenGL context."); - msgBox.exec(); - return -1; - } - - container->setMinimumSize(QSize(800, 600)); - container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - container->setFocusPolicy(Qt::StrongFocus); - - QWidget *widget = new QWidget; - QHBoxLayout *hLayout = new QHBoxLayout(widget); - QVBoxLayout *vLayoutLeft = new QVBoxLayout(); - vLayoutLeft->setAlignment(Qt::AlignTop); - QVBoxLayout *vLayoutRight = new QVBoxLayout(); - vLayoutRight->setAlignment(Qt::AlignTop); - hLayout->addLayout(vLayoutLeft); - hLayout->addWidget(container, 1); - hLayout->addLayout(vLayoutRight); - - QFont font = QFont("Century Gothic", 14); - QLabel *label = new QLabel("Show:"); - font.setBold(true); - label->setFont(font); - vLayoutLeft->addWidget(label); - - font.setBold(false); - QCheckBox *checkboxOne = new QCheckBox("Oil Rig 1"); - checkboxOne->setChecked(true); - checkboxOne->setFont(font); - vLayoutLeft->addWidget(checkboxOne); - - QCheckBox *checkboxTwo = new QCheckBox("Oil Rig 2"); - checkboxTwo->setChecked(true); - checkboxTwo->setFont(font); - vLayoutLeft->addWidget(checkboxTwo); - - QCheckBox *checkboxThree = new QCheckBox("Refinery"); - checkboxThree->setFont(font); - vLayoutLeft->addWidget(checkboxThree); - - QLabel *label2 = new QLabel("Visuals:"); - font.setBold(true); - label2->setFont(font); - vLayoutRight->addWidget(label2); - - QCheckBox *checkboxOneRight = new QCheckBox("See-Through"); - font.setBold(false); - checkboxOneRight->setFont(font); - vLayoutRight->addWidget(checkboxOneRight); - - QCheckBox *checkboxTwoRight = new QCheckBox("Highlight Oil"); - checkboxTwoRight->setFont(font); - vLayoutRight->addWidget(checkboxTwoRight); - - QCheckBox *checkboxThreeRight = new QCheckBox("Shadows"); - checkboxThreeRight->setFont(font); - checkboxThreeRight->setChecked(true); - vLayoutRight->addWidget(checkboxThreeRight); - - QLabel *label3 = new QLabel("Selection:"); - font.setBold(true); - label3->setFont(font); - vLayoutRight->addWidget(label3); - - QLabel *label4 = new QLabel("Nothing"); - font.setBold(false); - font.setPointSize(11); - label4->setFont(font); - vLayoutRight->addWidget(label4); - - widget->setWindowTitle(QStringLiteral("Custom Items in Graph")); - - widget->show(); - - CustomItemGraph *modifier = new CustomItemGraph(graph, label4); - - QObject::connect(checkboxOne, &QCheckBox::stateChanged, - modifier, &CustomItemGraph::toggleItemOne); - QObject::connect(checkboxTwo, &QCheckBox::stateChanged, - modifier, &CustomItemGraph::toggleItemTwo); - QObject::connect(checkboxThree, &QCheckBox::stateChanged, - modifier, &CustomItemGraph::toggleItemThree); - - QObject::connect(checkboxOneRight, &QCheckBox::stateChanged, - modifier, &CustomItemGraph::toggleSeeThrough); - QObject::connect(checkboxTwoRight, &QCheckBox::stateChanged, - modifier, &CustomItemGraph::toggleOilHighlight); - QObject::connect(checkboxThreeRight, &QCheckBox::stateChanged, - modifier, &CustomItemGraph::toggleShadows); - - return app.exec(); -} diff --git a/examples/datavisualization/datavisualization.pro b/examples/datavisualization/datavisualization.pro index 8fbaa375..ff9af2c5 100644 --- a/examples/datavisualization/datavisualization.pro +++ b/examples/datavisualization/datavisualization.pro @@ -8,9 +8,6 @@ qtHaveModule(quick) { !android:!ios:!winrt { SUBDIRS += graphgallery \ - surface \ - customitems \ - texturesurface \ volumetric } diff --git a/examples/datavisualization/graphgallery/CMakeLists.txt b/examples/datavisualization/graphgallery/CMakeLists.txt index cde7adc7..0f16b1bc 100644 --- a/examples/datavisualization/graphgallery/CMakeLists.txt +++ b/examples/datavisualization/graphgallery/CMakeLists.txt @@ -32,6 +32,11 @@ qt_add_executable(graphgallery scattergraph.cpp scattergraph.h scatterdatamodifier.cpp scatterdatamodifier.h axesinputhandler.cpp axesinputhandler.h + surfacegraph.cpp surfacegraph.h + surfacegraphmodifier.cpp surfacegraphmodifier.h + custominputhandler.cpp custominputhandler.h + highlightseries.cpp highlightseries.h + topographicseries.cpp topographicseries.h ) set_target_properties(graphgallery PROPERTIES WIN32_EXECUTABLE TRUE @@ -46,6 +51,14 @@ target_link_libraries(graphgallery PUBLIC set(graphgallery_resource_files "data/raindata.txt" + "data/layer_1.png" + "data/layer_2.png" + "data/layer_3.png" + "data/oilrig.obj" + "data/pipe.obj" + "data/refinery.obj" + "data/maptexture.jpg" + "data/topography.png" ) qt6_add_resources(graphgallery "graphgallery" diff --git a/examples/datavisualization/texturesurface/custominputhandler.cpp b/examples/datavisualization/graphgallery/custominputhandler.cpp index 98b14bdc..e02f1585 100644 --- a/examples/datavisualization/texturesurface/custominputhandler.cpp +++ b/examples/datavisualization/graphgallery/custominputhandler.cpp @@ -1,19 +1,13 @@ -// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "custominputhandler.h" -#include <QtDataVisualization/Q3DCamera> +#include <QtDataVisualization/q3dcamera.h> #include <QtCore/qmath.h> CustomInputHandler::CustomInputHandler(QAbstract3DGraph *graph, QObject *parent) : - Q3DInputHandler(parent), - m_highlight(0), - m_mousePressed(false), - m_state(StateNormal), - m_axisX(0), - m_axisZ(0), - m_speedModifier(20.0f) + Q3DInputHandler(parent) { // Connect to the item selection signal from graph connect(graph, &QAbstract3DGraph::selectedElementChanged, this, @@ -43,7 +37,7 @@ void CustomInputHandler::wheelEvent(QWheelEvent *event) float y = (m_axisXMaxValue - m_axisXMinValue) * m_aspectRatio; m_axisX->setRange(m_axisXMinValue, m_axisXMaxValue); - m_axisY->setRange(100.0f, y); + m_axisY->setRange(100.f, y); m_axisZ->setRange(m_axisZMinValue, m_axisZMaxValue); } //! [1] @@ -84,7 +78,7 @@ void CustomInputHandler::handleElementSelected(QAbstract3DGraph::ElementType typ void CustomInputHandler::handleAxisDragging() { - float distance = 0.0f; + float distance = 0.f; // Get scene orientation from active camera float xRotation = scene()->activeCamera()->xRotation(); @@ -100,7 +94,7 @@ void CustomInputHandler::handleAxisDragging() // Adjust axes switch (m_state) { -//! [0] + //! [0] case StateDraggingX: distance = (move.x() * xMulX - move.y() * xMulY) * m_speedModifier; m_axisXMinValue -= distance; @@ -117,7 +111,7 @@ void CustomInputHandler::handleAxisDragging() } m_axisX->setRange(m_axisXMinValue, m_axisXMaxValue); break; -//! [0] + //! [0] case StateDraggingZ: distance = (move.x() * zMulX + move.y() * zMulY) * m_speedModifier; m_axisZMinValue += distance; @@ -141,18 +135,18 @@ void CustomInputHandler::handleAxisDragging() void CustomInputHandler::checkConstraints() { -//! [2] + //! [2] if (m_axisXMinValue < m_areaMinValue) m_axisXMinValue = m_areaMinValue; if (m_axisXMaxValue > m_areaMaxValue) m_axisXMaxValue = m_areaMaxValue; // Don't allow too much zoom in if ((m_axisXMaxValue - m_axisXMinValue) < m_axisXMinRange) { - float adjust = (m_axisXMinRange - (m_axisXMaxValue - m_axisXMinValue)) / 2.0f; + float adjust = (m_axisXMinRange - (m_axisXMaxValue - m_axisXMinValue)) / 2.f; m_axisXMinValue -= adjust; m_axisXMaxValue += adjust; } -//! [2] + //! [2] if (m_axisZMinValue < m_areaMinValue) m_axisZMinValue = m_areaMinValue; @@ -160,7 +154,7 @@ void CustomInputHandler::checkConstraints() m_axisZMaxValue = m_areaMaxValue; // Don't allow too much zoom in if ((m_axisZMaxValue - m_axisZMinValue) < m_axisZMinRange) { - float adjust = (m_axisZMinRange - (m_axisZMaxValue - m_axisZMinValue)) / 2.0f; + float adjust = (m_axisZMinRange - (m_axisZMaxValue - m_axisZMinValue)) / 2.f; m_axisZMinValue -= adjust; m_axisZMaxValue += adjust; } diff --git a/examples/datavisualization/texturesurface/custominputhandler.h b/examples/datavisualization/graphgallery/custominputhandler.h index 2231248c..6ae11b60 100644 --- a/examples/datavisualization/texturesurface/custominputhandler.h +++ b/examples/datavisualization/graphgallery/custominputhandler.h @@ -1,14 +1,15 @@ -// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef CUSTOMINPUTHANDLER_H #define CUSTOMINPUTHANDLER_H -#include <QtDataVisualization/Q3DInputHandler> -#include <QtDataVisualization/QAbstract3DGraph> -#include <QtDataVisualization/QValue3DAxis> #include "highlightseries.h" +#include <QtDataVisualization/q3dinputhandler.h> +#include <QtDataVisualization/qabstract3dgraph.h> +#include <QtDataVisualization/qvalue3daxis.h> + class CustomInputHandler : public Q3DInputHandler { Q_OBJECT @@ -42,6 +43,7 @@ public: inline void setHighlightSeries(HighlightSeries *series) { m_highlight = series; } inline void setDragSpeedModifier(float modifier) { m_speedModifier = modifier; } +protected: virtual void mousePressEvent(QMouseEvent *event, const QPoint &mousePos); virtual void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos); virtual void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos); @@ -53,22 +55,22 @@ private: void checkConstraints(); private: - HighlightSeries *m_highlight; - bool m_mousePressed; - InputState m_state; - QValue3DAxis *m_axisX; - QValue3DAxis *m_axisY; - QValue3DAxis *m_axisZ; - float m_speedModifier; - float m_aspectRatio; - float m_axisXMinValue; - float m_axisXMaxValue; - float m_axisXMinRange; - float m_axisZMinValue; - float m_axisZMaxValue; - float m_axisZMinRange; - float m_areaMinValue; - float m_areaMaxValue; + HighlightSeries *m_highlight = nullptr; + bool m_mousePressed = false; + InputState m_state = StateNormal; + QValue3DAxis *m_axisX = nullptr; + QValue3DAxis *m_axisY = nullptr; + QValue3DAxis *m_axisZ = nullptr; + float m_speedModifier = 20.f; + float m_aspectRatio = 0.f; + float m_axisXMinValue = 0.f; + float m_axisXMaxValue = 0.f; + float m_axisXMinRange = 0.f; + float m_axisZMinValue = 0.f; + float m_axisZMaxValue = 0.f; + float m_axisZMinRange = 0.f; + float m_areaMinValue = 0.f; + float m_areaMaxValue = 0.f; }; #endif diff --git a/examples/datavisualization/customitems/layer_1.png b/examples/datavisualization/graphgallery/data/layer_1.png Binary files differindex 9138c710..9138c710 100644 --- a/examples/datavisualization/customitems/layer_1.png +++ b/examples/datavisualization/graphgallery/data/layer_1.png diff --git a/examples/datavisualization/customitems/layer_2.png b/examples/datavisualization/graphgallery/data/layer_2.png Binary files differindex 61631ae8..61631ae8 100644 --- a/examples/datavisualization/customitems/layer_2.png +++ b/examples/datavisualization/graphgallery/data/layer_2.png diff --git a/examples/datavisualization/customitems/layer_3.png b/examples/datavisualization/graphgallery/data/layer_3.png Binary files differindex 066ffbe7..066ffbe7 100644 --- a/examples/datavisualization/customitems/layer_3.png +++ b/examples/datavisualization/graphgallery/data/layer_3.png diff --git a/examples/datavisualization/texturesurface/license.txt b/examples/datavisualization/graphgallery/data/license.txt index 749daf31..749daf31 100644 --- a/examples/datavisualization/texturesurface/license.txt +++ b/examples/datavisualization/graphgallery/data/license.txt diff --git a/examples/datavisualization/texturesurface/maptexture.jpg b/examples/datavisualization/graphgallery/data/maptexture.jpg Binary files differindex ae5d66eb..ae5d66eb 100644 --- a/examples/datavisualization/texturesurface/maptexture.jpg +++ b/examples/datavisualization/graphgallery/data/maptexture.jpg diff --git a/examples/datavisualization/customitems/oilrig.obj b/examples/datavisualization/graphgallery/data/oilrig.obj index c3b6ea57..c3b6ea57 100644 --- a/examples/datavisualization/customitems/oilrig.obj +++ b/examples/datavisualization/graphgallery/data/oilrig.obj diff --git a/examples/datavisualization/customitems/pipe.obj b/examples/datavisualization/graphgallery/data/pipe.obj index 6ccbb286..6ccbb286 100644 --- a/examples/datavisualization/customitems/pipe.obj +++ b/examples/datavisualization/graphgallery/data/pipe.obj diff --git a/examples/datavisualization/customitems/refinery.obj b/examples/datavisualization/graphgallery/data/refinery.obj index ed90c361..ed90c361 100644 --- a/examples/datavisualization/customitems/refinery.obj +++ b/examples/datavisualization/graphgallery/data/refinery.obj diff --git a/examples/datavisualization/texturesurface/topography.png b/examples/datavisualization/graphgallery/data/topography.png Binary files differindex 9349cdb3..9349cdb3 100644 --- a/examples/datavisualization/texturesurface/topography.png +++ b/examples/datavisualization/graphgallery/data/topography.png diff --git a/examples/datavisualization/graphgallery/doc/images/graphgallery-example.png b/examples/datavisualization/graphgallery/doc/images/graphgallery-example.png Binary files differnew file mode 100644 index 00000000..f3320c8e --- /dev/null +++ b/examples/datavisualization/graphgallery/doc/images/graphgallery-example.png diff --git a/examples/datavisualization/graphgallery/doc/src/graphgallery.qdoc b/examples/datavisualization/graphgallery/doc/src/graphgallery.qdoc index 240fb359..aca8c1a7 100644 --- a/examples/datavisualization/graphgallery/doc/src/graphgallery.qdoc +++ b/examples/datavisualization/graphgallery/doc/src/graphgallery.qdoc @@ -1,9 +1,9 @@ -// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! \example graphgallery - \meta tags {DataVisualization, Q3DBars, Bar Graph, Custom Proxy, Q3DScatter, Scatter Graph, Custom Input Handler} + \meta tags {DataVisualization, Q3DBars, Bar Graph, Custom Proxy, Q3DScatter, Scatter Graph, Custom Input Handler, Q3DSurface, Surface Graph, QCustom3DItem, Textured Surface} \meta category {Graphics} \title Graph Gallery \ingroup qtdatavisualization_examples @@ -12,7 +12,7 @@ \e {Graph Gallery} demonstrates all three graph types and some of their special features. The graphs have their own tabs in the application. - \image qmlgraphgallery-example.png + \image graphgallery-example.png \include examples-run.qdocinc @@ -418,5 +418,286 @@ You could also adjust the modifier automatically based on the axis range and camera zoom level. + \section1 Surface Graph + + In the \uicontrol {Surface Graph} tab, create a 3D surface graph using Q3DSurface. + The example shows how to: + + \list + \li Set up a basic QSurfaceDataProxy and set data for it. + \li Use QHeightMapSurfaceDataProxy for showing 3D height maps. + \li Use topographic data to create 3D height maps. + \li Use three different selection modes for studying the graph. + \li Use axis ranges to display selected portions of the graph. + \li Set a custom surface gradient. + \li Add custom items and labels with QCustom3DItem and QCustom3DLabel. + \li Use custom input handler to enable zooming and panning. + \li Highlight an area of the surface. + \endlist + + For basic application creation, see \l {Bar Graph}. + + \section2 Simple Surface with Generated Data + + First, instantiate a new QSurfaceDataProxy and attach it to a new QSurface3DSeries: + + \snippet graphgallery/surfacegraphmodifier.cpp 0 + + Then, fill the proxy with a simple square root and sine wave data. Create a new + \c QSurfaceDataArray instance, and add \c QSurfaceDataRow elements to it. + Set the created \c QSurfaceDataArray as the data array for the QSurfaceDataProxy by calling + \c{resetArray()}. + + \snippet graphgallery/surfacegraphmodifier.cpp 1 + + \section2 Multiseries Height Map Data + + Create the height map by instantiating a QHeightMapSurfaceDataProxy with a QImage containing + the height data. Use QHeightMapSurfaceDataProxy::setValueRanges() to define the + value range of the map. In the example, the map is from an imaginary position of + 34.0\unicode 0x00B0 N - 40.0\unicode 0x00B0 N and 18.0\unicode 0x00B0 E - 24.0\unicode 0x00B0 E. + These values are used to position the map on the axes. + + \snippet graphgallery/surfacegraphmodifier.cpp 2 + + Add the other surface layers the same way, by creating a proxy and a series for them using + height map images. + + \section2 Topographic Map Data + + The topographic data is obtained from the National Land Survey of Finland. It provides a product + called \c{Elevation Model 2 m}, which is suitable for this example. + The topography data is from Levi fell. The accuracy of the data is well beyond the need, and + therefore it is compressed and encoded into a PNG file. The height value of the original + ASCII data is encoded into RGB format using a multiplier, which you will see later in + a code extract. The multiplier is calculated by dividing the largest 24-bit value with the + highest point in Finland. + + QHeightMapSurfaceDataProxy converts only one-byte values. To utilize the higher accuracy of + the data from the National Land Survey of Finland, read the data from the PNG file and decode + it into QSurface3DSeries. + + First, define the encoding multiplier: + + \snippet graphgallery/topographicseries.cpp 0 + + Then, perform the actual decoding: + + \snippet graphgallery/topographicseries.cpp 1 + + Now, the data is usable by the proxy. + + \section2 Selecting the Data Set + + To demonstrate different proxies, \uicontrol {Surface Graph} has three radio buttons to + switch between the series. + + With \uicontrol {Sqrt & Sin}, the simple generated series is activated. First, set + the decorative features, such as enabling the grid for the surface, and selecting the flat + shading mode. Next, define the axis label format and value ranges. Set automatic label rotation + to improve label readability at low camera angles. Finally, make sure the correct series is + added to the graph and the others are not: + + \snippet graphgallery/surfacegraphmodifier.cpp 3 + + With \uicontrol {Multiseries Height Map}, the height map series are activated and others + disabled. Auto-adjusting Y-axis range works well for the height map surface, so ensure it is + set. + + \snippet graphgallery/surfacegraphmodifier.cpp 4 + + With \uicontrol {Textured Topography}, the topographic series is activated and others disabled. + Activate a custom input handler for this series, to be able to highlight areas on it: + + \snippet graphgallery/surfacegraphmodifier.cpp 5 + + See \l {Use Custom Input Handler to Enable Zooming and Panning} for information about the + custom input handler for this data set. + + \section2 Selection Modes + + The three selection modes supported by Q3DSurface can be used with radio buttons. + To activate the selected mode or to clear it, add the following inline methods: + + \snippet graphgallery/surfacegraphmodifier.h 0 + + Add \c{QAbstract3DGraph::SelectionSlice} and \c{QAbstract3DGraph::SelectionMultiSeries} flags + for the row and column selection modes to support doing a slice selection to all visible series + in the graph simultaneously. + + \section2 Axis Ranges for Studying the Graph + + The example has four slider controls for adjusting the min and max values for X and Z + axes. When selecting the proxy, these sliders are adjusted to match the axis ranges of the + current data set: + + \snippet graphgallery/surfacegraphmodifier.cpp 6 + + Add support for setting the X range from the widget controls to the graph: + + \snippet graphgallery/surfacegraphmodifier.cpp 7 + + Add the support for Z range the same way. + + \section2 Custom Surface Gradients + + With the \uicontrol {Sqrt & Sin} data set, custom surface gradients can be taken into use + with two push buttons. Define the gradient with QLinearGradient, where the desired colors are + set. Also, change the color style to Q3DTheme::ColorStyleRangeGradient to use the gradient. + + \snippet graphgallery/surfacegraphmodifier.cpp 8 + + \section2 Adding Custom Meshes to the Application + + Add the mesh files to \c{CMakeLists.txt} for cmake build: + + \badcode + set(graphgallery_resource_files + ... + "data/oilrig.obj" + "data/pipe.obj" + "data/refinery.obj" + ... + ) + + qt6_add_resources(graphgallery "graphgallery" + PREFIX + "/" + FILES + ${graphgallery_resource_files} + ) + \endcode + + Also, add them in the qrc resource file for use with qmake: + + \badcode + <RCC> + <qresource prefix="/"> + ... + <file>data/refinery.obj</file> + <file>data/oilrig.obj</file> + <file>data/pipe.obj</file> + ... + </qresource> + </RCC> + \endcode + + \section2 Adding Custom Item to a Graph + + With the \uicontrol {Multiseries Height Map} data set, custom items are inserted into the + graph and can be toggled on or off using checkboxes. Other visual qualities can also be + controlled with another set of checkboxes, including see-through for the two top layers, and + a highlight for the bottom layer. + + Begin by creating a small QImage. Fill it with a single color to use as the color for the + custom object: + + \snippet graphgallery/surfacegraphmodifier.cpp 9 + + Then, specify the position of the item in a variable. The position can then be used for + removing the correct item from the graph: + + \snippet graphgallery/surfacegraphmodifier.cpp 10 + + Then, create a new QCustom3DItem with all the parameters: + + \snippet graphgallery/surfacegraphmodifier.cpp 11 + + Finally, add the item to the graph: + + \snippet graphgallery/surfacegraphmodifier.cpp 12 + + \section2 Adding Custom Label to a Graph + + Adding a custom label is very similar to adding a custom item. For the label, a custom mesh is + not needed, but just a QCustom3DLabel instance: + + \snippet graphgallery/surfacegraphmodifier.cpp 13 + + \section2 Removing Custom Item from a Graph + + To remove a specific item from the graph, call \c removeCustomItemAt() with the position of + the item: + + \snippet graphgallery/surfacegraphmodifier.cpp 14 + + \note Removing a custom item from the graph also deletes the object. If you want to preserve + the item, use the \c releaseCustomItem() method instead. + + \section2 Texture to a Surface Series + + With the \uicontrol {Textured Topography} data set, create a map texture to be used with the + topographic height map. + + Set an image to be used as the texture on a surface with QSurface3DSeries::setTextureFile(). + Add a check box to control if the texture is set or not, and a handler to react to the checkbox + state: + + \snippet graphgallery/surfacegraphmodifier.cpp 15 + + The image in this example is read from a JPG file. Setting an empty file with the method clears + the texture, and the surface uses the gradients or colors from the theme. + + \section2 Use Custom Input Handler to Enable Zooming and Panning + + With the \uicontrol {Textured Topography} data set, create a custom input handler to + highlight the selection on the graph and allow panning the graph. + + The panning implementation is similar to the one shown in \l{Implementing Axis Dragging}. + The difference is that, in this example, you follow only the X and Z axes and don't allow + dragging the surface outside the graph. To limit the dragging, follow the limits of the axes + and do nothing if going outside the graph: + + \snippet graphgallery/custominputhandler.cpp 0 + + For zooming, catch the \c wheelEvent and adjust the X and Y axis ranges according to the delta + value on QWheelEvent. Adjust the Y axis so that the aspect ratio between the Y axis and the XZ + plane stays the same. This prevents getting a graph in which the height is exaggerated: + + \snippet graphgallery/custominputhandler.cpp 1 + + Next, add some limits to the zoom level, so that it won't get too near to or far from the + surface. For instance, if the value for the X axis gets below the allowed limit, i.e. zooming + gets too far, the value is set to the minimum allowed value. If the range is going to below + the range minimum, both ends of the axis are adjusted so that the range stays at the limit: + + \snippet graphgallery/custominputhandler.cpp 2 + + \section2 Highlight an Area of the Surface + + To implement a highlight to be displayed on the surface, create a copy of the series and add + some offset to the y value. In this example, the class \c HighlightSeries implements the + creation of the copy in its \c handlePositionChange method. + + First, give \c HighlightSeries the pointer to the original series, and then start listening to + the QSurface3DSeries::selectedPointChanged signal: + + \snippet graphgallery/highlightseries.cpp 0 + + When the signal triggers, check that the position is valid. Then, calculate the ranges + for the copied area, and check that they stay within the bounds. Finally, fill the data array + of the highlight series with the range from the data array of the topography series: + + \snippet graphgallery/highlightseries.cpp 1 + + \section2 A Gradient to the Highlight Series + + Since the \c HighlightSeries is QSurface3DSeries, all the decoration methods a series can + have are available. In this example, add a gradient to emphasize the elevation. Because the + suitable gradient style depends on the range of the Y axis and we change the range when + zooming, the gradient color positions need to be adjusted as the range changes. Do this by + defining proportional values for the gradient color positions: + + \snippet graphgallery/highlightseries.cpp 2 + + The gradient modification is done in the \c handleGradientChange method, so connect it to + react to changes on the Y axis: + + \snippet graphgallery/surfacegraphmodifier.cpp 16 + + When a change in the Y axis max value happens, calculate the new gradient color positions: + + \snippet graphgallery/highlightseries.cpp 3 + \section1 Example Contents */ diff --git a/examples/datavisualization/graphgallery/graphgallery.pro b/examples/datavisualization/graphgallery/graphgallery.pro index 56ccde61..c9bd96f6 100644 --- a/examples/datavisualization/graphgallery/graphgallery.pro +++ b/examples/datavisualization/graphgallery/graphgallery.pro @@ -19,9 +19,15 @@ SOURCES += main.cpp \ variantbardatamapping.cpp \ scattergraph.cpp \ scatterdatamodifier.cpp \ - axesinputhandler.cpp + axesinputhandler.cpp \ + surfacegraph.cpp \ + surfacegraphmodifier.cpp \ + custominputhandler.cpp \ + highlightseries.cpp \ + topographicseries.cpp -HEADERS += bargraph.h \ +HEADERS += \ + bargraph.h \ graphmodifier.h \ rainfalldata.h \ variantdataset.h \ @@ -29,10 +35,15 @@ HEADERS += bargraph.h \ variantbardatamapping.h \ scattergraph.h \ scatterdatamodifier.h \ - axesinputhandler.h + axesinputhandler.h \ + surfacegraph.h \ + surfacegraphmodifier.h \ + custominputhandler.h \ + highlightseries.h \ + topographicseries.h RESOURCES += graphgallery.qrc OTHER_FILES += doc/src/* \ doc/images/* \ - data/raindata.txt + data/* diff --git a/examples/datavisualization/graphgallery/graphgallery.qrc b/examples/datavisualization/graphgallery/graphgallery.qrc index 53cd4915..6df5703d 100644 --- a/examples/datavisualization/graphgallery/graphgallery.qrc +++ b/examples/datavisualization/graphgallery/graphgallery.qrc @@ -1,5 +1,13 @@ <RCC> <qresource prefix="/"> <file>data/raindata.txt</file> + <file>data/layer_1.png</file> + <file>data/layer_2.png</file> + <file>data/layer_3.png</file> + <file>data/refinery.obj</file> + <file>data/oilrig.obj</file> + <file>data/pipe.obj</file> + <file>data/maptexture.jpg</file> + <file>data/topography.png</file> </qresource> </RCC> diff --git a/examples/datavisualization/texturesurface/highlightseries.cpp b/examples/datavisualization/graphgallery/highlightseries.cpp index fb567d5c..c2aab2db 100644 --- a/examples/datavisualization/texturesurface/highlightseries.cpp +++ b/examples/datavisualization/graphgallery/highlightseries.cpp @@ -1,10 +1,10 @@ -// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "highlightseries.h" //! [2] -const float darkRedPos = 1.0f; +const float darkRedPos = 1.f; const float redPos = 0.8f; const float yellowPos = 0.6f; const float greenPos = 0.4f; @@ -12,8 +12,6 @@ const float darkGreenPos = 0.2f; //! [2] HighlightSeries::HighlightSeries() - : m_width(100), - m_height(100) { setDrawMode(QSurface3DSeries::DrawSurface); setFlatShadingEnabled(true); @@ -43,7 +41,6 @@ void HighlightSeries::handlePositionChange(const QPoint &position) if (position == invalidSelectionPosition()) { setVisible(false); - return; } @@ -89,7 +86,7 @@ void HighlightSeries::handleGradientChange(float value) float ratio = m_minHeight / value; QLinearGradient gr; - gr.setColorAt(0.0f, Qt::black); + gr.setColorAt(0.f, Qt::black); gr.setColorAt(darkGreenPos * ratio, Qt::darkGreen); gr.setColorAt(greenPos * ratio, Qt::green); gr.setColorAt(yellowPos * ratio, Qt::yellow); diff --git a/examples/datavisualization/texturesurface/highlightseries.h b/examples/datavisualization/graphgallery/highlightseries.h index 10d53530..deb4c45f 100644 --- a/examples/datavisualization/texturesurface/highlightseries.h +++ b/examples/datavisualization/graphgallery/highlightseries.h @@ -1,10 +1,10 @@ -// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef HIGHLIGHTSERIES_H #define HIGHLIGHTSERIES_H -#include <QtDataVisualization/QSurface3DSeries> +#include <QtDataVisualization/qsurface3dseries.h> #include "topographicseries.h" @@ -23,13 +23,13 @@ public Q_SLOTS: void handleGradientChange(float value); private: - int m_width; - int m_height; - int m_srcWidth; - int m_srcHeight; - QPoint m_position; - TopographicSeries *m_topographicSeries; - float m_minHeight; + int m_width = 100; + int m_height = 100; + int m_srcWidth = 0; + int m_srcHeight = 0; + QPoint m_position = {}; + TopographicSeries *m_topographicSeries = nullptr; + float m_minHeight = 0.f; }; #endif // HIGHLIGHTSERIES_H diff --git a/examples/datavisualization/graphgallery/main.cpp b/examples/datavisualization/graphgallery/main.cpp index 0d42388e..005ca1bf 100644 --- a/examples/datavisualization/graphgallery/main.cpp +++ b/examples/datavisualization/graphgallery/main.cpp @@ -3,6 +3,7 @@ #include "bargraph.h" #include "scattergraph.h" +#include "surfacegraph.h" #include <QtWidgets/qapplication.h> #include <QtWidgets/qwidget.h> @@ -24,6 +25,11 @@ int main(int argc, char **argv) if (!scatter->initialize()) return -1; + // Create surface graph + SurfaceGraph *surface = new SurfaceGraph(); + if (!surface->initialize()) + return -1; + // Create a tab widget for creating own tabs for Q3DBars, Q3DScatter, and Q3DSurface QTabWidget *tabWidget = new QTabWidget(); tabWidget->setWindowTitle(QLatin1String("Graph Gallery")); @@ -32,6 +38,8 @@ int main(int argc, char **argv) tabWidget->addTab(bars->barsWidget(), QLatin1String("Bar Graph")); // Add scatter widget tabWidget->addTab(scatter->scatterWidget(), QLatin1String("Scatter Graph")); + // Add surface widget + tabWidget->addTab(surface->surfaceWidget(), QLatin1String("Surface Graph")); tabWidget->show(); return app.exec(); diff --git a/examples/datavisualization/graphgallery/surfacegraph.cpp b/examples/datavisualization/graphgallery/surfacegraph.cpp new file mode 100644 index 00000000..5731e5a2 --- /dev/null +++ b/examples/datavisualization/graphgallery/surfacegraph.cpp @@ -0,0 +1,335 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "surfacegraph.h" +#include "surfacegraphmodifier.h" + +#include <QtWidgets/qboxlayout.h> +#include <QtWidgets/qcheckbox.h> +#include <QtWidgets/qcombobox.h> +#include <QtWidgets/qradiobutton.h> +#include <QtWidgets/qgroupbox.h> +#include <QtWidgets/qlabel.h> +#include <QtWidgets/qmessagebox.h> +#include <QtWidgets/qcommandlinkbutton.h> +#include <QtGui/qpainter.h> + +SurfaceGraph::SurfaceGraph() +{ + m_surfaceGraph = new Q3DSurface(); + m_container = QWidget::createWindowContainer(m_surfaceGraph); +} + +SurfaceGraph::~SurfaceGraph() +{ + delete m_container; +} + +bool SurfaceGraph::initialize() +{ + if (!m_surfaceGraph->hasContext()) { + QMessageBox msgBox; + msgBox.setText("Couldn't initialize the OpenGL context."); + msgBox.exec(); + return -1; + } + + QSize screenSize = m_surfaceGraph->screen()->size(); + m_container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 1.75)); + m_container->setMaximumSize(screenSize); + m_container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_container->setFocusPolicy(Qt::StrongFocus); + + m_surfaceWidget = new QWidget; + QHBoxLayout *hLayout = new QHBoxLayout(m_surfaceWidget); + QVBoxLayout *vLayout = new QVBoxLayout(); + hLayout->addWidget(m_container, 1); + hLayout->addLayout(vLayout); + vLayout->setAlignment(Qt::AlignTop); + + // Create control widgets + QGroupBox *modelGroupBox = new QGroupBox(QLatin1String("Model")); + + QRadioButton *sqrtSinModelRB = new QRadioButton(m_surfaceWidget); + sqrtSinModelRB->setText(QLatin1String("Sqrt && Sin")); + sqrtSinModelRB->setChecked(false); + + QRadioButton *heightMapModelRB = new QRadioButton(m_surfaceWidget); + heightMapModelRB->setText(QLatin1String("Multiseries\nHeight Map")); + heightMapModelRB->setChecked(false); + + QRadioButton *texturedModelRB = new QRadioButton(m_surfaceWidget); + texturedModelRB->setText(QLatin1String("Textured\nTopography")); + texturedModelRB->setChecked(false); + + QVBoxLayout *modelVBox = new QVBoxLayout; + modelVBox->addWidget(sqrtSinModelRB); + modelVBox->addWidget(heightMapModelRB); + modelVBox->addWidget(texturedModelRB); + modelGroupBox->setLayout(modelVBox); + + QGroupBox *selectionGroupBox = new QGroupBox(QLatin1String("Graph Selection Mode")); + + QRadioButton *modeNoneRB = new QRadioButton(m_surfaceWidget); + modeNoneRB->setText(QLatin1String("No selection")); + modeNoneRB->setChecked(false); + + QRadioButton *modeItemRB = new QRadioButton(m_surfaceWidget); + modeItemRB->setText(QLatin1String("Item")); + modeItemRB->setChecked(false); + + QRadioButton *modeSliceRowRB = new QRadioButton(m_surfaceWidget); + modeSliceRowRB->setText(QLatin1String("Row Slice")); + modeSliceRowRB->setChecked(false); + + QRadioButton *modeSliceColumnRB = new QRadioButton(m_surfaceWidget); + modeSliceColumnRB->setText(QLatin1String("Column Slice")); + modeSliceColumnRB->setChecked(false); + + QVBoxLayout *selectionVBox = new QVBoxLayout; + selectionVBox->addWidget(modeNoneRB); + selectionVBox->addWidget(modeItemRB); + selectionVBox->addWidget(modeSliceRowRB); + selectionVBox->addWidget(modeSliceColumnRB); + selectionGroupBox->setLayout(selectionVBox); + + QGroupBox *axisGroupBox = new QGroupBox(QLatin1String("Axis ranges")); + + QSlider *axisMinSliderX = new QSlider(Qt::Horizontal); + axisMinSliderX->setMinimum(0); + axisMinSliderX->setTickInterval(1); + axisMinSliderX->setEnabled(true); + QSlider *axisMaxSliderX = new QSlider(Qt::Horizontal); + axisMaxSliderX->setMinimum(1); + axisMaxSliderX->setTickInterval(1); + axisMaxSliderX->setEnabled(true); + QSlider *axisMinSliderZ = new QSlider(Qt::Horizontal); + axisMinSliderZ->setMinimum(0); + axisMinSliderZ->setTickInterval(1); + axisMinSliderZ->setEnabled(true); + QSlider *axisMaxSliderZ = new QSlider(Qt::Horizontal); + axisMaxSliderZ->setMinimum(1); + axisMaxSliderZ->setTickInterval(1); + axisMaxSliderZ->setEnabled(true); + + QVBoxLayout *axisVBox = new QVBoxLayout; + axisVBox->addWidget(new QLabel(QLatin1String("Column range"))); + axisVBox->addWidget(axisMinSliderX); + axisVBox->addWidget(axisMaxSliderX); + axisVBox->addWidget(new QLabel(QLatin1String("Row range"))); + axisVBox->addWidget(axisMinSliderZ); + axisVBox->addWidget(axisMaxSliderZ); + axisGroupBox->setLayout(axisVBox); + + // Mode-dependent controls + // sqrt-sin + QGroupBox *colorGroupBox = new QGroupBox(QLatin1String("Custom gradient")); + + QLinearGradient grBtoY(0, 0, 1, 100); + grBtoY.setColorAt(1.f, Qt::black); + grBtoY.setColorAt(0.67f, Qt::blue); + grBtoY.setColorAt(0.33f, Qt::red); + grBtoY.setColorAt(0.f, Qt::yellow); + QPixmap pm(24, 100); + QPainter pmp(&pm); + pmp.setBrush(QBrush(grBtoY)); + pmp.setPen(Qt::NoPen); + pmp.drawRect(0, 0, 24, 100); + QPushButton *gradientBtoYPB = new QPushButton(m_surfaceWidget); + gradientBtoYPB->setIcon(QIcon(pm)); + gradientBtoYPB->setIconSize(QSize(24, 100)); + + QLinearGradient grGtoR(0, 0, 1, 100); + grGtoR.setColorAt(1.f, Qt::darkGreen); + grGtoR.setColorAt(0.5f, Qt::yellow); + grGtoR.setColorAt(0.2f, Qt::red); + grGtoR.setColorAt(0.f, Qt::darkRed); + pmp.setBrush(QBrush(grGtoR)); + pmp.drawRect(0, 0, 24, 100); + QPushButton *gradientGtoRPB = new QPushButton(m_surfaceWidget); + gradientGtoRPB->setIcon(QIcon(pm)); + gradientGtoRPB->setIconSize(QSize(24, 100)); + + QHBoxLayout *colorHBox = new QHBoxLayout; + colorHBox->addWidget(gradientBtoYPB); + colorHBox->addWidget(gradientGtoRPB); + colorGroupBox->setLayout(colorHBox); + + // Multiseries heightmap + QGroupBox *showGroupBox = new QGroupBox(QLatin1String("Show Object")); + showGroupBox->setVisible(false); + + QCheckBox *checkboxShowOilRigOne = new QCheckBox(QLatin1String("Oil Rig 1")); + checkboxShowOilRigOne->setChecked(true); + + QCheckBox *checkboxShowOilRigTwo = new QCheckBox(QLatin1String("Oil Rig 2")); + checkboxShowOilRigTwo->setChecked(true); + + QCheckBox *checkboxShowRefinery = new QCheckBox(QLatin1String("Refinery")); + + QVBoxLayout *showVBox = new QVBoxLayout; + showVBox->addWidget(checkboxShowOilRigOne); + showVBox->addWidget(checkboxShowOilRigTwo); + showVBox->addWidget(checkboxShowRefinery); + showGroupBox->setLayout(showVBox); + + QGroupBox *visualsGroupBox = new QGroupBox(QLatin1String("Visuals")); + visualsGroupBox->setVisible(false); + + QCheckBox *checkboxVisualsSeeThrough = new QCheckBox(QLatin1String("See-Through")); + + QCheckBox *checkboxHighlightOil = new QCheckBox(QLatin1String("Highlight Oil")); + + QCheckBox *checkboxShowShadows = new QCheckBox(QLatin1String("Shadows")); + checkboxShowShadows->setChecked(true); + + QVBoxLayout *visualVBox = new QVBoxLayout; + visualVBox->addWidget(checkboxVisualsSeeThrough); + visualVBox->addWidget(checkboxHighlightOil); + visualVBox->addWidget(checkboxShowShadows); + visualsGroupBox->setLayout(visualVBox); + + QLabel *labelSelection = new QLabel(QLatin1String("Selection:")); + labelSelection->setVisible(false); + + QLabel *labelSelectedItem = new QLabel(QLatin1String("Nothing")); + labelSelectedItem->setVisible(false); + + // Textured topography heightmap + QCheckBox *enableTexture = new QCheckBox(QLatin1String("Surface texture")); + enableTexture->setVisible(false); + + int height = 400; + int width = 110; + int border = 10; + QLinearGradient gr(0, 0, 1, height - 2 * border); + gr.setColorAt(1.f, Qt::black); + gr.setColorAt(0.8f, Qt::darkGreen); + gr.setColorAt(0.6f, Qt::green); + gr.setColorAt(0.4f, Qt::yellow); + gr.setColorAt(0.2f, Qt::red); + gr.setColorAt(0.f, Qt::darkRed); + + QPixmap pmHighlight(width, height); + pmHighlight.fill(Qt::transparent); + QPainter pmpHighlight(&pmHighlight); + pmpHighlight.setBrush(QBrush(gr)); + pmpHighlight.setPen(Qt::NoPen); + pmpHighlight.drawRect(border, border, 35, height - 2 * border); + pmpHighlight.setPen(Qt::black); + int step = (height - 2 * border) / 5; + for (int i = 0; i < 6; i++) { + int yPos = i * step + border; + pmpHighlight.drawLine(border, yPos, 55, yPos); + pmpHighlight.drawText(60, yPos + 2, QString("%1 m").arg(550 - (i * 110))); + } + + QLabel *label = new QLabel(m_surfaceWidget); + label->setPixmap(pmHighlight); + + QGroupBox *heightMapGroupBox = new QGroupBox(QLatin1String("Highlight color map")); + QVBoxLayout *colorMapVBox = new QVBoxLayout; + colorMapVBox->addWidget(label); + heightMapGroupBox->setLayout(colorMapVBox); + heightMapGroupBox->setVisible(false); + + // Populate vertical layout + // Common + vLayout->addWidget(modelGroupBox); + vLayout->addWidget(selectionGroupBox); + vLayout->addWidget(axisGroupBox); + + // Sqrt Sin + vLayout->addWidget(colorGroupBox); + + // Multiseries heightmap + vLayout->addWidget(showGroupBox); + vLayout->addWidget(visualsGroupBox); + vLayout->addWidget(labelSelection); + vLayout->addWidget(labelSelectedItem); + + // Textured topography + vLayout->addWidget(heightMapGroupBox); + vLayout->addWidget(enableTexture); + + // Create the controller + SurfaceGraphModifier *modifier = new SurfaceGraphModifier(m_surfaceGraph, labelSelectedItem); + + // Connect widget controls to controller + QObject::connect(heightMapModelRB, &QRadioButton::toggled, + modifier, &SurfaceGraphModifier::enableHeightMapModel); + QObject::connect(sqrtSinModelRB, &QRadioButton::toggled, + modifier, &SurfaceGraphModifier::enableSqrtSinModel); + QObject::connect(texturedModelRB, &QRadioButton::toggled, + modifier, &SurfaceGraphModifier::enableTopographyModel); + + QObject::connect(modeNoneRB, &QRadioButton::toggled, + modifier, &SurfaceGraphModifier::toggleModeNone); + QObject::connect(modeItemRB, &QRadioButton::toggled, + modifier, &SurfaceGraphModifier::toggleModeItem); + QObject::connect(modeSliceRowRB, &QRadioButton::toggled, + modifier, &SurfaceGraphModifier::toggleModeSliceRow); + QObject::connect(modeSliceColumnRB, &QRadioButton::toggled, + modifier, &SurfaceGraphModifier::toggleModeSliceColumn); + + QObject::connect(axisMinSliderX, &QSlider::valueChanged, + modifier, &SurfaceGraphModifier::adjustXMin); + QObject::connect(axisMaxSliderX, &QSlider::valueChanged, + modifier, &SurfaceGraphModifier::adjustXMax); + QObject::connect(axisMinSliderZ, &QSlider::valueChanged, + modifier, &SurfaceGraphModifier::adjustZMin); + QObject::connect(axisMaxSliderZ, &QSlider::valueChanged, + modifier, &SurfaceGraphModifier::adjustZMax); + + // Mode dependent connections + QObject::connect(gradientBtoYPB, &QPushButton::pressed, + modifier, &SurfaceGraphModifier::setBlackToYellowGradient); + QObject::connect(gradientGtoRPB, &QPushButton::pressed, + modifier, &SurfaceGraphModifier::setGreenToRedGradient); + + QObject::connect(checkboxShowOilRigOne, &QCheckBox::stateChanged, + modifier, &SurfaceGraphModifier::toggleItemOne); + QObject::connect(checkboxShowOilRigTwo, &QCheckBox::stateChanged, + modifier, &SurfaceGraphModifier::toggleItemTwo); + QObject::connect(checkboxShowRefinery, &QCheckBox::stateChanged, + modifier, &SurfaceGraphModifier::toggleItemThree); + + QObject::connect(checkboxVisualsSeeThrough, &QCheckBox::stateChanged, + modifier, &SurfaceGraphModifier::toggleSeeThrough); + QObject::connect(checkboxHighlightOil, &QCheckBox::stateChanged, + modifier, &SurfaceGraphModifier::toggleOilHighlight); + QObject::connect(checkboxShowShadows, &QCheckBox::stateChanged, + modifier, &SurfaceGraphModifier::toggleShadows); + + QObject::connect(enableTexture, &QCheckBox::stateChanged, + modifier, &SurfaceGraphModifier::toggleSurfaceTexture); + + // Connections to disable features depending on mode + QObject::connect(sqrtSinModelRB, &QRadioButton::toggled, + colorGroupBox, &QGroupBox::setVisible); + + QObject::connect(heightMapModelRB, &QRadioButton::toggled, + showGroupBox, &QGroupBox::setVisible); + QObject::connect(heightMapModelRB, &QRadioButton::toggled, + visualsGroupBox, &QGroupBox::setVisible); + QObject::connect(heightMapModelRB, &QRadioButton::toggled, + labelSelection, &QLabel::setVisible); + QObject::connect(heightMapModelRB, &QRadioButton::toggled, + labelSelectedItem, &QLabel::setVisible); + + QObject::connect(texturedModelRB, &QRadioButton::toggled, + enableTexture, &QLabel::setVisible); + QObject::connect(texturedModelRB, &QRadioButton::toggled, + heightMapGroupBox, &QGroupBox::setVisible); + + modifier->setAxisMinSliderX(axisMinSliderX); + modifier->setAxisMaxSliderX(axisMaxSliderX); + modifier->setAxisMinSliderZ(axisMinSliderZ); + modifier->setAxisMaxSliderZ(axisMaxSliderZ); + + sqrtSinModelRB->setChecked(true); + modeItemRB->setChecked(true); + enableTexture->setChecked(true); + + return true; +} diff --git a/examples/datavisualization/graphgallery/surfacegraph.h b/examples/datavisualization/graphgallery/surfacegraph.h new file mode 100644 index 00000000..90494d17 --- /dev/null +++ b/examples/datavisualization/graphgallery/surfacegraph.h @@ -0,0 +1,26 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef SURFACEGRAPH_H +#define SURFACEGRAPH_H + +#include <QtCore/qobject.h> +#include <QtDataVisualization/q3dsurface.h> + +class SurfaceGraph : public QObject +{ + Q_OBJECT +public: + explicit SurfaceGraph(); + ~SurfaceGraph(); + + bool initialize(); + QWidget *surfaceWidget() { return m_surfaceWidget; } + +private: + Q3DSurface *m_surfaceGraph = nullptr; + QWidget *m_container = nullptr; + QWidget *m_surfaceWidget = nullptr; +}; + +#endif diff --git a/examples/datavisualization/graphgallery/surfacegraphmodifier.cpp b/examples/datavisualization/graphgallery/surfacegraphmodifier.cpp new file mode 100644 index 00000000..8e301e73 --- /dev/null +++ b/examples/datavisualization/graphgallery/surfacegraphmodifier.cpp @@ -0,0 +1,649 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "surfacegraphmodifier.h" +#include "highlightseries.h" +#include "topographicseries.h" +#include "custominputhandler.h" + +#include <QtDataVisualization/qvalue3daxis.h> +#include <QtDataVisualization/q3dtheme.h> +#include <QtGui/qimage.h> +#include <QtCore/qmath.h> + +const int sampleCountX = 150; +const int sampleCountZ = 150; +const int heightMapGridStepX = 6; +const int heightMapGridStepZ = 6; +const float sampleMin = -8.f; +const float sampleMax = 8.f; + +const float areaWidth = 8000.f; +const float areaHeight = 8000.f; +const float aspectRatio = 0.1389f; +const float minRange = areaWidth * 0.49f; + +SurfaceGraphModifier::SurfaceGraphModifier(Q3DSurface *surface, QLabel *label) + : m_graph(surface), + m_textField(label) +{ + m_graph->scene()->activeCamera()->setZoomLevel(85.f); + m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetIsometricRight); + m_graph->activeTheme()->setType(Q3DTheme::ThemeRetro); + + m_graph->setAxisX(new QValue3DAxis); + m_graph->setAxisY(new QValue3DAxis); + m_graph->setAxisZ(new QValue3DAxis); + + // + // Sqrt Sin + // + //! [0] + m_sqrtSinProxy = new QSurfaceDataProxy(); + m_sqrtSinSeries = new QSurface3DSeries(m_sqrtSinProxy); + //! [0] + fillSqrtSinProxy(); + + // + // Multisurface heightmap + // + //! [2] + // Create the first surface layer + QImage heightMapImageOne(":/data/layer_1.png"); + m_heightMapProxyOne = new QHeightMapSurfaceDataProxy(heightMapImageOne); + m_heightMapSeriesOne = new QSurface3DSeries(m_heightMapProxyOne); + m_heightMapSeriesOne->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel")); + m_heightMapProxyOne->setValueRanges(34.f, 40.f, 18.f, 24.f); + //! [2] + + // Create the other 2 surface layers + QImage heightMapImageTwo(":/data/layer_2.png"); + m_heightMapProxyTwo = new QHeightMapSurfaceDataProxy(heightMapImageTwo); + m_heightMapSeriesTwo = new QSurface3DSeries(m_heightMapProxyTwo); + m_heightMapSeriesTwo->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel")); + m_heightMapProxyTwo->setValueRanges(34.f, 40.f, 18.f, 24.f); + + QImage heightMapImageThree(":/data/layer_3.png"); + m_heightMapProxyThree = new QHeightMapSurfaceDataProxy(heightMapImageThree); + m_heightMapSeriesThree = new QSurface3DSeries(m_heightMapProxyThree); + m_heightMapSeriesThree->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel")); + m_heightMapProxyThree->setValueRanges(34.f, 40.f, 18.f, 24.f); + + // The images are the same size, so it's enough to get the dimensions from one + m_heightMapWidth = heightMapImageOne.width(); + m_heightMapHeight = heightMapImageOne.height(); + + // Set the gradients for multi-surface layers + QLinearGradient grOne; + grOne.setColorAt(0.f, Qt::black); + grOne.setColorAt(0.38f, Qt::darkYellow); + grOne.setColorAt(0.39f, Qt::darkGreen); + grOne.setColorAt(0.5f, Qt::darkGray); + grOne.setColorAt(1.f, Qt::gray); + m_heightMapSeriesOne->setBaseGradient(grOne); + m_heightMapSeriesOne->setColorStyle(Q3DTheme::ColorStyleRangeGradient); + + QLinearGradient grTwo; + grTwo.setColorAt(0.39f, Qt::blue); + grTwo.setColorAt(0.4f, Qt::white); + m_heightMapSeriesTwo->setBaseGradient(grTwo); + m_heightMapSeriesTwo->setColorStyle(Q3DTheme::ColorStyleRangeGradient); + + QLinearGradient grThree; + grThree.setColorAt(0.f, Qt::white); + grThree.setColorAt(0.05f, Qt::black); + m_heightMapSeriesThree->setBaseGradient(grThree); + m_heightMapSeriesThree->setColorStyle(Q3DTheme::ColorStyleRangeGradient); + + // Custom items and label + connect(m_graph, &QAbstract3DGraph::selectedElementChanged, + this, &SurfaceGraphModifier::handleElementSelected); + + m_selectionAnimation = new QPropertyAnimation(this); + m_selectionAnimation->setPropertyName("scaling"); + m_selectionAnimation->setDuration(500); + m_selectionAnimation->setLoopCount(-1); + + QFont titleFont = QFont("Century Gothic", 30); + titleFont.setBold(true); + m_titleLabel = new QCustom3DLabel("Oil Rigs on Imaginary Sea", titleFont, + QVector3D(0.f, 1.2f, 0.f), + QVector3D(1.f, 1.f, 0.f), + QQuaternion()); + m_titleLabel->setPositionAbsolute(true); + m_titleLabel->setFacingCamera(true); + m_titleLabel->setBackgroundColor(QColor(0x66cdaa)); + m_graph->addCustomItem(m_titleLabel); + m_titleLabel->setVisible(false); + + // Make two of the custom object visible + toggleItemOne(true); + toggleItemTwo(true); + + // + // Topographic map + // + m_topography = new TopographicSeries(); + m_topography->setTopographyFile(":/data/topography.png", areaWidth, areaHeight); + m_topography->setItemLabelFormat(QStringLiteral("@yLabel m")); + + m_highlight = new HighlightSeries(); + m_highlight->setTopographicSeries(m_topography); + m_highlight->setMinHeight(minRange * aspectRatio); + m_highlight->handleGradientChange(areaWidth * aspectRatio); + //! [16] + QObject::connect(m_graph->axisY(), &QValue3DAxis::maxChanged, + m_highlight, &HighlightSeries::handleGradientChange); + //! [16] + + m_customInputHandler = new CustomInputHandler(m_graph); + m_customInputHandler->setHighlightSeries(m_highlight); + m_customInputHandler->setAxes(m_graph->axisX(), m_graph->axisY(), m_graph->axisZ()); + m_customInputHandler->setLimits(0.f, areaWidth, minRange); + m_customInputHandler->setAspectRatio(aspectRatio); +} + +SurfaceGraphModifier::~SurfaceGraphModifier() +{ + delete m_graph; +} + +void SurfaceGraphModifier::fillSqrtSinProxy() +{ + float stepX = (sampleMax - sampleMin) / float(sampleCountX - 1); + float stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1); + + //! [1] + QSurfaceDataArray *dataArray = new QSurfaceDataArray; + dataArray->reserve(sampleCountZ); + for (int i = 0 ; i < sampleCountZ ; i++) { + QSurfaceDataRow *newRow = new QSurfaceDataRow(sampleCountX); + // Keep values within range bounds, since just adding step can cause minor drift due + // to the rounding errors. + float z = qMin(sampleMax, (i * stepZ + sampleMin)); + int index = 0; + for (int j = 0; j < sampleCountX; j++) { + float x = qMin(sampleMax, (j * stepX + sampleMin)); + float R = qSqrt(z * z + x * x) + 0.01f; + float y = (qSin(R) / R + 0.24f) * 1.61f; + (*newRow)[index++].setPosition(QVector3D(x, y, z)); + } + *dataArray << newRow; + } + + m_sqrtSinProxy->resetArray(dataArray); + //! [1] +} + +void SurfaceGraphModifier::enableSqrtSinModel(bool enable) +{ + if (enable) { + //! [3] + m_sqrtSinSeries->setDrawMode(QSurface3DSeries::DrawSurfaceAndWireframe); + m_sqrtSinSeries->setFlatShadingEnabled(true); + + m_graph->axisX()->setLabelFormat("%.2f"); + m_graph->axisZ()->setLabelFormat("%.2f"); + m_graph->axisX()->setRange(sampleMin, sampleMax); + m_graph->axisY()->setRange(0.f, 2.f); + m_graph->axisZ()->setRange(sampleMin, sampleMax); + m_graph->axisX()->setLabelAutoRotation(30.f); + m_graph->axisY()->setLabelAutoRotation(90.f); + m_graph->axisZ()->setLabelAutoRotation(30.f); + + m_graph->removeSeries(m_heightMapSeriesOne); + m_graph->removeSeries(m_heightMapSeriesTwo); + m_graph->removeSeries(m_heightMapSeriesThree); + m_graph->removeSeries(m_topography); + m_graph->removeSeries(m_highlight); + + m_graph->addSeries(m_sqrtSinSeries); + //! [3] + + m_titleLabel->setVisible(false); + m_graph->axisX()->setTitleVisible(false); + m_graph->axisY()->setTitleVisible(false); + m_graph->axisZ()->setTitleVisible(false); + + m_graph->axisX()->setTitle(QStringLiteral("")); + m_graph->axisY()->setTitle(QStringLiteral("")); + m_graph->axisZ()->setTitle(QStringLiteral("")); + + m_graph->setActiveInputHandler(m_defaultInputHandler); + + //! [6] + // Reset range sliders for Sqrt & Sin + m_rangeMinX = sampleMin; + m_rangeMinZ = sampleMin; + m_stepX = (sampleMax - sampleMin) / float(sampleCountX - 1); + m_stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1); + m_axisMinSliderX->setMinimum(0); + m_axisMinSliderX->setMaximum(sampleCountX - 2); + m_axisMinSliderX->setValue(0); + m_axisMaxSliderX->setMinimum(1); + m_axisMaxSliderX->setMaximum(sampleCountX - 1); + m_axisMaxSliderX->setValue(sampleCountX - 1); + m_axisMinSliderZ->setMinimum(0); + m_axisMinSliderZ->setMaximum(sampleCountZ - 2); + m_axisMinSliderZ->setValue(0); + m_axisMaxSliderZ->setMinimum(1); + m_axisMaxSliderZ->setMaximum(sampleCountZ - 1); + m_axisMaxSliderZ->setValue(sampleCountZ - 1); + //! [6] + } +} + +void SurfaceGraphModifier::enableHeightMapModel(bool enable) +{ + if (enable) { + m_heightMapSeriesOne->setDrawMode(QSurface3DSeries::DrawSurface); + m_heightMapSeriesOne->setFlatShadingEnabled(false); + m_heightMapSeriesTwo->setDrawMode(QSurface3DSeries::DrawSurface); + m_heightMapSeriesTwo->setFlatShadingEnabled(false); + m_heightMapSeriesThree->setDrawMode(QSurface3DSeries::DrawSurface); + m_heightMapSeriesThree->setFlatShadingEnabled(false); + + m_graph->axisX()->setLabelFormat("%.1f N"); + m_graph->axisZ()->setLabelFormat("%.1f E"); + m_graph->axisX()->setRange(34.f, 40.f); + //! [4] + m_graph->axisY()->setAutoAdjustRange(true); + //! [4] + m_graph->axisZ()->setRange(18.f, 24.f); + + m_graph->axisX()->setTitle(QStringLiteral("Latitude")); + m_graph->axisY()->setTitle(QStringLiteral("Height")); + m_graph->axisZ()->setTitle(QStringLiteral("Longitude")); + + m_graph->removeSeries(m_sqrtSinSeries); + m_graph->removeSeries(m_topography); + m_graph->removeSeries(m_highlight); + m_graph->addSeries(m_heightMapSeriesOne); + m_graph->addSeries(m_heightMapSeriesTwo); + m_graph->addSeries(m_heightMapSeriesThree); + + m_graph->setActiveInputHandler(m_defaultInputHandler); + + m_titleLabel->setVisible(true); + m_graph->axisX()->setTitleVisible(true); + m_graph->axisY()->setTitleVisible(true); + m_graph->axisZ()->setTitleVisible(true); + + // Reset range sliders for height map + int mapGridCountX = m_heightMapWidth / heightMapGridStepX; + int mapGridCountZ = m_heightMapHeight / heightMapGridStepZ; + m_rangeMinX = 34.f; + m_rangeMinZ = 18.f; + m_stepX = 6.f / float(mapGridCountX - 1); + m_stepZ = 6.f / float(mapGridCountZ - 1); + m_axisMinSliderX->setMinimum(0); + m_axisMinSliderX->setMaximum(mapGridCountX - 2); + m_axisMinSliderX->setValue(0); + m_axisMaxSliderX->setMinimum(1); + m_axisMaxSliderX->setMaximum(mapGridCountX - 1); + m_axisMaxSliderX->setValue(mapGridCountX - 1); + m_axisMinSliderZ->setMinimum(0); + m_axisMinSliderZ->setMaximum(mapGridCountZ - 2); + m_axisMinSliderZ->setValue(0); + m_axisMaxSliderZ->setMinimum(1); + m_axisMaxSliderZ->setMaximum(mapGridCountZ - 1); + m_axisMaxSliderZ->setValue(mapGridCountZ - 1); + } +} + +void SurfaceGraphModifier::enableTopographyModel(bool enable) +{ + if (enable) { + m_graph->axisX()->setLabelFormat("%i"); + m_graph->axisZ()->setLabelFormat("%i"); + m_graph->axisX()->setRange(0.f, areaWidth); + m_graph->axisY()->setRange(100.f, areaWidth * aspectRatio); + m_graph->axisZ()->setRange(0.f, areaHeight); + m_graph->axisX()->setLabelAutoRotation(30.f); + m_graph->axisY()->setLabelAutoRotation(90.f); + m_graph->axisZ()->setLabelAutoRotation(30.f); + + m_graph->removeSeries(m_heightMapSeriesOne); + m_graph->removeSeries(m_heightMapSeriesTwo); + m_graph->removeSeries(m_heightMapSeriesThree); + m_graph->addSeries(m_topography); + m_graph->addSeries(m_highlight); + + m_titleLabel->setVisible(false); + m_graph->axisX()->setTitleVisible(false); + m_graph->axisY()->setTitleVisible(false); + m_graph->axisZ()->setTitleVisible(false); + + m_graph->axisX()->setTitle(QStringLiteral("")); + m_graph->axisY()->setTitle(QStringLiteral("")); + m_graph->axisZ()->setTitle(QStringLiteral("")); + + //! [5] + m_graph->setActiveInputHandler(m_customInputHandler); + //! [5] + + // Reset range sliders for topography map + m_rangeMinX = 0.f; + m_rangeMinZ = 0.f; + m_stepX = 1.f; + m_stepZ = 1.f; + m_axisMinSliderX->setMinimum(0); + m_axisMinSliderX->setMaximum(areaWidth - 200); + m_axisMinSliderX->setValue(0); + m_axisMaxSliderX->setMinimum(200); + m_axisMaxSliderX->setMaximum(areaWidth); + m_axisMaxSliderX->setValue(areaWidth); + m_axisMinSliderZ->setMinimum(0); + m_axisMinSliderZ->setMaximum(areaHeight - 200); + m_axisMinSliderZ->setValue(0); + m_axisMaxSliderZ->setMinimum(200); + m_axisMaxSliderZ->setMaximum(areaHeight); + m_axisMaxSliderZ->setValue(areaHeight); + } +} + +void SurfaceGraphModifier::adjustXMin(int min) +{ + float minX = m_stepX * float(min) + m_rangeMinX; + + int max = m_axisMaxSliderX->value(); + if (min >= max) { + max = min + 1; + m_axisMaxSliderX->setValue(max); + } + float maxX = m_stepX * max + m_rangeMinX; + + setAxisXRange(minX, maxX); +} + +void SurfaceGraphModifier::adjustXMax(int max) +{ + float maxX = m_stepX * float(max) + m_rangeMinX; + + int min = m_axisMinSliderX->value(); + if (max <= min) { + min = max - 1; + m_axisMinSliderX->setValue(min); + } + float minX = m_stepX * min + m_rangeMinX; + + setAxisXRange(minX, maxX); +} + +void SurfaceGraphModifier::adjustZMin(int min) +{ + float minZ = m_stepZ * float(min) + m_rangeMinZ; + + int max = m_axisMaxSliderZ->value(); + if (min >= max) { + max = min + 1; + m_axisMaxSliderZ->setValue(max); + } + float maxZ = m_stepZ * max + m_rangeMinZ; + + setAxisZRange(minZ, maxZ); +} + +void SurfaceGraphModifier::adjustZMax(int max) +{ + float maxX = m_stepZ * float(max) + m_rangeMinZ; + + int min = m_axisMinSliderZ->value(); + if (max <= min) { + min = max - 1; + m_axisMinSliderZ->setValue(min); + } + float minX = m_stepZ * min + m_rangeMinZ; + + setAxisZRange(minX, maxX); +} + +//! [7] +void SurfaceGraphModifier::setAxisXRange(float min, float max) +{ + m_graph->axisX()->setRange(min, max); +} +//! [7] + +void SurfaceGraphModifier::setAxisZRange(float min, float max) +{ + m_graph->axisZ()->setRange(min, max); +} + +void SurfaceGraphModifier::setBlackToYellowGradient() +{ + //! [8] + QLinearGradient gr; + gr.setColorAt(0.f, Qt::black); + gr.setColorAt(0.33f, Qt::blue); + gr.setColorAt(0.67f, Qt::red); + gr.setColorAt(1.f, Qt::yellow); + + m_sqrtSinSeries->setBaseGradient(gr); + m_sqrtSinSeries->setColorStyle(Q3DTheme::ColorStyleRangeGradient); + //! [8] +} + +void SurfaceGraphModifier::setGreenToRedGradient() +{ + QLinearGradient gr; + gr.setColorAt(0.f, Qt::darkGreen); + gr.setColorAt(0.5f, Qt::yellow); + gr.setColorAt(0.8f, Qt::red); + gr.setColorAt(1.f, Qt::darkRed); + + m_sqrtSinSeries->setBaseGradient(gr); + m_sqrtSinSeries->setColorStyle(Q3DTheme::ColorStyleRangeGradient); +} + +void SurfaceGraphModifier::toggleItemOne(bool show) +{ + //! [10] + QVector3D positionOne = QVector3D(39.f, 77.f, 19.2f); + //! [10] + QVector3D positionOnePipe = QVector3D(39.f, 45.f, 19.2f); + QVector3D positionOneLabel = QVector3D(39.f, 107.f, 19.2f); + if (show) { + //! [9] + QImage color = QImage(2, 2, QImage::Format_RGB32); + color.fill(Qt::red); + //! [9] + //! [11] + QCustom3DItem *item = new QCustom3DItem(":/data/oilrig.obj", positionOne, + QVector3D(0.025f, 0.025f, 0.025f), + QQuaternion::fromAxisAndAngle(0.f, 1.f, 0.f, 45.f), + color); + //! [11] + //! [12] + m_graph->addCustomItem(item); + //! [12] + item = new QCustom3DItem(":/data/pipe.obj", positionOnePipe, + QVector3D(0.005f, 0.5f, 0.005f), + QQuaternion(), + color); + item->setShadowCasting(false); + m_graph->addCustomItem(item); + + //! [13] + QCustom3DLabel *label = new QCustom3DLabel(); + label->setText("Oil Rig One"); + label->setPosition(positionOneLabel); + label->setScaling(QVector3D(1.f, 1.f, 1.f)); + m_graph->addCustomItem(label); + //! [13] + } else { + resetSelection(); + //! [14] + m_graph->removeCustomItemAt(positionOne); + //! [14] + m_graph->removeCustomItemAt(positionOnePipe); + m_graph->removeCustomItemAt(positionOneLabel); + } +} + +void SurfaceGraphModifier::toggleItemTwo(bool show) +{ + QVector3D positionTwo = QVector3D(34.5f, 77.f, 23.4f); + QVector3D positionTwoPipe = QVector3D(34.5f, 45.f, 23.4f); + QVector3D positionTwoLabel = QVector3D(34.5f, 107.f, 23.4f); + if (show) { + QImage color = QImage(2, 2, QImage::Format_RGB32); + color.fill(Qt::red); + QCustom3DItem *item = new QCustom3DItem(); + item->setMeshFile(":/data/oilrig.obj"); + item->setPosition(positionTwo); + item->setScaling(QVector3D(0.025f, 0.025f, 0.025f)); + item->setRotation(QQuaternion::fromAxisAndAngle(0.f, 1.f, 0.f, 25.f)); + item->setTextureImage(color); + m_graph->addCustomItem(item); + item = new QCustom3DItem(":/data/pipe.obj", positionTwoPipe, + QVector3D(0.005f, 0.5f, 0.005f), + QQuaternion(), + color); + item->setShadowCasting(false); + m_graph->addCustomItem(item); + + QCustom3DLabel *label = new QCustom3DLabel(); + label->setText("Oil Rig Two"); + label->setPosition(positionTwoLabel); + label->setScaling(QVector3D(1.f, 1.f, 1.f)); + m_graph->addCustomItem(label); + } else { + resetSelection(); + m_graph->removeCustomItemAt(positionTwo); + m_graph->removeCustomItemAt(positionTwoPipe); + m_graph->removeCustomItemAt(positionTwoLabel); + } +} + +void SurfaceGraphModifier::toggleItemThree(bool show) +{ + QVector3D positionThree = QVector3D(34.5f, 86.f, 19.1f); + QVector3D positionThreeLabel = QVector3D(34.5f, 116.f, 19.1f); + if (show) { + QImage color = QImage(2, 2, QImage::Format_RGB32); + color.fill(Qt::darkMagenta); + QCustom3DItem *item = new QCustom3DItem(); + item->setMeshFile(":/data/refinery.obj"); + item->setPosition(positionThree); + item->setScaling(QVector3D(0.04f, 0.04f, 0.04f)); + item->setRotation(QQuaternion::fromAxisAndAngle(0.f, 1.f, 0.f, 75.f)); + item->setTextureImage(color); + m_graph->addCustomItem(item); + + QCustom3DLabel *label = new QCustom3DLabel(); + label->setText("Refinery"); + label->setPosition(positionThreeLabel); + label->setScaling(QVector3D(1.f, 1.f, 1.f)); + m_graph->addCustomItem(label); + } else { + resetSelection(); + m_graph->removeCustomItemAt(positionThree); + m_graph->removeCustomItemAt(positionThreeLabel); + } +} + +void SurfaceGraphModifier::toggleSeeThrough(bool seethrough) +{ + if (seethrough) { + m_graph->seriesList().at(0)->setDrawMode(QSurface3DSeries::DrawWireframe); + m_graph->seriesList().at(1)->setDrawMode(QSurface3DSeries::DrawWireframe); + } else { + m_graph->seriesList().at(0)->setDrawMode(QSurface3DSeries::DrawSurface); + m_graph->seriesList().at(1)->setDrawMode(QSurface3DSeries::DrawSurface); + } +} + +void SurfaceGraphModifier::toggleOilHighlight(bool highlight) +{ + if (highlight) { + QLinearGradient grThree; + grThree.setColorAt(0.0, Qt::black); + grThree.setColorAt(0.05, Qt::red); + m_graph->seriesList().at(2)->setBaseGradient(grThree); + } else { + QLinearGradient grThree; + grThree.setColorAt(0.0, Qt::white); + grThree.setColorAt(0.05, Qt::black); + m_graph->seriesList().at(2)->setBaseGradient(grThree); + } +} + +void SurfaceGraphModifier::toggleShadows(bool shadows) +{ + if (shadows) + m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualityMedium); + else + m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualityNone); +} + +//! [15] +void SurfaceGraphModifier::toggleSurfaceTexture(bool enable) +{ + if (enable) + m_topography->setTextureFile(":/data/maptexture.jpg"); + else + m_topography->setTextureFile(""); +} +//! [15] + +void SurfaceGraphModifier::handleElementSelected(QAbstract3DGraph::ElementType type) +{ + resetSelection(); + if (type == QAbstract3DGraph::ElementCustomItem) { + QCustom3DItem *item = m_graph->selectedCustomItem(); + QString text; + if (qobject_cast<QCustom3DLabel *>(item) != 0) { + text.append("Custom label: "); + } else { + QStringList split = item->meshFile().split("/"); + text.append(split.last()); + text.append(": "); + } + int index = m_graph->selectedCustomItemIndex(); + text.append(QString::number(index)); + m_textField->setText(text); + m_previouslyAnimatedItem = item; + m_previousScaling = item->scaling(); + m_selectionAnimation->setTargetObject(item); + m_selectionAnimation->setStartValue(item->scaling()); + m_selectionAnimation->setEndValue(item->scaling() * 1.5f); + m_selectionAnimation->start(); + } else if (type == QAbstract3DGraph::ElementSeries) { + QString text = "Surface ("; + QSurface3DSeries *series = m_graph->selectedSeries(); + if (series) { + QPoint point = series->selectedPoint(); + QString posStr; + posStr.setNum(point.x()); + text.append(posStr); + text.append(", "); + posStr.setNum(point.y()); + text.append(posStr); + } + text.append(")"); + m_textField->setText(text); + } else if (type > QAbstract3DGraph::ElementSeries + && type < QAbstract3DGraph::ElementCustomItem) { + int index = m_graph->selectedLabelIndex(); + QString text; + if (type == QAbstract3DGraph::ElementAxisXLabel) + text.append("Axis X label: "); + else if (type == QAbstract3DGraph::ElementAxisYLabel) + text.append("Axis Y label: "); + else + text.append("Axis Z label: "); + text.append(QString::number(index)); + m_textField->setText(text); + } else { + m_textField->setText("Nothing"); + } +} + +void SurfaceGraphModifier::resetSelection() +{ + m_selectionAnimation->stop(); + if (m_previouslyAnimatedItem) + m_previouslyAnimatedItem->setScaling(m_previousScaling); + m_previouslyAnimatedItem = nullptr; +} diff --git a/examples/datavisualization/graphgallery/surfacegraphmodifier.h b/examples/datavisualization/graphgallery/surfacegraphmodifier.h new file mode 100644 index 00000000..19ae04b2 --- /dev/null +++ b/examples/datavisualization/graphgallery/surfacegraphmodifier.h @@ -0,0 +1,110 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef SURFACEGRAPHMODIFIER_H +#define SURFACEGRAPHMODIFIER_H + +#include <QtDataVisualization/q3dsurface.h> +#include <QtDataVisualization/qsurfacedataproxy.h> +#include <QtDataVisualization/qheightmapsurfacedataproxy.h> +#include <QtDataVisualization/qsurface3dseries.h> +#include <QtDataVisualization/qcustom3ditem.h> +#include <QtDataVisualization/qcustom3dlabel.h> +#include <QtDataVisualization/q3dinputhandler.h> +#include <QtWidgets/qslider.h> +#include <QtWidgets/qlabel.h> +#include <QtCore/qpropertyanimation.h> + +class TopographicSeries; +class HighlightSeries; +class CustomInputHandler; + +class SurfaceGraphModifier : public QObject +{ + Q_OBJECT +public: + explicit SurfaceGraphModifier(Q3DSurface *surface, QLabel *label); + ~SurfaceGraphModifier(); + + //! [0] + void toggleModeNone() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionNone); } + void toggleModeItem() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionItem); } + void toggleModeSliceRow() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionItemAndRow + | QAbstract3DGraph::SelectionSlice + | QAbstract3DGraph::SelectionMultiSeries); } + void toggleModeSliceColumn() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionItemAndColumn + | QAbstract3DGraph::SelectionSlice + | QAbstract3DGraph::SelectionMultiSeries); } + //! [0] + + void setBlackToYellowGradient(); + void setGreenToRedGradient(); + + void setAxisMinSliderX(QSlider *slider) { m_axisMinSliderX = slider; } + void setAxisMaxSliderX(QSlider *slider) { m_axisMaxSliderX = slider; } + void setAxisMinSliderZ(QSlider *slider) { m_axisMinSliderZ = slider; } + void setAxisMaxSliderZ(QSlider *slider) { m_axisMaxSliderZ = slider; } + + void adjustXMin(int min); + void adjustXMax(int max); + void adjustZMin(int min); + void adjustZMax(int max); + +public Q_SLOTS: + void enableSqrtSinModel(bool enable); + void enableHeightMapModel(bool enable); + void enableTopographyModel(bool enable); + + void toggleItemOne(bool show); + void toggleItemTwo(bool show); + void toggleItemThree(bool show); + void toggleSeeThrough(bool seethrough); + void toggleOilHighlight(bool highlight); + void toggleShadows(bool shadows); + void toggleSurfaceTexture(bool enable); + +private: + void setAxisXRange(float min, float max); + void setAxisZRange(float min, float max); + void fillSqrtSinProxy(); + void handleElementSelected(QAbstract3DGraph::ElementType type); + void resetSelection(); + +private: + Q3DSurface *m_graph = nullptr; + QSurfaceDataProxy *m_sqrtSinProxy = nullptr; + QSurface3DSeries *m_sqrtSinSeries = nullptr; + QHeightMapSurfaceDataProxy *m_heightMapProxyOne = nullptr; + QHeightMapSurfaceDataProxy *m_heightMapProxyTwo = nullptr; + QHeightMapSurfaceDataProxy *m_heightMapProxyThree = nullptr; + QSurface3DSeries *m_heightMapSeriesOne = nullptr; + QSurface3DSeries *m_heightMapSeriesTwo = nullptr; + QSurface3DSeries *m_heightMapSeriesThree = nullptr; + + QSlider *m_axisMinSliderX = nullptr; + QSlider *m_axisMaxSliderX = nullptr; + QSlider *m_axisMinSliderZ = nullptr; + QSlider *m_axisMaxSliderZ = nullptr; + float m_rangeMinX = 0.f; + float m_rangeMinZ = 0.f; + float m_stepX = 0.f; + float m_stepZ = 0.f; + int m_heightMapWidth = 0; + int m_heightMapHeight = 0; + + QLabel *m_textField = nullptr; + QPropertyAnimation *m_selectionAnimation = nullptr; + QCustom3DLabel *m_titleLabel = nullptr; + QCustom3DItem *m_previouslyAnimatedItem = nullptr; + QVector3D m_previousScaling = {}; + + TopographicSeries *m_topography = nullptr; + HighlightSeries *m_highlight = nullptr; + int m_highlightWidth = 0; + int m_highlightHeight = 0; + + CustomInputHandler *m_customInputHandler = nullptr; + Q3DInputHandler *m_defaultInputHandler = new Q3DInputHandler(); +}; + +#endif // SURFACEGRAPHMODIFIER_H diff --git a/examples/datavisualization/texturesurface/topographicseries.cpp b/examples/datavisualization/graphgallery/topographicseries.cpp index 01110388..d33fa6bd 100644 --- a/examples/datavisualization/texturesurface/topographicseries.cpp +++ b/examples/datavisualization/graphgallery/topographicseries.cpp @@ -1,11 +1,11 @@ -// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "topographicseries.h" //! [0] // Value used to encode height data as RGB value on PNG file -const float packingFactor = 11983.0f; +const float packingFactor = 11983.f; //! [0] TopographicSeries::TopographicSeries() @@ -21,7 +21,7 @@ TopographicSeries::~TopographicSeries() void TopographicSeries::setTopographyFile(const QString file, float width, float height) { -//! [1] + //! [1] QImage heightMapImage(file); uchar *bits = heightMapImage.bits(); int imageHeight = heightMapImage.height(); @@ -49,7 +49,7 @@ void TopographicSeries::setTopographyFile(const QString file, float width, float } dataProxy()->resetArray(dataArray); -//! [1] + //! [1] m_sampleCountX = float(imageWidth); m_sampleCountZ = float(imageHeight); diff --git a/examples/datavisualization/texturesurface/topographicseries.h b/examples/datavisualization/graphgallery/topographicseries.h index 1280e03a..8c49c338 100644 --- a/examples/datavisualization/texturesurface/topographicseries.h +++ b/examples/datavisualization/graphgallery/topographicseries.h @@ -1,10 +1,10 @@ -// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef TOPOGRAPHICSERIES_H #define TOPOGRAPHICSERIES_H -#include <QtDataVisualization/QSurface3DSeries> +#include <QtDataVisualization/qsurface3dseries.h> class TopographicSeries : public QSurface3DSeries { @@ -21,8 +21,8 @@ public: public Q_SLOTS: private: - float m_sampleCountX; - float m_sampleCountZ; + float m_sampleCountX = 0.f; + float m_sampleCountZ = 0.f; }; #endif // TOPOGRAPHICSERIES_H diff --git a/examples/datavisualization/surface/CMakeLists.txt b/examples/datavisualization/surface/CMakeLists.txt deleted file mode 100644 index 54e0c5ec..00000000 --- a/examples/datavisualization/surface/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (C) 2022 The Qt Company Ltd. -# SPDX-License-Identifier: BSD-3-Clause - -cmake_minimum_required(VERSION 3.16) -project(surface LANGUAGES CXX) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}") - -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Widgets) -find_package(Qt6 COMPONENTS DataVisualization) - -qt_add_executable(surface - main.cpp - surfacegraph.cpp surfacegraph.h -) -set_target_properties(surface PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(surface PUBLIC - Qt::Core - Qt::Gui - Qt::Widgets - Qt::DataVisualization -) - -set_source_files_properties("mountain.png" - PROPERTIES QT_RESOURCE_ALIAS "mountain" -) -set(surface_resource_files - "mountain.png" -) - -qt6_add_resources(surface "surface" - PREFIX - "/maps" - FILES - ${surface_resource_files} -) - -install(TARGETS surface - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) diff --git a/examples/datavisualization/surface/doc/images/surface-example.png b/examples/datavisualization/surface/doc/images/surface-example.png Binary files differdeleted file mode 100644 index c323df78..00000000 --- a/examples/datavisualization/surface/doc/images/surface-example.png +++ /dev/null diff --git a/examples/datavisualization/surface/doc/src/surface.qdoc b/examples/datavisualization/surface/doc/src/surface.qdoc deleted file mode 100644 index 7ee17fa1..00000000 --- a/examples/datavisualization/surface/doc/src/surface.qdoc +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only - -/*! - \example surface - \meta tags {DataVisualization, Q3DSurface} - \meta category {Graphics} - \title Surface Graph - \ingroup qtdatavisualization_examples - \brief Using Q3DSurface in a widget application. - - The surface example shows how to make a simple 3D surface graph using Q3DSurface and - combining the use of widgets for adjusting several adjustable qualities. This example - demonstrates the following features: - - \list - \li How to set up a basic QSurfaceDataProxy and set data for it. - \li How to use QHeightMapSurfaceDataProxy for showing 3D height maps. - \li Three different selection modes for studying the graph. - \li Axis range usage for displaying selected portions of the graph. - \li Changing theme. - \li How to set a custom surface gradient. - \endlist - - For instructions about how to interact with the graph, see \l{Qt Data Visualization Interacting with Data}{this page}. - - \image surface-example.png - - \include examples-run.qdocinc - - \section1 Creating the Application - - First, in \c main.cpp, we create a QApplication, instantiate Q3DSurface, and a window container - for it: - - \snippet surface/main.cpp 0 - - The call to QWidget::createWindowContainer is required, as all data visualization graph classes - (Q3DBars, Q3DScatter, and Q3DSurface) inherit QWindow. Any class inheriting QWindow cannot be used - as a widget any other way. - - Then we'll create horizontal and vertical layouts. We'll add the graph with the container and - the vertical layout into the horizontal one: - - \snippet surface/main.cpp 1 - - The rest of the code in \c main.cpp is creating control widgets for features in Q3DSurface. We - have separated code for changing these features into \c surfacegraph.cpp and only connect - signals from widgets into methods in \c surfacegraph.cpp. Next chapter explains more - about using Q3DSurface. - - \section1 Setting up Proxies and Data - - First we instantiate a new QSurfaceDataProxy and attach it to a new QSurface3DSeries: - - \snippet surface/surfacegraph.cpp 0 - - Then we fill the proxy with a simple square root and sine wave data. This is done by - creating a new \c QSurfaceDataArray instance and adding \c QSurfaceDataRow elements to it. - The created \c QSurfaceDataArray is set to be the data array for the QSurfaceDataProxy. - - \snippet surface/surfacegraph.cpp 1 - - The height map is created by instantiating a QHeightMapSurfaceDataProxy with - a QImage containing the height data. The method QHeightMapSurfaceDataProxy::setValueRanges() is - used to define the value range of the map. In our example the map is from imaginary position of - 34.0\unicode 0x00B0 N - 40.0\unicode 0x00B0 N and 18.0\unicode 0x00B0 E - 24.0\unicode 0x00B0 E. - These values are used to show and position the map to the axis. - - \snippet surface/surfacegraph.cpp 2 - - For demonstrating different proxies this example has two radio buttons which - the user can use to switch between the series. When the user selects the - \c {Sqrt & Sin} radio button, the selected series is activated with the following - code. First we set the decorative issues like enable the grid for the surface and - select the flat shading mode. Next lines define the axis label format and value - ranges. Automatic label rotation is set to improve label readability at low camera angles. - Finally we make sure the correct series is added to the graph: - - \snippet surface/surfacegraph.cpp 3 - - When the \c{Height Map} radio button is activated, the following code sets the correct series active. - The axis label format is set to show N and E letters and ranges are set to the imaginary coordinates. - Auto adjusting Y-axis range is fine for our height map surface, so we ensure it is set. - - \snippet surface/surfacegraph.cpp 4 - - \section1 Selection Modes - - Q3Dsurface supports three different selection modes. These are demonstrated in the - example with radio buttons, which the user can use to activate a suitable selection mode. - The following inline methods are connected to radio buttons to activate the selected mode. - - \snippet surface/surfacegraph.h 0 - - \section1 Axis Ranges for Studying the Graph - - The example has four slider controls for adjusting the min and max values for X and Z - axis. When selecting the proxy these sliders are adjusted so that one step on the slider - moves the range by one segment step: - - \snippet surface/surfacegraph.cpp 8 - - The ranges are set for the axes like this: - - \snippet surface/surfacegraph.cpp 5 - - \section1 Themes - - Q3DSurface supports all the themes Qt Data Visualization has. The example has a pull - down menu for selecting the theme. The following method is connected to the - menu to activate the selected theme. The theme type is changed to another predefined theme, - which overwrites all theme properties to predefined values: - - \snippet surface/surfacegraph.cpp 6 - - \section1 Custom Surface Gradients - - The example demonstrates the custom surface gradients with two push buttons. The gradient - can be defined with QLinearGradient where the desired colors are set to positions. The following - code shows how to create an example gradient and set it to the series. Note that you also need - to change the color style to Q3DTheme::ColorStyleRangeGradient to actually use the gradient. - - \snippet surface/surfacegraph.cpp 7 -*/ diff --git a/examples/datavisualization/surface/main.cpp b/examples/datavisualization/surface/main.cpp deleted file mode 100644 index e017b039..00000000 --- a/examples/datavisualization/surface/main.cpp +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -#include "surfacegraph.h" - -#include <QtWidgets/QApplication> -#include <QtWidgets/QWidget> -#include <QtWidgets/QHBoxLayout> -#include <QtWidgets/QVBoxLayout> -#include <QtWidgets/QPushButton> -#include <QtWidgets/QRadioButton> -#include <QtWidgets/QSlider> -#include <QtWidgets/QGroupBox> -#include <QtWidgets/QComboBox> -#include <QtWidgets/QLabel> -#include <QtWidgets/QMessageBox> -#include <QtGui/QPainter> -#include <QtGui/QScreen> - -int main(int argc, char **argv) -{ - qputenv("QSG_RHI_BACKEND", "opengl"); - //! [0] - QApplication app(argc, argv); - Q3DSurface *graph = new Q3DSurface(); - QWidget *container = QWidget::createWindowContainer(graph); - //! [0] - - if (!graph->hasContext()) { - QMessageBox msgBox; - msgBox.setText("Couldn't initialize the OpenGL context."); - msgBox.exec(); - return -1; - } - - QSize screenSize = graph->screen()->size(); - container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 1.6)); - container->setMaximumSize(screenSize); - container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - container->setFocusPolicy(Qt::StrongFocus); - - //! [1] - QWidget *widget = new QWidget; - QHBoxLayout *hLayout = new QHBoxLayout(widget); - QVBoxLayout *vLayout = new QVBoxLayout(); - hLayout->addWidget(container, 1); - hLayout->addLayout(vLayout); - vLayout->setAlignment(Qt::AlignTop); - //! [1] - - widget->setWindowTitle(QStringLiteral("Surface example")); - - QGroupBox *modelGroupBox = new QGroupBox(QStringLiteral("Model")); - - QRadioButton *sqrtSinModelRB = new QRadioButton(widget); - sqrtSinModelRB->setText(QStringLiteral("Sqrt && Sin")); - sqrtSinModelRB->setChecked(false); - - QRadioButton *heightMapModelRB = new QRadioButton(widget); - heightMapModelRB->setText(QStringLiteral("Height Map")); - heightMapModelRB->setChecked(false); - - QVBoxLayout *modelVBox = new QVBoxLayout; - modelVBox->addWidget(sqrtSinModelRB); - modelVBox->addWidget(heightMapModelRB); - modelGroupBox->setLayout(modelVBox); - - QGroupBox *selectionGroupBox = new QGroupBox(QStringLiteral("Selection Mode")); - - QRadioButton *modeNoneRB = new QRadioButton(widget); - modeNoneRB->setText(QStringLiteral("No selection")); - modeNoneRB->setChecked(false); - - QRadioButton *modeItemRB = new QRadioButton(widget); - modeItemRB->setText(QStringLiteral("Item")); - modeItemRB->setChecked(false); - - QRadioButton *modeSliceRowRB = new QRadioButton(widget); - modeSliceRowRB->setText(QStringLiteral("Row Slice")); - modeSliceRowRB->setChecked(false); - - QRadioButton *modeSliceColumnRB = new QRadioButton(widget); - modeSliceColumnRB->setText(QStringLiteral("Column Slice")); - modeSliceColumnRB->setChecked(false); - - QVBoxLayout *selectionVBox = new QVBoxLayout; - selectionVBox->addWidget(modeNoneRB); - selectionVBox->addWidget(modeItemRB); - selectionVBox->addWidget(modeSliceRowRB); - selectionVBox->addWidget(modeSliceColumnRB); - selectionGroupBox->setLayout(selectionVBox); - - QSlider *axisMinSliderX = new QSlider(Qt::Horizontal, widget); - axisMinSliderX->setMinimum(0); - axisMinSliderX->setTickInterval(1); - axisMinSliderX->setEnabled(true); - QSlider *axisMaxSliderX = new QSlider(Qt::Horizontal, widget); - axisMaxSliderX->setMinimum(1); - axisMaxSliderX->setTickInterval(1); - axisMaxSliderX->setEnabled(true); - QSlider *axisMinSliderZ = new QSlider(Qt::Horizontal, widget); - axisMinSliderZ->setMinimum(0); - axisMinSliderZ->setTickInterval(1); - axisMinSliderZ->setEnabled(true); - QSlider *axisMaxSliderZ = new QSlider(Qt::Horizontal, widget); - axisMaxSliderZ->setMinimum(1); - axisMaxSliderZ->setTickInterval(1); - axisMaxSliderZ->setEnabled(true); - - QComboBox *themeList = new QComboBox(widget); - themeList->addItem(QStringLiteral("Qt")); - themeList->addItem(QStringLiteral("Primary Colors")); - themeList->addItem(QStringLiteral("Digia")); - themeList->addItem(QStringLiteral("Stone Moss")); - themeList->addItem(QStringLiteral("Army Blue")); - themeList->addItem(QStringLiteral("Retro")); - themeList->addItem(QStringLiteral("Ebony")); - themeList->addItem(QStringLiteral("Isabelle")); - - QGroupBox *colorGroupBox = new QGroupBox(QStringLiteral("Custom gradient")); - - QLinearGradient grBtoY(0, 0, 1, 100); - grBtoY.setColorAt(1.0, Qt::black); - grBtoY.setColorAt(0.67, Qt::blue); - grBtoY.setColorAt(0.33, Qt::red); - grBtoY.setColorAt(0.0, Qt::yellow); - QPixmap pm(24, 100); - QPainter pmp(&pm); - pmp.setBrush(QBrush(grBtoY)); - pmp.setPen(Qt::NoPen); - pmp.drawRect(0, 0, 24, 100); - QPushButton *gradientBtoYPB = new QPushButton(widget); - gradientBtoYPB->setIcon(QIcon(pm)); - gradientBtoYPB->setIconSize(QSize(24, 100)); - - QLinearGradient grGtoR(0, 0, 1, 100); - grGtoR.setColorAt(1.0, Qt::darkGreen); - grGtoR.setColorAt(0.5, Qt::yellow); - grGtoR.setColorAt(0.2, Qt::red); - grGtoR.setColorAt(0.0, Qt::darkRed); - pmp.setBrush(QBrush(grGtoR)); - pmp.drawRect(0, 0, 24, 100); - QPushButton *gradientGtoRPB = new QPushButton(widget); - gradientGtoRPB->setIcon(QIcon(pm)); - gradientGtoRPB->setIconSize(QSize(24, 100)); - - QHBoxLayout *colorHBox = new QHBoxLayout; - colorHBox->addWidget(gradientBtoYPB); - colorHBox->addWidget(gradientGtoRPB); - colorGroupBox->setLayout(colorHBox); - - vLayout->addWidget(modelGroupBox); - vLayout->addWidget(selectionGroupBox); - vLayout->addWidget(new QLabel(QStringLiteral("Column range"))); - vLayout->addWidget(axisMinSliderX); - vLayout->addWidget(axisMaxSliderX); - vLayout->addWidget(new QLabel(QStringLiteral("Row range"))); - vLayout->addWidget(axisMinSliderZ); - vLayout->addWidget(axisMaxSliderZ); - vLayout->addWidget(new QLabel(QStringLiteral("Theme"))); - vLayout->addWidget(themeList); - vLayout->addWidget(colorGroupBox); - - widget->show(); - - SurfaceGraph *modifier = new SurfaceGraph(graph); - - QObject::connect(heightMapModelRB, &QRadioButton::toggled, - modifier, &SurfaceGraph::enableHeightMapModel); - QObject::connect(sqrtSinModelRB, &QRadioButton::toggled, - modifier, &SurfaceGraph::enableSqrtSinModel); - QObject::connect(modeNoneRB, &QRadioButton::toggled, - modifier, &SurfaceGraph::toggleModeNone); - QObject::connect(modeItemRB, &QRadioButton::toggled, - modifier, &SurfaceGraph::toggleModeItem); - QObject::connect(modeSliceRowRB, &QRadioButton::toggled, - modifier, &SurfaceGraph::toggleModeSliceRow); - QObject::connect(modeSliceColumnRB, &QRadioButton::toggled, - modifier, &SurfaceGraph::toggleModeSliceColumn); - QObject::connect(axisMinSliderX, &QSlider::valueChanged, - modifier, &SurfaceGraph::adjustXMin); - QObject::connect(axisMaxSliderX, &QSlider::valueChanged, - modifier, &SurfaceGraph::adjustXMax); - QObject::connect(axisMinSliderZ, &QSlider::valueChanged, - modifier, &SurfaceGraph::adjustZMin); - QObject::connect(axisMaxSliderZ, &QSlider::valueChanged, - modifier, &SurfaceGraph::adjustZMax); - QObject::connect(themeList, &QComboBox::currentIndexChanged, - modifier, &SurfaceGraph::changeTheme); - QObject::connect(gradientBtoYPB, &QPushButton::pressed, - modifier, &SurfaceGraph::setBlackToYellowGradient); - QObject::connect(gradientGtoRPB, &QPushButton::pressed, - modifier, &SurfaceGraph::setGreenToRedGradient); - - modifier->setAxisMinSliderX(axisMinSliderX); - modifier->setAxisMaxSliderX(axisMaxSliderX); - modifier->setAxisMinSliderZ(axisMinSliderZ); - modifier->setAxisMaxSliderZ(axisMaxSliderZ); - - sqrtSinModelRB->setChecked(true); - modeItemRB->setChecked(true); - themeList->setCurrentIndex(2); - - return app.exec(); -} diff --git a/examples/datavisualization/surface/mountain.png b/examples/datavisualization/surface/mountain.png Binary files differdeleted file mode 100644 index 9138c710..00000000 --- a/examples/datavisualization/surface/mountain.png +++ /dev/null diff --git a/examples/datavisualization/surface/surface.pro b/examples/datavisualization/surface/surface.pro deleted file mode 100644 index a49fa468..00000000 --- a/examples/datavisualization/surface/surface.pro +++ /dev/null @@ -1,20 +0,0 @@ -android|ios|winrt { - error( "This example is not supported for android, ios, or winrt." ) -} - -!include( ../examples.pri ) { - error( "Couldn't find the examples.pri file!" ) -} - -SOURCES += main.cpp \ - surfacegraph.cpp - -HEADERS += surfacegraph.h - -QT += widgets -requires(qtConfig(combobox)) - -RESOURCES += surface.qrc - -OTHER_FILES += doc/src/* \ - doc/images/* diff --git a/examples/datavisualization/surface/surface.qrc b/examples/datavisualization/surface/surface.qrc deleted file mode 100644 index e4a7c38b..00000000 --- a/examples/datavisualization/surface/surface.qrc +++ /dev/null @@ -1,5 +0,0 @@ -<RCC> - <qresource prefix="/maps"> - <file alias="mountain">mountain.png</file> - </qresource> -</RCC> diff --git a/examples/datavisualization/surface/surfacegraph.cpp b/examples/datavisualization/surface/surfacegraph.cpp deleted file mode 100644 index 9ef395c9..00000000 --- a/examples/datavisualization/surface/surfacegraph.cpp +++ /dev/null @@ -1,251 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -#include "surfacegraph.h" - -#include <QtDataVisualization/QValue3DAxis> -#include <QtDataVisualization/Q3DTheme> -#include <QtGui/QImage> -#include <QtCore/qmath.h> - -const int sampleCountX = 50; -const int sampleCountZ = 50; -const int heightMapGridStepX = 6; -const int heightMapGridStepZ = 6; -const float sampleMin = -8.0f; -const float sampleMax = 8.0f; - -SurfaceGraph::SurfaceGraph(Q3DSurface *surface) - : m_graph(surface) -{ - m_graph->setAxisX(new QValue3DAxis); - m_graph->setAxisY(new QValue3DAxis); - m_graph->setAxisZ(new QValue3DAxis); - - //! [0] - m_sqrtSinProxy = new QSurfaceDataProxy(); - m_sqrtSinSeries = new QSurface3DSeries(m_sqrtSinProxy); - //! [0] - fillSqrtSinProxy(); - - //! [2] - QImage heightMapImage(":/maps/mountain"); - m_heightMapProxy = new QHeightMapSurfaceDataProxy(heightMapImage); - m_heightMapSeries = new QSurface3DSeries(m_heightMapProxy); - m_heightMapSeries->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel")); - m_heightMapProxy->setValueRanges(34.0f, 40.0f, 18.0f, 24.0f); - //! [2] - m_heightMapWidth = heightMapImage.width(); - m_heightMapHeight = heightMapImage.height(); -} - -SurfaceGraph::~SurfaceGraph() -{ - delete m_graph; -} - -//! [1] -void SurfaceGraph::fillSqrtSinProxy() -{ - float stepX = (sampleMax - sampleMin) / float(sampleCountX - 1); - float stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1); - - QSurfaceDataArray *dataArray = new QSurfaceDataArray; - dataArray->reserve(sampleCountZ); - for (int i = 0 ; i < sampleCountZ ; i++) { - QSurfaceDataRow *newRow = new QSurfaceDataRow(sampleCountX); - // Keep values within range bounds, since just adding step can cause minor drift due - // to the rounding errors. - float z = qMin(sampleMax, (i * stepZ + sampleMin)); - int index = 0; - for (int j = 0; j < sampleCountX; j++) { - float x = qMin(sampleMax, (j * stepX + sampleMin)); - float R = qSqrt(z * z + x * x) + 0.01f; - float y = (qSin(R) / R + 0.24f) * 1.61f; - (*newRow)[index++].setPosition(QVector3D(x, y, z)); - } - *dataArray << newRow; - } - - m_sqrtSinProxy->resetArray(dataArray); -} -//! [1] - -void SurfaceGraph::enableSqrtSinModel(bool enable) -{ - if (enable) { - //! [3] - m_sqrtSinSeries->setDrawMode(QSurface3DSeries::DrawSurfaceAndWireframe); - m_sqrtSinSeries->setFlatShadingEnabled(true); - - m_graph->axisX()->setLabelFormat("%.2f"); - m_graph->axisZ()->setLabelFormat("%.2f"); - m_graph->axisX()->setRange(sampleMin, sampleMax); - m_graph->axisY()->setRange(0.0f, 2.0f); - m_graph->axisZ()->setRange(sampleMin, sampleMax); - m_graph->axisX()->setLabelAutoRotation(30); - m_graph->axisY()->setLabelAutoRotation(90); - m_graph->axisZ()->setLabelAutoRotation(30); - - m_graph->removeSeries(m_heightMapSeries); - m_graph->addSeries(m_sqrtSinSeries); - //! [3] - - //! [8] - // Reset range sliders for Sqrt&Sin - m_rangeMinX = sampleMin; - m_rangeMinZ = sampleMin; - m_stepX = (sampleMax - sampleMin) / float(sampleCountX - 1); - m_stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1); - m_axisMinSliderX->setMaximum(sampleCountX - 2); - m_axisMinSliderX->setValue(0); - m_axisMaxSliderX->setMaximum(sampleCountX - 1); - m_axisMaxSliderX->setValue(sampleCountX - 1); - m_axisMinSliderZ->setMaximum(sampleCountZ - 2); - m_axisMinSliderZ->setValue(0); - m_axisMaxSliderZ->setMaximum(sampleCountZ - 1); - m_axisMaxSliderZ->setValue(sampleCountZ - 1); - //! [8] - } -} - -void SurfaceGraph::enableHeightMapModel(bool enable) -{ - if (enable) { - //! [4] - m_heightMapSeries->setDrawMode(QSurface3DSeries::DrawSurface); - m_heightMapSeries->setFlatShadingEnabled(false); - - m_graph->axisX()->setLabelFormat("%.1f N"); - m_graph->axisZ()->setLabelFormat("%.1f E"); - m_graph->axisX()->setRange(34.0f, 40.0f); - m_graph->axisY()->setAutoAdjustRange(true); - m_graph->axisZ()->setRange(18.0f, 24.0f); - - m_graph->axisX()->setTitle(QStringLiteral("Latitude")); - m_graph->axisY()->setTitle(QStringLiteral("Height")); - m_graph->axisZ()->setTitle(QStringLiteral("Longitude")); - - m_graph->removeSeries(m_sqrtSinSeries); - m_graph->addSeries(m_heightMapSeries); - //! [4] - - // Reset range sliders for height map - int mapGridCountX = m_heightMapWidth / heightMapGridStepX; - int mapGridCountZ = m_heightMapHeight / heightMapGridStepZ; - m_rangeMinX = 34.0f; - m_rangeMinZ = 18.0f; - m_stepX = 6.0f / float(mapGridCountX - 1); - m_stepZ = 6.0f / float(mapGridCountZ - 1); - m_axisMinSliderX->setMaximum(mapGridCountX - 2); - m_axisMinSliderX->setValue(0); - m_axisMaxSliderX->setMaximum(mapGridCountX - 1); - m_axisMaxSliderX->setValue(mapGridCountX - 1); - m_axisMinSliderZ->setMaximum(mapGridCountZ - 2); - m_axisMinSliderZ->setValue(0); - m_axisMaxSliderZ->setMaximum(mapGridCountZ - 1); - m_axisMaxSliderZ->setValue(mapGridCountZ - 1); - } -} - -void SurfaceGraph::adjustXMin(int min) -{ - float minX = m_stepX * float(min) + m_rangeMinX; - - int max = m_axisMaxSliderX->value(); - if (min >= max) { - max = min + 1; - m_axisMaxSliderX->setValue(max); - } - float maxX = m_stepX * max + m_rangeMinX; - - setAxisXRange(minX, maxX); -} - -void SurfaceGraph::adjustXMax(int max) -{ - float maxX = m_stepX * float(max) + m_rangeMinX; - - int min = m_axisMinSliderX->value(); - if (max <= min) { - min = max - 1; - m_axisMinSliderX->setValue(min); - } - float minX = m_stepX * min + m_rangeMinX; - - setAxisXRange(minX, maxX); -} - -void SurfaceGraph::adjustZMin(int min) -{ - float minZ = m_stepZ * float(min) + m_rangeMinZ; - - int max = m_axisMaxSliderZ->value(); - if (min >= max) { - max = min + 1; - m_axisMaxSliderZ->setValue(max); - } - float maxZ = m_stepZ * max + m_rangeMinZ; - - setAxisZRange(minZ, maxZ); -} - -void SurfaceGraph::adjustZMax(int max) -{ - float maxX = m_stepZ * float(max) + m_rangeMinZ; - - int min = m_axisMinSliderZ->value(); - if (max <= min) { - min = max - 1; - m_axisMinSliderZ->setValue(min); - } - float minX = m_stepZ * min + m_rangeMinZ; - - setAxisZRange(minX, maxX); -} - -//! [5] -void SurfaceGraph::setAxisXRange(float min, float max) -{ - m_graph->axisX()->setRange(min, max); -} - -void SurfaceGraph::setAxisZRange(float min, float max) -{ - m_graph->axisZ()->setRange(min, max); -} -//! [5] - -//! [6] -void SurfaceGraph::changeTheme(int theme) -{ - m_graph->activeTheme()->setType(Q3DTheme::Theme(theme)); -} -//! [6] - -void SurfaceGraph::setBlackToYellowGradient() -{ - //! [7] - QLinearGradient gr; - gr.setColorAt(0.0, Qt::black); - gr.setColorAt(0.33, Qt::blue); - gr.setColorAt(0.67, Qt::red); - gr.setColorAt(1.0, Qt::yellow); - - m_graph->seriesList().at(0)->setBaseGradient(gr); - m_graph->seriesList().at(0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient); - //! [7] -} - -void SurfaceGraph::setGreenToRedGradient() -{ - QLinearGradient gr; - gr.setColorAt(0.0, Qt::darkGreen); - gr.setColorAt(0.5, Qt::yellow); - gr.setColorAt(0.8, Qt::red); - gr.setColorAt(1.0, Qt::darkRed); - - m_graph->seriesList().at(0)->setBaseGradient(gr); - m_graph->seriesList().at(0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient); -} - diff --git a/examples/datavisualization/surface/surfacegraph.h b/examples/datavisualization/surface/surfacegraph.h deleted file mode 100644 index f23370f7..00000000 --- a/examples/datavisualization/surface/surfacegraph.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -#ifndef SURFACEGRAPH_H -#define SURFACEGRAPH_H - -#include <QtDataVisualization/Q3DSurface> -#include <QtDataVisualization/QSurfaceDataProxy> -#include <QtDataVisualization/QHeightMapSurfaceDataProxy> -#include <QtDataVisualization/QSurface3DSeries> -#include <QtWidgets/QSlider> - -class SurfaceGraph : public QObject -{ - Q_OBJECT -public: - explicit SurfaceGraph(Q3DSurface *surface); - ~SurfaceGraph(); - - void enableHeightMapModel(bool enable); - void enableSqrtSinModel(bool enable); - - //! [0] - void toggleModeNone() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionNone); } - void toggleModeItem() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionItem); } - void toggleModeSliceRow() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionItemAndRow - | QAbstract3DGraph::SelectionSlice); } - void toggleModeSliceColumn() { m_graph->setSelectionMode(QAbstract3DGraph::SelectionItemAndColumn - | QAbstract3DGraph::SelectionSlice); } - //! [0] - - void setBlackToYellowGradient(); - void setGreenToRedGradient(); - - void setAxisMinSliderX(QSlider *slider) { m_axisMinSliderX = slider; } - void setAxisMaxSliderX(QSlider *slider) { m_axisMaxSliderX = slider; } - void setAxisMinSliderZ(QSlider *slider) { m_axisMinSliderZ = slider; } - void setAxisMaxSliderZ(QSlider *slider) { m_axisMaxSliderZ = slider; } - - void adjustXMin(int min); - void adjustXMax(int max); - void adjustZMin(int min); - void adjustZMax(int max); - -public Q_SLOTS: - void changeTheme(int theme); - -private: - Q3DSurface *m_graph; - QHeightMapSurfaceDataProxy *m_heightMapProxy; - QSurfaceDataProxy *m_sqrtSinProxy; - QSurface3DSeries *m_heightMapSeries; - QSurface3DSeries *m_sqrtSinSeries; - - QSlider *m_axisMinSliderX; - QSlider *m_axisMaxSliderX; - QSlider *m_axisMinSliderZ; - QSlider *m_axisMaxSliderZ; - float m_rangeMinX; - float m_rangeMinZ; - float m_stepX; - float m_stepZ; - int m_heightMapWidth; - int m_heightMapHeight; - - void setAxisXRange(float min, float max); - void setAxisZRange(float min, float max); - void fillSqrtSinProxy(); -}; - -#endif // SURFACEGRAPH_H diff --git a/examples/datavisualization/texturesurface/CMakeLists.txt b/examples/datavisualization/texturesurface/CMakeLists.txt deleted file mode 100644 index ef1a6706..00000000 --- a/examples/datavisualization/texturesurface/CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright (C) 2022 The Qt Company Ltd. -# SPDX-License-Identifier: BSD-3-Clause - -cmake_minimum_required(VERSION 3.16) -project(texturesurface LANGUAGES CXX) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}") - -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Widgets) -find_package(Qt6 COMPONENTS DataVisualization) - -qt_add_executable(texturesurface - custominputhandler.cpp custominputhandler.h - highlightseries.cpp highlightseries.h - main.cpp - surfacegraph.cpp surfacegraph.h - topographicseries.cpp topographicseries.h -) -set_target_properties(texturesurface PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(texturesurface PUBLIC - Qt::Core - Qt::Gui - Qt::Widgets - Qt::DataVisualization -) - -set_source_files_properties("maptexture.jpg" - PROPERTIES QT_RESOURCE_ALIAS "maptexture" -) -set_source_files_properties("topography.png" - PROPERTIES QT_RESOURCE_ALIAS "topography" -) -set(texturedsurface_resource_files - "maptexture.jpg" - "topography.png" -) - -qt6_add_resources(texturesurface "texturedsurface" - PREFIX - "/maps" - FILES - ${texturedsurface_resource_files} -) - -install(TARGETS texturesurface - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) diff --git a/examples/datavisualization/texturesurface/doc/images/texturesurface-example.png b/examples/datavisualization/texturesurface/doc/images/texturesurface-example.png Binary files differdeleted file mode 100644 index 76819607..00000000 --- a/examples/datavisualization/texturesurface/doc/images/texturesurface-example.png +++ /dev/null diff --git a/examples/datavisualization/texturesurface/doc/src/texturesurface.qdoc b/examples/datavisualization/texturesurface/doc/src/texturesurface.qdoc deleted file mode 100644 index 887d1b8f..00000000 --- a/examples/datavisualization/texturesurface/doc/src/texturesurface.qdoc +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only - -/*! - \example texturesurface - \meta tags {DataVisualization, Q3DSurface, Textured Surface} - \meta category {Graphics} - \title Textured Surface Graph - \ingroup qtdatavisualization_examples - \brief Using texture with Q3DSurface. - \since QtDataVisualization 1.2 - - The textured surface graph example shows how to add an image as a texture for a surface. The - example shows also how to: - - \list - \li Create a surface series from an image - \li Use custom input handler to enable zooming and panning - \li Highlight an area of the surface - \endlist - - \image texturesurface-example.png - - \include examples-run.qdocinc - - \section1 Texture to a Surface Series - - The image to be set as a texture to a surface can be set using QSurface3DSeries::setTextureFile(). - In this example we have added a check box to control if the texture is set or not. The - following code extract is for reacting to the check box selections. The image in this - example is read from the resource file where it is as a JPG file. Setting an empty file - with the method clears the texture, and the surface uses the gradients or colors from the theme. - - \snippet texturesurface/surfacegraph.cpp 0 - - \section1 Topographic Surface Series - - The topographic data for this example is obtained from National Land Survey of Finland. It - provides a product called \c{Elevation Model 2 m}, which was suitable for our needs. We selected - Levi fell to be shown. The accuracy of the data was well beyond our needs and therefore it - is compressed and encoded into a PNG file. The height value from the original ASCII data is - encoded into RGB format using a multiplier, which you will see later on a code extract. - The multiplier is calculated simply by dividing the largest 24 bit value with the highest point - in Finland. - - Qt Data Visualization has a special proxy for height map image files, but it converts - only one byte values. So to utilize the bigger accuracy on the data from National Land - Survey of Finland, we read the data from the PNG file and decode it into QSurface3DSeries. - The following code samples show how this is done. - - First the encoding multiplier. - \snippet texturesurface/topographicseries.cpp 0 - - And then the actual decoding. - \snippet texturesurface/topographicseries.cpp 1 - - \section1 Use Custom Input Handler to Enable Zooming and Panning - - For the panning the implementation is similar to the \l{Input Handling for Axes}. - The difference is that in this example we follow only dragging of X and Z axis and we don't - allow dragging the surface outside the graph. The control for this is very simple and done as - on the following example for the X axis. - - \snippet texturesurface/custominputhandler.cpp 0 - - For the zooming we catch the \c wheelEvent and adjust the X and Y axis ranges according to delta - value on QWheelEvent. The Y axis is also adjusted so that the aspect ratio between Y axis and - XZ plane stays the same, and we don't get silly looking graph with height exaggerated too much. - - \snippet texturesurface/custominputhandler.cpp 1 - - In this case we want to control the zoom level so that it won't get too near to or far from the - surface. For instance, if the value for the X axis gets below the allowed, i.e. zooming gets too - far, the value is set to the minimum allowed value. If the range is going to below the range - minimum, both ends of the axis are adjusted so that the range stays at the limit. - - \snippet texturesurface/custominputhandler.cpp 2 - - \section1 Highlight an Area of the Surface - - The main idea on creating a highlight on the surface is to create a copy of the series and add - a bit of offset to the y value. On this example the class \c HighlightSeries implements the - creation of the copy on its \c handlePositionChange method. Firstly the \c HighlightSeries - needs to get the pointer to the original series and then it starts to listen the - QSurface3DSeries::selectedPointChanged signal. - - \snippet texturesurface/highlightseries.cpp 0 - - When the signal arrives, first thing is to check that the position is valid. Then the ranges - for the copied area are calculated and checked that they stay within the bounds. Finally - we simply fill the data array of the highlight series with the range from the data array of - topography series. - - \snippet texturesurface/highlightseries.cpp 1 - - \section1 A Gradient to the Highlight Series - - Since the \c HighlightSeries is QSurface3DSeries, we can use all the decoration methods series can - have. In this example we added a gradient to emphasize the elevation. Because the suitable gradient - style depends on the range of the Y axis and we change the range when zooming, we need to adjust - the gradient color positions as the range change. - - For the gradient color positions we define proportional values. - - \snippet texturesurface/highlightseries.cpp 2 - - The gradient modification is done on \c handleGradientChange method and we connect it to react to - changes on Y axis. - - \snippet texturesurface/surfacegraph.cpp 1 - - When a change on Y axis max value happens, we calculate the gradient color positions. - - \snippet texturesurface/highlightseries.cpp 3 -*/ diff --git a/examples/datavisualization/texturesurface/main.cpp b/examples/datavisualization/texturesurface/main.cpp deleted file mode 100644 index fbc8c6e2..00000000 --- a/examples/datavisualization/texturesurface/main.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -#include "surfacegraph.h" - -#include <QtWidgets/QApplication> -#include <QtWidgets/QWidget> -#include <QtWidgets/QHBoxLayout> -#include <QtWidgets/QVBoxLayout> -#include <QtWidgets/QGroupBox> -#include <QtWidgets/QCheckBox> -#include <QtWidgets/QLabel> -#include <QtWidgets/QMessageBox> -#include <QtGui/QScreen> -#include <QtGui/QPainter> - -int main(int argc, char **argv) -{ - qputenv("QSG_RHI_BACKEND", "opengl"); - QApplication app(argc, argv); - Q3DSurface *graph = new Q3DSurface(); - QWidget *container = QWidget::createWindowContainer(graph); - - if (!graph->hasContext()) { - QMessageBox msgBox; - msgBox.setText("Couldn't initialize the OpenGL context."); - msgBox.exec(); - return -1; - } - - QSize screenSize = graph->screen()->size(); - container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 1.6)); - container->setMaximumSize(screenSize); - container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - container->setFocusPolicy(Qt::StrongFocus); - - QWidget *widget = new QWidget; - QHBoxLayout *hLayout = new QHBoxLayout(widget); - QVBoxLayout *vLayout = new QVBoxLayout(); - hLayout->addWidget(container, 1); - hLayout->addLayout(vLayout); - vLayout->setAlignment(Qt::AlignTop); - - widget->setWindowTitle(QStringLiteral("Textured surface example")); - - QCheckBox *enableTexture = new QCheckBox(widget); - enableTexture->setText(QStringLiteral("Surface texture")); - - int height = 400; - int width = 100; - int border = 10; - QLinearGradient gr(0, 0, 1, height - 2 * border); - gr.setColorAt(1.0f, Qt::black); - gr.setColorAt(0.8f, Qt::darkGreen); - gr.setColorAt(0.6f, Qt::green); - gr.setColorAt(0.4f, Qt::yellow); - gr.setColorAt(0.2f, Qt::red); - gr.setColorAt(0.0f, Qt::darkRed); - - QPixmap pm(width, height); - pm.fill(Qt::transparent); - QPainter pmp(&pm); - pmp.setBrush(QBrush(gr)); - pmp.setPen(Qt::NoPen); - pmp.drawRect(border, border, 35, height - 2 * border); - pmp.setPen(Qt::black); - int step = (height - 2 * border) / 5; - for (int i = 0; i < 6; i++) { - int yPos = i * step + border; - pmp.drawLine(border, yPos, 55, yPos); - pmp.drawText(60, yPos + 2, QString("%1 m").arg(550 - (i * 110))); - } - - QLabel *label = new QLabel(widget); - label->setPixmap(pm); - - QGroupBox *heightMapGroupBox = new QGroupBox(QStringLiteral("Highlight color map")); - QVBoxLayout *colorMapVBox = new QVBoxLayout; - colorMapVBox->addWidget(label); - heightMapGroupBox->setLayout(colorMapVBox); - - vLayout->addWidget(enableTexture); - vLayout->addWidget(heightMapGroupBox); - - widget->show(); - - SurfaceGraph *modifier = new SurfaceGraph(graph); - - QObject::connect(enableTexture, &QCheckBox::stateChanged, - modifier, &SurfaceGraph::toggleSurfaceTexture); - - enableTexture->setChecked(true); - - return app.exec(); -} diff --git a/examples/datavisualization/texturesurface/surfacegraph.cpp b/examples/datavisualization/texturesurface/surfacegraph.cpp deleted file mode 100644 index a7900914..00000000 --- a/examples/datavisualization/texturesurface/surfacegraph.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -#include "surfacegraph.h" -#include "topographicseries.h" - -#include <QtDataVisualization/QValue3DAxis> -#include <QtDataVisualization/Q3DTheme> - -const float areaWidth = 8000.0f; -const float areaHeight = 8000.0f; -const float aspectRatio = 0.1389f; -const float minRange = areaWidth * 0.49f; - -SurfaceGraph::SurfaceGraph(Q3DSurface *surface) - : m_graph(surface) -{ - m_graph->setAxisX(new QValue3DAxis); - m_graph->setAxisY(new QValue3DAxis); - m_graph->setAxisZ(new QValue3DAxis); - m_graph->axisX()->setLabelFormat("%i"); - m_graph->axisZ()->setLabelFormat("%i"); - m_graph->axisX()->setRange(0.0f, areaWidth); - m_graph->axisY()->setRange(100.0f, areaWidth * aspectRatio); - m_graph->axisZ()->setRange(0.0f, areaHeight); - m_graph->axisX()->setLabelAutoRotation(30); - m_graph->axisY()->setLabelAutoRotation(90); - m_graph->axisZ()->setLabelAutoRotation(30); - m_graph->activeTheme()->setType(Q3DTheme::ThemePrimaryColors); - - QFont font = m_graph->activeTheme()->font(); - font.setPointSize(20); - m_graph->activeTheme()->setFont(font); - - m_topography = new TopographicSeries(); - m_topography->setTopographyFile(":/maps/topography", areaWidth, areaHeight); - m_topography->setItemLabelFormat(QStringLiteral("@yLabel m")); - - m_highlight = new HighlightSeries(); - m_highlight->setTopographicSeries(m_topography); - m_highlight->setMinHeight(minRange * aspectRatio); - m_highlight->handleGradientChange(areaWidth * aspectRatio); -//! [1] - QObject::connect(m_graph->axisY(), &QValue3DAxis::maxChanged, - m_highlight, &HighlightSeries::handleGradientChange); -//! [1] - - m_graph->addSeries(m_topography); - m_graph->addSeries(m_highlight); - - m_inputHandler = new CustomInputHandler(m_graph); - m_inputHandler->setHighlightSeries(m_highlight); - m_inputHandler->setAxes(m_graph->axisX(), m_graph->axisY(), m_graph->axisZ()); - m_inputHandler->setLimits(0.0f, areaWidth, minRange); - m_inputHandler->setAspectRatio(aspectRatio); - - m_graph->setActiveInputHandler(m_inputHandler); -} - -SurfaceGraph::~SurfaceGraph() -{ - delete m_graph; -} - -//! [0] -void SurfaceGraph::toggleSurfaceTexture(bool enable) -{ - if (enable) - m_topography->setTextureFile(":/maps/maptexture"); - else - m_topography->setTextureFile(""); -} -//! [0] diff --git a/examples/datavisualization/texturesurface/surfacegraph.h b/examples/datavisualization/texturesurface/surfacegraph.h deleted file mode 100644 index bae10f98..00000000 --- a/examples/datavisualization/texturesurface/surfacegraph.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -#ifndef SURFACEGRAPH_H -#define SURFACEGRAPH_H - -#include <QtDataVisualization/Q3DSurface> -#include <QtDataVisualization/QSurface3DSeries> -#include <QtWidgets/QSlider> -#include "topographicseries.h" -#include "highlightseries.h" - -#include "custominputhandler.h" - -class SurfaceGraph : public QObject -{ - Q_OBJECT -public: - explicit SurfaceGraph(Q3DSurface *surface); - ~SurfaceGraph(); - - void toggleSurfaceTexture(bool enable); - -private: - Q3DSurface *m_graph; - - TopographicSeries *m_topography; - HighlightSeries *m_highlight; - int m_highlightWidth; - int m_highlightHeight; - - CustomInputHandler *m_inputHandler; -}; - -#endif // SURFACEGRAPH_H diff --git a/examples/datavisualization/texturesurface/texturedsurface.qrc b/examples/datavisualization/texturesurface/texturedsurface.qrc deleted file mode 100644 index 94b96d24..00000000 --- a/examples/datavisualization/texturesurface/texturedsurface.qrc +++ /dev/null @@ -1,6 +0,0 @@ -<RCC> - <qresource prefix="/maps"> - <file alias="topography">topography.png</file> - <file alias="maptexture">maptexture.jpg</file> - </qresource> -</RCC> diff --git a/examples/datavisualization/texturesurface/texturesurface.pro b/examples/datavisualization/texturesurface/texturesurface.pro deleted file mode 100644 index efef1944..00000000 --- a/examples/datavisualization/texturesurface/texturesurface.pro +++ /dev/null @@ -1,25 +0,0 @@ -android|ios|winrt { - error( "This example is not supported for android, ios, or winrt." ) -} - -!include( ../examples.pri ) { - error( "Couldn't find the examples.pri file!" ) -} - -SOURCES += main.cpp \ - surfacegraph.cpp \ - topographicseries.cpp \ - highlightseries.cpp \ - custominputhandler.cpp - -HEADERS += surfacegraph.h \ - topographicseries.h \ - highlightseries.h \ - custominputhandler.h - -QT += widgets - -RESOURCES += texturedsurface.qrc - -OTHER_FILES += doc/src/* \ - doc/images/* |