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
37using namespace QtDataVisualization;
38
39CustomItemGraph::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(minX: 34.0f, maxX: 40.0f, minZ: 18.0f, maxZ: 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(minX: 34.0f, maxX: 40.0f, minZ: 18.0f, maxZ: 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(minX: 34.0f, maxX: 40.0f, minZ: 18.0f, maxZ: 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(min: 34.0f, max: 40.0f);
71 m_graph->axisY()->setRange(min: 0.0f, max: 200.0f);
72 m_graph->axisZ()->setRange(min: 18.0f, max: 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(series: layerOneSeries);
79 m_graph->addSeries(series: layerTwoSeries);
80 m_graph->addSeries(series: layerThreeSeries);
81
82 QLinearGradient grOne;
83 grOne.setColorAt(pos: 0.0, color: Qt::black);
84 grOne.setColorAt(pos: 0.38, color: Qt::darkYellow);
85 grOne.setColorAt(pos: 0.39, color: Qt::darkGreen);
86 grOne.setColorAt(pos: 0.5, color: Qt::darkGray);
87 grOne.setColorAt(pos: 1.0, color: Qt::gray);
88 m_graph->seriesList().at(i: 0)->setBaseGradient(grOne);
89 m_graph->seriesList().at(i: 0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
90
91 QLinearGradient grTwo;
92 grTwo.setColorAt(pos: 0.385, color: Qt::blue);
93 grTwo.setColorAt(pos: 0.395, color: Qt::white);
94 m_graph->seriesList().at(i: 1)->setBaseGradient(grTwo);
95 m_graph->seriesList().at(i: 1)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
96
97 QLinearGradient grThree;
98 grThree.setColorAt(pos: 0.0, color: Qt::white);
99 grThree.setColorAt(pos: 0.05, color: Qt::black);
100 m_graph->seriesList().at(i: 2)->setBaseGradient(grThree);
101 m_graph->seriesList().at(i: 2)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
102
103 m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront);
104
105 connect(sender: m_graph, signal: &QAbstract3DGraph::selectedElementChanged,
106 receiver: this, slot: &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(item: titleLabel);
123
124 toggleItemOne(show: true);
125 toggleItemTwo(show: true);
126}
127
128CustomItemGraph::~CustomItemGraph()
129{
130 delete m_graph;
131}
132
133void 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(color: 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(x: 0.0f, y: 1.0f, z: 0.0f, angle: 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(item: label);
166 } else {
167 resetSelection();
168 //! [4]
169 m_graph->removeCustomItemAt(position: positionOne);
170 //! [4]
171 m_graph->removeCustomItemAt(position: positionOnePipe);
172 m_graph->removeCustomItemAt(position: positionOneLabel);
173 }
174}
175
176void 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(color: 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(x: 0.0f, y: 1.0f, z: 0.0f, angle: 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(item: label);
203 } else {
204 resetSelection();
205 m_graph->removeCustomItemAt(position: positionTwo);
206 m_graph->removeCustomItemAt(position: positionTwoPipe);
207 m_graph->removeCustomItemAt(position: positionTwoLabel);
208 }
209}
210
211void 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(color: 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(x: 0.0f, y: 1.0f, z: 0.0f, angle: 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(item: label);
231 } else {
232 resetSelection();
233 m_graph->removeCustomItemAt(position: positionThree);
234 m_graph->removeCustomItemAt(position: positionThreeLabel);
235 }
236}
237
238void CustomItemGraph::toggleSeeThrough(bool seethrough)
239{
240 if (seethrough) {
241 m_graph->seriesList().at(i: 0)->setDrawMode(QSurface3DSeries::DrawWireframe);
242 m_graph->seriesList().at(i: 1)->setDrawMode(QSurface3DSeries::DrawWireframe);
243 } else {
244 m_graph->seriesList().at(i: 0)->setDrawMode(QSurface3DSeries::DrawSurface);
245 m_graph->seriesList().at(i: 1)->setDrawMode(QSurface3DSeries::DrawSurface);
246 }
247}
248
249void CustomItemGraph::toggleOilHighlight(bool highlight)
250{
251 if (highlight) {
252 QLinearGradient grThree;
253 grThree.setColorAt(pos: 0.0, color: Qt::black);
254 grThree.setColorAt(pos: 0.05, color: Qt::red);
255 m_graph->seriesList().at(i: 2)->setBaseGradient(grThree);
256 } else {
257 QLinearGradient grThree;
258 grThree.setColorAt(pos: 0.0, color: Qt::white);
259 grThree.setColorAt(pos: 0.05, color: Qt::black);
260 m_graph->seriesList().at(i: 2)->setBaseGradient(grThree);
261 }
262}
263
264void CustomItemGraph::toggleShadows(bool shadows)
265{
266 if (shadows)
267 m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualityMedium);
268 else
269 m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualityNone);
270}
271
272void 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 *>(object: item) != 0) {
279 text.append(s: "Custom label: ");
280 } else {
281 QStringList split = item->meshFile().split(sep: "/");
282 text.append(s: split.last());
283 text.append(s: ": ");
284 }
285 int index = m_graph->selectedCustomItemIndex();
286 text.append(s: 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(n: point.x());
301 text.append(s: posStr);
302 text.append(s: ", ");
303 posStr.setNum(n: point.y());
304 text.append(s: posStr);
305 }
306 text.append(s: ")");
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(s: "Axis X label: ");
314 else if (type == QAbstract3DGraph::ElementAxisYLabel)
315 text.append(s: "Axis Y label: ");
316 else
317 text.append(s: "Axis Z label: ");
318 text.append(s: QString::number(index));
319 m_textField->setText(text);
320 } else {
321 m_textField->setText("Nothing");
322 }
323}
324
325void CustomItemGraph::resetSelection()
326{
327 m_selectionAnimation->stop();
328 if (m_previouslyAnimatedItem)
329 m_previouslyAnimatedItem->setScaling(m_previousScaling);
330 m_previouslyAnimatedItem = 0;
331}
332

source code of qtdatavis3d/examples/datavisualization/customitems/customitemgraph.cpp