1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Data Visualization module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 or (at your option) any later version
20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 ** included in the packaging of this file. Please review the following
23 ** information to ensure the GNU General Public License requirements will
24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 **
26 ** $QT_END_LICENSE$
27 **
28 ****************************************************************************/
29 
30 #include "customitemgraph.h"
31 
32 #include <QtDataVisualization/Q3DTheme>
33 #include <QtDataVisualization/QCustom3DItem>
34 #include <QtDataVisualization/QCustom3DLabel>
35 #include <QtGui/QImage>
36 
37 using namespace QtDataVisualization;
38 
CustomItemGraph(Q3DSurface * surface,QLabel * label)39 CustomItemGraph::CustomItemGraph(Q3DSurface *surface, QLabel *label)
40     : m_graph(surface),
41       m_textField(label),
42       m_previouslyAnimatedItem(0)
43 {
44     QImage layerOneHMap(":/maps/layer_1.png");
45     QHeightMapSurfaceDataProxy *layerOneProxy = new QHeightMapSurfaceDataProxy(layerOneHMap);
46     QSurface3DSeries *layerOneSeries = new QSurface3DSeries(layerOneProxy);
47     layerOneSeries->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel"));
48     layerOneProxy->setValueRanges(34.0f, 40.0f, 18.0f, 24.0f);
49     layerOneSeries->setDrawMode(QSurface3DSeries::DrawSurface);
50     layerOneSeries->setFlatShadingEnabled(false);
51 
52     QImage layerTwoHMap(":/maps/layer_2.png");
53     QHeightMapSurfaceDataProxy *layerTwoProxy = new QHeightMapSurfaceDataProxy(layerTwoHMap);
54     QSurface3DSeries *layerTwoSeries = new QSurface3DSeries(layerTwoProxy);
55     layerTwoSeries->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel"));
56     layerTwoProxy->setValueRanges(34.0f, 40.0f, 18.0f, 24.0f);
57     layerTwoSeries->setDrawMode(QSurface3DSeries::DrawSurface);
58     layerTwoSeries->setFlatShadingEnabled(false);
59 
60     QImage layerThreeHMap(":/maps/layer_3.png");
61     QHeightMapSurfaceDataProxy *layerThreeProxy = new QHeightMapSurfaceDataProxy(layerThreeHMap);
62     QSurface3DSeries *layerThreeSeries = new QSurface3DSeries(layerThreeProxy);
63     layerThreeSeries->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel"));
64     layerThreeProxy->setValueRanges(34.0f, 40.0f, 18.0f, 24.0f);
65     layerThreeSeries->setDrawMode(QSurface3DSeries::DrawSurface);
66     layerThreeSeries->setFlatShadingEnabled(false);
67 
68     m_graph->axisX()->setLabelFormat("%.1f N");
69     m_graph->axisZ()->setLabelFormat("%.1f E");
70     m_graph->axisX()->setRange(34.0f, 40.0f);
71     m_graph->axisY()->setRange(0.0f, 200.0f);
72     m_graph->axisZ()->setRange(18.0f, 24.0f);
73 
74     m_graph->axisX()->setTitle(QStringLiteral("Latitude"));
75     m_graph->axisY()->setTitle(QStringLiteral("Height"));
76     m_graph->axisZ()->setTitle(QStringLiteral("Longitude"));
77 
78     m_graph->addSeries(layerOneSeries);
79     m_graph->addSeries(layerTwoSeries);
80     m_graph->addSeries(layerThreeSeries);
81 
82     QLinearGradient grOne;
83     grOne.setColorAt(0.0, Qt::black);
84     grOne.setColorAt(0.38, Qt::darkYellow);
85     grOne.setColorAt(0.39, Qt::darkGreen);
86     grOne.setColorAt(0.5, Qt::darkGray);
87     grOne.setColorAt(1.0, Qt::gray);
88     m_graph->seriesList().at(0)->setBaseGradient(grOne);
89     m_graph->seriesList().at(0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
90 
91     QLinearGradient grTwo;
92     grTwo.setColorAt(0.385, Qt::blue);
93     grTwo.setColorAt(0.395, Qt::white);
94     m_graph->seriesList().at(1)->setBaseGradient(grTwo);
95     m_graph->seriesList().at(1)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
96 
97     QLinearGradient grThree;
98     grThree.setColorAt(0.0, Qt::white);
99     grThree.setColorAt(0.05, Qt::black);
100     m_graph->seriesList().at(2)->setBaseGradient(grThree);
101     m_graph->seriesList().at(2)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
102 
103     m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront);
104 
105     connect(m_graph, &QAbstract3DGraph::selectedElementChanged,
106             this, &CustomItemGraph::handleElementSelected);
107 
108     m_selectionAnimation = new QPropertyAnimation(this);
109     m_selectionAnimation->setPropertyName("scaling");
110     m_selectionAnimation->setDuration(500);
111     m_selectionAnimation->setLoopCount(-1);
112 
113     QFont titleFont = QFont("Century Gothic", 30);
114     titleFont.setBold(true);
115     QCustom3DLabel *titleLabel = new QCustom3DLabel("Oil Rigs on Imaginary Sea", titleFont,
116                                                     QVector3D(0.0f, 1.2f, 0.0f),
117                                                     QVector3D(1.0f, 1.0f, 0.0f),
118                                                     QQuaternion());
119     titleLabel->setPositionAbsolute(true);
120     titleLabel->setFacingCamera(true);
121     titleLabel->setBackgroundColor(QColor(0x66cdaa));
122     m_graph->addCustomItem(titleLabel);
123 
124     toggleItemOne(true);
125     toggleItemTwo(true);
126 }
127 
~CustomItemGraph()128 CustomItemGraph::~CustomItemGraph()
129 {
130     delete m_graph;
131 }
132 
toggleItemOne(bool show)133 void CustomItemGraph::toggleItemOne(bool show)
134 {
135     //! [1]
136     QVector3D positionOne = QVector3D(39.0f, 77.0f, 19.2f);
137     //! [1]
138     QVector3D positionOnePipe = QVector3D(39.0f, 45.0f, 19.2f);
139     QVector3D positionOneLabel = QVector3D(39.0f, 107.0f, 19.2f);
140     if (show) {
141         //! [0]
142         QImage color = QImage(2, 2, QImage::Format_RGB32);
143         color.fill(Qt::red);
144         //! [0]
145         //! [2]
146         QCustom3DItem *item = new QCustom3DItem(":/items/oilrig.obj", positionOne,
147                                                 QVector3D(0.025f, 0.025f, 0.025f),
148                                                 QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 45.0f),
149                                                 color);
150         //! [2]
151         //! [3]
152         m_graph->addCustomItem(item);
153         //! [3]
154         item = new QCustom3DItem(":/items/pipe.obj", positionOnePipe,
155                                  QVector3D(0.005f, 0.5f, 0.005f),
156                                  QQuaternion(),
157                                  color);
158         item->setShadowCasting(false);
159         m_graph->addCustomItem(item);
160 
161         QCustom3DLabel *label = new QCustom3DLabel();
162         label->setText("Oil Rig One");
163         label->setPosition(positionOneLabel);
164         label->setScaling(QVector3D(1.0f, 1.0f, 1.0f));
165         m_graph->addCustomItem(label);
166     } else {
167         resetSelection();
168         //! [4]
169         m_graph->removeCustomItemAt(positionOne);
170         //! [4]
171         m_graph->removeCustomItemAt(positionOnePipe);
172         m_graph->removeCustomItemAt(positionOneLabel);
173     }
174 }
175 
toggleItemTwo(bool show)176 void CustomItemGraph::toggleItemTwo(bool show)
177 {
178     QVector3D positionTwo = QVector3D(34.5f, 77.0f, 23.4f);
179     QVector3D positionTwoPipe = QVector3D(34.5f, 45.0f, 23.4f);
180     QVector3D positionTwoLabel = QVector3D(34.5f, 107.0f, 23.4f);
181     if (show) {
182         QImage color = QImage(2, 2, QImage::Format_RGB32);
183         color.fill(Qt::red);
184         QCustom3DItem *item = new QCustom3DItem();
185         item->setMeshFile(":/items/oilrig.obj");
186         item->setPosition(positionTwo);
187         item->setScaling(QVector3D(0.025f, 0.025f, 0.025f));
188         item->setRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 25.0f));
189         item->setTextureImage(color);
190         m_graph->addCustomItem(item);
191         item = new QCustom3DItem(":/items/pipe.obj", positionTwoPipe,
192                                  QVector3D(0.005f, 0.5f, 0.005f),
193                                  QQuaternion(),
194                                  color);
195         item->setShadowCasting(false);
196         m_graph->addCustomItem(item);
197 
198         QCustom3DLabel *label = new QCustom3DLabel();
199         label->setText("Oil Rig Two");
200         label->setPosition(positionTwoLabel);
201         label->setScaling(QVector3D(1.0f, 1.0f, 1.0f));
202         m_graph->addCustomItem(label);
203     } else {
204         resetSelection();
205         m_graph->removeCustomItemAt(positionTwo);
206         m_graph->removeCustomItemAt(positionTwoPipe);
207         m_graph->removeCustomItemAt(positionTwoLabel);
208     }
209 }
210 
toggleItemThree(bool show)211 void CustomItemGraph::toggleItemThree(bool show)
212 {
213     QVector3D positionThree = QVector3D(34.5f, 86.0f, 19.1f);
214     QVector3D positionThreeLabel = QVector3D(34.5f, 116.0f, 19.1f);
215     if (show) {
216         QImage color = QImage(2, 2, QImage::Format_RGB32);
217         color.fill(Qt::darkMagenta);
218         QCustom3DItem *item = new QCustom3DItem();
219         item->setMeshFile(":/items/refinery.obj");
220         item->setPosition(positionThree);
221         item->setScaling(QVector3D(0.04f, 0.04f, 0.04f));
222         item->setRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 75.0f));
223         item->setTextureImage(color);
224         m_graph->addCustomItem(item);
225 
226         QCustom3DLabel *label = new QCustom3DLabel();
227         label->setText("Refinery");
228         label->setPosition(positionThreeLabel);
229         label->setScaling(QVector3D(1.0f, 1.0f, 1.0f));
230         m_graph->addCustomItem(label);
231     } else {
232         resetSelection();
233         m_graph->removeCustomItemAt(positionThree);
234         m_graph->removeCustomItemAt(positionThreeLabel);
235     }
236 }
237 
toggleSeeThrough(bool seethrough)238 void CustomItemGraph::toggleSeeThrough(bool seethrough)
239 {
240     if (seethrough) {
241         m_graph->seriesList().at(0)->setDrawMode(QSurface3DSeries::DrawWireframe);
242         m_graph->seriesList().at(1)->setDrawMode(QSurface3DSeries::DrawWireframe);
243     } else {
244         m_graph->seriesList().at(0)->setDrawMode(QSurface3DSeries::DrawSurface);
245         m_graph->seriesList().at(1)->setDrawMode(QSurface3DSeries::DrawSurface);
246     }
247 }
248 
toggleOilHighlight(bool highlight)249 void CustomItemGraph::toggleOilHighlight(bool highlight)
250 {
251     if (highlight) {
252         QLinearGradient grThree;
253         grThree.setColorAt(0.0, Qt::black);
254         grThree.setColorAt(0.05, Qt::red);
255         m_graph->seriesList().at(2)->setBaseGradient(grThree);
256     } else {
257         QLinearGradient grThree;
258         grThree.setColorAt(0.0, Qt::white);
259         grThree.setColorAt(0.05, Qt::black);
260         m_graph->seriesList().at(2)->setBaseGradient(grThree);
261     }
262 }
263 
toggleShadows(bool shadows)264 void CustomItemGraph::toggleShadows(bool shadows)
265 {
266     if (shadows)
267         m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualityMedium);
268     else
269         m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualityNone);
270 }
271 
handleElementSelected(QAbstract3DGraph::ElementType type)272 void CustomItemGraph::handleElementSelected(QAbstract3DGraph::ElementType type)
273 {
274     resetSelection();
275     if (type == QAbstract3DGraph::ElementCustomItem) {
276         QCustom3DItem *item = m_graph->selectedCustomItem();
277         QString text;
278         if (qobject_cast<QCustom3DLabel *>(item) != 0) {
279             text.append("Custom label: ");
280         } else {
281             QStringList split = item->meshFile().split("/");
282             text.append(split.last());
283             text.append(": ");
284         }
285         int index = m_graph->selectedCustomItemIndex();
286         text.append(QString::number(index));
287         m_textField->setText(text);
288         m_previouslyAnimatedItem = item;
289         m_previousScaling = item->scaling();
290         m_selectionAnimation->setTargetObject(item);
291         m_selectionAnimation->setStartValue(item->scaling());
292         m_selectionAnimation->setEndValue(item->scaling() * 1.5f);
293         m_selectionAnimation->start();
294     } else if (type == QAbstract3DGraph::ElementSeries) {
295         QString text = "Surface (";
296         QSurface3DSeries *series = m_graph->selectedSeries();
297         if (series) {
298             QPoint point = series->selectedPoint();
299             QString posStr;
300             posStr.setNum(point.x());
301             text.append(posStr);
302             text.append(", ");
303             posStr.setNum(point.y());
304             text.append(posStr);
305         }
306         text.append(")");
307         m_textField->setText(text);
308     } else if (type > QAbstract3DGraph::ElementSeries
309                && type < QAbstract3DGraph::ElementCustomItem) {
310         int index = m_graph->selectedLabelIndex();
311         QString text;
312         if (type == QAbstract3DGraph::ElementAxisXLabel)
313             text.append("Axis X label: ");
314         else if (type == QAbstract3DGraph::ElementAxisYLabel)
315             text.append("Axis Y label: ");
316         else
317             text.append("Axis Z label: ");
318         text.append(QString::number(index));
319         m_textField->setText(text);
320     } else {
321         m_textField->setText("Nothing");
322     }
323 }
324 
resetSelection()325 void CustomItemGraph::resetSelection()
326 {
327     m_selectionAnimation->stop();
328     if (m_previouslyAnimatedItem)
329         m_previouslyAnimatedItem->setScaling(m_previousScaling);
330     m_previouslyAnimatedItem = 0;
331 }
332