Qt 5.11 | Qt Data Visualization | Custom Items Example | customitemgraph.cpp Example File

Qt Data Visualization | Commercial or GPLv3

# customitemgraph.cpp Example File

customitems/customitemgraph.cpp

      /****************************************************************************
      **
      ** Copyright (C) 2016 The Qt Company Ltd.
      ** Contact: https://www.qt.io/licensing/
      **
      ** This file is part of the Qt Data Visualization module of the Qt Toolkit.
      **
      ** $QT_BEGIN_LICENSE:GPL$
      ** Commercial License Usage
      ** Licensees holding valid commercial Qt licenses may use this file in
      ** accordance with the commercial license agreement provided with the
      ** Software or, alternatively, in accordance with the terms contained in
      ** a written agreement between you and The Qt Company. For licensing terms
      ** and conditions see https://www.qt.io/terms-conditions. For further
      ** information use the contact form at https://www.qt.io/contact-us.
      **
      ** GNU General Public License Usage
      ** Alternatively, this file may be used under the terms of the GNU
      ** General Public License version 3 or (at your option) any later version
      ** approved by the KDE Free Qt Foundation. The licenses are as published by
      ** the Free Software Foundation and appearing in the file LICENSE.GPL3
      ** included in the packaging of this file. Please review the following
      ** information to ensure the GNU General Public License requirements will
      ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
      **
      ** $QT_END_LICENSE$
      **
      ****************************************************************************/

      #include "customitemgraph.h"

      #include <QtDataVisualization/Q3DTheme>
      #include <QtDataVisualization/QCustom3DItem>
      #include <QtDataVisualization/QCustom3DLabel>
      #include <QtGui/QImage>

      using namespace QtDataVisualization;

      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)
      {
          QVector3D positionOne = QVector3D(39.0f, 77.0f, 19.2f);
          QVector3D positionOnePipe = QVector3D(39.0f, 45.0f, 19.2f);
          QVector3D positionOneLabel = QVector3D(39.0f, 107.0f, 19.2f);
          if (show) {
              QImage color = QImage(2, 2, QImage::Format_RGB32);
              color.fill(Qt::red);
              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);
              m_graph->addCustomItem(item);
              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();
              m_graph->removeCustomItemAt(positionOne);
              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;
      }